home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume7 / uuencode / uudecode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  2.8 KB  |  181 lines

  1. /*
  2.  * uudecode [input]
  3.  *
  4.  * create the specified file, decoding as you go.
  5.  * used with uuencode.
  6.  */
  7. #include <stdio.h>
  8. #include <pwd.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11.  
  12. /* single character decode */
  13. #define DEC(c)    (((c) - ' ') & 077)
  14.  
  15. main(argc, argv)
  16. char **argv;
  17. {
  18.     FILE *in, *out;
  19.     struct stat sbuf;
  20.     int mode;
  21.     char dest[128];
  22.     char buf[80];
  23.  
  24.     /* optional input arg */
  25.     if (argc > 1) {
  26.         if ((in = fopen(argv[1], "r")) == NULL) {
  27.             perror(argv[1]);
  28.             exit(1);
  29.         }
  30.         argv++; argc--;
  31.     } else
  32.         in = stdin;
  33.  
  34.     if (argc != 1) {
  35.         printf("Usage: uudecode [infile]\n");
  36.         exit(2);
  37.     }
  38.  
  39.     /* search for header line */
  40.     for (;;) {
  41.         if (fgets(buf, sizeof buf, in) == NULL) {
  42.             fprintf(stderr, "No begin line\n");
  43.             exit(3);
  44.         }
  45.         if (strncmp(buf, "begin ", 6) == 0)
  46.             break;
  47.     }
  48.     sscanf(buf, "begin %o %s", &mode, dest);
  49.  
  50.     /* handle ~user/file format */
  51.     if (dest[0] == '~') {
  52.         char *sl;
  53.         struct passwd *getpwnam();
  54.         char *index();
  55.         struct passwd *user;
  56.         char dnbuf[100];
  57.  
  58.         sl = index(dest, '/');
  59.         if (sl == NULL) {
  60.             fprintf(stderr, "Illegal ~user\n");
  61.             exit(3);
  62.         }
  63.         *sl++ = 0;
  64.         user = getpwnam(dest+1);
  65.         if (user == NULL) {
  66.             fprintf(stderr, "No such user as %s\n", dest);
  67.             exit(4);
  68.         }
  69.         strcpy(dnbuf, user->pw_dir);
  70.         strcat(dnbuf, "/");
  71.         strcat(dnbuf, sl);
  72.         strcpy(dest, dnbuf);
  73.     }
  74.  
  75.     /* create output file */
  76.     out = fopen(dest, "w");
  77.     if (out == NULL) {
  78.         perror(dest);
  79.         exit(4);
  80.     }
  81.     chmod(dest, mode);
  82.  
  83.     decode(in, out);
  84.  
  85.     if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n")) {
  86.         fprintf(stderr, "No end line\n");
  87.         exit(5);
  88.     }
  89.     exit(0);
  90. }
  91.  
  92. /*
  93.  * copy from in to out, decoding as you go along.
  94.  */
  95. decode(in, out)
  96. FILE *in;
  97. FILE *out;
  98. {
  99.     char buf[80];
  100.     char *bp;
  101.     int n;
  102.  
  103.     for (;;) {
  104.         /* for each input line */
  105.         if (fgets(buf, sizeof buf, in) == NULL) {
  106.             printf("Short file\n");
  107.             exit(10);
  108.         }
  109.         n = DEC(buf[0]);
  110.         if (n <= 0)
  111.             break;
  112.  
  113.         bp = &buf[1];
  114.         while (n > 0) {
  115.             outdec(bp, out, n);
  116.             bp += 4;
  117.             n -= 3;
  118.         }
  119.     }
  120. }
  121.  
  122. /*
  123.  * output a group of 3 bytes (4 input characters).
  124.  * the input chars are pointed to by p, they are to
  125.  * be output to file f.  n is used to tell us not to
  126.  * output all of them at the end of the file.
  127.  */
  128. outdec(p, f, n)
  129. char *p;
  130. FILE *f;
  131. {
  132.     int c1, c2, c3;
  133.  
  134.     c1 = DEC(*p) << 2 | DEC(p[1]) >> 4;
  135.     c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
  136.     c3 = DEC(p[2]) << 6 | DEC(p[3]);
  137.     if (n >= 1)
  138.         putc(c1, f);
  139.     if (n >= 2)
  140.         putc(c2, f);
  141.     if (n >= 3)
  142.         putc(c3, f);
  143. }
  144.  
  145.  
  146. /* fr: like read but stdio */
  147. int
  148. fr(fd, buf, cnt)
  149. FILE *fd;
  150. char *buf;
  151. int cnt;
  152. {
  153.     int c, i;
  154.  
  155.     for (i=0; i<cnt; i++) {
  156.         c = getc(fd);
  157.         if (c == EOF)
  158.             return(i);
  159.         buf[i] = c;
  160.     }
  161.     return (cnt);
  162. }
  163.  
  164. /*
  165.  * Return the ptr in sp at which the character c appears;
  166.  * NULL if not found
  167.  */
  168.  
  169. #define    NULL    0
  170.  
  171. char *
  172. index(sp, c)
  173. register char *sp, c;
  174. {
  175.     do {
  176.         if (*sp == c)
  177.             return(sp);
  178.     } while (*sp++);
  179.     return(NULL);
  180. }
  181.