home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / PPPBCKP / SRC / SRC15B19.ZIP / NETWORK.C < prev    next >
C/C++ Source or Header  |  1997-03-29  |  42KB  |  1,691 lines

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