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