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