diff --git a/test/uudecode.c b/test/uudecode.c index ce00cd0..7f2770c 100644 --- a/test/uudecode.c +++ b/test/uudecode.c @@ -2,11 +2,16 @@ #include "textcode.h" #include "str.h" #include "buffer.h" +#include "open.h" int main(int argc,char* argv[]) { char buf[4096]; + char obuf[4096]; buffer filein; + buffer fileout; int fd=1; + int ofd=-1; + unsigned long mode=0,lineno=0; if (argc>1) { fd=open_read(argv[1]); if (fd<0) { @@ -25,21 +30,57 @@ int main(int argc,char* argv[]) { buffer_putsflush(buffer_2,"warning: hit end of file without finding any uuencoded data!\n"); return 0; } - if (l>0 && buf[l-1]=='\r') --l; /* kill DOS line endings */ - buf[l]=0; - if (!str_diffn(line,"begin ",6)) break; + ++lineno; + if (l>0 && line[l-1]=='\r') --l; /* kill DOS line endings */ + line[l]=0; + if (!str_diffn(line,"begin ",6)) { + if (line[l=6+scan_8long(line+6,&mode)]==' ' && mode) { + int i; + ++l; + if (line[l+(i=str_rchr(line+l,'/'))]) l+=i+1; + while (line[l]=='.') ++l; + if (line[l]) { + ofd=open_excl(line+l); + if (ofd<0) { + buffer_puts(buffer_2,"error: could not create file \""); + buffer_puts(buffer_2,line+l); + buffer_putsflush(buffer_2,"\" (must not exist yet)\n"); + } else break; + } + } + } } + buffer_init(&fileout,write,ofd,buf,sizeof buf); /* read uuencoded lines */ for (;;) { char line[1000]; /* uuencoded lines can never be longer than 64 characters */ + unsigned int scanned,x; + char tmp[100]; int l; if ((l=buffer_getline(&filein,line,(sizeof line)-1))==0) { buffer_putsflush(buffer_2,"warning: hit end of file without finding \"end\"!\n"); return 0; } - if (l>0 && buf[l-1]=='\r') --l; /* kill DOS line endings */ - buf[l]=0; - if (!str_diffn(line,"begin ",6)) break; + ++lineno; + if (l>0 && line[l-1]=='\r') --l; /* kill DOS line endings */ + line[l]=0; + x=scan_uuencoded(line,tmp,&scanned); + if (!x) { + if (str_equal(line,"end")) { + buffer_flush(&fileout); + fchmod(ofd,mode); + close(ofd); + return 0; + } else { +parseerror: + buffer_puts(buffer_1,"parse error in line "); + buffer_putulong(buffer_1,lineno); + buffer_puts(buffer_1,": \""); + buffer_puts(buffer_1,line); + buffer_putsflush(buffer_1,"\"\n"); + exit(1); + } + } + buffer_put(&fileout,tmp,scanned); } - /* TODO */ } diff --git a/textcode/scan_uuencoded.c b/textcode/scan_uuencoded.c index 245a3ba..13e38b0 100644 --- a/textcode/scan_uuencoded.c +++ b/textcode/scan_uuencoded.c @@ -6,7 +6,7 @@ unsigned int scan_uuencoded(const char *src,char *dest,unsigned int *destlen) { unsigned long tmp; register const unsigned char* s=(const unsigned char*) src; const char* orig=dest; - if ((len=*s-' ')>64) return 0; + if ((len=*s-' ')>64) return 0; len&=63; ++s; while (len>0) { if (s[0]-' '>64 || s[1]-' '>64 || s[2]-' '>64 || s[3]-' '>64) return 0;