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