27 static long totai(
long year,
long month,
long mday)
30 if (month >= 2) month -= 2;
31 else { month += 10; --year; }
32 result = (mday - 1) * 10 + 5 + 306 * month;
34 if (result == 365) { year -= 3; result = 1460; }
35 else result += 365 * (year % 4);
37 result += 1461 * (year % 25);
39 if (result == 36524) { year -= 3; result = 146096; }
40 else { result += 36524 * (year % 4); }
42 result += 146097 * (year - 5);
44 return result * 86400;
47 static int flagneedbase = 1;
50 static int flagneedcurrentyear = 1;
51 static long currentyear;
53 static void initbase(
void)
56 if (!flagneedbase)
return;
60 base = -(totai(t->tm_year + 1900,t->tm_mon,t->tm_mday) + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec);
66 static void initnow(
void)
72 now = time((time_t *) 0) - base;
74 if (flagneedcurrentyear) {
76 if ((now % 86400) < 0) --day;
78 year = 5 + day / 146097;
80 if (day < 0) { day += 146097; --year; }
82 if (day == 146096) { year += 3; day = 36524; }
83 else { year += day / 36524; day %= 36524; }
88 if (day == 1460) { year += 3; day = 365; }
89 else { year += day / 365; day %= 365; }
91 if ((day + 5) / 306 >= 10) ++year;
93 flagneedcurrentyear = 0;
101 static long guesstai(
long month,
long mday)
108 for (year = currentyear - 1;year < currentyear + 100;++year) {
109 t = totai(year,month,mday);
110 if (now - t < 350 * 86400)
116 static int check(
char *buf,
const char *monthname)
118 if ((buf[0] != monthname[0]) && (buf[0] != monthname[0] - 32))
return 0;
119 if ((buf[1] != monthname[1]) && (buf[1] != monthname[1] - 32))
return 0;
120 if ((buf[2] != monthname[2]) && (buf[2] != monthname[2] - 32))
return 0;
124 static const char *months[12] = {
125 "jan",
"feb",
"mar",
"apr",
"may",
"jun",
"jul",
"aug",
"sep",
"oct",
"nov",
"dec"
128 static int getmonth(
char *buf,
int len)
132 for (i = 0;i < 12;++i)
133 if (check(buf,months[i]))
return i;
137 static long getlong(
char *buf,
int len)
141 u = u * 10 + (*buf++ -
'0');
161 fp->sizetype = FTPPARSE_SIZE_UNKNOWN;
163 fp->mtimetype = FTPPARSE_MTIME_UNKNOWN;
165 fp->idtype = FTPPARSE_ID_UNKNOWN;
178 for (j = 1;j < len;++j) {
180 fp->name = buf + j + 1;
181 fp->namelen = len - j - 1;
193 fp->sizetype = FTPPARSE_SIZE_BINARY;
194 fp->size = getlong(buf + i + 1,j - i - 1);
197 fp->mtimetype = FTPPARSE_MTIME_LOCAL;
199 fp->mtime = base + getlong(buf + i + 1,j - i - 1);
202 fp->idtype = FTPPARSE_ID_FULL;
203 fp->id = buf + i + 1;
204 fp->idlen = j - i - 1;
235 if (*buf ==
'd') fp->flagtrycwd = 1;
236 if (*buf ==
'-') fp->flagtryretr = 1;
237 if (*buf ==
'l') fp->flagtrycwd = fp->flagtryretr = 1;
241 for (j = 1;j < len;++j)
242 if ((buf[j] ==
' ') && (buf[j - 1] !=
' ')) {
249 if ((j - i == 6) && (buf[i] ==
'f'))
256 size = getlong(buf + i,j - i);
260 month = getmonth(buf + i,j - i);
264 size = getlong(buf + i,j - i);
267 mday = getlong(buf + i,j - i);
271 if ((j - i == 4) && (buf[i + 1] ==
':')) {
272 hour = getlong(buf + i,1);
273 minute = getlong(buf + i + 2,2);
274 fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE;
276 fp->mtime = base + guesstai(month,mday) + hour * 3600 + minute * 60;
277 }
else if ((j - i == 5) && (buf[i + 2] ==
':')) {
278 hour = getlong(buf + i,2);
279 minute = getlong(buf + i + 3,2);
280 fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE;
282 fp->mtime = base + guesstai(month,mday) + hour * 3600 + minute * 60;
284 else if (j - i >= 4) {
285 year = getlong(buf + i,j - i);
286 fp->mtimetype = FTPPARSE_MTIME_REMOTEDAY;
288 fp->mtime = base + totai(year,month,mday);
292 fp->name = buf + j + 1;
293 fp->namelen = len - j - 1;
300 while ((i < len) && (buf[i] ==
' ')) ++i;
307 fp->sizetype = FTPPARSE_SIZE_BINARY;
310 for (i = 0;i + 3 < fp->namelen;++i)
311 if (fp->name[i] ==
' ')
312 if (fp->name[i + 1] ==
'-')
313 if (fp->name[i + 2] ==
'>')
314 if (fp->name[i + 3] ==
' ') {
320 if ((buf[1] ==
' ') || (buf[1] ==
'['))
322 if (fp->name[0] ==
' ')
323 if (fp->name[1] ==
' ')
324 if (fp->name[2] ==
' ') {
337 for (i = 0;i < len;++i)
344 if (buf[i - 4] ==
'.')
345 if (buf[i - 3] ==
'D')
346 if (buf[i - 2] ==
'I')
347 if (buf[i - 1] ==
'R') {
353 while (buf[i] !=
' ')
if (++i == len)
return 0;
354 while (buf[i] ==
' ')
if (++i == len)
return 0;
355 while (buf[i] !=
' ')
if (++i == len)
return 0;
356 while (buf[i] ==
' ')
if (++i == len)
return 0;
358 while (buf[j] !=
'-')
if (++j == len)
return 0;
359 mday = getlong(buf + i,j - i);
360 while (buf[j] ==
'-')
if (++j == len)
return 0;
362 while (buf[j] !=
'-')
if (++j == len)
return 0;
363 month = getmonth(buf + i,j - i);
364 if (month < 0)
return 0;
365 while (buf[j] ==
'-')
if (++j == len)
return 0;
367 while (buf[j] !=
' ')
if (++j == len)
return 0;
368 year = getlong(buf + i,j - i);
369 while (buf[j] ==
' ')
if (++j == len)
return 0;
371 while (buf[j] !=
':')
if (++j == len)
return 0;
372 hour = getlong(buf + i,j - i);
373 while (buf[j] ==
':')
if (++j == len)
return 0;
375 while ((buf[j] !=
':') && (buf[j] !=
' '))
if (++j == len)
return 0;
376 minute = getlong(buf + i,j - i);
378 fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE;
380 fp->mtime = base + totai(year,month,mday) + hour * 3600 + minute * 60;
389 if ((*buf >=
'0') && (*buf <=
'9')) {
392 while (buf[j] !=
'-')
if (++j == len)
return 0;
393 month = getlong(buf + i,j - i) - 1;
394 while (buf[j] ==
'-')
if (++j == len)
return 0;
396 while (buf[j] !=
'-')
if (++j == len)
return 0;
397 mday = getlong(buf + i,j - i);
398 while (buf[j] ==
'-')
if (++j == len)
return 0;
400 while (buf[j] !=
' ')
if (++j == len)
return 0;
401 year = getlong(buf + i,j - i);
402 if (year < 50) year += 2000;
403 if (year < 1000) year += 1900;
404 while (buf[j] ==
' ')
if (++j == len)
return 0;
406 while (buf[j] !=
':')
if (++j == len)
return 0;
407 hour = getlong(buf + i,j - i);
408 while (buf[j] ==
':')
if (++j == len)
return 0;
410 while ((buf[j] !=
'A') && (buf[j] !=
'P'))
if (++j == len)
return 0;
411 minute = getlong(buf + i,j - i);
412 if (hour == 12) hour = 0;
413 if (buf[j] ==
'A')
if (++j == len)
return 0;
414 if (buf[j] ==
'P') { hour += 12;
if (++j == len)
return 0; }
415 if (buf[j] ==
'M')
if (++j == len)
return 0;
417 while (buf[j] ==
' ')
if (++j == len)
return 0;
420 while (buf[j] !=
' ')
if (++j == len)
return 0;
424 while (buf[j] !=
' ')
if (++j == len)
return 0;
425 fp->size = getlong(buf + i,j - i);
426 fp->sizetype = FTPPARSE_SIZE_BINARY;
429 while (buf[j] ==
' ')
if (++j == len)
return 0;
432 fp->namelen = len - j;
434 fp->mtimetype = FTPPARSE_MTIME_REMOTEMINUTE;
436 fp->mtime = base + totai(year,month,mday) + hour * 3600 + minute * 60;