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