The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ftpparse.c File Reference
#include <ftpparse.h>
+ Include dependency graph for ftpparse.c:

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
 

Function Documentation

static int check ( char *  buf,
char *  monthname 
)
static

Definition at line 115 of file ftpparse.c.

116 {
117  if ((buf[0] != monthname[0]) && (buf[0] != monthname[0] - 32)) return 0;
118  if ((buf[1] != monthname[1]) && (buf[1] != monthname[1] - 32)) return 0;
119  if ((buf[2] != monthname[2]) && (buf[2] != monthname[2] - 32)) return 0;
120  return 1;
121 }
int ftpparse ( struct ftpparse fp,
char *  buf,
int  len 
)

Definition at line 144 of file ftpparse.c.

145 {
146  int i;
147  int j;
148  int state;
149  long size = 0;
150  long year;
151  long month = 0;
152  long mday = 0;
153  long hour;
154  long minute;
155 
156  fp->name = 0;
157  fp->namelen = 0;
158  fp->flagtrycwd = 0;
159  fp->flagtryretr = 0;
161  fp->size = 0;
163  fp->mtime = 0;
165  fp->id = 0;
166  fp->idlen = 0;
167 
168  if (len < 2) /* an empty name in EPLF, with no info, could be 2 chars */
169  return 0;
170 
171  switch(*buf) {
172  /* see http://pobox.com/~djb/proto/eplf.txt */
173  /* "+i8388621.29609,m824255902,/,\tdev" */
174  /* "+i8388621.44468,m839956783,r,s10376,\tRFCEPLF" */
175  case '+':
176  i = 1;
177  for (j = 1;j < len;++j) {
178  if (buf[j] == 9) {
179  fp->name = buf + j + 1;
180  fp->namelen = len - j - 1;
181  return 1;
182  }
183  if (buf[j] == ',') {
184  switch(buf[i]) {
185  case '/':
186  fp->flagtrycwd = 1;
187  break;
188  case 'r':
189  fp->flagtryretr = 1;
190  break;
191  case 's':
193  fp->size = getlong(buf + i + 1,j - i - 1);
194  break;
195  case 'm':
197  initbase();
198  fp->mtime = base + getlong(buf + i + 1,j - i - 1);
199  break;
200  case 'i':
201  fp->idtype = FTPPARSE_ID_FULL;
202  fp->id = buf + i + 1;
203  fp->idlen = j - i - 1;
204  }
205  i = j + 1;
206  }
207  }
208  return 0;
209 
210  /* UNIX-style listing, without inum and without blocks */
211  /* "-rw-r--r-- 1 root other 531 Jan 29 03:26 README" */
212  /* "dr-xr-xr-x 2 root other 512 Apr 8 1994 etc" */
213  /* "dr-xr-xr-x 2 root 512 Apr 8 1994 etc" */
214  /* "lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin" */
215  /* Also produced by Microsoft's FTP servers for Windows: */
216  /* "---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z" */
217  /* "d--------- 1 owner group 0 May 9 19:45 Softlib" */
218  /* Also WFTPD for MSDOS: */
219  /* "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 message.ftp" */
220  /* Also NetWare: */
221  /* "d [R----F--] supervisor 512 Jan 16 18:53 login" */
222  /* "- [R----F--] rhesus 214059 Oct 20 15:27 cx.exe" */
223  /* Also NetPresenz for the Mac: */
224  /* "-------r-- 326 1391972 1392298 Nov 22 1995 MegaPhone.sit" */
225  /* "drwxrwxr-x folder 2 May 10 1996 network" */
226  case 'b':
227  case 'c':
228  case 'd':
229  case 'l':
230  case 'p':
231  case 's':
232  case '-':
233 
234  if (*buf == 'd') fp->flagtrycwd = 1;
235  if (*buf == '-') fp->flagtryretr = 1;
236  if (*buf == 'l') fp->flagtrycwd = fp->flagtryretr = 1;
237 
238  state = 1;
239  i = 0;
240  for (j = 1;j < len;++j)
241  if ((buf[j] == ' ') && (buf[j - 1] != ' ')) {
242  switch(state) {
243  case 1: /* skipping perm */
244  state = 2;
245  break;
246  case 2: /* skipping nlink */
247  state = 3;
248  if ((j - i == 6) && (buf[i] == 'f')) /* for NetPresenz */
249  state = 4;
250  break;
251  case 3: /* skipping uid */
252  state = 4;
253  break;
254  case 4: /* getting tentative size */
255  size = getlong(buf + i,j - i);
256  state = 5;
257  break;
258  case 5: /* searching for month, otherwise getting tentative size */
259  month = getmonth(buf + i,j - i);
260  if (month >= 0)
261  state = 6;
262  else
263  size = getlong(buf + i,j - i);
264  break;
265  case 6: /* have size and month */
266  mday = getlong(buf + i,j - i);
267  state = 7;
268  break;
269  case 7: /* have size, month, mday */
270  if ((j - i == 4) && (buf[i + 1] == ':')) {
271  hour = getlong(buf + i,1);
272  minute = getlong(buf + i + 2,2);
274  initbase();
275  fp->mtime = base + guesstai(month,mday) + hour * 3600 + minute * 60;
276  } else if ((j - i == 5) && (buf[i + 2] == ':')) {
277  hour = getlong(buf + i,2);
278  minute = getlong(buf + i + 3,2);
280  initbase();
281  fp->mtime = base + guesstai(month,mday) + hour * 3600 + minute * 60;
282  }
283  else if (j - i >= 4) {
284  year = getlong(buf + i,j - i);
286  initbase();
287  fp->mtime = base + totai(year,month,mday);
288  }
289  else
290  return 0;
291  fp->name = buf + j + 1;
292  fp->namelen = len - j - 1;
293  state = 8;
294  break;
295  case 8: /* twiddling thumbs */
296  break;
297  }
298  i = j + 1;
299  while ((i < len) && (buf[i] == ' ')) ++i;
300  }
301 
302  if (state != 8)
303  return 0;
304 
305  fp->size = size;
307 
308  if (*buf == 'l')
309  for (i = 0;i + 3 < fp->namelen;++i)
310  if (fp->name[i] == ' ')
311  if (fp->name[i + 1] == '-')
312  if (fp->name[i + 2] == '>')
313  if (fp->name[i + 3] == ' ') {
314  fp->namelen = i;
315  break;
316  }
317 
318  /* eliminate extra NetWare spaces */
319  if ((buf[1] == ' ') || (buf[1] == '['))
320  if (fp->namelen > 3)
321  if (fp->name[0] == ' ')
322  if (fp->name[1] == ' ')
323  if (fp->name[2] == ' ') {
324  fp->name += 3;
325  fp->namelen -= 3;
326  }
327 
328  return 1;
329  }
330 
331  /* MultiNet (some spaces removed from examples) */
332  /* "00README.TXT;1 2 30-DEC-1996 17:44 [SYSTEM] (RWED,RWED,RE,RE)" */
333  /* "CORE.DIR;1 1 8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)" */
334  /* and non-MutliNet VMS: */
335  /* "CII-MANUAL.TEX;1 213/216 29-JAN-1996 03:33:12 [ANONYMOU,ANONYMOUS] (RWED,RWED,,)" */
336  for (i = 0;i < len;++i)
337  if (buf[i] == ';')
338  break;
339  if (i < len) {
340  fp->name = buf;
341  fp->namelen = i;
342  if (i > 4)
343  if (buf[i - 4] == '.')
344  if (buf[i - 3] == 'D')
345  if (buf[i - 2] == 'I')
346  if (buf[i - 1] == 'R') {
347  fp->namelen -= 4;
348  fp->flagtrycwd = 1;
349  }
350  if (!fp->flagtrycwd)
351  fp->flagtryretr = 1;
352  while (buf[i] != ' ') if (++i == len) return 0;
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  j = i;
357  while (buf[j] != '-') if (++j == len) return 0;
358  mday = getlong(buf + i,j - i);
359  while (buf[j] == '-') if (++j == len) return 0;
360  i = j;
361  while (buf[j] != '-') if (++j == len) return 0;
362  month = getmonth(buf + i,j - i);
363  if (month < 0) return 0;
364  while (buf[j] == '-') if (++j == len) return 0;
365  i = j;
366  while (buf[j] != ' ') if (++j == len) return 0;
367  year = getlong(buf + i,j - i);
368  while (buf[j] == ' ') if (++j == len) return 0;
369  i = j;
370  while (buf[j] != ':') if (++j == len) return 0;
371  hour = getlong(buf + i,j - i);
372  while (buf[j] == ':') if (++j == len) return 0;
373  i = j;
374  while ((buf[j] != ':') && (buf[j] != ' ')) if (++j == len) return 0;
375  minute = getlong(buf + i,j - i);
376 
378  initbase();
379  fp->mtime = base + totai(year,month,mday) + hour * 3600 + minute * 60;
380 
381  return 1;
382  }
383 
384  /* MSDOS format */
385  /* 04-27-00 09:09PM <DIR> licensed */
386  /* 07-18-00 10:16AM <DIR> pub */
387  /* 04-14-00 03:47PM 589 readme.htm */
388  if ((*buf >= '0') && (*buf <= '9')) {
389  i = 0;
390  j = 0;
391  while (buf[j] != '-') if (++j == len) return 0;
392  month = getlong(buf + i,j - i) - 1;
393  while (buf[j] == '-') if (++j == len) return 0;
394  i = j;
395  while (buf[j] != '-') if (++j == len) return 0;
396  mday = getlong(buf + i,j - i);
397  while (buf[j] == '-') if (++j == len) return 0;
398  i = j;
399  while (buf[j] != ' ') if (++j == len) return 0;
400  year = getlong(buf + i,j - i);
401  if (year < 50) year += 2000;
402  if (year < 1000) year += 1900;
403  while (buf[j] == ' ') if (++j == len) return 0;
404  i = j;
405  while (buf[j] != ':') if (++j == len) return 0;
406  hour = getlong(buf + i,j - i);
407  while (buf[j] == ':') if (++j == len) return 0;
408  i = j;
409  while ((buf[j] != 'A') && (buf[j] != 'P')) if (++j == len) return 0;
410  minute = getlong(buf + i,j - i);
411  if (hour == 12) hour = 0;
412  if (buf[j] == 'A') if (++j == len) return 0;
413  if (buf[j] == 'P') { hour += 12; if (++j == len) return 0; }
414  if (buf[j] == 'M') if (++j == len) return 0;
415 
416  while (buf[j] == ' ') if (++j == len) return 0;
417  if (buf[j] == '<') {
418  fp->flagtrycwd = 1;
419  while (buf[j] != ' ') if (++j == len) return 0;
420  }
421  else {
422  i = j;
423  while (buf[j] != ' ') if (++j == len) return 0;
424  fp->size = getlong(buf + i,j - i);
426  fp->flagtryretr = 1;
427  }
428  while (buf[j] == ' ') if (++j == len) return 0;
429 
430  fp->name = buf + j;
431  fp->namelen = len - j;
432 
434  initbase();
435  fp->mtime = base + totai(year,month,mday) + hour * 3600 + minute * 60;
436 
437  return 1;
438  }
439 
440  /* Some useless lines, safely ignored: */
441  /* "Total of 11 Files, 10966 Blocks." (VMS) */
442  /* "total 14786" (UNIX) */
443  /* "DISK$ANONFTP:[ANONYMOUS]" (VMS) */
444  /* "Directory DISK$PCSA:[ANONYM]" (VMS) */
445 
446  return 0;
447 }
#define FTPPARSE_MTIME_REMOTEDAY
Definition: ftpparse.h:41
char * id
Definition: ftpparse.h:30
static long totai(long year, long month, long mday)
Definition: ftpparse.c:26
int flagtrycwd
Definition: ftpparse.h:23
char * name
Definition: ftpparse.h:21
int mtimetype
Definition: ftpparse.h:27
int idlen
Definition: ftpparse.h:31
#define FTPPARSE_MTIME_UNKNOWN
Definition: ftpparse.h:38
#define FTPPARSE_SIZE_UNKNOWN
Definition: ftpparse.h:34
static long getlong(char *buf, int len)
Definition: ftpparse.c:136
int sizetype
Definition: ftpparse.h:25
int namelen
Definition: ftpparse.h:22
int flagtryretr
Definition: ftpparse.h:24
#define FTPPARSE_ID_FULL
Definition: ftpparse.h:49
#define FTPPARSE_MTIME_LOCAL
Definition: ftpparse.h:39
static long guesstai(long month, long mday)
Definition: ftpparse.c:100
int size
Definition: regex.c:5043
time_t mtime
Definition: ftpparse.h:28
static int getmonth(char *buf, int len)
Definition: ftpparse.c:127
int idtype
Definition: ftpparse.h:29
#define FTPPARSE_SIZE_BINARY
Definition: ftpparse.h:35
static void initbase(void)
Definition: ftpparse.c:52
#define FTPPARSE_ID_UNKNOWN
Definition: ftpparse.h:48
long size
Definition: ftpparse.h:26
#define FTPPARSE_MTIME_REMOTEMINUTE
Definition: ftpparse.h:40
static time_t base
Definition: ftpparse.c:47
static long getlong ( char *  buf,
int  len 
)
static

