home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / PPPBCKP / SRC / SRC15B85.ZIP / EXP.CPP < prev    next >
Text File  |  1998-01-11  |  60KB  |  2,106 lines

  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <dos.h>
  6. #include <fcntl.h>
  7. #include <sys/stat.h>
  8. #include <ctype.h>
  9. #include <mem.h>
  10. #include <conio.h>
  11. #include <io.h>
  12. #include <share.h>
  13. #include <errno.h>
  14. #include <dir.h>
  15. #include <time.h>
  16. #include <alloc.h>
  17. #include <process.h>
  18. #include <direct.h>
  19. #include "vardec.h"
  20. #include "net.h"
  21. #include "retcode.h"
  22.  
  23. #include "version.h"
  24.  
  25. #define WAIT_TIME 10
  26. #define TRIES 100
  27. #define SHARE_LEVEL 10
  28. #define MT_DESQVIEW 0x01
  29. #define MT_WINDOWS  0x02
  30. #define MT_OS2      0x04
  31. #define MT_NB       0x40
  32.  
  33.  
  34. struct msghdr {
  35.   char fromUserName[205];
  36.   char toUserName[81];
  37.   char subject[81];
  38.   char dateTime[81];
  39. };
  40.  
  41. typedef struct {
  42.   char ownername[60];
  43.   char subtype[8];
  44.   char opttext[30];
  45. } MAILLISTREC;
  46.  
  47. MAILLISTREC *maillist;
  48. configrec syscfg;
  49.  
  50. char net_name[31], postmaster[31], net_data[MAXPATH];
  51. char POPNAME[21], REPLYTO[81], DOMAIN[81], tagfile[MAXPATH], maindir[MAXPATH], spamname[81];
  52. unsigned short net_sysnum, defuser, use_alias, usermail, instance, spam;
  53. unsigned curuser, num_users, replyaddr;
  54. int multitasker = 0;
  55. int nlists = 0;
  56. char alphasubtype[8];
  57. unsigned long cur_daten;
  58.  
  59. void dv_pause(void)
  60. {
  61.   __emit__(0xb8, 0x1a, 0x10, 0xcd, 0x15);
  62.   __emit__(0xb8, 0x00, 0x10, 0xcd, 0x15);
  63.   __emit__(0xb8, 0x25, 0x10, 0xcd, 0x15);
  64. }
  65.  
  66. void win_pause(void)
  67. {
  68.   __emit__(0x55, 0xb8, 0x80, 0x16, 0xcd, 0x2f, 0x5d);
  69. }
  70.  
  71. int get_dos_version(void)
  72. {
  73.   _AX = 0x3000;
  74.   geninterrupt(0x21);
  75.   if (_AX % 256 >= 10) {
  76.     multitasker |= MT_OS2;
  77.   }
  78.   return (_AX);
  79. }
  80.  
  81. int get_dv_version(void)
  82. {
  83.   int v;
  84.  
  85.   if (multitasker & MT_OS2)
  86.     return 0;
  87.   _AX = 0x2b01;
  88.   _CX = 0x4445;
  89.   _DX = 0x5351;
  90.   geninterrupt(0x21);
  91.   if (_AL == 0xff) {
  92.     return 0;
  93.   } else {
  94.     v = _BX;
  95.     multitasker |= MT_DESQVIEW;
  96.     return v;
  97.   }
  98. }
  99.  
  100. int get_win_version(void)
  101. {
  102.   int v = 0;
  103.  
  104.   __emit__(0x55, 0x06, 0x53);
  105.   _AX = 0x352f;
  106.   geninterrupt(0x21);
  107.   _AX = _ES;
  108.   if (_AX | _BX) {
  109.     _AX = 0x1600;
  110.     geninterrupt(0x2f);
  111.     v = _AX;
  112.     if (v % 256 <= 1)
  113.       v = 0;
  114.   }
  115.   __emit__(0x5b, 0x07, 0x5d);
  116.   if (v != 0)
  117.     multitasker |= MT_WINDOWS;
  118.   return (v);
  119. }
  120.  
  121. int get_nb_version(void)
  122. {
  123.   _AX = 0;
  124.   geninterrupt(0x2A);
  125.   return (_AH);
  126. }
  127.  
  128. void detect_multitask(void)
  129. {
  130.   get_dos_version();
  131.   get_win_version();
  132.   get_dv_version();
  133.   if (multitasker < 2)
  134.     if (get_nb_version())
  135.       multitasker = MT_NB;
  136. }
  137.  
  138. void giveup_timeslice(void)
  139. {
  140.   if (multitasker) {
  141.     switch (multitasker) {
  142.  case 1: 
  143.  case 3: 
  144.         dv_pause();
  145.         break;
  146.       case 2:
  147.       case 4:
  148.       case 5:
  149.       case 6:
  150.       case 7:
  151.         win_pause();
  152.         break;
  153.       default:
  154.         break;
  155.     }
  156.   }
  157. }
  158.  
  159. int sh_write(int handle, void *buffer, unsigned long len)
  160. {
  161.   if (handle == -1) {
  162.     return (-1);
  163.   }
  164.   return (write(handle, buffer, (unsigned) len));
  165. }
  166.  
  167. int sh_open(char *path, int file_access, unsigned fmode)
  168. {
  169.   int handle, count, share;
  170.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  171.  
  172.   if ((file_access & O_RDWR) || (file_access & O_WRONLY) || (fmode & S_IWRITE)) {
  173.     share = SH_DENYRW;
  174.   } else {
  175.     share = SH_DENYWR;
  176.   }
  177.   handle = open(path, file_access | share, fmode);
  178.   if (handle < 0) {
  179.     count = 1;
  180.     fnsplit(path, drive, dir, file, ext);
  181.     if (access(path, 0) != -1) {
  182.       delay(WAIT_TIME);
  183.       handle = open(path, file_access | share, fmode);
  184.       while (((handle < 0) && (errno == EACCES)) && (count < TRIES)) {
  185.         if (count % 2)
  186.           delay(WAIT_TIME);
  187.         else
  188.           giveup_timeslice();
  189.         count++;
  190.         handle = open(path, file_access | share, fmode);
  191.       }
  192.     }
  193.   }
  194.   return (handle);
  195. }
  196.  
  197. int sh_open1(char *path, int access)
  198. {
  199.   unsigned fmode;
  200.  
  201.   fmode = 0;
  202.   if ((access & O_RDWR) || (access & O_WRONLY))
  203.     fmode |= S_IWRITE;
  204.   if ((access & O_RDWR) || (access & O_RDONLY))
  205.     fmode |= S_IREAD;
  206.   return (sh_open(path, access, fmode));
  207. }
  208.  
  209. int sh_close(int f)
  210. {
  211.   if (f != -1)
  212.     close(f);
  213.   return (-1);
  214. }
  215.  
  216. int sh_read(int handle, void *buf, unsigned len)
  217. {
  218.   if (handle == -1) {
  219.     return (-1);
  220.   }
  221.   return (read(handle, buf, len));
  222. }
  223.  
  224. long sh_lseek(int handle, long offset, int fromwhere)
  225. {
  226.   if (handle == -1) {
  227.     return (-1L);
  228.   }
  229.   return (lseek(handle, offset, fromwhere));
  230. }
  231.  
  232. FILE *fsh_open(char *path, char *fmode)
  233. {
  234.   FILE *f;
  235.   int count, share, md, fd;
  236.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  237.  
  238.   share = SH_DENYWR;
  239.   md = 0;
  240.   if (((char *) _fstrchr(fmode, 'w')) != NULL) {
  241.     share = SH_DENYRD;
  242.     md = O_RDWR | O_CREAT | O_TRUNC;
  243.   } else
  244.     if (((char *) _fstrchr(fmode, 'a')) != NULL) {
  245.     share = SH_DENYRD;
  246.     md = O_RDWR | O_CREAT;
  247.   } else {
  248.     md = O_RDONLY;
  249.   }
  250.   if (((char *) _fstrchr(fmode, 'b')) != NULL) {
  251.     md |= O_BINARY;
  252.   }
  253.   if (((char *) _fstrchr(fmode, '+')) != NULL) {
  254.     md &= ~O_RDONLY;
  255.     md |= O_RDWR;
  256.     share = SH_DENYRD;
  257.   }
  258.   fd = open(path, md | share, S_IREAD | S_IWRITE);
  259.   if (fd < 0) {
  260.     count = 1;
  261.     fnsplit(path, drive, dir, file, ext);
  262.     if ((access(path, 0)) != -1) {
  263.       delay(WAIT_TIME);
  264.       fd = open(path, md | share, S_IREAD | S_IWRITE);
  265.       while (((fd < 0) && (errno == EACCES)) && (count < TRIES)) {
  266.         delay(WAIT_TIME);
  267.         count++;
  268.         fd = open(path, md | share, S_IREAD | S_IWRITE);
  269.       }
  270.     }
  271.   }
  272.   if (fd > 0) {
  273.     if (((char *) _fstrchr(fmode, 'a')) != NULL)
  274.       sh_lseek(fd, 0L, SEEK_END);
  275.     f = fdopen(fd, fmode);
  276.     if (!f) {
  277.       close(fd);
  278.     }
  279.   } else
  280.     f = 0;
  281.   return (f);
  282. }
  283.  
  284. size_t fsh_write(void *ptr, size_t size, size_t n, FILE * stream)
  285. {
  286.  
  287.   if (stream == NULL) {
  288.     return (0);
  289.   }
  290.   return (fwrite(ptr, size, n, stream));
  291. }
  292.  
  293.  
  294. int exist(char *s)
  295. {
  296.   int i;
  297.   struct ffblk ff;
  298.  
  299.   i = findfirst(s, &ff, 0);
  300.   if (i)
  301.     return (0);
  302.   else
  303.     return (1);
  304. }
  305.  
  306. char *stripspace(char *str)
  307. {
  308.   char *obuf, *nbuf;
  309.  
  310.   if (str) {
  311.     for (obuf = str, nbuf = str; *obuf; ++obuf) {
  312.       if (!isspace(*obuf))
  313.         *nbuf++ = *obuf;
  314.     }
  315.     *nbuf = NULL;
  316.   }
  317.   return (str);
  318. }
  319.  
  320. static unsigned char *trimstr1(unsigned char *s)
  321. {
  322.   int i;
  323.   static char *whitespace = " \r\n\t";
  324.  
  325.   i = (int) strlen(s);
  326.   while ((i > 0) && ((char *) _fstrchr(whitespace, s[i - 1]) != NULL))
  327.     --i;
  328.   while ((i > 0) && ((char *) _fstrchr(whitespace, *s) != NULL)) {
  329.     memmove(s, s + 1, --i);
  330.   }
  331.   s[i] = 0;
  332.   return (s);
  333. }
  334.  
  335. void output(char *fmt,...)
  336. {
  337.   va_list v;
  338.   char s[255];
  339.  
  340.   va_start(v, fmt);
  341.   vsprintf(s, fmt, v);
  342.   va_end(v);
  343.   fputs(s, stderr);
  344. }
  345.  
  346. int log_it(int display, char *fmt,...)
  347. {
  348.   va_list v;
  349.   char s[255], fn[MAXPATH];
  350.   FILE *fp;
  351.  
  352.   sprintf(fn, "%sNEWS.LOG", net_data);
  353.   if ((fp = fsh_open(fn, "at")) == NULL) {
  354.     output("\n ! Error accessing %s.", fn);
  355.     return 1;
  356.   }
  357.   va_start(v, fmt);
  358.   vsprintf(s, fmt, v);
  359.   va_end(v);
  360.   fputs(s, fp);
  361.   fclose(fp);
  362.   if (display)
  363.     fputs(s, stderr);
  364.   return 0;
  365. }
  366.  
  367.  
  368. int num_to_name(int out, char *where, int whichuser, int alias)
  369. {
  370.   char *ss, fn[MAXPATH], s[101], buf[60];
  371.   int i, userfile, num_users, found;
  372.   long pos;
  373.   FILE *fp;
  374.   userrec ur;
  375.  
  376.   found = 0;
  377.   if (alias == 2) {
  378.     strcpy(where, "Anonymous");
  379.     return 1;
  380.   }
  381.   if (out) {
  382.     sprintf(fn, "%sACCT.INI", net_data);
  383.     if ((fp = fsh_open(fn, "rt")) != NULL) {
  384.       while ((fgets(s, 100, fp)) && (!found)) {
  385.         if (strnicmp(s, "USER", 4) == 0) {
  386.           ss = strtok(s, "=");
  387.           strcpy(buf, &s[4]);
  388.           if (isdigit(buf[0])) {
  389.             i = atoi(buf);
  390.             if (i == whichuser) {
  391.               ss = strtok(NULL, "\r\n");
  392.               if (ss) {
  393.                 trimstr1(ss);
  394.                 strcpy(where, ss);
  395.                 found = 1;
  396.                 replyaddr = 1;
  397.               }
  398.             }
  399.           }
  400.         }
  401.       }
  402.       if (fp != NULL)
  403.         fclose(fp);
  404.       if (found)
  405.         return (found);
  406.     }
  407.   }
  408.   sprintf(fn, "%sUSER.LST", syscfg.datadir);
  409.   userfile = sh_open1(fn, O_RDONLY | O_BINARY);
  410.   if (userfile < 0) {
  411.     log_it(1, "\n ■ Cannot open %s.", fn);
  412.     return (found);
  413.   }
  414.   num_users = ((int) (filelength(userfile) / sizeof(userrec)));
  415.  
  416.   if (whichuser > num_users) {
  417.     log_it(1, "\n ■ User #%d out of range.", whichuser);
  418.     return (found);
  419.   }
  420.   pos = ((long) sizeof(userrec) * ((long) whichuser));
  421.   lseek(userfile, pos, SEEK_SET);
  422.   sh_read(userfile, &ur, sizeof(userrec));
  423.   if (ur.realname[0] == 0)
  424.     log_it(1, "\n ■ User #%d has blank real name field!", whichuser);
  425.   else {
  426.     if (ur.inact == inact_deleted)
  427.       log_it(1, "\n ■ User #%d is marked as deleted!", whichuser);
  428.     else {
  429.       if (!alias)
  430.         strcpy(where, ur.realname);
  431.       else {
  432.         strcpy(where, ur.name);
  433.         strlwr(where);
  434.       }
  435.       found = 1;
  436.     }
  437.   }
  438.   sh_close(userfile);
  439.   return (found);
  440. }
  441.  
  442.  
  443. void parse_net_ini(void)
  444. {
  445.   char s[MAXPATH], origline[121], line[121], *ss, inlist = 0;
  446.   FILE *fp;
  447.   long fptr;
  448.  
  449.   defuser = 1;
  450.   use_alias = 1;
  451.   usermail = 1;
  452.   nlists = 0;
  453.   maillist = NULL;
  454.   *REPLYTO = 0;
  455.   sprintf(s, "%sNET.INI", maindir);
  456.   if ((fp = fsh_open(s, "rt")) == NULL) {
  457.     log_it(1, "\n ■ Unable to open %s.", s);
  458.     return;
  459.   }
  460.   while (fgets(line, 80, fp)) {
  461.     ss = NULL;
  462.     strcpy(origline, line);
  463.     stripspace(line);
  464.     if ((line[0] == ';') || (line[0] == '\n') || (line[0] == 0))
  465.       continue;
  466.     if (strnicmp(line, "[MAILLIST]", 10) == 0) {
  467.       fptr = ftell(fp);
  468.       while ((fgets(line, 80, fp)) && (line[0] != '[')) {
  469.         if ((line[0] != '[') && (line[0] != ';') && (line[0] != 0))
  470.           ++nlists;
  471.       }
  472.       fseek(fp, fptr, SEEK_SET);
  473.       maillist = (MAILLISTREC *) malloc((nlists + 1) * sizeof(MAILLISTREC));
  474.       if (maillist == NULL)
  475.         log_it(1, "\n ■ Not enough memory to process %d mailing lists.", nlists);
  476.       else
  477.         inlist = 1;
  478.       nlists = 0;
  479.       continue;
  480.     } else
  481.       if (line[0] == '[') {
  482.       inlist = 0;
  483.       continue;
  484.       }
  485.     if (inlist) {
  486.       if ((line[0] != ';') && (line[0] != 0)) {
  487.         ss = strtok(line, "\"");
  488.         trimstr1(ss);
  489.         if (*ss) {
  490.           ss = strtok(NULL, "\"");
  491.           if (*ss) {
  492.             strncpy(maillist[nlists].opttext, ss, 29);
  493.             maillist[nlists].opttext[30] = '\0';
  494.           } else
  495.             maillist[nlists].opttext[0] = '\0';
  496.         }
  497.         ss = strtok(line, "*\n");
  498.         trimstr1(ss);
  499.         strcpy(maillist[nlists].ownername, ss);
  500.         ss = strtok(NULL, "\"\n");
  501.         trimstr1(ss);
  502.         if (*ss) {
  503.           strlwr(maillist[nlists].ownername);
  504.           strcpy(maillist[nlists++].subtype, ss);
  505.         } else
  506.           log_it(1, "\n ■ Missing *subtype in maillist for %s.",
  507.                  maillist[nlists].ownername);
  508.       }
  509.       continue;
  510.     }
  511.     if (strnicmp(line, "POSTMASTER", 10) == 0) {
  512.       ss = strtok(line, "=");
  513.       if (ss) {
  514.         ss = strtok(NULL, "\n");
  515.         if (ss)
  516.           defuser = atoi(ss);
  517.       }
  518.       continue;
  519.     }
  520.     if (strnicmp(line, "SPAMCONTROL", 11) == 0) {
  521.       ss = strtok(line, "=");
  522.       if (ss) {
  523.         ss = strtok(NULL, "\n");
  524.         if ((ss[0] == 'y') || (ss[0] == 'Y'))
  525.           spam = 1;
  526.       }
  527.       continue;
  528.     }
  529.     if (strnicmp(line, "USERMAIL", 8) == 0) {
  530.       ss = strtok(line, "=");
  531.       if (ss) {
  532.         ss = strtok(NULL, "\n");
  533.         if ((ss[0] == 'n') || (ss[0] == 'N'))
  534.           usermail = 0;
  535.       }
  536.       continue;
  537.     }
  538.     if (strnicmp(line, "SPAMADDRESS", 9) == 0) {
  539.       ss = strtok(line, "=");
  540.       if (ss) {
  541.         ss = strtok(NULL, "\n");
  542.         trimstr1(ss);
  543.         strcpy(spamname, ss);
  544.         if (stricmp(spamname, "DEFAULT") == 0)
  545.           strcpy(spamname, "WWIV_BBS@nospam.net");
  546.       }
  547.       continue;
  548.     }
  549.     if (strnicmp(line, "REPLYTO", 7) == 0) {
  550.       ss = strtok(origline, "=");
  551.       if (ss) {
  552.         ss = strtok(NULL, "\n");
  553.         trimstr1(ss);
  554.         strcpy(REPLYTO, ss);
  555.       }
  556.       continue;
  557.     }
  558.     if (strnicmp(line, "SIGNATURE", 9) == 0) {
  559.       ss = strtok(line, "=");
  560.       if (ss) {
  561.         ss = strtok(NULL, "\n");
  562.         trimstr1(ss);
  563.         strcpy(tagfile, ss);
  564.         if (!exist(tagfile)) {
  565.           log_it(1, "\n ■ Default signature file %s not found!", tagfile);
  566.           tagfile[0] = 0;
  567.         }
  568.       }
  569.       continue;
  570.     }
  571.     if (strnicmp(line, "REALNAME", 8) == 0) {
  572.       ss = strtok(line, "=");
  573.       if (ss) {
  574.         ss = strtok(NULL, "\n");
  575.         if ((ss[0] == 'y') || (ss[0] == 'Y'))
  576.           use_alias = 0;
  577.       }
  578.     }
  579.   }
  580.   num_to_name(0, postmaster, defuser, 1);
  581.   if (fp != NULL)
  582.     fclose(fp);
  583.   return;
  584. }
  585.  
  586. unsigned char *strrep(char *str, char old, char New)
  587. {
  588.   int i;
  589.  
  590.   for (i = 0; str[i]; i++)
  591.     if (str[i] == old)
  592.       str[i] = New;
  593.   return (str);
  594. }
  595.  
  596.  
  597. char *stristr(char *String, char *Pattern)
  598. {
  599.   char *pptr, *sptr, *start;
  600.   unsigned int slen, plen;
  601.  
  602.   for (start = String, pptr = Pattern, slen = strlen(String),
  603.        plen = strlen(Pattern); slen >= plen; start++, slen--) {
  604.     while (toupper(*start) != toupper(*Pattern)) {
  605.       start++;
  606.       slen--;
  607.       if (slen < plen)
  608.         return (NULL);
  609.     }
  610.     sptr = start;
  611.     pptr = Pattern;
  612.     while (toupper(*sptr) == toupper(*pptr)) {
  613.       sptr++;
  614.       pptr++;
  615.       if ('\0' == *pptr)
  616.         return (start);
  617.     }
  618.   }
  619.   return (NULL);
  620. }
  621.  
  622. unsigned int name_to_num(char *name)
  623. {
  624.   int userfile, usernum;
  625.   userrec ur;
  626.   long pos;
  627.   char fn[MAXPATH], ur_name[60], ur_realname[60];
  628.  
  629.   if ((stristr(name, "Multiple recipients of") != NULL) || (strlen(name) == 0))
  630.     return 0;
  631.   sprintf(fn, "%sM%s.NET", net_data, name);
  632.   if (exist(fn)) {
  633.     log_it(1, "\n ■ Matched \"%s\" mailing list.", name);
  634.     strcpy(alphasubtype, name);
  635.     return (unsigned) (65535L);
  636.   }
  637.   sprintf(fn, "%sUSER.LST", syscfg.datadir);
  638.   userfile = sh_open1(fn, O_RDONLY | O_BINARY);
  639.   if (userfile < 0) {
  640.     log_it(1, "\n ■ Cannot open %s", fn);
  641.     return (0);
  642.   } else
  643.     log_it(1, "\n ■ Searching for user \"%s\"...", name);
  644.   num_users = ((int) (filelength(userfile) / sizeof(userrec)));
  645.  
  646.   for (usernum = 1; usernum < num_users; usernum++) {
  647.     pos = ((long) sizeof(userrec) * ((long) usernum));
  648.     lseek(userfile, pos, SEEK_SET);
  649.     sh_read(userfile, &ur, sizeof(userrec));
  650.     strcpy(ur_realname, ur.realname);
  651.     strrep(ur_realname, ' ', '_');
  652.     strcpy(ur_name, ur.name);
  653.     strrep(ur_name, ' ', '_');
  654.     if ((strcmpi(ur.realname, name) == 0) || (strcmpi(ur_realname, name) == 0) ||
  655.         (strcmpi(ur.name, name) == 0) || (strcmpi(ur_name, name) == 0)) {
  656.       if (ur.inact == inact_deleted) {
  657.         log_it(1, " user #%d is deleted account.", usernum);
  658.         usernum = 0;
  659.         break;
  660.       } else {
  661.         log_it(1, " matched to user #%d.", usernum);
  662.         break;
  663.       }
  664.     }
  665.   }
  666.   userfile = sh_close(userfile);
  667.  
  668.   if (usernum >= num_users) {
  669.     log_it(1, "... no match found.");
  670.     return 0;
  671.   }
  672.   return (usernum);
  673. }
  674.  
  675. char *find_name(char *name)
  676. {
  677.   char *ss, *ss1, hold[81];
  678.   int focus = 0;
  679.  
  680.   curuser = 0;
  681.   strcpy(hold, name);
  682.   ss1 = NULL;
  683.   if ((ss = _fstrchr(name, '(')) != NULL) {
  684.     ss1 = strtok(name, "(");
  685.     ss1 = strtok(NULL, ")");
  686.   } else
  687.     if ((ss = _fstrchr(name, '\"')) != NULL) {
  688.     ss1 = strtok(ss, "\"");
  689.   } else
  690.     if ((ss = _fstrchr(name, '<')) != NULL) {
  691.     ss1 = strtok(name, "<");
  692.   } else
  693.     focus = 1;
  694.   trimstr1(ss1);
  695.   if (focus) {
  696.     stripspace(hold);
  697.     curuser = name_to_num(hold);
  698.   } else
  699.     curuser = name_to_num(ss1);
  700.   if (curuser == 0)
  701.     return ('\0');
  702.   else
  703.     if (curuser == ((unsigned) 65535L))
  704.     return (alphasubtype);
  705.   else
  706.     return (ss1);
  707. }
  708.  
  709. void name_packet(char *pktname)
  710. {
  711.   int ok;
  712.   struct stat info;
  713.   unsigned i;
  714.  
  715.   ok = 0;
  716.   for (i = 0; ((i < 1000) && (!ok)); i++) {
  717.     sprintf(pktname, "%sP0-%u.%3.3hu", net_data, i, instance);
  718.     if (stat(pktname, &info) == -1)
  719.       ok = 1;
  720.   }
  721. }
  722.  
  723. void name_bad(char *newfn)
  724. {
  725.   int ok;
  726.   struct stat info;
  727.   unsigned i;
  728.  
  729.   ok = 0;
  730.   for (i = 0; ((i < 1000) && (!ok)); i++) {
  731.     sprintf(newfn, "%sINBOUND\\SUB-%3.3u.BAD", net_data, i);
  732.     if (stat(newfn, &info) == -1)
  733.       ok = 1;
  734.   }
  735. }
  736.  
  737. #define FROM_RETURN 0x01
  738. #define FROM_FROM   0x02
  739. #define FROM_REPLY  0x04
  740.  
  741. int import(char *fn)
  742. {
  743.   char s[513], s1[121], pktname[MAXPATH], msgdate[61], *ss, *ss1, *p, *id, *name;
  744.   char alphatype[21], recvdate[81];
  745.   int i, f, from, match, subj, intext, done, tolist, mailuser;
  746.   long textlen, reallen;
  747.   struct msghdr mh;
  748.   net_header_rec nh;
  749.   FILE *fp;
  750.  
  751.   tolist = 0;
  752.   intext = 0;
  753.   mailuser = 0;
  754.   f = sh_open1(fn, O_RDONLY | O_BINARY);
  755.   if (f < 0)
  756.     return (1);
  757.   textlen = filelength(f);
  758.   if (textlen > 32767L) {
  759.     sh_close(f);
  760.     log_it(1, "\n ■ Skipping UU/Base64 %s.", fn);
  761.     return (1);
  762.   }
  763.   p = (char *) malloc((int) (textlen + 1));
  764.   if (p == NULL) {
  765.     sh_close(f);
  766.     log_it(1, "\n ■ Unable to allocate %ld bytes.", textlen);
  767.     return (1);
  768.   }
  769.   sh_read(f, (void *) p, (int) textlen);
  770.   sh_close(f);
  771.  
  772.   nh.tosys = net_sysnum;
  773.   nh.fromsys = 32767;
  774.   nh.fromuser = 0;
  775.   nh.touser = defuser;
  776.   nh.main_type = main_type_email;
  777.   nh.minor_type = 0;
  778.   nh.list_len = 0;
  779.   ++cur_daten;
  780.   nh.daten = cur_daten;
  781.   strncpy(msgdate, ctime(&(time_t) nh.daten), 24);
  782.   msgdate[24] = '\0';
  783.   sprintf(recvdate, "0RReceived: PPP Project %s on %s\r\n", VERSION, msgdate);
  784.   strcat(msgdate, "\r\n");
  785.   nh.method = 0;
  786.  
  787.   strcpy(mh.fromUserName, "Unknown");
  788.   strcpy(mh.toUserName, "Unknown");
  789.   strcpy(mh.subject, "None");
  790.  
  791.   if ((fp = fsh_open(fn, "rb")) == NULL) {
  792.     free(p);
  793.     return 1;
  794.   }
  795.   match = subj = done = 0;
  796.   while ((fgets(s, 254, fp)) && !done) {
  797.     if (s[0] == 4) {
  798.       ss = strtok(s, "R");
  799.       ss = strtok(NULL, "\r\n");
  800.       if (ss == NULL)
  801.         s[0] = 0;
  802.       else
  803.         strcpy(s, ss);
  804.     } else
  805.       intext = 1;
  806.     if (!intext) {
  807.       if (strncmpi(s, "x-wwiv-user", 11) == 0) {
  808.         ss1 = strtok(s, "#");
  809.         if (ss1) {
  810.           ss1 = strtok(NULL, "\r\n");
  811.           mailuser = atoi(ss1);
  812.         }
  813.       }
  814.       if (strncmpi(s, "from:", 5) == 0)
  815.         from = FROM_FROM;
  816.       else
  817.         if (strncmpi(s, "return-path:", 12) == 0)
  818.         from = FROM_RETURN;
  819.       else
  820.         if (strncmpi(s, "sender:", 7) == 0)
  821.         from = FROM_RETURN;
  822.       else
  823.         if (strncmpi(s, "x-sender:", 9) == 0)
  824.         from = FROM_RETURN;
  825.       else
  826.         if (strncmpi(s, "x-to:", 5) == 0)
  827.         from = FROM_RETURN;
  828.       else
  829.         if (strncmpi(s, "reply-to:", 9) == 0)
  830.         from = FROM_REPLY;
  831.       else
  832.         if (strncmpi(s, "x-reply-to:", 11) == 0)
  833.         from = FROM_REPLY;
  834.       else
  835.         from = 0;
  836.       if (from) {
  837.         ss = strtok(s, ": ");
  838.         ss = strtok(NULL, "\r\n");
  839.         trimstr1(ss);
  840.         if ((from & (FROM_RETURN | FROM_REPLY)) && (nh.main_type == main_type_email)) {
  841.           strcpy(s1, ss);
  842.           strlwr(s1);
  843.           for (i = 0; (i < nlists) && (nh.main_type == main_type_email); i++) {
  844.             if (stristr(s1, maillist[i].ownername) != NULL) {
  845.               if (atoi(maillist[i].subtype)) {
  846.                 nh.main_type = main_type_pre_post;
  847.                 nh.minor_type = atoi(maillist[i].subtype);
  848.               } else {
  849.                 nh.main_type = main_type_new_post;
  850.                 nh.minor_type = 0;
  851.                 strcpy(alphatype, maillist[i].subtype);
  852.               }
  853.               strcpy(alphasubtype, maillist[i].subtype);
  854.               nh.touser = 0;
  855.               from = 0;
  856.             }
  857.           }
  858.         }
  859.         if ((from > match) && ((nh.main_type == main_type_email) || (from == FROM_FROM))) {
  860.           match = from;
  861.           if (strcspn(ss, "<") != strlen(ss)) {
  862.             if ((strcspn(ss, " ")) < (strcspn(ss, "<"))) {
  863.               name = strtok(ss, "<");
  864.               trimstr1(name);
  865.               id = strtok(NULL, ">");
  866.               trimstr1(id);
  867.               sprintf(mh.fromUserName, "%s <%s>", name, id);
  868.             } else {
  869.               strncpy(mh.fromUserName, ss, 205);
  870.               trimstr1(mh.fromUserName);
  871.               if (strcspn(ss, " ") != strlen(ss))
  872.                 log_it(1, "\nName is *after* host in \"%s\"", name);
  873.             }
  874.           } else
  875.             strncpy(mh.fromUserName, ss, 205);
  876.           mh.fromUserName[190] = 0;
  877.           strcat(mh.fromUserName, "\r\n");
  878.         }
  879.       } else
  880.         if ((strncmpi(s, "subject:", 8) == 0) && (!subj)) {
  881.         ss = strtok(s, ": ");
  882.         ss = strtok(NULL, "\r\n");
  883.         trimstr1(ss);
  884.         strncpy(mh.subject, ss, 81);
  885.         mh.subject[72] = 0;
  886.         subj = 1;
  887.       } else
  888.         if (strncmpi(s, "date:", 5) == 0) {
  889.         ss = strtok(s, ": ");
  890.         ss = strtok(NULL, "\r\n");
  891.         trimstr1(ss);
  892.         strncpy(msgdate, ss, 58);
  893.         msgdate[58] = '\0';
  894.         strcat(msgdate, "\r\n");
  895.       } else
  896.         if ((strncmpi(s, "to:", 3) == 0) || (strncmpi(s, "cc:", 3) == 0)) {
  897.         if (mailuser == 0) {
  898.           ss = strtok(s, ":");
  899.           ss = strtok(NULL, "\r\n");
  900.           strncpy(mh.toUserName, ss, 81);
  901.           mh.toUserName[80] = 0;
  902.           curuser = 0;
  903.           trimstr1(mh.toUserName);
  904.           find_name(mh.toUserName);
  905.         } else {
  906.           curuser = mailuser;
  907.           if (!num_to_name(0, mh.toUserName, curuser, use_alias)) {
  908.             curuser = 0;
  909.             mh.toUserName[0] = 0;
  910.           }
  911.         }
  912.  
  913.         if ((stristr(mh.toUserName, "Multiple recipients of") != NULL) && (curuser != (unsigned) 65535L)) {
  914.           for (i = 0; (i < nlists) && (nh.main_type == main_type_email); i++) {
  915.             if (stristr(mh.toUserName, maillist[i].opttext) != NULL) {
  916.               if (atoi(maillist[i].subtype)) {
  917.                 nh.main_type = main_type_pre_post;
  918.                 nh.minor_type = atoi(maillist[i].subtype);
  919.               } else {
  920.                 nh.main_type = main_type_new_post;
  921.                 nh.minor_type = 0;
  922.                 strcpy(alphatype, maillist[i].subtype);
  923.               }
  924.               strcpy(alphasubtype, maillist[i].subtype);
  925.               nh.touser = 0;
  926.             }
  927.           }
  928.         }
  929.         if ((curuser == (unsigned) 65535L) && (nh.main_type == main_type_email)) {
  930.           strcpy(alphatype, alphasubtype);
  931.           nh.main_type = main_type_new_post;
  932.           nh.minor_type = 0;
  933.           nh.touser = 0;
  934.           tolist = 1;
  935.         } else
  936.           if ((mh.toUserName[0] == 0) || (curuser == 0)) {
  937.           nh.touser = defuser;
  938.           strcpy(mh.toUserName, postmaster);
  939.         } else {
  940.           nh.touser = curuser;
  941.         }
  942.       } else
  943.         if (strncmpi(s, "apparently-to:", 14) == 0) {
  944.         ss = strtok(s, ": ");
  945.         ss = strtok(NULL, "\r\n");
  946.         strncpy(mh.toUserName, ss, 81);
  947.         mh.toUserName[80] = 0;
  948.         curuser = 0;
  949.         trimstr1(mh.toUserName);
  950.         if (_fstrstr(mh.toUserName, " "))
  951.           find_name(mh.toUserName);
  952.         else
  953.           mh.toUserName[0] = 0;
  954.         if ((curuser == (unsigned) 65535L) && (nh.main_type == main_type_email)) {
  955.           strcpy(alphatype, alphasubtype);
  956.           nh.main_type = main_type_new_post;
  957.           nh.minor_type = 0;
  958.           nh.touser = 0;
  959.           tolist = 1;
  960.         } else
  961.           if ((mh.toUserName[0] == 0) || (curuser == 0)) {
  962.           nh.touser = defuser;
  963.           strcpy(mh.toUserName, postmaster);
  964.         } else
  965.           nh.touser = curuser;
  966.         }
  967.     } else
  968.       done = 1;
  969.   }
  970.   if (fp != NULL)
  971.     fclose(fp);
  972.   trimstr1(mh.fromUserName);
  973.   strcat(mh.fromUserName, "\r\n");
  974.   log_it(1, "\n ■ From    : %s", strlwr(mh.fromUserName));
  975.   if ((nh.main_type == main_type_pre_post) ||
  976.       (nh.main_type == main_type_new_post))
  977.     log_it(1, " ■ Post to : Sub %s", alphasubtype);
  978.   else
  979.     log_it(1, " ■ Sent to : %s #%hd", strupr(mh.toUserName), nh.touser);
  980.   log_it(1, "\n ■ Subject : %s", mh.subject);
  981.   name_packet(pktname);
  982.   if ((fp = fsh_open(pktname, "wb")) == NULL) {
  983.     log_it(1, "\n ■ Unable to create packet %s", pktname);
  984.     free(p);
  985.     return (1);
  986.   }
  987.   nh.length = textlen + strlen(mh.fromUserName) + strlen(mh.subject)
  988.       + strlen(msgdate) + strlen(recvdate) + 1;
  989.   if (nh.main_type == main_type_new_post)
  990.     nh.length += strlen(alphatype) + 1;
  991.   while (tolist >= 0) {
  992.     fsh_write(&nh, sizeof(net_header_rec), 1, fp);
  993.     if (nh.main_type == main_type_new_post)
  994.       fsh_write(alphatype, sizeof(char), strlen(alphatype) +1, fp);
  995.     fsh_write(mh.subject, sizeof(char), strlen(mh.subject) +1, fp);
  996.     fsh_write(mh.fromUserName, sizeof(char), strlen(mh.fromUserName), fp);
  997.     fsh_write(msgdate, sizeof(char), strlen(msgdate), fp);
  998.     fsh_write(recvdate, sizeof(char), strlen(recvdate), fp);
  999.     reallen = fsh_write(p, sizeof(char), (int) textlen, fp);
  1000.     if (reallen != textlen)
  1001.       log_it(1, "\n ■ Expected %ld bytes, wrote %ld bytes.", textlen, reallen);
  1002.     nh.tosys = 32767;
  1003.     --tolist;
  1004.   }
  1005.   if (fp != NULL)
  1006.     fclose(fp);
  1007.   free(p);
  1008.   return (0);
  1009. }
  1010.  
  1011.  
  1012. char *stripcolors(char *str)
  1013. {
  1014.   char *obuf, *nbuf;
  1015.  
  1016.   if (str) {
  1017.     for (obuf = str, nbuf = str; *obuf; ++obuf) {
  1018.       if (*obuf == 3)
  1019.         ++obuf;
  1020.       else
  1021.         if (((*obuf < 32) && (*obuf != 9)) || (*obuf > 126))
  1022.         continue;
  1023.       else
  1024.         *nbuf++ = *obuf;
  1025.     }
  1026.     *nbuf = NULL;
  1027.   }
  1028.   return (str);
  1029. }
  1030.  
  1031. void properize(char *s)
  1032. {
  1033.   int i;
  1034.  
  1035.   for (i = 0; i < strlen(s); i++) {
  1036.     if ((i == 0) || ((i > 0) && ((s[i - 1] == ' ') || (s[i - 1] == '.') ||
  1037.            ((s[i - 1] == 'c') && (s[i - 2] == 'M')) || ((s[i - 1] == 'c') &&
  1038.              (s[i - 2] == 'a') && (s[i - 3] == 'M')) || (s[i - 1] == '-') ||
  1039.          (s[i - 1] == '_') || ((s[i - 1] == '\'') && (s[i - 2] == 'O'))))) {
  1040.       s[i] = toupper(s[i]);
  1041.     } else
  1042.       s[i] = tolower(s[i]);
  1043.   }
  1044. }
  1045.  
  1046. void move_dead(net_header_rec * nh, char *text)
  1047. {
  1048.   char fn[81];
  1049.   int f;
  1050.   long l, l1;
  1051.  
  1052.   sprintf(fn, "%sDEAD.NET", net_data);
  1053.   f = sh_open(fn, O_RDWR | O_BINARY | SH_DENYRW | O_CREAT, S_IREAD | S_IWRITE);
  1054.   if (f > 0) {
  1055.     lseek(f, 0L, SEEK_END);
  1056.     l = l1 = tell(f);
  1057.     write(f, (void *) nh, sizeof(net_header_rec));
  1058.     l1 += sizeof(net_header_rec);
  1059.     write(f, (void *) text, (int) (nh->length));
  1060.     l1 += nh->length;
  1061.     if (l1 != tell(f))
  1062.       chsize(f, l);
  1063.     f = sh_close(f);
  1064.   } else
  1065.     log_it(1, "\n ! Couldn't open '%s'", fn);
  1066. }
  1067.  
  1068. void get_subtype(int sub, char *where)
  1069. {
  1070.   int ok, which;
  1071.   char fn[181], s[81], net_name[21], *ss;
  1072.   FILE *fp;
  1073.  
  1074.   where[0] = 0;
  1075.   which = sub;
  1076.   sprintf(fn, "%sSUBS.XTR", syscfg.datadir);
  1077.   if ((fp = fsh_open(fn, "r")) == NULL)
  1078.     return;
  1079.   ok = 0;
  1080.   while (fgets(s, 80, fp)) {
  1081.     if (*s == '!') {
  1082.       if (which == atoi(&s[1]))
  1083.         ok = 1;
  1084.     }
  1085.     if (ok && (*s == '$')) {
  1086.       ss = strtok(s, " ");
  1087.       strcpy(net_name, &ss[1]);
  1088.       ss = strtok(NULL, " ");
  1089.       if (fp != NULL)
  1090.         fclose(fp);
  1091.       if ((stricmp(net_name, "FILENET") == 0)) {
  1092.         trimstr1(ss);
  1093.         strcpy(where, ss);
  1094.         return;
  1095.       } else
  1096.         return;
  1097.     }
  1098.   }
  1099.   if (fp != NULL)
  1100.     fclose(fp);
  1101. }
  1102.  
  1103. unsigned find_anony(char *stype)
  1104. {
  1105.   int i, found, anony, result, num_subs;
  1106.   char fn[MAXPATH], subtype[12];
  1107.   subboardrec sub;
  1108.   FILE *fp;
  1109.  
  1110.   result = 0;
  1111.   sprintf(fn, "%sSUBS.DAT", syscfg.datadir);
  1112.   if ((fp = fsh_open(fn, "rb")) == NULL) {
  1113.     log_it(1, "\n ■ Unable to read %s.", fn);
  1114.     return 0;
  1115.   } else {
  1116.     fseek(fp, 0L, SEEK_END);
  1117.     num_subs = (int) (ftell(fp) / sizeof(subboardrec));
  1118.     found = 0;
  1119.     output("    ");
  1120.     for (i = 0; (i < num_subs) && (!found); i++) {
  1121.       output("\b\b\b\b%-4d", i);
  1122.       fseek(fp, (long) i * sizeof(subboardrec), SEEK_SET);
  1123.       fread(&sub, sizeof(subboardrec), 1, fp);
  1124.       get_subtype(i, subtype);
  1125.       if (stricmp(subtype, stype) == 0) {
  1126.         anony = sub.anony & 0x0f;
  1127.         output("\b\b\b\b%s - ", sub.name);
  1128.         switch (anony) {
  1129.           case anony_force_anony:
  1130.             output("forced anonymous.");
  1131.             result = 2;
  1132.             break;
  1133.           case 0:
  1134.             output("aliases.");
  1135.             result = 1;
  1136.             break;
  1137.           default:
  1138.             output("real names.");
  1139.             result = 0;
  1140.             break;
  1141.         }
  1142.         found = 1;
  1143.       }
  1144.     }
  1145.     if (!found)
  1146.       output("\b\b\b\bnot found.");
  1147.   }
  1148.   fclose(fp);
  1149.   return result;
  1150. }
  1151.  
  1152.  
  1153.  
  1154. int export(char *fn)
  1155. {
  1156.   char fn1[121], tagfn[121], groupname[81], outfn[121], _temp_buffer[256], acct_addr[80];
  1157.   char *ss, *buffer, *text, mytype[12], alphatype[21], hold[21], tempoutfn[21];
  1158.   unsigned stype, ttype;
  1159.   int infile, outfile, inloc, outloc, term, ok, a, f, i, j, ns, i6, tolist;
  1160.   net_header_rec nhr;
  1161.   struct msghdr mh;
  1162.   struct tm *time_msg;
  1163.   FILE *fp;
  1164.   time_t some;
  1165.   char *main_type[] =
  1166.   {
  1167.     "Network Update", "email by usernum", "post from sub host", "file",
  1168.     "post to sub host", "external message", "email by name",
  1169.     "NetEdit message", "SUBS.LST", "Extra Data", "BBSLIST from GC",
  1170.     "CONNECT from GC", "Unused_1", "Info from GC", "SSM", "Sub Add Request",
  1171.     "Sub Drop Request", "Sub Add Response", "Sub Drop Response", "Sub Info",
  1172.     "Unused 1", "Unused 2", "Unused 3", "Unused 4", "Unused 5", "new post",
  1173.     "new external"
  1174.   };
  1175.  
  1176.   if ((infile = sh_open1(fn, O_RDONLY | O_BINARY)) == -1)
  1177.     return 1;
  1178.  
  1179.   if ((buffer = (char *) malloc(32 * 1024)) == NULL) {
  1180.     sh_close(infile);
  1181.     log_it(1, "\n ■ Out of memory allocating input buffer!");
  1182.     return 1;
  1183.   }
  1184.   if ((text = (char *) malloc(32 * 1024)) == NULL) {
  1185.     log_it(1, "\n ■ Out of memory allocating output buffer!");
  1186.     sh_close(infile);
  1187.     if (buffer != NULL)
  1188.       free(buffer);
  1189.     return 1;
  1190.   }
  1191.   while (sh_read(infile, &nhr, sizeof(nhr))) {
  1192.     sh_read(infile, buffer, (int) nhr.length);
  1193.     if (nhr.tosys != 32767) {
  1194.       log_it(1, "\n ■ System @%hd routing through @32767... moving to DEAD.NET.",
  1195.              nhr.fromsys);
  1196.       move_dead(&nhr, buffer);
  1197.       continue;
  1198.     }
  1199.     tolist = 0;
  1200.     if (nhr.main_type == main_type_pre_post)
  1201.       nhr.main_type = main_type_post;
  1202.     if ((nhr.main_type == main_type_post) ||
  1203.         (nhr.main_type == main_type_new_post) ||
  1204.         (nhr.main_type == main_type_email_name) ||
  1205.         (nhr.main_type == main_type_ssm)) {
  1206.       inloc = 0;
  1207.       sprintf(hold, "%hu", nhr.minor_type);
  1208.       if ((nhr.main_type == main_type_email_name) ||
  1209.           (nhr.main_type == main_type_ssm) ||
  1210.           (nhr.main_type == main_type_new_post)) {
  1211.         stype = nhr.minor_type;
  1212.         inloc = strlen(buffer) + 1;
  1213.         if ((nhr.main_type == main_type_new_post) || ((nhr.fromsys != net_sysnum) &&
  1214.                                                   (nhr.fromsys != 32767))) {
  1215.           strcpy(alphasubtype, buffer);
  1216.           strcpy(hold, alphasubtype);
  1217.         } else
  1218.           strcpy(mh.toUserName, buffer);
  1219.       } else
  1220.         if (nhr.main_type == main_type_post) {
  1221.         stype = nhr.minor_type;
  1222.       } else {
  1223.         stype = atoi(&buffer[inloc]);
  1224.         sprintf(_temp_buffer, "%u", stype);
  1225.         inloc += strlen(_temp_buffer) + 1;
  1226.       }
  1227.  
  1228.       strncpy(mh.subject, &buffer[inloc], sizeof(mh.subject));
  1229.       stripcolors(mh.subject);
  1230.       inloc += strlen(&buffer[inloc]) + 1;
  1231.  
  1232.       for (term = inloc; buffer[term] != '\r'; term++);
  1233.       buffer[term] = '\0';
  1234.  
  1235.       if ((nhr.fromsys == net_sysnum) && (nhr.fromuser)) {
  1236.         replyaddr = 0;
  1237.         *mytype = 0;
  1238.         if (nhr.main_type == main_type_new_post)
  1239.           strcpy(mytype, hold);
  1240.         if (nhr.main_type == main_type_post)
  1241.           sprintf(mytype, "%hu", nhr.minor_type);
  1242.         if (*mytype) {
  1243.           output("\n ■ Subtype %s - ", mytype);
  1244.           a = find_anony(mytype);
  1245.           if (!num_to_name(1, acct_addr, nhr.fromuser, a)) {
  1246.             log_it(1, "\n ■ No match for user #%hd... skipping message!",
  1247.                    nhr.fromuser);
  1248.             continue;
  1249.           }
  1250.         } else {
  1251.           if (!num_to_name(1, acct_addr, nhr.fromuser, use_alias)) {
  1252.             log_it(1, "\n ■ No match for user #%hd... skipping message!",
  1253.                    nhr.fromuser);
  1254.             continue;
  1255.           }
  1256.         }
  1257.         if (!replyaddr) {
  1258.           strncpy(mh.fromUserName, acct_addr, sizeof(acct_addr));
  1259.           stripcolors(mh.fromUserName);
  1260.           strtok(mh.fromUserName, "#");
  1261.           trimstr1(mh.fromUserName);
  1262.         } else {
  1263.           strncpy(_temp_buffer, &buffer[inloc], sizeof(_temp_buffer));
  1264.           stripcolors(_temp_buffer);
  1265.           strtok(_temp_buffer, "#");
  1266.           trimstr1(_temp_buffer);
  1267.           if (strlen(_temp_buffer) > 25)
  1268.             _temp_buffer[25] = '\0';
  1269.           sprintf(mh.fromUserName, "\"%s\" <%s>", _temp_buffer, acct_addr);
  1270.         }
  1271.       } else {
  1272.         strncpy(mh.fromUserName, &buffer[inloc], sizeof(mh.fromUserName));
  1273.         stripcolors(mh.fromUserName);
  1274.         strtok(mh.fromUserName, "#");
  1275.         trimstr1(mh.fromUserName);
  1276.         if ((nhr.main_type == main_type_post) &&
  1277.             (nhr.main_type == main_type_new_post)) {
  1278.           sprintf(_temp_buffer, " #%hd @%hu", nhr.fromuser, nhr.fromsys);
  1279.           strcat(mh.fromUserName, _temp_buffer);
  1280.           log_it(1, "\n ! From: %s\n", mh.fromUserName);
  1281.         }
  1282.       }
  1283.  
  1284.       inloc = term + 2;
  1285.  
  1286.       while (buffer[inloc] != '\n')
  1287.         inloc++;
  1288.       inloc++;
  1289.  
  1290.       if (strnicmp(&buffer[inloc], "RE: ", 4) == 0) {
  1291.         for (term = inloc; buffer[term] != '\r'; term++);
  1292.         buffer[term] = '\0';
  1293.         strncpy(mh.subject, &buffer[inloc + 4], sizeof(mh.subject));
  1294.         if (strnicmp(mh.subject, "RE: ", 4) != 0) {
  1295.           strcpy(_temp_buffer, "Re: ");
  1296.           strcat(_temp_buffer, mh.subject);
  1297.         }
  1298.         strcpy(mh.subject, _temp_buffer);
  1299.         inloc = term + 2;
  1300.       }
  1301.       if ((strncmp(&buffer[inloc], "BY: ", 4) == 0) ||
  1302.           (strncmp(&buffer[inloc], "TO: ", 4) == 0)) {
  1303.         for (term = inloc; buffer[term] != '\r'; term++);
  1304.         buffer[term] = '\0';
  1305.         strncpy(mh.toUserName, &buffer[inloc + 4], sizeof(mh.toUserName));
  1306.         stripcolors(mh.toUserName);
  1307.         if (strcspn(mh.toUserName, "<") != strlen(mh.toUserName)) {
  1308.           if ((_fstrstr(mh.toUserName, "\"") == 0) && (_fstrstr(mh.toUserName, "(") == 0)) {
  1309.             ss = strtok(mh.toUserName, "<");
  1310.             ss = strtok(NULL, ">");
  1311.             strcpy(mh.toUserName, ss);
  1312.           }
  1313.         }
  1314.         inloc = term + 2;
  1315.       } else {
  1316.         if (nhr.main_type != main_type_email_name) {
  1317.           strcpy(mh.toUserName, "ALL");
  1318.         }
  1319.       }
  1320.       outloc = 0;
  1321.       do {
  1322.         if (buffer[inloc] == 2) {
  1323.           i = inloc + 1;
  1324.           for (j = 1; j < 255; j++) {
  1325.             if (buffer[i] == 'π')
  1326.               buffer[i] = '\r';
  1327.             if ((buffer[i] == '\r') || (i > nhr.length))
  1328.               break;
  1329.             i++;
  1330.           }
  1331.           if (j < 80) {
  1332.             i = (80 - j) / 2;
  1333.             for (j = 1; j <= i; j++)
  1334.               text[outloc++] = ' ';
  1335.           }
  1336.           inloc++;
  1337.         } else
  1338.           if (buffer[inloc] == 3)
  1339.           inloc += 2;
  1340.         else
  1341.           if ((buffer[inloc] == 124) && (isdigit(buffer[inloc + 1])) && (isdigit(buffer[inloc + 2])))
  1342.           inloc += 3;
  1343.         else
  1344.           if ((buffer[inloc] == 4) && (isdigit(buffer[inloc + 1]))) {
  1345.           i = inloc;
  1346.           for (j = 1; j < 255; j++) {
  1347.             if ((buffer[i] == '\r') || (i > nhr.length))
  1348.               break;
  1349.             i++;
  1350.             inloc++;
  1351.           }
  1352.           inloc++;
  1353.           if (buffer[inloc] == '\n')
  1354.             inloc++;
  1355.         } else
  1356.           if (buffer[inloc] >= 127)
  1357.           inloc++;
  1358.         else
  1359.           if (buffer[inloc] == 1)
  1360.           inloc++;
  1361.         else
  1362.           text[outloc++] = buffer[inloc++];
  1363.       } while (inloc < nhr.length);
  1364.  
  1365.       text[outloc] = '\0';
  1366.  
  1367.       if ((nhr.main_type == main_type_post) ||
  1368.           (nhr.main_type == main_type_pre_post) ||
  1369.           (nhr.main_type == main_type_new_post)) {
  1370.         if (nhr.main_type == main_type_new_post) {
  1371.           sprintf(fn1, "%sM%s.NET", net_data, alphasubtype);
  1372.           if (exist(fn1)) {
  1373.             tolist = 1;
  1374.             nhr.main_type = main_type_email_name;
  1375.           }
  1376.         }
  1377.         for (i = 0; (i < nlists) && (nhr.main_type != main_type_email_name); i++) {
  1378.           if (nhr.main_type == main_type_new_post) {
  1379.             if (strcmpi(alphasubtype, maillist[i].subtype) == 0) {
  1380.               nhr.main_type = main_type_email_name;
  1381.               strcpy(mh.toUserName, maillist[i].ownername);
  1382.             }
  1383.           } else {
  1384.             ttype = atoi(maillist[i].subtype);
  1385.             if (ttype == stype) {
  1386.               nhr.main_type = main_type_email_name;
  1387.               strcpy(mh.toUserName, maillist[i].ownername);
  1388.             }
  1389.           }
  1390.         }
  1391.       }
  1392.       switch (nhr.main_type) {
  1393.         case main_type_email:
  1394.         case main_type_email_name:
  1395.         case main_type_ssm:
  1396.           i = 1;
  1397.           sprintf(outfn, "%sMQUEUE\\MSG.%d", net_data, i);
  1398.           while (exist(outfn))
  1399.             sprintf(outfn, "%sMQUEUE\\MSG.%d", net_data, ++i);
  1400.           break;
  1401.         case main_type_new_post:
  1402.         case main_type_post:
  1403.         case main_type_pre_post:
  1404.           i = 1;
  1405.           strcpy(tempoutfn, hold);
  1406.           sprintf(outfn, "%sOUTBOUND\\%s.%d", net_data, tempoutfn, i);
  1407.           while (exist(outfn))
  1408.             sprintf(outfn, "%sOUTBOUND\\%s.%d", net_data, tempoutfn, ++i);
  1409.           break;
  1410.         default:
  1411.           continue;
  1412.       }
  1413.  
  1414.       if (!replyaddr)
  1415.         properize(mh.fromUserName);
  1416.       log_it(1, "\n ■ Creating: %s", outfn);
  1417.       if (nhr.fromsys != net_sysnum) {
  1418.         log_it(1, "\n ■ From    : %s", mh.fromUserName);
  1419.       } else {
  1420.         if (usermail) {
  1421.           if (replyaddr)
  1422.             log_it(1, "\n ■ From    : %s", mh.fromUserName);
  1423.           else
  1424.             log_it(1, "\n ■ From    : \"%s\" <%s@%s>", mh.fromUserName, POPNAME, DOMAIN);
  1425.         } else
  1426.           log_it(1, "\n ■ From    : <%s@%s>", POPNAME, DOMAIN);
  1427.       }
  1428.       if ((nhr.main_type == main_type_post) ||
  1429.           (nhr.main_type == main_type_pre_post) ||
  1430.           (nhr.main_type == main_type_new_post)) {
  1431.         sprintf(fn1, "%sNEWS.RC", net_data);
  1432.         if ((fp = fsh_open(fn1, "rt")) == NULL) {
  1433.           log_it(1, "\n ■ %s not found!", fn1);
  1434.           sh_close(infile);
  1435.           if (text)
  1436.             free(text);
  1437.           if (buffer)
  1438.             free(buffer);
  1439.           return 1;
  1440.         } else {
  1441.           ok = 0;
  1442.           while ((fgets(_temp_buffer, 80, fp) != NULL) && (!ok)) {
  1443.             groupname[0] = 0;
  1444.             ss = strtok(_temp_buffer, " ");
  1445.             if (ss) {
  1446.               strcpy(groupname, ss);
  1447.               ss = strtok(NULL, " ");
  1448.               ss = strtok(NULL, "\r");
  1449.               if (nhr.main_type == main_type_new_post) {
  1450.                 strcpy(alphatype, ss);
  1451.                 if (strncmpi(alphasubtype, alphatype, strlen(alphasubtype)) == 0)
  1452.                   ok = 1;
  1453.               } else {
  1454.                 ttype = atoi(ss);
  1455.                 if (ttype == stype)
  1456.                   ok = 1;
  1457.               }
  1458.             }
  1459.           }
  1460.           *ss = NULL;
  1461.           if (fp != NULL)
  1462.             fclose(fp);
  1463.           if (!ok) {
  1464.             if (nhr.main_type != main_type_new_post)
  1465.               sprintf(alphatype, "%u", stype);
  1466.             log_it(1, "\n ■ Subtype %s not found in NEWS.RC!", alphatype);
  1467.             sh_close(infile);
  1468.             if (text)
  1469.               free(text);
  1470.             if (buffer)
  1471.               free(buffer);
  1472.             return 1;
  1473.           }
  1474.         }
  1475.       }
  1476.       if ((nhr.main_type == main_type_email) ||
  1477.           (nhr.main_type == main_type_email_name) ||
  1478.           (nhr.main_type == main_type_ssm)) {
  1479.         if (tolist)
  1480.           log_it(1, "\n ■ Sent to : %s Mailing List", alphasubtype);
  1481.         else
  1482.           log_it(1, "\n ■ Rcpt to : %s", mh.toUserName);
  1483.       } else
  1484.         log_it(1, "\n ■ Post to : %s", groupname);
  1485.  
  1486.       strcpy(_temp_buffer, mh.subject);
  1487.       j = 0;
  1488.       for (i = 0; i < strlen(mh.subject); i++) {
  1489.         if (_temp_buffer[i] == 3)
  1490.           ++i;
  1491.         else
  1492.           mh.subject[j++] = _temp_buffer[i];
  1493.       }
  1494.       mh.subject[j] = '\0';
  1495.  
  1496.       log_it(1, "\n ■ Subject : %s", mh.subject);
  1497.  
  1498.       if ((nhr.main_type == main_type_email) ||
  1499.           (nhr.main_type == main_type_email_name) ||
  1500.           (nhr.main_type == main_type_ssm)) {
  1501.         if (tolist) {
  1502.           sprintf(fn1, "%sM%s.NET", net_data, alphasubtype);
  1503.           f = sh_open1(fn1, O_RDONLY | O_BINARY);
  1504.           if (filelength(f) <= 0) {
  1505.             log_it(1, "\n ■ Mailing list %s has no subscribers.", alphasubtype);
  1506.             sh_close(f);
  1507.             continue;
  1508.           }
  1509.           sh_close(f);
  1510.         }
  1511.       }
  1512.       outfile = sh_open(outfn, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC | O_EXCL, S_IWRITE);
  1513.       if (outfile == -1) {
  1514.         sh_close(infile);
  1515.         if (buffer)
  1516.           free(buffer);
  1517.         if (text)
  1518.           free(text);
  1519.         log_it(1, "\n ■ Unable to open output file %s", outfn);
  1520.         return 1;
  1521.       }
  1522.       time(&some);
  1523.       time_msg = localtime(&some);
  1524.       strftime(mh.dateTime, 80, "%a, %d %b %y %H:%M:%S (%Z)", time_msg);
  1525.       if (nhr.fromsys == 32767) {
  1526.         sprintf(_temp_buffer, "From: %s\n", mh.fromUserName);
  1527.       } else
  1528.         if (nhr.fromsys != net_sysnum) {
  1529.         sprintf(_temp_buffer, "From: \"%s #%hd-%hu\" <%s@%s>\n", mh.fromUserName,
  1530.                 nhr.fromuser, nhr.fromsys, POPNAME, DOMAIN);
  1531.       } else {
  1532.         if ((spam) && ((nhr.main_type == main_type_post) || (nhr.main_type == main_type_new_post))) {
  1533.           if (!replyaddr) {
  1534.             if (a == 2)
  1535.               sprintf(_temp_buffer, "From: \"%s\" <user@wwivbbs.org>\n", mh.fromUserName);
  1536.             else if (spamname[0] == 0)
  1537.               sprintf(_temp_buffer, "From: \"%s\" <%s@dont.spam.me.%s>\n",
  1538.                       mh.fromUserName, POPNAME, DOMAIN);
  1539.             else
  1540.               sprintf(_temp_buffer, "From: \"%s\" <%s>\n", mh.fromUserName, spamname);
  1541.           } else {
  1542.             if (a == 2)
  1543.               sprintf(_temp_buffer, "From: \"%s\" <wwivbbs.org>\n", mh.fromUserName);
  1544.             else
  1545.               sprintf(_temp_buffer, "%s\n", mh.fromUserName);
  1546.           }
  1547.         } else {
  1548.           if (usermail) {
  1549.             if (replyaddr)
  1550.               sprintf(_temp_buffer, "From: %s\n", mh.fromUserName);
  1551.             else
  1552.               sprintf(_temp_buffer, "From: \"%s\" <%s@%s>\n",
  1553.                       mh.fromUserName, POPNAME, DOMAIN);
  1554.           } else
  1555.             sprintf(_temp_buffer, "From: <%s@%s>\n", POPNAME, DOMAIN);
  1556.         }
  1557.       }
  1558.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1559.       ++cur_daten;
  1560.       sprintf(_temp_buffer, "Message-ID: <%lx-%s@wwivbbs.org>\n",
  1561.               cur_daten, POPNAME);
  1562.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1563.       if ((nhr.main_type == main_type_email) ||
  1564.           (nhr.main_type == main_type_email_name) ||
  1565.           (nhr.main_type == main_type_ssm)) {
  1566.         if (!tolist) {
  1567.           sprintf(_temp_buffer, "To: %s\n", mh.toUserName);
  1568.           sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1569.         } else {
  1570.           sprintf(fn1, "%sM%s.NET", net_data, alphasubtype);
  1571.           i = 0;
  1572.           if ((fp = fsh_open(fn1, "rt")) != NULL) {
  1573.             while (fgets(_temp_buffer, 80, fp) != NULL) {
  1574.               if (_fstrstr(_temp_buffer, "@")) {
  1575.                 strcpy(mh.toUserName, _temp_buffer);
  1576.                 sprintf(_temp_buffer, "To: %s", mh.toUserName);
  1577.                 if (_temp_buffer[strlen(_temp_buffer) - 1] != '\n')
  1578.                   strcat(_temp_buffer, "\n");
  1579.                 sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1580.                 i = 1;
  1581.               }
  1582.             }
  1583.             if (fp != NULL)
  1584.               fclose(fp);
  1585.           }
  1586.           if (!i) {
  1587.             sh_close(infile);
  1588.             if (buffer)
  1589.               free(buffer);
  1590.             if (text)
  1591.               free(text);
  1592.             log_it(1, "\n ■ Error processing mailing list %s.", alphasubtype);
  1593.             return (1);
  1594.           } else {
  1595.             sprintf(_temp_buffer, "Reply-To: \"%s\" <%s@%s>\n", alphasubtype,
  1596.                     POPNAME, DOMAIN);
  1597.             sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1598.           }
  1599.         }
  1600.       } else {
  1601.         sprintf(_temp_buffer, "Newsgroups: %s\n", groupname);
  1602.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1603.       }
  1604.       sprintf(_temp_buffer, "Subject: %s\n", mh.subject);
  1605.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1606.       sprintf(_temp_buffer, "Date: %s\n", mh.dateTime);
  1607.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1608.       if (nhr.main_type != main_type_email_name) {
  1609.         if (a == 2)
  1610.           sprintf(_temp_buffer, "Path: anonymous!wwivbbs.org\n");
  1611.         else
  1612.           sprintf(_temp_buffer, "Path: %s!%s\n", POPNAME, DOMAIN);
  1613.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1614.         if (a == 2)
  1615.           sprintf(_temp_buffer, "Organization: WWIV BBS\n");
  1616.         else
  1617.           sprintf(_temp_buffer, "Organization: %s * %s\n",
  1618.                   syscfg.systemname, syscfg.systemphone);
  1619.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1620.       }
  1621.       if (tolist) {
  1622.         sprintf(_temp_buffer, "X-Reply-To: \"%s\" <%s@%s>\n",
  1623.                 alphasubtype, POPNAME, DOMAIN);
  1624.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1625.         sprintf(_temp_buffer, "Source: %s Mail List\n", alphasubtype);
  1626.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1627.       }
  1628.       if (((nhr.main_type == main_type_post) || (nhr.main_type == main_type_new_post)) &&
  1629.               (!tolist) && (a != 2)) {
  1630.         if (!replyaddr) {
  1631.           if (*REPLYTO)
  1632.             sprintf(_temp_buffer, "Reply-to: \"%s\" <%s>\n", mh.fromUserName, REPLYTO);
  1633.           else
  1634.             sprintf(_temp_buffer, "Reply-to: \"%s\" <%s@%s>\n",
  1635.                     mh.fromUserName, POPNAME, DOMAIN);
  1636.         } else
  1637.           sprintf(_temp_buffer, "Reply-to: %s\n", mh.fromUserName);
  1638.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1639.       }
  1640.       sprintf(_temp_buffer, "Version: WWIV PPP Project %s\n\n", VERSION);
  1641.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1642.  
  1643.       if ((nhr.main_type != main_type_email) &&
  1644.           (nhr.main_type != main_type_email_name) &&
  1645.           (strncmp(mh.toUserName, "ALL", 3) != 0)) {
  1646.         sprintf(_temp_buffer, "Responding to: %s\n", mh.toUserName);
  1647.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1648.       }
  1649.       for (i = 0; i < strlen(text); i++)
  1650.         if (text[i] == 'π')
  1651.           text[i] = '\n';
  1652.  
  1653.       sh_write(outfile, text, strlen(text));
  1654.       sprintf(tagfn, "%sI%u.TAG", syscfg.datadir, stype);
  1655.       if (exist(tagfn))
  1656.         strcpy(tagfile, tagfn);
  1657.       tagfn[0] = 0;
  1658.       ns = 0;
  1659.       for (i6 = 0; i6 < 99; i6++) {
  1660.         sprintf(tagfn, "%sI%u.T%d", syscfg.datadir, i6);
  1661.         if (exist(tagfn))
  1662.           ns++;
  1663.         else
  1664.           break;
  1665.       }
  1666.       sprintf(tagfn, "%sI%u.T%d", syscfg.datadir, random(ns));
  1667.       if (exist(tagfn))
  1668.         strcpy(tagfile, tagfn);
  1669.       if (tagfile[0] == 0) {
  1670.         sprintf(_temp_buffer, "\n\nOrigin: %s * %s\n\n",
  1671.                 syscfg.systemname, syscfg.systemphone);
  1672.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1673.       } else {
  1674.         if ((fp = fsh_open(tagfile, "rt")) == NULL)
  1675.           log_it(1, "\n ■ Error reading %s.", tagfile);
  1676.         else {
  1677.           sprintf(_temp_buffer, "\n\n");
  1678.           sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1679.           while (fgets(_temp_buffer, 120, fp)) {
  1680.             for (i = 0; ((i < strlen(_temp_buffer)) &&
  1681.                (_temp_buffer[i] != '\r') && (_temp_buffer[i] != '\n')); i++)
  1682.               if ((_temp_buffer[i] < 32) || (_temp_buffer[i] > 126))
  1683.                 _temp_buffer[i] = 32;
  1684.             sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1685.           }
  1686.           if (fp != NULL)
  1687.             fclose(fp);
  1688.           sprintf(_temp_buffer, "\n\n");
  1689.           sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1690.         }
  1691.       }
  1692.       sh_close(outfile);
  1693.     } else {
  1694.       if ((nhr.main_type >= 0x01) && (nhr.main_type <= 0x1b))
  1695.         log_it(1, "\n ■ %s message skipped",
  1696.                main_type[nhr.main_type - 1]);
  1697.       else
  1698.         log_it(1, "\n ■ Unknown Main_type %hd skipped", nhr.main_type);
  1699.     }
  1700.   }
  1701.   sh_close(infile);
  1702.   unlink(fn);
  1703.   if (text)
  1704.     free(text);
  1705.   if (buffer)
  1706.     free(buffer);
  1707.   return (0);
  1708. }
  1709.  
  1710. void get_dir(char *s, int be)
  1711. {
  1712.   strcpy(s, "X:\\");
  1713.   s[0] = 'A' + getdisk();
  1714.   getcurdir(0, s + 3);
  1715.   if (be) {
  1716.     if (s[strlen(s) - 1] != '\\')
  1717.       strcat(s, "\\");
  1718.   }
  1719. }
  1720.  
  1721. void ssm(char *s)
  1722. {
  1723.   int f, i, i1;
  1724.   char s1[161];
  1725.   shortmsgrec sm;
  1726.  
  1727.   sprintf(s1, "%sSMW.DAT", syscfg.datadir);
  1728.   f = sh_open(s1, O_RDWR | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
  1729.   if (f < 0)
  1730.     return;
  1731.   i = (int) (filelength(f) / sizeof(shortmsgrec));
  1732.   i1 = i - 1;
  1733.   if (i1 >= 0) {
  1734.     sh_lseek(f, ((long) (i1)) * sizeof(shortmsgrec), SEEK_SET);
  1735.     sh_read(f, (void *) &sm, sizeof(shortmsgrec));
  1736.     while ((sm.tosys == 0) && (sm.touser == 0) && (i1 > 0)) {
  1737.       --i1;
  1738.       sh_lseek(f, ((long) (i1)) * sizeof(shortmsgrec), SEEK_SET);
  1739.       sh_read(f, (void *) &sm, sizeof(shortmsgrec));
  1740.     }
  1741.     if ((sm.tosys) || (sm.touser))
  1742.       ++i1;
  1743.   } else
  1744.     i1 = 0;
  1745.   sm.tosys = 0;
  1746.   sm.touser = 1;
  1747.   strncpy(sm.message, s, 80);
  1748.   sm.message[80] = 0;
  1749.   sh_lseek(f, ((long) (i1)) * sizeof(shortmsgrec), SEEK_SET);
  1750.   sh_write(f, (void *) &sm, sizeof(shortmsgrec));
  1751.   sh_close(f);
  1752. }
  1753.  
  1754.  
  1755. /*
  1756.   action: 1 = unsubscribed,
  1757.           2 = subscribed,
  1758.           3 = already subscribed,
  1759.           4 = not subscribed
  1760.           5 = invalid list
  1761.           6 = sending MAILLIST.TXT
  1762. */
  1763.  
  1764. void send_note(int action, char *mailname, char *listname)
  1765. {
  1766.   char s[81], fn[MAXPATH];
  1767.   int i;
  1768.   FILE *fp, *rlz;
  1769.  
  1770.   i = 1;
  1771.   sprintf(fn, "%sMQUEUE\\MSG.%d", net_data, i);
  1772.   while (exist(fn))
  1773.     sprintf(fn, "%sMQUEUE\\MSG.%d", net_data, ++i);
  1774.  
  1775.   if ((fp = fsh_open(fn, "wt+")) == NULL) {
  1776.     log_it(1, "\n ! Unable to create %s.", fn);
  1777.     return;
  1778.   }
  1779.   if (action != 5)
  1780.     fprintf(fp, "From: \"%s\" <%s@%s>\n", listname, POPNAME, DOMAIN);
  1781.   else
  1782.     fprintf(fp, "From: <%s@%s>\n", POPNAME, DOMAIN);
  1783.   fprintf(fp, "To: %s\n", mailname);
  1784.   fprintf(fp, "Subject: %s Mailing List\n\n", listname);
  1785.  
  1786.   switch (action) {
  1787.     case 1:
  1788.       sprintf(s, "%s removed from mailing list: %s", mailname, listname);
  1789.       fprintf(fp, "\n%s\n\n", s);
  1790.       log_it(1, "\n ■ %s", s);
  1791.       ssm(s);
  1792.       break;
  1793.     case 2:
  1794.       sprintf(fn, "%sR%s.RLZ", net_data, listname);
  1795.       if (!(exist(fn)))
  1796.         sprintf(fn, "%sGLOBAL.RLZ", net_data);
  1797.       if ((rlz = fsh_open(fn, "rt")) != NULL) {
  1798.         while (fgets(s, 80, rlz))
  1799.           fprintf(fp, s);
  1800.         fprintf(fp, "\n\n");
  1801.         fclose(rlz);
  1802.         sprintf(s, "%s added to mailing list: %s", mailname, listname);
  1803.         log_it(1, "\n%s", s);
  1804.         ssm(s);
  1805.       } else {
  1806.         sprintf(s, "%s added to mailing list: %s", mailname, listname);
  1807.         fprintf(fp, "\n%s\n\n", s);
  1808.         log_it(1, "\n ■ %s", s);
  1809.         ssm(s);
  1810.       }
  1811.       break;
  1812.     case 3:
  1813.       sprintf(fn, "%sR%s.RLZ", net_data, listname);
  1814.       if (!(exist(fn)))
  1815.         sprintf(fn, "%sGLOBAL.RLZ", net_data);
  1816.       if ((rlz = fsh_open(fn, "rt")) != NULL) {
  1817.         while (fgets(s, 80, rlz))
  1818.           fprintf(fp, s);
  1819.         fprintf(fp, "\n\n");
  1820.         fclose(rlz);
  1821.       } else
  1822.         fprintf(fp, "\n%s was already subscribed to mailing list:\n\n   %s\n\n",
  1823.                 mailname, listname);
  1824.       break;
  1825.     case 4:
  1826.       fprintf(fp, "\n%s not subscribed to mailing list:\n\n   %s\n\n",
  1827.               mailname, listname);
  1828.       break;
  1829.     case 5:
  1830.       sprintf(s, "%s requested an invalid mailing list: %s", mailname, listname);
  1831.       fprintf(fp, "\n%s\n\n", s);
  1832.       log_it(1, "\n ■ %s", s);
  1833.       ssm(s);
  1834.       break;
  1835.     case 6:
  1836.       sprintf(fn, "%sMAILLIST.TXT", syscfg.gfilesdir);
  1837.       if ((rlz = fsh_open(fn, "rt")) != NULL) {
  1838.         while (fgets(s, 80, rlz))
  1839.           fprintf(fp, s);
  1840.         fprintf(fp, "\n\n");
  1841.         fclose(rlz);
  1842.         sprintf(s, "Sent MAILLIST.TXT to %s.", mailname);
  1843.       } else
  1844.         sprintf(s, "No mailing list file found.  Notify system operator.");
  1845.       fprintf(fp, "\n%s\n\n", s);
  1846.       log_it(1, "\n ■ %s", s);
  1847.       ssm(s);
  1848.       break;
  1849.   }
  1850.   if (fp != NULL)
  1851.     fclose(fp);
  1852. }
  1853.  
  1854. int copyfile(char *input, char *output)
  1855. {
  1856.   int f1, f2, i;
  1857.   char *b;
  1858.   struct ftime ft;
  1859.  
  1860.   if ((strcmp(input, output) != 0) && (exist(input)) && (!exist(output))) {
  1861.     if ((b = (char *) malloc(16400)) == NULL)
  1862.       return 0;
  1863.     f1 = sh_open1(input, O_RDONLY | O_BINARY);
  1864.     if (!f1) {
  1865.       free(b);
  1866.       b = NULL;
  1867.       return 0;
  1868.     }
  1869.     getftime(f1, &ft);
  1870.  
  1871.     f2 = sh_open(output, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  1872.     if (!f2) {
  1873.       free(b);
  1874.       b = NULL;
  1875.       f1 = sh_close(f1);
  1876.       return 0;
  1877.     }
  1878.     i = read(f1, (void *) b, 16384);
  1879.     while (i > 0) {
  1880.       sh_write(f2, (void *) b, i);
  1881.       i = read(f1, (void *) b, 16384);
  1882.     }
  1883.     f1 = sh_close(f1);
  1884.     setftime(f2, &ft);
  1885.     f2 = sh_close(f2);
  1886.     free(b);
  1887.     b = NULL;
  1888.   }
  1889.   return 1;
  1890. }
  1891.  
  1892.  
  1893. int subscribe(char *fn)
  1894. {
  1895.   char *ss, s[81], s1[81], mailname[81], subtype[81];
  1896.   int done, found, unsubscribe;
  1897.   FILE *fp, *oldfp, *newfp;
  1898.  
  1899.   if ((fp = fsh_open(fn, "rt")) == NULL) {
  1900.     log_it(1, "\n ! Unable to open %s.", fn);
  1901.     return 1;
  1902.   }
  1903.   done = unsubscribe = 0;
  1904.   while ((fgets(s1, 80, fp)) && (!done)) {
  1905.     strcpy(s, &(s1[3]));
  1906.     if (strnicmp(s, "from:", 5) == 0) {
  1907.       ss = strtok(s, ":");
  1908.       if (ss) {
  1909.         ss = strtok(NULL, "\r\n");
  1910.         trimstr1(ss);
  1911.         strcpy(mailname, ss);
  1912.       }
  1913.     }
  1914.     if (strnicmp(s, "subject:", 8) == 0) {
  1915.       done = 1;
  1916.       ss = strtok(s, ":");
  1917.       if (ss) {
  1918.         ss = strtok(NULL, "\r\n");
  1919.         trimstr1(ss);
  1920.         strcpy(s1, ss);
  1921.         if (strnicmp(s1, "subscribe", 9) == 0) {
  1922.           ss = strtok(s1, " ");
  1923.           if (ss) {
  1924.             ss = strtok(NULL, "\r\n");
  1925.             trimstr1(ss);
  1926.             strcpy(subtype, ss);
  1927.           }
  1928.         }
  1929.         if (strnicmp(s1, "unsubscribe", 11) == 0) {
  1930.           unsubscribe = 1;
  1931.           ss = strtok(s1, " ");
  1932.           if (ss) {
  1933.             ss = strtok(NULL, "\r\n");
  1934.             trimstr1(ss);
  1935.             strcpy(subtype, ss);
  1936.           }
  1937.         }
  1938.       }
  1939.       ss = NULL;
  1940.     }
  1941.   }
  1942.   if (fp != NULL)
  1943.     fclose(fp);
  1944.   if ((!*mailname) || (!*subtype)) {
  1945.     log_it(1, "\n ! Invalid subscription request %s.", fn);
  1946.     return 1;
  1947.   }
  1948.   if (strlen(subtype) == 1) {
  1949.     log_it(1, "\n ! %s attempted to write to M%s.NET!", mailname, subtype);
  1950.     return 1;
  1951.   }
  1952.   if (strnicmp(subtype, "LISTS", 10) == 0) {
  1953.     send_note(6, mailname, subtype);
  1954.     return 1;
  1955.   }
  1956.   sprintf(s, "%sM%s.NET", net_data, subtype);
  1957.   if (!exist(s)) {
  1958.     log_it(1, "\n ! %s subscriber list not found.", s);
  1959.     send_note(5, mailname, subtype);
  1960.     return 1;
  1961.   }
  1962.   if ((oldfp = fsh_open(s, "rt")) == NULL) {
  1963.     log_it(1, "\n ! Unable to open input file %s.", s);
  1964.     return 1;
  1965.   }
  1966.   sprintf(s1, "%sM%s.TMP", net_data, subtype);
  1967.   if (exist(s1))
  1968.     unlink(s1);
  1969.   if ((newfp = fsh_open(s1, "wt+")) == NULL) {
  1970.     log_it(1, "\n ! Unable to open output file %s.", s1);
  1971.     return 1;
  1972.   }
  1973.   found = 0;
  1974.   while (fgets(s, 80, oldfp)) {
  1975.     trimstr1(s);
  1976.     if (unsubscribe) {
  1977.       if (stricmp(s, mailname) == 0) {
  1978.         log_it(1, "\n ■ Removing %s from %s mailing list.", mailname, subtype);
  1979.         send_note(1, mailname, subtype);
  1980.         found = 1;
  1981.       } else
  1982.         fprintf(newfp, "%s\n", s);
  1983.     } else {
  1984.       if (stricmp(s, mailname) == 0) {
  1985.         log_it(1, "\n ■ %s already in %s mailing list.", mailname, subtype);
  1986.         send_note(3, mailname, subtype);
  1987.         found = 1;
  1988.       }
  1989.       fprintf(newfp, "%s\n", s);
  1990.     }
  1991.   }
  1992.   if (!found) {
  1993.     if (unsubscribe) {
  1994.       log_it(1, "\n ■ %s was not a member of %s mailing list.", mailname, subtype);
  1995.       send_note(4, mailname, subtype);
  1996.     } else {
  1997.       log_it(1, "\n ■ Adding %s to %s mailing list.", mailname, subtype);
  1998.       fprintf(newfp, "%s\n", mailname);
  1999.       send_note(2, mailname, subtype);
  2000.     }
  2001.   }
  2002.   if (oldfp != NULL)
  2003.     fclose(oldfp);
  2004.   if (newfp != NULL)
  2005.     fclose(newfp);
  2006.   sprintf(s, "%sM%s.TMP", net_data, subtype);
  2007.   sprintf(s1, "%sM%s.NET", net_data, subtype);
  2008.   if (exist(s1))
  2009.     unlink(s1);
  2010.   copyfile(s, s1);
  2011.   return 0;
  2012. }
  2013.  
  2014. int main(int argc, char *argv[])
  2015. {
  2016.   char fn[MAXPATH], newfn[MAXPATH], ext[5], *ss;
  2017.   int f, f1, i;
  2018.   struct ffblk ff;
  2019.   struct date dt;
  2020.   struct time tm;
  2021.  
  2022.   output("\n ■ PPP Import/Export %s", VERSION);
  2023.   if (argc != 7) {
  2024.     log_it(1, "\n ■ EXP <filename> <net_data> <net_sysnum> <POPNAME> <DOMAIN> <net_name>\n\n");
  2025.     if (argc > 1) {
  2026.       log_it(1, "Command line was: ");
  2027.       for (i = 0; i < argc; i++)
  2028.         log_it(1, "%s ", argv[i]);
  2029.       log_it(1, "\n\n");
  2030.     }
  2031.     return (1);
  2032.   }
  2033.   strcpy(net_data, argv[2]);
  2034.   f = sh_open1("CONFIG.DAT", O_RDONLY | O_BINARY);
  2035.   if (f < 0) {
  2036.     log_it(1, "Could not open CONFIG.DAT!\n\n");
  2037.     return 1;
  2038.   }
  2039.   sh_read(f, (void *) &syscfg, sizeof(configrec));
  2040.   sh_close(f);
  2041.  
  2042.   detect_multitask();
  2043.  
  2044.   get_dir(maindir, 1);
  2045.   sprintf(fn, "%s%s", net_data, argv[1]);
  2046.   strcpy(net_name, argv[6]);
  2047.   strcpy(POPNAME, argv[4]);
  2048.   strcpy(DOMAIN, argv[5]);
  2049.   net_sysnum = atoi(argv[3]);
  2050.   tagfile[0] = 0;
  2051.   spam = 0;
  2052.  
  2053.   ss = getenv("WWIV_INSTANCE");
  2054.   if (ss) {
  2055.     instance = atoi(ss);
  2056.     if (instance >= 1000) {
  2057.       log_it(1, "\n ■ WWIV_INSTANCE set to %hd.  Can only be 1..999!",
  2058.              instance);
  2059.       instance = 1;
  2060.     }
  2061.   } else
  2062.     instance = 1;
  2063.  
  2064.   parse_net_ini();
  2065.   gettime(&tm);
  2066.   getdate(&dt);
  2067.   cur_daten = dostounix(&dt, &tm);
  2068.  
  2069.   strupr(postmaster);
  2070.   export(fn);
  2071.  
  2072.   sprintf(fn, "%sSPOOL\\UNK*.*", net_data);
  2073.   f1 = findfirst(fn, &ff, 0);
  2074.   while (f1 == 0) {
  2075.     sprintf(fn, "%sSPOOL\\%s", net_data, ff.ff_name);
  2076.     if (!import(fn)) {
  2077.       unlink(fn);
  2078.     }
  2079.     f1 = findnext(&ff);
  2080.   }
  2081.  
  2082.   sprintf(fn, "%sINBOUND\\SUB*.*", net_data);
  2083.   f1 = findfirst(fn, &ff, 0);
  2084.   while (f1 == 0) {
  2085.     sprintf(fn, "%sINBOUND\\%s", net_data, ff.ff_name);
  2086.     fnsplit(fn, NULL, NULL, NULL, ext);
  2087.     if (strnicmp(ext, ".BAD", 4) == 0)
  2088.       log_it(1, "\n ■ Unprocessed subscriber request %s...", ff.ff_name);
  2089.     else {
  2090.       log_it(1, "\n ■ Processing subscriber request %s...", ff.ff_name);
  2091.       if (!subscribe(fn))
  2092.         unlink(fn);
  2093.       else {
  2094.         name_bad(newfn);
  2095.         rename(fn, newfn);
  2096.       }
  2097.     }
  2098.     f1 = findnext(&ff);
  2099.   }
  2100.  
  2101.   if (maillist != NULL)
  2102.     free(maillist);
  2103.  
  2104.   return 0;
  2105. }
  2106.