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