uue.c

Go to the documentation of this file.
00001 /* uue - bulletproof version of uuencode */
00002 
00003 /* Uue -- encode a file so that it's printable ascii, short lines
00004  *
00005  * Slightly modified from a version posted to net.sources a while back,
00006  * and suitable for compilation on the IBM PC
00007  *
00008  * modified for Lattice C on the ST - 11.05.85 by MSD
00009  * modified for ALCYON on the ST -    10-24-86 by RDR
00010  * modified a little more for MWC...  02/09/87 by JPHD
00011  * (An optional first argument of the form: -nnumber (e.g. -500), will
00012  * produce a serie of files that long, linked by the include statement,
00013  * such files are automatically uudecoded by the companion program.)
00014  * More mods, - ...                05/06/87 by jphd
00015  * Mods for TOPS 20, and more.     08/06/87 by jphd
00016  *     (remove freopen and rindex...change filename generation...)
00017  * (A lot more to do about I/O speed, avoiding completely the stdio.h...)
00018  * May be called as uuencode.       Oct 2 1993 by Kees J. Bot
00019  *
00020  */
00021 
00022 
00023 #include <ctype.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <stdio.h>
00027 
00028 #define USAGE
00029 #define FILE_NAME 10            /* affects how long names are truncated */
00030 
00031 /* ENC is the basic 1 character encoding function to make a char printing */
00032 #define ENC(c) (((c) & 077) + ' ')
00033 
00034 FILE *fp, *outp;
00035 char ofname[80];
00036 int lenofname;
00037 int stdo = 0;
00038 
00039 #ifdef ST
00040 #define READ "rb"
00041 #else
00042 #define READ "r"
00043 #endif
00044 
00045 int part = 'a', chap = 'a';
00046 #define SEQMAX 'z'
00047 #define SEQMIN 'a'
00048 char seqc = SEQMAX;
00049 
00050 int split = 0;
00051 int fileln = 32000;
00052 
00053 _PROTOTYPE(int main, (int argc, char **argv));
00054 _PROTOTYPE(void maketable, (void));
00055 _PROTOTYPE(void makename, (void));
00056 _PROTOTYPE(void encode, (void));
00057 _PROTOTYPE(void outdec, (char *p));
00058 _PROTOTYPE(int fr, (char *buf, int cnt));
00059 
00060 int main(argc, argv)
00061 int argc;
00062 char *argv[];
00063 {
00064   char *prog_name;
00065   char *fname;
00066   int filter;
00067 
00068   prog_name = argv[0] + strlen(argv[0]);
00069   while (prog_name > argv[0] && prog_name[-1] != '/') prog_name--;
00070   filter = strcmp(prog_name, "uuencode") == 0;
00071 
00072   if (argc < 2) {
00073         fprintf(stderr, "Usage: %s [-n] inputfile [-]\n", prog_name);
00074         exit(2);
00075   }
00076   if (argv[1][0] == '-') {
00077         fileln = -atoi(argv[1]);
00078         if (fileln <= 0) {
00079                 fprintf(stderr, "Wrong file length arg.\n");
00080                 exit(3);
00081         }
00082         split = 1;
00083         argv++;
00084         argc--;
00085   }
00086   if (filter) {         /* old uuencode reads from standard input */
00087         fp = stdin;
00088   } else {
00089         if ((fp = fopen(argv[1], READ)) == NULL) {      /* binary input !!! */
00090                 fprintf(stderr, "Cannot open %s\n", argv[1]);
00091                 exit(1);
00092         }
00093   }
00094   fname = argv[1] + strlen(argv[1]);
00095   while (fname > argv[1] && fname[-1] != '/') fname--;
00096   strcpy(ofname, fname);
00097   fname = ofname;
00098   do {
00099         if (*fname == '.') *fname = '\0';
00100   } while (*fname++);
00101   /* 10 char prefix + .uue -> 14 chars MAX */
00102   lenofname = strlen(ofname);
00103   if (lenofname > FILE_NAME) ofname[FILE_NAME] = '\0';
00104   strcat(ofname, ".uue");
00105   lenofname = strlen(ofname);
00106   if (!split && (filter || (argc > 2) && (argv[2][0] == '-'))) {
00107         stdo = 1;
00108         outp = stdout;
00109   } else {
00110         makename();
00111         if ((outp = fopen(ofname, "w")) == NULL) {
00112                 fprintf(stderr, "Cannot open %s\n", ofname);
00113                 exit(1);
00114         }
00115   }
00116   maketable();
00117   fprintf(outp, "begin %o %s\n", 0644, argv[1]);
00118   encode();
00119   fprintf(outp, "end\n");
00120   fclose(outp);
00121   return(0);
00122 }
00123 
00124 /* Create ASCII table so a mailer can screw it up and the decode
00125  * program can restore the error.
00126  */
00127 void maketable()
00128 {
00129   register int i, j;
00130 
00131   fputs("table\n", outp);
00132   for (i = ' ', j = 0; i < '`'; j++) {
00133         if (j == 32) putc('\n', outp);
00134         fputc(i++, outp);
00135   }
00136   putc('\n', outp);
00137 }
00138 
00139 /* Generate the names needed for single and multiple part encoding.  */
00140 void makename()
00141 {
00142   if (split) {
00143         ofname[lenofname - 1] = part;
00144         ofname[lenofname - 2] = chap;
00145   }
00146 }
00147 
00148 /* Copy from in to out, encoding as you go along.  */
00149 void encode()
00150 {
00151   char buf[80];
00152   register int i, n;
00153   register int lines;
00154   lines = 6;
00155 
00156   for (;;) {
00157         n = fr(buf, 45);
00158         putc(ENC(n), outp);
00159         for (i = 0; i < n; i += 3) outdec(&buf[i]);
00160         putc(seqc, outp);
00161         seqc--;
00162         if (seqc < SEQMIN) seqc = SEQMAX;
00163         putc('\n', outp);
00164         ++lines;
00165         if (split && (lines > fileln)) {
00166                 part++;
00167                 if (part > 'z') {
00168                         part = 'a';
00169                         if (chap == 'z')
00170                                 chap = 'a';     /* loop ... */
00171                         else
00172                                 chap++;
00173                 }
00174                 makename();
00175                 fprintf(outp, "include %s\n", ofname);
00176                 fclose(outp);
00177                 if ((outp = fopen(ofname, "w")) == NULL) {
00178                         fprintf(stderr, "Cannot open %s\n", ofname);
00179                         exit(1);
00180                 }
00181                 maketable();
00182                 fprintf(outp, "begin part %c %s\n", part, ofname);
00183                 lines = 6;
00184         }
00185         if (n <= 0) break;
00186   }
00187 }
00188 
00189 /* Output one group of 3 bytes, pointed at by p, on file f.  */
00190 void outdec(p)
00191 register char *p;
00192 {
00193   register int c1, c2, c3, c4;
00194 
00195   c1 = *p >> 2;
00196   c2 = ((*p << 4) & 060) | ((p[1] >> 4) & 017);
00197   c3 = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03);
00198   c4 = p[2] & 077;
00199   putc(ENC(c1), outp);
00200   putc(ENC(c2), outp);
00201   putc(ENC(c3), outp);
00202   putc(ENC(c4), outp);
00203 }
00204 
00205 /* Fr: like read but stdio */
00206 int fr(buf, cnt)
00207 register char *buf;
00208 register int cnt;
00209 {
00210   register int c, i;
00211   for (i = 0; i < cnt; i++) {
00212         c = fgetc(fp);
00213         if (feof(fp)) return(i);
00214         buf[i] = c;
00215   }
00216   return(cnt);
00217 }

Generated on Fri Apr 14 22:57:13 2006 for minix by  doxygen 1.4.6