home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / PPPBCKP / SRC / SRC15B32.ZIP / UUMAIN.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  15KB  |  587 lines

  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <dir.h>
  6. #include <dos.h>
  7. #include <share.h>
  8. #include <sys\stat.h>
  9. #include <alloc.h>
  10. #include <io.h>
  11. #include <fcntl.h>
  12. #include <time.h>
  13. #include <errno.h>
  14. #include "uu.h"
  15. #include "net.h"
  16. #include "vardec.h"
  17. #include "version.h"
  18.  
  19. unsigned _stklen = 8192;
  20.  
  21. #define MAX_BUF 1024
  22.  
  23. #define SHARE_LEVEL 10
  24. #define WAIT_TIME 10
  25. #define TRIES 100
  26. #define MT_DESQVIEW 0x01
  27. #define MT_WINDOWS  0x02
  28. #define MT_OS2      0x04
  29. #define MT_NB       0x40
  30.  
  31.  
  32. #define LAST(s) s[strlen(s)-1]
  33.  
  34. char buf[MAX_BUF];
  35. int multitasker = 0;
  36. char *version = "Freeware UU Encode/Decode " VERSION;
  37.  
  38. void dv_pause(void)
  39. {
  40.   __emit__(0xb8, 0x1a, 0x10, 0xcd, 0x15);
  41.   __emit__(0xb8, 0x00, 0x10, 0xcd, 0x15);
  42.   __emit__(0xb8, 0x25, 0x10, 0xcd, 0x15);
  43. }
  44.  
  45. void win_pause(void)
  46. {
  47.   __emit__(0x55, 0xb8, 0x80, 0x16, 0xcd, 0x2f, 0x5d);
  48. }
  49.  
  50. int get_dos_version(void)
  51. {
  52.   _AX = 0x3000;
  53.   geninterrupt(0x21);
  54.   if (_AX % 256 >= 10) {
  55.     multitasker |= MT_OS2;
  56.   }
  57.   return (_AX);
  58. }
  59.  
  60. int get_dv_version(void)
  61. {
  62.   int v;
  63.  
  64.   if (multitasker & MT_OS2)
  65.     return 0;
  66.   _AX = 0x2b01;
  67.   _CX = 0x4445;
  68.   _DX = 0x5351;
  69.   geninterrupt(0x21);
  70.   if (_AL == 0xff) {
  71.     return 0;
  72.   } else {
  73.     v = _BX;
  74.     multitasker |= MT_DESQVIEW;
  75.     return v;
  76.   }
  77. }
  78.  
  79. int get_win_version(void)
  80. {
  81.   int v = 0;
  82.  
  83.   __emit__(0x55, 0x06, 0x53);
  84.   _AX = 0x352f;
  85.   geninterrupt(0x21);
  86.   _AX = _ES;
  87.   if (_AX | _BX) {
  88.     _AX = 0x1600;
  89.     geninterrupt(0x2f);
  90.     v = _AX;
  91.     if (v % 256 <= 1)
  92.       v = 0;
  93.   }
  94.   __emit__(0x5b, 0x07, 0x5d);
  95.   if (v != 0)
  96.     multitasker |= MT_WINDOWS;
  97.   return (v);
  98. }
  99.  
  100. int get_nb_version(void)
  101. {
  102.   _AX = 0;
  103.   geninterrupt(0x2A);
  104.   return (_AH);
  105. }
  106.  
  107. void detect_multitask(void)
  108. {
  109.   get_dos_version();
  110.   get_win_version();
  111.   get_dv_version();
  112.   if (multitasker < 2)
  113.     if (get_nb_version())
  114.       multitasker = MT_NB;
  115. }
  116.  
  117. void giveup_timeslice(void)
  118. {
  119.   if (multitasker) {
  120.     switch (multitasker) {
  121.  case 1:
  122.  case 3:
  123.         dv_pause();
  124.         break;
  125.       case 2:
  126.       case 4:
  127.       case 5:
  128.       case 6:
  129.       case 7:
  130.         win_pause();
  131.         break;
  132.       default:
  133.         break;
  134.     }
  135.   }
  136. }
  137.  
  138. int sh_read(int handle, void *buf, unsigned len)
  139. {
  140.   if (handle == -1) {
  141.     return (-1);
  142.   }
  143.   return (read(handle, buf, len));
  144. }
  145.  
  146. long sh_lseek(int handle, long offset, int fromwhere)
  147. {
  148.   if (handle == -1) {
  149.     return (-1L);
  150.   }
  151.   return (lseek(handle, offset, fromwhere));
  152. }
  153.  
  154. int sh_write(int handle, void *buffer, unsigned long len)
  155. {
  156.   if (handle == -1) {
  157.     return (-1);
  158.   }
  159.   return (write(handle, buffer, (unsigned) len));
  160. }
  161.  
  162. int sh_close(int f)
  163. {
  164.   if (f != -1)
  165.     close(f);
  166.   return (-1);
  167. }
  168.  
  169. int sh_open(char *path, int file_access, unsigned fmode)
  170. {
  171.   int handle, count, share;
  172.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  173.  
  174.   if ((file_access & O_RDWR) || (file_access & O_WRONLY) || (fmode & S_IWRITE)) {
  175.     share = SH_DENYRW;
  176.   } else {
  177.     share = SH_DENYWR;
  178.   }
  179.   handle = open(path, file_access | share, fmode);
  180.   if (handle < 0) {
  181.     count = 1;
  182.     fnsplit(path, drive, dir, file, ext);
  183.     if (access(path, 0) != -1) {
  184.       delay(WAIT_TIME);
  185.       handle = open(path, file_access | share, fmode);
  186.       while (((handle < 0) && (errno == EACCES)) && (count < TRIES)) {
  187.         if (count % 2)
  188.           delay(WAIT_TIME);
  189.         else
  190.           giveup_timeslice();
  191.         count++;
  192.         handle = open(path, file_access | share, fmode);
  193.       }
  194.     }
  195.   }
  196.   return (handle);
  197. }
  198.  
  199. int sh_open1(char *path, int access)
  200. {
  201.   unsigned fmode;
  202.  
  203.   fmode = 0;
  204.   if ((access & O_RDWR) || (access & O_WRONLY))
  205.     fmode |= S_IWRITE;
  206.   if ((access & O_RDWR) || (access & O_RDONLY))
  207.     fmode |= S_IREAD;
  208.   return (sh_open(path, access, fmode));
  209. }
  210.  
  211. scanfor(char *token, FILE * in)
  212. {
  213.   long pos;
  214.  
  215.   pos = ftell(in);
  216.   while (fgets(buf, MAX_BUF, in) && strncmpi(buf, token, strlen(token))) {
  217.     pos = ftell(in);
  218.   }
  219.   rewind(in);
  220.   fseek(in, pos, 0);
  221.   pos = ftell(in);
  222.   return (!strncmpi(buf, "begin ", 6));
  223. }
  224.  
  225. scanfornet(FILE * in, char *net_name)
  226. {
  227.   char *ss;
  228.   int found = 0;
  229.  
  230.   while ((fgets(buf, MAX_BUF, in)) && !found) {
  231.     if (strncmpi(buf, "subject:", strlen("subject:"))) {
  232.       ss = strtok(buf, " ");
  233.       ss = strtok(NULL, " ");
  234.       if (ss[0] == '@') {
  235.         found = 1;
  236.         strcpy(net_name, ss);
  237.       }
  238.     }
  239.   }
  240.   rewind(in);
  241.   return found;
  242. }
  243.  
  244. void cd_to(char *s)
  245. {
  246.   char s1[81];
  247.   int i, db;
  248.  
  249.   strcpy(s1, s);
  250.   i = strlen(s1) - 1;
  251.   db = (s1[i] == '\\');
  252.   if (i == 0)
  253.     db = 0;
  254.   if ((i == 2) && (s1[1] == ':'))
  255.     db = 0;
  256.   if (db)
  257.     s1[i] = 0;
  258.   chdir(s1);
  259.   if (s[1] == ':') {
  260.     setdisk(s[0] - 'A');
  261.     if (s[2] == 0)
  262.       chdir("\\");
  263.   }
  264. }
  265.  
  266. void get_dir(char *s, int be)
  267. {
  268.   strcpy(s, "X:\\");
  269.   s[0] = 'A' + getdisk();
  270.   getcurdir(0, &(s[3]));
  271.   if (be) {
  272.     if (s[strlen(s) - 1] != '\\')
  273.       strcat(s, "\\");
  274.   }
  275. }
  276.  
  277. int exist(char *s)
  278. {
  279.   int i;
  280.   struct ffblk ff;
  281.  
  282.   i = findfirst(s, &ff, FA_HIDDEN);
  283.   if (i)
  284.     return (0);
  285.   else
  286.     return (1);
  287. }
  288.  
  289. void output(char *fmt, ...)
  290. {
  291.   va_list v;
  292.   char s[255];
  293.  
  294.   va_start(v, fmt);
  295.   vsprintf(s, fmt, v);
  296.   va_end(v);
  297.   fputs(s, stderr);
  298. }
  299.  
  300.  
  301. int copyfile(char *infile, char *outfile)
  302. {
  303.   int f1, f2, i;
  304.   char *b, s[181], s1[21], s2[81], s3[81];
  305.   struct ftime ft;
  306.  
  307.   if ((strcmp(infile, outfile) != 0) && (exist(infile))) {
  308.     if (exist(outfile)) {
  309.       fnsplit(outfile, s3, s2, s1, NULL);
  310.       i = 0;
  311.       sprintf(s, "%s%s%s.%03d", s3, s2, s1, i);
  312.       while (exist(s))
  313.         sprintf(s, "%s%s%s.%03d", s3, s2, s1, ++i);
  314.       strcpy(outfile, s);
  315.     }
  316.     output(" as %s", outfile);
  317.     if ((b = (char *) farmalloc(16400)) == NULL)
  318.       return 0;
  319.     f1 = open(infile, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
  320.     if (!f1) {
  321.       farfree(b);
  322.       return 0;
  323.     }
  324.     getftime(f1, &ft);
  325.     f2 = open(outfile, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  326.     if (!f2) {
  327.       farfree(b);
  328.       close(f1);
  329.       return 0;
  330.     }
  331.     i = read(f1, (void *) b, 16384);
  332.     while (i > 0) {
  333.       write(f2, (void *) b, i);
  334.       i = read(f1, (void *) b, 16384);
  335.     }
  336.     f1 = close(f1);
  337.     setftime(f2, &ft);
  338.     f2 = close(f2);
  339.     farfree(b);
  340.   }
  341.   return 1;
  342. }
  343.  
  344. char *stripfn(char *fn)
  345. {
  346.   static char ofn[15];
  347.   int i, i1;
  348.   char s[81];
  349.  
  350.   i1 = -1;
  351.   for (i = 0; i < strlen(fn); i++)
  352.     if ((fn[i] == '\\') || (fn[i] == ':') || (fn[i] == '/'))
  353.       i1 = i;
  354.   if (i1 != -1)
  355.     strcpy(s, &(fn[i1 + 1]));
  356.   else
  357.     strcpy(s, fn);
  358.   for (i = 0; i < strlen(s); i++)
  359.     if ((s[i] >= 'A') && (s[i] <= 'Z'))
  360.       s[i] = s[i] - 'A' + 'a';
  361.   i = 0;
  362.   while (s[i] != 0) {
  363.     if (s[i] == 32)
  364.       strcpy(&s[i], &s[i + 1]);
  365.     else
  366.       ++i;
  367.   }
  368.   strcpy(ofn, s);
  369.   return (ofn);
  370. }
  371.  
  372. void ssm(char *s)
  373. {
  374.   int f, i, i1;
  375.   char s1[161];
  376.   shortmsgrec sm;
  377.   configrec syscfg;
  378.  
  379.   sprintf(s1, "CONFIG.DAT");
  380.   f = sh_open1(s1, O_RDWR | O_BINARY);
  381.   if (f < 0)
  382.     return;
  383.   sh_read(f, (void *) (&syscfg), sizeof(configrec));
  384.   sh_close(f);
  385.   sprintf(s1, "%sSMW.DAT", syscfg.datadir);
  386.   f = sh_open(s1, O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  387.   if (f < 0)
  388.     return;
  389.   i = (int) (filelength(f) / sizeof(shortmsgrec));
  390.   i1 = i - 1;
  391.   if (i1 >= 0) {
  392.     sh_lseek(f, ((long) (i1)) * sizeof(shortmsgrec), SEEK_SET);
  393.     sh_read(f, (void *) &sm, sizeof(shortmsgrec));
  394.     while ((sm.tosys == 0) && (sm.touser == 0) && (i1 > 0)) {
  395.       --i1;
  396.       sh_lseek(f, ((long) (i1)) * sizeof(shortmsgrec), SEEK_SET);
  397.       sh_read(f, (void *) &sm, sizeof(shortmsgrec));
  398.     }
  399.     if ((sm.tosys) || (sm.touser))
  400.       ++i1;
  401.   } else
  402.     i1 = 0;
  403.   sm.tosys = 0;
  404.   sm.touser = 1;
  405.   strncpy(sm.message, s, 80);
  406.   sm.message[80] = 0;
  407.   sh_lseek(f, ((long) (i1)) * sizeof(shortmsgrec), SEEK_SET);
  408.   sh_write(f, (void *) &sm, sizeof(shortmsgrec));
  409.   sh_close(f);
  410. }
  411.  
  412. main(int argc, char *argv[])
  413. {
  414.   FILE *out = NULL, *in = NULL;
  415.   char outname[181], net_name[21];
  416.   char cur_dir[181], temp_dir[181], s1[181], s2[181], s3[21], s4[21], s5[21];
  417.   int i;
  418.  
  419.   detect_multitask();
  420.  
  421.   if (argc == 4 || argc == 5) {
  422.     if (strcmpi(argv[1], "-encode") == 0 && argc == 4) {
  423.       if (((in = fopen(argv[2], "r")) != NULL) && ((out = fopen(argv[3], "at+")) != NULL)) {
  424.         output(" %ld bytes.", uuencode(in, out, argv[2]));
  425.         if (in)
  426.           fclose(in);
  427.         if (out)
  428.           fclose(out);
  429.         exit(EXIT_SUCCESS);
  430.       } else {
  431.         exit(EXIT_FAILURE);
  432.       }
  433.     } else
  434.       if (strcmpi(argv[1], "-decode") == 0 && argc == 5) {
  435.       get_dir(cur_dir, 1);
  436.       strcpy(temp_dir, argv[3]);
  437.       if (LAST(temp_dir) == '\\')
  438.         LAST(temp_dir) = 0;
  439.       cd_to(temp_dir);
  440.       if ((in = fopen(argv[2], "r")) != NULL) {
  441.         if (!scanfornet(in, net_name))
  442.           net_name[0] = 0;
  443.         rewind(in);
  444.         scanfor("begin", in);
  445.         switch (uudecode(in, argv[3], outname)) {
  446.           case UU_NO_MEM:
  447.             output("\n ■ Insufficient memory to decode... moved to CHECKNET.");
  448.             sprintf(s1, "%s\\%s", temp_dir, argv[2]);
  449.             sprintf(s2, "%sCHECKNET\\%s", argv[4], argv[2]);
  450.             if (copyfile(s1, s2))
  451.               unlink(s1);
  452.             cd_to(cur_dir);
  453.             if (in)
  454.               fclose(in);
  455.             sprintf(s1, "Out of memory decoding %s - moved to CHECKNET!", argv[2]);
  456.             ssm(s1);
  457.             exit(EXIT_FAILURE);
  458.           case UU_BAD_BEGIN:
  459.             output("\n ■ Appears to be a standard message... moving to SPOOL");
  460.             sprintf(s1, "%s\\%s", temp_dir, argv[2]);
  461.             while (LAST(argv[2]) != '.')
  462.               LAST(argv[2]) = 0;
  463.             strcat(argv[2], "MSG");
  464.             sprintf(s2, "%sSPOOL\\%s", argv[4], argv[2]);
  465.             if (copyfile(s1, s2))
  466.               unlink(s1);
  467.             cd_to(cur_dir);
  468.             if (in)
  469.               fclose(in);
  470.             exit(EXIT_FAILURE);
  471.           case UU_CANT_OPEN:
  472.             output("\n ■ Cannot open %s%s", argv[4], outname);
  473.             cd_to(cur_dir);
  474.             if (in)
  475.               fclose(in);
  476.             exit(EXIT_FAILURE);
  477.           case UU_CHECKSUM:
  478.             output("\n ■ Bad checksum... moving packet to CHECKNET");
  479.             sprintf(s1, "%s\\%s", temp_dir, argv[2]);
  480.             while (LAST(argv[2]) != '.')
  481.               LAST(argv[2]) = 0;
  482.             strcat(argv[2], "MSG");
  483.             sprintf(s2, "%sCHECKNET\\%s", argv[4], argv[2]);
  484.             if (copyfile(s1, s2))
  485.               unlink(s1);
  486.             cd_to(cur_dir);
  487.             if (in)
  488.               fclose(in);
  489.             sprintf(s1, "Bad checksum decoding %s - moved to CHECKNET!", argv[2]);
  490.             ssm(s1);
  491.             exit(EXIT_FAILURE);
  492.           case UU_BAD_END:
  493.             output("\n ■ \'end\' not found in message... moving to CHECKNET");
  494.             sprintf(s1, "%s\\%s", temp_dir, argv[2]);
  495.             while (LAST(argv[2]) != '.')
  496.               LAST(argv[2]) = 0;
  497.             strcat(argv[2], "MSG");
  498.             sprintf(s2, "%sCHECKNET\\%s", argv[4], argv[2]);
  499.             if (copyfile(s1, s2))
  500.               unlink(s1);
  501.             cd_to(cur_dir);
  502.             if (in)
  503.               fclose(in);
  504.             sprintf(s1, "No \'end\' found in %s - moved to CHECKNET!", argv[2]);
  505.             ssm(s1);
  506.             exit(EXIT_FAILURE);
  507.           case UU_SUCCESS:
  508.             output("\n ■ Decoded %s", stripfn(outname));
  509.             fnsplit(outname, NULL, NULL, s4, s3);
  510.             sprintf(s5, "%s%s", s4, s3);
  511.             if ((strcmpi(s3, ".NET") == NULL) && (strncmpi(argv[2], "PKT", 3) == NULL)) {
  512.               unlink(argv[2]);
  513.               i = 0;
  514.               sprintf(s2, "%sP1-%03d.NET", argv[4], i);
  515.               while (exist(s2))
  516.                 sprintf(s2, "%sP1-%03d.NET", argv[4], ++i);
  517.               sprintf(s1, "%s\\%s", temp_dir, stripfn(outname));
  518.               if (!copyfile(s1, s2)) {
  519.                 output("\n ■ Error creating %s", s2);
  520.                 cd_to(cur_dir);
  521.                 if (in)
  522.                   fclose(in);
  523.                 exit(EXIT_FAILURE);
  524.               } else
  525.                 unlink(s1);
  526.             } else {
  527.               sprintf(s1, "Received transferred file : %s.", s5);
  528.               ssm(s1);
  529.               sprintf(s1, "%s\\%s", temp_dir, stripfn(outname));
  530.               sprintf(s2, "%sCHECKNET\\%s", argv[4], stripfn(outname));
  531.               if (exist(s2)) {
  532.                 s2[strlen(s2 - 1)] = 0;
  533.                 i = 0;
  534.                 sprintf(s2, "%sCHECKNET\\%s%d", argv[4], stripfn(outname), i);
  535.                 while (exist(s2)) {
  536.                   sprintf(s2, "%sCHECKNET\\%s%d", argv[4], stripfn(outname), ++i);
  537.                   if (i > 9)
  538.                     break;
  539.                 }
  540.               }
  541.               if (!copyfile(s1, s2)) {
  542.                 output("\n ■ Error creating %s", s2);
  543.                 cd_to(cur_dir);
  544.                 if (in)
  545.                   fclose(in);
  546.                 exit(EXIT_FAILURE);
  547.               } else {
  548.                 unlink(s1);
  549.                 sprintf(s1, "%s\\%s", temp_dir, argv[2]);
  550.                 unlink(s1);
  551.               }
  552.             }
  553.             cd_to(cur_dir);
  554.             if (in)
  555.               fclose(in);
  556.             exit(EXIT_SUCCESS);
  557.           default:
  558.             output("\n ■ Unknown error... moving packet to CHECKNET");
  559.             sprintf(s1, "%s\\%s", temp_dir, argv[2]);
  560.             while (LAST(argv[2]) != '.')
  561.               LAST(argv[2]) = 0;
  562.             strcat(argv[2], "MSG");
  563.             sprintf(s2, "%sCHECKNET\\%s", argv[4], argv[2]);
  564.             if (copyfile(s1, s2))
  565.               unlink(s1);
  566.             cd_to(cur_dir);
  567.             if (in)
  568.               fclose(in);
  569.             sprintf(s1, "Unknown error processing %s - moved to CHECKNET!", argv[2]);
  570.             ssm(s1);
  571.             exit(EXIT_FAILURE);
  572.         }
  573.       } else {
  574.         cd_to(cur_dir);
  575.         output("\n ■ Input file %s not found.", argv[2]);
  576.         if (in)
  577.           fclose(in);
  578.         exit(EXIT_FAILURE);
  579.       }
  580.       }
  581.   } else
  582.     output("\n ■ %s\n", version);
  583.   if (in)
  584.     fclose(in);
  585.   return 0;
  586. }
  587.