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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdarg.h>
  5. #include <dos.h>
  6. #include <fcntl.h>
  7. #include <sys/stat.h>
  8. #include <ctype.h>
  9. #include <mem.h>
  10. #include <conio.h>
  11. #include <io.h>
  12. #include <share.h>
  13. #include <errno.h>
  14. #include <malloc.h>
  15. #include <dir.h>
  16. #include <time.h>
  17. #include <process.h>
  18. #include <direct.h>
  19. #include "vardec.h"
  20. #include "net.h"
  21. #include "version.h"
  22.  
  23. #define NUL '\0'
  24. #define LAST(s) s[strlen(s)-1]
  25. #define MAX_PATH 79
  26.  
  27. #define SHARE_LEVEL 10
  28. #define WAIT_TIME 10
  29. #define TRIES 100
  30.  
  31. #define MT_DESQVIEW 0x01
  32. #define MT_WINDOWS  0x02
  33. #define MT_OS2      0x04
  34. #define MT_NB       0x40
  35.  
  36. #define VIDEO 0x10
  37.  
  38. #define INI_NETWORK   0x01
  39. #define INI_GENERAL   0x02
  40. #define INI_NEWS      0x04
  41.  
  42. char *version = "Freeware PPP Net Packet Engine " VERSION;
  43. char *author = "Contact Frank Reid at edare@abs.net or 1@8213.WWIVnet for support";
  44.  
  45. unsigned _stklen = 8192;
  46.  
  47. configrec syscfg;
  48. configoverrec syscfgovr;
  49. net_networks_rec netcfg;
  50. net_system_list_rec *netsys;
  51.  
  52. int multitasker = 0, ini_section = 0;
  53. char wwiv_net_no[20], maindir[121];
  54. char net_name[16], net_data[121];
  55. unsigned short net_sysnum;
  56. int num_sys_list, net_num, net_num_max, netnum;
  57. static int lsl_loaded;
  58.  
  59. char SMTPHOST[60], POPHOST[60], NEWSHOST[60], POPNAME[60], POPPASS[25];
  60.  
  61. char IPADDR[21], NETMASK[21], FWDNAME[60], FWDDOM[60];
  62. char DNS[21], DOMAIN[60], GATEWAY[60], temp_dir[MAXPATH];
  63. unsigned int KEEPSENT = 0, ALLMAIL = 1, CLEANUP = 0, MOREINFO = 0, TIMEOUT = 60, SOCK_DELAY = 30, INACTIVE = 60;
  64. unsigned int ONECALL = 0, PURGE = 1;
  65. int instance;
  66.  
  67. char *xenviron[50];
  68.  
  69. void dv_pause(void)
  70. {
  71.   __emit__(0xb8, 0x1a, 0x10, 0xcd, 0x15);
  72.   __emit__(0xb8, 0x00, 0x10, 0xcd, 0x15);
  73.   __emit__(0xb8, 0x25, 0x10, 0xcd, 0x15);
  74. }
  75.  
  76. void win_pause(void)
  77. {
  78.   __emit__(0x55, 0xb8, 0x80, 0x16, 0xcd, 0x2f, 0x5d);
  79. }
  80.  
  81. int get_dos_version(void)
  82. {
  83.   _AX = 0x3000;
  84.   geninterrupt(0x21);
  85.   if (_AX % 256 >= 10) {
  86.     multitasker |= MT_OS2;
  87.   }
  88.   return (_AX);
  89. }
  90.  
  91. int get_dv_version(void)
  92. {
  93.   int v;
  94.  
  95.   if (multitasker & MT_OS2)
  96.     return 0;
  97.   _AX = 0x2b01;
  98.   _CX = 0x4445;
  99.   _DX = 0x5351;
  100.   geninterrupt(0x21);
  101.   if (_AL == 0xff) {
  102.     return 0;
  103.   } else {
  104.     v = _BX;
  105.     multitasker |= MT_DESQVIEW;
  106.     return v;
  107.   }
  108. }
  109.  
  110. int get_win_version(void)
  111. {
  112.   int v = 0;
  113.  
  114.   __emit__(0x55, 0x06, 0x53);
  115.   _AX = 0x352f;
  116.   geninterrupt(0x21);
  117.   _AX = _ES;
  118.   if (_AX | _BX) {
  119.     _AX = 0x1600;
  120.     geninterrupt(0x2f);
  121.     v = _AX;
  122.     if (v % 256 <= 1)
  123.       v = 0;
  124.   }
  125.   __emit__(0x5b, 0x07, 0x5d);
  126.   if (v != 0)
  127.     multitasker |= MT_WINDOWS;
  128.   return (v);
  129. }
  130.  
  131. int get_nb_version(void)
  132. {
  133.   _AX = 0;
  134.   geninterrupt(0x2A);
  135.   return (_AH);
  136. }
  137.  
  138. void detect_multitask(void)
  139. {
  140.   get_dos_version();
  141.   get_win_version();
  142.   get_dv_version();
  143.   if (multitasker < 2)
  144.     if (get_nb_version())
  145.       multitasker = MT_NB;
  146. }
  147.  
  148. void giveup_timeslice(void)
  149. {
  150.   if (multitasker) {
  151.     switch (multitasker) {
  152.  case 1:
  153.  case 3:
  154.         dv_pause();
  155.         break;
  156.       case 2:
  157.       case 4:
  158.       case 5:
  159.       case 6:
  160.       case 7:
  161.         win_pause();
  162.         break;
  163.       default:
  164.         break;
  165.     }
  166.   }
  167. }
  168.  
  169. char *stripspace(char *str)
  170. {
  171.   char *obuf, *nbuf;
  172.  
  173.   if (str) {
  174.     for (obuf = str, nbuf = str; *obuf; ++obuf) {
  175.       if (!isspace(*obuf))
  176.         *nbuf++ = *obuf;
  177.     }
  178.     *nbuf = NULL;
  179.   }
  180.   return (str);
  181. }
  182.  
  183. int sh_write(int handle, void *buffer, unsigned long len)
  184. {
  185.   if (handle == -1) {
  186.     return (-1);
  187.   }
  188.   return (write(handle, buffer, (unsigned) len));
  189. }
  190.  
  191. int sh_open(char *path, int file_access, unsigned fmode)
  192. {
  193.   int handle, count, share;
  194.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  195.  
  196.   if ((file_access & O_RDWR) || (file_access & O_WRONLY) || (fmode & S_IWRITE)) {
  197.     share = SH_DENYRW;
  198.   } else {
  199.     share = SH_DENYWR;
  200.   }
  201.   handle = open(path, file_access | share, fmode);
  202.   if (handle < 0) {
  203.     count = 1;
  204.     fnsplit(path, drive, dir, file, ext);
  205.     if (access(path, 0) != -1) {
  206.       delay(WAIT_TIME);
  207.       handle = open(path, file_access | share, fmode);
  208.       while (((handle < 0) && (errno == EACCES)) && (count < TRIES)) {
  209.         if (count % 2)
  210.           delay(WAIT_TIME);
  211.         else
  212.           giveup_timeslice();
  213.         count++;
  214.         handle = open(path, file_access | share, fmode);
  215.       }
  216.     }
  217.   }
  218.   return (handle);
  219. }
  220.  
  221. int sh_open1(char *path, int access)
  222. {
  223.   unsigned fmode;
  224.  
  225.   fmode = 0;
  226.   if ((access & O_RDWR) || (access & O_WRONLY))
  227.     fmode |= S_IWRITE;
  228.   if ((access & O_RDWR) || (access & O_RDONLY))
  229.     fmode |= S_IREAD;
  230.   return (sh_open(path, access, fmode));
  231. }
  232.  
  233. int sh_close(int f)
  234. {
  235.   if (f != -1)
  236.     close(f);
  237.   return (-1);
  238. }
  239.  
  240. int sh_read(int handle, void *buf, unsigned len)
  241. {
  242.   if (handle == -1) {
  243.     return (-1);
  244.   }
  245.   return (read(handle, buf, len));
  246. }
  247.  
  248. long sh_lseek(int handle, long offset, int fromwhere)
  249. {
  250.   if (handle == -1) {
  251.     return (-1L);
  252.   }
  253.   return (lseek(handle, offset, fromwhere));
  254. }
  255.  
  256. FILE *fsh_open(char *path, char *fmode)
  257. {
  258.   FILE *f;
  259.   int count, share, md, fd;
  260.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  261.  
  262.   share = SH_DENYWR;
  263.   md = 0;
  264.   if (((char *) _fstrchr(fmode, 'w')) != NULL) {
  265.     share = SH_DENYRD;
  266.     md = O_RDWR | O_CREAT | O_TRUNC;
  267.   } else
  268.     if (((char *) _fstrchr(fmode, 'a')) != NULL) {
  269.     share = SH_DENYRD;
  270.     md = O_RDWR | O_CREAT;
  271.   } else {
  272.     md = O_RDONLY;
  273.   }
  274.   if (((char *) _fstrchr(fmode, 'b')) != NULL) {
  275.     md |= O_BINARY;
  276.   }
  277.   if (((char *) _fstrchr(fmode, '+')) != NULL) {
  278.     md &= ~O_RDONLY;
  279.     md |= O_RDWR;
  280.     share = SH_DENYRD;
  281.   }
  282.   fd = open(path, md | share, S_IREAD | S_IWRITE);
  283.   if (fd < 0) {
  284.     count = 1;
  285.     fnsplit(path, drive, dir, file, ext);
  286.     if ((access(path, 0)) != -1) {
  287.       delay(WAIT_TIME);
  288.       fd = open(path, md | share, S_IREAD | S_IWRITE);
  289.       while (((fd < 0) && (errno == EACCES)) && (count < TRIES)) {
  290.         delay(WAIT_TIME);
  291.         count++;
  292.         fd = open(path, md | share, S_IREAD | S_IWRITE);
  293.       }
  294.     }
  295.   }
  296.   if (fd > 0) {
  297.     if (((char *) _fstrchr(fmode, 'a')) != NULL)
  298.       sh_lseek(fd, 0L, SEEK_END);
  299.     f = fdopen(fd, fmode);
  300.     if (!f) {
  301.       close(fd);
  302.     }
  303.   } else
  304.     f = NULL;
  305.   return (f);
  306. }
  307.  
  308. void output(char *fmt, ...)
  309. {
  310.   va_list v;
  311.   char s[255];
  312.  
  313.   va_start(v, fmt);
  314.   vsprintf(s, fmt, v);
  315.   va_end(v);
  316.   fputs(s, stderr);
  317. }
  318.  
  319.  
  320. void backline(void)
  321. {
  322.   int i;
  323.  
  324.   output(" ");
  325.   for (i = wherex(); i > 0; i--)
  326.     output("\b \b");
  327. }
  328.  
  329.  
  330. int do_spawn(char *cl)
  331. {
  332.   int i, i1, l;
  333.   char *s, *ss[50];
  334.  
  335.   s = strdup(cl);
  336.   ss[0] = s;
  337.   i = 1;
  338.   l = strlen(s);
  339.   for (i1 = 1; i1 < l; i1++)
  340.     if (s[i1] == 32) {
  341.       s[i1] = 0;
  342.       ss[i++] = &(s[i1 + 1]);
  343.     }
  344.   ss[i] = NULL;
  345.   if (MOREINFO)
  346.     output("\n");
  347.   i = (spawnvpe(P_WAIT, ss[0], ss, xenviron) & 0x00ff);
  348.   free(s);
  349.   return (i);
  350. }
  351.  
  352. void unload_klos(void)
  353. {
  354.   char s[101];
  355.  
  356.   sprintf(s, "%s\\IPSTUB U", maindir);
  357.   do_spawn(s);
  358.   sprintf(s, "%s\\PPP U", maindir);
  359.   do_spawn(s);
  360.   if (!lsl_loaded) {
  361.     sprintf(s, "%s\\LSL U", maindir);
  362.     do_spawn(s);
  363.   }
  364. }
  365.  
  366. void cd_to(char *s)
  367. {
  368.   char *s1;
  369.   int i, db;
  370.  
  371.   s1 = s;
  372.   i = strlen(s1) - 1;
  373.   db = (s1[i] == '\\');
  374.   if (i == 0)
  375.     db = 0;
  376.   if ((i == 2) && (s1[1] == ':'))
  377.     db = 0;
  378.   if (db)
  379.     s1[i] = 0;
  380.   chdir(s1);
  381.   if (s[1] == ':')
  382.     setdisk(s[0] - 'A');
  383. }
  384.  
  385. void get_dir(char *s, int be)
  386. {
  387.   strcpy(s, "X:\\");
  388.   s[0] = 'A' + getdisk();
  389.   getcurdir(0, s + 3);
  390.   if (be) {
  391.     if (s[strlen(s) - 1] != '\\')
  392.       strcat(s, "\\");
  393.   }
  394. }
  395.  
  396. unsigned char *trimstr1(unsigned char *s)
  397. {
  398.   int i;
  399.   static char *whitespace = " \r\n\t";
  400.  
  401.   i = (int) strlen(s);
  402.   while ((i > 0) && ((char *) _fstrchr(whitespace, s[i - 1]) != NULL))
  403.     --i;
  404.   while ((i > 0) && ((char *) _fstrchr(whitespace, *s) != NULL)) {
  405.     memmove(s, s + 1, --i);
  406.   }
  407.   s[i] = NUL;
  408.   return (s);
  409. }
  410.  
  411. char *make_abs_path(unsigned char *checkdir)
  412. {
  413.   char newdir[121];
  414.  
  415.   if ((strlen(checkdir) < 3) || (checkdir[1] != ':') || (checkdir[2] != '\\')) {
  416.     cd_to(maindir);
  417.     cd_to(checkdir);
  418.     if (LAST(checkdir) == '\\')
  419.       get_dir(newdir, 1);
  420.     else
  421.       get_dir(newdir, 0);
  422.     cd_to(maindir);
  423.     strcpy(checkdir, newdir);
  424.   }
  425.   return checkdir;
  426. }
  427.  
  428. int exist(char *s)
  429. {
  430.   int i;
  431.   struct ffblk ff;
  432.  
  433.   i = findfirst(s, &ff, 0);
  434.   if (i)
  435.     return (0);
  436.   else
  437.     return (1);
  438. }
  439.  
  440. void set_net_num(int n)
  441. {
  442.   char s[121];
  443.   int f;
  444.  
  445.   sprintf(s, "%sNETWORKS.DAT", syscfg.datadir);
  446.   f = sh_open1(s, O_RDONLY | O_BINARY);
  447.   if (f < 0)
  448.     return;
  449.   lseek(f, ((long) (n)) * sizeof(net_networks_rec), SEEK_SET);
  450.   sh_read(f, &netcfg, sizeof(net_networks_rec));
  451.   close(f);
  452.   net_num = n;
  453.   net_sysnum = netcfg.sysnum;
  454.   strcpy(net_name, netcfg.name);
  455.   strcpy(net_data, make_abs_path(netcfg.dir));
  456.   if (LAST(net_data) != '\\')
  457.     strcat(net_data, "\\");
  458.   sprintf(wwiv_net_no, "WWIV_NET=%d", net_num);
  459. }
  460.  
  461. int make_path(char *s)
  462. {
  463.   unsigned int i;
  464.   char drive, current_path[MAX_PATH], current_drive, *p, *flp;
  465.   union REGS r;
  466.  
  467.   p = flp = strdup(s);
  468.   _getdcwd(0, current_path, MAX_PATH);
  469.   current_drive = *current_path - '@';
  470.   if (LAST(s) == '\\')
  471.     LAST(s) = 0;
  472.   if (p[1] == ':') {
  473.     drive = toupper(p[0]) - 'A' + 1;
  474.     if ((_osmajor == 3 && _osminor >= 1) || (_osmajor > 3)) {
  475.       r.x.ax = 0x4409;
  476.       r.h.bl = drive;
  477.       int86(0x21, &r, &r);
  478.       if (r.x.cflag)
  479.         return -3;
  480.     }
  481.     if (_chdrive(drive)) {
  482.       chdir(current_path);
  483.       _dos_setdrive(current_drive, &i);
  484.       return -2;
  485.     }
  486.     p += 2;
  487.   }
  488.   if (*p == '\\') {
  489.     chdir("\\");
  490.     p++;
  491.   }
  492.   for (; (p = strtok(p, "\\")) != 0; p = 0) {
  493.     if (chdir(p)) {
  494.       if (mkdir(p)) {
  495.         chdir(current_path);
  496.         _dos_setdrive(current_drive, &i);
  497.         return -1;
  498.       }
  499.       chdir(p);
  500.     }
  501.   }
  502.   chdir(current_path);
  503.   if (flp)
  504.     free(flp);
  505.   return 0;
  506. }
  507.  
  508. void process_mail(void)
  509. {
  510.   char s[121];
  511.  
  512.   sprintf(s, "%s\\FLINK.EXE", maindir);
  513.   if (exist(s))
  514.     do_spawn(s);
  515.   sprintf(s, "%s\\LINKER.EXE", maindir);
  516.   if (exist(s))
  517.     do_spawn(s);
  518. }
  519.  
  520. int valid_system(unsigned int ts)
  521. {
  522.   int i;
  523.  
  524.   for (i = 0; i < num_sys_list; i++) {
  525.     if (netsys[i].sysnum == ts) {
  526.       if (netsys[i].numhops == 1)
  527.         return (1);
  528.       else
  529.         return (0);
  530.     }
  531.   }
  532.   return (0);
  533. }
  534.  
  535. void good_addr(char *address, unsigned short sn)
  536. {
  537.   char *ss, fn[101], s[81];
  538.   unsigned short node;
  539.   int curfile;
  540.   FILE *fp;
  541.  
  542.  
  543.   curfile = 1;
  544.   address[0] = 0;
  545.   do {
  546.     sprintf(fn, "%sADDRESS.%d", net_data, curfile);
  547.     fp = fsh_open(fn, "rt");
  548.     if (!fp)
  549.       curfile = -1;
  550.     while ((curfile > 0) && (fgets(s, 80, fp) != NULL)) {
  551.       if (s[0] != '@')
  552.         continue;
  553.       ss = strtok(s, " \t\r");
  554.       node = atoi(&ss[1]);
  555.       if (node == sn) {
  556.         ss = strtok(NULL, " \t\r");
  557.         trimstr1(ss);
  558.         strcpy(address, ss);
  559.         curfile = -1;
  560.       }
  561.     }
  562.     if (fp)
  563.       fclose(fp);
  564.     ++curfile;
  565.   } while (curfile > 0);
  566.   if (!address[0])
  567.     return;
  568.   sprintf(fn, "%sADDRESS.0", net_data);
  569.   fp = fsh_open(fn, "rt");
  570.   if (!fp)
  571.     return;
  572.   while (fgets(s, 80, fp) != NULL) {
  573.     if (s[0] != '@')
  574.       continue;
  575.     ss = strtok(s, " \t\r");
  576.     node = atoi(&ss[1]);
  577.     if (node == sn) {
  578.       do {
  579.         ss = strtok(NULL, " \t\r");
  580.         switch (ss[0]) {
  581.           case '-':
  582.             address[0] = 0;
  583.             break;
  584.         }
  585.       } while (ss);
  586.     }
  587.   }
  588.   if (fp)
  589.     fclose(fp);
  590. }
  591.  
  592. int copyfile(char *input, char *output)
  593. {
  594.   int f1, f2, i;
  595.   char *b;
  596.   struct ftime ft;
  597.  
  598.   if ((strcmp(input, output) != 0) && (exist(input)) && (!exist(output))) {
  599.     if ((b = (char *) malloc(16400)) == NULL)
  600.       return 0;
  601.     f1 = sh_open1(input, O_RDONLY | O_BINARY);
  602.     if (!f1) {
  603.       free(b);
  604.       b = NULL;
  605.       return 0;
  606.     }
  607.     getftime(f1, &ft);
  608.     f2 = sh_open(output, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  609.     if (!f2) {
  610.       free(b);
  611.       b = NULL;
  612.       sh_close(f1);
  613.       return 0;
  614.     }
  615.     i = read(f1, (void *) b, 16384);
  616.     while (i > 0) {
  617.       sh_write(f2, (void *) b, i);
  618.       i = read(f1, (void *) b, 16384);
  619.     }
  620.     f1 = sh_close(f1);
  621.     setftime(f2, &ft);
  622.     f2 = sh_close(f2);
  623.     free(b);
  624.     b = NULL;
  625.   }
  626.   return 1;
  627. }
  628.  
  629. void do_exit(int exitlevel)
  630. {
  631.  
  632.   delay(2000);
  633.   exit(exitlevel);
  634. }
  635.  
  636. int uu(char *fn, char *pktname, char *dest)
  637. {
  638.   int ok;
  639.   char s[121], s1[121], s2[81];
  640.   FILE *fp;
  641.  
  642.   sprintf(s, "%sMQUEUE\\%s.UUE", net_data, pktname);
  643.   if ((fp = fsh_open(s, "wt")) == NULL) {
  644.     output("\n ■ Unable to open %s for write operations!", s);
  645.     do_exit(EXIT_FAILURE);
  646.   } else {
  647.     sprintf(s2, "from: %s@%s\n", POPNAME, DOMAIN);
  648.     fprintf(fp, s2);
  649.     sprintf(s2, "to: %s\n", dest);
  650.     fprintf(fp, s2);
  651.     sprintf(s2, "subject: @%s NET PACKET : %s.UUE\n\n", net_name, pktname);
  652.     fprintf(fp, s2);
  653.   }
  654.   if (fp)
  655.     fclose(fp);
  656.   sprintf(s1, "%s\\UU -encode %s %s", maindir, fn, s);
  657.   ok = do_spawn(s1);
  658.   return ok;
  659. }
  660.  
  661. int update_contact(unsigned short sy, unsigned long sb, unsigned long rb)
  662. {
  663.   char s[101];
  664.   int i, i1, f;
  665.   long cur_time, l;
  666.  
  667.   sprintf(s, "%sCONTACT.NET", net_data);
  668.   f = sh_open1(s, O_RDONLY | O_BINARY);
  669.   if (f >= 0) {
  670.     l = filelength(f);
  671.     netcfg.num_ncn = (int) (l / sizeof(net_contact_rec));
  672.     if ((netcfg.ncn = (net_contact_rec *) malloc((netcfg.num_ncn + 2) *
  673.                                         sizeof(net_contact_rec))) == NULL) {
  674.       output("\n ■ Unable to allocate %d bytes of memory to update CONTACT.NET",
  675.               (int) (netcfg.num_ncn + 2) * sizeof(net_contact_rec));
  676.       sh_close(f);
  677.       return 1;
  678.     }
  679.     sh_lseek(f, 0L, SEEK_SET);
  680.     sh_read(f, (void *) netcfg.ncn, netcfg.num_ncn * sizeof(net_contact_rec));
  681.     sh_close(f);
  682.   }
  683.   for (i = 0; i < netcfg.num_ncn; i++)
  684.     if (netcfg.ncn[i].systemnumber == sy)
  685.       i1 = i;
  686.   time(&cur_time);
  687.   netcfg.ncn[i1].lasttry = cur_time;
  688.   ++netcfg.ncn[i1].numcontacts;
  689.   if (!netcfg.ncn[i1].firstcontact)
  690.     netcfg.ncn[i1].firstcontact = cur_time;
  691.   netcfg.ncn[i1].lastcontact = cur_time;
  692.   netcfg.ncn[i1].lastcontactsent = cur_time;
  693.   netcfg.ncn[i1].bytes_sent += sb;
  694.   if (rb)
  695.     netcfg.ncn[i1].bytes_received += rb;
  696.   netcfg.ncn[i1].bytes_waiting = 0L;
  697.   sprintf(s, "%sS%hd.net", net_data, sy);
  698.   if (!exist(s))
  699.     sprintf(s, "%sZ%hd.net", net_data, sy);
  700.   f = sh_open1(s, O_RDONLY | O_BINARY);
  701.   if (f > 0) {
  702.     netcfg.ncn[i1].bytes_waiting += filelength(f);
  703.     close(f);
  704.   }
  705.   sprintf(s, "%sCONTACT.NET", net_data);
  706.   f = sh_open1(s, O_RDWR | O_CREAT | O_BINARY);
  707.   if (f > 0) {
  708.     sh_lseek(f, 0L, SEEK_SET);
  709.     sh_write(f, (void *) netcfg.ncn, netcfg.num_ncn * sizeof(net_contact_rec));
  710.     sh_close(f);
  711.   }
  712.   if (netcfg.ncn)
  713.     free(netcfg.ncn);
  714.   return 0;
  715. }
  716.  
  717.  
  718. int uu_packets(void)
  719. {
  720.   char fn[121], pktname[21], s[121], s1[121], s2[121], s3[121], destaddr[101], *ss, temp[121];
  721.   int found, sz, f, f1;
  722.   long fpos;
  723.   unsigned short node;
  724.   unsigned long sbytes;
  725.   FILE *fp;
  726.  
  727.   sprintf(s, "%sBBSDATA.NET", net_data);
  728.   f = sh_open1(s, O_RDONLY | O_BINARY);
  729.   num_sys_list = 0;
  730.   if (f > 0) {
  731.     num_sys_list = (int) (filelength(f) / sizeof(net_system_list_rec));
  732.     if ((netsys = (net_system_list_rec *) malloc((num_sys_list + 2) *
  733.                                     sizeof(net_system_list_rec))) == NULL) {
  734.       output("\n ■ Unable to allocate %d bytes of memory for BBSDATA.NET",
  735.               (int) (num_sys_list + 2) * sizeof(net_system_list_rec));
  736.       sh_close(f);
  737.       return 0;
  738.     }
  739.     sh_lseek(f, 0L, SEEK_SET);
  740.     sh_read(f, (void *) netsys, num_sys_list * sizeof(net_system_list_rec));
  741.     sh_close(f);
  742.   } else
  743.     return 0;
  744.   sprintf(fn, "%sADDRESS.NET", net_data);
  745.   fp = fsh_open(fn, "rt");
  746.   if (!fp) {
  747.     free(netsys);
  748.     return 0;
  749.   }
  750.   found = 0;
  751.   while (fgets(s, 80, fp) != NULL) {
  752.     node = 0;
  753.     if (s[0] != '@')
  754.       continue;
  755.     ss = strtok(s, " ");
  756.     node = atoi(&ss[1]);
  757.     if ((valid_system(node)) && (node != 32767)) {
  758.       sprintf(s1, "%sS%hd.NET", net_data, node);
  759.       if (exist(s1))
  760.         sz = 0;
  761.       else {
  762.         sprintf(s1, "%sZ%hd.NET", net_data, node);
  763.         if (exist(s1))
  764.           sz = 1;
  765.         else
  766.           continue;
  767.       }
  768.       do {
  769.         sprintf(pktname, "%lx", time(NULL));
  770.         sprintf(temp, "%sMQUEUE\\%s.UUE", net_data, pktname);
  771.       } while (exist(temp));
  772.       good_addr(destaddr, node);
  773.       backline();
  774.       output("\r ■ Encoding %s%hd.NET as %s.UUE -",
  775.               sz ? "Z" : "S", node, strupr(pktname));
  776.       if (fp) {
  777.         fpos = ftell(fp);
  778.         fclose(fp);
  779.       }
  780.       if ((uu(s1, pktname, destaddr)) == EXIT_FAILURE) {
  781.         output("\n ■ Error creating %sMQUEUE\\%s.UUE", net_data, pktname);
  782.         free(netsys);
  783.         do_exit(EXIT_FAILURE);
  784.       } else {
  785.         found = 1;
  786.         if (KEEPSENT) {
  787.           sprintf(s3, "%sMQUEUE\\%s.UUE", net_data, pktname);
  788.           sprintf(s2, "%sSENT\\%s.SNT", net_data, pktname);
  789.           f1 = sh_open1(s3, O_RDONLY | O_BINARY);
  790.           if (f1 > 0) {
  791.             sbytes = filelength(f1);
  792.             sh_close(f1);
  793.           }
  794.           if (!copyfile(s3, s2))
  795.             output("\n ■ Error moving %s%hd.NET", sz ? "Z" : "S", node);
  796.         }
  797.         unlink(s1);
  798.         update_contact(node, sbytes, 0);
  799.       }
  800.       fp = fsh_open(fn, "rt");
  801.       fseek(fp, fpos, 0);
  802.     } else {
  803.       continue;
  804.     }
  805.     ss = strtok(NULL, "\r");
  806.     ss = NULL;
  807.   }
  808.   if (netsys)
  809.     free(netsys);
  810.   if (fp)
  811.     fclose(fp);
  812.   return found;
  813. }
  814.  
  815. int purge_sent(void)
  816. {
  817.   char s[121];
  818.   int f1, howmany = 0;
  819.   long age;
  820.   struct ffblk ff;
  821.   struct stat fileinfo;
  822.  
  823.   sprintf(s, "%sSENT\\*.*", net_data);
  824.   f1 = findfirst(s, &ff, 0);
  825.   while (f1 == 0) {
  826.     sprintf(s, "%sSENT\\%s", net_data, ff.ff_name);
  827.     if (stat(s, &fileinfo) == 0) {
  828.       age = (time(NULL) - fileinfo.st_atime);
  829.       if (age > (86400L * KEEPSENT)) {
  830.         ++howmany;
  831.         unlink(s);
  832.       }
  833.     }
  834.     f1 = findnext(&ff);
  835.   }
  836.   return howmany;
  837. }
  838.  
  839. int parse_net_ini(void)
  840. {
  841.   char cursect;
  842.   char line[121], *ss;
  843.   FILE *fp;
  844.  
  845.   fp = fsh_open("NET.INI", "rt");
  846.   if (!fp)
  847.     return (0);
  848.   while (fgets(line, 80, fp)) {
  849.     stripspace(line);
  850.     ss = NULL;
  851.     ss = strtok(line, "=");
  852.     if (ss)
  853.       ss = strtok(NULL, "\n");
  854.     if ((line[0] == ';') || (line[0] == '\n') || (strlen(line) == 0))
  855.       continue;
  856.     if ((strnicmp(line, "[FILENET]", 9) == 0) ||
  857.         (strnicmp(line, "[PPPNET]", 8) == 0)) {
  858.       cursect = INI_NETWORK;
  859.       ini_section |= INI_NETWORK;
  860.       continue;
  861.     }
  862.     if (strnicmp(line, "[GENERAL]", 9) == 0) {
  863.       cursect = INI_GENERAL;
  864.       ini_section |= INI_GENERAL;
  865.       continue;
  866.     }
  867.     if (strnicmp(line, "[NEWS]", 6) == 0) {
  868.       cursect = INI_NEWS;
  869.       ini_section |= INI_NEWS;
  870.       continue;
  871.     }
  872.     if (cursect & INI_NETWORK) {
  873.       if (strnicmp(line, "SMTPHOST", 8) == 0) {
  874.         if (ss)
  875.           strcpy(SMTPHOST, ss);
  876.         continue;
  877.       }
  878.       if (strnicmp(line, "POPHOST", 7) == 0) {
  879.         if (ss)
  880.           strcpy(POPHOST, ss);
  881.         continue;
  882.       }
  883.       if (strnicmp(line, "POPNAME", 7) == 0) {
  884.         if (ss)
  885.           strcpy(POPNAME, ss);
  886.         continue;
  887.       }
  888.       if (strnicmp(line, "POPPASS", 7) == 0) {
  889.         if (ss)
  890.           strcpy(POPPASS, ss);
  891.         continue;
  892.       }
  893.     }
  894.     if (cursect & INI_GENERAL) {
  895.       if (strnicmp(line, "TIMEOUT", 7) == 0) {
  896.         if (atoi(ss))
  897.           TIMEOUT = atoi(ss);
  898.         continue;
  899.       }
  900.       if (strnicmp(line, "SOCK_DELAY", 10) == 0) {
  901.         if (atoi(ss))
  902.           SOCK_DELAY = atoi(ss);
  903.         continue;
  904.       }
  905.       if (strnicmp(line, "INACTIVE", 13) == 0) {
  906.         if (atoi(ss))
  907.           INACTIVE = atoi(ss);
  908.         continue;
  909.       }
  910.       if (strnicmp(line, "KEEPSENT", 8) == 0) {
  911.         if (atoi(ss))
  912.           KEEPSENT = atoi(ss);
  913.         continue;
  914.       }
  915.       if (strnicmp(line, "PURGE", 5) == 0) {
  916.         if (toupper(ss[0]) == 'N')
  917.           PURGE = 0;
  918.         continue;
  919.       }
  920.       if (strnicmp(line, "ALLMAIL", 7) == 0) {
  921.         if (toupper(ss[0]) == 'N')
  922.           ALLMAIL = 0;
  923.         continue;
  924.       }
  925.       if (strnicmp(line, "ONECALL", 7) == 0) {
  926.         if (toupper(ss[0]) == 'Y')
  927.           ONECALL = 1;
  928.         continue;
  929.       }
  930.       if (strnicmp(line, "MOREINFO", 8) == 0) {
  931.         if (toupper(ss[0]) == 'Y')
  932.           MOREINFO = 1;
  933.         continue;
  934.       }
  935.       if (strnicmp(line, "CLEANUP", 7) == 0) {
  936.         if (toupper(ss[0]) == 'Y')
  937.           CLEANUP = 1;
  938.         continue;
  939.       }
  940.       if (strnicmp(line, "IPADDR", 6) == 0) {
  941.         if ((ss) && (ss[0] != '0'))
  942.           strcpy(IPADDR, ss);
  943.         continue;
  944.       }
  945.       if (strnicmp(line, "NETMASK", 7) == 0) {
  946.         if (ss)
  947.           strcpy(NETMASK, ss);
  948.         continue;
  949.       }
  950.       if (strnicmp(line, "DNS", 3) == 0) {
  951.         if (ss)
  952.           strcpy(DNS, ss);
  953.         continue;
  954.       }
  955.       if (strnicmp(line, "DOMAIN", 6) == 0) {
  956.         if (ss)
  957.           strcpy(DOMAIN, ss);
  958.         continue;
  959.       }
  960.       if (strnicmp(line, "FWDNAME", 7) == 0) {
  961.         if (ss)
  962.           strcpy(FWDNAME, ss);
  963.         continue;
  964.       }
  965.       if (strnicmp(line, "FWDDOM", 6) == 0) {
  966.         if (ss)
  967.           strcpy(FWDDOM, ss);
  968.         continue;
  969.       }
  970.       if (strnicmp(line, "GATEWAY", 7) == 0) {
  971.         if ((ss) && (ss[0] != '0'))
  972.           strcpy(GATEWAY, ss);
  973.         continue;
  974.       }
  975.     }
  976.     if (cursect & INI_NEWS) {
  977.       if (strnicmp(line, "NEWSHOST", 8) == 0) {
  978.         if (ss)
  979.           strcpy(NEWSHOST, ss);
  980.         continue;
  981.       }
  982.     }
  983.   }
  984.   if (!FWDNAME[0])
  985.     strcpy(FWDNAME, POPNAME);
  986.   if (!FWDDOM[0])
  987.     strcpy(FWDDOM, DOMAIN);
  988.   if (fp)
  989.     fclose(fp);
  990.   return (1);
  991. }
  992.  
  993.  
  994. int count_lines(char *s)
  995. {
  996.   FILE *fp;
  997.   char fn[121];
  998.   unsigned int nl = 0;
  999.   const int NEWLINE = '\n';
  1000.   int c;
  1001.  
  1002.   strcpy(fn, s);
  1003.   fp = fsh_open(fn, "rt");
  1004.   if (fp == NULL) {
  1005.     printf("\n ■ Cannot open %s", fn);
  1006.     return 0;
  1007.   }
  1008.   while ((c = getc(fp)) != EOF) {
  1009.     if (c == NEWLINE)
  1010.       ++nl;
  1011.   }
  1012.   if (fp)
  1013.     fclose(fp);
  1014.   return nl;
  1015. }
  1016.  
  1017. typedef struct {
  1018.   char line[81];
  1019. } nlines;
  1020.  
  1021. nlines *NETLOG;
  1022.  
  1023. int write_netlog(int sn, long sent, long recd, char *tmused)
  1024. {
  1025.   FILE *fp;
  1026.   int i = 0;
  1027.   unsigned int lines;
  1028.   char s[81], s1[81], s2[81], fn[121];
  1029.   struct tm *time_now;
  1030.   time_t some;
  1031.  
  1032.   sprintf(fn, "%sNET.LOG", syscfg.gfilesdir);
  1033.   lines = 0;
  1034.   lines = count_lines(fn);
  1035.   if ((NETLOG = ((nlines *) malloc((lines + 2) * 81))) == NULL) {
  1036.     output("\n ■ Unable to allocate %d bytes for NET.LOG entry",
  1037.             (lines + 2) * 81);
  1038.     return 1;
  1039.   }
  1040.   fp = fsh_open(fn, "r");
  1041.   if (!fp)
  1042.     return 1;
  1043.   while (fgets(s, 80, fp)) {
  1044.     strtok(s, "\n");
  1045.     strcpy(NETLOG[i++].line, s);
  1046.   }
  1047.   if (fp)
  1048.     fclose(fp);
  1049.   time(&some);
  1050.   time_now = localtime(&some);
  1051.   strftime(s1, 35, "%m/%d/%y %H:%M:%S", time_now);
  1052.   if ((sent) || (recd)) {
  1053.     if ((recd) && (!sent))
  1054.       sprintf(s2, "       , R:%4ldk,", recd);
  1055.     else {
  1056.       if ((recd) && (sent))
  1057.         sprintf(s2, "S:%4ldk, R:%4ldk,", sent, recd);
  1058.       else
  1059.         sprintf(s2, "S:%4ldk,         ", sent);
  1060.     }
  1061.   } else
  1062.     strcpy(s2, "                 ");
  1063.   fp = fsh_open(fn, "wt+");
  1064.   fprintf(fp, "%s To %5d, %s          %4s min  %s\n", s1, sn, s2,
  1065.           tmused, net_name);
  1066.   for (i = 0; i < lines; i++)
  1067.     fprintf(fp, "%s\n", NETLOG[i].line);
  1068.   if (NETLOG)
  1069.     free(NETLOG);
  1070.   NETLOG = NULL;
  1071.   if (fp)
  1072.     fclose(fp);
  1073.   return 0;
  1074. }
  1075.  
  1076. void read_networks(void)
  1077. {
  1078.   int f;
  1079.   char s[121];
  1080.  
  1081.   sprintf(s, "%sNETWORKS.DAT", syscfg.datadir);
  1082.   f = sh_open1(s, O_RDONLY | O_BINARY);
  1083.   net_num_max = 0;
  1084.   if (f > 0) {
  1085.     net_num_max = (int) (filelength(f) / sizeof(net_networks_rec));
  1086.     sh_close(f);
  1087.   }
  1088. }
  1089.  
  1090. void init(void)
  1091. {
  1092.   char s[81], s1[81], *ss;
  1093.   int i, i1, dv, f;
  1094.   struct tm *time_now;
  1095.   time_t some;
  1096.  
  1097.   output("\n%s\n%s\n\n", version, author);
  1098.   get_dir(maindir, 0);
  1099.   ss = getenv("WWIV_INSTANCE");
  1100.   if (ss) {
  1101.     instance = atoi(ss);
  1102.     if ((instance <= 0) || (instance > 999)) {
  1103.       output("\n ■ WWIV_INSTANCE can only be 1..999!");
  1104.       instance = 1;
  1105.     }
  1106.   } else {
  1107.     instance = 1;
  1108.   }
  1109.  
  1110.   detect_multitask();
  1111.  
  1112.   switch (multitasker) {
  1113.     case 1:
  1114.       dv = get_dv_version();
  1115.       sprintf(s1, "DesqView %d.%02d", dv / 256, dv % 256);
  1116.       break;
  1117.     case 2:
  1118.       dv = get_win_version();
  1119.       if (dv == 4)
  1120.         strcpy(s1, "Windows 95");
  1121.       else
  1122.         sprintf(s1, "Windows %d.%02d", dv % 256, dv / 256);
  1123.       break;
  1124.     case 3:
  1125.       dv = get_dv_version();
  1126.       sprintf(s1, "Windows and DesqView %d.%02d", dv / 256, dv % 256);
  1127.       break;
  1128.     case 4:
  1129.     case 5:
  1130.     case 6:
  1131.     case 7:
  1132.       if ((_osmajor / 10 == 2) && (_osminor >= 30))
  1133.         strcpy(s1, "OS/2 Warp");
  1134.       else
  1135.         sprintf(s1, "OS/2 %d.%2.2d", _osmajor / 10, _osminor);
  1136.       break;
  1137.     case 8:
  1138.       sprintf(s1, "NETBIOS network");
  1139.       multitasker = 1;
  1140.       break;
  1141.     default:
  1142.       strcpy(s1, "DOS");
  1143.       break;
  1144.   }
  1145.   strcpy(s, "CONFIG.DAT");
  1146.   f = sh_open1(s, O_RDONLY | O_BINARY);
  1147.   if (f < 0) {
  1148.     output("\n ■ %s NOT FOUND.", s);
  1149.     return;
  1150.   }
  1151.   sh_read(f, (void *) (&syscfg), sizeof(configrec));
  1152.   sh_close(f);
  1153.   output(" ■ Running under %s on instance %d ", s1, instance);
  1154.   time(&some);
  1155.   time_now = localtime(&some);
  1156.   strftime(s, 80, "at %I:%M%p, %d %b %y", time_now);
  1157.   printf(s);
  1158.   strcpy(s, "CONFIG.OVR");
  1159.   f = sh_open1(s, O_RDONLY | O_BINARY);
  1160.   if (f < 0) {
  1161.     output("\n ■ %s NOT FOUND.", s);
  1162.     return;
  1163.   }
  1164.   sh_lseek(f, (instance - 1) * sizeof(configoverrec), SEEK_SET);
  1165.   read(f, &syscfgovr, sizeof(configoverrec));
  1166.   f = sh_close(f);
  1167.   sprintf(s, "%sINSTANCE.DAT", syscfg.datadir);
  1168.   if (!exist(s)) {
  1169.     output("\n ■ %s NOT FOUND.", s);
  1170.     return;
  1171.   }
  1172.   read_networks();
  1173.   i = i1 = 0;
  1174.   while (environ[i] != NULL) {
  1175.     xenviron[i1++] = environ[i];
  1176.     ++i;
  1177.   }
  1178.   xenviron[i1] = NULL;
  1179. }
  1180.  
  1181. long getfctime(char *s)
  1182. {
  1183.   struct stat statbuf;
  1184.  
  1185.   if (stat(s, &statbuf) < 0)
  1186.     return (0L);
  1187.   else
  1188.     return (statbuf.st_atime);
  1189. }
  1190.  
  1191. int process_bbsdata(void)
  1192. {
  1193.   char s[101];
  1194.   unsigned long bbslist_ctime, connect_ctime, callout_ctime, bbsdata_ctime;
  1195.   int tf, n, net3;
  1196.  
  1197.   net3 = 0;
  1198.   sprintf(s, "%sBBSLIST.NET", net_data);
  1199.   bbslist_ctime = getfctime(s);
  1200.   sprintf(s, "%sCONNECT.NET", net_data);
  1201.   connect_ctime = getfctime(s);
  1202.   sprintf(s, "%sCALLOUT.NET", net_data);
  1203.   callout_ctime = getfctime(s);
  1204.   sprintf(s, "%sBBSDATA.NET", net_data);
  1205.   bbsdata_ctime = getfctime(s);
  1206.   sprintf(s, "%sBBSLIST.UPD", net_data);
  1207.   bbslist_ctime = getfctime(s);
  1208.   sprintf(s, "%sCONNECT.UPD", net_data);
  1209.   connect_ctime = getfctime(s);
  1210.  
  1211.   n = 0;
  1212.   tf = ((bbslist_ctime > bbsdata_ctime) || (connect_ctime > bbsdata_ctime));
  1213.   if (tf)
  1214.     n = 1;
  1215.   tf = (tf || (callout_ctime > bbsdata_ctime));
  1216.   if (tf) {
  1217.     sprintf(s, "NETWORK3 .%d", netnum);
  1218.     if (n) {
  1219.       sprintf(s, "NETWORK3 .%d Y", netnum);
  1220.       net3 = 1;
  1221.     }
  1222.     do_spawn(s);
  1223.   }
  1224.   return (net3);
  1225. }
  1226.  
  1227. void do_it(char *cl)
  1228. {
  1229.   int i, i1, l;
  1230.   char *s, *ss[30];
  1231.  
  1232.   s = strdup(cl);
  1233.   ss[0] = s;
  1234.   i = 1;
  1235.   l = strlen(s);
  1236.   for (i1 = 1; i1 < l; i1++)
  1237.     if (s[i1] == 32) {
  1238.       s[i1] = 0;
  1239.       ss[i++] = &(s[i1 + 1]);
  1240.     }
  1241.   ss[i] = NULL;
  1242.   execvpe(ss[0], ss, xenviron);
  1243. }
  1244.  
  1245. int create_wattcp_cfg(void)
  1246. {
  1247.   char s[MAXPATH], s1[41];
  1248.   FILE *fp;
  1249.  
  1250.   sprintf(s, "%s\\WATTCP.CFG", maindir);
  1251.   if ((fp = fsh_open(s, "wt")) == NULL) {
  1252.     output("\n ■ Can't open %s for output!", s);
  1253.     return 1;
  1254.   }
  1255.   fseek(fp, 0L, SEEK_SET);
  1256.   sprintf(s, "my_ip=%s\n", IPADDR);
  1257.   fprintf(fp, s);
  1258.   fprintf(fp, "netmask=%s\n", NETMASK);
  1259.   fprintf(fp, "nameserver=%s\n", DNS);
  1260.   if (GATEWAY[0] == 0) {
  1261.     strcpy(s1, IPADDR);
  1262.     while (LAST(s1) != '.')
  1263.       LAST(s1) = 0;
  1264.     strcat(s1, "1");
  1265.     strcpy(GATEWAY, s1);
  1266.   }
  1267.   sprintf(s, "gateway=%s\n", GATEWAY);
  1268.   fprintf(fp, s);
  1269.   fprintf(fp, "domainslist=\"%s\"\n", DOMAIN);
  1270.   fprintf(fp, "hostname=\"%s\"\n", POPNAME);
  1271.   fprintf(fp, "sockdelay=%d\n", SOCK_DELAY);
  1272.   fprintf(fp, "inactive=%d\n", INACTIVE);
  1273.   if (fp)
  1274.     fclose(fp);
  1275.   return 0;
  1276. }
  1277.  
  1278. int check_for_lsl(void)
  1279. {
  1280.   union REGS r;
  1281.   struct SREGS s;
  1282.   char *intstr;
  1283.  
  1284.   for (r.h.ah = 0xc0; r.h.ah != 0; r.h.ah++) {
  1285.     r.h.al = 0;
  1286.     int86x(0x2f, &r, &r, &s);
  1287.     if (r.h.al == 0xff) {
  1288.       intstr = (char *) MK_FP(s.es, r.x.si);
  1289.       if (strncmp(intstr, "LINKSUP$", 8) == 0)
  1290.         return 1;
  1291.     }
  1292.   }
  1293.   return 0;
  1294. }
  1295.  
  1296. void klos_ppp(void)
  1297. {
  1298.   char s[121], *ss;
  1299.   int i;
  1300.   FILE *fp;
  1301.  
  1302.   lsl_loaded = check_for_lsl();
  1303.   if (!lsl_loaded) {
  1304.     sprintf(s, "%s\\LSL.COM", maindir);
  1305.     if (exist(s)) {
  1306.       output("\n ■ Loading Link Support Layer and ");
  1307.       do_spawn(s);
  1308.     } else {
  1309.       output("\n ■ LSL.COM not in BBS main directory!");
  1310.       do_exit(EXIT_FAILURE);
  1311.     }
  1312.   } else
  1313.     output("\n ■ LSL already in memory - loading ");
  1314.   sprintf(s, "%s\\PPP.EXE", maindir);
  1315.   if (exist(s)) {
  1316.     output("PPP packet driver.");
  1317.     do_spawn(s);
  1318.   } else {
  1319.     output("\n ■ %s\\PPP.EXE not found!", maindir);
  1320.     do_exit(EXIT_FAILURE);
  1321.   }
  1322.   while (kbhit())
  1323.     getch();
  1324.   sprintf(s, "%s\\PPPSTATE.EXE", maindir);
  1325.   if (exist(s)) {
  1326.     output("\n ■ Dialing %s and waiting %d seconds for connection... ", DOMAIN, TIMEOUT);
  1327.     sprintf(s, "%s\\PPPSTATE.EXE WAIT=%d IP", maindir, TIMEOUT);
  1328.     i = do_spawn(s);
  1329.     switch (i) {
  1330.       case 0:
  1331.         output(" connected!");
  1332.         break;
  1333.       case 1:
  1334.         output("\n ■ Unable to establish connection... aborting");
  1335.         sprintf(s, "%s\\PPP U", maindir);
  1336.         do_spawn(s);
  1337.         if (!lsl_loaded) {
  1338.           sprintf(s, "%s\\LSL U", maindir);
  1339.           do_spawn(s);
  1340.         }
  1341.         do_exit(EXIT_FAILURE);
  1342.       case 2:
  1343.         output("\n ■ Unable to find PPP layer... aborting");
  1344.         sprintf(s, "%s\\PPP U", maindir);
  1345.         do_spawn(s);
  1346.         if (!lsl_loaded) {
  1347.           sprintf(s, "%s\\LSL U", maindir);
  1348.           do_spawn(s);
  1349.         }
  1350.         do_exit(EXIT_FAILURE);
  1351.       default:
  1352.         output("\n ■ Unknown PPPState Error #%d... aborting", i);
  1353.         sprintf(s, "%s\\PPP U", maindir);
  1354.         do_spawn(s);
  1355.         if (!lsl_loaded) {
  1356.           sprintf(s, "%s\\LSL U", maindir);
  1357.           do_spawn(s);
  1358.         }
  1359.         do_exit(EXIT_FAILURE);
  1360.     }
  1361.   } else {
  1362.     output("\n ■ %s\\PPPSTATE.EXE not found!", maindir);
  1363.     do_exit(EXIT_FAILURE);
  1364.   }
  1365.   if (!IPADDR[0]) {
  1366.     sprintf(s, "%s\\PPPWAT.EXE", maindir);
  1367.     if (exist(s)) {
  1368.       do_spawn(s);
  1369.     } else {
  1370.       output("\n ■ %s\\PPPWAT.EXE not found!", maindir);
  1371.       unload_klos();
  1372.       do_exit(EXIT_FAILURE);
  1373.     }
  1374.     sprintf(s, "%s\\WATTCP.CFG", maindir);
  1375.     fp = fsh_open(s, "rt");
  1376.     if (fp) {
  1377.       while (fgets(s, 100, fp) != NULL) {
  1378.         if (strnicmp(s, "my_ip", 5) == 0) {
  1379.           ss = strtok(s, "=");
  1380.           ss = strtok(NULL, "\r");
  1381.           trimstr1(ss);
  1382.           strcpy(IPADDR, ss);
  1383.           break;
  1384.         }
  1385.       }
  1386.       fclose(fp);
  1387.     } else {
  1388.       output("\n ■ Unable to read %s\\WATTCP.CFG... aborting!", maindir);
  1389.       unload_klos();
  1390.       do_exit(EXIT_FAILURE);
  1391.     }
  1392.   }
  1393.   if (IPADDR) {
  1394.     output("\n ■ Session IP address %s... ", IPADDR);
  1395.     if (create_wattcp_cfg()) {
  1396.       unload_klos();
  1397.       do_exit(EXIT_FAILURE);
  1398.     }
  1399.   } else {
  1400.     output("\n ■ Could not find IP Address... aborting!");
  1401.     unload_klos();
  1402.     do_exit(EXIT_FAILURE);
  1403.   }
  1404.   sprintf(s, "%s\\IPSTUB.EXE", maindir);
  1405.   if (exist(s)) {
  1406.     do_spawn(s);
  1407.   } else {
  1408.     output("\n ■ %s\\IPSTUB.EXE not found!", maindir);
  1409.     do_exit(EXIT_FAILURE);
  1410.   }
  1411.   output("establishing socket     ");
  1412.   for (i = 5; i >= 0; i--) {
  1413.     output("\b\b\b\b%d...", i);
  1414.     delay(1000);
  1415.   }
  1416.   output("\b\b\b\b\b... ready!");
  1417. }
  1418.  
  1419. double freek(int dr)
  1420. {
  1421.   float d;
  1422.   struct dfree df;
  1423.  
  1424.   getdfree(dr, &df);
  1425.   d = (float) df.df_avail;
  1426.   d *= ((float) df.df_bsec);
  1427.   d *= ((float) df.df_sclus);
  1428.   d /= 1024.0;
  1429.   if (df.df_sclus == 0xffff)
  1430.     d = -1.0;
  1431.   return (d);
  1432. }
  1433.  
  1434. int main(int argc, char *argv[])
  1435. {
  1436.   int i, ok, news, totf, send, f1;
  1437.   unsigned short sy;
  1438.   double dspace;
  1439.   char *ss, s[121], s1[MAXPATH], destaddr[121], temp[121];
  1440.   char ttotal[21];
  1441.   clock_t starttime, mailtime, newstime;
  1442.   unsigned long sentbytes, recdbytes, rnewsbytes, snewsbytes;
  1443.   FILE *fp;
  1444.   struct ffblk ff;
  1445.  
  1446.   init();
  1447.   news = 0;
  1448.   ss = argv[argc - 1];
  1449.   ok = 0;
  1450.   if (_fstrstr((char *) ss, ".") != NULL) {
  1451.     if (atoi(&ss[1]) < net_num_max) {
  1452.       netnum = atoi(&ss[1]);
  1453.       ok = 1;
  1454.     }
  1455.   } else {
  1456.     ss = (getenv("WWIV_NET"));
  1457.     netnum = atoi(ss);
  1458.     if (netnum < net_num_max)
  1459.       ok = 1;
  1460.   }
  1461.   if (!ok) {
  1462.     strcpy(s, "WWIV_NET.DAT");
  1463.     if ((fp = fsh_open(s, "rb")) != NULL) {
  1464.       fgets(s, 3, fp);
  1465.       netnum = atoi(s);
  1466.       if (fp)
  1467.         fclose(fp);
  1468.       if (netnum < net_num_max)
  1469.         ok = 1;
  1470.     }
  1471.   }
  1472.   ss = argv[1];
  1473.   if (strncmpi(ss, "/N", 2))
  1474.     ok = 0;
  1475.   if (ok) {
  1476.     SMTPHOST[0] = 0;
  1477.     POPHOST[0] = 0;
  1478.     NEWSHOST[0] = 0;
  1479.     POPNAME[0] = 0;
  1480.     POPPASS[0] = 0;
  1481.     IPADDR[0] = 0;
  1482.     NETMASK[0] = 0;
  1483.     DNS[0] = 0;
  1484.     DOMAIN[0] = 0;
  1485.     GATEWAY[0] = 0;
  1486.     FWDNAME[0] = 0;
  1487.     FWDDOM[0] = 0;
  1488.     if (parse_net_ini()) {
  1489.       set_net_num(netnum);
  1490.       if (ini_section & INI_NETWORK) {
  1491.         if (!(ini_section & INI_GENERAL)) {
  1492.           output("\n ■ [GENERAL] tag missing from NET.INI!");
  1493.           ok = 0;
  1494.         }
  1495.       } else {
  1496.         ok = 0;
  1497.         output("\n ■ [FILENET] tag missing from NET.INI!");
  1498.       }
  1499.     } else {
  1500.       output("\n ■ Could not open file NET.INI!");
  1501.       ok = 0;
  1502.     }
  1503.   }
  1504.   if (ok) {
  1505.     output("\n ■ Available memory : %ld bytes...", coreleft());
  1506.     if (net_data[1] == ':')
  1507.       i = net_data[0];
  1508.     else
  1509.       i = maindir[0];
  1510.     i = toupper(i) - 'A' + 1;
  1511.     dspace = freek(i);
  1512.     if (dspace < 1024.0) {
  1513.       output("\n ■ Only %.1fK available on drive %c:... aborting!",
  1514.               dspace, i + '@');
  1515.       do_exit(EXIT_FAILURE);
  1516.     } else {
  1517.       output(" disk space ");
  1518.       if (dspace < 10000.0)
  1519.         output(": %c:%.1fK", i + '@', dspace);
  1520.       else
  1521.         output(": %c:%.1fM", i + '@', dspace / 1024.0);
  1522.     }
  1523.  
  1524.     set_net_num(netnum);
  1525.     ss = argv[1];
  1526.     sy = atoi(&ss[2]);
  1527.     destaddr[0] = 0;
  1528.     if (sy != 32767)
  1529.       good_addr(destaddr, sy);
  1530.  
  1531.     if ((destaddr[0] == 0) && (sy != 32767)) {
  1532.       output("\n ■ Using direct dial for @%hd.%s\n\n", sy, net_name);
  1533.       ok = 0;
  1534.     } else {
  1535.       ok = 1;
  1536.       if (sy == 32767) {
  1537.         if (ini_section & INI_NEWS) {
  1538.           output("\n ■ Initiating newsgroup retrieval session...");
  1539.           news = 1;
  1540.         } else {
  1541.           output("\n ■ [NEWS] tag missing from NET.INI!");
  1542.           do_exit(EXIT_FAILURE);
  1543.         }
  1544.       }
  1545.     }
  1546.   }
  1547.   if (ok) {
  1548.     if (!MOREINFO)
  1549.       freopen(NULL, "w", stdout);
  1550.     if (CLEANUP)
  1551.       process_mail();
  1552.     set_net_num(netnum);
  1553.     sprintf(s, "%sSPOOL", net_data);
  1554.     if ((make_path(s)) < 0) {
  1555.       output("\n ■ Unable to create \"%s\"", s);
  1556.       do_exit(EXIT_FAILURE);
  1557.     }
  1558.     sprintf(s, "%sMQUEUE", net_data);
  1559.     if ((make_path(s)) < 0) {
  1560.       output("\n ■ Unable to create \"%s\"", s);
  1561.       do_exit(EXIT_FAILURE);
  1562.     }
  1563.     sprintf(s, "%sOUTBOUND", net_data);
  1564.     if ((make_path(s)) < 0) {
  1565.       output("\n ■ Unable to create \"%s\"", s);
  1566.       do_exit(EXIT_FAILURE);
  1567.     }
  1568.     sprintf(s, "%sINBOUND", net_data);
  1569.     if ((make_path(s)) < 0) {
  1570.       output("\n ■ Unable to create \"%s\"", s);
  1571.       do_exit(EXIT_FAILURE);
  1572.     }
  1573.     sprintf(s, "%sSENT", net_data);
  1574.     if ((make_path(s)) < 0) {
  1575.       output("\n ■ Unable to create \"%s\"", s);
  1576.       do_exit(EXIT_FAILURE);
  1577.     }
  1578.     if (PURGE) {
  1579.       if ((KEEPSENT) && (sy != 32767)) {
  1580.         output("\n ■ Purging sent packets older than %d day%s...", KEEPSENT,
  1581.                 KEEPSENT == 1 ? "" : "s");
  1582.         i = purge_sent();
  1583.         output(" %d packet%s deleted.", i, i == 1 ? "" : "s");
  1584.       }
  1585.     }
  1586.     sprintf(s, "%sCHECKNET", net_data);
  1587.     if ((make_path(s)) < 0) {
  1588.       output("\n ■ Unable to create \"%s\"", s);
  1589.       do_exit(EXIT_FAILURE);
  1590.     }
  1591.     send = 1;
  1592.  
  1593.     cd_to(maindir);
  1594.     sprintf(s, "%s\\EXP.EXE", maindir);
  1595.     if (!exist(s)) {
  1596.       output("\n ■ Export module EXP.EXE not found!");
  1597.     } else {
  1598.       sprintf(s, "%sS32767.NET", net_data);
  1599.       sprintf(s1, "%sSPOOL\\UNK*.*", net_data);
  1600.       if ((exist(s)) || (exist(s1))) {
  1601.         sprintf(s, "EXP.EXE S32767.NET %s %hu %s %s %s",
  1602.                 net_data, net_sysnum, FWDNAME, FWDDOM, net_name);
  1603.         if (do_spawn(s))
  1604.           output("\n ■ Unknown error during export.");
  1605.       } else
  1606.         output("\n ■ No inbound or outbound Internet mail or newsgroup posts to process.");
  1607.     }
  1608.  
  1609.     cd_to(maindir);
  1610.     if ((sy != 32767) || (ONECALL)) {
  1611.       output("\n ■ Preparing outbound mail for transmission...");
  1612.       if (!uu_packets()) {
  1613.         sprintf(s, "%sMQUEUE\\*.*", net_data);
  1614.         if (findfirst(s, &ff, 0) == 0) {
  1615.           output(" outbound packets in MQUEUE.");
  1616.         } else {
  1617.           output(" no mail or packets to send.");
  1618.           send = 0;
  1619.         }
  1620.       } else {
  1621.         backline();
  1622.         output("\r ■ All packets prepared for transmission.");
  1623.       }
  1624.     }
  1625.     sprintf(s, "%sNET%d.CFG", net_data, instance);
  1626.     if (exist(s)) {
  1627.       sprintf(s1, "%s\\NET.CFG", maindir);
  1628.       unlink(s1);
  1629.       if (!copyfile(s, s1))
  1630.         output("\n ■ Unable to copy %s to %s", s, s1);
  1631.     }
  1632.  
  1633.     starttime = clock();
  1634.     sentbytes = recdbytes = snewsbytes = rnewsbytes = 0L;
  1635.  
  1636.     cd_to(maindir);
  1637.  
  1638.     klos_ppp();
  1639.  
  1640.     sprintf(temp_dir, "%sINBOUND\\", net_data);
  1641.  
  1642.     if ((send) && ((sy != 32767) || (ONECALL))) {
  1643.       totf = 0;
  1644.       sprintf(temp, "%sMQUEUE\\*.*", net_data);
  1645.       f1 = findfirst(temp, &ff, FA_ARCH);
  1646.       if (f1 == 0)
  1647.         output("\n");
  1648.       while (f1 == 0) {
  1649.         sprintf(s1, "%sMQUEUE\\%s", net_data, ff.ff_name);
  1650.         sprintf(s, "%s\\POP -send %s %s %s %d", maindir, SMTPHOST, DOMAIN, s1, MOREINFO);
  1651.         backline();
  1652.         output("\r ■ Sending %s ", ff.ff_name);
  1653.         if (do_spawn(s) == EXIT_SUCCESS) {
  1654.           unlink(s1);
  1655.           sentbytes += ff.ff_fsize;
  1656.           ++totf;
  1657.         } else
  1658.           output("\n ■ Unsuccessful!  %s remains in MQUEUE.", ff.ff_name);
  1659.         f1 = findnext(&ff);
  1660.       }
  1661.       sprintf(temp, "%sMQUEUE\\*.*", net_data);
  1662.       f1 = findfirst(temp, &ff, FA_ARCH);
  1663.       while (f1 == 0) {
  1664.         sprintf(s1, "%sMQUEUE\\%s", net_data, ff.ff_name);
  1665.         sprintf(s, "%s\\POP -send %s %s %s %d", maindir, SMTPHOST, DOMAIN, s1, MOREINFO);
  1666.         backline();
  1667.         output("\r ■ Sending %s ", ff.ff_name);
  1668.         if (do_spawn(s) == EXIT_SUCCESS) {
  1669.           unlink(s1);
  1670.           sentbytes += ff.ff_fsize;
  1671.           ++totf;
  1672.         } else
  1673.           output("\n ■ Unsuccessful!  %s remains in MQUEUE.", ff.ff_name);
  1674.         f1 = findnext(&ff);
  1675.       }
  1676.       backline();
  1677.       output("\r ■ Outbound mail transfer completed - %d file%s, %ldK bytes.",
  1678.               totf, totf == 1 ? "" : "s", ((sentbytes + 1023) / 1024));
  1679.       send = 0;
  1680.     }
  1681.     if ((sy != 32767) || (ONECALL)) {
  1682.       sprintf(s, "%s\\POP -receive %s %s %s %s %d %s %d", maindir, POPHOST, POPNAME, POPPASS,
  1683.               temp_dir, ALLMAIL, DOMAIN, MOREINFO);
  1684.       output("\n ■ Checking %s for inbound net packets.", POPHOST);
  1685.       sprintf(s1, "%s*.*", temp_dir);
  1686.       if ((do_spawn(s) == EXIT_SUCCESS) || (exist(s1))) {
  1687.         sprintf(temp, "%s*.*", temp_dir);
  1688.         f1 = findfirst(temp, &ff, FA_ARCH);
  1689.         i = 0;
  1690.         send = 0;
  1691.         while (f1 == 0) {
  1692.           if ((strncmp(ff.ff_name, "BAD", 3) != 0) && (ff.ff_fsize)) {
  1693.             recdbytes += ff.ff_fsize;
  1694.             sprintf(s1, "%s%s", temp_dir, ff.ff_name);
  1695.             sprintf(temp, "%s\\UU -decode %s %s %s", maindir, ff.ff_name,
  1696.                     temp_dir, net_data);
  1697.             if (!do_spawn(temp)) {
  1698.               send = 1;
  1699.               unlink(s1);
  1700.             }
  1701.           }
  1702.           f1 = findnext(&ff);
  1703.         }
  1704.       } else
  1705.         output("\n ■ No network packets to process");
  1706.  
  1707.       if ((send) && (CLEANUP)) {
  1708.         output("\n ■ Running FLINK/Linker on received packets... please wait.");
  1709.         process_mail();
  1710.         set_net_num(netnum);
  1711.         process_bbsdata();
  1712.       }
  1713.     }
  1714.     sprintf(s, "%sSPOOL\\UNK*.*", net_data);
  1715.     if (exist(s)) {
  1716.       sprintf(s, "EXP.EXE S32767.NET %s %hu %s %s %s",
  1717.               net_data, net_sysnum, FWDNAME, FWDDOM, net_name);
  1718.       if (do_spawn(s))
  1719.         output("\n ■ Unknown error during export");
  1720.     }
  1721.     mailtime = clock() - starttime;
  1722.     if ((sy == 32767) || (ONECALL)) {
  1723.       starttime = clock();
  1724.       set_net_num(netnum);
  1725.       sprintf(temp, "%sOUTBOUND\\*.*", net_data);
  1726.       f1 = findfirst(temp, &ff, FA_ARCH);
  1727.       while (f1 == 0) {
  1728.         snewsbytes += ff.ff_fsize;
  1729.         f1 = findnext(&ff);
  1730.       }
  1731.       cd_to(maindir);
  1732.       strcpy(s1, net_data);
  1733.       if (LAST(s1) == '\\')
  1734.         LAST(s1) = 0;
  1735.       sprintf(s, "%s\\NEWS.EXE %s %s %hu", maindir, s1, NEWSHOST, net_sysnum);
  1736.       ok = 1;
  1737.       if (do_spawn(s) != EXIT_SUCCESS)
  1738.         output("\n ■ Unsuccessful news retrieval session...");
  1739.       set_net_num(netnum);
  1740.       sprintf(temp, "%sP0*.*", net_data);
  1741.       f1 = findfirst(temp, &ff, 0);
  1742.       while (f1 == 0) {
  1743.         rnewsbytes += ff.ff_fsize;
  1744.         f1 = findnext(&ff);
  1745.       }
  1746.     }
  1747.   } else {
  1748.     output("\n");
  1749.     set_net_num(netnum);
  1750.     strcpy(s, "NETWORK0.EXE");
  1751.     for (i = 1; i < argc; i++) {
  1752.       strcat(s, " ");
  1753.       strcat(s, argv[i]);
  1754.     }
  1755.     s[strlen(s) + 1] = '\0';
  1756.     do_it(s);
  1757.     do_exit(EXIT_SUCCESS);
  1758.   }
  1759.   unload_klos();
  1760.   newstime = clock() - starttime;
  1761.   output("\n ■ Updating network connection records...");
  1762.   if (ONECALL) {
  1763.     recdbytes = ((recdbytes + 1023) / 1024);
  1764.     sentbytes = ((sentbytes + 1023) / 1024);
  1765.     if (mailtime)
  1766.       sprintf(ttotal, "%2.1f", (mailtime / CLK_TCK / 60));
  1767.     else
  1768.       strcpy(ttotal, "0.1");
  1769.     if (update_contact(sy, sentbytes, recdbytes))
  1770.       output("\n ■ Unable to access CONTACT.NET!");
  1771.     if (write_netlog(sy, sentbytes, recdbytes, ttotal))
  1772.       output("\n ■ Unable to access NET.LOG!");
  1773.     if (newstime)
  1774.       sprintf(ttotal, "%2.1f", (newstime / CLK_TCK / 60));
  1775.     else
  1776.       strcpy(ttotal, "0.1");
  1777.     rnewsbytes = ((rnewsbytes + 1023) / 1024);
  1778.     snewsbytes = ((snewsbytes + 1023) / 1024);
  1779.     if (update_contact(32767, snewsbytes, rnewsbytes))
  1780.       output("\n ■ Unable to access CONTACT.NET!");
  1781.     if (write_netlog(32767, snewsbytes, rnewsbytes, ttotal))
  1782.       output("\n ■ Unable to access NET.LOG!");
  1783.   } else {
  1784.     if (news) {
  1785.       if (newstime)
  1786.         sprintf(ttotal, "%2.1f", (newstime / CLK_TCK / 60));
  1787.       else
  1788.         strcpy(ttotal, "0.1");
  1789.       rnewsbytes = ((rnewsbytes + 1023) / 1024);
  1790.       snewsbytes = ((snewsbytes + 1023) / 1024);
  1791.       if (update_contact(32767, snewsbytes, rnewsbytes))
  1792.         output("\n ■ Unable to access CONTACT.NET!");
  1793.       if (write_netlog(32767, snewsbytes, rnewsbytes, ttotal))
  1794.         output("\n ■ Unable to access NET.LOG!");
  1795.     } else {
  1796.       recdbytes = ((recdbytes + 1023) / 1024);
  1797.       sentbytes = ((sentbytes + 1023) / 1024);
  1798.       if (mailtime)
  1799.         sprintf(ttotal, "%2.1f", (mailtime / CLK_TCK / 60));
  1800.       else
  1801.         strcpy(ttotal, "0.1");
  1802.       if (update_contact(sy, sentbytes, recdbytes))
  1803.         output("\n ■ Unable to access CONTACT.NET!");
  1804.       if (write_netlog(sy, sentbytes, recdbytes, ttotal))
  1805.         output("\n ■ Unable to access NET.LOG!");
  1806.     }
  1807.   }
  1808.   cd_to(maindir);
  1809.   set_net_num(netnum);
  1810.   output("\n ■ %s completed!\n\n", version);
  1811.   return 0;
  1812. }
  1813.