home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / telecom / uucp_442 / src / unix / uudecode.c < prev    next >
C/C++ Source or Header  |  1990-10-08  |  3KB  |  220 lines

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