Definition at line 136 of file ftpparse.c.

137 {
138  long u = 0;
139  while (len-- > 0)
140  u = u * 10 + (*buf++ - '0');
141  return u;
142 }
static int getmonth ( char *  buf,
int  len 
)
static

Definition at line 127 of file ftpparse.c.

128 {
129  int i;
130  if (len == 3)
131  for (i = 0;i < 12;++i)
132  if (check(buf,months[i])) return i;
133  return -1;
134 }
static int check(char *buf, char *monthname)
Definition: ftpparse.c:115
static char * months[12]
Definition: ftpparse.c:123
static long guesstai ( long  month,
long  mday 
)
static

Definition at line 100 of file ftpparse.c.

101 {
102  long year;
103  long t;
104 
105  initnow();
106 
107  for (year = currentyear - 1;year < currentyear + 100;++year) {
108  t = totai(year,month,mday);
109  if (now - t < 350 * 86400)
110  return t;
111  }
112  return 0;
113 }
static long totai(long year, long month, long mday)
Definition: ftpparse.c:26
static long now
Definition: ftpparse.c:48
static long currentyear
Definition: ftpparse.c:50
static void initnow(void)
Definition: ftpparse.c:65
static void initbase ( void  )
static

Definition at line 52 of file ftpparse.c.

