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

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