"Fossies" - the Free Open Source Software Archive  

Member "uuencode-1.0/uudecode.c" (23 Aug 1993, 6797 Bytes) of package /linux/misc/old/uuencode-1.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    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 #include <stdio.h>
   50 #include "getopt.h"
   51 
   52 #ifdef  __GNUC__
   53 #undef  alloca
   54 #define alloca(n)   __builtin_alloca (n)
   55 #else   /* Not GCC.  */
   56 #ifdef  HAVE_ALLOCA_H
   57 #include <alloca.h>
   58 #else   /* Not HAVE_ALLOCA_H.  */
   59 #ifndef _AIX
   60 extern char *alloca ();
   61 #endif  /* Not AIX.  */
   62 #endif  /* HAVE_ALLOCA_H.  */
   63 #endif  /* GCC.  */
   64 
   65 /* Get definitions for the file permission bits.  */
   66 
   67 #ifndef S_IRWXU
   68 #define S_IRWXU 0700
   69 #endif
   70 #ifndef S_IRUSR
   71 #define S_IRUSR 0400
   72 #endif
   73 #ifndef S_IWUSR
   74 #define S_IWUSR 0200
   75 #endif
   76 #ifndef S_IXUSR
   77 #define S_IXUSR 0100
   78 #endif
   79 
   80 #ifndef S_IRWXG
   81 #define S_IRWXG 0070
   82 #endif
   83 #ifndef S_IRGRP
   84 #define S_IRGRP 0040
   85 #endif
   86 #ifndef S_IWGRP
   87 #define S_IWGRP 0020
   88 #endif
   89 #ifndef S_IXGRP
   90 #define S_IXGRP 0010
   91 #endif
   92 
   93 #ifndef S_IRWXO
   94 #define S_IRWXO 0007
   95 #endif
   96 #ifndef S_IROTH
   97 #define S_IROTH 0004
   98 #endif
   99 #ifndef S_IWOTH
  100 #define S_IWOTH 0002
  101 #endif
  102 #ifndef S_IXOTH
  103 #define S_IXOTH 0001
  104 #endif
  105 
  106 static struct option longopts[] =
  107 {
  108   { "version", 0, 0, 'v' },
  109   { "help", 0, 0, 'h' },
  110   { NULL, 0, 0, 0 }
  111 };
  112 
  113 #if __STDC__
  114 static int decode (char *);
  115 static void usage (FILE *, int);
  116 #else
  117 static int decode ();
  118 static void usage ();
  119 #endif
  120 
  121 extern char version[];
  122 static char *program_name;
  123 
  124 int
  125 main (argc, argv)
  126      int argc;
  127      char **argv;
  128 {
  129   int opt;
  130   int rval;
  131 
  132   program_name = argv[0];
  133 
  134   while ((opt = getopt_long (argc, argv, "hv", longopts, (int *) NULL))
  135      != EOF)
  136     {
  137       switch (opt)
  138     {
  139     case 'h':
  140       printf ("Decode a file created by uuencode\n");
  141       usage (stdout, 0);
  142 
  143     case 'v':
  144       printf ("%s\n", version);
  145       exit (0);
  146 
  147     case 0:
  148       break;
  149 
  150     default:
  151       usage (stderr, 1);
  152     }
  153     }
  154 
  155   if (optind == argc)
  156     rval = decode ((char *) "stdin");
  157   else
  158     {
  159       char *filename;
  160 
  161       rval = 0;
  162       do
  163     {
  164       if (freopen (argv[optind], "r", stdin) != NULL)
  165         rval |= decode (argv[optind]);
  166       else
  167         {
  168           fprintf (stderr, "%s:", program_name);
  169           perror (argv[optind]);
  170           rval = 1;
  171         }
  172       ++optind;
  173     }
  174       while (optind < argc);
  175     }
  176 
  177   exit (rval);
  178 }
  179 
  180 #define DEC(c)  (((c) - ' ') & 077) /* single character decode */
  181 
  182 static int
  183 decode (filename)
  184      char *filename;
  185 {
  186   struct passwd *pw;
  187   register int n;
  188   register char ch, *p;
  189   int mode, n1;
  190   char buf[2 * BUFSIZ];
  191   char *outname;
  192 
  193   /* search for header line */
  194   do
  195     {
  196       if (fgets (buf, sizeof (buf), stdin) == NULL)
  197     {
  198       fprintf (stderr,
  199           "%s:%s: no \"begin\" line\n", program_name, filename);
  200       return 1;
  201     }
  202     }
  203   while (strncmp (buf, "begin ", 6) != 0);
  204 
  205   sscanf (buf, "begin %o %s", &mode, buf);
  206 
  207   /* handle ~user/file format */
  208   if (buf[0] != '~')
  209     outname = buf;
  210   else
  211     {
  212       p = buf + 1;
  213       while (*p != '/')
  214     ++p;
  215       if (*p == '\0')
  216     {
  217       fprintf (stderr, "%s:%s: illegal ~user\n", program_name,
  218            filename);
  219       return 1;
  220     }
  221       *p++ = '\0';
  222       pw = getpwnam (buf + 1);
  223       if (pw == NULL)
  224     {
  225       fprintf (stderr, "%s:%s: no user %s\n", program_name,
  226            filename, buf + 1);
  227       return 1;
  228     }
  229       n = strlen (pw->pw_dir);
  230       n1 = strlen (p);
  231       outname = (char *) alloca (n + n1 + 2);
  232       memcpy (outname + n + 1, p, n1 + 1);
  233       memcpy (outname, pw->pw_dir, n);
  234       outname[n] = '/';
  235     }
  236 
  237   /* create output file, set mode */
  238   if (freopen (outname, "w", stdout) == NULL
  239       || fchmod (fileno (stdout),
  240          mode & (S_IRWXU | S_IRWXG | S_IRWXO)))
  241     {
  242       fprintf (stderr, "%s:%s:", program_name, outname);
  243       perror (filename);
  244       return 1;
  245     }
  246 
  247   /* for each input line */
  248   while (1)
  249     {
  250       if (fgets (buf, sizeof(buf), stdin) == NULL)
  251     {
  252       fprintf (stderr, "%s:%s: short file.\n", program_name,
  253            filename);
  254       return 1;
  255     }
  256       p = buf;
  257       /*
  258        * `n' is used to avoid writing out all the characters
  259        * at the end of the file.
  260        */
  261       n = DEC (*p);
  262       if (n <= 0)
  263     break;
  264       for (++p; n > 0; p += 4, n -= 3)
  265     {
  266       if (n >= 3)
  267         {
  268           ch = DEC (p[0]) << 2 | DEC (p[1]) >> 4;
  269           putchar (ch);
  270           ch = DEC (p[1]) << 4 | DEC (p[2]) >> 2;
  271           putchar (ch);
  272           ch = DEC (p[2]) << 6 | DEC (p[3]);
  273           putchar (ch);
  274         }
  275       else
  276         {
  277           if (n >= 1)
  278         {
  279           ch = DEC (p[0]) << 2 | DEC (p[1]) >> 4;
  280           putchar (ch);
  281         }
  282           if (n >= 2)
  283         {
  284           ch = DEC (p[1]) << 4 | DEC (p[2]) >> 2;
  285           putchar (ch);
  286         }
  287         }
  288     }
  289     }
  290 
  291   if (fgets (buf, sizeof(buf), stdin) == NULL
  292       || strcmp (buf, "end\n"))
  293     {
  294       fprintf (stderr, "%s:%s: no \"end\" line.\n", program_name,
  295            filename);
  296       return 1;
  297     }
  298 
  299   return 0;
  300 }
  301 
  302 static void
  303 usage (f, status)
  304      FILE *f;
  305      int status;
  306 {
  307   fprintf (f, "usage: %s [file ...]\n", program_name);
  308   exit (status);
  309 }