home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8709 / 6 / uuencode.c < prev   
Encoding:
C/C++ Source or Header  |  1987-09-11  |  3.2 KB  |  163 lines

  1. /* #ifndef lint
  2. static char sccsid[] = "@(#)uuencode.c  5.3-1 (Berkeley) 9/1/87";
  3. #endif */
  4.  
  5. /* Written by Mark Horton */
  6. /* Modified by ajr (Alan J Rosenthatl,flaps@utcsri.UUCP) to use checksums */
  7. /* Modified by fnf (Fred Fish,well!fnf) to use Keith Pyle's suggestion for
  8.    compatibility */
  9. /* Modified by bcn (Bryce Nesbitt,ucbvax!cogsci!bryce) to enable CTRL-C for
  10.    Amiga Lattice C and add a transparant file size trailer for later check. */
  11.  
  12. /*
  13.  * uuencode >outfile [infile] name
  14.  *
  15.  * Encode a file so it can be mailed to a remote system.  This version
  16.  * transparantly adds line checksums and a file size for sanity checks.
  17.  *
  18.  */
  19.  
  20. #include <stdio.h>
  21.  
  22. #ifdef    AMIGA            /* Amiga Lattice C */
  23. #define AMIGA_LATTICE
  24. #define MCH_AMIGA
  25. #define MPU68000
  26. #endif
  27.  
  28. #ifdef unix
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #endif
  32.  
  33. #define SUMSIZE 64  /* 6 bits */
  34. /* ENC is the basic 1 character encode function to make a char printing */
  35. /* Each output character represents 6 bits of input */
  36. #define ENC(c) ((c) ? ((c) & 077) + ' ': '`')
  37. long    totalsize=0;    /* Used to count the file size because ftell() does
  38.                not return sane results for pipes */
  39.  
  40. main(argc, argv)
  41. char **argv;
  42. {
  43.     FILE *in;
  44.     int mode;
  45. #ifdef unix
  46.     struct stat sbuf;
  47. #endif
  48. #ifdef AMIGA_LATTICE
  49.     extern int Enable_Abort;    /* Enable CTRL-C for Lattice */
  50.     Enable_Abort=1;
  51. #endif
  52.  
  53.     /* optional 1st argument */
  54.     if (argc > 2) {
  55.         if ((in = fopen(argv[1], "r")) == NULL) {
  56.             fprintf(stderr, "ERROR: can't find %s\n", argv[1]);
  57.             fprintf(stderr, "USAGE: uuencode >outfile [infile] name\n");
  58.             exit(10);
  59.         }
  60.         argv++; argc--;
  61.     } else
  62.         in = stdin;
  63.  
  64.     if (argc != 2) {
  65.         fprintf(stderr, "USAGE: uuencode >outfile [infile] name\n");
  66.         exit(11);
  67.     }
  68.  
  69. #ifdef unix
  70.     /* figure out the input file mode */
  71.     fstat(fileno(in), &sbuf);
  72.     mode = sbuf.st_mode & 0777;
  73. #else
  74.     mode = 0644;        /* Default permissions */
  75. #endif
  76.  
  77.     printf("\nbegin %o %s\n", mode, argv[1]);
  78.  
  79.     encode(in, stdout);
  80.  
  81.     printf("end\n");
  82.     printf("size %ld\n",totalsize);
  83.     exit(0);
  84. }
  85.  
  86. /*
  87.  * copy from in to out, encoding as you go along.
  88.  */
  89. encode(in, out)
  90. FILE *in;
  91. FILE *out;
  92. {
  93. #ifndef unix
  94. extern errno;
  95. #endif
  96.     char buf[80];
  97.     int i, n, checksum;
  98.  
  99.     for (;;) {
  100.         /* 1 (up to) 45 character line */
  101.         n = fr(in, buf, 45);
  102.         putc(ENC(n), out);
  103.  
  104.         checksum = 0;
  105.         for (i=0; i<n; i += 3)
  106.             checksum = (checksum+outdec(&buf[i], out)) % SUMSIZE;
  107.  
  108.         putc(ENC(checksum), out);
  109.         putc('\n', out);
  110.  
  111. #ifndef unix
  112.         /* Error checking under UNIX?? You must be kidding! */
  113.         if (errno) {
  114.             fprintf(stderr, "ERROR: error writing to output\n");
  115.             exit(12);
  116.             }
  117. #endif
  118.         if (n <= 0)
  119.             break;
  120.     }
  121. }
  122.  
  123. /*
  124.  * output one group of 3 bytes, pointed at by p, on file f.
  125.  * return the checksum increment.
  126.  */
  127. int outdec(p, f)
  128. char *p;
  129. FILE *f;
  130. {
  131.     int c1, c2, c3, c4;
  132.  
  133.     c1 = *p >> 2;
  134.     c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
  135.     c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
  136.     c4 = p[2] & 077;
  137.     putc(ENC(c1), f);
  138.     putc(ENC(c2), f);
  139.     putc(ENC(c3), f);
  140.     putc(ENC(c4), f);
  141.  
  142.     return((p[0]+p[1]+p[2]) % SUMSIZE);
  143. }
  144.  
  145. /* fr: like read but stdio */
  146. int
  147. fr(fd, buf, cnt)
  148. FILE *fd;
  149. char *buf;
  150. int cnt;
  151. {
  152.     int c, i;
  153.  
  154.     for (i=0; i<cnt; i++) {
  155.         c = getc(fd);
  156.         if (c == EOF)
  157.             return(i);
  158.         totalsize++;
  159.         buf[i] = c;
  160.     }
  161.     return (cnt);
  162. }
  163.