home *** CD-ROM | disk | FTP | other *** search
- /*
- * VEC.C (VEC)
- *
- * Copyright (c) 1991, 1992, 1993 Ville Saari
- * All rights reserved
- *
- * Created: 18-Dec-91
- * Updated: 04-Dec-93
- */
-
- #include "vec.h"
-
- const static struct
- {
- unsigned char uuencodetab[4];
- unsigned char encodetab[182];
- } tabs=
- {
- /* characters used by uuencode method: */
-
- 96, 33, 34, 35,
-
- /* characters used by all methods: */
-
- 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
- 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
- 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
-
- /* characters used by all but uuencode method */
-
- 96, 97, 98, 99,
-
- /* characters used by >=6.5 bit methods: */
-
- 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
- 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
-
- /* characters used by >=7 bit methods: */
-
- 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
- 171, 172, 173, 174, 175, 176, 177, 178, 179, 180,
- 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
- 191, 192, 193, 194, 195, 196, 197,
-
- /* characters used by 7.5 bit method: */
-
- 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
- 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
- 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
- 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
- 238, 239, 240, 241, 242, 243, 244, 245, 246, 247,
- 248, 249, 250, 251
- };
-
- static const unsigned char hextab[]=
- {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
- };
-
- #define uuencodetab tabs.uuencodetab
- #define encodetab tabs.encodetab
-
- static int lineleft;
-
- static void sevenandhalfbitcoder(const unsigned char *i, unsigned char *o)
- {
- const unsigned char *j=i+8;
- unsigned int z;
-
- z=(*i++|*j++<<8)&0x7fff;
- *o++=encodetab[z%182];
- *o++=encodetab[z/182];
-
- z=(*i++|*j++<<8)&0x7fff;
- *o++=encodetab[z%182];
- *o++=encodetab[z/182];
-
- z=(*i++|*j++<<8)&0x7fff;
- *o++=encodetab[z%182];
- *o++=encodetab[z/182];
-
- z=(*i++|*j++<<8)&0x7fff;
- *o++=encodetab[z%182];
- *o++=encodetab[z/182];
-
- z=(*i++|*j++<<8)&0x7fff;
- *o++=encodetab[z%182];
- *o++=encodetab[z/182];
-
- z=(*i++|*j++<<8)&0x7fff;
- *o++=encodetab[z%182];
- *o++=encodetab[z/182];
-
- z=(*i++|*j <<8)&0x7fff;
- *o++=encodetab[z%182];
- *o++=encodetab[z/182];
-
- z=*i++;
- z|=(*i++&0x80)<<1;
- z|=(*i++&0x80)<<2;
- z|=(*i++&0x80)<<3;
- z|=(*i++&0x80)<<4;
- z|=(*i++&0x80)<<5;
- z|=(*i++&0x80)<<6;
- z|=(*i &0x80)<<7;
- *o++=encodetab[z%182];
- *o =encodetab[z/182];
- }
-
- static void sevenbitcoder(const unsigned char *i, unsigned char *o)
- {
- unsigned int z;
- unsigned char c;
-
- *o++=encodetab[(c=*i++)&0x7f]; z=c>>7;
- *o++=encodetab[(c=*i++)&0x7f]; z|=(c&0x80)>>6;
- *o++=encodetab[(c=*i++)&0x7f]; z|=(c&0x80)>>5;
- *o++=encodetab[(c=*i++)&0x7f]; z|=(c&0x80)>>4;
- *o++=encodetab[(c=*i++)&0x7f]; z|=(c&0x80)>>3;
- *o++=encodetab[(c=*i++)&0x7f]; z|=(c&0x80)>>2;
- *o++=encodetab[(c=*i )&0x7f]; z|=(c&0x80)>>1;
- *o =encodetab[z];
- }
-
- static void sixandhalfbitcoder(const unsigned char *i, unsigned char *o)
- {
- const unsigned char *j=i+8;
- unsigned int z;
-
- z=*i++|((*j++&0x1f)<<8);
- *o++=encodetab[z%91];
- *o++=encodetab[z/91];
-
- z=*i++|((*j++&0x1f)<<8);
- *o++=encodetab[z%91];
- *o++=encodetab[z/91];
-
- z=*i++|((*j++&0x1f)<<8);
- *o++=encodetab[z%91];
- *o++=encodetab[z/91];
-
- z=*i++|((*j++&0x1f)<<8);
- *o++=encodetab[z%91];
- *o++=encodetab[z/91];
-
- z=*i++|((*j &0x1f)<<8);
- *o++=encodetab[z%91];
- *o++=encodetab[z/91];
-
- j-=4;
- z=*i++|((j[0]&0xe0)<<3)|((j[3]&0x60)<<6);
- *o++=encodetab[z%91];
- *o++=encodetab[z/91];
-
- j++;
- z=*i++|((j[0]&0xe0)<<3)|((j[3]&0x60)<<6);
- *o++=encodetab[z%91];
- *o++=encodetab[z/91];
-
- j++;
- z=*i |((j[0]&0xe0)<<3)|((j[1]&0x80)<<4)|((j[2]&0x80)<<5);
- *o++=encodetab[z%91];
- *o =encodetab[z/91];
- }
-
- static void sixbitcoder(const unsigned char *i, unsigned char *o)
- {
- *o++=encodetab[*i++&0x3f];
- *o++=encodetab[*i++&0x3f];
- *o++=encodetab[*i++&0x3f];
- *o++=encodetab[*i++&0x3f];
- *o++=encodetab[*i++&0x3f];
- *o++=encodetab[*i &0x3f];
-
- i-=5;
-
- {
- unsigned int z;
-
- z=*i++>>6;
- z|=(*i++&0xc0)>>4;
- z|=(*i++&0xc0)>>2;
- *o++=encodetab[z];
-
- z=*i++>>6;
- z|=(*i++&0xc0)>>4;
- z|=(*i &0xc0)>>2;
- *o=encodetab[z];
- }
- }
-
- static void hexcoder(const unsigned char *i, unsigned char *o)
- {
- *o++=hextab[*i>>4&0xf];
- *o =hextab[*i &0xf];
- }
-
- static char *stox(unsigned short s)
- {
- static char buf[5];
- unsigned char t;
-
- t=(char)(s>>8);
- hexcoder(&t, buf);
-
- t=(char)s;
- hexcoder(&t, buf+2);
-
- return buf;
- }
-
- static void uucoder(const unsigned char *i, unsigned char *o)
- {
- unsigned int t, u;
-
- *o++=uuencodetab[ (t=*i++)>>2 ];
- *o++=uuencodetab[t<<4&0x30|(u=*i++)>>4&0xf];
- *o++=uuencodetab[u<<2&0x3c|(t=*i )>>6&0x3];
- *o =uuencodetab[t &0x3f ];
- }
-
- static void newline(void)
- {
- if(cr) put1(13);
- put1(10);
-
- lineleft=width;
- }
-
- static void breakput(const unsigned char *block, int size)
- {
- for(;;)
- {
- if((lineleft-=size)>=0)
- {
- put(block, size);
- return;
- }
-
- put(block, lineleft+size);
-
- block+=lineleft+size;
- size=-lineleft;
-
- newline();
- }
- }
-
- static void addbreaks(unsigned long size)
- {
- while(lineleft<size)
- {
- outptr+=lineleft;
- size-=lineleft;
- lineleft=width;
-
- if(cr)
- {
- unsigned int b=size;
- char *f=outptr+b;
- char *t=f+2;
-
- while(b--) *--t=*--f;
-
- *outptr++=13;
- }
- else
- {
- unsigned int b=size;
- char *f=outptr+b;
- char *t=f+1;
-
- while(b--) *--t=*--f;
- }
-
- *outptr++=10;
- }
-
- outptr+=size;
- lineleft-=size;
-
- if(outptr>=outbufend) flushoutput();
- }
-
- #define checkeol(n) { if(lineleft<=n && (lineleft<n || next!=10)) \
- { put1(94); newline(); } lineleft-=n; }
-
- static void asciiencode(void)
- {
- unsigned char current, next;
- unsigned short crc=0;
- int eof=0, iso=method=='i';
-
- if(inptr>=inbufend && !fillbuffer(1))
- {
- eof=1;
- next=0;
- }
- else
- next=*inptr++;
-
- while(!eof)
- {
- current=next;
-
- if(inptr>=inbufend && !fillbuffer(1))
- {
- eof=1;
- next=0;
- }
- else
- next=*inptr++;
-
- if(!quick) crc=(crc>>8)^crc16tab[(unsigned char)(crc^current)];
-
- if(current==10 && shortlines || !lineleft)
- newline();
- else if(current<32 && (!literaltabs || current!=9))
- {
- if(lineleft<=3)
- if(current==10 && (lineleft<3 || next<32 && next!=10 ||
- next==92 || next==94 || next>127 && (!iso || next<160)))
- {
- newline();
- continue;
- }
- else if(lineleft<2 || lineleft==2 && next!=10)
- {
- put1(94);
- newline();
- }
-
- lineleft-=2;
- put1(94);
- put1(current+64);
- }
- else if((current==92 && !iso) || current==94 &&
- (next<32 || next>(iso?60:58) && (!iso || next<160 || next==255) ||
- next==33 || lineleft<3))
- {
- checkeol(2);
- put1(94);
- put1(current==92?60:61);
- }
- else if(current<127 || iso && current>=160)
- {
- checkeol(1);
- put1(current);
- }
- else
- {
- checkeol(2);
-
- if(current==255)
- {
- put1(94);
- put1(59);
- }
- else if(current>=160)
- {
- put1(92);
- put1(current+128);
- }
- else if(current==127)
- {
- put1(94);
- put1(63);
- }
- else if(current==159)
- {
- put1(94);
- put1(62);
- }
- else
- {
- put1(94);
- put1(current-32);
- }
- }
- }
-
- breakput("^!", 2);
-
- if(!quick)
- breakput(stox(crc), 4);
- }
-
- static void uuencode(const char *filename)
- {
- unsigned char flagbuf[3]={'6', '0', '0'};
- unsigned char outbuf[62], *inbuf, *i, *o, *l;
- unsigned long size=0;
-
- if(filename && !nomode) getfilemode(filename, flagbuf, 1);
-
- put("begin ", 6);
- put(flagbuf, 3);
- put(" ", 1);
-
- if(name) filename=name;
- filename=basename(filename);
- if(!*filename) filename="noname";
-
- put(filename, strlen(filename));
- newline();
-
- do {
- i=inbuf=get(45);
- o=outbuf;
- *o++=uuencodetab[trueread];
-
- l=i+trueread;
-
- while(i<l)
- {
- uucoder(i, o);
- i+=3;
- o+=4;
- }
-
- if(!quick)
- {
- unsigned int s=0;
-
- i=inbuf;
-
- while(i<l)
- {
- s+=*i++;
- s+=*i++;
- s+=*i++;
- }
-
- *o++=uuencodetab[s&0x3F];
- size+=trueread;
- }
-
- put(outbuf, o-outbuf);
- newline();
- }
- while(trueread);
-
- put("end", 3);
- newline();
-
- if(!quick)
- {
- char *t=ltoa(size);
-
- put("size ", 5);
- put(t, strlen(t));
- newline();
- }
- }
-
- void vec(const char *filename)
- {
- unsigned char flagbuf[6], outblockbuf[16], *indata;
- int inblock, outblock;
- unsigned short crc=0;
- void (*coder)(const unsigned char *, unsigned char *)=0;
-
- flagbuf[0]=!quick;
- flagbuf[1]=flagbuf[2]=flagbuf[3]=flagbuf[4]=flagbuf[5]=0;
-
- if(filename && !nomode)
- getfilemode(filename, flagbuf, 0);
-
- if(name) filename=name;
- filename=basename(filename);
-
- if(!silent && *filename)
- {
- printerr(filename);
- printerr("\n");
- }
-
- if(!*filename) filename="noname";
-
- if(method=='u')
- {
- uuencode(filename);
- return;
- }
-
- if(!quick) flagbuf[0]|=1;
-
- sixbitcoder(flagbuf, outblockbuf);
-
- put("yobufi", 6);
- put(&method, 1);
- put(outblockbuf, 8);
- put(filename, strlen(filename));
- newline();
-
- switch(method)
- {
- case '3':
- coder=sevenandhalfbitcoder;
- inblock=15;
- outblock=16;
- break;
-
- case '2':
- coder=sevenbitcoder;
- inblock=7;
- outblock=8;
- break;
-
- case '1':
- coder=sixandhalfbitcoder;
- inblock=13;
- outblock=16;
- break;
-
- case '0':
- coder=sixbitcoder;
- inblock=6;
- outblock=8;
- break;
-
- case 'x':
- coder=hexcoder;
- inblock=1;
- outblock=2;
- }
-
- if(coder)
- {
- while(indata=get(inblock), trueread)
- {
- coder(indata, outptr);
- addbreaks(outblock);
-
- if(!quick)
- {
- unsigned int datainblock=trueread;
- unsigned char *t=indata;
-
- while(datainblock--)
- crc=(crc>>8)^crc16tab[(unsigned char)(crc^*t++)];
- }
-
- if(trueread<inblock) break;
- }
-
- if(!trueread) trueread=inblock;
-
- breakput("!", 1);
- breakput(hextab+inblock-trueread, 1);
-
- if(!quick)
- breakput(stox(crc), 4);
- }
- else
- asciiencode();
-
- newline();
- }
-