int calendar_spec_normalize(CalendarSpec *c) { assert(c); if (streq_ptr(c->timezone, "UTC")) { c->utc = true; c->timezone = mfree(c->timezone); } if (c->weekdays_bits <= 0 || c->weekdays_bits >= BITS_WEEKDAYS) c->weekdays_bits = -1; if (c->end_of_month && !c->day) c->end_of_month = false; fix_year(c->year); normalize_chain(&c->year); normalize_chain(&c->month); normalize_chain(&c->day); normalize_chain(&c->hour); normalize_chain(&c->minute); normalize_chain(&c->microsecond); return 0; }
static int parse_supertcp(struct ftpparse *f, char *p[], int l[], unsigned int count) { unsigned long mon; unsigned long day; unsigned long year; unsigned long hour; unsigned long min; unsigned long sec; int mtimetype; uint64 size=0; /* optional, dirs */ int x; int dir=0; /* CMT <DIR> 11-21-94 10:17 */ /* DESIGN1.DOC 11264 05-11-95 14:20 */ if (count<4) return 0; x=scan_time(p[3],l[3],&hour,&min,&sec,&mtimetype); if (x!=l[3]) return 0; x=get_ulong(p[2],l[2],&mon); if (x!=2 || p[2][x]!='-') return 0; x++; x+=get_ulong(p[2]+x,l[2]-x,&day); if (x!=5 || p[2][x]!='-') return 0; x++; x+=get_ulong(p[2]+x,l[2]-x,&year); if ((x!=8 && x!=10) || p[2][x]!=' ') return 0; if (!fix_year(&year)) return 0; if (my_byte_equal(p[1],5,"<DIR>")) dir=1; else { x=get_uint64(p[1],l[1],&size); if (!x || p[1][x]!=' ') return 0; } f->name=p[0]; f->namelen=l[0]; f->size=size; if (!dir) f->sizetype=FTPPARSE_SIZE_BINARY; utcdate2tai (&f->mtime,year,mon,day,hour,min,sec); f->mtimetype=mtimetype; if (dir) f->flagtrycwd=1; else f->flagtryretr=1; return 1; }
int calendar_spec_normalize(CalendarSpec *c) { assert(c); if (c->weekdays_bits <= 0 || c->weekdays_bits >= 127) c->weekdays_bits = -1; fix_year(c->year); sort_chain(&c->year); sort_chain(&c->month); sort_chain(&c->day); sort_chain(&c->hour); sort_chain(&c->minute); sort_chain(&c->second); return 0; }
int calendar_spec_normalize(CalendarSpec *c) { assert(c); if (c->weekdays_bits <= 0 || c->weekdays_bits >= BITS_WEEKDAYS) c->weekdays_bits = -1; if (c->end_of_month && !c->day) c->end_of_month = false; fix_year(c->year); normalize_chain(&c->year); normalize_chain(&c->month); normalize_chain(&c->day); normalize_chain(&c->hour); normalize_chain(&c->minute); normalize_chain(&c->microsecond); return 0; }
/* another bright re-invention of a broken wheel from the people, who * made an art of it. */ static int parse_os2(struct ftpparse *f, char *p[], int l[], unsigned int count) { /* 0 DIR 04-11-95 16:26 ADDRESS * 612 A 07-28-95 16:45 air_tra1.bag * 310992 06-28-94 09:56 INSTALL.EXE */ unsigned long mon; unsigned long day; unsigned long year; unsigned long hour; unsigned long min; unsigned long sec; int mtimetype; uint64 size; int x; unsigned int i; int dir=0; if (count<4) return 0; x=get_uint64(p[0],l[0],&size); if (!x || p[0][x]!=' ') return 0; for (i=1; i<count-2; i++) { x=get_ulong(p[i],l[i],&mon); if (!x) continue; if (x!=2 || p[i][x]!='-') return 0; mon-=1; x++; x+=get_ulong(p[i]+x,l[i]-x,&day); if (x!=5 || p[i][x]!='-') return 0; x++; x+=get_ulong(p[i]+x,l[i]-x,&year); if (x!=8 || p[i][x]!=' ') return 0; if (!fix_year(&year)) return 0; break; } if (i>1) if (my_byte_equal(p[i-1],3,"DIR")) dir=1; i++; if (i==count) return 0; x=scan_time(p[i],l[i],&hour,&min,&sec,&mtimetype); if (x!=l[i]) return 0; i++; if (i==count) return 0; f->name=p[i]; f->namelen=l[i]; if (dir) { f->flagtrycwd=1; } else { f->flagtryretr=1; f->sizetype=FTPPARSE_SIZE_BINARY; f->size=size; } utcdate2tai (&f->mtime,year,mon,day,hour,min,sec); f->mtimetype=mtimetype; return 1; }
static int parse_unix(struct ftpparse *f, char *buf, int len, char *p[], int l[], unsigned int count) { /* the horror ... */ /* this list has been taken from Daniel Bernsteins ftpparse.c */ /* 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" */ /*restructured: */ /* -PERM 1 user group 531 Jan 29 03:26 README */ /* dPERM 2 user group 512 Apr 8 1994 etc */ /* dPERM 2 user 512 Apr 8 1994 etc */ /* lPERM 1 user group 7 Jan 25 00:17 bin -> usr/bin */ /* -PERM 1 user group 1803128 Jul 10 10:18 ls-lR.Z */ /* dPERM 1 user group 0 May 9 19:45 Softlib */ /* -PERM 1 user group 322 Aug 19 1996 message.ftp */ /* d [R----F--] user 512 Jan 16 18:53 login */ /* - [R----F--] user 214059 Oct 20 15:27 cx.exe */ /* -PERM 326 NUMB NUMBER Nov 22 1995 MegaPhone.sit */ /* dPERM folder 2 May 10 1996 network */ /* handled as: */ /* dPERM folder 2 May 10 1996 network */ /* 0 1 2 3 4 5 6 7 8 */ /* note the date system: MON DAY [YEAR|TIME] */ int mon=-1; /* keep gcc quiet */ unsigned long day; unsigned long year; unsigned long hour; unsigned long min; unsigned long sec; uint64 size; int flagtrycwd=0; int flagtryretr=0; unsigned int i; int x; int mtimetype; int may_have_size=0; switch(p[0][0]) { case 'd': flagtrycwd=1; break; case '-': flagtryretr=1; break; case 'l': flagtryretr=flagtrycwd=1; break; } i=3; if (l[1]==6 && my_byte_equal(p[1],l[1],"folder")) i=2; x=get_uint64(p[i],l[i],&size); if (x==l[i]) may_have_size=1; i++; while (i<count) { mon=get_month(p[i],l[i]); if (-1==mon) { /* may be size */ x=get_uint64(p[i],l[i],&size); if (x==l[i]) may_have_size=1; } i++; if (-1!=mon) break; } if (i==count) return 0; x=get_ulong(p[i],l[i],&day); if (!x) return 0; if (p[i][x]!=' ') return 0; if (++i==count) return 0; x=get_ulong(p[i],l[i],&year); if (!x) return 0; if (p[i][x]==':') { x=scan_time(p[i],l[i],&hour,&min,&sec,&mtimetype); if (x!=l[i]) return 0; year=guess_year(mon,day); } else { mtimetype=FTPPARSE_MTIME_REMOTEDAY; hour=min=sec=0; /* may be this case: */ /* - [-RWCE-F-] mlm 11820 Feb 3 93 12:00 drivers.doc */ if (i+2<count) { x=scan_time(p[i+1],l[i+1],&hour,&min,&sec,&mtimetype); if (x!=l[i+1]) { hour=min=sec=0; mtimetype=FTPPARSE_MTIME_REMOTEDAY; } else i++; } if (!fix_year(&year)) return 0; } if (++i==count) return 0; /* note: dosplit eats spaces - but we need them here. So go back. */ f->name=p[i]; f->namelen=buf+len-p[i]; /* "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 message.ftp" */ /* "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 spacy" */ /* but: */ /* "d [R----F--] supervisor 512 Jan 16 18:53 login" */ if (p[0][1]!=' ') { while (f->name[-2]==' ') { f->name--; f->namelen++; } } if (may_have_size) { f->sizetype=FTPPARSE_SIZE_BINARY; f->size=size; } f->flagtryretr=flagtryretr; f->flagtrycwd=flagtrycwd; utcdate2tai (&f->mtime,year,mon,day,hour,min,sec); f->mtimetype=mtimetype; f->format=FTPPARSE_FORMAT_LS; /* for programs dealing with symlinks */ if ('l'==*buf) { unsigned int j; for (j=1;j<f->namelen-4;j++) /* 1, -4: no empty names, please */ if (f->name[j]==' ' && f->name[j+1]=='-' && f->name[j+2]=='>' && f->name[j+3]==' ') { f->symlink=f->name+j+4; f->symlinklen=f->namelen-j-4; f->namelen=j; break; } } return 1; }
static int parse_multinet(struct ftpparse *f, char *p[], int l[], unsigned int count) { /* "CORE.DIR;1 1 8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)" */ /* "[VMSSERV.FILES]ALARM.DIR;1 1/3 5-MAR-1993 18:09:" */ int mon; unsigned long day; unsigned long year; unsigned long hour; unsigned long min; unsigned long sec; int mtimetype; int x; char *q; int m; if (count<4) return 0; q=p[2]; m=l[2]; x=get_ulong(q,m,&day); if (!x || x>2 || day>31) return 0; if (q[x] != '-') return 0; q+=x+1; m-=x+1; mon=get_month(q,m); if (-1==mon) return 0; if (q[3]!='-') return 0; q+=4; if (m<5) return 0; m-=4; x=get_ulong(q,m,&year); if (!x || q[x]!=' ') return 0; if (!fix_year(&year)) return 0; x=scan_time(p[3],l[3],&hour,&min,&sec,&mtimetype); if (x!=l[3]) return 0; f->mtimetype = mtimetype;; utcdate2tai (&f->mtime,year,mon,day,hour,min,sec); for (x=0;x<l[0];x++) if (p[0][x]==';') break; if (x>4) if (p[0][x-4]=='.' && p[0][x-3]=='D' && p[0][x-2]=='I' && p[0][x-1]=='R') { x-=4; f->flagtrycwd=1; } if (!f->flagtrycwd) f->flagtryretr=1; f->namelen=x; f->name=p[0]; if (f->name[0]=='[') { /* [dir]file.maybe */ unsigned int y; for (y=1;y<f->namelen;y++) if (f->name[y]==']') break; if (y!=f->namelen) y++; /* skip ] */ if (y!=f->namelen) { f->name+=y; f->namelen-=y; } } return 1; }
/* note the mon-day-year! */ static int parse_msdos(struct ftpparse *f, char *buf, unsigned int len) { unsigned int pos,start; unsigned int state; unsigned long mon; unsigned long day; unsigned long year; unsigned long hour; unsigned long min; unsigned long sec; int mtimetype; unsigned int x; uint64 size=0; unsigned int flagtrycwd=0; unsigned int flagtryretr=0; int maxspaces=0; /* to keep leading spaces before dir/file name */ for (state=start=pos=0;pos<len;pos++) { switch(state) { case 0: /* month */ if ('-'==buf[pos]) { state++; if (pos==start) return 0; if (get_ulong(buf+start,pos-start,&mon)!=pos-start) return 0; start=pos+1; } break; case 1: /* day */ if ('-'==buf[pos]) { state++; if (pos==start) return 0; if (get_ulong(buf+start,pos-start,&day)!=pos-start) return 0; start=pos+1; } break; case 2: /* year */ if (' '==buf[pos]) { state++; if (pos-start!=2 && pos-start!=4) return 0; if (get_ulong(buf+start,pos-start,&year)!=pos-start) return 0; start=pos+1; if (!fix_year(&year)) return 0; } break; case 3: /* spaces */ if (' ' == buf[pos]) continue; state++; start=pos; /* FALL THROUGH */ case 4: /* time */ x=scan_time(buf+start,len-pos,&hour,&min,&sec,&mtimetype); if (!x) return 0; pos+=x; if (pos==len) return 0; state++; break; case 5: /* spaces */ if (' ' == buf[pos]) continue; state++; start=pos; /* FALL THROUGH */ case 6: /* <DIR> or length */ if (' ' == buf[pos]) { if (get_uint64(buf+start,pos-start,&size)!=pos-start) { if (pos-start < 5 || !my_byte_equal(buf+start,5,"<DIR>")) return 0; flagtrycwd=1; maxspaces=10; } else { flagtryretr=1; maxspaces=1; } state++; start=pos; } break; case 7: /* spaces */ if (' ' == buf[pos]) if (--maxspaces) continue; state++; start=pos; /* FALL THROUGH */ case 8: /* file / dir name */ f->name=buf+start; f->namelen=len-pos; f->flagtrycwd=flagtrycwd; f->flagtryretr=flagtryretr; f->mtimetype=mtimetype; if (flagtryretr) { f->size=size; f->sizetype=FTPPARSE_SIZE_BINARY; } if (!fix_year(&year)) return 0; utcdate2tai(&f->mtime,year,mon-1,day,hour,min,sec); return 1; } } return 0; }