rsalz@uunet.uu.net (Rich Salz) (04/01/89)
Submitted-by: Dave Taylor <taylor@hplabsz.hpl.hp.com> Posting-number: Volume 18, Issue 79 Archive-name: april-fool # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # This archive contains: # uuexpand.1 uuexpand.c Makefile # # Error checking via wc(1) will be performed. LANG=""; export LANG echo x - uuexpand.1 cat >uuexpand.1 <<'@EOF' .TH UUEXPAND 1L "" "" .ad b .SH NAME uuexpand, uuunexpand \- make file representation independent .SH SYNOPSIS .B uuexpand [ .B \-87?hAEdeuv ] [ .B \-16 ] [ .B \-w .I width ] .br .B uuunexpand [ .I uuexpand options ] .SH DESCRIPTION .I Uuexpand is a representation independent file archival and transportation mechanism for any operating system that has a "C" compiler available, including Unix, the Macintosh, MS-DOS, OS/2, VMS, and the like. .I Uuexpand also supports all international character sets, including 16-bit Asian, and 8-bit non-English, as required by the application. .PP The program pair are intended to be used to aid in the easy transportation of program and textual sources, data files, and binaries via electronic media. .PP .SS Options .PP There are many options: .TP .B \-16 Specifies that 16-bit character sets are being used and to ensure portability. (Note on non-standard character sets: you must ensure that when unexpanded the same parameter is specified to the program!) .TP .B \-8 Specifies that 8-bit character sets are being used. This is the default character set assumed (255 character extended ASCII) .TP .B \-7 Use a 7-bit ASCII representation for smaller output files. This is useful if you are sure that you've not strayed beyond the basic 128 ASCII characters. (see the note under the '-16' option) .TP .B \-? Output a summary of the starting options available. .TP .B \-A Use the ASCII character set for the output of the program. This is the default character set assumed. .TP .B \-E Use the EBCDIC character set for the output of the program. If you use this option you must ensure that the other end also uses this option when the file or software is unpacked. .TP .B \-d Turn on debugging for more output and some ending statistics. .TP .B \-e Expand the input -- act as if we'd invoked .I uuexpand explicitly (for sites that choose to change the name). .TP .B \-h Output a summary of starting options; identical to '-?' .TP .B \-u Unexpand the input -- act as if we'd invoked .I uuunexpand explicitly (for sites that might not have the symbolic link between the two names installed) .TP .B \-v Enable verbose output including some ending statistics. .TP .B \-w N Set the expanded line output width to .I N representational independent output elements. The default, with the 8-bit characters, is 8 units per output line. including indirect blocks, is printed. .SH EXAMPLES A very typical usage of the program would be for a person at a site in, say, Hong Kong, to mail a Chinese (16-bit) data file to a fellow Unix-ite with: .PP .ti +.5i uuexpand -16 < data | mail -s "Data" user@farhost.com .ti -.5i .PP The user at the other end could then simply save the message int a file then invoke a command similar to: .PP .ti +.5i uuunexpand -16 < data.mailed > data .ti -.5i .PP And the data file would be intact regardless of transport hosts along the way. .SH AUTHOR Dave Taylor, Intuitive Systems, Los Altos, California .SH SEE ALSO uuencode(1L), crypt(1), mail(1), uumail(1), shar(1L) .SH INTERNATIONAL SUPPORT 16-bit, 8-bit and 7-bit data. .SH BUGS The EBCDIC support is minimal and needs to be further developed by someone on an IBM or other EBCDIC machine. .PP The portability of the C code has not been completely verified; input from people on strange hardware, especially 386 Unix machines, would be a useful addition. .PP The program doesn't, but should, deal with machines that have peculiar byte sex problems. @EOF if test "`wc -lwc <uuexpand.1`" != ' 123 595 3485' then echo ERROR: wc results of uuexpand.1 are `wc -lwc <uuexpand.1` should be 123 595 3485 fi chmod 666 uuexpand.1 echo x - uuexpand.c cat >uuexpand.c <<'@EOF' /** uuexpand.c **/ /** This is a representation independent file archival and transportation mechanism for any operating system that has a "C" compiler available, including Unix, the Macintosh, MS-DOS, OS/2, VMS, and the like. This also supports all international character sets, including 16-bit Asian characters as required by the application. (C) Copyright 1989 Dave Taylor, Intuitive Systems, Los Altos California > Permission is hereby granted for the free distribution of this < > software throughout the known world with the clause that it be < > free and this version of the source code is always available. < **/ #include <stdio.h> #define SLEN 2048 /* max length of an input line */ #define DEFAULT_CHAR_WIDTH 8 /* 8 bit ASCII by default */ #define DEFAULT_BYTES_ON_LINE 8 /* default byte units / line */ #define EXPAND 1 #define UNEXPAND 2 #define ASCII 425 #define EBCDIC 943 #define ON_CHAR '1' #define OFF_CHAR '0' #define plural(n) (n == 1? "" : "s") int width_of_line, /* width of output block/line */ action, /* what are we doing? expand or unexpand */ lines = 0, /* lines we've read in from stdin */ chars = 0, /* chars we've read in from stdin */ lines_output = 0, /* lines we've output to stdout */ char_width; /* are we using 7-bit, 8-bit, or 16-bit? */ extern char *optarg; main(argc, argv) int argc; char *argv[]; { register int i, bit; char buffer[SLEN], char_buffer; int bytes_on_line, verbose, output_charset, c; /* first step: set up the defaults for the program */ action = (strcmp(argv[0], "uuexpand") == 0? EXPAND: UNEXPAND); char_width = DEFAULT_CHAR_WIDTH; bytes_on_line = DEFAULT_BYTES_ON_LINE; output_charset = ASCII; /* default */ /* now let's parse the starting arguments */ while ((c = getopt(argc, argv, "AEeu781:w:vdh?")) != EOF) { switch (c) { case 'A' : output_charset = ASCII; break; case 'E' : output_charset = EBCDIC; break; case '7' : char_width = 7; break; case '8' : char_width = 8; break; case '1' : char_width = 16; break; case 'w' : bytes_on_line = atoi(optarg); break; case 'v' : case 'd' : verbose++; break; case 'e' : action = EXPAND; break; case 'u' : action = UNEXPAND; break; case 'h' : case '?' : help(0); break; default : usage("unknown starting option"); } } /** a quick reality check on the bytes per line argument */ if (bytes_on_line < 1 || (bytes_on_line * char_width > SLEN/2)) usage("invalid specification for line width"); /** and we recompute the line width for output **/ width_of_line = (char_width * bytes_on_line) - 1; /** now we're ready to go. **/ if (verbose) { fprintf(stderr, "%sexpand: %s character set %s with %d-bit chars\n", action == EXPAND ? "" : "un", action == UNEXPAND ? "input" : "output", output_charset == ASCII ? "ASCII" : "EBCDIC", char_width); } /** Main switch here: expanding, or unexpanding? **/ if (action == EXPAND) { while (fgets(buffer, SLEN, stdin) != NULL) { lines++; chars += strlen(buffer); for (i=0; buffer[i] != '\0'; i++) { char_buffer = buffer[i]; /* ease of use */ for (bit=0;bit < char_width; bit++, char_buffer >>= 1) output( char_buffer & 01 ); } } } else /* UNEXPAND */ { while (gets(buffer) != NULL) { lines++; chars += strlen(buffer); for (i=0; i < strlen(buffer); i += char_width) { char_buffer = 0; for (bit=char_width;bit >= 0; bit--) { char_buffer <<= 1; char_buffer += (buffer[i+bit] == ON_CHAR ? 1 : 0); } putchar(char_buffer); if (char_buffer == '\n' || char_buffer == '\r') lines_output++; } } } if (verbose) { if (action == EXPAND) { fprintf(stderr, "Read in %d character%s, %d line%s\n", chars, plural(chars), lines, plural(lines)); fprintf(stderr, "Output %d representation independent element%s in %d line%s.\n", chars * char_width, plural(chars * char_width), lines_output, plural(lines_output)); } else { fprintf(stderr, "Read in %d representation independent element%s in %d line%s\n", chars, plural(chars), lines, plural(lines)); fprintf(stderr, "Output %d character%s in %d line%s.\n", (int) (chars / char_width), plural(chars / char_width), lines_output, plural(lines_output)); } } } output(bitvalue) int bitvalue; { /** Outputs the ON or OFF value based on what we've been handed. No return value. **/ static int location_on_line = 0; if (location_on_line > width_of_line) { putchar('\n'); lines_output++; location_on_line = 0; } putchar(bitvalue ? ON_CHAR : OFF_CHAR); location_on_line++; } usage(errmsg) char *errmsg; { /** Output the error message and call help() for a usage **/ fprintf(stderr, "\n**** Error: %s ****\n", errmsg); help(1); } help(exitcode) int exitcode; { /** output some starting parameter help and exit with the code specified by the calling routine. **/ fprintf(stderr,"\nUsage: uuexpand [opts]\n"); fprintf(stderr," or: uuunexpand [opts]\n\n"); fprintf(stderr,"Where [opts] can be:\n\n"); fprintf(stderr, "\t-16 \tEnsure 16-bit portability\n\ \t-8 \tEnsure 8-bit portability (the default)\n\ \t-7 \tEnsure 7-bit portability\n"); fprintf(stderr, "\t-? \tList the starting options (this information)\n\ \t-h \tIdentical in functionality to '-?'\n"); fprintf(stderr, "\t-A \tUse the ASCII character set for expanded output\n\ \t-E \tUse the EBCDIC character set for expanded output\n"); fprintf(stderr, "\t-d \tEnable debugging output (to stderr)\n"); fprintf(stderr, "\t-e \tExpand output (same as invoking 'uuexpand')\n\ \t-u \tUnExpand output (same as invoking 'uuunexpand')\n"); fprintf(stderr, "\t-v \tEnable verbose output (to stderr)\n"); fprintf(stderr, "\t-w N \tSet expanded line output width to 'N' representational elements\n\ \t \tper line (default is 8 per 8-bit represented line)\n\n"); exit(exitcode); } @EOF if test "`wc -lwc <uuexpand.c`" != ' 211 842 6118' then echo ERROR: wc results of uuexpand.c are `wc -lwc <uuexpand.c` should be 211 842 6118 fi chmod 666 uuexpand.c echo x - Makefile cat >Makefile <<'@EOF' # # Makefile for the uuexpand program # # (C) 1989 Dave Taylor # SRC = uuexpand.c EXECUTABLE = uuexpand OTHERNAME = uuunexpand MANPAGE = uuexpand.1 INSTALLDIR = /usr/local/bin MANDIR = /usr/man/man1 CC = cc CFLAGS = -O DEFINES = $(EXECUTABLE) : $(SRC) $(CC) $(CFLAGS) $(DEFINES) $(SRC) -o $(EXECUTABLE) install: $(EXECUTABLE) strip $(EXECUTABLE) cp $(EXECUTABLE) $(INSTALLDIR)/$(EXECUTABLE) ln -s $(EXECUTABLE) $(OTHERNAME) cp $(MANPAGE) $(MANDIR)/$(MANPAGE) ln -s $(MANDIR)/$(MANPAGE) $(MANDIR)/$(OTHERNAME).1 lint: $(SRC) lint $(DEFINES) $(SRC) > LINT.OUT clean: rm -f a.out core @EOF if test "`wc -lwc <Makefile`" != ' 35 79 621' then echo ERROR: wc results of Makefile are `wc -lwc <Makefile` should be 35 79 621 fi chmod 666 Makefile exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.