#include #include #include #include "stat.h" #include "fat.h" #include "dir.h" #include "debug.h" static int get_stat_from_fat_entry(struct fat_direntry* dirent, struct stat* buf); static int dos2unixdate(unsigned short time, unsigned short date); int stat(char *name, struct stat *buf) { struct fat_direntry entry; char namecopy[256]; char* filename; DIR* dir; int namelen; if ( name[0] != '/' ) { DEBUGF("Only absolute paths supported right now\n"); errno = EINVAL; return -1; } strncpy(namecopy,name,sizeof(namecopy)); namecopy[sizeof(namecopy)-1] = 0; filename=strrchr(namecopy,'/'); *filename='\0'; filename++; namelen=strlen(filename); dir=opendir(namecopy); if (dir==NULL) { /* let opendir set errno */ return -1; } while (fat_getnext(&(dir->fatdir),&entry) >= 0) { if ( entry.name[0] && strncasecmp(filename,entry.name,namelen)==0) { /* Make sure to clean up after myself */ closedir(dir); return get_stat_from_fat_entry(&entry,buf); } } /* Make sure to clean up after myself */ closedir(dir); errno=ENOENT; return -1; } static int get_stat_from_fat_entry(struct fat_direntry* dirent, struct stat* buf) { memset(buf,0,sizeof(struct stat)); buf->st_ino=dirent->firstcluster; if (dirent->attr&FAT_ATTR_READ_ONLY) { buf->st_mode=S_IRUSR|S_IRGRP|S_IROTH; } else { buf->st_mode=S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; } buf->st_size=dirent->filesize; buf->st_rdev=S_IFREG; /* Fill in st_blksize and st_blocks later */ buf->st_atime=buf->st_mtime= dos2unixdate(dirent->wrttime,dirent->wrtdate); buf->st_ctime=dos2unixdate(dirent->crttime,dirent->crtdate); return 0; } static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 }; /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */ static int dos2unixdate(unsigned short time, unsigned short date) { int month,year,secs; month = ((date >> 5) & 15)-1; year = date >> 9; secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400* ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 && month < 2 ? 1 : 0)+3653); return secs; } /* * local variables: * eval: (load-file "../rockbox-mode.el") * end: */