/****************************************************************************** libprozilla - a download accelerator library Copyright (C) 2001 Kalum Somaratna This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ******************************************************************************/ //Rewrite of the ftp parsing code as we needed to extract the date of //the file to save it when the downloading is complete. #include "common.h" #include "ftpparse.h" #include "prozilla.h" /* MultiNet (some spaces removed from examples) */ /* "00README.TXT;1 2 30-DEC-1996 17:44 [SYSTEM] (RWED,RWED,RE,RE)" */ /* "CORE.DIR;1 1 8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)" */ /* and non-MutliNet VMS: */ /* "CII-MANUAL.TEX;1 213/216 29-JAN-1996 03:33:12 [ANONYMOU,ANONYMOUS] (RWED,RWED,,)" */ /* MSDOS format */ /* 04-27-00 09:09PM licensed */ /* 07-18-00 10:16AM pub */ /* 04-14-00 03:47PM 589 readme.htm */ long getlong(char *buf,int len) { long u = 0; while (len-- > 0) u = u * 10 + (*buf++ - '0'); return u; } /* Find next Field ** --------------- ** Finds the next RFC822 token in a string ** On entry, ** *pstr points to a string containing a word separated ** by white white space "," ";" or "=". The word ** can optionally be quoted using <"> or "<" ">" ** Comments surrrounded by '(' ')' are filtered out ** ** On exit, ** *pstr has been moved to the first delimiter past the ** field ** THE STRING HAS BEEN MUTILATED by a 0 terminator ** ** Returns a pointer to the first word or NULL on error */ char * get_nextfield (char ** pstr) { char * p = *pstr; char * start = NULL; if (!pstr || !*pstr) return NULL; while (1) { /* Strip white space and other delimiters */ while (*p && (isspace((int) *p) || *p==',' || *p==';' || *p=='=')) p++; if (!*p) { *pstr = p; return NULL; /* No field */ } if (*p == '"') { /* quoted field */ start = ++p; for(;*p && *p!='"'; p++) if (*p == '\\' && *(p+1)) p++; /* Skip escaped chars */ break; /* kr95-10-9: needs to stop here */ } else if (*p == '<') { /* quoted field */ start = ++p; for(;*p && *p!='>'; p++) if (*p == '\\' && *(p+1)) p++; /* Skip escaped chars */ break; /* kr95-10-9: needs to stop here */ } else if (*p == '(') { /* Comment */ for(;*p && *p!=')'; p++) if (*p == '\\' && *(p+1)) p++; /* Skip escaped chars */ p++; } else { /* Spool field */ start = p; while(*p && !isspace((int) *p) && *p!=',' && *p!=';' && *p!='=') p++; break; /* Got it */ } } if (*p) *p++ = '\0'; *pstr = p; return start; } uerr_t ftp_parse(ftpparse *fp,char *buf,int len) { char *cp; char *token; char *ptr; char *date; int i; fp->filename = 0; fp->namelen = 0; // fp->flagtrycwd = 0; // fp->flagtryretr = 0; //fp->sizetype = FTPPARSE_SIZE_UNKNOWN; fp->filesize = 0; // fp->mtimetype = FTPPARSE_MTIME_UNKNOWN; fp->mtime = 0; // fp->idtype = FTPPARSE_ID_UNKNOWN; fp->id = 0; // fp->idlen = 0; proz_debug("FTP LIST to be parsed is %s", cp=strdup(buf)); free(cp); if (len < 2) /* an empty name in EPLF, with no info, could be 2 chars */ return FTPPARSENOTEXIST; switch(*buf) { case 'b': case 'c': case 'd': case 'l': case 'p': case 's': case '-': /* UNIX-style listing, without inum and without blocks */ /* "-rw-r--r-- 1 root other 531 Jan 29 03:26 README" */ /* "dr-xr-xr-x 2 root other 512 Apr 8 1994 etc" */ /* "dr-xr-xr-x 2 root 512 Apr 8 1994 etc" */ /* "lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin" */ /* Also produced by Microsoft's FTP servers for Windows: */ /* "---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z" */ /* "d--------- 1 owner group 0 May 9 19:45 Softlib" */ /* Also WFTPD for MSDOS: */ /* "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 message.ftp" */ /* Also NetWare: */ /* "d [R----F--] supervisor 512 Jan 16 18:53 login" */ /* "- [R----F--] rhesus 214059 Oct 20 15:27 cx.exe" */ /* Also NetPresenz for the Mac: */ /* "-------r-- 326 1391972 1392298 Nov 22 1995 MegaPhone.sit" */ /* "drwxrwxr-x folder 2 May 10 1996 network" */ if (*buf == 'd') fp->filetype = DIRECTORY; if (*buf == '-') fp->filetype = DIRECTORY; if (*buf == 'l') fp->filetype = SYMBOLIC_LINK; ptr=cp=strdup(buf); for (i=0;i<4;i++) { //add checking token= get_nextfield(&cp); if(token == NULL) //failed to parse return FTPPARSEFAIL; } /* ** This field can either be group or size. We find out by looking at the ** next field. If this is a non-digit then this field is the size. */ while (*cp && isspace((int) *cp)) cp++; if (isdigit((int) *cp)) { token = get_nextfield(&cp); while (*cp && isspace((int) *cp)) cp++; } //if it is a filename fp->filesize=strtol(token,NULL,10); proz_debug("FTP file size is %ld", fp->filesize); while (*cp && isspace((int) *cp)) cp++; assert(cp+12date_str = strdup(date); proz_debug("LIST date is %s", fp->date_str); return FTPPARSEOK; default: return FTPPARSEFAIL; } } time_t parse_time(const char * str) { char * p; struct tm tm; time_t t; if (!str) return 0; if ((p = strchr(str, ','))) { } return 0; }