From dd2d9119fc009d3cb447a1901b856617b01eb523 Mon Sep 17 00:00:00 2001 From: leitner Date: Sun, 15 Sep 2002 22:45:51 +0000 Subject: [PATCH] comment typo in byte.h byte_rchr did not work at all (oops) uudecode now handles yenc (a little) --- byte.h | 2 +- byte/byte_rchr.c | 8 ++-- t.c | 5 +++ test/uudecode.c | 98 ++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 100 insertions(+), 13 deletions(-) diff --git a/byte.h b/byte.h index e598124..b1df0ee 100644 --- a/byte.h +++ b/byte.h @@ -8,7 +8,7 @@ #endif /* byte_chr returns the smallest integer i between 0 and len-1 - * inclusive such that one[i] equals needle, or len it not found. */ + * inclusive such that one[i] equals needle, or len if not found. */ unsigned int byte_chr(const void* haystack, unsigned int len, char needle) __pure__; /* byte_rchr returns the largest integer i between 0 and len-1 inclusive diff --git a/byte/byte_rchr.c b/byte/byte_rchr.c index 3b5b58c..221816d 100644 --- a/byte/byte_rchr.c +++ b/byte/byte_rchr.c @@ -7,10 +7,10 @@ unsigned int byte_rchr(const void* haystack,unsigned int len,char needle) { register const char* s=haystack; register const char* t=s+len; for (;;) { - --t; if (s<=t) break; if (*t==c) break; - --t; if (s<=t) break; if (*t==c) break; - --t; if (s<=t) break; if (*t==c) break; - --t; if (s<=t) break; if (*t==c) break; + --t; if (s>=t) break; if (*t==c) break; + --t; if (s>=t) break; if (*t==c) break; + --t; if (s>=t) break; if (*t==c) break; + --t; if (s>=t) break; if (*t==c) break; } return t-s; } diff --git a/t.c b/t.c index e412b58..d629a47 100644 --- a/t.c +++ b/t.c @@ -9,6 +9,7 @@ #include "ip4.h" #include "mmap.h" #include "open.h" +#include "byte.h" #include "textcode.h" #include #include @@ -17,6 +18,9 @@ __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") int main(int argc,char* argv[]) { + char buf[100]="foo bar baz"; + printf("%d (expect 7)\n",byte_rchr(buf,11,' ')); +#if 0 unsigned long size; char* buf=mmap_read(argv[1],&size); if (buf) { @@ -26,6 +30,7 @@ int main(int argc,char* argv[]) { y=fmt_yenc(tmp,buf,size); write(1,tmp,x); } +#endif #if 0 char buf[100]; char buf2[100]; diff --git a/test/uudecode.c b/test/uudecode.c index 38656da..ceebfbd 100644 --- a/test/uudecode.c +++ b/test/uudecode.c @@ -1,4 +1,5 @@ #include +#include #include "textcode.h" #include "str.h" #include "buffer.h" @@ -11,11 +12,15 @@ int main(int argc,char* argv[]) { buffer fileout; int fd=0; int ofd=-1; + int broken_encoder=0; int found=0; char line[1000]; /* uuencoded lines can never be longer than 64 characters */ int l; enum { BEFOREBEGIN, AFTERBEGIN, SKIPHEADER } state=BEFOREBEGIN; - unsigned long mode=0,lineno=0; + enum { UUDECODE, YENC } mode=UUDECODE; + unsigned long fmode=0,lineno=0; + unsigned long offset,endoffset,totalsize,linelen; /* used only for yenc */ + if (argc>1) { fd=open_read(argv[1]); if (fd<0) { @@ -36,7 +41,7 @@ again: buffer_putsflush(buffer_1,"!\n"); if (ofd>=0) { buffer_flush(&fileout); - fchmod(ofd,mode); + fchmod(ofd,fmode); close(ofd); } ++found; @@ -55,15 +60,17 @@ again: buffer_putsflush(buffer_1,"!\n"); if (ofd>=0) { buffer_flush(&fileout); - fchmod(ofd,mode); + fchmod(ofd,fmode); close(ofd); } ++found; } state=BEFOREBEGIN; - if (line[l=6+scan_8long(line+6,&mode)]==' ' && mode) { + if (line[l=6+scan_8long(line+6,&fmode)]==' ' && fmode) { int i; ++l; + mode=UUDECODE; +foundfilename: if (line[l]=='"') { int m; ++l; @@ -72,7 +79,10 @@ again: if (line[l+(i=str_rchr(line+l,'/'))]) l+=i+1; while (line[l]=='.') ++l; if (line[l]) { - ofd=open_excl(line+l); + if (mode==YENC) + ofd=open_write(line+l); + else + ofd=open_excl(line+l); if (ofd<0) { buffer_puts(buffer_2,"error: could not create file \""); buffer_puts(buffer_2,line+l); @@ -90,7 +100,62 @@ again: } else if (str_equal(line,"end")) { if (ofd>=0) { buffer_flush(&fileout); - fchmod(ofd,mode); + fchmod(ofd,fmode); + close(ofd); + ofd=-1; + } + ++found; + state=BEFOREBEGIN; + continue; + } else if (str_start(line,"=ybegin ")) { + char* filename=strstr(line," name="); + if (!filename) { +invalidybegin: + buffer_puts(buffer_2,"invalid =ybegin at line "); + buffer_putulong(buffer_2,lineno); + buffer_putsflush(buffer_2,".\n"); + continue; + } + l=filename-line+6; + if (!(filename=strstr(line," size="))) goto invalidybegin; + if (filename[6+scan_ulong(filename+6,&totalsize)] != ' ') goto invalidybegin; + if (!(filename=strstr(line," line="))) goto invalidybegin; + if (filename[6+scan_ulong(filename+6,&linelen)] != ' ') goto invalidybegin; + mode=YENC; + goto foundfilename; + } else if (str_start(line,"=ypart ")) { + char* tmp=strstr(line," begin="); + char c; + if (!tmp) { +invalidpart: + buffer_puts(buffer_2,"invalid =ypart at line "); + buffer_putulong(buffer_2,lineno); + buffer_putsflush(buffer_2,".\n"); + continue; + } + c=tmp[7+scan_ulong(tmp+7,&offset)]; + if (c!=' ' && c!=0) goto invalidpart; + if (!(tmp=strstr(line," end="))) goto invalidpart; + c=tmp[5+scan_ulong(tmp+5,&endoffset)]; + if (c!=' ' && c!=0) goto invalidpart; + --offset; endoffset; + if (endoffsettotalsize) goto invalidpart; + lseek(ofd,offset,SEEK_SET); + continue; + } else if (str_start(line,"=yend")) { + unsigned long cur; + if (ofd>=0) { + off_t rlen; + buffer_flush(&fileout); + rlen=lseek(ofd,0,SEEK_CUR)-offset; + if (rlen != endoffset-offset) { + int toomuch=rlen-(endoffset-offset); + buffer_puts(buffer_2,"warning: part size "); + buffer_putulong(buffer_2,rlen); + buffer_puts(buffer_2,", expected "); + buffer_putulong(buffer_2,endoffset-offset); + buffer_putsflush(buffer_2,"!\n"); + } close(ofd); ofd=-1; } @@ -102,8 +167,25 @@ again: state=SKIPHEADER; } else { unsigned int scanned,x; - char tmp[100]; - x=scan_uuencoded(line,tmp,&scanned); + char tmp[300]; + switch (mode) { + case UUDECODE: x=scan_uuencoded(line,tmp,&scanned); break; + case YENC: + /* work around broken yenc encoders */ + if ((line[0]=='.' && line[1]=='.') || + (line[0]=='>' && line[1]=='.')) { + if (l>linelen && line[l-2]!='=') { + if (!broken_encoder) { + broken_encoder=1; + buffer_putsflush(buffer_2,"compensating for broken encoder...\n"); + } + x=scan_yenc(line+1,tmp,&scanned); + break; + } + } + x=scan_yenc(line,tmp,&scanned); + break; + } if (!x) { if (state==AFTERBEGIN) { buffer_puts(buffer_1,"parse error in line ");