53 {
54  struct tm *t;
55  if (!flagneedbase) return;
56 
57  base = 0;
58  t = gmtime(&base);
59  base = -(totai(t->tm_year + 1900,t->tm_mon,t->tm_mday) + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec);
60  /* assumes the right time_t, counting seconds. */
61  /* base may be slightly off if time_t counts non-leap seconds. */
62  flagneedbase = 0;
63 }
static long totai(long year, long month, long mday)
Definition: ftpparse.c:26
static int flagneedbase
Definition: ftpparse.c:46
static time_t base
Definition: ftpparse.c:47
static void initnow ( void  )
static

Definition at line 65 of file ftpparse.c.

66 {
67  long day;
68  long year;
69 
70  initbase();
71  now = time((time_t *) 0) - base;
72 
73  if (flagneedcurrentyear) {
74  day = now / 86400;
75  if ((now % 86400) < 0) --day;
76  day -= 11017;
77  year = 5 + day / 146097;
78  day = day % 146097;
79  if (day < 0) { day += 146097; --year; }
80  year *= 4;
81  if (day == 146096) { year += 3; day = 36524; }
82  else { year += day / 36524; day %= 36524; }
83  year *= 25;
84  year += day / 1461;
85  day %= 1461;
86  year *= 4;
87  if (day == 1460) { year += 3; day = 365; }
88  else { year += day / 365; day %= 365; }
89  day *= 10;
90  if ((day + 5) / 306 >= 10) ++year;
91  currentyear = year;
93  }
94 }
static int flagneedcurrentyear
Definition: ftpparse.c:49
static long now
Definition: ftpparse.c:48
static long currentyear
Definition: ftpparse.c:50
static void initbase(void)
Definition: ftpparse.c:52
static time_t base
Definition: ftpparse.c:47
static long totai ( long  year,
long  month,
long  mday 
)
static

Definition at line 26 of file ftpparse.c.

27 {
28  long result;
29  if (month >= 2) month -= 2;
30  else { month += 10; --year; }
31  result = (mday - 1) * 10 + 5 + 306 * month;
32  result /= 10;
33  if (result == 365) { year -= 3; result = 1460; }
34  else result += 365 * (year % 4);
35  year /= 4;
36  result += 1461 * (year % 25);
37  year /= 25;
38  if (result == 36524) { year -= 3; result = 146096; }
39  else { result += 36524 * (year % 4); }
40  year /= 4;
41  result += 146097 * (year - 5);
42  result += 11017;
43  return result * 86400;
44 }
result
Definition: regex.c:5545

Variable Documentation

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
Initial value:
= {
"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.