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