home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / UUCPbb_2_1_src.lzh / UUCPBB21 / uudecode.c < prev    next >
Text File  |  1994-09-25  |  5KB  |  221 lines

  1. /*
  2.    uudecode [input]
  3.  
  4.    create the specified file, decoding as you go.
  5.    used with uuencode.
  6.  
  7.    Modified to allow split uuencoded files to be joined together.  Such files
  8.    might come from an archive server such as ftp@cabrales.cs.wisc.edu.
  9.          Bob Billson <bob@kc2wz.bubble.org>     16 Feb 1992
  10. */
  11.  
  12. #include "uucp.h"
  13.  
  14. #define DEC(c) (((c) - ' ')&077)         /* single character decode */
  15.  
  16. char *decode();
  17. char buf[256];
  18.  
  19.  
  20. main (argc, argv)
  21. int   argc;
  22. char  *argv[];
  23. {
  24.      FILE  *in, *out;
  25.      char  dest[128], path[128];
  26.      register char *p;
  27.      int first_one;
  28.  
  29.      if (argc > 2)
  30.           usage();
  31.  
  32.      if (argc > 1)
  33.        {
  34.           if (strcmp (argv[1], "-?") == 0)
  35.                usage();
  36.  
  37.           if ((in = fopen (argv[1], "r")) == NULL)
  38.             {
  39.                fprintf (stderr, "can't open %s\n\n", argv[1]);
  40.                usage();
  41.             }
  42.  
  43.           argv++;
  44.           argc--;
  45.        }
  46.      else
  47.           in = stdin;
  48.  
  49.      /* decode the file.  If it is split across more than one file, handle
  50.         each one separately. */
  51.  
  52.      for (first_one = TRUE;;)
  53.        {
  54.           /* search for the header line */
  55.           if ( !findbegin (in)  &&  !first_one)
  56.             {
  57.                fputs ("No begin line\n", stderr);
  58.                exit (0);
  59.             }
  60.  
  61.           /* create the output file the first time through */
  62.           if (first_one)
  63.             {
  64.                p = strrchr (buf, ' ');
  65.                strncpy (dest, &p[1], sizeof (dest));
  66.                dest[sizeof (dest) - 1] = '\0';
  67.  
  68.                if ((out = fopen (dest, "w")) == NULL)
  69.                  {
  70.                     fprintf (stderr, "can't create %s for output\n", dest);
  71.                     exit (errno);
  72.                  }
  73.             }
  74.           p = decode (in, out);
  75.  
  76.           if (p != NULL)
  77.             {
  78.                /* close old input file */
  79.                fclose (in);
  80.  
  81.                /* get the name of next part from 'include ...' line */
  82.                p = strchr (p, ' ');
  83.                strncpy (path, &p[1], sizeof (path));
  84.                path[sizeof (path) - 1] = '\0';
  85.                printf ("adding next file '%s'\n", path);
  86.                first_one = FALSE;
  87.  
  88.                /* open the input, decode it to the current output stream */
  89.                if ((in = fopen (path, "r")) == NULL)
  90.                  {
  91.                     fprintf (stderr, "can't open '%s' for input\n", path);
  92.                     exit (errno);
  93.                  }
  94.             }
  95.           else
  96.             {
  97.                if ((fgets (buf, sizeof (buf), in) == NULL)
  98.                     || (strcmp (buf, "end\n") != 0))
  99.                  {
  100.                     fputs ("No end line\n", stderr);
  101.                  }
  102.  
  103.                exit(0);
  104.             }
  105.        }
  106. }
  107.  
  108.  
  109.  
  110. /* copy from in to out, decoding as you go along */
  111.  
  112. char *decode (in, out)
  113. FILE  *in, *out;
  114. {
  115.      char  buff[80], *bp;
  116.      register int n;
  117.  
  118.      /* for each input line */
  119.      for (;;)
  120.        {
  121.           if (fgets (buff, sizeof (buff), in) == NULL)
  122.             {
  123.                fputs ("Short file\n", stderr);
  124.                exit (0);
  125.             }
  126.  
  127.           /* decode the data */
  128.           n = DEC(buff[0]);
  129.  
  130.           /* everything is in this one file ? */
  131.           if (n <= 0)
  132.                break;
  133.  
  134.           /* was this file split in more than one piece? */
  135.           if (strncmp (buff, "include ", 8) == 0)
  136.             {
  137.                /* get rid of the CR */
  138.                if ((bp = strchr (buff, '\n')) != NULL)
  139.                     *bp = '\0';
  140.  
  141.                return (buff);
  142.             }
  143.  
  144.           bp = &buff[1];
  145.  
  146.           while (n > 0)
  147.             {
  148.                outdec (bp, out, n);
  149.                bp += 4;
  150.                n -= 3;
  151.             }
  152.        }
  153.  
  154.      /* everything is in this one file ? */
  155.      return (NULL);
  156. }
  157.  
  158.  
  159.  
  160. /* Output a group of 3 bytes (4 input characters).  The input chars are
  161.    pointed to by p, they are to be output to file f.  n is used to tell us not
  162.    to output all of them at the end of the file.  */
  163.  
  164. int outdec ( p, f, n)
  165. register char  *p;
  166. FILE  *f;
  167. int   n;
  168. {
  169.      int   c1, c2, c3;
  170.  
  171.      c1 = DEC(*p) << 2 | DEC(p[1]) >> 4;
  172.      c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
  173.      c3 = DEC(p[2]) << 6 | DEC(p[3]);
  174.  
  175.      if (n >= 1)
  176.           putc (c1, f);
  177.  
  178.      if (n >= 2)
  179.           putc (c2, f);
  180.  
  181.      if (n >= 3)
  182.           putc (c3, f);
  183. }
  184.  
  185.  
  186.  
  187. /* search for the 'begin' header line */
  188.  
  189. int findbegin (in)
  190. FILE *in;
  191. {
  192.      register char *p;
  193.  
  194.      p = buf;
  195.  
  196.      while (fgets (p, sizeof (buf), in) != NULL)
  197.           if (strncmp (p, "begin ", 6) == 0) 
  198.                return (TRUE);
  199.  
  200.      return (FALSE);
  201. }
  202.  
  203.  
  204.  
  205. int usage()
  206. {
  207.      char **help;
  208.      static char *helptxt[] = {
  209.              "Usage: uudecode [infile]\n",
  210.              "Restore a file created with uuencode.  Split files will be restored if the",
  211.              "last line is in the form 'include XX', where XX is a sequencial name.",
  212.              "uudecode will look for a file called <infile>.XX for its next input.\n",
  213.              NULL
  214.           };
  215.  
  216.      for (help = helptxt; *help != NULL; ++help)
  217.           fprintf (stderr, "%s\n", *help);
  218.  
  219.      exit (2);
  220. }
  221.