home *** CD-ROM | disk | FTP | other *** search
- #import <string.h>
- #import <time.h>
- #import "DirEntry.h"
-
- enum {Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec};
- static const char *monthNames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
- "Aug", "Sep", "Oct", "Nov", "Dec", ""};
- static const char *monthFirstLetters = "JFMASOND";
- static int thisYear;
-
- char *NextEntry(char *buffer)
- {
- static char *searchBuffer;
- char *tmp,tmp_c;
- int count;
- if(buffer != NULL)
- searchBuffer = buffer;
- /* Find the next "\n[d-][rwxs-]x9" sequence in buffer */
- tmp = index(searchBuffer,'\n');
- if(tmp == NULL)
- return (char *) -1;
- searchBuffer = ++tmp;
- /* Check next 10 characters */
- if(strlen(tmp) < 11)
- return NULL;
- tmp_c = tmp[10];
- tmp[10] = '\0';
- count = strspn(tmp,"drwxs-");
- tmp[10] = tmp_c;
- if(count == 10)
- return tmp;
- return NULL;
- }
-
- /* Search the line from the ftp dir output and return the file information.
- Returns 0 on sucess with buffer set to the file name, -1 on failure. */
- int ParseAttributes(char **buffer,int *size,int *month,int *day,int *year,int *hr,int *min)
- {
- char *tmpPtr,*datePtr,*dayPtr,*yr_timePtr;
- int success;
-
- /* Find the start of the date string by locating its 3 letter month code */
- datePtr = tmpPtr = strpbrk(*buffer,monthFirstLetters);
- if(tmpPtr == NULL)
- return -1;
- /* Make sure this is a month name */
- switch(tmpPtr[0])
- {
- case 'J' :
- success = !strncmp(tmpPtr,monthNames[Jan],3);
- if(success)
- {
- *month = 1;
- break;
- }
- success = !strncmp(tmpPtr,monthNames[Jun],3);
- if(success)
- {
- *month = 6;
- break;
- }
- success = !strncmp(tmpPtr,monthNames[Jul],3);
- if(success)
- {
- *month = 7;
- break;
- }
- return -1;
- break;
- case 'F' :
- if(strncmp(tmpPtr,monthNames[Feb],3) != 0)
- return -1;
- *month = 2;
- break;
- case 'M' :
- success = !strncmp(tmpPtr,monthNames[Mar],3);
- if(success)
- {
- *month = 3;
- break;
- }
- success = !strncmp(tmpPtr,monthNames[May],3);
- if(success)
- {
- *month = 5;
- break;
- }
- return -1;
- break;
- case 'A' :
- success = !strncmp(tmpPtr,monthNames[Apr],3);
- if(success)
- {
- *month = 4;
- break;
- }
- success = !strncmp(tmpPtr,monthNames[Aug],3);
- if(success)
- {
- *month = 8;
- break;
- }
- return -1;
- break;
- case 'S' :
- if(strncmp(tmpPtr,monthNames[Sep],3) != 0)
- return -1;
- *month = 9;
- break;
- case 'O' :
- if(strncmp(tmpPtr,monthNames[Oct],3) != 0)
- return -1;
- *month = 10;
- break;
- case 'N' :
- if(strncmp(tmpPtr,monthNames[Nov],3) != 0)
- return -1;
- *month = 11;
- break;
- case 'D' :
- if(strncmp(tmpPtr,monthNames[Dec],3) != 0)
- return -1;
- *month = 12;
- break;
- default :
- return -1; // Never should happen
- }
- /* Now backup to the start of the size field */
- while( isdigit(*tmpPtr) == 0)
- tmpPtr --;
- /* And to the start of the date */
- while( isdigit(*tmpPtr) != 0)
- tmpPtr --;
- sscanf(++tmpPtr,"%d",size);
- /* Get the day */
- datePtr += 4;
- while( isdigit(*datePtr) == 0)
- datePtr ++;
- dayPtr = datePtr; // A pointer to the date
- while( isdigit(*datePtr) != 0)
- datePtr ++;
- *datePtr = '\0';
- *day = atoi(dayPtr);
- /* Get the year or time */
- datePtr ++;
- while( isdigit(*datePtr) == 0)
- datePtr ++;
- yr_timePtr = datePtr; // A pointer to the year or time
- while( isdigit(*datePtr) != 0)
- datePtr ++;
- if( *datePtr == ':')
- {
- sscanf(yr_timePtr,"%d:%d",hr,min);
- *year = thisYear;
- datePtr += 3;
- }
- else
- {
- *datePtr = '\0';
- *year = atoi(yr_timePtr);
- *hr = *min = 0;
- datePtr ++;
- }
- /* Lastly set the buffer to the file name */
- while( isspace(*datePtr) != 0)
- datePtr ++;
- *buffer = datePtr;
- return 0;
- }
-
-
- DirEntryPtr ParseBuffer(char *buffer)
- {
- DirEntryPtr tmp,list;
- char lineBuffer[128],*tmpPtr,*linkName;
- int size,month,day,year,hr,min;
- struct tm *timeStruct;
- time_t now;
-
- time(&now);
- timeStruct = localtime(&now);
- thisYear = timeStruct->tm_year + 1900;
-
- tmpPtr = buffer;
- list = NULL;
- while( (tmpPtr = NextEntry(tmpPtr)) != (char *) -1 )
- {
- if(tmpPtr != NULL)
- {
- sscanf(tmpPtr,"%[^\n]",lineBuffer);
- tmpPtr = lineBuffer + 10;
- if(ParseAttributes(&tmpPtr,&size,&month,&day,&year,&hr,&min) == 0)
- {
- /* Don't display the '.' or '..' files */
- if(strcmp(tmpPtr,".") == 0 || strcmp(tmpPtr,"..") == 0)
- {
- tmpPtr = NULL;
- continue;
- }
-
- if(list == NULL)
- tmp = list = (DirEntryPtr) malloc(sizeof(DirEntry));
- else
- {
- tmp->next = (DirEntryPtr) malloc(sizeof(DirEntry));
- tmp = tmp->next;
- }
- strncpy(tmp->mode,lineBuffer,10);
- sprintf(tmp->date,"%.4d%.2d%.2d%.2d%.2d",
- year,month,day,hr,min);
- tmp->bytes = size;
- /* Handle links - Ignore them for now
- if(lineBuffer[0] == 'l')
- {
- linkName = index(tmpPtr,'>');
- linkName -= 2; // move back before "->"
- while( isspace(*linkName) != 0)
- linkName --;
- *(++linkName) = '\0';
- } */
- tmp->name = (char *) malloc(strlen(tmpPtr)+1);
- strcpy(tmp->name,tmpPtr);
- tmp->next = NULL;
- }
- tmpPtr = NULL;
- }
- }
- return list;
- }
-
- void PrintDirList(DirEntryPtr list)
- {
- while(list != NULL)
- {
- fprintf(stderr,"%s %d %s %s\n",list->mode,list->bytes,list->date,list->name);
- list = list->next;
- }
- }
-
- #ifdef FTPPARSE_MAIN
- #import <stdio.h>
- #import <sys/file.h>
-
- char buffer[4096];
- main(int argc,char **argv)
- {
- int fd,n;
- DirEntryPtr list;
-
- fd = open((argc == 1 ? "./ftp_dir.out" : argv[1]),O_RDONLY);
- n = read(fd,buffer,4095);
- printf("Read %d bytes\n",n);
-
- /* Parse the file entries */
- list = ParseBuffer(buffer);
- PrintDirList(list);
- }
- #endif //FTPPARSE_MAIN
-