home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 341b.lha / uucp1_v1.03d / src / compress / uudecode.c < prev    next >
C/C++ Source or Header  |  1990-01-28  |  3KB  |  214 lines

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