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