home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / decode / xxcode.zoo / xxdecode.c next >
Encoding:
C/C++ Source or Header  |  1990-01-17  |  6.5 KB  |  319 lines

  1.  
  2. #ifndef lint
  3. static char sccsid[] = "@(#)xxdecode.c  5.3 (Berkeley) 4/10/85";
  4. #endif
  5.  
  6. /*
  7.  * xxdecode [input]
  8.  *
  9.  * create the specified file, decoding as you go.
  10.  * used with xxencode.
  11.  */
  12. #define MSDOS
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include <string.h>
  16. #ifndef MSDOS
  17. #ifndef VMCMS
  18. #include <pwd.h>
  19. #endif /* VMCMS */
  20. #else /* MSDOS */
  21. #include <fcntl.h>
  22. #include <io.h>
  23. #endif /* MSDOS */
  24.  
  25. #ifdef VMCMS
  26. #include <types.h>
  27. #include <stat.h>
  28. #include <dir.h>
  29. DIR * dir;
  30. #define perror(string) fprintf (stderr, "%s\n", string)
  31. #endif /* VMCMS */
  32.  
  33. /* single character decode */
  34. #define DEC(c)  ( table[ (c) & 0177 ] )
  35.  
  36. static char set[] = "+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  37. static char table[128];
  38. int replace;
  39.  
  40. main (argc, argv)
  41. int argc;
  42. char * argv [];
  43.  
  44. {
  45. FILE *in, *out;
  46. int mode;
  47. char source [128];
  48. char cdest [128];
  49. char * dest;
  50. char * temp;
  51. int i;
  52. char buf[80];
  53. int did = 0;
  54. int replflg = 0;
  55. int nameptr = 1;
  56.  
  57. if (argc > 1)
  58.     {
  59.     if (strcmp (argv [1], "-r") == 0 || strcmp (argv [1], "-R") == 0)
  60.         {
  61.         replflg = 1;
  62.         nameptr = 2;
  63.         }
  64.     }
  65. /* input filename */
  66. if (nameptr <= argc - 1)
  67.     {
  68.     strcpy (source, argv [nameptr]);
  69. #ifdef VMCMS
  70.     for (i = nameptr + 1; i < argc; i++)
  71.         {
  72.         strcat (source, " ");
  73.         strcat (source, argv [i]);
  74.         }
  75. #endif /* VMCMS */
  76.     if ((in = fopen(source, "r")) == NULL)
  77.         {
  78. #ifndef VMCMS
  79.         perror(source);
  80. #else /* VMCMS */
  81.         fprintf (stderr, "Cannot open file <%s>\n", source);
  82. #endif /* VMCMS */
  83.         exit(1);
  84.         }
  85.     }
  86. else
  87. #ifdef VMCMS
  88.     {
  89.     fprintf (stderr, "Usage: xxdecode [-r] fn ft [fm] ");
  90.     fprintf (stderr, "[> fn ft [fm] [(options] (bin]\n");
  91.     exit (2);
  92.     }
  93. #else
  94.     in = stdin;
  95. if (isatty (fileno (in)) || argc > 2)
  96.     {
  97.     fprintf (stderr, "Usage: xxdecode [-r] [infile]\n");
  98.     exit(2);
  99.     }
  100. #endif /* VMCMS */
  101.  
  102. while (1)
  103.     {
  104.     dest = cdest;
  105.     /* search for header line */
  106.     for (;;)
  107.         {
  108.         if (fgets(buf, sizeof buf, in) == NULL)
  109.             {
  110.             if (! did)
  111.                 {
  112.                 fprintf (stderr, "No begin line\n");
  113.                 exit (3);
  114.                 }
  115.             else
  116.                 exit (0);
  117.             }
  118.         if (strncmp(buf, "begin ", 6) == 0)
  119.             {
  120.             did = 1;
  121.             break;
  122.             }
  123.         }
  124.     sscanf(buf, "begin %o %s", &mode, dest);
  125.  
  126.     /* handle %user/file format */
  127.     if (dest[0] == '~')
  128.         {
  129. #ifndef VMCMS
  130. #ifndef MSDOS
  131.         char *sl;
  132.         struct passwd *getpwnam();
  133.         char *index();
  134.         struct passwd *user;
  135.         char dnbuf[100];
  136.  
  137.         sl = index(dest, '/');
  138.         if (sl == NULL)
  139.             {
  140.             fprintf(stderr, "Illegal ~user\n");
  141.             exit(3);
  142.             }
  143.         *sl++ = 0;
  144.         user = getpwnam(dest+1);
  145.         if (user == NULL)
  146.             {
  147.             fprintf(stderr, "No such user as %s\n", dest);
  148.             exit(4);
  149.             }
  150.         strcpy(dnbuf, user->pw_dir);
  151.         strcat(dnbuf, "/");
  152.         strcat(dnbuf, sl);
  153.         strcpy(dest, dnbuf);
  154. #else
  155.         dest++;
  156. #endif /* MSDOS */
  157. #endif /* VMCMS */
  158.         }
  159.     replace = replflg;
  160.     if (strcmp (dest, "/dev/stdout") != 0)
  161.         {
  162. #ifdef VMCMS
  163.         for (i = strlen (dest) - 1; i >= 0 && dest [i] != '/'; i--)
  164.             dest [i] = toupper (dest [i]);
  165.         dest = &dest [i + 1];
  166.         for (i = 0; dest [i] && dest [i] != '.'; i++)
  167.             dest [i] = toupper (dest [i]);
  168.         if (dest [i] == '.')
  169.             dest [i] = ' ';
  170.         for (; dest [i] && dest [i] != '.'; i++)
  171.             ;
  172.         if (dest [i] == '.')
  173.             dest [i] = '\0';
  174. #endif /* VMCMS */
  175.         };
  176.         replace = 1;
  177.     /* create output file */
  178.     if (replace)
  179.         {
  180.         fprintf (stderr, "Opening file: %s\n", dest);
  181.         if (strcmp (dest, "/dev/stdout") == 0)
  182.             out = stdout;
  183.         else
  184.             out = fopen(dest, "w");
  185. #ifdef MSDOS
  186.         if (setmode (fileno (out), O_BINARY) == -1)
  187.             {
  188.             perror ("Cannot open stdout as binary\n");
  189.             exit (3);
  190.             }
  191. #endif /* MSDOS */
  192.         if (out == NULL)
  193.             {
  194. #ifndef VMCMS
  195.             perror(dest);
  196. #else /* VMCMS */
  197.             fprintf (stderr, "Cannot open file <%s>\n", dest);
  198. #endif /* VMCMS */
  199.             exit(4);
  200.             }
  201. #ifndef VMCMS
  202.         chmod(dest, mode);
  203. #endif /* VMCMS */
  204.         }
  205.  
  206.     decode(in, out);
  207.  
  208.     if (fgets(buf,sizeof (buf), in) == NULL || strcmp (buf, "end\n"))
  209.         {
  210.         fprintf(stderr, "No end line\n");
  211.         exit(5);
  212.         }
  213.     }
  214. }
  215.  
  216. /*
  217.  * copy from in to out, decoding as you go along.
  218.  */
  219. decode(in, out)
  220. FILE *in;
  221. FILE *out;
  222. {
  223.         char buf[80];
  224.         char *bp;
  225.         int n;
  226.  
  227.         bp=table;       /* clear table */
  228.         for( n=128 ; n ; --n ) {
  229.           *(bp++) = 0;
  230.         };
  231.  
  232.         bp=set;         /* fill table */
  233.         for( n=64 ; n ; --n ) {
  234.           table[ *(bp++) & 0177 ] = 64-n;
  235.         };
  236.  
  237.         for (;;) {
  238.                 /* for each input line */
  239.                 if (fgets(buf, sizeof buf, in) == NULL) {
  240.                         printf("Short file\n");
  241.                         exit(10);
  242.                 }
  243.                 n = DEC(buf[0]);
  244.                 if (n <= 0)
  245.                         break;
  246.  
  247.                 bp = &buf[1];
  248.                 while (n > 0) {
  249.                         if (replace)
  250.                             outdec(bp, out, n);
  251.                         bp += 4;
  252.                         n -= 3;
  253.                 }
  254.         }
  255. }
  256.  
  257. /*
  258.  * output a group of 3 bytes (4 input characters).
  259.  * the input chars are pointed to by p, they are to
  260.  * be output to file f.  n is used to tell us not to
  261.  * output all of them at the end of the file.
  262.  */
  263. outdec(p, f, n)
  264. char *p;
  265. FILE *f;
  266. {
  267.         int c1, c2, c3;
  268.  
  269.         c1 = DEC(*p) << 2 | DEC(p[1]) >> 4;
  270.         c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
  271.         c3 = DEC(p[2]) << 6 | DEC(p[3]);
  272.         if (n >= 1)
  273.                 putc(c1, f);
  274.         if (n >= 2)
  275.                 putc(c2, f);
  276.         if (n >= 3)
  277.                 putc(c3, f);
  278. }
  279.  
  280.  
  281. /* fr: like read but stdio */
  282. int
  283. fr(fd, buf, cnt)
  284. FILE *fd;
  285. char *buf;
  286. int cnt;
  287. {
  288.         int c, i;
  289.  
  290.         for (i=0; i<cnt; i++) {
  291.                 c = getc(fd);
  292.                 if (c == EOF)
  293.                         return(i);
  294.                 buf[i] = c;
  295.         }
  296.         return (cnt);
  297. }
  298.  
  299. /*
  300.  * Return the ptr in sp at which the character c appears;
  301.  * NULL if not found
  302.  */
  303.  
  304. #define NULL    0
  305.  
  306. char *
  307. index(sp, c)
  308. register char *sp, c;
  309. {
  310.         do {
  311.                 if (*sp == c)
  312.                         return(sp);
  313.         } while (*sp++);
  314.         return(NULL);
  315. }
  316.  
  317.  
  318.  
  319.