home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / duucp-1.17 / AU-117b4-src.lha / src / unix / uudecode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-24  |  3.0 KB  |  193 lines

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