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

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