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

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