home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / starter / uuencode.c < prev    next >
C/C++ Source or Header  |  1994-03-05  |  4KB  |  165 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 are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. /*
  19.  * Modified 12 April 1990 by Mark Adler for use on MSDOS systems with
  20.  * Microsoft C and Turbo C.  Standard input problem fixed 29 April 1990
  21.  * as per suggestion by Steve Harrold.
  22.  *
  23.  * Modifed 13 February 1991 by Greg Roelofs for use on VMS systems.
  24.  * Compile and link normally (but note that the shared-image link option
  25.  * produces a binary only 6 blocks long, as opposed to the 152-block one
  26.  * produced by an ordinary link).  To set up the VMS symbol to run the
  27.  * program ("run uuencode filename1 filename2 filename3" won't work), do:
  28.  *        uuencode :== "$disk:[directory]uuencode.exe"
  29.  * and don't forget the leading "$" or it still won't work.  The syntax
  30.  * differs slightly from the Unix and MS-DOS versions since VMS has such
  31.  * an awkward approach to redirection; run the program with no arguments
  32.  * for the usage (or see USAGE below).  The output file is in VMS "stream-
  33.  * LF" format but should be readable by MAIL, ftp, or anything else.
  34.  */
  35.  
  36. #ifndef lint
  37. static char sccsid[] = "@(#)uuencode.c    5.6 (Berkeley) 7/6/88";
  38. #endif /* not lint */
  39.  
  40. #ifdef __MSDOS__        /* For Turbo C */
  41. #define MSDOS 1
  42. #endif
  43.  
  44. /*
  45.  * uuencode [input] output
  46.  *
  47.  * Encode a file so it can be mailed to a remote system.
  48.  */
  49. #include <stdio.h>
  50.  
  51. #ifdef VMS
  52. #  define OUT out    /* force user to specify output file */
  53. #  define NUM_ARGS 3
  54. #  define USAGE "Usage: uuencode [infile] remotefile uufile\n"
  55. #  include <types.h>
  56. #  include <stat.h>
  57. #else
  58. #  define OUT stdout    /* Unix, MS-DOS:  anybody with decent redirection */
  59. #  define NUM_ARGS 2
  60. #  define USAGE "Usage: uuencode [infile] remotefile\n"
  61. #  include <sys/types.h>
  62. #  include <sys/stat.h>
  63. #endif
  64.  
  65. #if MSDOS
  66. #include <io.h>
  67. #include <fcntl.h>
  68. #endif
  69.  
  70. /* ENC is the basic 1-character encoding function to make a char printing */
  71. #define ENC(c) ((c) ? ((c) & 077) + ' ': '`')
  72.  
  73. main(argc, argv)
  74. char **argv;
  75. {
  76. #ifdef VMS
  77.     FILE *out;
  78. #endif
  79.     FILE *in;
  80.     struct stat sbuf;
  81.     int mode;
  82.  
  83.     /* optional 1st argument */
  84.     if (argc > NUM_ARGS) {
  85.         if ((in = fopen(argv[1], "r")) == NULL) {
  86.             perror(argv[1]);
  87.             exit(1);
  88.         }
  89.         argv++; argc--;
  90.     } else
  91.         in = stdin;
  92.  
  93. #if MSDOS
  94.     /* set input file mode to binary for MSDOS systems */
  95.     setmode(fileno(in), O_BINARY);
  96. #endif
  97.  
  98.     if (argc != NUM_ARGS) {
  99.         fprintf(stderr, USAGE);
  100.         exit(2);
  101.     }
  102.  
  103. #ifdef VMS   /* mandatory 3rd argument is name of uuencoded file */
  104.     if ((out = fopen(argv[2], "w")) == NULL) {
  105.         perror(argv[2]);
  106.         exit(4);
  107.     }
  108. #endif
  109.  
  110.     /* figure out the input file mode */
  111.     if (fstat(fileno(in), &sbuf) < 0 || !isatty(fileno(in)))
  112.         mode = 0666 & ~umask(0666);
  113.     else
  114.         mode = sbuf.st_mode & 0777;
  115.     fprintf(OUT, "begin %o %s\n", mode, argv[1]);
  116.  
  117.     encode(in, OUT);
  118.  
  119.     fprintf(OUT, "end\n");
  120.     exit(0);
  121. }
  122.  
  123. /*
  124.  * copy from in to out, encoding as you go along.
  125.  */
  126. encode(in, out)
  127. register FILE *in;
  128. register FILE *out;
  129. {
  130.     char buf[80];
  131.     register int i, n;
  132.  
  133.     for (;;) {
  134.         /* 1 (up to) 45 character line */
  135.         n = fread(buf, 1, 45, in);
  136.         putc(ENC(n), out);
  137.  
  138.         for (i=0; i<n; i += 3)
  139.             outdec(&buf[i], out);
  140.  
  141.         putc('\n', out);
  142.         if (n <= 0)
  143.             break;
  144.     }
  145. }
  146.  
  147. /*
  148.  * output one group of 3 bytes, pointed at by p, on file f.
  149.  */
  150. outdec(p, f)
  151. register char *p;
  152. register FILE *f;
  153. {
  154.     register int c1, c2, c3, c4;
  155.  
  156.     c1 = *p >> 2;
  157.     c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
  158.     c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
  159.     c4 = p[2] & 077;
  160.     putc(ENC(c1), f);
  161.     putc(ENC(c2), f);
  162.     putc(ENC(c3), f);
  163.     putc(ENC(c4), f);
  164. }
  165.