⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uud.c

📁 操作系统源代码
💻 C
字号:
/* uud - bulletproof version of uudecode *//* * Uud -- decode a uuencoded file back to binary form. * * From the Berkeley original, modified by MSD, RDR, JPHD & WLS. * The Atari GEMDOS version compiled with MWC 2.x. * The MSDOS version with TurboC. * The Unix version with cc. * this version is made: 25 Nov 1988. * Jan 2 1990: Change system definition and change MSDOS to open the output *             file for write binary do cr/lf replacement. */#define UNIX  1		/* define one of: UNIX (Minix too!), MSDOS, or GEMDOS */ #ifdef GEMDOS#define SYSNAME "gemdos"#define SMALL 1#endif#ifdef MSDOS#define SYSNAME "msdos"#define SMALL 1#endif#ifdef UNIX#define SYSNAME "unix"#endif#include <sys/types.h>#include <stdarg.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <sys/stat.h>#include <stdio.h>#ifdef GEMDOS#include <osbind.h>#define Error(n)  { Bconin(2); exit(n); }#else#define Error(n)  exit(n)#endif#ifdef UNIX#define WRITE	  "w"#else#define WRITE	  "wb"		/* for both MSDOS and GEMDOS!	*/#endif#define loop	while (1)#define NCHARS  256#define LINELEN 256#define FILELEN 64#define NORMLEN 60	/* allows for 80 encoded chars per line */#define SEQMAX 'z'#define SEQMIN 'a'char seqc;int first, secnd, check, numl;FILE *in, *out;char *pos;char ifname[FILELEN], ofname[FILELEN];char *source = NULL, *target = NULL;char blank, part = '\0';int partn, lens;int debug = 0, nochk = 0, onedone = 0;int chtbl[NCHARS], cdlen[NORMLEN + 3];_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(char *getnword, (char *str, int n));_PROTOTYPE(void gettable, (void));_PROTOTYPE(void decode, (void));_PROTOTYPE(void getfile, (char *buf));_PROTOTYPE(void format, (char *fp, ...));_PROTOTYPE(void doprnt, (char *fp, char *ap));_PROTOTYPE(void puti, (unsigned int i, unsigned int r));_PROTOTYPE(void outc, (int c));int main(argc, argv) int argc; char *argv[];{	int mode;	register int i, j;	char *curarg;	char dest[FILELEN], buf[LINELEN];	while ((curarg = argv[1]) != NULL && curarg[0] == '-') {		if (((curarg[1] == 'd') || (curarg[1] == 'D')) &&		    (curarg[2] == '\0')) {			debug = 1;		} else if (((curarg[1] == 'n') || (curarg[1] == 'N')) &&			   (curarg[2] == '\0')) {			nochk = 1;		} else if (((curarg[1] == 't') || (curarg[1] == 'T')) &&			   (curarg[2] == '\0')) {			argv++;			argc--;			if (argc < 2) {				format("uud: Missing target directory.\n");				Error(15);			}			target = argv[1];			if (debug)				format("Target dir = %s\n",target);		} else if (((curarg[1] == 's') || (curarg[1] == 'S')) &&			   (curarg[2] == '\0')) {			argv++;			argc--;			if (argc < 2) {				format("uud: Missing source directory.\n");				Error(15);			}			source = argv[1];			if (debug)				format("Source dir = %s\n",source);		} else if (curarg[1] != '\0') {			format("Usage: uud [-n] [-d] [-s dir] [-t dir] [input-file]\n");			Error(1);		} else			break;		argv++;		argc--;	}	if (curarg == NULL || ((curarg[0] == '-') && (curarg[1] == '\0'))) {		in = stdin;		strcpy(ifname, "<stdin>");	} else {		if (source != NULL) {			strcpy(ifname, source);			strcat(ifname, curarg);		} else			strcpy(ifname, curarg);		if ((in = fopen(ifname, "r")) == NULL) {			format("uud: Can't open %s\n", ifname);			Error(2);		}		numl = 0;	}/* * Set up the default translation table. */	for (i = 0; i < ' '; i++) chtbl[i] = -1;	for (i = ' ', j = 0; i < ' ' + 64; i++, j++) chtbl[i] = j;	for (i = ' ' + 64; i < NCHARS; i++) chtbl[i] = -1;	chtbl['`'] = chtbl[' '];	/* common mutation */	chtbl['~'] = chtbl['^'];	/* an other common mutation */	blank = ' ';/* * set up the line length table, to avoid computing lotsa * and / ... */	cdlen[0] = 1;	for (i = 1, j = 5; i <= NORMLEN; i += 3, j += 4)		cdlen[i] = (cdlen[i + 1] = (cdlen[i + 2] = j));/* * search for header or translation table line. */	loop {	/* master loop for multiple decodes in one file */		partn = 'a';		loop {			if (fgets(buf, sizeof buf, in) == NULL) {				if (onedone) {					if (debug) format("End of file.\n");					exit(0);				} else {					format("uud: No begin line.\n");					Error(3);				}			}			numl++;			if (strncmp(buf, "table", (size_t)5) == 0) {				gettable();				continue;			}			if (strncmp(buf, "begin", (size_t)5) == 0) {				break;			}		}		lens = strlen(buf);		if (lens) buf[--lens] = '\0';#ifdef SMALL		if ((pos = getnword(buf, 3))) {			strcpy(dest, pos);		} else#else		if(sscanf(buf,"begin%o%s", &mode, dest) != 2)#endif		{			format("uud: Missing filename in begin line.\n");			Error(10);		}		if (target != NULL) {			strcpy(ofname, target);			strcat(ofname, dest);		} else			strcpy(ofname, dest);		if((out = fopen(ofname, WRITE)) == NULL) {			format("uud: Cannot open output file: %s\n", ofname);			Error(4);		}		if (debug) format("Begin uudecoding: %s\n", ofname);		seqc = SEQMAX;		check = nochk ? 0 : 1;		first = 1;		secnd = 0;		decode();		fclose(out);#ifdef UNIX		chmod(ofname, mode);#endif		onedone = 1;		if (debug) format("End uudecoding: %s\n", ofname);	}	/* master loop for multiple decodes in one file */}/* * Bring back a pointer to the start of the nth word. */char *getnword(str, n) register char *str; register int n;{	while((*str == '\t') || (*str == ' ')) str++;	if (! *str) return NULL;	while(--n) {		while ((*str != '\t') && (*str != ' ') && (*str)) str++;		if (! *str) return NULL;		while((*str == '\t') || (*str == ' ')) str++;		if (! *str) return NULL;	}	return str;}/* * Install the table in memory for later use. */void gettable(){	char buf[LINELEN];	register int c, n = 0;	register char *cpt;	for (c = 0; c < NCHARS; c++) chtbl[c] = -1;again:	if (fgets(buf, sizeof buf, in) == NULL) {		format("uud: EOF while in translation table.\n");		Error(5);	}	numl++;	if (strncmp(buf, "begin", (size_t)5) == 0) {		format("uud: Incomplete translation table.\n");		Error(6);	}	cpt = buf + strlen(buf) - 1;	*cpt = ' ';	while (*(cpt) == ' ') {		*cpt = 0;		cpt--;	}	cpt = buf;	while (c = *cpt) {		if (chtbl[c] != -1) {			format("uud: Duplicate char in translation table.\n");			Error(7);		}		if (n == 0) blank = c;		chtbl[c] = n++;		if (n >= 64) return;		cpt++;	}	goto again;}/* * copy from in to out, decoding as you go along. */void decode(){	char buf[LINELEN], outl[LINELEN];	register char *bp, *ut;	register int *trtbl = chtbl;	register int n, c, rlen;	register unsigned int len;	loop {		if (fgets(buf, sizeof buf, in) == NULL) {			format("uud: EOF before end.\n");			fclose(out);			Error(8);		}		numl++;		len = strlen(buf);		if (len) buf[--len] = '\0';/* * Is it an unprotected empty line before the end line ? */		if (len == 0) continue;/* * Get the binary line length. */		n = trtbl[*buf];		if (n >= 0) goto decod;/* * end of uuencoded file ? */		if (strncmp(buf, "end", (size_t)3) == 0) return;/* * end of current file ? : get next one. */		if (strncmp(buf, "include", (size_t)7) == 0) {			getfile(buf);			continue;		}		format("uud: Bad prefix line %d in file: %s\n",numl, ifname);		if (debug) format("Bad line =%s\n",buf);		Error(11);/* * Sequence checking ? */decod:		rlen = cdlen[n];/* * Is it the empty line before the end line ? */		if (n == 0) continue;/* * Pad with blanks. */		for (bp = &buf[c = len];			c < rlen; c++, bp++) *bp = blank;/* * Verify if asked for. */		if (debug) {			for (len = 0, bp = buf; len < rlen; len++) {				if (trtbl[*bp] < 0) {					format(	"Non uuencoded char <%c>, line %d in file: %s\n", *bp, numl, ifname);					format("Bad line =%s\n",buf);					Error(16);				}				bp++;			}		}/* * All this just to check for uuencodes that append a 'z' to each line.... */		if (secnd && check) {			secnd = 0;			if (buf[rlen] == SEQMAX) {				check = 0;				if (debug) format("Sequence check turned off (2).\n");			} else				if (debug) format("Sequence check on (2).\n");		} else if (first && check) {			first = 0;			secnd = 1;			if (buf[rlen] != SEQMAX) {				check = 0;				if (debug) format("No sequence check (1).\n");			} else				if (debug) format("Sequence check on (1).\n");		}/* * There we check. */		if (check) {			if (buf[rlen] != seqc) {				format("uud: Wrong sequence line %d in %s\n",					numl, ifname);				if (debug)					format(	"Sequence char is <%c> instead of <%c>.\n", buf[rlen], seqc);				Error(18);			}			seqc--;			if (seqc < SEQMIN) seqc = SEQMAX;		}/* * output a group of 3 bytes (4 input characters). * the input chars are pointed to by p, they are to * be output to file f.n is used to tell us not to * output all of them at the end of the file. */		ut = outl;		len = n;		bp = &buf[1];		while (n > 0) {			*(ut++) = trtbl[*bp] << 2 | trtbl[bp[1]] >> 4;			n--;			if (n) {				*(ut++) = (trtbl[bp[1]] << 4) |					  (trtbl[bp[2]] >> 2);				n--;			}			if (n) {				*(ut++) = trtbl[bp[2]] << 6 | trtbl[bp[3]];				n--;			}			bp += 4;		}		if ((n = fwrite(outl, (size_t)1, (size_t)len, out)) <= 0) {			format("uud: Error on writing decoded file.\n");			Error(18);		}	}}/* * Find the next needed file, if existing, otherwise try further * on next file. */void getfile(buf) register char *buf;{	if ((pos = getnword(buf, 2)) == NULL) {		format("uud: Missing include file name.\n");		Error(17);	} else		if (source != NULL) {			strcpy(ifname, source);			strcat(ifname, pos);		} else			strcpy(ifname, pos);#ifdef GEMDOS	if (Fattrib(ifname, 0, 0) < 0)#else	if (access(ifname, 04))#endif	{		if (debug) {			format("Cant find: %s\n", ifname);			format("Continuing to read same file.\n");		}	}	else {		if (freopen(ifname, "r", in) == in) {			numl = 0;			if (debug) 				format("Reading next section from: %s\n", ifname);		} else {			format("uud: Freopen abort: %s\n", ifname);			Error(9);		}	}	loop {		if (fgets(buf, LINELEN, in) == NULL) {			format("uud: No begin line after include: %s\n", ifname);			Error(12);		}		numl++;		if (strncmp(buf, "table", (size_t)5) == 0) {			gettable();			continue;		}		if (strncmp(buf, "begin", (size_t)5) == 0) break;	}	lens = strlen(buf);	if (lens) buf[--lens] = '\0';/* * Check the part suffix. */	if ((pos = getnword(buf, 3)) == NULL ) {		format("uud: Missing part name, in included file: %s\n", ifname);		Error(13);	} else {		part = *pos;		partn++;		if (partn > 'z') partn = 'a';		if (part != partn) {			format("uud: Part suffix mismatch: <%c> instead of <%c>.\n",				part, partn);			Error(14);		}		if (debug) format("Reading part %c\n", *pos);	}}/* * Printf style formatting. (Borrowed from MicroEmacs by Dave Conroy.)  * A lot smaller than the full fledged printf. */#ifdef __STDC__void format(char *fp, ...){  va_list args;  va_start (args, fp);  doprnt(fp, (char *)&args);  va_end(args);}#else/* VARARGS1 */void format(fp, args) char *fp;{	doprnt(fp, (char *)&args);}#endifvoid doprnt(fp, ap)register char	*fp;register char	*ap;{	register int	c, k;	register char	*s;	while ((c = *fp++) != '\0') {		if (c != '%')			outc(c);		else {			c = *fp++;			switch (c) {			case 'd':				puti(*(int *)ap, 10);				ap += sizeof(int);				break;			case 's':				s = *(char **)ap;				while ((k = *s++) != '\0')					outc(k);				ap += sizeof(char *);				break;			case 'c':				outc(*(int *)ap);				ap += sizeof(int);				break;			default:				outc(c);			}		}	}}/* * Put integer, in radix "r". */void puti(i, r)register unsigned int	i;register unsigned int	r;{	register unsigned int	q, s;	if ((q = i / r) != 0)		puti(q, r);	s = i % r;	if (s <= 9)		outc(s + '0');	else		outc(s - 10 + 'A');}void outc(c) register char c;{#ifdef GEMDOS	if (c == '\n') Bconout(2, '\r');	Bconout(2, c);#else	putchar(c);#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -