home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / internet / uucode_68020 / uucoders / uuencode.c < prev   
C/C++ Source or Header  |  1997-08-31  |  4KB  |  172 lines

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