|
|
1.1 ! root 1: /* uucode.c */ ! 2: ! 3: /* Unix-to-unix encoding/decoding routines */ ! 4: ! 5: /* $Id: uucode.c,v 1.4 2004/04/08 05:21:32 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include <stdio.h> ! 39: #include <stdlib.h> ! 40: #include <string.h> ! 41: #include <ctype.h> ! 42: #include "uucode.h" ! 43: ! 44: int uudecode(char *target, size_t tlen, const char *source, size_t slen) ! 45: { ! 46: int i; ! 47: char ch; ! 48: size_t rd=0; ! 49: size_t wr=0; ! 50: size_t block; ! 51: size_t len; ! 52: unsigned char cell[4]; ! 53: ! 54: if(slen==0) ! 55: slen=strlen(source); ! 56: while(rd<slen && wr<tlen) { ! 57: ch=source[rd++]; ! 58: if(ch<' ') ! 59: continue; ! 60: len=(ch-' ')&0x3f; ! 61: if(len<=0 || rd>=slen) ! 62: break; ! 63: block=0; ! 64: while(block<len && wr<tlen && rd<slen) { ! 65: memset(cell,0,sizeof(cell)); ! 66: /* Remove space bias */ ! 67: for(i=0;i<sizeof(cell) && rd<slen;i++) { ! 68: cell[i]=source[rd++]; ! 69: if(cell[i]>=' ') cell[i]-=' '; ! 70: } ! 71: /* Convert block of 4 6-bit chars into 3 8-bit chars */ ! 72: target[wr]=(cell[0]&0x3f)<<2; /* lower 6 (s1) to upper 6 (d1) */ ! 73: target[wr++]|=(cell[1]&0x30)>>4; /* upper 2 (s2) to lower 2 (d1) */ ! 74: target[wr]=(cell[1]&0x0f)<<4; /* lower 4 (s2) to upper 4 (d2) */ ! 75: target[wr++]|=(cell[2]&0x3c)>>2; /* upper 4 (s3) to lower 4 (d2) */ ! 76: target[wr]=(cell[2]&0x03)<<6; /* lower 2 (s3) to upper 2 (d3) */ ! 77: target[wr++]|=cell[3]&0x3f; /* lower 6 (s4) to lower 6 (d3) */ ! 78: block+=3; ! 79: } ! 80: #if 0 ! 81: if(block!=len) { ! 82: fprintf(stderr,"block (%d) != len (%d)\n",block,len); ! 83: return(-1); ! 84: } ! 85: #endif ! 86: while(rd<slen && source[rd]>' ') ! 87: rd++; /* find whitespace (line termination) */ ! 88: while(rd<slen && source[rd]!=0 && source[rd]<=' ') ! 89: rd++; /* skip whitespace separating blocks/lines */ ! 90: } ! 91: ! 92: return(wr); ! 93: } ! 94: ! 95: #define BIAS(b) if((b)==0) (b)='`'; else (b)+=' '; ! 96: ! 97: int uuencode(char *target, size_t tlen, const char *source, size_t slen) ! 98: { ! 99: size_t rd=0; ! 100: size_t wr=0; ! 101: size_t block; ! 102: size_t len; ! 103: ! 104: if(slen==0) ! 105: slen=strlen(source); ! 106: ! 107: if(tlen<3) ! 108: return(-1); ! 109: tlen-=3; /* reserve room for terminator */ ! 110: while(rd<=slen && wr<tlen) { ! 111: len=45; ! 112: if(rd+len>slen) ! 113: len=slen-rd; ! 114: BIAS(len); ! 115: target[wr++]=len; ! 116: ! 117: block=0; ! 118: while(block<len && wr<tlen && rd<slen) { ! 119: target[wr]=source[rd]>>2; /* upper 6 (s1) to lower 6 (d1) */ ! 120: BIAS(target[wr]); wr++; ! 121: target[wr]=(source[rd++]&0x03)<<4; /* lower 2 (s1) to upper 2 (d2) */ ! 122: target[wr]|=source[rd]>>4; /* upper 4 (s2) to lower 4 (d2) */ ! 123: BIAS(target[wr]); wr++; ! 124: target[wr]=(source[rd++]&0x0f)<<2; /* lower 4 (s2) to upper 4 (d3) */ ! 125: target[wr]|=source[rd]>>6; /* upper 2 (s3) to lower 2 (d3) */ ! 126: BIAS(target[wr]); wr++; ! 127: target[wr]=source[rd++]&0x3f; /* lower 6 (s3) to lower 6 (d4) */ ! 128: BIAS(target[wr]); wr++; ! 129: block+=3; ! 130: } ! 131: if(wr<tlen) { ! 132: target[wr++]='\r'; ! 133: target[wr++]='\n'; ! 134: } ! 135: if(rd>=slen) ! 136: break; ! 137: } ! 138: ! 139: if(wr<tlen) ! 140: target[wr++]=0; ! 141: return(wr); ! 142: } ! 143: ! 144: #ifdef UUDECODE_TEST ! 145: ! 146: static char* truncstr(char* str, const char* set) ! 147: { ! 148: char* p; ! 149: ! 150: p=strpbrk(str,set); ! 151: if(p!=NULL) ! 152: *p=0; ! 153: ! 154: return(p); ! 155: } ! 156: ! 157: int main(int argc, char**argv) ! 158: { ! 159: char str[1024]; ! 160: char buf[256]; ! 161: char* p; ! 162: FILE* in; ! 163: FILE* out=NULL; ! 164: int len; ! 165: int line; ! 166: ! 167: if(argc<2) { ! 168: fprintf(stderr,"usage: uudecode infile\n"); ! 169: return 1; ! 170: } ! 171: ! 172: if((in=fopen(argv[1],"rb"))==NULL) { ! 173: perror(argv[1]); ! 174: return 1; ! 175: } ! 176: ! 177: while(!feof(in)) { ! 178: memset(str,0,sizeof(str)); ! 179: if(fgets(str,sizeof(str),in)==NULL) ! 180: break; ! 181: truncstr(str,"\r\n"); ! 182: if(strncmp(str,"begin ",6)==0) { ! 183: p=str+7; ! 184: while(*p && isdigit(*p)) p++; /* skip mode */ ! 185: while(*p && *p<=' ') p++; ! 186: if((out=fopen(p,"wb"))==NULL) { ! 187: perror(p); ! 188: return 1; ! 189: } ! 190: fprintf(stderr,"Creating %s\n",p); ! 191: line=1; ! 192: continue; ! 193: } ! 194: if(strcmp(str,"end")==0) { ! 195: if(out!=NULL) { ! 196: fclose(out); ! 197: out=NULL; ! 198: } ! 199: continue; ! 200: } ! 201: if(out==NULL) ! 202: continue; ! 203: len=uudecode(buf,sizeof(buf),str,0); ! 204: if(len<0) { ! 205: fprintf(stderr,"!Error decoding: %s\n",str); ! 206: break; ! 207: } ! 208: fwrite(buf,len,1,out); ! 209: line++; ! 210: } ! 211: ! 212: return 0; ! 213: } ! 214: #elif defined(UUENCODE_TEST) ! 215: ! 216: int main(int argc, char**argv) ! 217: { ! 218: char str[1024]; ! 219: char buf[256]; ! 220: FILE* in; ! 221: int len; ! 222: ! 223: if(argc<2) { ! 224: fprintf(stderr,"usage: uuencode infile\n"); ! 225: return 1; ! 226: } ! 227: ! 228: if((in=fopen(argv[1],"rb"))==NULL) { ! 229: perror(argv[1]); ! 230: return 1; ! 231: } ! 232: ! 233: while(!feof(in)) { ! 234: len=fread(buf,1,45,in); ! 235: if(len<0) ! 236: break; ! 237: len=uuencode(str,sizeof(str),buf,len); ! 238: if(len<1) ! 239: break; ! 240: printf("%.*s",len,str); ! 241: } ! 242: ! 243: return 0; ! 244: } ! 245: ! 246: #endif ! 247: ! 248:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.