home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2729 / uudecode.c next >
Encoding:
C/C++ Source or Header  |  1991-02-10  |  3.0 KB  |  189 lines

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