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