#include <ftpparse.h>
Go to the source code of this file.
Functions | |
| static int | check (char *buf, char *monthname) |
| int | ftpparse (struct ftpparse *fp, char *buf, int len) |
| static long | getlong (char *buf, int len) |
| static int | getmonth (char *buf, int len) |
| static long | guesstai (long month, long mday) |
| static void | initbase (void) |
| static void | initnow (void) |
| static long | totai (long year, long month, long mday) |
Variables | |
| static time_t | base |
| static long | currentyear |
| static int | flagneedbase = 1 |
| static int | flagneedcurrentyear = 1 |
| static char * | months [12] |
| static long | now |
| static int check | ( | char * | buf, | |
| char * | monthname | |||
| ) | [static] |
Definition at line 115 of file ftpparse.c.
Definition at line 144 of file ftpparse.c.
00145 { 00146 int i; 00147 int j; 00148 int state; 00149 long size = 0; 00150 long year; 00151 long month = 0; 00152 long mday = 0; 00153 long hour; 00154 long minute; 00155 00156 fp->name = 0; 00157 fp->namelen = 0; 00158 fp->flagtrycwd = 0; 00159 fp->flagtryretr = 0; 00160 fp->sizetype = FTPPARSE_SIZE_UNKNOWN; 00161 fp->size = 0; 00162 fp->mtimetype = FTPPARSE_MTIME_UNKNOWN; 00163 fp->mtime = 0; 00164 fp->idtype = FTPPARSE_ID_UNKNOWN; 00165 fp->id = 0; 00166 fp->idlen = 0; 00167 00168 if (len < 2) /* an empty name in EPLF, with no info, could be 2 chars */ 00169 return 0; 00170 00171 switch(*buf) { 00172 /* see http://pobox.com/~djb/proto/eplf.txt */ 00173 /* "+i8388621.29609,m824255902,/,\tdev" */ 00174 /* "+i8388621.44468,m839956783,r,s10376,\tRFCEPLF" */ 00175 case '+': 00176 i = 1; 00177 for (j = 1;j < len;++j) { 00178 if (buf[j] == 9) { 00179 fp->name = buf + j + 1; 00180 fp->namelen = len - j - 1; 00181 return 1; 00182 } 00183 if (buf[j] == ',') { 00184 switch(buf[i]) { 00185 case '/': 00186 fp->flagtrycwd = 1; 00187 break; 00188 case 'r': 00189 fp->flagtryretr = 1; 00190 break; 00191 case 's': 00192 fp->sizetype = FTPPARSE_SIZE_BINARY; 00193 fp->size = getlong(buf + i + 1,j - i - 1); 00194 break; 00195 case 'm': 00196 fp->mtimetype = FTPPARSE_MTIME_LOCAL; 00197 initbase(); 00198 fp->mtime = base + getlong(buf + i + 1,j - i - 1); 00199 break; 00200 case 'i': 00201 fp->idtype = FTPPARSE_ID_FULL; 00202 fp->id = buf + i + 1; 00203 fp->idlen = j - i - 1; 00204 } 00205 i = j + 1; 00206 } 00207 } 00208 return 0; 00209 00210 /* UNIX-style listing, without inum and without blocks */ 00211 /* "-rw-r--r-- 1 root other 531 Jan 29 03:26 README" */ 00212 /* "dr-xr-xr-x 2 root other 512 Apr 8 1994 etc" */ 00213 /* "dr-xr-xr-x 2 root 512 Apr 8 1994 etc" */ 00214 /* "lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin" */ 00215 /* Also produced by Microsoft's FTP servers for Windows: */ 00216 /* "---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z" */ 00217 /* "d--------- 1 owner group 0 May 9 19:45 Softlib" */ 00218 /* Also WFTPD for MSDOS: */ 00219 /* "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 message.ftp" */ 00220 /* Also NetWare: */ 00221 /* "d [R----F--] supervisor 512 Jan 16 18:53 login" */ 00222 /* "- [R----F--] rhesus 214059 Oct 20 15:27 cx.exe" */ 00223 /* Also NetPresenz for the Mac: */ 00224 /* "-------r-- 326 1391972 1392298 Nov 22 1995 MegaPhone.sit" */ 00225 /* "drwxrwxr-x folder 2 May 10 1996 network" */ 00226 case 'b': 00227 case 'c': 00228 case 'd': 00229 case 'l': 00230 case 'p': 00231 case 's': 00232 case '-': 00233 00234 if (*buf == 'd') fp->flagtrycwd = 1; 00235 if (*buf == '-') fp->flagtryretr = 1; 00236 if (*buf == 'l') fp->flagtrycwd = fp->flagtryretr = 1; 00237 00238 state = 1; 00239 i = 0; 00240 for (j = 1;j < len;++j) 00241 if ((buf[j] == ' ') && (buf[j - 1] != ' ')) { 00242 switch(state) { 00243 case 1: /* skipping perm */ 00244 state = 2; 00245 break; 00246 case 2: /* skipping nlink */ 00247 state = 3; 00248 if ((j - i == 6) && (buf[i] == 'f')) /* for NetPresenz */ 00249 state = 4; 00250 break; 00251 case 3: /* skipping uid */ 00252 state = 4; 00253 break; 00254 case 4: /* getting tentative size */ 00255 size = getlong(buf + i,j - i); 00256 state = 5; 00257 break; 00258 case 5: /* searching for month, otherwise getting tentative size */ 00259 month = getmonth(buf + i,j - i); 00260 if (month >= 0) 00261 state = 6; 00262 else 00263 size = getlong(buf + i,j - i); 00264 break; 00265 case 6: /* have size and month */ 00266 mday = getlong(buf + i,j - i); 00267 state = 7; 00268 break; 00269 case 7: /* have size, month, mday */ 00270 if ((j - i == 4) && (buf[i + 1] == ':')) { 00271 hour = getlong(buf + i,1); 00272 minute = getlong(buf + i + 2,2); 00273 fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; 00274 initbase(); 00275 fp->mtime = base + guesstai(month,mday) + hour * 3600 + minute * 60; 00276 } else if ((j - i == 5) && (buf[i + 2] == ':')) { 00277 hour = getlong(buf + i,2); 00278 minute = getlong(buf + i + 3,2); 00279 fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; 00280 initbase(); 00281 fp->mtime = base + guesstai(month,mday) + hour * 3600 + minute * 60; 00282 } 00283 else if (j - i >= 4) { 00284 year = getlong(buf + i,j - i); 00285 fp->mtimetype = FTPPARSE_MTIME_REMOTEDAY; 00286 initbase(); 00287 fp->mtime = base + totai(year,month,mday); 00288 } 00289 else 00290 return 0; 00291 fp->name = buf + j + 1; 00292 fp->namelen = len - j - 1; 00293 state = 8; 00294 break; 00295 case 8: /* twiddling thumbs */ 00296 break; 00297 } 00298 i = j + 1; 00299 while ((i < len) && (buf[i] == ' ')) ++i; 00300 } 00301 00302 if (state != 8) 00303 return 0; 00304 00305 fp->size = size; 00306 fp->sizetype = FTPPARSE_SIZE_BINARY; 00307 00308 if (*buf == 'l') 00309 for (i = 0;i + 3 < fp->namelen;++i) 00310 if (fp->name[i] == ' ') 00311 if (fp->name[i + 1] == '-') 00312 if (fp->name[i + 2] == '>') 00313 if (fp->name[i + 3] == ' ') { 00314 fp->namelen = i; 00315 break; 00316 } 00317 00318 /* eliminate extra NetWare spaces */ 00319 if ((buf[1] == ' ') || (buf[1] == '[')) 00320 if (fp->namelen > 3) 00321 if (fp->name[0] == ' ') 00322 if (fp->name[1] == ' ') 00323 if (fp->name[2] == ' ') { 00324 fp->name += 3; 00325 fp->namelen -= 3; 00326 } 00327 00328 return 1; 00329 } 00330 00331 /* MultiNet (some spaces removed from examples) */ 00332 /* "00README.TXT;1 2 30-DEC-1996 17:44 [SYSTEM] (RWED,RWED,RE,RE)" */ 00333 /* "CORE.DIR;1 1 8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)" */ 00334 /* and non-MutliNet VMS: */ 00335 /* "CII-MANUAL.TEX;1 213/216 29-JAN-1996 03:33:12 [ANONYMOU,ANONYMOUS] (RWED,RWED,,)" */ 00336 for (i = 0;i < len;++i) 00337 if (buf[i] == ';') 00338 break; 00339 if (i < len) { 00340 fp->name = buf; 00341 fp->namelen = i; 00342 if (i > 4) 00343 if (buf[i - 4] == '.') 00344 if (buf[i - 3] == 'D') 00345 if (buf[i - 2] == 'I') 00346 if (buf[i - 1] == 'R') { 00347 fp->namelen -= 4; 00348 fp->flagtrycwd = 1; 00349 } 00350 if (!fp->flagtrycwd) 00351 fp->flagtryretr = 1; 00352 while (buf[i] != ' ') if (++i == len) return 0; 00353 while (buf[i] == ' ') if (++i == len) return 0; 00354 while (buf[i] != ' ') if (++i == len) return 0; 00355 while (buf[i] == ' ') if (++i == len) return 0; 00356 j = i; 00357 while (buf[j] != '-') if (++j == len) return 0; 00358 mday = getlong(buf + i,j - i); 00359 while (buf[j] == '-') if (++j == len) return 0; 00360 i = j; 00361 while (buf[j] != '-') if (++j == len) return 0; 00362 month = getmonth(buf + i,j - i); 00363 if (month < 0) return 0; 00364 while (buf[j] == '-') if (++j == len) return 0; 00365 i = j; 00366 while (buf[j] != ' ') if (++j == len) return 0; 00367 year = getlong(buf + i,j - i); 00368 while (buf[j] == ' ') if (++j == len) return 0; 00369 i = j; 00370 while (buf[j] != ':') if (++j == len) return 0; 00371 hour = getlong(buf + i,j - i); 00372 while (buf[j] == ':') if (++j == len) return 0; 00373 i = j; 00374 while ((buf[j] != ':') && (buf[j] != ' ')) if (++j == len) return 0; 00375 minute = getlong(buf + i,j - i); 00376 00377 fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; 00378 initbase(); 00379 fp->mtime = base + totai(year,month,mday) + hour * 3600 + minute * 60; 00380 00381 return 1; 00382 } 00383 00384 /* MSDOS format */ 00385 /* 04-27-00 09:09PM <DIR> licensed */ 00386 /* 07-18-00 10:16AM <DIR> pub */ 00387 /* 04-14-00 03:47PM 589 readme.htm */ 00388 if ((*buf >= '0') && (*buf <= '9')) { 00389 i = 0; 00390 j = 0; 00391 while (buf[j] != '-') if (++j == len) return 0; 00392 month = getlong(buf + i,j - i) - 1; 00393 while (buf[j] == '-') if (++j == len) return 0; 00394 i = j; 00395 while (buf[j] != '-') if (++j == len) return 0; 00396 mday = getlong(buf + i,j - i); 00397 while (buf[j] == '-') if (++j == len) return 0; 00398 i = j; 00399 while (buf[j] != ' ') if (++j == len) return 0; 00400 year = getlong(buf + i,j - i); 00401 if (year < 50) year += 2000; 00402 if (year < 1000) year += 1900; 00403 while (buf[j] == ' ') if (++j == len) return 0; 00404 i = j; 00405 while (buf[j] != ':') if (++j == len) return 0; 00406 hour = getlong(buf + i,j - i); 00407 while (buf[j] == ':') if (++j == len) return 0; 00408 i = j; 00409 while ((buf[j] != 'A') && (buf[j] != 'P')) if (++j == len) return 0; 00410 minute = getlong(buf + i,j - i); 00411 if (hour == 12) hour = 0; 00412 if (buf[j] == 'A') if (++j == len) return 0; 00413 if (buf[j] == 'P') { hour += 12; if (++j == len) return 0; } 00414 if (buf[j] == 'M') if (++j == len) return 0; 00415 00416 while (buf[j] == ' ') if (++j == len) return 0; 00417 if (buf[j] == '<') { 00418 fp->flagtrycwd = 1; 00419 while (buf[j] != ' ') if (++j == len) return 0; 00420 } 00421 else { 00422 i = j; 00423 while (buf[j] != ' ') if (++j == len) return 0; 00424 fp->size = getlong(buf + i,j - i); 00425 fp->sizetype = FTPPARSE_SIZE_BINARY; 00426 fp->flagtryretr = 1; 00427 } 00428 while (buf[j] == ' ') if (++j == len) return 0; 00429 00430 fp->name = buf + j; 00431 fp->namelen = len - j; 00432 00433 fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE; 00434 initbase(); 00435 fp->mtime = base + totai(year,month,mday) + hour * 3600 + minute * 60; 00436 00437 return 1; 00438 } 00439 00440 /* Some useless lines, safely ignored: */ 00441 /* "Total of 11 Files, 10966 Blocks." (VMS) */ 00442 /* "total 14786" (UNIX) */ 00443 /* "DISK$ANONFTP:[ANONYMOUS]" (VMS) */ 00444 /* "Directory DISK$PCSA:[ANONYM]" (VMS) */ 00445 00446 return 0; 00447 }
| static long getlong | ( | char * | buf, | |
| int | len | |||
| ) | [static] |
Definition at line 136 of file ftpparse.c.
| static int getmonth | ( | char * | buf, | |
| int | len | |||
| ) | [static] |
| static long guesstai | ( | long | month, | |
| long | mday | |||
| ) | [static] |
Definition at line 100 of file ftpparse.c.
00101 { 00102 long year; 00103 long t; 00104 00105 initnow(); 00106 00107 for (year = currentyear - 1;year < currentyear + 100;++year) { 00108 t = totai(year,month,mday); 00109 if (now - t < 350 * 86400) 00110 return t; 00111 } 00112 return 0; 00113 }
| static void initbase | ( | void | ) | [static] |
Definition at line 52 of file ftpparse.c.
00053 { 00054 struct tm *t; 00055 if (!flagneedbase) return; 00056 00057 base = 0; 00058 t = gmtime(&base); 00059 base = -(totai(t->tm_year + 1900,t->tm_mon,t->tm_mday) + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec); 00060 /* assumes the right time_t, counting seconds. */ 00061 /* base may be slightly off if time_t counts non-leap seconds. */ 00062 flagneedbase = 0; 00063 }
| static void initnow | ( | void | ) | [static] |
Definition at line 65 of file ftpparse.c.
00066 { 00067 long day; 00068 long year; 00069 00070 initbase(); 00071 now = time((time_t *) 0) - base; 00072 00073 if (flagneedcurrentyear) { 00074 day = now / 86400; 00075 if ((now % 86400) < 0) --day; 00076 day -= 11017; 00077 year = 5 + day / 146097; 00078 day = day % 146097; 00079 if (day < 0) { day += 146097; --year; } 00080 year *= 4; 00081 if (day == 146096) { year += 3; day = 36524; } 00082 else { year += day / 36524; day %= 36524; } 00083 year *= 25; 00084 year += day / 1461; 00085 day %= 1461; 00086 year *= 4; 00087 if (day == 1460) { year += 3; day = 365; } 00088 else { year += day / 365; day %= 365; } 00089 day *= 10; 00090 if ((day + 5) / 306 >= 10) ++year; 00091 currentyear = year; 00092 flagneedcurrentyear = 0; 00093 } 00094 }
| static long totai | ( | long | year, | |
| long | month, | |||
| long | mday | |||
| ) | [static] |
Definition at line 26 of file ftpparse.c.
00027 { 00028 long result; 00029 if (month >= 2) month -= 2; 00030 else { month += 10; --year; } 00031 result = (mday - 1) * 10 + 5 + 306 * month; 00032 result /= 10; 00033 if (result == 365) { year -= 3; result = 1460; } 00034 else result += 365 * (year % 4); 00035 year /= 4; 00036 result += 1461 * (year % 25); 00037 year /= 25; 00038 if (result == 36524) { year -= 3; result = 146096; } 00039 else { result += 36524 * (year % 4); } 00040 year /= 4; 00041 result += 146097 * (year - 5); 00042 result += 11017; 00043 return result * 86400; 00044 }
time_t base [static] |
Definition at line 47 of file ftpparse.c.
long currentyear [static] |
Definition at line 50 of file ftpparse.c.
int flagneedbase = 1 [static] |
Definition at line 46 of file ftpparse.c.
int flagneedcurrentyear = 1 [static] |
Definition at line 49 of file ftpparse.c.
char* months[12] [static] |
{
"jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"
}
Definition at line 123 of file ftpparse.c.
long now [static] |
Definition at line 48 of file ftpparse.c.
1.6.1