// INCLUDES #include #include #include "dirinfo.h" // DEFINITIONS #define DIRINFO_DIR_SIZE 512 // STRUCTURE DEFINITIONS typedef struct { char *name; char *link; long mode; int uid; int gid; long size; long asecs; long msecs; long csecs; } FILE_T; struct DIRINFO_T { int num; int size; FILE_T **files; }; // FUNCTION PROTOTYPES FILE_T *File_Create(LPSTR); void File_Destroy(FILE_T *); LPSTR FindUNIXName(LPSTR szLine); // FUNCTION DEFINITIONS /* DirInfo_Create */ DIRINFO *DirInfo_Create() { DIRINFO *dir = malloc( sizeof(DIRINFO) ); assert(dir); dir->num = 0; dir->size = DIRINFO_DIR_SIZE; dir->files = malloc( sizeof(FILE_T *) * dir->size ); assert(dir->files); return dir; } /* DirInfo_Destroy */ void DirInfo_Destroy(DIRINFO *dir) { if ( dir ) { DirInfo_Initialize(dir); dir->size = 0; free(dir->files); free(dir); } } /* DirInfo_Initialize */ void DirInfo_Initialize(DIRINFO *dir) { int i; for ( i = 0 ; i < dir->num ; i++ ) File_Destroy(dir->files[i]); dir->num = 0; } /* DirInfo_Print */ void DirInfo_Print(DIRINFO *dir) { int i; printf("\n**** FILES ****\n\n"); for ( i = 0 ; i < dir->num ; i++ ) { if ( dir->files[i]->link ) printf("%s %x %d %d %d %d--> %s\n", dir->files[i]->name, dir->files[i]->mode, dir->files[i]->uid, dir->files[i]->gid, dir->files[i]->size, dir->files[i]->msecs, dir->files[i]->link); else printf("%s %x %d %d %d %d\n", dir->files[i]->name, dir->files[i]->mode, dir->files[i]->uid, dir->files[i]->gid, dir->files[i]->size, dir->files[i]->msecs); } } /* DirInfo_Add */ const int DirInfo_Add(DIRINFO *dir, LPSTR info) { FILE_T *file = File_Create(info); assert(file); dir->num++; if ( dir->num == dir->size ) { printf("\n****REALLOCATING MEMORY****\n"); dir->size *= 2; dir->files = realloc(dir->files, sizeof(FILE_T *) * dir->size); assert(dir->files); } dir->files[dir->num - 1] = file; return dir->num - 1; } /* DirInfo_Find */ const int DirInfo_Find(DIRINFO *dir, LPSTR name) { int l, r, x, cmpval; l = 0; r = dir->num - 1; // Find by binary search while ( r >= l ) { x = (l + r)/2; cmpval = strcmp(name, dir->files[x]->name); if ( cmpval < 0 ) r = x - 1; else if ( cmpval == 0 ) return x; else l = x + 1; } return -1; } /* DirInfo_GetNum */ const int DirInfo_GetNum(DIRINFO *dir) { return dir->num; } /* DirInfo_GetName */ LPSTR DirInfo_GetName(DIRINFO *dir, int index) { return dir->files[index]->name; } /* DirInfo_GetLink */ LPSTR DirInfo_GetLink(DIRINFO *dir, int index) { return dir->files[index]->link; } /* DirInfo_GetMode */ long DirInfo_GetMode(DIRINFO *dir, int index) { return dir->files[index]->mode; } /* DirInfo_GetUid */ int DirInfo_GetUid(DIRINFO *dir, int index) { return dir->files[index]->uid; } /* DirInfo_GetGid */ int DirInfo_GetGid(DIRINFO *dir, int index) { return dir->files[index]->gid; } /* DirInfo_GetSize */ long DirInfo_GetSize(DIRINFO *dir, int index) { return dir->files[index]->size; } /* DirInfo_GetASeconds */ long DirInfo_GetASeconds(DIRINFO *dir, int index) { return dir->files[index]->asecs; } /* DirInfo_GetMSeconds */ long DirInfo_GetMSeconds(DIRINFO *dir, int index) { return dir->files[index]->msecs; } /* DirInfo_GetCSeconds */ long DirInfo_GetCSeconds(DIRINFO *dir, int index) { return dir->files[index]->csecs; } /* File_Create */ FILE_T *File_Create(LPSTR info) { int i, day; char buf[10], buf2[10]; time_t cur_time; struct tm time_info, *cur_time2; LPSTR ptr, ptr2; FILE_T *file = malloc( sizeof(FILE_T) ); assert(file); // get the mode file->mode = 0x00000; if ( info[0] == 'l' ) file->mode |= 0xA000; // link else if ( info[0] == 'd' ) file->mode |= 0x04000; // directory else file->mode |= 0x8000; // file if ( info[1] == 'r' ) file->mode |= 0x00100; // owner read if ( info[2] == 'w' ) file->mode |= 0x00080; // owner write if ( info[3] == 'x' ) file->mode |= 0x00040; // owner execute if ( info[4] == 'r' ) file->mode |= 0x00020; // group read if ( info[5] == 'w' ) file->mode |= 0x00010; // group write if ( info[6] == 'x' ) file->mode |= 0x00008; // group execute if ( info[7] == 'r' ) file->mode |= 0x00004; // world read if ( info[8] == 'w' ) file->mode |= 0x00002; // world write if ( info[9] == 'x' ) file->mode |= 0x00001; // world execute // Get the uid, gid, and file size ptr = strchr(info, ' '); sscanf(ptr, "%d %d %d %d %s %d %s", &i, &file->uid, &file->gid, &file->size, buf, &day, buf2); time_info.tm_mday = day; if ( strncmp("Jan", buf, 3) == 0 ) time_info.tm_mon = 0; else if ( strncmp("Feb", buf, 3) == 0 ) time_info.tm_mon = 1; else if ( strncmp("Mar", buf, 3) == 0 ) time_info.tm_mon = 2; else if ( strncmp("Apr", buf, 3) == 0 ) time_info.tm_mon = 3; else if ( strncmp("May", buf, 3) == 0 ) time_info.tm_mon = 4; else if ( strncmp("Jun", buf, 3) == 0 ) time_info.tm_mon = 5; else if ( strncmp("Jul", buf, 3) == 0 ) time_info.tm_mon = 6; else if ( strncmp("Aug", buf, 3) == 0 ) time_info.tm_mon = 7; else if ( strncmp("Sep", buf, 3) == 0 ) time_info.tm_mon = 8; else if ( strncmp("Oct", buf, 3) == 0 ) time_info.tm_mon = 9; else if ( strncmp("Nov", buf, 3) == 0 ) time_info.tm_mon = 10; else time_info.tm_mon = 11; cur_time = time(NULL); cur_time2 = localtime(&cur_time); // time_info.tm_isdst = cur_time2->tm_isdst; if ( buf2[2] == ':' ) { buf2[2] = '\0'; time_info.tm_hour = atoi(buf2); time_info.tm_min = atoi(buf2 + 3); time_info.tm_sec = 0; if ( time_info.tm_mon < 6 ) time_info.tm_year = cur_time2->tm_year; else time_info.tm_year = cur_time2->tm_year - 1; } else { time_info.tm_year = atoi(buf2 + 2); time_info.tm_hour = 0; time_info.tm_min = 0; time_info.tm_sec = 0; } file->asecs = 0; file->msecs = mktime(&time_info); file->csecs = 0; ptr = FindUNIXName(info); i = strlen(ptr) - 1; if ( ptr[i] == '/' || ptr[i] == '\\' ) ptr[i] = '\0'; if ( info[0] == 'l' ) { ptr2 = strstr(info, " ->"); *ptr2 = '\0'; ptr2 += 4; // 4 characters to represent arrow and spaces file->link = malloc( sizeof(char) * (strlen(ptr2) + 1) ); assert(file->link); strcpy(file->link, ptr2); ptr = FindUNIXName(info); } else file->link = NULL; file->name = malloc( sizeof(char) * (strlen(ptr) + 1) ); assert(file->name); strcpy(file->name, ptr); return file; } /* File_Destroy */ void File_Destroy(FILE_T *file) { if ( file ) { file->mode = 0; file->size = 0; file->uid = 0; file->gid = 0; file->asecs = 0; file->msecs = 0; file->csecs = 0; free(file->name); free(file); } } /* FindUNIXName */ LPSTR FindUNIXName(LPSTR szLine) { int nIndex; char *pStr; // strip trailing garbage from the line if there is any. while ((nIndex = strlen(szLine)) > 2 && (szLine[nIndex - 1] == 0x0a || szLine[nIndex - 1] == 0x0d || szLine[nIndex - 1] == ' ' || szLine[nIndex - 1] == 0x09)) szLine[nIndex] = 0; // now the name SHOULD be the last thing on the line if ((pStr = strrchr(szLine,' ')) != NULL || (pStr = strrchr(szLine,0x09)) != NULL) { while (*pStr && (*pStr == ' ' || *pStr == 0x09)) pStr++; return(pStr); } return(szLine); }