home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / PPPBCKP / SRC / SRC15B27.ZIP / EXP.C < prev    next >
Text File  |  1997-05-18  |  33KB  |  1,189 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <dos.h>
  5. #include <fcntl.h>
  6. #include <sys/stat.h>
  7. #include <ctype.h>
  8. #include <mem.h>
  9. #include <conio.h>
  10. #include <io.h>
  11. #include <share.h>
  12. #include <errno.h>
  13. #include <dir.h>
  14. #include <time.h>
  15. #include <malloc.h>
  16. #include <process.h>
  17. #include <direct.h>
  18. #include "vardec.h"
  19. #include "net.h"
  20.  
  21. #include "version.h"
  22.  
  23. #define WAIT_TIME 10
  24. #define TRIES 100
  25. #define SHARE_LEVEL 10
  26. #define MT_DESQVIEW 0x01
  27. #define MT_WINDOWS  0x02
  28. #define MT_OS2      0x04
  29. #define MT_NB       0x40
  30.  
  31.  
  32. struct msghdr {
  33.   char fromUserName[205];
  34.   char toUserName[81];
  35.   char subject[81];
  36.   char dateTime[81];
  37. };
  38.  
  39. configrec syscfg;
  40. char *net_name, postmaster[31], net_data[MAXPATH], POPNAME[21], DOMAIN[81], tagfile[MAXPATH], maindir[MAXPATH], spamname[81];
  41. unsigned short net_sysnum, defuser, num_users, use_alias, instance, curuser, spam;
  42. int multitasker = 0;
  43. char alphasubtype[8];
  44.  
  45. void dv_pause(void)
  46. {
  47.   __emit__(0xb8, 0x1a, 0x10, 0xcd, 0x15);
  48.   __emit__(0xb8, 0x00, 0x10, 0xcd, 0x15);
  49.   __emit__(0xb8, 0x25, 0x10, 0xcd, 0x15);
  50. }
  51.  
  52. void win_pause(void)
  53. {
  54.   __emit__(0x55, 0xb8, 0x80, 0x16, 0xcd, 0x2f, 0x5d);
  55. }
  56.  
  57. int get_dos_version(void)
  58. {
  59.   _AX = 0x3000;
  60.   geninterrupt(0x21);
  61.   if (_AX % 256 >= 10) {
  62.     multitasker |= MT_OS2;
  63.   }
  64.   return (_AX);
  65. }
  66.  
  67. int get_dv_version(void)
  68. {
  69.   int v;
  70.  
  71.   if (multitasker & MT_OS2)
  72.     return 0;
  73.   _AX = 0x2b01;
  74.   _CX = 0x4445;
  75.   _DX = 0x5351;
  76.   geninterrupt(0x21);
  77.   if (_AL == 0xff) {
  78.     return 0;
  79.   } else {
  80.     v = _BX;
  81.     multitasker |= MT_DESQVIEW;
  82.     return v;
  83.   }
  84. }
  85.  
  86. int get_win_version(void)
  87. {
  88.   int v = 0;
  89.  
  90.   __emit__(0x55, 0x06, 0x53);
  91.   _AX = 0x352f;
  92.   geninterrupt(0x21);
  93.   _AX = _ES;
  94.   if (_AX | _BX) {
  95.     _AX = 0x1600;
  96.     geninterrupt(0x2f);
  97.     v = _AX;
  98.     if (v % 256 <= 1)
  99.       v = 0;
  100.   }
  101.   __emit__(0x5b, 0x07, 0x5d);
  102.   if (v != 0)
  103.     multitasker |= MT_WINDOWS;
  104.   return (v);
  105. }
  106.  
  107. int get_nb_version(void)
  108. {
  109.   _AX = 0;
  110.   geninterrupt(0x2A);
  111.   return (_AH);
  112. }
  113.  
  114. void detect_multitask(void)
  115. {
  116.   get_dos_version();
  117.   get_win_version();
  118.   get_dv_version();
  119. }
  120.  
  121. void giveup_timeslice(void)
  122. {
  123.   if (multitasker) {
  124.     switch (multitasker) {
  125.  case 1: 
  126.  case 3: 
  127.         dv_pause();
  128.         break;
  129.       case 2:
  130.       case 4:
  131.       case 5:
  132.       case 6:
  133.       case 7:
  134.         win_pause();
  135.         break;
  136.       default:
  137.         break;
  138.     }
  139.   }
  140. }
  141.  
  142. int sh_write(int handle, void *buffer, unsigned long len)
  143. {
  144.   if (handle == -1) {
  145.     return (-1);
  146.   }
  147.   return (write(handle, buffer, (unsigned) len));
  148. }
  149.  
  150. int sh_open(char *path, int file_access, unsigned fmode)
  151. {
  152.   int handle, count, share;
  153.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  154.  
  155.   if ((file_access & O_RDWR) || (file_access & O_WRONLY) || (fmode & S_IWRITE)) {
  156.     share = SH_DENYRW;
  157.   } else {
  158.     share = SH_DENYWR;
  159.   }
  160.   handle = open(path, file_access | share, fmode);
  161.   if (handle < 0) {
  162.     count = 1;
  163.     fnsplit(path, drive, dir, file, ext);
  164.     if (access(path, 0) != -1) {
  165.       delay(WAIT_TIME);
  166.       handle = open(path, file_access | share, fmode);
  167.       while (((handle < 0) && (errno == EACCES)) && (count < TRIES)) {
  168.         if (count % 2)
  169.           delay(WAIT_TIME);
  170.         else
  171.           giveup_timeslice();
  172.         count++;
  173.         handle = open(path, file_access | share, fmode);
  174.       }
  175.     }
  176.   }
  177.   return (handle);
  178. }
  179.  
  180. int sh_open1(char *path, int access)
  181. {
  182.   unsigned fmode;
  183.  
  184.   fmode = 0;
  185.   if ((access & O_RDWR) || (access & O_WRONLY))
  186.     fmode |= S_IWRITE;
  187.   if ((access & O_RDWR) || (access & O_RDONLY))
  188.     fmode |= S_IREAD;
  189.   return (sh_open(path, access, fmode));
  190. }
  191.  
  192. int sh_close(int f)
  193. {
  194.   if (f != -1)
  195.     close(f);
  196.   return (-1);
  197. }
  198.  
  199. int sh_read(int handle, void *buf, unsigned len)
  200. {
  201.   if (handle == -1) {
  202.     return (-1);
  203.   }
  204.   return (read(handle, buf, len));
  205. }
  206.  
  207. long sh_lseek(int handle, long offset, int fromwhere)
  208. {
  209.   if (handle == -1) {
  210.     return (-1L);
  211.   }
  212.   return (lseek(handle, offset, fromwhere));
  213. }
  214.  
  215. FILE *fsh_open(char *path, char *fmode)
  216. {
  217.   FILE *f;
  218.   int count, share, md, fd;
  219.   char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
  220.  
  221.   share = SH_DENYWR;
  222.   md = 0;
  223.   if (((char *) _fstrchr(fmode, 'w')) != NULL) {
  224.     share = SH_DENYRD;
  225.     md = O_RDWR | O_CREAT | O_TRUNC;
  226.   } else
  227.     if (((char *) _fstrchr(fmode, 'a')) != NULL) {
  228.     share = SH_DENYRD;
  229.     md = O_RDWR | O_CREAT;
  230.   } else {
  231.     md = O_RDONLY;
  232.   }
  233.   if (((char *) _fstrchr(fmode, 'b')) != NULL) {
  234.     md |= O_BINARY;
  235.   }
  236.   if (((char *) _fstrchr(fmode, '+')) != NULL) {
  237.     md &= ~O_RDONLY;
  238.     md |= O_RDWR;
  239.     share = SH_DENYRD;
  240.   }
  241.   fd = open(path, md | share, S_IREAD | S_IWRITE);
  242.   if (fd < 0) {
  243.     count = 1;
  244.     fnsplit(path, drive, dir, file, ext);
  245.     if ((access(path, 0)) != -1) {
  246.       delay(WAIT_TIME);
  247.       fd = open(path, md | share, S_IREAD | S_IWRITE);
  248.       while (((fd < 0) && (errno == EACCES)) && (count < TRIES)) {
  249.         delay(WAIT_TIME);
  250.         count++;
  251.         fd = open(path, md | share, S_IREAD | S_IWRITE);
  252.       }
  253.     }
  254.   }
  255.   if (fd > 0) {
  256.     if (((char *) _fstrchr(fmode, 'a')) != NULL)
  257.       sh_lseek(fd, 0L, SEEK_END);
  258.     f = fdopen(fd, fmode);
  259.     if (!f) {
  260.       close(fd);
  261.     }
  262.   } else
  263.     f = 0;
  264.   return (f);
  265. }
  266.  
  267. size_t fsh_write(void *ptr, size_t size, size_t n, FILE * stream)
  268. {
  269.  
  270.   if (stream == NULL) {
  271.     return (0);
  272.   }
  273.   return (fwrite(ptr, size, n, stream));
  274. }
  275.  
  276.  
  277. int exist(char *s)
  278. {
  279.   int i;
  280.   struct ffblk ff;
  281.  
  282.   i = findfirst(s, &ff, 0);
  283.   if (i)
  284.     return (0);
  285.   else
  286.     return (1);
  287. }
  288.  
  289. char *stripspace(char *str)
  290. {
  291.   char *obuf, *nbuf;
  292.  
  293.   if (str) {
  294.     for (obuf = str, nbuf = str; *obuf; ++obuf) {
  295.       if (!isspace(*obuf))
  296.         *nbuf++ = *obuf;
  297.     }
  298.     *nbuf = NULL;
  299.   }
  300.   return (str);
  301. }
  302.  
  303. static unsigned char *trimstr1(unsigned char *s)
  304. {
  305.   int i;
  306.   static char *whitespace = " \r\n\t";
  307.  
  308.   i = (int) strlen(s);
  309.   while ((i > 0) && ((char *) _fstrchr(whitespace, s[i - 1]) != NULL))
  310.     --i;
  311.   while ((i > 0) && ((char *) _fstrchr(whitespace, *s) != NULL)) {
  312.     memmove(s, s + 1, --i);
  313.   }
  314.   s[i] = 0;
  315.   return (s);
  316. }
  317.  
  318.  
  319. int num_to_name(char *where, int whichuser, int alias)
  320. {
  321.   int userfile, num_users, found;
  322.   userrec ur;
  323.   long pos;
  324.   char fn[MAXPATH];
  325.  
  326.   found = 0;
  327.   sprintf(fn, "%sUSER.LST", syscfg.datadir);
  328.   userfile = sh_open1(fn, O_RDONLY | O_BINARY);
  329.   if (userfile < 0) {
  330.     fprintf(stderr, "\n ■ Cannot open %s.", fn);
  331.     return (found);
  332.   }
  333.   num_users = ((int) (filelength(userfile) / sizeof(userrec)));
  334.  
  335.   if (whichuser > num_users) {
  336.     fprintf(stderr, "\n ■ User #%d out of range.", whichuser);
  337.     return (found);
  338.   }
  339.   pos = ((long) sizeof(userrec) * ((long) whichuser));
  340.   lseek(userfile, pos, SEEK_SET);
  341.   sh_read(userfile, &ur, sizeof(userrec));
  342.   if (ur.realname[0] == 0)
  343.     fprintf(stderr, "\n ■ User #%d has blank real name field!", whichuser);
  344.   else {
  345.     if (ur.inact == inact_deleted)
  346.       fprintf(stderr, "\n ■ User #%d is marked as deleted!", whichuser);
  347.     else {
  348.       if (!alias)
  349.         strcpy(where, ur.realname);
  350.       else {
  351.         strlwr(ur.name);
  352.         strcpy(where, ur.name);
  353.       }
  354.       found = 1;
  355.     }
  356.   }
  357.   sh_close(userfile);
  358.   return (found);
  359. }
  360.  
  361.  
  362. void parse_net_ini(void)
  363. {
  364.   char s[MAXPATH], line[121], *ss;
  365.   FILE *fp;
  366.  
  367.   defuser = 1;
  368.   use_alias = 1;
  369.   sprintf(s, "%sNET.INI", maindir);
  370.   fp = fsh_open(s, "rt");
  371.   if (!fp) {
  372.     fprintf(stderr, "\n ■ Unable to open %s.", s);
  373.     return;
  374.   }
  375.   while (fgets(line, 80, fp)) {
  376.     ss = NULL;
  377.     stripspace(line);
  378.     /* fprintf(stderr, "\nCurrent : %s\n", line); */
  379.     if ((line[0] == ';') || (line[0] == '\n') || (line[0] == '['))
  380.       continue;
  381.     if (strlen(line) == 0)
  382.       continue;
  383.     if (strnicmp(line, "POSTMASTER", 10) == 0) {
  384.       ss = strtok(line, "=");
  385.       if (ss) {
  386.         ss = strtok(NULL, "\n");
  387.         if (ss)
  388.           defuser = atoi(ss);
  389.       }
  390.     }
  391.     if (strnicmp(line, "SPAMCONTROL", 11) == 0) {
  392.       ss = strtok(line, "=");
  393.       if (ss) {
  394.         ss = strtok(NULL, "\n");
  395.         if ((ss[0] == 'y') || (ss[0] == 'Y'))
  396.           spam = 1;
  397.       }
  398.     }
  399.     if (strnicmp(line, "SPAMADDRESS", 9) == 0) {
  400.       ss = strtok(line, "=");
  401.       if (ss) {
  402.         ss = strtok(NULL, "\n");
  403.         trimstr1(ss);
  404.         spamname[0]=0;
  405.         strcpy(spamname, ss);
  406.         if (stricmp(spamname,"DEFAULT")==0)
  407.             strcpy(spamname,"WWIV_BBS_PPP_PROJECT@NOSPAM.NET");
  408.       }
  409.     }
  410.     if (strnicmp(line, "SIGNATURE", 9) == 0) {
  411.       ss = strtok(line, "=");
  412.       if (ss) {
  413.         ss = strtok(NULL, "\n");
  414.         trimstr1(ss);
  415.         strcpy(tagfile, ss);
  416.         if (!exist(tagfile)) {
  417.           fprintf(stderr, "\n ■ Default signature file %s not found!", tagfile);
  418.           tagfile[0] = 0;
  419.         }
  420.       }
  421.     }
  422.     if (strnicmp(line, "REALNAME", 8) == 0) {
  423.       ss = strtok(line, "=");
  424.       if (ss) {
  425.         ss = strtok(NULL, "\n");
  426.         if ((ss[0] == 'y') || (ss[0] == 'Y'))
  427.           use_alias = 0;
  428.       }
  429.     }
  430.   }
  431.   num_to_name(postmaster, defuser, 1);
  432.   fclose(fp);
  433.   return;
  434. }
  435.  
  436. unsigned char *strrep(char *str, char old, char New)
  437. {
  438.   int i;
  439.  
  440.   for (i = 0; str[i]; i++)
  441.     if (str[i] == old)
  442.       str[i] = New;
  443.   return (str);
  444. }
  445.  
  446.  
  447. int name_to_num(char *name)
  448. {
  449.   int userfile, usernum;
  450.   userrec ur;
  451.   long pos;
  452.   char fn[MAXPATH], ur_name[60], ur_realname[60];
  453.  
  454.   sprintf(fn, "%sUSER.LST", syscfg.datadir);
  455.   userfile = sh_open1(fn, O_RDONLY | O_BINARY);
  456.   if (userfile < 0) {
  457.     fprintf(stderr, "\n ■ Cannot open %s", fn);
  458.     return (0);
  459.   } else
  460.     fprintf(stderr, "\n ■ Searching for user \"%s\"...", name);
  461.   num_users = ((int) (filelength(userfile) / sizeof(userrec)));
  462.  
  463.   for (usernum = 1; usernum < num_users; usernum++) {
  464.     pos = ((long) sizeof(userrec) * ((long) usernum));
  465.     lseek(userfile, pos, SEEK_SET);
  466.     sh_read(userfile, &ur, sizeof(userrec));
  467.     strcpy(ur_realname, ur.realname);
  468.     strrep(ur_realname, ' ', '_');
  469.     strcpy(ur_name, ur.name);
  470.     strrep(ur_name, ' ', '_');
  471.     if ((strcmpi(ur.realname, name) == 0) || (strcmpi(ur_realname, name) == 0) ||
  472.         (strcmpi(ur.name, name) == 0) || (strcmpi(ur_name, name) == 0)) {
  473.       if (ur.inact == inact_deleted) {
  474.         fprintf(stderr, " user #%d is deleted account.", usernum);
  475.         usernum = 0;
  476.         break;
  477.       } else {
  478.         fprintf(stderr, " matched user #%d.", usernum);
  479.         break;
  480.       }
  481.     }
  482.   }
  483.   userfile = sh_close(userfile);
  484.  
  485.   if (usernum >= num_users) {
  486.     fprintf(stderr, "... no match found.");
  487.     return (0);
  488.   }
  489.   return (usernum);
  490. }
  491.  
  492. char *find_name(char *name)
  493. {
  494.   char *ss;
  495.  
  496.   curuser = 0;
  497.   if (strcspn(name, "(") != strlen(name)) {
  498.     ss = strtok(name, "(");
  499.     ss = strtok(NULL, ")");
  500.     strcpy(name, ss);
  501.     curuser = name_to_num(name);
  502.   } else
  503.     if (strcspn(name, "\"") != strlen(name)) {
  504.     ss = strtok(name, "\"");
  505.     ss = strtok(NULL, "\"");
  506.     strcpy(name, ss);
  507.     curuser = name_to_num(name);
  508.   } else
  509.     if (strcspn(name, "<") != strlen(name)) {
  510.     if ((strcspn(name, " ")) < (strcspn(name, "<"))) {
  511.       ss = strtok(name, "<");
  512.       trimstr1(ss);
  513.       strcpy(name, ss);
  514.       curuser = name_to_num(name);
  515.     } else {
  516.       fprintf(stderr, "\nName is *after* host in \"%s\"", name);
  517.     }
  518.     }
  519.   if (curuser == 0)
  520.     return ('\0');
  521.   else
  522.     return (ss);
  523. }
  524.  
  525. void name_packet(char *pktname)
  526. {
  527.   int ok;
  528.   struct stat info;
  529.   unsigned i;
  530.  
  531.   ok = 0;
  532.   for (i = 0; ((i < 1000) && (!ok)); i++) {
  533.     sprintf(pktname, "%sP0-%u.%3.3hu", net_data, i, instance);
  534.     if (stat(pktname, &info) == -1)
  535.       ok = 1;
  536.   }
  537. }
  538.  
  539.  
  540. int import(char *fn)
  541. {
  542.   char s[513], pktname[MAXPATH], msgdate[31], *ss, *p;
  543.   int f, from, subj, intext, done;
  544.   long textlen, reallen;
  545.   struct msghdr mh;
  546.   net_header_rec nh;
  547.   struct date dt;
  548.   struct time tm;
  549.   FILE *fp;
  550.  
  551.   intext = 0;
  552.   f = sh_open1(fn, O_RDONLY | O_BINARY);
  553.   if (f < 0)
  554.     return (1);
  555.   textlen = filelength(f);
  556.   if (textlen > 32767L) {
  557.     fprintf(stderr, "\n ■ Skipping %s - greater than 32K.", fn);
  558.     return (1);
  559.   }
  560.   p = (char *) malloc((int)(textlen + 1));
  561.   if (p == NULL) {
  562.     fprintf(stderr, "\n ■ Unable to allocate %ld bytes.", textlen);
  563.     return (1);
  564.   }
  565.   sh_read(f, (void *) p, (int)textlen);
  566.   sh_close(f);
  567.  
  568.   nh.tosys = net_sysnum;
  569.   nh.fromsys = 32767;
  570.   nh.fromuser = 0;
  571.   nh.touser = defuser;
  572.   nh.main_type = main_type_email;
  573.   nh.minor_type = 0;
  574.   nh.list_len = 0;
  575.   gettime(&tm);
  576.   getdate(&dt);
  577.   nh.daten = dostounix(&dt, &tm);
  578.   nh.method = 0;
  579.  
  580.   fp = fsh_open(fn, "rb");
  581.   if (!fp) {
  582.     free(p);
  583.     return (1);
  584.   }
  585.   from = subj = done = 0;
  586.   while ((fgets(s, 254, fp)) && !done) {
  587.     if ((s[0] == '\r') || (s[0] == '\n') || (s[0] == 0))
  588.       intext = 1;
  589.     if (s[0] == 4) {
  590.       ss = strtok(s, "R");
  591.       ss = strtok(NULL, "\r\n");
  592.       strcpy(s, ss);
  593.     }
  594.     if (!intext) {
  595.       if ((strncmpi(s, "reply-to:", 9) == 0)) {
  596.         from = 1;
  597.         ss = strtok(s, ": ");
  598.         ss = strtok(NULL, "\r\n");
  599.         trimstr1(ss);
  600.         /* strncpy(mh.fromUserName, ss, 46); */
  601.         strcpy(mh.fromUserName, ss);
  602.         if (strlen(mh.fromUserName) > 190)
  603.           mh.fromUserName[190] = '\0';
  604.         strcat(mh.fromUserName, "\r\n");
  605.       } else
  606.         if ((strncmpi(s, "from:", 5) == 0) && (!from)) {
  607.         from = 1;
  608.         ss = strtok(s, ": ");
  609.         ss = strtok(NULL, "\r\n");
  610.         trimstr1(ss);
  611.         /* strncpy(mh.fromUserName, ss, 46); */
  612.         strcpy(mh.fromUserName, ss);
  613.         if (strlen(mh.fromUserName) > 190)
  614.           mh.fromUserName[190] = '\0';
  615.         strcat(mh.fromUserName, "\r\n");
  616.       } else
  617.         if ((strncmpi(s, "return-path:", 12) == 0) && (!from)) {
  618.         ss = strtok(s, ": ");
  619.         ss = strtok(NULL, "\r\n");
  620.         trimstr1(ss);
  621.         /* strncpy(mh.fromUserName, ss, 46); */
  622.         strcpy(mh.fromUserName, ss);
  623.         if (strlen(mh.fromUserName) > 190)
  624.           mh.fromUserName[190] = '\0';
  625.         strcat(mh.fromUserName, "\r\n");
  626.       } else
  627.         if ((strncmpi(s, "subject:", 8) == 0) && (!subj)) {
  628.         ss = strtok(s, ": ");
  629.         ss = strtok(NULL, "\r\n");
  630.         trimstr1(ss);
  631.         strcpy(mh.subject, ss);
  632.         if (strlen(mh.subject) > 72)
  633.           mh.subject[72] = '\0';
  634.         else
  635.           mh.subject[strlen(mh.subject)] = '\0';
  636.       } else
  637.         if ((strncmpi(s, "to:", 3) == 0) || (strncmpi(s, "cc:", 3) == 0)) {
  638.         ss = strtok(s, ": ");
  639.         ss = strtok(NULL, "\r\n");
  640.         strcpy(mh.toUserName, ss);
  641.         trimstr1(mh.toUserName);
  642.         if (_fstrstr(mh.toUserName, " "))
  643.           find_name(mh.toUserName);
  644.         else
  645.           mh.toUserName[0] = '\0';
  646.         if ((mh.toUserName[0] == 0) || (curuser == 0)) {
  647.           nh.touser = defuser;
  648.           strcpy(mh.toUserName, postmaster);
  649.         } else
  650.           nh.touser = curuser;
  651.         }
  652.     } else
  653.       done = 1;
  654.   }
  655.   fclose(fp);
  656.   fprintf(stderr, "\n ■ From    : %s", mh.fromUserName);
  657.   fprintf(stderr, " ■ Sent to : %s #%hd", strupr(mh.toUserName), nh.touser);
  658.   fprintf(stderr, "\n ■ Subject : %s", mh.subject);
  659.   name_packet(pktname);
  660.   fp = fsh_open(pktname, "wb");
  661.   if (fp < 0) {
  662.     fprintf(stderr, "\n ■ Unable to create packet %s", pktname);
  663.     free(p);
  664.     return (1);
  665.   }
  666.   strncpy(msgdate, ctime(&(time_t) nh.daten), 24);
  667.   msgdate[24] = '\0';
  668.   strcat(msgdate, "\r\n");
  669.   nh.length = textlen + strlen(mh.fromUserName) + strlen(mh.subject) + strlen(msgdate) + 1;
  670.   fsh_write(&nh, sizeof(net_header_rec), 1, fp);
  671.   fsh_write(mh.subject, sizeof(char), strlen(mh.subject) +1, fp);
  672.   fsh_write(mh.fromUserName, sizeof(char), strlen(mh.fromUserName), fp);
  673.   fsh_write(msgdate, sizeof(char), strlen(msgdate), fp);
  674.   reallen = fsh_write(p, sizeof(char), (int)textlen, fp);
  675.   if (reallen != textlen)
  676.     fprintf(stderr, "\n ■ Expected %ld bytes, wrote %ld bytes.", textlen, reallen);
  677.   fclose(fp);
  678.   free(p);
  679.   return (0);
  680. }
  681.  
  682. unsigned char *stripcolors(unsigned char *text)
  683. {
  684.   static unsigned char s[161];
  685.   int i, i1;
  686.  
  687.   if (strlen(text) == 0)
  688.     return ("");
  689.  
  690.   i = 0;
  691.   i1 = 0;
  692.   do {
  693.     if (text[i] == 3)
  694.       i++;
  695.     else {
  696.       s[i1] = text[i];
  697.       i1++;
  698.     }
  699.     i++;
  700.   } while (i < strlen(text));
  701.   s[i1] = 0;
  702.   return (s);
  703. }
  704.  
  705. int export(char *fn)
  706. {
  707.   char fn1[121], tagfn[121], groupname[81], outfn[121], _temp_buffer[256];
  708.   char *ss, *buffer, *text, alphatype[21], hold[21], tempoutfn[21];
  709.   unsigned stype, ttype;
  710.   int infile, outfile, inloc, outloc, term, ok, i, j, ns, i6;
  711.   net_header_rec nhr;
  712.   struct msghdr mh;
  713.   struct tm *time_msg;
  714.   FILE *fp;
  715.   time_t some;
  716.   char *main_type[] =
  717.   {
  718.     "Network Update", "email by usernum", "post from sub host", "file",
  719.     "post to sub host", "external message", "email by name",
  720.     "NetEdit message", "SUBS.LST", "Extra Data", "BBSLIST from GC",
  721.     "CONNECT from GC", "Unused_1", "Info from GC", "SSM", "Sub Add Request",
  722.     "Sub Drop Request", "Sub Add Response", "Sub Drop Response", "Sub Info",
  723.     "Unused 1", "Unused 2", "Unused 3", "Unused 4", "Unused 5", "new post",
  724.     "new external"
  725.   };
  726.  
  727.   if ((infile = sh_open1(fn, O_RDONLY | O_BINARY)) == -1)
  728.     return (1);
  729.  
  730.   if ((buffer = (char *) malloc(32 * 1024)) == NULL) {
  731.     fprintf(stderr, "\n ■ Out of memory allocating input buffer!");
  732.     return (1);
  733.   }
  734.   if ((text = (char *) malloc(32 * 1024)) == NULL) {
  735.     fprintf(stderr, "\n ■ Out of memory allocating output buffer!");
  736.     if (buffer)
  737.       free(buffer);
  738.     buffer = NULL;
  739.     return (1);
  740.   }
  741.   while (sh_read(infile, &nhr, sizeof(nhr))) {
  742.     sh_read(infile, buffer, (int)nhr.length);
  743.     if (nhr.tosys != 32767) {
  744.       fprintf(stderr, "\n ■ Non-Internet system routing via @32767... aborting export.");
  745.       return (1);
  746.     }
  747.     if (nhr.main_type == main_type_pre_post)
  748.       nhr.main_type = main_type_post;
  749.     if ((nhr.main_type == main_type_post) ||
  750.         (nhr.main_type == main_type_new_post) ||
  751.         (nhr.main_type == main_type_email_name) ||
  752.         (nhr.main_type == main_type_ssm)) {
  753.       inloc = 0;
  754.       sprintf(hold, "%hu", nhr.minor_type);
  755.       if ((nhr.main_type == main_type_email_name) ||
  756.           (nhr.main_type == main_type_ssm) ||
  757.           (nhr.main_type == main_type_new_post)) {
  758.         stype = nhr.minor_type;
  759.         inloc = strlen(buffer) + 1;
  760.         if (nhr.main_type == main_type_new_post) {
  761.           strcpy(alphasubtype, buffer);
  762.           strcpy(hold, alphasubtype);
  763.         } else
  764.           strcpy(mh.toUserName, buffer);
  765.         if (nhr.fromsys != net_sysnum) {
  766.           fprintf(stderr, "\n ■ Gate from #%hd@%hd to %s not yet supported",
  767.                   nhr.fromuser, nhr.fromsys, mh.toUserName);
  768.           continue;
  769.         }
  770.       } else
  771.         if (nhr.main_type == main_type_post)
  772.         stype = nhr.minor_type;
  773.       else {
  774.         stype = atoi(&buffer[inloc]);
  775.         sprintf(_temp_buffer, "%u", stype);
  776.         inloc += strlen(_temp_buffer) + 1;
  777.       }
  778.       strncpy(mh.subject, &buffer[inloc], sizeof(mh.subject));
  779.       stripcolors(mh.subject);
  780.       inloc += strlen(&buffer[inloc]) + 1;
  781.  
  782.       for (term = inloc; buffer[term] != '\r'; term++);
  783.       buffer[term] = '\0';
  784.  
  785.       if ((nhr.fromsys == net_sysnum) && (nhr.fromuser)) {
  786.         if ((nhr.main_type != main_type_post) &&
  787.             (nhr.main_type != main_type_new_post)) {
  788.           if (!num_to_name(mh.fromUserName, nhr.fromuser, use_alias)) {
  789.             fprintf(stderr, "\n ■ No match for user #%hd... skipping message!",
  790.                     nhr.fromuser);
  791.             continue;
  792.           }
  793.         } else {
  794.           if (!num_to_name(mh.fromUserName, nhr.fromuser, 1)) {
  795.             fprintf(stderr, "\n ■ No match for user #%hd... skipping message!",
  796.                     nhr.fromuser);
  797.             continue;
  798.           }
  799.         }
  800.       } else {
  801.         strncpy(mh.fromUserName, &buffer[inloc], sizeof(mh.fromUserName));
  802.         stripcolors(mh.fromUserName);
  803.         strtok(mh.fromUserName, "#");
  804.         if ((nhr.main_type == main_type_post) &&
  805.             (nhr.main_type == main_type_new_post) &&
  806.             (nhr.fromsys != net_sysnum)) {
  807.           sprintf(_temp_buffer, " #%hd @%hu", nhr.fromuser, nhr.fromsys);
  808.           strcat(mh.fromUserName, _temp_buffer);
  809.         }
  810.       }
  811.  
  812.       inloc = term + 2;
  813.  
  814.       while (buffer[inloc] != '\n')
  815.         inloc++;
  816.       inloc++;
  817.  
  818.       if (strncmp(&buffer[inloc], "0R", 3) == 0) {
  819.         while (buffer[inloc] != '\n')
  820.           ++inloc;
  821.         inloc++;
  822.       }
  823.       if (strnicmp(&buffer[inloc], "RE: ", 4) == 0) {
  824.         for (term = inloc; buffer[term] != '\r'; term++);
  825.         buffer[term] = '\0';
  826.         strncpy(mh.subject, &buffer[inloc + 4], sizeof(mh.subject));
  827.         inloc = term + 2;
  828.       }
  829.       if ((strncmp(&buffer[inloc], "BY: ", 4) == 0) ||
  830.           (strncmp(&buffer[inloc], "TO: ", 4) == 0)) {
  831.         for (term = inloc; buffer[term] != '\r'; term++);
  832.         buffer[term] = '\0';
  833.         strncpy(mh.toUserName, &buffer[inloc + 4], sizeof(mh.toUserName));
  834.         stripcolors(mh.toUserName);
  835.         if (strcspn(mh.toUserName, "<") != strlen(mh.toUserName)) {
  836.           if ((strstr(mh.toUserName, "\"") == 0) && (strstr(mh.toUserName, "(") == 0)) {
  837.             ss = strtok(mh.toUserName, "<");
  838.             ss = strtok(NULL, ">");
  839.             strcpy(mh.toUserName, ss);
  840.           }
  841.         }
  842.         inloc = term + 2;
  843.       } else {
  844.         if (nhr.main_type != main_type_email_name) {
  845.           strcpy(mh.toUserName, "ALL\n");
  846.         }
  847.       }
  848.  
  849.       outloc = 0;
  850.       do {
  851.         if (buffer[inloc] == 2) {
  852.           i = inloc + 1;
  853.           for (j = 1; j < 80; j++) {
  854.             if ((buffer[i] == '\r') ||
  855.                 (i > nhr.length))
  856.               break;
  857.             i++;
  858.           }
  859.           if (j < 80) {
  860.             i = (80 - j) / 2;
  861.             for (j = 1; j <= i; j++)
  862.               text[outloc++] = ' ';
  863.           }
  864.           inloc++;
  865.         } else
  866.           if (buffer[inloc] == 3)
  867.           inloc += 2;
  868.         else
  869.           if ((buffer[inloc] == 4) && ((buffer[inloc + 1] >= 48) && (buffer[inloc + 1] <= 57)))
  870.             inloc += 2;
  871.         else
  872.           if (buffer[inloc] >= 127) {
  873.           inloc++;
  874.         } else
  875.           if (buffer[inloc] == 1)
  876.           inloc++;
  877.         else
  878.           text[outloc++] = buffer[inloc++];
  879.       } while (inloc < nhr.length);
  880.  
  881.       text[outloc] = '\0';
  882.  
  883.       switch (nhr.main_type) {
  884.         case main_type_email:
  885.         case main_type_email_name:
  886.         case main_type_ssm:
  887.           i = 1;
  888.           sprintf(outfn, "%sMQUEUE\\MSG.%d", net_data, i);
  889.           while (exist(outfn))
  890.             sprintf(outfn, "%sMQUEUE\\MSG.%d", net_data, ++i);
  891.           break;
  892.         case main_type_new_post:
  893.         case main_type_post:
  894.         case main_type_pre_post:
  895.           i = 1;
  896.           strcpy(tempoutfn, hold);
  897.           sprintf(outfn, "%sOUTBOUND\\%s.%d", net_data, tempoutfn, i);
  898.           while (exist(outfn))
  899.             sprintf(outfn, "%sOUTBOUND\\%s.%d", net_data, tempoutfn, ++i);
  900.           break;
  901.         default:
  902.           continue;
  903.       }
  904.  
  905.       fprintf(stderr, "\n ■ Creating: %s", outfn);
  906.       fprintf(stderr, "\n ■ From    : %s", mh.fromUserName);
  907.       if ((nhr.main_type == main_type_post) ||
  908.           (nhr.main_type == main_type_pre_post) ||
  909.           (nhr.main_type == main_type_new_post)) {
  910.         sprintf(fn1, "%sNEWS.RC", net_data);
  911.         fp = fsh_open(fn1, "rt");
  912.         if (!fp)
  913.           fprintf(stderr, "\n ■ %s not found!", fn1);
  914.         else {
  915.           ok = 0;
  916.           while ((fgets(_temp_buffer, 80, fp) != NULL) && (!ok)) {
  917.             groupname[0] = 0;
  918.             ss = strtok(_temp_buffer, " ");
  919.             if (ss) {
  920.               strcpy(groupname, ss);
  921.               ss = strtok(NULL, " ");
  922.               ss = strtok(NULL, "\r");
  923.               if (nhr.main_type == main_type_new_post) {
  924.                 strcpy(alphatype, ss);
  925.                 if (strncmpi(alphasubtype, alphatype, strlen(alphasubtype)) == 0)
  926.                   ok = 1;
  927.               } else {
  928.                 ttype = atoi(ss);
  929.                 if (ttype == stype)
  930.                   ok = 1;
  931.               }
  932.             }
  933.           }
  934.           *ss = NULL;
  935.           fclose(fp);
  936.         }
  937.       }
  938.       if ((nhr.main_type == main_type_email) ||
  939.           (nhr.main_type == main_type_email_name) ||
  940.           (nhr.main_type == main_type_ssm)) {
  941.         fprintf(stderr, "\n ■ To      : %s", strlwr(mh.toUserName));
  942.       } else {
  943.         if (groupname[0] == 0)
  944.           fprintf(stderr, "\n ■ No match for subtype %u in NEWS.RC", stype);
  945.         else
  946.           fprintf(stderr, "\n ■ Post to : %s", groupname);
  947.       }
  948.  
  949.       fprintf(stderr, "\n ■ Subject : %s", mh.subject);
  950.  
  951.       outfile = sh_open(outfn, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC | O_EXCL, S_IWRITE);
  952.       if (outfile == -1) {
  953.         if (buffer)
  954.           free(buffer);
  955.         if (text)
  956.           free(text);
  957.         fprintf(stderr, "\n ■ Unable to open output file %s", outfn);
  958.         return (1);
  959.       }
  960.       time(&some);
  961.       time_msg = localtime(&some);
  962.       strftime(mh.dateTime, 80, "%a, %d %b %y %H:%M:%S (%Z)", time_msg);
  963.       for (j = 0; j < strlen(mh.fromUserName); j++)
  964.         if (mh.fromUserName[j] == ' ')
  965.           mh.fromUserName[j] = '_';
  966.       if ((spam) && ((nhr.main_type == main_type_post) || (nhr.main_type == main_type_new_post)))
  967.         if (spamname[0] == 0)
  968.           sprintf(_temp_buffer, "From: %s@dont.spam.me.%s (%s)\n",
  969.                   POPNAME, DOMAIN,
  970.                   mh.fromUserName);
  971.         else
  972.           sprintf(_temp_buffer, "From: %s (%s)\n",
  973.                   spamname,
  974.                   mh.fromUserName);
  975.       else
  976.         sprintf(_temp_buffer, "From: %s@%s (%s)\n",
  977.                 POPNAME, DOMAIN, mh.fromUserName);
  978.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  979.       delay(2000);
  980.       sprintf(_temp_buffer, "Message-ID: <%lx-%s@%s>\n",
  981.               time(NULL), POPNAME, DOMAIN);
  982.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  983.       if ((nhr.main_type == main_type_email) ||
  984.           (nhr.main_type == main_type_email_name) ||
  985.           (nhr.main_type == main_type_ssm)) {
  986.         sprintf(_temp_buffer, "To: %s\n",
  987.                 mh.toUserName);
  988.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  989.       } else {
  990.         sprintf(_temp_buffer, "Newsgroups: %s\n", groupname);
  991.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  992.       }
  993.       sprintf(_temp_buffer, "Subject: %s\n", mh.subject);
  994.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  995.       sprintf(_temp_buffer, "Date: %s\n", mh.dateTime);
  996.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  997.       sprintf(_temp_buffer, "Organization: %s * @%hu.%s * %s\n",
  998.               syscfg.systemname, net_sysnum, net_name, syscfg.systemphone);
  999.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1000.       if ((!spam) && ((nhr.main_type != main_type_post) || (nhr.main_type != main_type_new_post))) {
  1001.         sprintf(_temp_buffer, "Reply-To: %s@%s (%s)\n",
  1002.                 POPNAME, DOMAIN, mh.fromUserName);
  1003.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1004.       }
  1005.       sprintf(_temp_buffer, "Version: WWIV PPP Project %s\n\n", VERSION);
  1006.       sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1007.  
  1008.       if ((spam) && ((nhr.main_type == main_type_post) || (nhr.main_type == main_type_new_post))) {
  1009.         sprintf(_temp_buffer, "Reply to: %s@%s (%s)\n\n",
  1010.                 POPNAME, DOMAIN, mh.fromUserName);
  1011.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1012.       }
  1013.       if ((nhr.main_type != main_type_email) &&
  1014.           (nhr.main_type != main_type_email_name) &&
  1015.           (strncmp(mh.toUserName, "ALL", 3) != 0)) {
  1016.         sprintf(_temp_buffer, "Responding to: %s\n", mh.toUserName);
  1017.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1018.       }
  1019.       sh_write(outfile, text, strlen(text));
  1020.  
  1021.       sprintf(tagfn, "%sI%u.TAG", syscfg.datadir, stype);
  1022.       if (exist(tagfn))
  1023.         strcpy(tagfile, tagfn);
  1024.       tagfn[0] = 0;
  1025.       ns = 0;
  1026.       for (i6 = 0; i6 < 99; i6++) {
  1027.         sprintf(tagfn, "%sI%u.T%d", syscfg.datadir, i6);
  1028.         if (exist(tagfn))
  1029.           ns++;
  1030.         else
  1031.           break;
  1032.       }
  1033.       sprintf(tagfn, "%sI%u.T%d", syscfg.datadir, random(ns));
  1034.       if (exist(tagfn))
  1035.         strcpy(tagfile, tagfn);
  1036.       if (tagfile[0] == 0) {
  1037.         sprintf(_temp_buffer, "\n\nOrigin: %s * %s * @%hu.FILEnet\n\n",
  1038.                 syscfg.systemname, syscfg.systemphone, net_sysnum);
  1039.         sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1040.       } else {
  1041.         fp = fsh_open(tagfile, "rt");
  1042.         if (!fp)
  1043.           fprintf(stderr, "\n ■ Error reading %s.", tagfile);
  1044.         else {
  1045.           sprintf(_temp_buffer, "\n\n");
  1046.           sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1047.           while (fgets(_temp_buffer, 120, fp)) {
  1048.             for (i = 0; ((i < strlen(_temp_buffer)) &&
  1049.                (_temp_buffer[i] != '\r') && (_temp_buffer[i] != '\n')); i++)
  1050.               if ((_temp_buffer[i] < 32) || (_temp_buffer[i] > 126))
  1051.                 _temp_buffer[i] = 32;
  1052.             sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1053.           }
  1054.           fclose(fp);
  1055.           sprintf(_temp_buffer, "\n\n");
  1056.           sh_write(outfile, _temp_buffer, strlen(_temp_buffer));
  1057.         }
  1058.       }
  1059.       sh_close(outfile);
  1060.     } else {
  1061.       if ((nhr.main_type >= 0x01) && (nhr.main_type <= 0x1b))
  1062.          fprintf(stderr, "\n ■ %s message skipped",
  1063.            main_type[nhr.main_type - 1]);
  1064.       else
  1065.         fprintf(stderr, "\n ■ Unknown Main_type %hd skipped", nhr.main_type);
  1066.     }
  1067.   }
  1068.   sh_close(infile);
  1069.   unlink(fn);
  1070.   if (text)
  1071.     free(text);
  1072.   if (buffer)
  1073.     free(buffer);
  1074.   return (0);
  1075. }
  1076.  
  1077. void get_dir(char *s, int be)
  1078. {
  1079.   strcpy(s, "X:\\");
  1080.   s[0] = 'A' + getdisk();
  1081.   getcurdir(0, s + 3);
  1082.   if (be) {
  1083.     if (s[strlen(s) - 1] != '\\')
  1084.       strcat(s, "\\");
  1085.   }
  1086. }
  1087.  
  1088. int main(int argc, char *argv[])
  1089. {
  1090.   char fn[MAXPATH], *ss;
  1091.   int f, f1, maxmail, i;
  1092.   struct ffblk ff;
  1093.  
  1094.   /* 0      1               2          3          4       5        6       */
  1095.   /* exp s32767.net,      net_data, net_sysnum, popname, domain, net_name  */
  1096.   /* exp netlog/contact,  net_data,   sysnum,     sent    recd   totaltime */
  1097.  
  1098.   fprintf(stderr, "\n ■ PPP Import/Export %s", VERSION);
  1099.   if (argc != 7) {
  1100.     fprintf(stderr, "\n ■ EXP <filename> <net_data> <net_sysnum> <POPNAME> <DOMAIN> <net_name>\n\n");
  1101.     if (argc > 1) {
  1102.       fprintf(stderr, "Command line was: ");
  1103.       for (i = 0; i < argc; i++)
  1104.         fprintf(stderr, "%s ", argv[i]);
  1105.       fprintf(stderr, "\n\n");
  1106.     }
  1107.     return (1);
  1108.   }
  1109.   if (get_nb_version())
  1110.     multitasker = 8;
  1111.   else
  1112.     detect_multitask();
  1113.   switch (multitasker) {
  1114.     case 1:
  1115.       get_dv_version();
  1116.       break;
  1117.     case 2:
  1118.       get_win_version();
  1119.       break;
  1120.     case 3:
  1121.       get_dv_version();
  1122.       break;
  1123.     case 4:
  1124.     case 5:
  1125.     case 6:
  1126.     case 7:
  1127.       break;
  1128.     case 8:
  1129.       multitasker = 1;
  1130.       break;
  1131.     default:
  1132.       break;
  1133.   }
  1134.   get_dir(maindir, 1);
  1135.   strcpy(net_data, argv[2]);
  1136.   sprintf(fn, "%s%s", net_data, argv[1]);
  1137.   net_name = argv[6];
  1138.   strcpy(POPNAME, argv[4]);
  1139.   strcpy(DOMAIN, argv[5]);
  1140.   net_sysnum = atoi(argv[3]);
  1141.   tagfile[0] = 0;
  1142.   spam = 0;
  1143.  
  1144.   f = sh_open1("CONFIG.DAT", O_RDONLY | O_BINARY);
  1145.   if (f < 0) {
  1146.     fprintf(stderr, "Could not open CONFIG.DAT!\n\n");
  1147.     return (1);
  1148.   }
  1149.   sh_read(f, (void *) &syscfg, sizeof(configrec));
  1150.   sh_close(f);
  1151.  
  1152.   ss = getenv("WWIV_INSTANCE");
  1153.   if (ss) {
  1154.     instance = atoi(ss);
  1155.     if (instance >= 1000) {
  1156.       fprintf(stderr, "\n ■ WWIV_INSTANCE set to %hd.  Can only be 1..999!",
  1157.               instance);
  1158.       instance = 1;
  1159.     }
  1160.   } else
  1161.     instance = 1;
  1162.  
  1163.   parse_net_ini();
  1164.  
  1165.   fprintf(stderr, "\n ■ Postmaster default account set to %s #%hd.",
  1166.           strupr(postmaster), defuser);
  1167.   fprintf(stderr, "\n ■ Using user %s on outbound Internet mail.",
  1168.           use_alias ? "aliases" : "real names");
  1169.   if (spam)
  1170.     fprintf(stderr, "\n ■ Using bogus originating address on newsgroup posts.");
  1171.   if (tagfile[0] != 0)
  1172.     fprintf(stderr, "\n ■ Using signature file : %s", tagfile);
  1173.  
  1174.   export(fn);
  1175.  
  1176.   sprintf(fn, "%sSPOOL\\UNK*.*", net_data);
  1177.   f1 = findfirst(fn, &ff, 0);
  1178.   maxmail = 14;
  1179.   while ((f1 == 0) && maxmail) {
  1180.     sprintf(fn, "%sSPOOL\\%s", net_data, ff.ff_name);
  1181.     if (!import(fn)) {
  1182.       unlink(fn);
  1183.       --maxmail;
  1184.     }
  1185.     f1 = findnext(&ff);
  1186.   }
  1187.   return 0;
  1188. }
  1189.