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