Annotation of sbbs/src/sbbs3/uucode.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.