home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / PPPBCKP / SRC / SRC15B85.ZIP / UU.CPP < prev    next >
C/C++ Source or Header  |  1997-11-11  |  4KB  |  159 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <malloc.h>
  5. #include <dir.h>
  6. #include <ctype.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <io.h>
  10. #include <fcntl.h>
  11. #include "uu.h"
  12. #include "vardec.h"
  13.  
  14. #define UUENC(c) ((c) ? ((c) & 077) + ' ': '`')
  15. #define UUDEC(c)  (((c)!='`')?(((c)-' ')&077):(0))   /* single char decode */
  16. #define MAXLINE 1024
  17.  
  18. #define min(a,b)    (((a) < (b)) ? (a) : (b))
  19.  
  20. char *strippath(char *fname)
  21. {
  22.   char *p;
  23.  
  24.   p = (char *)_fstrrchr(fname, '\\');
  25.   if (!p)
  26.     p = (char *)_fstrrchr(fname, ':');
  27.   if (!p)
  28.     p = fname;
  29.   return (p);
  30. }
  31.  
  32. char *trim(char *str)
  33. {
  34.   int i;
  35.  
  36.   if (str == NULL)
  37.     return (str);
  38.   for (i = strlen(str) - 1; (i >= 0) && isspace(str[i]); str[i--] = '\0');
  39.   while (isspace(str[0]))
  40.     strcpy(str, str + 1);
  41.   return (str);
  42. }
  43.  
  44. long uuencode_aux(FILE *in, FILE *out)
  45. {
  46.   long len = 0L;
  47.   char buf[80];
  48.   int c1, c2, c3, c4, i, n;
  49.  
  50.   for (;;) {
  51.     /* 1 (up to) 45 character line */
  52.     n = fread(buf, 1, 45, in);
  53.     putc(UUENC(n), out);
  54.     for (i = 0; i < n; i += 3) {
  55.       c1 = buf[i] >> 2;
  56.       c2 = ((buf[i] << 4) & 060) | ((buf[i + 1] >> 4) & 017);
  57.       c3 = ((buf[i + 1] << 2) & 074) | ((buf[i + 2] >> 6) & 03);
  58.       c4 = buf[i + 2] & 077;
  59.       putc(UUENC(c1), out);
  60.       putc(UUENC(c2), out);
  61.       putc(UUENC(c3), out);
  62.       putc(UUENC(c4), out);
  63.     }
  64.     putc('\n', out);
  65.     if (n <= 0)
  66.       break;
  67.     else
  68.       len += n;
  69.   }
  70.   return (len);
  71. }
  72.  
  73. long uuencode(FILE *in, FILE *out, char *name)
  74. {
  75.   long len = 0L;
  76.   struct stat sbuf;
  77.   int mode;
  78.   char s[12], s1[5];
  79.  
  80.   setmode(fileno(in), O_BINARY);
  81.   if (fstat(fileno(in), &sbuf) < 0)
  82.     mode = 0666 & ~umask(0666);
  83.   else
  84.     mode = sbuf.st_mode & 0777;
  85.   fnsplit(name, NULL, NULL, s, s1);
  86.   fprintf(out, "begin %o %s%s\n", mode, s, s1);
  87.   len = uuencode_aux(in, out);
  88.   fprintf(out, "end\n\n");
  89.   if (out != NULL)
  90.     fclose(out);
  91.   return (len);
  92. }
  93.  
  94. void *uudecode_aux(char *in, unsigned char *out)
  95. {
  96.   out[0] = (UUDEC(in[0]) << 2) | (UUDEC(in[1]) >> 4);
  97.   out[1] = (UUDEC(in[1]) << 4) | (UUDEC(in[2]) >> 2);
  98.   out[2] = (UUDEC(in[2]) << 6) | (UUDEC(in[3]));
  99.   return (out);
  100. }
  101.  
  102. #define UU_FREE_ALL free(fname); free(buf);
  103.  
  104. int uudecode(FILE *in, char *path, char *name)
  105. {
  106.   FILE *out;
  107.   int i = 0, done = 0, len, wlen;
  108.   char *buf, dest[121], *fname;
  109.   unsigned char   temp[4];
  110.   unsigned mode;
  111.  
  112.   if ((fname = ((char *) malloc(strlen(path) + 15))) <= 0) {
  113.     return (UU_NO_MEM);
  114.   }
  115.   if ((buf = (char *) malloc(MAXLINE)) <= 0) {
  116.     free(fname);
  117.     return (UU_NO_MEM);
  118.   }
  119.   if (fscanf(in, "begin %o %s\n", &mode, dest) < 2) {
  120.     UU_FREE_ALL;
  121.     return (UU_BAD_BEGIN);
  122.   }
  123.   if (name)
  124.     strcpy(name, dest);
  125.   sprintf(fname, "%s%s", path, strippath(dest));
  126.   if ((out = fsh_open(fname, "wb")) <= 0) {
  127.     UU_FREE_ALL;
  128.     return (UU_CANT_OPEN);
  129.   }
  130.   while (fgets(buf, MAXLINE, in)) {
  131.     trim(buf);
  132.     if (strcmpi(buf, "end") == 0) {
  133.       done = 1;
  134.       break;
  135.     }
  136.     if ((strlen(buf) == 22) && ((buf[0] == '.') && (buf[1] == '.')))
  137.       strcpy(buf, buf + 1);
  138.     if ((strlen(buf) - 1) != (len = (((UUDEC(buf[0]) + 2) / 3) * 4))) {
  139.       UU_FREE_ALL;
  140.       if (out != NULL)
  141.         fclose(out);
  142.       unlink(fname);
  143.       return (UU_CHECKSUM);
  144.     }
  145.     wlen=UUDEC(buf[0]);
  146.     for (i = 1; i < len; i += 4) {
  147.       fwrite(uudecode_aux(&buf[i], temp), 1, min(wlen, 3), out);
  148.       wlen -= 3;
  149.     }
  150.   }
  151.   UU_FREE_ALL;
  152.   if (out != NULL)
  153.     fclose(out);
  154.   if (done)
  155.     return (UU_SUCCESS);
  156.   unlink(fname);
  157.   return (UU_BAD_END);
  158. }
  159.