home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / PPPBCKP / SRC / SRC15B76.ZIP / EXP.CPP < prev    next >
Text File  |  1997-12-06  |  51KB  |  1,785 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 <malloc.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, num_users, use_alias, usermail, instance, spam;
  53. unsigned curuser;
  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 num_to_name(char *where, int whichuser, int alias)
  347. {
  348.   int userfile, num_users, found;
  349.   userrec ur;
  350.   long pos;
  351.   char fn[MAXPATH];
  352.  
  353.   found = 0;
  354.   sprintf(fn, "%sUSER.LST", syscfg.datadir);
  355.   userfile = sh_open1(fn, O_RDONLY | O_BINARY);
  356.   if (userfile < 0) {
  357.     output("\n ■ Cannot open %s.", fn);
  358.     return (found);
  359.   }
  360.   num_users = ((int) (filelength(userfile) / sizeof(userrec)));
  361.  
  362.   if (whichuser > num_users) {
  363.     output("\n ■ User #%d out of range.", whichuser);
  364.     return (found);
  365.   }
  366.   pos = ((long) sizeof(userrec) * ((long) whichuser));
  367.   lseek(userfile, pos, SEEK_SET);
  368.   sh_read(userfile, &ur, sizeof(userrec));
  369.   if (ur.realname[0] == 0)
  370.     output("\n ■ User #%d has blank real name field!", whichuser);
  371.   else {
  372.     if (ur.inact == inact_deleted)
  373.       output("\n ■ User #%d is marked as deleted!", whichuser);
  374.     else {
  375.       if (!alias)
  376.         strcpy(where, ur.realname);
  377.       else {
  378.         strcpy(where, ur.name);
  379.         strlwr(where);
  380.       }
  381.       found = 1;
  382.     }
  383.   }
  384.   sh_close(userfile);
  385.   return (found);
  386. }
  387.  
  388.  
  389. void parse_net_ini(void)
  390. {
  391.   char s[MAXPATH], origline[121], line[121], *ss, inlist = 0;
  392.   FILE *fp;
  393.   long fptr;
  394.  
  395.   defuser = 1;
  396.   use_alias = 1;
  397.   usermail = 1;
  398.   nlists = 0;
  399.   maillist = NULL;
  400.   *REPLYTO = 0;
  401.   sprintf(s, "%sNET.INI", maindir);
  402.   if ((fp = fsh_open(s, "rt")) == NULL) {
  403.     output("\n ■ Unable to open %s.", s);
  404.     return;
  405.   }
  406.   while (fgets(line, 80, fp)) {
  407.     ss = NULL;
  408.     strcpy(origline, line);
  409.     stripspace(line);
  410.     if ((line[0] == ';') || (line[0] == '\n') || (line[0] == 0))
  411.       continue;
  412.     if (strnicmp(line, "[MAILLIST]", 10) == 0) {
  413.       fptr = ftell(fp);
  414.       while ((fgets(line, 80, fp)) && (line[0] != '[')) {
  415.         if ((line[0] != '[') && (line[0] != ';') && (line[0] != 0))
  416.           ++nlists;
  417.       }
  418.       fseek(fp, fptr, SEEK_SET);
  419.       maillist = (MAILLISTREC *) malloc((nlists + 1) * sizeof(MAILLISTREC));
  420.       if (maillist == NULL)
  421.         output("\n ■ Not enough memory to process %d mailing lists.", nlists);
  422.       else
  423.         inlist = 1;
  424.       nlists = 0;
  425.       continue;
  426.     } else if (line[0] == '[') {
  427.       inlist = 0;
  428.       continue;
  429.     }
  430.     if (inlist) {
  431.       if ((line[0] != ';') && (line[0] != 0)) {
  432.         ss = strtok(line, "\"");
  433.         trimstr1(ss);
  434.         if (*ss) {
  435.           ss = strtok(NULL, "\"");
  436.           if (*ss) {
  437.             strncpy(maillist[nlists].opttext, ss, 29);
  438.             maillist[nlists].opttext[30] = '\0';
  439.           } else
  440.             maillist[nlists].opttext[0] = '\0';
  441.         }
  442.         ss = strtok(line, "*\n");
  443.         trimstr1(ss);
  444.         strcpy(maillist[nlists].ownername, ss);
  445.         ss = strtok(NULL, "\"\n");
  446.         trimstr1(ss);
  447.         if (*ss) {
  448.           strlwr(maillist[nlists].ownername);
  449.           strcpy(maillist[nlists++].subtype, ss);
  450.         } else
  451.           output("\n ■ Missing *subtype in maillist for %s.",
  452.                  maillist[nlists].ownername);
  453.       }
  454.       continue;
  455.     }
  456.     if (strnicmp(line, "POSTMASTER", 10) == 0) {
  457.       ss = strtok(line, "=");
  458.       if (ss) {
  459.         ss = strtok(NULL, "\n");
  460.         if (ss)
  461.           defuser = atoi(ss);
  462.       }
  463.       continue;
  464.     }
  465.     if (strnicmp(line, "SPAMCONTROL", 11) == 0) {
  466.       ss = strtok(line, "=");
  467.       if (ss) {
  468.         ss = strtok(NULL, "\n");
  469.         if ((ss[0] == 'y') || (ss[0] == 'Y'))
  470.           spam = 1;
  471.       }
  472.       continue;
  473.     }
  474.     if (strnicmp(line, "USERMAIL", 8) == 0) {
  475.       ss = strtok(line, "=");
  476.       if (ss) {
  477.         ss = strtok(NULL, "\n");
  478.         if ((ss[0] == 'n') || (ss[0] == 'N'))
  479.           usermail = 0;
  480.       }
  481.       continue;
  482.     }
  483.     if (strnicmp(line, "SPAMADDRESS", 9) == 0) {
  484.       ss = strtok(line, "=");
  485.       if (ss) {
  486.         ss = strtok(NULL, "\n");
  487.         trimstr1(ss);
  488.         strcpy(spamname, ss);
  489.         if (stricmp(spamname, "DEFAULT") == 0)
  490.           strcpy(spamname, "WWIV_BBS@nospam.net");
  491.       }
  492.       continue;
  493.     }
  494.     if (strnicmp(line, "REPLYTO", 7) == 0) {
  495.       ss = strtok(origline, "=");
  496.       if (ss) {
  497.         ss = strtok(NULL, "\n");
  498.         trimstr1(ss);
  499.         strcpy(REPLYTO, ss);
  500.       }
  501.       continue;
  502.     }
  503.     if (strnicmp(line, "SIGNATURE", 9) == 0) {
  504.       ss = strtok(line, "=");
  505.       if (ss) {
  506.         ss = strtok(NULL, "\n");
  507.         trimstr1(ss);
  508.         strcpy(tagfile, ss);
  509.         if (!exist(tagfile)) {
  510.           output("\n ■ Default signature file %s not found!", tagfile);
  511.           tagfile[0] = 0;
  512.         }
  513.       }
  514.       continue;
  515.     }
  516.     if (strnicmp(line, "REALNAME", 8) == 0) {
  517.       ss = strtok(line, "=");
  518.       if (ss) {
  519.         ss = strtok(NULL, "\n");
  520.         if ((ss[0] == 'y') || (ss[0] == 'Y'))
  521.           use_alias = 0;
  522.       }
  523.     }
  524.   }
  525.   num_to_name(postmaster, defuser, 1);
  526.   if (fp != NULL)
  527.     fclose(fp);
  528.   return;
  529. }
  530.  
  531. unsigned char *strrep(char *str, char old, char New)
  532. {
  533.   int i;
  534.  
  535.   for (i = 0; str[i]; i++)
  536.     if (str[i] == old)
  537.       str[i] = New;
  538.   return (str);
  539. }
  540.  
  541.  
  542. unsigned int name_to_num(char *name)
  543. {
  544.   int userfile, usernum;
  545.   userrec ur;
  546.   long pos;
  547.   char fn[MAXPATH], ur_name[60], ur_realname[60];
  548.  
  549.   sprintf(fn, "%sM%s.NET", net_data, name);
  550.   if (exist(fn)) {
  551.     output("\n ■ Matched \"%s\" mailing list.", name);
  552.     strcpy(alphasubtype, name);
  553.     return (unsigned) (65535L);
  554.   }
  555.   sprintf(fn, "%sUSER.LST", syscfg.datadir);
  556.   userfile = sh_open1(fn, O_RDONLY | O_BINARY);
  557.   if (userfile < 0) {
  558.     output("\n ■ Cannot open %s", fn);
  559.     return (0);
  560.   } else
  561.     output("\n ■ Searching for user \"%s\"...", name);
  562.   num_users = ((int) (filelength(userfile) / sizeof(userrec)));
  563.  
  564.   for (usernum = 1; usernum < num_users; usernum++) {
  565.     pos = ((long) sizeof(userrec) * ((long) usernum));
  566.     lseek(userfile, pos, SEEK_SET);
  567.     sh_read(userfile, &ur, sizeof(userrec));
  568.     strcpy(ur_realname, ur.realname);
  569.     strrep(ur_realname, ' ', '_');
  570.     strcpy(ur_name, ur.name);
  571.     strrep(ur_name, ' ', '_');
  572.     if ((strcmpi(ur.realname, name) == 0) || (strcmpi(ur_realname, name) == 0) ||
  573.         (strcmpi(ur.name, name) == 0) || (strcmpi(ur_name, name) == 0)) {
  574.       if (ur.inact == inact_deleted) {
  575.         output(" user #%d is deleted account.", usernum);
  576.         usernum = 0;
  577.         break;
  578.       } else {
  579.         output(" matched to user #%d.", usernum);
  580.         break;
  581.       }
  582.     }
  583.   }
  584.   userfile = sh_close(userfile);
  585.  
  586.   if (usernum >= num_users) {
  587.     output("... no match found.");
  588.     return (0);
  589.   }
  590.   return (usernum);
  591. }
  592.  
  593. char *find_name(char *name)
  594. {
  595.   char *ss, *ss1;
  596.  
  597.   curuser = 0;
  598.   ss1 = NULL;
  599.   if ((ss = strchr(name, '(')) != NULL) {
  600.     ss1 = strtok(name, "(");
  601.     ss1 = strtok(NULL, ")");
  602.   } else if ((ss = strchr(name, '\"')) != NULL) {
  603.     ss1 = strtok(ss, "\"");
  604.   } else if ((ss = strchr(name, '<')) != NULL) {
  605.     ss1 = strtok(name, "<");
  606.   }
  607.   if (*ss1) {
  608.     trimstr1(ss1);
  609.     curuser = name_to_num(ss1);
  610.   }
  611.   if (curuser == 0)
  612.     return ('\0');
  613.   else if (curuser == ((unsigned) 65535L))
  614.     return (alphasubtype);
  615.   else
  616.     return (ss1);
  617. }
  618.  
  619. void name_packet(char *pktname)
  620. {
  621.   int ok;
  622.   struct stat info;
  623.   unsigned i;
  624.  
  625.   ok = 0;
  626.   for (i = 0; ((i < 1000) && (!ok)); i++) {
  627.     sprintf(pktname, "%sP0-%u.%3.3hu", net_data, i, instance);
  628.     if (stat(pktname, &info) == -1)
  629.       ok = 1;
  630.   }
  631. }
  632.  
  633. char *stristr(char *String, char *Pattern)
  634. {
  635.   char *pptr, *sptr, *start;
  636.   unsigned int slen, plen;
  637.  
  638.   for (start = String, pptr = Pattern, slen = strlen(String),
  639.        plen = strlen(Pattern); slen >= plen; start++, slen--) {
  640.     while (toupper(*start) != toupper(*Pattern)) {
  641.       start++;
  642.       slen--;
  643.       if (slen < plen)
  644.         return (NULL);
  645.     }
  646.     sptr = start;
  647.     pptr = Pattern;
  648.     while (toupper(*sptr) == toupper(*pptr)) {
  649.       sptr++;
  650.       pptr++;
  651.       if ('\0' == *pptr)
  652.         return (start);
  653.     }
  654.   }
  655.   return (NULL);
  656. }
  657.  
  658. #define FROM_RETURN 0x01
  659. #define FROM_FROM   0x02
  660. #define FROM_REPLY  0x04
  661.  
  662. int import(char *fn)
  663. {
  664.   char s[513], s1[121], pktname[MAXPATH], msgdate[61], *ss, *p, *id, *name;
  665.   char alphatype[21], recvdate[81];
  666.   int i, f, from, match, subj, intext, done, tolist;
  667.   long textlen, reallen;
  668.   struct msghdr mh;
  669.   net_header_rec nh;
  670.   FILE *fp;
  671.  
  672.   tolist = 0;
  673.   intext = 0;
  674.   f = sh_open1(fn, O_RDONLY | O_BINARY);
  675.   if (f < 0)
  676.     return (1);
  677.   textlen = filelength(f);
  678.   if (textlen > 32767L) {
  679.     output("\n ■ Skipping %s - greater than 32K.", fn);
  680.     return (1);
  681.   }
  682.   p = (char *) malloc((int) (textlen + 1));
  683.   if (p == NULL) {
  684.     output("\n ■ Unable to allocate %ld bytes.", textlen);
  685.     return (1);
  686.   }
  687.   sh_read(f, (void *) p, (int) textlen);
  688.   sh_close(f);
  689.  
  690.   nh.tosys = net_sysnum;
  691.   nh.fromsys = 32767;
  692.   nh.fromuser = 0;
  693.   nh.touser = defuser;
  694.   nh.main_type = main_type_email;
  695.   nh.minor_type = 0;
  696.   nh.list_len = 0;
  697.   ++cur_daten;
  698.   nh.daten = cur_daten;
  699.   strncpy(msgdate, ctime(&(time_t) nh.daten), 24);
  700.   msgdate[24] = '\0';
  701.   sprintf(recvdate, "0RReceived: PPP Project %s on %s\r\n", VERSION, msgdate);
  702.   strcat(msgdate, "\r\n");
  703.   nh.method = 0;
  704.  
  705.   strcpy(mh.fromUserName, "Unknown");
  706.   strcpy(mh.toUserName, "Unknown");
  707.   strcpy(mh.subject, "None");
  708.  
  709.   if ((fp = fsh_open(fn, "rb")) == NULL) {
  710.     free(p);
  711.     return (1);
  712.   }
  713.   match = subj = done = 0;
  714.   while ((fgets(s, 254, fp)) && !done) {
  715.     if (s[0] == 4) {
  716.       ss = strtok(s, "R");
  717.       ss = strtok(NULL, "\r\n");
  718.       if (ss == NULL)
  719.         s[0] = 0;
  720.       else
  721.         strcpy(s, ss);
  722.     } else
  723.       intext = 1;
  724.     if (!intext) {
  725.       if (strncmpi(s, "from:", 5) == 0)
  726.         from = FROM_FROM;
  727.       else
  728.         if (strncmpi(s, "return-path:", 12) == 0)
  729.         from = FROM_RETURN;
  730.       else
  731.         if (strncmpi(s, "sender:", 7) == 0)
  732.         from = FROM_RETURN;
  733.       else
  734.         if (strncmpi(s, "x-sender:", 9) == 0)
  735.         from = FROM_RETURN;
  736.       else
  737.         if (strncmpi(s, "x-to:", 5) == 0)
  738.         from = FROM_RETURN;
  739.       else
  740.         if (strncmpi(s, "reply-to:", 9) == 0)
  741.         from = FROM_REPLY;
  742.       else
  743.         if (strncmpi(s, "x-reply-to:", 11) == 0)
  744.         from = FROM_REPLY;
  745.       else
  746.         from = 0;
  747.       if (from) {
  748.         ss = strtok(s, ": ");
  749.         ss = strtok(NULL, "\r\n");
  750.         trimstr1(ss);
  751.         if ((from & (FROM_RETURN | FROM_REPLY)) && (nh.main_type == main_type_email)) {
  752.           strcpy(s1, ss);
  753.           strlwr(s1);
  754.           for (i = 0; (i < nlists) && (nh.main_type == main_type_email); i++) {
  755.             if (stristr(s1, maillist[i].ownername) != NULL) {
  756.               if (atoi(maillist[i].subtype)) {
  757.                 nh.main_type = main_type_pre_post;
  758.                 nh.minor_type = atoi(maillist[i].subtype);
  759.               } else {
  760.                 nh.main_type = main_type_new_post;
  761.                 nh.minor_type = 0;
  762.                 strcpy(alphatype, maillist[i].subtype);
  763.               }
  764.               strcpy(alphasubtype, maillist[i].subtype);
  765.               nh.touser = 0;
  766.               from = 0;
  767.             }
  768.           }
  769.         }
  770.         if ((from > match) && ((nh.main_type == main_type_email) || (from == FROM_FROM))) {
  771.           match = from;
  772.           if (strcspn(ss, "<") != strlen(ss)) {
  773.             if ((strcspn(ss, " ")) < (strcspn(ss, "<"))) {
  774.               name = strtok(ss, "<");
  775.               trimstr1(name);
  776.               id = strtok(NULL, ">");
  777.               trimstr1(id);
  778.               sprintf(mh.fromUserName, "%s <%s>", name, id);
  779.             } else {
  780.               strncpy(mh.fromUserName, ss, 205);
  781.               trimstr1(mh.fromUserName);
  782.               if (strcspn(ss, " ") != strlen(ss))
  783.                 output("\nName is *after* host in \"%s\"", name);
  784.             }
  785.           } else
  786.             strncpy(mh.fromUserName, ss, 205);
  787.           mh.fromUserName[190] = 0;
  788.           strcat(mh.fromUserName, "\r\n");
  789.         }
  790.       } else if ((strncmpi(s, "subject:", 8) == 0) && (!subj)) {
  791.         ss = strtok(s, ": ");
  792.         ss = strtok(NULL, "\r\n");
  793.         trimstr1(ss);
  794.         strncpy(mh.subject, ss, 81);
  795.         mh.subject[72] = 0;
  796.         subj = 1;
  797.       } else if (strncmpi(s, "date:", 5) == 0) {
  798.         ss = strtok(s, ": ");
  799.         ss = strtok(NULL, "\r\n");
  800.         trimstr1(ss);
  801.         strncpy(msgdate, ss, 58);
  802.         msgdate[58] = '\0';
  803.         strcat(msgdate, "\r\n");
  804.       } else if ((strncmpi(s, "to:", 3) == 0) || (strncmpi(s, "cc:", 3) == 0)) {
  805.         ss = strtok(s, ":");
  806.         ss = strtok(NULL, "\r\n");
  807.         strncpy(mh.toUserName, ss, 81);
  808.         mh.toUserName[80] = 0;
  809.         curuser = 0;
  810.         trimstr1(mh.toUserName);
  811.         if ((_fstrchr(mh.toUserName, ' ') != NULL) || (_fstrchr(mh.toUserName, '\"') != NULL) ||
  812.             (_fstrchr(mh.toUserName, '(') != NULL))
  813.           find_name(mh.toUserName);
  814.         else
  815.           mh.toUserName[0] = 0;
  816.         if ((stristr(mh.toUserName, "Multiple recipients of list") != NULL) && (curuser != (unsigned) 65535L)) {
  817.           for (i = 0; (i < nlists) && (nh.main_type == main_type_email); i++) {
  818.             if (stristr(mh.toUserName, maillist[i].opttext) != NULL) {
  819.               if (atoi(maillist[i].subtype)) {
  820.                 nh.main_type = main_type_pre_post;
  821.                 nh.minor_type = atoi(maillist[i].subtype);
  822.               } else {
  823.                 nh.main_type = main_type_new_post;
  824.                 nh.minor_type = 0;
  825.                 strcpy(alphatype, maillist[i].subtype);
  826.               }
  827.               strcpy(alphasubtype, maillist[i].subtype);
  828.               nh.touser = 0;
  829.             }
  830.           }
  831.         }
  832.         if ((curuser == (unsigned) 65535L) && (nh.main_type == main_type_email)) {
  833.           strcpy(alphatype, alphasubtype);
  834.           nh.main_type = main_type_new_post;
  835.           nh.minor_type = 0;
  836.           nh.touser = 0;
  837.           tolist = 1;
  838.         } else
  839.           if ((mh.toUserName[0] == 0) || (curuser == 0)) {
  840.           nh.touser = defuser;
  841.           strcpy(mh.toUserName, postmaster);
  842.         } else {
  843.           nh.touser = curuser;
  844.         }
  845.       } else if (strncmpi(s, "apparently-to:", 14) == 0) {
  846.         ss = strtok(s, ": ");
  847.         ss = strtok(NULL, "\r\n");
  848.         strncpy(mh.toUserName, ss, 81);
  849.         mh.toUserName[80] = 0;
  850.         curuser = 0;
  851.         trimstr1(mh.toUserName);
  852.         if (_fstrstr(mh.toUserName, " "))
  853.           find_name(mh.toUserName);
  854.         else
  855.           mh.toUserName[0] = 0;
  856.         if ((curuser == (unsigned) 65535L) && (nh.main_type == main_type_email)) {
  857.           strcpy(alphatype, alphasubtype);
  858.           nh.main_type = main_type_new_post;
  859.           nh.minor_type = 0;
  860.           nh.touser = 0;
  861.           tolist = 1;
  862.         } else if ((mh.toUserName[0] == 0) || (curuser == 0)) {
  863.           nh.touser = defuser;
  864.           strcpy(mh.toUserName, postmaster);
  865.         } else
  866.           nh.touser = curuser;
  867.       }
  868.     } else
  869.       done = 1;
  870.   }
  871.   if (fp != NULL)
  872.     fclose(fp);
  873.   output("\n ■ From    : %s", strlwr(mh.fromUserName));
  874.   if ((nh.main_type == main_type_pre_post) ||
  875.       (nh.main_type == main_type_new_post))
  876.     output(" ■ Post to : Sub %s", alphasubtype);
  877.   else
  878.     output(" ■ Sent to : %s #%hd", strupr(mh.toUserName), nh.touser);
  879.   output("\n ■ Subject : %s", mh.subject);
  880.   name_packet(pktname);
  881.   if ((fp = fsh_open(pktname, "wb")) == NULL) {
  882.     output("\n ■ Unable to create packet %s", pktname);
  883.     free(p);
  884.     return (1);
  885.   }
  886.   nh.length = textlen + strlen(mh.fromUserName) + strlen(mh.subject)
  887.       + strlen(msgdate) + strlen(recvdate) + 1;
  888.   if (nh.main_type == main_type_new_post)
  889.     nh.length += strlen(alphatype) + 1;
  890.   while (tolist >= 0) {
  891.     fsh_write(&nh, sizeof(net_header_rec), 1, fp);
  892.     if (nh.main_type == main_type_new_post)
  893.       fsh_write(alphatype, sizeof(char), strlen(alphatype) +1, fp);
  894.     fsh_write(mh.subject, sizeof(char), strlen(mh.subject) +1, fp);
  895.     fsh_write(mh.fromUserName, sizeof(char), strlen(mh.fromUserName), fp);
  896.     fsh_write(msgdate, sizeof(char), strlen(msgdate), fp);
  897.     fsh_write(recvdate, sizeof(char), strlen(recvdate), fp);
  898.     reallen = fsh_write(p, sizeof(char), (int) textlen, fp);
  899.     if (reallen != textlen)
  900.       output("\n ■ Expected %ld bytes, wrote %ld bytes.", textlen, reallen);
  901.     nh.tosys = 32767;
  902.     --tolist;
  903.   }
  904.   if (fp != NULL)
  905.     fclose(fp);
  906.   free(p);
  907.   return (0);
  908. }
  909.  
  910.  
  911. char *stripcolors(char *str)
  912. {
  913.   char *obuf, *nbuf;
  914.  
  915.   if (str) {
  916.     for (obuf = str, nbuf = str; *obuf; ++obuf) {
  917.       if (*obuf == 3)
  918.         ++obuf;
  919.       else
  920.         if (((*obuf < 32) && (*obuf != 9)) || (*obuf > 126))
  921.         continue;
  922.       else
  923.         *nbuf++ = *obuf;
  924.     }
  925.     *nbuf = NULL;
  926.   }
  927.   return (str);
  928. }
  929.  
  930. void properize(char *s)
  931. {
  932.   int i;
  933.  
  934.   for (i = 0; i < strlen(s); i++) {
  935.     if ((i == 0) || ((i > 0) && ((s[i - 1] == ' ') || (s[i - 1] == '.') ||
  936.            ((s[i - 1] == 'c') && (s[i - 2] == 'M')) || ((s[i - 1] == 'c') &&
  937.              (s[i - 2] == 'a') && (s[i - 3] == 'M')) || (s[i - 1] == '-') ||
  938.          (s[i - 1] == '_') || ((s[i - 1] == '\'') && (s[i - 2] == 'O'))))) {
  939.       s[i] = toupper(s[i]);
  940.     } else
  941.       s[i] = tolower(s[i]);
  942.   }
  943. }
  944.  
  945.  
  946.  
  947. int export(char *fn)
  948. {
  949.   char fn1[121], tagfn[121], groupname[81], outfn[121], _temp_buffer[256];
  950.   char *ss, *buffer, *text, alphatype[21], hold[21], tempoutfn[21];
  951.   unsigned stype, ttype;
  952.   int infile, outfile, inloc, outloc, term, ok, i, j, ns, i6, tolist;
  953.   net_header_rec nhr;
  954.   struct msghdr mh;
  955.   struct tm *time_msg;
  956.   FILE *fp;
  957.   time_t some;
  958.   char *main_type[] =
  959.   {
  960.     "Network Update", "email by usernum", "post from sub host", "file",
  961.     "post to sub host", "external message", "email by name",
  962.     "NetEdit message", "SUBS.LST", "Extra Data", "BBSLIST from GC",
  963.     "CONNECT from GC", "Unused_1", "Info from GC", "SSM", "Sub Add Request",
  964.     "Sub Drop Request", "Sub Add Response", "Sub Drop Response", "Sub Info",
  965.     "Unused 1", "Unused 2", "Unused 3", "Unused 4", "Unused 5", "new post",
  966.     "new external"
  967.   };
  968.  
  969.   if ((infile = sh_open1(fn, O_RDONLY | O_BINARY)) == -1)
  970.     return 1;
  971.  
  972.   if ((buffer = (char *) malloc(32 * 1024)) == NULL) {
  973.     sh_close(infile);
  974.     output("\n ■ Out of memory allocating input buffer!");
  975.     return 1;
  976.   }
  977.   if ((text = (char *) malloc(32 * 1024)) == NULL) {
  978.     output("\n ■ Out of memory allocating output buffer!");
  979.     sh_close(infile);
  980.     if (buffer != NULL)
  981.       free(buffer);
  982.     return 1;
  983.   }
  984.   while (sh_read(infile, &nhr, sizeof(nhr))) {
  985.     sh_read(infile, buffer, (int) nhr.length);
  986.     if (nhr.tosys != 32767) {
  987.       output("\n ■ Non-Internet system routing via @32767... aborting export.");
  988.       sh_close(infile);
  989.       if (text)
  990.         free(text);
  991.       if (buffer)
  992.         free(buffer);
  993.       return (1);
  994.     }
  995.     tolist = 0;
  996.     if (nhr.main_type == main_type_pre_post)
  997.       nhr.main_type = main_type_post;
  998.     if ((nhr.main_type == main_type_post) ||
  999.         (nhr.main_type == main_type_new_post) ||
  1000.         (nhr.main_type == main_type_email_name) ||
  1001.         (nhr.main_type == main_type_ssm)) {
  1002.       inloc = 0;
  1003.       sprintf(hold, "%hu", nhr.minor_type);
  1004.       if ((nhr.main_type == main_type_email_name) ||
  1005.           (nhr.main_type == main_type_ssm) ||
  1006.           (nhr.main_type == main_type_new_post)) {
  1007.         stype = nhr.minor_type;
  1008.         inloc = strlen(buffer) + 1;
  1009.         if ((nhr.main_type == main_type_new_post) || ((nhr.fromsys != net_sysnum) &&
  1010.                                                   (nhr.fromsys != 32767))) {
  1011.           strcpy(alphasubtype, buffer);
  1012.           strcpy(hold, alphasubtype);
  1013.         } else
  1014.           strcpy(mh.toUserName, buffer);
  1015. /*
  1016.         if ((nhr.fromsys != net_sysnum) && (nhr.fromsys != 32767)) {
  1017.           output("\n ■ Gate from #%hd@%hd to %s not yet supported",
  1018.                  nhr.fromuser, nhr.fromsys, mh.toUserName);
  1019.           continue;
  1020.         }
  1021. */
  1022.       } else
  1023.         if (nhr.main_type == main_type_post) {
  1024.         stype = nhr.minor_type;
  1025.       } else {
  1026.         stype = atoi(&buffer[inloc]);
  1027.         sprintf(_temp_buffer, "%u", stype);
  1028.         inloc += strlen(_temp_buffer) + 1;
  1029.       }
  1030.  
  1031.       strncpy(mh.subject, &buffer[inloc], sizeof(mh.subject));
  1032.       stripcolors(mh.subject);
  1033.       inloc += strlen(&buffer[inloc]) + 1;
  1034.  
  1035.       for (term = inloc; buffer[term] != '\r'; term++);
  1036.       buffer[term] = '\0';
  1037.  
  1038.       if ((nhr.fromsys == net_sysnum) && (nhr.fromuser)) {
  1039.         if ((nhr.main_type != main_type_post) &&
  1040.             (nhr.main_type != main_type_new_post)) {
  1041.           if (!num_to_name(mh.fromUserName, nhr.fromuser, use_alias)) {
  1042.             output("\n ■ No match for user #%hd... skipping message!",
  1043.                    nhr.fromuser);
  1044.             continue;
  1045.           }
  1046.         } else {
  1047.           strncpy(mh.fromUserName, &buffer[inloc], sizeof(mh.fromUserName));
  1048.           stripcolors(mh.fromUserName);
  1049.           strtok(mh.fromUserName, "#");
  1050.           trimstr1(mh.fromUserName);
  1051.         }
  1052.       } else {
  1053.         strncpy(mh.fromUserName, &buffer[inloc], sizeof(mh.fromUserName));
  1054.         stripcolors(mh.fromUserName);
  1055.         strtok(mh.fromUserName, "#");
  1056.         trimstr1(mh.fromUserName);
  1057.         if ((nhr.main_type == main_type_post) &&
  1058.             (nhr.main_type == main_type_new_post)) {
  1059.           sprintf(_temp_buffer, " #%hd @%hu", nhr.fromuser, nhr.fromsys);
  1060.           strcat(mh.fromUserName, _temp_buffer);
  1061.           output("\nFrom: %s\n", mh.fromUserName);
  1062.         }
  1063.       }
  1064.  
  1065.       inloc = term + 2;
  1066.  
  1067.       while (buffer[inloc] != '\n')
  1068.         inloc++;
  1069.       inloc++;
  1070.  
  1071.       if (strnicmp(&buffer[inloc], "RE: ", 4) == 0) {
  1072.         for (term = inloc; buffer[term] != '\r'; term++);
  1073.         buffer[term] = '\0';
  1074.         strncpy(mh.subject, &buffer[inloc + 4], sizeof(mh.subject));
  1075.         if (strnicmp(mh.subject, "RE: ", 4) != 0) {
  1076.           strcpy(_temp_buffer, "Re: ");
  1077.           strcat(_temp_buffer, mh.subject);
  1078.         }
  1079.         strcpy(mh.subject, _temp_buffer);
  1080.         inloc = term + 2;
  1081.       }
  1082.       if ((strncmp(&buffer[inloc], "BY: ", 4) == 0) ||
  1083.           (strncmp(&buffer[inloc], "TO: ", 4) == 0)) {
  1084.         for (term = inloc; buffer[term] != '\r'; term++);
  1085.         buffer[term] = '\0';
  1086.         strncpy(mh.toUserName, &buffer[inloc + 4], sizeof(mh.toUserName));
  1087.         stripcolors(mh.toUserName);
  1088.         if (strcspn(mh.toUserName, "<") != strlen(mh.toUserName)) {
  1089.           if ((_fstrstr(mh.toUserName, "\"") == 0) && (_fstrstr(mh.toUserName, "(") == 0)) {
  1090.             ss = strtok(mh.toUserName, "<");
  1091.             ss = strtok(NULL, ">");
  1092.             strcpy(mh.toUserName, ss);
  1093.           }
  1094.         }
  1095.         inloc = term + 2;
  1096.       } else {
  1097.         if (nhr.main_type != main_type_email_name) {
  1098.           strcpy(mh.toUserName, "ALL");
  1099.         }
  1100.       }
  1101.       outloc = 0;
  1102.       do {
  1103.         if (buffer[inloc] == 2) {
  1104.           i = inloc + 1;
  1105.           for (j = 1; j < 255; j++) {
  1106.             if (buffer[i] == 'π')
  1107.               buffer[i] = '\r';
  1108.             if ((buffer[i] == '\r') || (i > nhr.length))
  1109.               break;
  1110.             i++;
  1111.           }
  1112.           if (j < 80) {
  1113.             i = (80 - j) / 2;
  1114.             for (j = 1; j <= i; j++)
  1115.               text[outloc++] = ' ';
  1116.           }
  1117.           inloc++;
  1118.         } else
  1119.           if (buffer[inloc] == 3)
  1120.           inloc += 2;
  1121.         else
  1122.           if ((buffer[inloc] == 124) && (isdigit(buffer[inloc + 1])) && (isdigit(buffer[inloc + 2])))
  1123.           inloc += 3;
  1124.         else
  1125.           if ((buffer[inloc] == 4) && (isdigit(buffer[inloc + 1]))) {
  1126.           i = inloc;
  1127.           for (j = 1; j < 255; j++) {
  1128.             if ((buffer[i] == '\r') || (i > nhr.length))
  1129.               break;
  1130.             i++;
  1131.             inloc++;
  1132.           }
  1133.           inloc++;
  1134.           if (buffer[inloc] == '\n')
  1135.             inloc++;
  1136.         } else
  1137.           if (buffer[inloc] >= 127)
  1138.           inloc++;
  1139.         else
  1140.           if (buffer[inloc] == 1)
  1141.           inloc++;
  1142.         else
  1143.           text[outloc++] = buffer[inloc++];
  1144.       } while (inloc < nhr.length);
  1145.  
  1146.       text[outloc] = '\0';
  1147.  
  1148.       if ((nhr.main_type == main_type_post) ||
  1149.           (nhr.main_type == main_type_pre_post) ||
  1150.           (nhr.main_type == main_type_new_post)) {
  1151.         if (nhr.main_type == main_type_new_post) {
  1152.           sprintf(fn1, "%sM%s.NET", net_data, alphasubtype);
  1153.           if (exist(fn1)) {
  1154.             tolist = 1;
  1155.             nhr.main_type = main_type_email_name;
  1156.           }
  1157.         }
  1158.         for (i = 0; (i < nlists) && (nhr.main_type != main_type_email_name); i++) {
  1159.           if (nhr.main_type == main_type_new_post) {
  1160.             if (strcmpi(alphasubtype, maillist[i].subtype) == 0) {
  1161.               nhr.main_type = main_type_email_name;
  1162.               strcpy(mh.toUserName, maillist[i].ownername);
  1163.             }
  1164.           } else {
  1165.             ttype = atoi(maillist[i].subtype);
  1166.             if (ttype == stype) {
  1167.               nhr.main_type = main_type_email_name;
  1168.               strcpy(mh.toUserName, maillist[i].ownername);
  1169.             }
  1170.           }
  1171.         }
  1172.       }
  1173.       switch (nhr.main_type) {
  1174.         case main_type_email:
  1175.         case main_type_email_name:
  1176.         case main_type_ssm:
  1177.           i = 1;
  1178.           sprintf(outfn, "%sMQUEUE\\MSG.%d", net_data, i);
  1179.           while (exist(outfn))
  1180.             sprintf(outfn, "%sMQUEUE\\MSG.%d", net_data, ++i);
  1181.           break;
  1182.         case main_type_new_post:
  1183.         case main_type_post:
  1184.         case main_type_pre_post:
  1185.           i = 1;
  1186.           strcpy(tempoutfn, hold);
  1187.           sprintf(outfn, "%sOUTBOUND\\%s.%d", net_data, tempoutfn, i);
  1188.           while (exist(outfn))
  1189.             sprintf(outfn, "%sOUTBOUND\\%s.%d", net_data, tempoutfn, ++i);
  1190.           break;
  1191.         default:
  1192.           continue;
  1193.       }
  1194.  
  1195.       properize(mh.fromUserName);
  1196.       output("\n ■ Creating: %s", outfn);
  1197.       if (nhr.fromsys != net_sysnum)
  1198.         output("\n ■ From    : %s", mh.fromUserName);
  1199.       else
  1200.         if (usermail)
  1201.         output("\n ■ From    : \"%s\" <%s@%s>", mh.fromUserName, POPNAME, DOMAIN);
  1202.       else
  1203.         output("\n ■ From    : <%s@%s>", POPNAME, DOMAIN);
  1204.       if ((nhr.main_type == main_type_post) ||
  1205.           (nhr.main_type == main_type_pre_post) ||
  1206.           (nhr.main_type == main_type_new_post)) {
  1207.         sprintf(fn1, "%sNEWS.RC", net_data);
  1208.         if ((fp = fsh_open(fn1, "rt")) == NULL) {
  1209.           output("\n ■ %s not found!", fn1);
  1210.           sh_close(infile);
  1211.           if (text)
  1212.             free(text);
  1213.           if (buffer)
  1214.             free(buffer);
  1215.           return 1;
  1216.         } else {
  1217.           ok = 0;
  1218.           while ((fgets(_temp_buffer, 80, fp) != NULL) && (!ok)) {
  1219.             groupname[0] = 0;
  1220.             ss = strtok(_temp_buffer, " ");
  1221.             if (ss) {
  1222.               strcpy(groupname, ss);
  1223.               ss = strtok(NULL, " ");
  1224.               ss = strtok(NULL, "\r");
  1225.               if (nhr.main_type == main_type_new_post) {
  1226.                 strcpy(alphatype, ss);
  1227.                 if (strncmpi(alphasubtype, alphatype, strlen(alphasubtype)) == 0)
  1228.                   ok = 1;
  1229.               } else {
  1230.                 ttype = atoi(ss);
  1231.                 if (ttype == stype)
  1232.                   ok = 1;
  1233.               }
  1234.             }
  1235.           }
  1236.           *ss = NULL;
  1237.           if (fp != NULL)
  1238.             fclose(fp);
  1239.           if (!ok) {
  1240.             if (nhr.main_type != main_type_new_post)
  1241.               sprintf(alphatype, "%u", stype);
  1242.             output("\n ■ Subtype %s not found in NEWS.RC!", alphatype);
  1243.             sh_close(infile);
  1244.             if (text)
  1245.               free(text);
  1246.             if (buffer)
  1247.               free(buffer);
  1248.             return 1;
  1249.           }
  1250.         }
  1251.       }
  1252.       if ((nhr.main_type == main_type_email) ||
  1253.           (nhr.main_type == main_type_email_name) ||
  1254.           (nhr.main_type == main_type_ssm)) {
  1255.         if (tolist)
  1256.           output("\n ■ Sent to : %s Mailing List", alphasubtype);
  1257.         else
  1258.           output("\n ■ Rcpt to : %s", mh.toUserName);
  1259.       } else
  1260.         output("\n ■ Post to : %s", groupname);
  1261.  
  1262.       strcpy(_temp_buffer, mh.subject);
  1263.       j = 0;
  1264.       for (i = 0; i < strlen(mh.subject); i++) {
  1265.         if (_temp_buffer[i] == 3)
  1266.           ++i;
  1267.         else
  1268.           mh.subject[j++] = _temp_buffer[i];
  1269.       }
  1270.       mh.subject[j] = '\0';
  1271.  
  1272.       output("\n ■ Subject : %s", mh.subject);
  1273.  
  1274.       outfile = sh_open(outfn, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC | O_EXCL, S_IWRITE);
  1275.       if (outfile == -1) {
  1276.         sh_close(infile);
  1277.         if (buffer)
  1278.           free(buffer);
  1279.         if (text)
  1280.           free(text);
  1281.         output("\n ■ Unable to open output file %s", outfn);
  1282.         return 1;
  1283.       }
  1284.       time(&some);
  1285.       time_msg = localtime(&some);
  1286.       strftime(mh.dateTime, 80, "%a, %d %b %y %H:%M:%S (%Z)", time_msg);
  1287.       if (nhr.fromsys == 32767) {
  1288.         sprintf(_temp_buffer, "From: %s\n", mh.fromUserName);
  1289.       } else if (nhr.fromsys != net_sysnum) {
  1290.         sprintf(_temp_buffer, "From: \"%s #%hd-%hu\" <%s@%s>\n", mh.fromUserName,
  1291.                 nhr.fromuser, nhr.fromsys, POPNAME, DOMAIN);
  1292.       } else {
  1293.           if ((spam) && ((nhr.main_type == main_type_post) || (nhr.main_type == main_type_new_post)))
  1294.             if (spamname[0] == 0)
  1295.               sprintf(_temp_buffer, "From: \"%s\" <%s@dont.spam.me.%s>\n",
  1296.                       mh.fromUserName, POPNAME, DOMAIN);
  1297.             else
  1298.               sprintf(_temp_buffer, "From: \"%s\" <%s>\n", mh.fromUserName, spamname);
  1299.           else {
  1300.             if (usermail)
  1301.               sprintf(_temp_buffer, "From: \"%s\" <%s@%s>\n",
  1302.                       mh.fromUserName, POPNAME, DOMAIN);
  1303.             else
  1304.               sprintf(_temp_buffer, "From: <%s@%s>\n", POPNAME, DOMAIN);
  1305.           }
  1306.       }
  1307.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1308.       ++cur_daten;
  1309.       sprintf(_temp_buffer, "Message-ID: <%lx-%s@WWIV-BBS>\n",
  1310.               cur_daten, POPNAME);
  1311.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1312.       if ((nhr.main_type == main_type_email) ||
  1313.           (nhr.main_type == main_type_email_name) ||
  1314.           (nhr.main_type == main_type_ssm)) {
  1315.         if (!tolist) {
  1316.           sprintf(_temp_buffer, "To: %s\n", mh.toUserName);
  1317.           sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1318.         } else {
  1319.           sprintf(fn1, "%sM%s.NET", net_data, alphasubtype);
  1320.           i = 0;
  1321.           if ((fp = fsh_open(fn1, "rt")) != NULL) {
  1322.             while (fgets(_temp_buffer, 80, fp) != NULL) {
  1323.               if (_fstrstr(_temp_buffer, "@")) {
  1324.                 strcpy(mh.toUserName, _temp_buffer);
  1325.                 sprintf(_temp_buffer, "To: %s", mh.toUserName);
  1326.                 if (_temp_buffer[strlen(_temp_buffer) - 1] != '\n')
  1327.                   strcat(_temp_buffer, "\n");
  1328.                 sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1329.                 i = 1;
  1330.               }
  1331.             }
  1332.             if (fp != NULL)
  1333.               fclose(fp);
  1334.           }
  1335.           if (!i) {
  1336.             sh_close(infile);
  1337.             if (buffer)
  1338.               free(buffer);
  1339.             if (text)
  1340.               free(text);
  1341.             output("\n ■ Error processing mailing list %s.", alphasubtype);
  1342.             return (1);
  1343.           } else {
  1344.             sprintf(_temp_buffer, "Reply-To: \"%s\" <%s@%s>\n", alphasubtype,
  1345.                     POPNAME, DOMAIN);
  1346.             sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1347.           }
  1348.         }
  1349.       } else {
  1350.         sprintf(_temp_buffer, "Newsgroups: %s\n", groupname);
  1351.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1352.       }
  1353.       sprintf(_temp_buffer, "Subject: %s\n", mh.subject);
  1354.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1355.       sprintf(_temp_buffer, "Date: %s\n", mh.dateTime);
  1356.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1357.       if (nhr.main_type != main_type_email_name) {
  1358.         sprintf(_temp_buffer, "Path: %s!%s\n", POPNAME, DOMAIN);
  1359.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1360.         sprintf(_temp_buffer, "Organization: %s * %s\n",
  1361.                 syscfg.systemname, syscfg.systemphone);
  1362.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1363.       }
  1364.       if (tolist) {
  1365.         sprintf(_temp_buffer, "X-Reply-To: \"%s\" <%s@%s>\n",
  1366.                 alphasubtype, POPNAME, DOMAIN);
  1367.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1368.       }
  1369. /*
  1370.       else {
  1371.         if ((!spam) && ((nhr.main_type != main_type_post) || (nhr.main_type != main_type_new_post))) {
  1372.           sprintf(_temp_buffer, "Reply-To: \"%s\" <%s@%s>\n",
  1373.               mh.fromUserName, POPNAME, DOMAIN);
  1374.           sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1375.         }
  1376.       }
  1377. */
  1378.  
  1379.       if (tolist) {
  1380.         sprintf(_temp_buffer, "Source: %s Mail List\n", alphasubtype);
  1381.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1382.       }
  1383.       if (((nhr.main_type == main_type_post) || (nhr.main_type == main_type_new_post)) && (!tolist)) {
  1384.         if (*REPLYTO)
  1385.           sprintf(_temp_buffer, "Reply-to: \"%s\" <%s>\n", mh.fromUserName, REPLYTO);
  1386.         else
  1387.           sprintf(_temp_buffer, "Reply-to: \"%s\" <%s@%s>\n",
  1388.                   mh.fromUserName, POPNAME, DOMAIN);
  1389.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1390.       }
  1391.       sprintf(_temp_buffer, "Version: WWIV PPP Project %s\n\n", VERSION);
  1392.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1393.  
  1394.       if ((nhr.main_type != main_type_email) &&
  1395.           (nhr.main_type != main_type_email_name) &&
  1396.           (strncmp(mh.toUserName, "ALL", 3) != 0)) {
  1397.         sprintf(_temp_buffer, "Responding to: %s\n", mh.toUserName);
  1398.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1399.       }
  1400.       for (i = 0; i < strlen(text); i++)
  1401.         if (text[i] == 'π')
  1402.           text[i] = '\n';
  1403.  
  1404.       sh_write(outfile, text, strlen(text));
  1405.       sprintf(tagfn, "%sI%u.TAG", syscfg.datadir, stype);
  1406.       if (exist(tagfn))
  1407.         strcpy(tagfile, tagfn);
  1408.       tagfn[0] = 0;
  1409.       ns = 0;
  1410.       for (i6 = 0; i6 < 99; i6++) {
  1411.         sprintf(tagfn, "%sI%u.T%d", syscfg.datadir, i6);
  1412.         if (exist(tagfn))
  1413.           ns++;
  1414.         else
  1415.           break;
  1416.       }
  1417.       sprintf(tagfn, "%sI%u.T%d", syscfg.datadir, random(ns));
  1418.       if (exist(tagfn))
  1419.         strcpy(tagfile, tagfn);
  1420.       if (tagfile[0] == 0) {
  1421.         sprintf(_temp_buffer, "\n\nOrigin: %s * %s\n\n",
  1422.                 syscfg.systemname, syscfg.systemphone);
  1423.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1424.       } else {
  1425.         if ((fp = fsh_open(tagfile, "rt")) == NULL)
  1426.           output("\n ■ Error reading %s.", tagfile);
  1427.         else {
  1428.           sprintf(_temp_buffer, "\n\n");
  1429.           sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1430.           while (fgets(_temp_buffer, 120, fp)) {
  1431.             for (i = 0; ((i < strlen(_temp_buffer)) &&
  1432.                (_temp_buffer[i] != '\r') && (_temp_buffer[i] != '\n')); i++)
  1433.               if ((_temp_buffer[i] < 32) || (_temp_buffer[i] > 126))
  1434.                 _temp_buffer[i] = 32;
  1435.             sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1436.           }
  1437.           if (fp != NULL)
  1438.             fclose(fp);
  1439.           sprintf(_temp_buffer, "\n\n");
  1440.           sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1441.         }
  1442.       }
  1443.       sh_close(outfile);
  1444.     } else {
  1445.       if ((nhr.main_type >= 0x01) && (nhr.main_type <= 0x1b))
  1446.         output("\n ■ %s message skipped",
  1447.                main_type[nhr.main_type - 1]);
  1448.       else
  1449.         output("\n ■ Unknown Main_type %hd skipped", nhr.main_type);
  1450.     }
  1451.   }
  1452.   sh_close(infile);
  1453.   unlink(fn);
  1454.   if (text)
  1455.     free(text);
  1456.   if (buffer)
  1457.     free(buffer);
  1458.   return (0);
  1459. }
  1460.  
  1461. void get_dir(char *s, int be)
  1462. {
  1463.   strcpy(s, "X:\\");
  1464.   s[0] = 'A' + getdisk();
  1465.   getcurdir(0, s + 3);
  1466.   if (be) {
  1467.     if (s[strlen(s) - 1] != '\\')
  1468.       strcat(s, "\\");
  1469.   }
  1470. }
  1471.  
  1472. /*
  1473.   action: 1 = unsubscribed,
  1474.           2 = subscribed,
  1475.           3 = already subscribed,
  1476.           4 = not subscribed
  1477.           5 = invalid list
  1478. */
  1479.  
  1480. void send_note(int action, char *mailname, char *listname)
  1481. {
  1482.   char s[81], fn[MAXPATH];
  1483.   int i;
  1484.   FILE *fp, *rlz;
  1485.  
  1486.   i = 1;
  1487.   sprintf(fn, "%sMQUEUE\\MSG.%d", net_data, i);
  1488.   while (exist(fn))
  1489.     sprintf(fn, "%sMQUEUE\\MSG.%d", net_data, ++i);
  1490.  
  1491.   if ((fp = fsh_open(fn, "wt+")) == NULL) {
  1492.     output("\n ! Unable to create %s.", fn);
  1493.     return;
  1494.   }
  1495.  
  1496.   if (action != 5)
  1497.     fprintf(fp, "From: \"%s\" <%s@%s>\n", listname, POPNAME, DOMAIN);
  1498.   else
  1499.     fprintf(fp, "From: <%s@%s>\n", POPNAME, DOMAIN);
  1500.   fprintf(fp, "To: %s\n", mailname);
  1501.   fprintf(fp, "Subject: %s Mailing List\n\n", listname);
  1502.  
  1503.   switch (action) {
  1504.     case 1:
  1505.       fprintf(fp, "%s has been unsubscribed from mailing list:\n\n   %s\n\n",
  1506.           mailname, listname);
  1507.       break;
  1508.     case 2:
  1509.       sprintf(fn, "%sR%s.RLZ", net_data, listname);
  1510.       if (!(exist(fn)))
  1511.         sprintf(fn, "%sGLOBAL.RLZ", net_data);
  1512.       if ((rlz = fsh_open(fn, "rt")) != NULL) {
  1513.         while (fgets(s, 80, rlz))
  1514.           fprintf(fp, s);
  1515.         fprintf(fp, "\n\n");
  1516.         fclose(rlz);
  1517.       } else
  1518.         fprintf(fp, "%s has been added to mailing list:\n\n   %s\n\n", mailname,
  1519.             listname);
  1520.       break;
  1521.     case 3:
  1522.       sprintf(fn, "%sR%s.RLZ", net_data, listname);
  1523.       if (!(exist(fn)))
  1524.         sprintf(fn, "%sGLOBAL.RLZ", net_data);
  1525.       if ((rlz = fsh_open(fn, "rt")) != NULL) {
  1526.         while (fgets(s, 80, rlz))
  1527.           fprintf(fp, s);
  1528.         fprintf(fp, "\n\n");
  1529.         fclose(rlz);
  1530.       } else
  1531.         fprintf(fp, "%s was already subscribed to mailing list:\n\n   %s\n\n",
  1532.             mailname, listname);
  1533.       break;
  1534.     case 4:
  1535.       fprintf(fp, "%s was not subscribed to mailing list:\n\n   %s\n\n",
  1536.           mailname, listname);
  1537.       break;
  1538.     case 5:
  1539.       fprintf(fp, "%s has requested an invalid mailing list:\n\n   %s\n\n",
  1540.           mailname, listname);
  1541.       break;
  1542.   }
  1543.   if (fp != NULL)
  1544.     fclose(fp);
  1545. }
  1546.  
  1547. int copyfile(char *input, char *output)
  1548. {
  1549.   int f1, f2, i;
  1550.   char *b;
  1551.   struct ftime ft;
  1552.  
  1553.   if ((strcmp(input, output) != 0) && (exist(input)) && (!exist(output))) {
  1554.     if ((b = (char *) malloc(16400)) == NULL)
  1555.       return 0;
  1556.     f1 = sh_open1(input, O_RDONLY | O_BINARY);
  1557.     if (!f1) {
  1558.       free(b);
  1559.       b = NULL;
  1560.       return 0;
  1561.     }
  1562.     getftime(f1, &ft);
  1563.  
  1564.     f2 = sh_open(output, O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  1565.     if (!f2) {
  1566.       free(b);
  1567.       b = NULL;
  1568.       f1 = sh_close(f1);
  1569.       return 0;
  1570.     }
  1571.     i = read(f1, (void *) b, 16384);
  1572.     while (i > 0) {
  1573.       sh_write(f2, (void *) b, i);
  1574.       i = read(f1, (void *) b, 16384);
  1575.     }
  1576.     f1 = sh_close(f1);
  1577.     setftime(f2, &ft);
  1578.     f2 = sh_close(f2);
  1579.     free(b);
  1580.     b = NULL;
  1581.   }
  1582.   return 1;
  1583. }
  1584.  
  1585.  
  1586. int subscribe(char *fn)
  1587. {
  1588.   char *ss, s[81], s1[81], mailname[81], subtype[81];
  1589.   int i, done, found, unsubscribe;
  1590.   FILE *fp, *oldfp, *newfp;
  1591.  
  1592.   if ((fp = fsh_open(fn, "rt")) == NULL) {
  1593.     output("\n ! Unable to open %s.", fn);
  1594.     return 1;
  1595.   }
  1596.   done = unsubscribe = 0;
  1597.   while ((fgets(s1, 80, fp)) && (!done)) {
  1598.     strcpy(s, &(s1[3]));
  1599.     if (strnicmp(s, "from:", 5) == 0) {
  1600.       ss = strtok(s, ":");
  1601.       if (ss) {
  1602.         ss = strtok(NULL, "\r\n");
  1603.         trimstr1(ss);
  1604.         strcpy(mailname, ss);
  1605.       }
  1606.     }
  1607.     if (strnicmp(s, "subject:", 8) == 0) {
  1608.       done = 1;
  1609.       ss = strtok(s, ":");
  1610.       if (ss) {
  1611.         ss = strtok(NULL, "\r\n");
  1612.         trimstr1(ss);
  1613.         strcpy(s1, ss);
  1614.         if (strnicmp(s1, "subscribe", 9) == 0) {
  1615.           ss = strtok(s1, " ");
  1616.           if (ss) {
  1617.             ss = strtok(NULL, "\r\n");
  1618.             trimstr1(ss);
  1619.             strcpy(subtype, ss);
  1620.           }
  1621.         }
  1622.         if (strnicmp(s1, "unsubscribe", 11) == 0) {
  1623.           unsubscribe = 1;
  1624.           ss = strtok(s1, " ");
  1625.           if (ss) {
  1626.             ss = strtok(NULL, "\r\n");
  1627.             trimstr1(ss);
  1628.             strcpy(subtype, ss);
  1629.           }
  1630.         }
  1631.       }
  1632.       ss = NULL;
  1633.     }
  1634.   }
  1635.   if (fp != NULL)
  1636.     fclose(fp);
  1637.   if ((!*mailname) || (!*subtype)) {
  1638.     output("\n ! Invalid subscription request %s.", fn);
  1639.     return 1;
  1640.   }
  1641.   if (strlen(subtype) == 1) {
  1642.     output("\n ! %s attempted to write to M%s.NET!", mailname, subtype);
  1643.     return 1;
  1644.   }
  1645.   sprintf(s, "%sM%s.NET", net_data, subtype);
  1646.   if (!exist(s)) {
  1647.     output("\n ! %s subscriber list not found.", s);
  1648.     send_note(5, mailname, subtype);
  1649.     return 1;
  1650.   }
  1651.   if ((oldfp = fsh_open(s, "rt")) == NULL) {
  1652.     output("\n ! Unable to open input file %s.", s);
  1653.     return 1;
  1654.   }
  1655.   sprintf(s1, "%sM%s.TMP", net_data, subtype);
  1656.   if (exist(s1))
  1657.     unlink(s1);
  1658.   if ((newfp = fsh_open(s1, "wt+")) == NULL) {
  1659.     output("\n ! Unable to open output file %s.", s1);
  1660.     return 1;
  1661.   }
  1662.   found = 0;
  1663.   while (fgets(s, 80, oldfp)) {
  1664.     trimstr1(s);
  1665.     if (unsubscribe) {
  1666.       if (stricmp(s, mailname) == 0) {
  1667.         output("\n ■ Removing %s from %s mailing list.", mailname, subtype);
  1668.         send_note(2, mailname, subtype);
  1669.         found = 1;
  1670.       } else
  1671.         fprintf(newfp, s);
  1672.     } else {
  1673.       if (stricmp(s, mailname) == 0) {
  1674.         output("\n ■ %s already in %s mailing list.", mailname, subtype);
  1675.         send_note(3, mailname, subtype);
  1676.         found = 1;
  1677.       }
  1678.       fprintf(newfp, s);
  1679.     }
  1680.   }
  1681.   if (!found) {
  1682.     if (unsubscribe)
  1683.       send_note(4, mailname, subtype);
  1684.     else {
  1685.       output("\n ■ Adding %s to %s mailing list.", mailname, subtype);
  1686.       fprintf(newfp, "\n%s\n", mailname);
  1687.       send_note(2, mailname, subtype);
  1688.     }
  1689.   }
  1690.   if (oldfp != NULL)
  1691.     fclose(oldfp);
  1692.   if (newfp != NULL)
  1693.     fclose(newfp);
  1694.   sprintf(s, "%sM%s.TMP", net_data, subtype);
  1695.   sprintf(s1, "%sM%s.NET", net_data, subtype);
  1696.   if (exist(s1))
  1697.     unlink(s1);
  1698.   copyfile(s, s1);
  1699.   return 0;
  1700. }
  1701.  
  1702. int main(int argc, char *argv[])
  1703. {
  1704.   char fn[MAXPATH], *ss;
  1705.   int f, f1, i;
  1706.   struct ffblk ff;
  1707.   struct date dt;
  1708.   struct time tm;
  1709.  
  1710.   output("\n ■ PPP Import/Export %s", VERSION);
  1711.   if (argc != 7) {
  1712.     output("\n ■ EXP <filename> <net_data> <net_sysnum> <POPNAME> <DOMAIN> <net_name>\n\n");
  1713.     if (argc > 1) {
  1714.       output("Command line was: ");
  1715.       for (i = 0; i < argc; i++)
  1716.         output("%s ", argv[i]);
  1717.       output("\n\n");
  1718.     }
  1719.     return (1);
  1720.   }
  1721.   f = sh_open1("CONFIG.DAT", O_RDONLY | O_BINARY);
  1722.   if (f < 0) {
  1723.     output("Could not open CONFIG.DAT!\n\n");
  1724.     return 1;
  1725.   }
  1726.   sh_read(f, (void *) &syscfg, sizeof(configrec));
  1727.   sh_close(f);
  1728.  
  1729.   detect_multitask();
  1730.  
  1731.   get_dir(maindir, 1);
  1732.   strcpy(net_data, argv[2]);
  1733.   sprintf(fn, "%s%s", net_data, argv[1]);
  1734.   strcpy(net_name, argv[6]);
  1735.   strcpy(POPNAME, argv[4]);
  1736.   strcpy(DOMAIN, argv[5]);
  1737.   net_sysnum = atoi(argv[3]);
  1738.   tagfile[0] = 0;
  1739.   spam = 0;
  1740.  
  1741.   ss = getenv("WWIV_INSTANCE");
  1742.   if (ss) {
  1743.     instance = atoi(ss);
  1744.     if (instance >= 1000) {
  1745.       output("\n ■ WWIV_INSTANCE set to %hd.  Can only be 1..999!",
  1746.              instance);
  1747.       instance = 1;
  1748.     }
  1749.   } else
  1750.     instance = 1;
  1751.  
  1752.   parse_net_ini();
  1753.   gettime(&tm);
  1754.   getdate(&dt);
  1755.   cur_daten = dostounix(&dt, &tm);
  1756.  
  1757.   strupr(postmaster);
  1758.   export(fn);
  1759.  
  1760.   sprintf(fn, "%sSPOOL\\UNK*.*", net_data);
  1761.   f1 = findfirst(fn, &ff, 0);
  1762.   while (f1 == 0) {
  1763.     sprintf(fn, "%sSPOOL\\%s", net_data, ff.ff_name);
  1764.     if (!import(fn)) {
  1765.       unlink(fn);
  1766.     }
  1767.     f1 = findnext(&ff);
  1768.   }
  1769.  
  1770.   sprintf(fn, "%sINBOUND\\SUB*.*", net_data);
  1771.   f1 = findfirst(fn, &ff, 0);
  1772.   while (f1 == 0) {
  1773.     sprintf(fn, "%sINBOUND\\%s", net_data, ff.ff_name);
  1774.     output("\n ■ Processing subscriber request %s...", ff.ff_name);
  1775.     subscribe(fn);
  1776.     unlink(fn);
  1777.     f1 = findnext(&ff);
  1778.   }
  1779.  
  1780.   if (maillist != NULL)
  1781.     free(maillist);
  1782.  
  1783.   return 0;
  1784. }
  1785.