home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / comms / encoders / uuenc / c / uudecode < prev    next >
Encoding:
Text File  |  1995-03-11  |  7.6 KB  |  325 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *      This product includes software developed by the University of
  16.  *      California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. /* Reworked to GNU style by Ian Lance Taylor, ian@airs.com, August 93.  */
  35.  
  36. /* AIX requires this to be the first thing in the file.  */
  37. /*#if defined (_AIX) && !defined (__GNUC__)
  38.  #pragma alloca
  39. #endif*/
  40.  
  41. /*
  42.  * uudecode [file ...]
  43.  *
  44.  * create the specified file, decoding as you go.
  45.  * used with uuencode.
  46.  */
  47. /*#include <sys/stat.h>
  48. #include <pwd.h>
  49. */
  50. #include <stdio.h>
  51. #include <string.h>
  52. #include "getopt.h"
  53.  
  54. #ifdef  __GNUC__
  55. #undef  alloca
  56. #define alloca(n)       __builtin_alloca (n)
  57. #else   /* Not GCC.  */
  58. #ifdef  HAVE_ALLOCA_H
  59. #include <alloca.h>
  60. #else   /* Not HAVE_ALLOCA_H.  */
  61. #ifndef _AIX
  62. extern char *alloca ();
  63. #endif  /* Not AIX.  */
  64. #endif  /* HAVE_ALLOCA_H.  */
  65. #endif  /* GCC.  */
  66.  
  67. /* Get definitions for the file permission bits.  */
  68.  
  69. #ifndef S_IRWXU
  70. #define S_IRWXU 0700
  71. #endif
  72. #ifndef S_IRUSR
  73. #define S_IRUSR 0400
  74. #endif
  75. #ifndef S_IWUSR
  76. #define S_IWUSR 0200
  77. #endif
  78. #ifndef S_IXUSR
  79. #define S_IXUSR 0100
  80. #endif
  81.  
  82. #ifndef S_IRWXG
  83. #define S_IRWXG 0070
  84. #endif
  85. #ifndef S_IRGRP
  86. #define S_IRGRP 0040
  87. #endif
  88. #ifndef S_IWGRP
  89. #define S_IWGRP 0020
  90. #endif
  91. #ifndef S_IXGRP
  92. #define S_IXGRP 0010
  93. #endif
  94.  
  95. #ifndef S_IRWXO
  96. #define S_IRWXO 0007
  97. #endif
  98. #ifndef S_IROTH
  99. #define S_IROTH 0004
  100. #endif
  101. #ifndef S_IWOTH
  102. #define S_IWOTH 0002
  103. #endif
  104. #ifndef S_IXOTH
  105. #define S_IXOTH 0001
  106. #endif
  107.  
  108. static struct option longopts[] =
  109. {
  110.   { "version", 0, 0, 'v' },
  111.   { "help", 0, 0, 'h' },
  112.   { NULL, 0, 0, 0 }
  113. };
  114.  
  115. #if __STDC__
  116. static int decode (char *);
  117. static void usage (FILE *, int);
  118. #else
  119. static int decode ();
  120. static void usage ();
  121. #endif
  122.  
  123. extern char version[];
  124. static char *program_name;
  125.  
  126. int
  127. main (argc, argv)
  128.      int argc;
  129.      char **argv;
  130. {
  131.   int opt;
  132.   int rval;
  133.  
  134.   program_name = argv[0];
  135.  
  136.   while ((opt = getopt_long (argc, argv, "hv", longopts, (int *) NULL))
  137.          != EOF)
  138.     {
  139.       switch (opt)
  140.         {
  141.         case 'h':
  142.           printf ("Decode a file created by uuencode\n");
  143.           usage (stdout, 0);
  144.  
  145.         case 'v':
  146.           printf ("%s\n", version);
  147.           exit (0);
  148.  
  149.         case 0:
  150.           break;
  151.  
  152.         default:
  153.           usage (stderr, 1);
  154.         }
  155.     }
  156.  
  157.   if (optind == argc)
  158.   {
  159.     printf("Please give an argument to uudecode\n");
  160.     rval=0;
  161.   }
  162.   else
  163.     {
  164.       char *filename;
  165.    
  166.       rval = 0;
  167.       do
  168.         {
  169.           if (freopen (argv[optind], "r", stdin) != NULL)
  170.             rval |= decode (argv[optind]);
  171.           else
  172.             {
  173.               fprintf (stderr, "%s:", program_name);
  174.               perror (argv[optind]);
  175.               rval = 1;
  176.             }
  177.           ++optind;
  178.         }
  179.       while (optind < argc);
  180.     }
  181.  
  182.   exit (rval);
  183. }
  184.  
  185. #define DEC(c)  (((c) - ' ') & 077) /* single character decode */
  186.  
  187. static int
  188. decode (filename)
  189.      char *filename;
  190. {
  191.   struct passwd *pw;
  192.   register int n;
  193.   register char ch, *p;
  194.   int mode, n1;
  195.   char buf[2 * BUFSIZ];
  196.   char *outname;
  197.  
  198.   /* search for header line */
  199.   do
  200.     {
  201.       if (fgets (buf, sizeof (buf), stdin) == NULL)
  202.         {
  203.           fprintf (stderr,
  204.                   "%s:%s: no \"begin\" line\n", program_name, filename);
  205.           return 1;
  206.         }
  207.     }
  208.   while (strncmp (buf, "begin ", 6) != 0);
  209.  
  210.   sscanf (buf, "begin %o %s", &mode, buf);
  211.                                 
  212. /* Here begins some code of my own invention */
  213. /* Dot remover and file-length truncator */
  214.                           
  215.   if (strlen(buf)>=11) *(buf+10)=0;
  216.   for (n=0;n<strlen(buf);n++)
  217.   {
  218.     if (buf[n]==46) buf[n]=47;
  219.   }
  220.  
  221. /* Here endeth the code */
  222.   /* handle ~user/file format */
  223. /*  if (buf[0] != '~') */
  224.     outname = buf;
  225. /*  else
  226.     {
  227.       p = buf + 1;
  228.       while (*p != '/')
  229.       ++p;
  230.       if (*p == '\0')
  231.       {
  232.           fprintf (stderr, "%s:%s: illegal ~user\n", program_name,
  233.                    filename);
  234.           return 1;
  235.       }
  236.       *p++ = '\0';
  237.       pw = getpwnam (buf + 1);
  238.       if (pw == NULL)
  239.       {
  240.           fprintf (stderr, "%s:%s: no user %s\n", program_name,
  241.                    filename, buf + 1);
  242.           return 1;
  243.       }
  244.       n = strlen (pw->pw_dir);
  245.       n1 = strlen (p);
  246.       outname = (char *) alloca (n + n1 + 2);
  247.       memcpy (outname + n + 1, p, n1 + 1);
  248.       memcpy (outname, pw->pw_dir, n);
  249.       outname[n] = '/';
  250.     }
  251.      */
  252.   /* create output file, set mode */
  253.   if (freopen (outname, "w", stdout) == NULL
  254.       /*|| fchmod (fileno (stdout),
  255.                  mode & (S_IRWXU | S_IRWXG | S_IRWXO))*/)
  256.     {
  257.       fprintf (stderr, "%s:%s:", program_name, outname);
  258.       perror (filename);
  259.       return 1;
  260.     }
  261.  
  262.   /* for each input line */
  263.   while (1)
  264.     {
  265.       if (fgets (buf, sizeof(buf), stdin) == NULL)
  266.         {
  267.           fprintf (stderr, "%s:%s: short file.\n", program_name,
  268.                    filename);
  269.           return 1;
  270.         }
  271.       p = buf;
  272.       /*
  273.        * `n' is used to avoid writing out all the characters
  274.        * at the end of the file.
  275.        */
  276.       n = DEC (*p);
  277.       if (n <= 0)
  278.         break;
  279.       for (++p; n > 0; p += 4, n -= 3)
  280.         {
  281.           if (n >= 3)
  282.             {
  283.               ch = DEC (p[0]) << 2 | DEC (p[1]) >> 4;
  284.               putchar (ch);
  285.               ch = DEC (p[1]) << 4 | DEC (p[2]) >> 2;
  286.               putchar (ch);
  287.               ch = DEC (p[2]) << 6 | DEC (p[3]);
  288.               putchar (ch);
  289.             }
  290.           else
  291.             {
  292.               if (n >= 1)
  293.                 {
  294.                   ch = DEC (p[0]) << 2 | DEC (p[1]) >> 4;
  295.                   putchar (ch);
  296.                 }
  297.               if (n >= 2)
  298.                 {
  299.                   ch = DEC (p[1]) << 4 | DEC (p[2]) >> 2;
  300.                   putchar (ch);
  301.                 }
  302.             }
  303.         }
  304.     }
  305.  
  306.   if (fgets (buf, sizeof(buf), stdin) == NULL
  307.       || strcmp (buf, "end\n"))
  308.     {
  309.       fprintf (stderr, "%s:%s: no \"end\" line.\n", program_name,
  310.                filename);
  311.       return 1;
  312.     }
  313.  
  314.   return 0;
  315. }
  316.  
  317. static void
  318. usage (f, status)
  319.      FILE *f;
  320.      int status;
  321. {
  322.   fprintf (f, "usage: %s [file ...]\n", program_name);
  323.   exit (status);
  324. }
  325.