home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / MESSAGE.C < prev    next >
Text File  |  1998-05-17  |  103KB  |  3,354 lines

  1.  
  2. // LoraBBS Version 2.41 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22. #include <stdlib.h>
  23. #include <dir.h>
  24. #include <io.h>
  25. #include <fcntl.h>
  26. #include <dos.h>
  27. #include <sys\stat.h>
  28.  
  29. #include <cxl\cxlvid.h>
  30. #include <cxl\cxlwin.h>
  31. #include <cxl\cxlstr.h>
  32.  
  33. #include "lsetup.h"
  34. #include "sched.h"
  35. #include "msgapi.h"
  36. #include "externs.h"
  37. #include "prototyp.h"
  38.  
  39. extern int maxakainfo, msg_parent, msg_child;
  40. extern char *internet_to;
  41. extern struct _akainfo *akainfo;
  42.  
  43. extern struct _node2name *nametable; // Gestione nomi per aree PRIVATE
  44. extern int nodes_num;
  45.  
  46. int track_outbound_messages (FILE *fpd, struct _msg *msgt, int fzone, int fpoint, int tzone, int tpoint);
  47. int check_hold (int zone, int net, int node, int point);
  48. FILE *mopen (char *filename, char *mode);
  49. int mclose (FILE *fp);
  50. int mputs (char *s, FILE *fp);
  51. void mprintf (FILE *fp, char *format, ...);
  52. long mseek (FILE *fp, long position, int offset);
  53. int mread (char *s, int n, int e, FILE *fp);
  54. void process_areafix_request (FILE *, int, int, int, int, char *);
  55. void process_raid_request (FILE *, int, int, int, int, char *);
  56. void replace_tearline (FILE *fpd, char *buf);
  57. int open_packet (int zone, int net, int node, int point, int ai);
  58.  
  59. struct _msgzone {
  60.    short dest_zone;
  61.    short orig_zone;
  62.    short dest_point;
  63.    short orig_point;
  64. };
  65.  
  66. void scan_message_base(area, upd)
  67. int area;
  68. char upd;
  69. {
  70.    int i, first, last;
  71.    char filename[80], *p;
  72.    struct ffblk blk;
  73.  
  74.    num_msg = 0;
  75.    first = 0;
  76.    last = 0;
  77.    msg_parent = msg_child = 0;
  78.  
  79.    sprintf(filename, "%s*.MSG", sys.msg_path);
  80.  
  81.    if (!findfirst(filename, &blk, 0))
  82.       do {
  83.          if ((p = strchr(blk.ff_name,'.')) != NULL)
  84.             *p = '\0';
  85.  
  86.          i = atoi(blk.ff_name);
  87.             if (last < i || !last)
  88.             last = i;
  89.          if (first > i || !first)
  90.             first = i;
  91.          num_msg++;
  92.       } while (!findnext(&blk));
  93.  
  94.    num_msg = num_msg;
  95.    first_msg = first;
  96.    last_msg = last;
  97.  
  98.    for (i=0;i<MAXLREAD;i++)
  99.       if (usr.lastread[i].area == area)
  100.          break;
  101.    if (i != MAXLREAD) {
  102.       if (usr.lastread[i].msg_num > last_msg)
  103.          usr.lastread[i].msg_num = last_msg;
  104.       lastread = usr.lastread[i].msg_num;
  105.    }
  106.    else {
  107.       for (i=0;i<MAXDLREAD;i++)
  108.          if (usr.dynlastread[i].area == area)
  109.             break;
  110.       if (i != MAXDLREAD) {
  111.          if (usr.dynlastread[i].msg_num > last_msg)
  112.             usr.dynlastread[i].msg_num = last_msg;
  113.          lastread = usr.dynlastread[i].msg_num;
  114.       }
  115.       else if (upd) {
  116.          lastread = 0;
  117.          for (i=1;i<MAXDLREAD;i++) {
  118.             usr.dynlastread[i-1].area = usr.dynlastread[i].area;
  119.             usr.dynlastread[i-1].msg_num = usr.dynlastread[i].msg_num;
  120.          }
  121.  
  122.          usr.dynlastread[i-1].area = area;
  123.          usr.dynlastread[i-1].msg_num = 0;
  124.       }
  125.       else
  126.          lastread = 0;
  127.    }
  128.  
  129.    if (lastread < 0)
  130.       lastread = 0;
  131. }
  132.  
  133. #ifndef POINT
  134. void read_forward(start,pause)
  135. int start,pause;
  136. {
  137.    int i;
  138.  
  139.    if (msg_list != NULL) {
  140.       free (msg_list);
  141.       msg_list = NULL;
  142.    }
  143.  
  144.    if (start < 0)
  145.       start = 0;
  146.  
  147.    if (start < last_msg)
  148.       start++;
  149.    else {
  150.       m_print(bbstxt[B_NO_MORE_MESSAGE]);
  151.       return;
  152.    }
  153.  
  154.    if (sys.quick_board || sys.gold_board)
  155.       while (!quick_read_message(start,pause,0)) {
  156.          if (start < last_msg)
  157.             start++;
  158.          else
  159.             break;
  160.       }
  161.    else if (sys.pip_board)
  162.       while (!pip_msg_read(sys.pip_board, start, 0, pause,0)) {
  163.          if (start < last_msg)
  164.             start++;
  165.          else
  166.             break;
  167.       }
  168.    else if (sys.squish)
  169.       while (!squish_read_message (start, pause,0)) {
  170.          if (start < last_msg)
  171.             start++;
  172.          else
  173.             break;
  174.       }
  175.     else {
  176.       while (!read_message(start,pause,0)) {
  177.          if (start < last_msg)
  178.             start++;
  179.          else
  180.             break;
  181.       }
  182.    }
  183.  
  184.    lastread = start;
  185.  
  186.    for (i=0;i<MAXLREAD;i++)
  187.       if (usr.lastread[i].area == usr.msg)
  188.          break;
  189.    if (i != MAXLREAD)
  190.       usr.lastread[i].msg_num = start;
  191.    else {
  192.       for (i=0;i<MAXDLREAD;i++)
  193.          if (usr.dynlastread[i].area == usr.msg)
  194.             break;
  195.       if (i != MAXDLREAD)
  196.          usr.dynlastread[i].msg_num = start;
  197.    }
  198. }
  199.  
  200. void read_nonstop()
  201. {
  202.    int start;
  203.  
  204.    start = lastread;
  205.  
  206.    while (start < last_msg && !RECVD_BREAK() && CARRIER) {
  207.       if (local_mode && local_kbd == 0x1B)
  208.          break;
  209.       read_forward(start,1);
  210.       start = lastread;
  211.       if (time_remain () <= 0)
  212.          break;
  213.       time_release ();
  214.    }
  215. }
  216.  
  217. void read_backward(start)
  218. int start;
  219. {
  220.    int i;
  221.  
  222.    if (msg_list != NULL) {
  223.       free (msg_list);
  224.       msg_list = NULL;
  225.    }
  226.  
  227.    if (start > first_msg)
  228.       start--;
  229.    else {
  230.       m_print(bbstxt[B_NO_MORE_MESSAGE]);
  231.       return;
  232.    }
  233.  
  234.    if (sys.quick_board || sys.gold_board)
  235.       while (!quick_read_message(start,0,0)) {
  236.          if (start < last_msg)
  237.             start++;
  238.          else
  239.             break;
  240.       }
  241.    else if (sys.pip_board)
  242.       while (!pip_msg_read(sys.pip_board, start, 0, 0,0)) {
  243.          if (start < last_msg)
  244.             start++;
  245.          else
  246.             break;
  247.       }
  248.    else if (sys.squish)
  249.       while (!squish_read_message (start, 0,0)) {
  250.          if (start < last_msg)
  251.             start++;
  252.          else
  253.             break;
  254.       }
  255.    else {
  256.       while (!read_message(start,0,0)) {
  257.          if (start > 1)
  258.             start--;
  259.          else
  260.             break;
  261.       }
  262.    }
  263.  
  264.    lastread = start;
  265.  
  266.    for (i=0;i<MAXLREAD;i++)
  267.       if (usr.lastread[i].area == usr.msg)
  268.          break;
  269.    if (i != MAXLREAD)
  270.       usr.lastread[i].msg_num = start;
  271.    else {
  272.       for (i=0;i<MAXDLREAD;i++)
  273.          if (usr.dynlastread[i].area == usr.msg)
  274.             break;
  275.       if (i != MAXDLREAD)
  276.          usr.dynlastread[i].msg_num = start;
  277.    }
  278. }
  279.  
  280. void read_parent (void)
  281. {
  282.    int i, start = msg_parent;
  283.  
  284.    if (msg_list != NULL) {
  285.       free (msg_list);
  286.       msg_list = NULL;
  287.    }
  288.  
  289.    if (start < 1 || start > last_msg) {
  290.       m_print(bbstxt[B_NO_MORE_MESSAGE]);
  291.       return;
  292.    }
  293.  
  294.    if (sys.quick_board || sys.gold_board) {
  295.       start--;
  296.       if (!quick_read_message (start, 0, 0))
  297.          start = lastread;
  298.    }
  299.    else if (sys.pip_board) {
  300.       if (!pip_msg_read(sys.pip_board, start, 0, 0, 0))
  301.          start = lastread;
  302.    }
  303.    else if (sys.squish) {
  304.       if (!squish_read_message (start, 0, 0))
  305.          start = lastread;
  306.    }
  307.     else {
  308.       if (!read_message (start, 0, 0))
  309.          start = lastread;
  310.    }
  311.  
  312.    lastread = start;
  313.  
  314.    for (i = 0; i < MAXLREAD; i++)
  315.       if (usr.lastread[i].area == usr.msg)
  316.          break;
  317.    if (i != MAXLREAD)
  318.       usr.lastread[i].msg_num = start;
  319.    else {
  320.       for (i = 0; i < MAXDLREAD; i++)
  321.          if (usr.dynlastread[i].area == usr.msg)
  322.             break;
  323.       if (i != MAXDLREAD)
  324.          usr.dynlastread[i].msg_num = start;
  325.    }
  326. }
  327.  
  328. void read_reply (void)
  329. {
  330.    int i, start = msg_child;
  331.  
  332.    if (msg_list != NULL) {
  333.       free (msg_list);
  334.       msg_list = NULL;
  335.    }
  336.  
  337.    if (start < 1 || start > last_msg) {
  338.       m_print(bbstxt[B_NO_MORE_MESSAGE]);
  339.       return;
  340.    }
  341.  
  342.    if (sys.quick_board || sys.gold_board) {
  343.       start--;
  344.       if (!quick_read_message (start, 0, 0))
  345.          start = lastread;
  346.    }
  347.    else if (sys.pip_board) {
  348.       if (!pip_msg_read(sys.pip_board, start, 0, 0, 0))
  349.          start = lastread;
  350.    }
  351.     else if (sys.squish) {
  352.       if (!squish_read_message (start, 0, 0))
  353.          start = lastread;
  354.    }
  355.    else {
  356.       if (!read_message (start, 0, 0))
  357.          start = lastread;
  358.    }
  359.  
  360.    lastread = start;
  361.  
  362.    for (i = 0; i < MAXLREAD; i++)
  363.       if (usr.lastread[i].area == usr.msg)
  364.          break;
  365.    if (i != MAXLREAD)
  366.       usr.lastread[i].msg_num = start;
  367.    else {
  368.       for (i = 0; i < MAXDLREAD; i++)
  369.          if (usr.dynlastread[i].area == usr.msg)
  370.             break;
  371.       if (i != MAXDLREAD)
  372.          usr.dynlastread[i].msg_num = start;
  373.    }
  374. }
  375.  
  376. void msg_kill()
  377. {
  378.    int i, m;
  379.    char stringa[10];
  380.  
  381.    if (!num_msg) {
  382.       if (sys.quick_board || sys.gold_board)
  383.          quick_scan_message_base (sys.quick_board, sys.gold_board, usr.msg, 1);
  384.       else if (sys.pip_board)
  385.          pip_scan_message_base (usr.msg, 1);
  386.       else if (sys.squish)
  387.          squish_scan_message_base (usr.msg, sys.msg_path, 1);
  388.       else
  389.          scan_message_base(usr.msg, 1);
  390.    }
  391.  
  392.    for (;;) {
  393.       if (!get_command_word (stringa, 4)) {
  394.          m_print (bbstxt[B_MSG_DELETE]);
  395.             chars_input(stringa, 4, INPUT_FIELD);
  396.       }
  397.  
  398.       if (!stringa[0])
  399.          break;
  400.  
  401.       i = atoi (stringa);
  402.  
  403.       if (i >= first_msg && i <= last_msg) {
  404.          if (sys.quick_board)
  405.             m = quick_kill_message (i, 0);
  406.          else if (sys.gold_board)
  407.             m = quick_kill_message (i, 1);
  408.          else if (sys.pip_board)
  409.             m = pip_kill_message (i);
  410.          else if (sys.squish)
  411.             m = squish_kill_message (i);
  412.          else
  413.             m = kill_message (i);
  414.  
  415.          if (!m)
  416.             m_print (bbstxt[B_CANT_KILL], i);
  417.          else {
  418.             m_print (bbstxt[B_MSG_REMOVED], i);
  419.             if (i == last_msg)
  420.                last_msg--;
  421.          }
  422.       }
  423.    }
  424.  
  425. /*
  426.    if (sys.quick_board || sys.gold_board)
  427.       quick_scan_message_base (sys.quick_board, sys.gold_board, usr.msg, 1);
  428.    else if (sys.pip_board)
  429.       pip_scan_message_base (usr.msg, 1);
  430.    else if (sys.squish)
  431.       squish_scan_message_base (usr.msg, sys.msg_path, 1);
  432.    else
  433.       scan_message_base (usr.msg, 1);
  434. */
  435. }
  436.  
  437. int kill_message(msg_num)
  438. int msg_num;
  439. {
  440.    int fd;
  441.    char buff[80];
  442.    struct _msg msgt;
  443.  
  444.    sprintf (buff, "%s%d.MSG", sys.msg_path, msg_num);
  445.    fd = open (buff, O_RDONLY|O_BINARY);
  446.    if (fd == -1)
  447.       return (0);
  448.  
  449.    read (fd, (char *)&msgt, sizeof(struct _msg));
  450.    close (fd);
  451.  
  452.    if (!stricmp (msgt.from, usr.name) || !stricmp (msgt.to, usr.name) || !stricmp (msgt.from, usr.handle) || !stricmp (msgt.to, usr.handle) || usr.priv == SYSOP) {
  453.       unlink (buff);
  454.         return (1);
  455.     }
  456.  
  457.     return (0);
  458. }
  459.  
  460.  
  461. int read_message(msg_num, flag, fakenum)
  462. int msg_num, flag, fakenum;
  463. {
  464.     FILE *fp;
  465.     int i, z, m, line, colf=0, shead;
  466.     char c, buff[150], wrp[150], *p, okludge;
  467.     long fpos;
  468.     struct _msg msgt;
  469.  
  470.     if (usr.full_read && !flag)
  471.         return(full_read_message(msg_num,fakenum));
  472.  
  473.     okludge = 0;
  474.     line = 1;
  475.     shead = 0;
  476.     msg_fzone = msg_tzone = config->alias[sys.use_alias].zone;
  477.    msg_fpoint = msg_tpoint = 0;
  478.  
  479.    sprintf(buff,"%s%d.MSG",sys.msg_path,msg_num);
  480.    i = sh_open (buff, SH_DENYWR, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  481.    if (i == -1)
  482.       return(0);
  483.  
  484.    fp = fdopen (i, "r+b");
  485.    if(fp == NULL)
  486.       return(0);
  487.  
  488.    fread((char *)&msgt,sizeof(struct _msg),1,fp);
  489.  
  490.    if (!stricmp(msgt.from,"ARCmail") && !stricmp(msgt.to,"Sysop")) {
  491.       fclose(fp);
  492.       return(0);
  493.    }
  494.  
  495.    if(msgt.attr & MSGPRIVATE) {
  496.       if(msg_num == 1 && sys.echomail) {
  497.          fclose(fp);
  498.          return(0);
  499.       }
  500.  
  501.       if (sys.netmail && usr.priv != SYSOP) {
  502.          for (i = 0; config->alias[i].net != 0 && i < MAX_ALIAS; i++) {
  503.             if (msgt.dest_net == config->alias[i].net && msgt.dest == config->alias[i].node)
  504.                break;
  505.          }
  506.          if (config->alias[i].net == 0 || i >= MAX_ALIAS) {
  507.             fclose (fp);
  508.             return (0);
  509.          }
  510.       }
  511.  
  512.       if (stricmp (msgt.from, usr.name) && stricmp (msgt.to, usr.name) && stricmp (msgt.from, usr.handle) && stricmp (msgt.to, usr.handle) && usr.priv != SYSOP) {
  513.          fclose (fp);
  514.          return (0);
  515.       }
  516.    }
  517.  
  518.    if (!flag)
  519.       cls();
  520.  
  521.    memcpy((char *)&msg,(char *)&msgt,sizeof(struct _msg));
  522.    msg_parent = msg.reply;
  523.    msg_child = msg.up;
  524.  
  525.    if(flag)
  526.       m_print(bbstxt[B_TWO_CR]);
  527.  
  528.    change_attr (WHITE|_BLACK);
  529.    m_print (" * %s\n", sys.msg_name);
  530.  
  531.    change_attr(CYAN|_BLACK);
  532.  
  533.    allow_reply = 1;
  534.    i=0;
  535.    fpos = filelength(fileno(fp));
  536.  
  537.    while (ftell (fp) < fpos) {
  538.         c = fgetc (fp);
  539.  
  540.       if ((byte)c == 0x8D || c == 0x0A || c == '\0')
  541.          continue;
  542.  
  543.       buff[i++] = c;
  544.  
  545.       if (c == 0x0D) {
  546.          buff[i - 1] = '\0';
  547.  
  548.          if (buff[0] == 0x01 && !okludge) {
  549.                 if (!strncmp (&buff[1], "INTL", 4) && !shead)
  550.                     sscanf (&buff[6], "%d:%d/%d %d:%d/%d", &msg_tzone, &i, &i, &msg_fzone, &i, &i);
  551.                 if (!strncmp(&buff[1], "TOPT", 4) && !shead)
  552.                sscanf (&buff[6], "%d", &msg_tpoint);
  553.                 if (!strncmp (&buff[1], "FMPT", 4) && !shead)
  554.                     sscanf (&buff[6], "%d", &msg_fpoint);
  555.             i = 0;
  556.             continue;
  557.          }
  558.          else if (!shead) {
  559.             if (sys.internet_mail && !strnicmp (buff, "To:", 3)) {
  560.                strtok (buff, ":");
  561.                if ((p = strtok (NULL, ": ")) != NULL) {
  562.                   if (strlen (p) > 35)
  563.                      p[35] = '\0';
  564.                   strcpy (msgt.to, p);
  565.                }
  566.                line = msg_attrib (&msgt, msg_num, line, 0);
  567.                m_print(bbstxt[B_ONE_CR]);
  568.                shead = 1;
  569.                i = 0;
  570.                continue;
  571.             }
  572.             line = msg_attrib (&msgt, fakenum ? fakenum : msg_num, line, 0);
  573.             m_print(bbstxt[B_ONE_CR]);
  574.             shead = 1;
  575.             okludge = 1;
  576.             fseek (fp, (long)sizeof (struct _msg), SEEK_SET);
  577.             i = 0;
  578.             continue;
  579.          }
  580.  
  581.          if (!usr.kludge && (!strncmp (buff, "SEEN-BY", 7) || buff[0] == 0x01)) {
  582.                 i = 0;
  583.             continue;
  584.          }
  585.  
  586.          if (buff[0] == 0x01) {
  587.             m_print (" %s\n", &buff[1]);
  588.             change_attr (LGREY|BLACK);
  589.          }
  590.          else if (!strncmp (buff, "SEEN-BY", 7)) {
  591.             m_print (" %s\n", buff);
  592.             change_attr (LGREY|BLACK);
  593.          }
  594.          else {
  595.             p = &buff[0];
  596.  
  597.             if(((strchr(buff,'>') - p) < 6) && (strchr(buff,'>'))) {
  598.                if(!colf) {
  599.                   change_attr(LGREY|BLACK);
  600.                   colf=1;
  601.                }
  602.             }
  603.             else {
  604.                if(colf) {
  605.                   change_attr(CYAN|BLACK);
  606.                   colf=0;
  607.                }
  608.             }
  609.  
  610.             if (!strncmp(buff,msgtxt[M_TEAR_LINE],4) || !strncmp(buff," * Origin: ",11))
  611.                m_print("%s\n",buff);
  612.             else
  613.                m_print("%s\n",buff);
  614.  
  615.             if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  616.                gather_origin_netnode (buff);
  617.          }
  618.  
  619.          i=0;
  620.  
  621.          if(flag == 1)
  622.             line=1;
  623.  
  624.          if(!(++line < (usr.len-1)) && usr.more) {
  625.             line = 1;
  626.                 if(!continua()) {
  627.                flag=1;
  628.                break;
  629.             }
  630.          }
  631.       }
  632.       else {
  633.          if(i<(usr.width-1))
  634.             continue;
  635.  
  636.          buff[i]='\0';
  637.          while(i>0 && buff[i] != ' ')
  638.             i--;
  639.  
  640.          m=0;
  641.  
  642.          if(i != 0) {
  643.             for(z=i+1; buff[z]; z++)
  644.                wrp[m++]=buff[z];
  645.          }
  646.  
  647.          buff[i]='\0';
  648.          wrp[m]='\0';
  649.  
  650.          if (!shead) {
  651.             line = msg_attrib(&msgt,fakenum ? fakenum : msg_num,line,0);
  652.             m_print(bbstxt[B_ONE_CR]);
  653.             shead = 1;
  654.             okludge = 1;
  655.             fseek (fp, (long)sizeof (struct _msg), SEEK_SET);
  656.             i = 0;
  657.             continue;
  658.          }
  659.  
  660.          if (((strchr(buff,'>') - buff) < 6) && (strchr(buff,'>'))) {
  661.             if(!colf) {
  662.                change_attr(LGREY|_BLACK);
  663.                colf=1;
  664.             }
  665.          }
  666.          else {
  667.             if(colf) {
  668.                change_attr(CYAN|_BLACK);
  669.                colf=0;
  670.                 }
  671.          }
  672.  
  673.          if (!strncmp(buff,msgtxt[M_TEAR_LINE],4) || !strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  674.             m_print("%s\n",buff);
  675.          else
  676.             m_print("%s\n",buff);
  677.  
  678.          if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  679.             gather_origin_netnode (buff);
  680.  
  681.          if(flag == 1)
  682.             line=1;
  683.  
  684.          if(!(++line < (usr.len-1)) && usr.more) {
  685.             line = 1;
  686.             if(!continua()) {
  687.                flag=1;
  688.                break;
  689.             }
  690.          }
  691.  
  692.          strcpy(buff,wrp);
  693.          i=strlen(wrp);
  694.       }
  695.    }
  696.  
  697.    if ((!stricmp (msgt.to, usr.name) || !stricmp (msgt.to, usr.handle)) && !(msgt.attr & MSGREAD)) {
  698.       msgt.attr |= MSGREAD;
  699.       rewind(fp);
  700.       fwrite((char *)&msgt,sizeof(struct _msg),1,fp);
  701.    }
  702.  
  703.    fclose(fp);
  704.  
  705.    if (!shead) {
  706.       line = msg_attrib(&msgt,msg_num,line,0);
  707.       m_print(bbstxt[B_ONE_CR]);
  708.       shead = 1;
  709.    }
  710.  
  711.    if (line > 1 && !flag && usr.more) {
  712.       press_enter ();
  713.       line = 1;
  714.     }
  715.  
  716.    return (1);
  717. }
  718.  
  719. int full_read_message(msg_num,fakenum)
  720. int msg_num, fakenum;
  721. {
  722.         FILE *fp;
  723.         int i, z, m, line, colf=0, shead;
  724.         char c, buff[150], wrp[150], *p, okludge;
  725.         long fpos;
  726.         struct _msg msgt;
  727.  
  728.         okludge = 0;
  729.         line = 2;
  730.         shead = 0;
  731.           msg_fzone = msg_tzone = config->alias[sys.use_alias].zone;
  732.           msg_fpoint = msg_tpoint = 0;
  733.  
  734.         sprintf(buff,"%s%d.MSG",sys.msg_path,msg_num);
  735.         i = sh_open (buff, SH_DENYWR, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  736.         if (i == -1)
  737.                 return(0);
  738.  
  739.         fp = fdopen (i, "r+b");
  740.         if(fp == NULL)
  741.                 return(0);
  742.  
  743.         fread((char *)&msgt,sizeof(struct _msg),1,fp);
  744.  
  745.         if (!stricmp(msgt.from,"ARCmail") && !stricmp(msgt.to,"Sysop")) {
  746.                 fclose(fp);
  747.                 return(0);
  748.         }
  749.  
  750.         if(msgt.attr & MSGPRIVATE) {
  751.                 if(msg_num == 1 && sys.echomail) {
  752.                         fclose(fp);
  753.                         return(0);
  754.                 }
  755.  
  756.       if (sys.netmail && usr.priv != SYSOP) {
  757.          for (i = 0; config->alias[i].net != 0 && i < MAX_ALIAS; i++) {
  758.             if (msgt.dest_net == config->alias[i].net && msgt.dest == config->alias[i].node)
  759.                break;
  760.          }
  761.          if (config->alias[i].net == 0 || i >= MAX_ALIAS) {
  762.             fclose (fp);
  763.             return (0);
  764.          }
  765.       }
  766.  
  767.                 if(stricmp(msgt.from,usr.name) && stricmp(msgt.to,usr.name) && stricmp(msgt.from,usr.handle) && stricmp(msgt.to,usr.handle) && usr.priv != SYSOP) {
  768.                         fclose(fp);
  769.                                 return(0);
  770.                 }
  771.         }
  772.  
  773.         cls();
  774.  
  775.         memcpy((char *)&msg,(char *)&msgt,sizeof(struct _msg));
  776.         msg_parent = msg.reply;
  777.         msg_child = msg.up;
  778.  
  779.         change_attr(BLUE|_LGREY);
  780.         del_line();
  781.         m_print(" * %s\n", sys.msg_name);
  782.  
  783.         allow_reply = 1;
  784.         i=0;
  785.         fpos = filelength(fileno(fp));
  786.  
  787.         while(ftell(fp) < fpos) {
  788.                 c = fgetc(fp);
  789.  
  790.                 if((byte)c == 0x8D || c == 0x0A || c == '\0')
  791.                         continue;
  792.  
  793.                 buff[i++]=c;
  794.  
  795.                 if(c == 0x0D) {
  796.                         buff[i-1]='\0';
  797.  
  798.                         if (buff[0] == 0x01 && !okludge) {
  799.                                           if (!strncmp(&buff[1],"INTL",4) && !shead)
  800.                                                      sscanf(&buff[6],"%d:%d/%d %d:%d/%d",&msg_tzone,&i,&i,&msg_fzone,&i,&i);
  801.                                 if (!strncmp(&buff[1],"TOPT",4) && !shead)
  802.                                         sscanf(&buff[6],"%d",&msg_tpoint);
  803.                                 if (!strncmp(&buff[1],"FMPT",4) && !shead)
  804.                                         sscanf(&buff[6],"%d",&msg_fpoint);
  805.                                 i=0;
  806.                                 continue;
  807.                         }
  808.                         else if (!shead) {
  809.                                 if (sys.internet_mail && !strnicmp (buff, "To:", 3)) {
  810.                                    strtok (buff, ":");
  811.                                    if ((p = strtok (NULL, ": ")) != NULL) {
  812.                                       if (strlen (p) > 35)
  813.                                                       p[35] = '\0';
  814.                                       strcpy (msgt.to, p);
  815.                                    }
  816.                                    line = msg_attrib(&msgt,msg_num,line,0);
  817.                                    change_attr(LGREY|_BLUE);
  818.                                    del_line();
  819.                                    change_attr(CYAN|_BLACK);
  820.                                    m_print(bbstxt[B_ONE_CR]);
  821.                                    shead = 1;
  822.                                    i = 0;
  823.                                    continue;
  824.                                 }
  825.                                 line = msg_attrib(&msgt,fakenum ? fakenum : msg_num,line,0);
  826.                                 change_attr(LGREY|_BLUE);
  827.                                 del_line();
  828.                                 change_attr(CYAN|_BLACK);
  829.                                 m_print(bbstxt[B_ONE_CR]);
  830.                                 shead = 1;
  831.                                 okludge = 1;
  832.                                 fseek (fp, (long)sizeof (struct _msg), SEEK_SET);
  833.                                 i = 0;
  834.                                 continue;
  835.                         }
  836.  
  837.                         if (!usr.kludge && (!strncmp (buff, "SEEN-BY", 7) || buff[0] == 0x01)) {
  838.                            i = 0;
  839.                            continue;
  840.                         }
  841.  
  842.                         if (buff[0] == 0x01) {
  843.                                 m_print(" %s\n",&buff[1]);
  844.                                 change_attr(CYAN|BLACK);
  845.                         }
  846.                         else if (!strncmp (buff, "SEEN-BY", 7)) {
  847.                                 m_print (" %s\n", buff);
  848.                                 change_attr (LGREY|BLACK);
  849.                         }
  850.                         else {
  851.                                 p = &buff[0];
  852.  
  853.                                 if(((strchr(buff,'>') - p) < 6) && (strchr(buff,'>'))) {
  854.                                         if(!colf) {
  855.                                                 change_attr(LGREY|BLACK);
  856.                                                 colf=1;
  857.                                                      }
  858.                                 }
  859.                                 else {
  860.                                         if(colf) {
  861.                                                 change_attr(CYAN|BLACK);
  862.                                                 colf=0;
  863.                                         }
  864.                                 }
  865.  
  866.                                 if (!strncmp(buff,msgtxt[M_TEAR_LINE],4) || !strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  867.                                         m_print("%s\n",buff);
  868.                                 else
  869.                                         m_print("%s\n",buff);
  870.  
  871.                                 if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  872.                                         gather_origin_netnode (buff);
  873.                         }
  874.  
  875.                         i=0;
  876.  
  877.                         if(!(++line < (usr.len-1)) && usr.more) {
  878.                                 if(!continua()) {
  879.                                         line = 1;
  880.                                         break;
  881.                                 }
  882.                                 else {
  883.                                         while (line > 5) {
  884.                                                 cpos(line--, 1);
  885.                                                 del_line();
  886.                                         }
  887.                                 }
  888.                         }
  889.                 }
  890.                 else {
  891.                         if(i<(usr.width-1))
  892.                                 continue;
  893.  
  894.                         buff[i]='\0';
  895.                         while(i>0 && buff[i] != ' ')
  896.                                 i--;
  897.  
  898.                         m=0;
  899.  
  900.                         if(i != 0)
  901.                                           for(z=i+1;buff[z];z++)
  902.                                         wrp[m++]=buff[z];
  903.  
  904.                         buff[i]='\0';
  905.                         wrp[m]='\0';
  906.  
  907.                         if (!shead) {
  908.                                 line = msg_attrib(&msgt,fakenum ? fakenum : msg_num,line,0);
  909.                                 change_attr(LGREY|_BLUE);
  910.                                 del_line();
  911.                                 change_attr(CYAN|_BLACK);
  912.                                 m_print(bbstxt[B_ONE_CR]);
  913.                                 shead = 1;
  914.                                 okludge = 1;
  915.                                 fseek (fp, (long)sizeof (struct _msg), SEEK_SET);
  916.                                 i = 0;
  917.                                 continue;
  918.                         }
  919.  
  920.                         if (((strchr(buff,'>') - buff) < 6) && (strchr(buff,'>'))) {
  921.                                 if(!colf) {
  922.                                         change_attr(LGREY|_BLACK);
  923.                                         colf=1;
  924.                                 }
  925.                         }
  926.                         else {
  927.                                 if(colf) {
  928.                                         change_attr(CYAN|_BLACK);
  929.                                         colf=0;
  930.                                 }
  931.                         }
  932.  
  933.                         if (!strncmp(buff,msgtxt[M_TEAR_LINE],4) || !strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  934.                                 m_print("%s\n",buff);
  935.                         else
  936.                                 m_print("%s\n",buff);
  937.  
  938.                         if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  939.                                 gather_origin_netnode (buff);
  940.  
  941.                         if(!(++line < (usr.len-1)) && usr.more)
  942.                         {
  943.                                 if(!continua())
  944.                                 {
  945.                                                      line = 1;
  946.                                         break;
  947.                                 }
  948.                                 else
  949.                                 {
  950.                                         while (line > 5) {
  951.                                                 cpos(line--, 1);
  952.                                                 del_line();
  953.                                         }
  954.                                 }
  955.                         }
  956.  
  957.                         strcpy(buff,wrp);
  958.                         i=strlen(wrp);
  959.                 }
  960.         }
  961.  
  962.         if((!stricmp(msgt.to,usr.name) || !stricmp(msgt.to,usr.handle)) && !(msgt.attr & MSGREAD)) {
  963.                 msgt.attr |= MSGREAD;
  964.                 rewind(fp);
  965.                 fwrite((char *)&msgt,sizeof(struct _msg),1,fp);
  966.         }
  967.  
  968.         fclose(fp);
  969.  
  970.         if (!shead) {
  971.                 line = msg_attrib(&msgt,msg_num,line,0);
  972.                 m_print(bbstxt[B_ONE_CR]);
  973.                 shead = 1;
  974.         }
  975.  
  976.           if(line > 1 && usr.more) {
  977.                 press_enter();
  978.                 line=1;
  979.         }
  980.  
  981.         return(1);
  982. }
  983.  
  984. int msg_attrib(msg_ptr,s,line,f)
  985. struct _msg *msg_ptr;
  986. int s, line, f;
  987. {
  988.    char stringa[60], *pto;
  989.  
  990.    adjust_date(msg_ptr);
  991.  
  992.    m_print(bbstxt[B_FROM]);
  993.    if(sys.netmail || sys.internet_mail) {
  994.         if (!msg_fzone)
  995.             msg_fzone = config->alias[sys.use_alias].zone;
  996.         sprintf(stringa,"%-25.25s (%d:%d/%d.%d)",msg_ptr->from,msg_fzone,msg_ptr->orig_net,msg_ptr->orig,msg_fpoint);
  997.       m_print("%36s  ",stringa);
  998.    }
  999.    else
  1000.       m_print("%-36s  ",msg_ptr->from);
  1001.  
  1002.    change_attr(WHITE|_BLACK);
  1003.    if(msg_ptr->attr & MSGPRIVATE)
  1004.       m_print(bbstxt[B_MSGPRIVATE]);
  1005.    if(msg_ptr->attr & MSGREAD)
  1006.       m_print(bbstxt[B_MSGREAD]);
  1007.    if (sys.netmail || sys.internet_mail) {
  1008.       if(msg_ptr->attr & MSGCRASH)
  1009.          m_print(bbstxt[B_MSGCRASH]);
  1010.       if(msg_ptr->attr & MSGSENT)
  1011.             m_print(bbstxt[B_MSGSENT]);
  1012.       if(msg_ptr->attr & MSGFILE)
  1013.          m_print(bbstxt[B_MSGFILE]);
  1014.       if(msg_ptr->attr & MSGFWD)
  1015.          m_print(bbstxt[B_MSGFWD]);
  1016.       if(msg_ptr->attr & MSGORPHAN)
  1017.          m_print(bbstxt[B_MSGORPHAN]);
  1018.       if(msg_ptr->attr & MSGKILL)
  1019.          m_print(bbstxt[B_MSGKILL]);
  1020.       if(msg_ptr->attr & MSGHOLD)
  1021.          m_print(bbstxt[B_MSGHOLD]);
  1022.       if(msg_ptr->attr & MSGFRQ)
  1023.          m_print(bbstxt[B_MSGFRQ]);
  1024.       if(msg_ptr->attr & MSGRRQ)
  1025.          m_print(bbstxt[B_MSGRRQ]);
  1026.       if(msg_ptr->attr & MSGCPT)
  1027.          m_print(bbstxt[B_MSGCPT]);
  1028.       if(msg_ptr->attr & MSGARQ)
  1029.          m_print(bbstxt[B_MSGARQ]);
  1030.       if(msg_ptr->attr & MSGURQ)
  1031.          m_print(bbstxt[B_MSGURQ]);
  1032.    }
  1033.     m_print(bbstxt[B_ONE_CR]);
  1034.    if ((line=more_question(line)) == 0)
  1035.       return(0);
  1036.  
  1037.    if(!f) {
  1038.       if (!stricmp (msg_ptr->to, "@ALL"))
  1039.          pto = usr.name;
  1040.       else
  1041.          pto = msg_ptr->to;
  1042.  
  1043.       m_print(bbstxt[B_TO]);
  1044.       if(sys.netmail || sys.internet_mail) {
  1045.          if (!msg_tzone)
  1046.                 msg_tzone = config->alias[sys.use_alias].zone;
  1047.             if (sys.internet_mail && internet_to != NULL)
  1048.             sprintf(stringa,"%-25.25s (%d:%d/%d.%d)",internet_to,msg_tzone,msg_ptr->dest_net,msg_ptr->dest,msg_tpoint);
  1049.          else
  1050.             sprintf(stringa,"%-25.25s (%d:%d/%d.%d)",pto,msg_tzone,msg_ptr->dest_net,msg_ptr->dest,msg_tpoint);
  1051.          m_print("%36s  ",stringa);
  1052.       }
  1053.       else
  1054.          m_print("%-36s  ",pto,msg_ptr->dest_net,msg_ptr->dest);
  1055.  
  1056.       change_attr(WHITE|_BLACK);
  1057.       if (s)
  1058.          m_print("Msg: #%d, ",s);
  1059.       m_print("%s ",show_date(config->dateformat,stringa,msg_ptr->date_written.date,msg_ptr->date_written.time));
  1060.       m_print("%s\n",show_date(config->timeformat,stringa,msg_ptr->date_written.date,msg_ptr->date_written.time));
  1061.  
  1062.       if ((line=more_question(line)) == 0)
  1063.          return(0);
  1064.    }
  1065.  
  1066.    if(msg_ptr->attr & MSGFILE || msg_ptr->attr & MSGFRQ)
  1067.       m_print(bbstxt[B_SUBJFILES]);
  1068.    else
  1069.       m_print(bbstxt[B_SUBJECT]);
  1070.    m_print("%s\n",msg_ptr->subj);
  1071.    if ((line=more_question(line)) == 0)
  1072.       return(0);
  1073.  
  1074.    change_attr(CYAN|_BLACK);
  1075.  
  1076.    return(line);
  1077. }
  1078.  
  1079. void adjust_date(msg_ptr)
  1080. struct _msg *msg_ptr;
  1081. {
  1082.    int yr, mo, dy, hh, mm, ss;
  1083.    char month[4];
  1084.  
  1085.    sscanf(msg_ptr->date,"%2d %3s %2d  %2d:%2d:%2d",&dy,month,&yr,&hh,&mm,&ss);
  1086.    month[3]='\0';
  1087.  
  1088.    for(mo=0;mo<12;mo++)
  1089.       if(!stricmp(month,mtext[mo]))
  1090.          break;
  1091.  
  1092.    if(mo == 12)
  1093.       mo=0;
  1094.  
  1095.    msg_ptr->date_written.date=(yr-80)*512+(mo+1)*32+dy;
  1096.    msg_ptr->date_written.time=hh*2048+mm*32+ss/2;
  1097. }
  1098.  
  1099. char *show_date(par,buffer,date,time)
  1100. char *par, *buffer;
  1101. int date, time;
  1102. {
  1103.     int yr, mo, dy, hh, mm, ss, flag, i;
  1104.         char parola[80];
  1105.  
  1106.     yr=((date >> 9) & 0x7F)+80;
  1107.     mo=((date >> 5) & 0x0F)-1;
  1108.     mo=(mo < 0)?0:mo;
  1109.     mo=(mo > 11)?11:mo;
  1110.     dy=date & 0x1F;
  1111.     hh=(time >> 11) & 0x1F;
  1112.     mm=(time >> 5) & 0x3F;
  1113.     ss=(time & 0x1F)*2;
  1114.  
  1115.     buffer[0]='\0';
  1116.     flag=0;
  1117.  
  1118.     if(par == NULL)
  1119.         return(buffer);
  1120.  
  1121.     while(*par) {
  1122.         if(flag) {
  1123.             switch(toupper(*par)) {
  1124.             case 'A':
  1125.                 if(hh < 12)
  1126.                     strcat(buffer,"am");
  1127.                 else
  1128.                     strcat(buffer,"pm");
  1129.                 break;
  1130.             case 'B':
  1131.                 if(strlen(buffer))
  1132.                                         sprintf(parola,"%02d",mo + 1);
  1133.                 else
  1134.                                     sprintf(parola,"%2d",mo + 1);
  1135.                 strcat(buffer,parola);
  1136.                 break;
  1137.             case 'C':
  1138.                 strcat(buffer,mesi[mo]);
  1139.                 break;
  1140.             case 'D':
  1141.                 if(strlen(buffer))
  1142.                     sprintf(parola,"%02d",dy);
  1143.                 else
  1144.                     sprintf(parola,"%2d",dy);
  1145.                 strcat(buffer,parola);
  1146.                 break;
  1147.             case 'E':
  1148.                 if(strlen(buffer)) {
  1149.                     if(hh <= 12)
  1150.                         sprintf(parola,"%02d",hh);
  1151.                     else
  1152.                         sprintf(parola,"%02d",hh-12);
  1153.                 }
  1154.                 else {
  1155.                     if(hh <= 12)
  1156.                         sprintf(parola,"%2d",hh);
  1157.                     else
  1158.                         sprintf(parola,"%2d",hh-12);
  1159.                 }
  1160.                 strcat(buffer,parola);
  1161.                 break;
  1162.             case 'H':
  1163.                 if(strlen(buffer))
  1164.                     sprintf(parola,"%02d",hh);
  1165.                 else
  1166.                     sprintf(parola,"%2d",hh);
  1167.                 strcat(buffer,parola);
  1168.                 break;
  1169.             case 'M':
  1170.                 if(strlen(buffer))
  1171.                     sprintf(parola,"%02d",mm);
  1172.                 else
  1173.                     sprintf(parola,"%2d",mm);
  1174.                 strcat(buffer,parola);
  1175.                 break;
  1176.             case 'S':
  1177.                 if(strlen(buffer))
  1178.                     sprintf(parola,"%02d",ss);
  1179.                 else
  1180.                     sprintf(parola,"%2d",ss);
  1181.                 strcat(buffer,parola);
  1182.                 break;
  1183.             case 'Y':
  1184.                 if(strlen(buffer))
  1185.                     sprintf(parola,"%02d",yr);
  1186.                 else
  1187.                     sprintf(parola,"%2d",yr);
  1188.                 strcat(buffer,parola);
  1189.                 break;
  1190.             default:
  1191.                 i=strlen(buffer);
  1192.                 buffer[i]=*par;
  1193.                 buffer[i+1]='\0';
  1194.                 break;
  1195.             }
  1196.             flag=0;
  1197.         }
  1198.         else {
  1199.             if(*par == '%')
  1200.                 flag=1;
  1201.             else {
  1202.                 i=strlen(buffer);
  1203.                 buffer[i]=*par;
  1204.                 buffer[i+1]='\0';
  1205.             }
  1206.         }
  1207.         par++;
  1208.     }
  1209.  
  1210.         return(buffer);
  1211. }
  1212.  
  1213. void list_headers (verbose)
  1214. {
  1215.    int fd, i, m, line = verbose ? 2 : 5, l = 0;
  1216.    char stringa[10], filename[80];
  1217.    struct _msg msgt;
  1218.    struct _msgzone mz;
  1219.  
  1220.    if (!get_command_word (stringa, 4)) {
  1221.       m_print(bbstxt[B_START_WITH_MSG]);
  1222.  
  1223.       input(stringa,4);
  1224.       if(!strlen(stringa))
  1225.          return;
  1226.    }
  1227.  
  1228.    if (!num_msg)
  1229.       scan_message_base(usr.msg, 1);
  1230.  
  1231.    if (stringa[0] != '=') {
  1232.       m = atoi(stringa);
  1233.       if(m < 1 || m > last_msg)
  1234.             return;
  1235.     }
  1236.     else
  1237.         m = last_msg;
  1238.  
  1239.     cls ();
  1240.     m_print (bbstxt[B_LIST_AREAHEADER], usr.msg, sys.msg_name);
  1241.  
  1242.     if (!verbose) {
  1243.         m_print(bbstxt[B_LIST_HEADER1]);
  1244.         m_print(bbstxt[B_LIST_HEADER2]);
  1245.     }
  1246.  
  1247.     if (sys.quick_board) {
  1248.         quick_list_headers (m, sys.quick_board, verbose, 0);
  1249.         return;
  1250.     }
  1251.     else if (sys.gold_board) {
  1252.         quick_list_headers (m, sys.gold_board, verbose, 1);
  1253.         return;
  1254.     }
  1255.     else if (sys.pip_board) {
  1256.         pip_list_headers (m, sys.pip_board, verbose);
  1257.         return;
  1258.     }
  1259.     else if (sys.squish) {
  1260.         squish_list_headers (m, verbose);
  1261.         return;
  1262.     }
  1263.  
  1264.     for(i = m; i <= last_msg; i++) {
  1265.         sprintf(filename,"%s%d.MSG",sys.msg_path,i);
  1266.  
  1267.         fd=shopen(filename,O_RDONLY|O_BINARY);
  1268.         if(fd == -1)
  1269.             continue;
  1270.         read(fd,(char *)&msgt,sizeof(struct _msg));
  1271.         close(fd);
  1272.  
  1273.         if((msgt.attr & MSGPRIVATE) && stricmp(msgt.from,usr.name) && stricmp(msgt.to,usr.name) && stricmp(msgt.from,usr.handle) && stricmp(msgt.to,usr.handle) && usr.priv < SYSOP)
  1274.             continue;
  1275.  
  1276.         memcpy ((char *)&mz, (char *)&msgt.date_written, sizeof (struct _msgzone));
  1277.  
  1278.         msg_fzone = mz.orig_zone;
  1279.       msg_tzone = mz.dest_zone;
  1280.       msg_fpoint = mz.orig_point;
  1281.       msg_tpoint = mz.dest_point;
  1282.  
  1283.       if (verbose) {
  1284.          if ((line = msg_attrib(&msgt,i,line,0)) == 0)
  1285.             break;
  1286.  
  1287.          m_print(bbstxt[B_ONE_CR]);
  1288.       }
  1289.       else
  1290.          m_print ("%-4d %c%-20.20s %c%-20.20s  %-32.32s\n",
  1291.                  i,
  1292.                  stricmp (msgt.from, usr.name) ? 'è' : 'Ä',
  1293.                  msgt.from,
  1294.                  stricmp (msgt.to, usr.name) ? 'è' : 'î',
  1295.                  msgt.to,
  1296.                  msgt.subj);
  1297.  
  1298.       if (!(l = more_question (line)) || !CARRIER && !RECVD_BREAK())
  1299.          break;
  1300.  
  1301.       if (!verbose && l < line) {
  1302.          l = 5;
  1303.  
  1304.          cls ();
  1305.          m_print (bbstxt[B_LIST_AREAHEADER], usr.msg, sys.msg_name);
  1306.          m_print(bbstxt[B_LIST_HEADER1]);
  1307.          m_print(bbstxt[B_LIST_HEADER2]);
  1308.       }
  1309.  
  1310.       line = l;
  1311.    }
  1312.  
  1313.    if (line && CARRIER)
  1314.       press_enter ();
  1315. }
  1316.  
  1317. void message_inquire ()
  1318. {
  1319.    int fd, i, line=4;
  1320.    char stringa[30], filename[80], *p;
  1321.    struct _msg msgt, backup;
  1322.  
  1323.    if (msg_list != NULL) {
  1324.       free (msg_list);
  1325.       msg_list = NULL;
  1326.    }
  1327.  
  1328.    if (!get_command_word (stringa, 4)) {
  1329.       m_print (bbstxt[B_MSG_TEXT]);
  1330.  
  1331.       input (stringa,29);
  1332.       if (!strlen (stringa))
  1333.          return;
  1334.    }
  1335.  
  1336.    if (!num_msg) {
  1337.       if (sys.quick_board || sys.gold_board)
  1338.          quick_scan_message_base (sys.quick_board, sys.gold_board, usr.msg, 1);
  1339.       else if (sys.pip_board)
  1340.          pip_scan_message_base (usr.msg, 1);
  1341.         else if (sys.squish)
  1342.          squish_scan_message_base (usr.msg, sys.msg_path, 1);
  1343.       else
  1344.          scan_message_base(usr.msg, 1);
  1345.    }
  1346.  
  1347.    m_print (bbstxt[B_MSG_SEARCHING], strupr (stringa));
  1348.  
  1349.    if (sys.quick_board) {
  1350.       quick_message_inquire (stringa, sys.quick_board, 0);
  1351.       return;
  1352.    }
  1353.    else if (sys.gold_board) {
  1354.       quick_message_inquire (stringa, sys.gold_board, 1);
  1355.       return;
  1356.    }
  1357.    else if (sys.pip_board) {
  1358.       return;
  1359.    }
  1360.    else if (sys.squish) {
  1361.       squish_message_inquire (stringa);
  1362.       return;
  1363.    }
  1364.  
  1365.    for (i = first_msg; i <= last_msg; i++) {
  1366.       sprintf (filename, "%s%d.MSG", sys.msg_path, i);
  1367.  
  1368.       fd = shopen (filename,O_RDONLY|O_BINARY);
  1369.       if (fd == -1)
  1370.          continue;
  1371.       read (fd, (char *)&msgt, sizeof (struct _msg));
  1372.  
  1373.       if (msgt.attr & MSGPRIVATE)
  1374.          if (stricmp (msgt.from, usr.name) && stricmp (msgt.to, usr.name) && stricmp (msgt.from, usr.handle) && stricmp (msgt.to, usr.handle) && usr.priv < SYSOP) {
  1375.             close (fd);
  1376.             continue;
  1377.          }
  1378.  
  1379.       p = (char *)malloc ((unsigned int)filelength (fd) - sizeof (struct _msg) + 1);
  1380.       if (p != NULL) {
  1381.          read (fd, p, (unsigned int)filelength (fd) - sizeof (struct _msg));
  1382.          p[(unsigned int)filelength (fd) - sizeof (struct _msg)] = '\0';
  1383.       }
  1384.       else
  1385.             p = NULL;
  1386.  
  1387.       close (fd);
  1388.  
  1389.       memcpy ((char *)&backup, (char *)&msgt, sizeof (struct _msg));
  1390.       strupr (msgt.to);
  1391.       strupr (msgt.from);
  1392.       strupr (msgt.subj);
  1393.  
  1394.       if (p != NULL)
  1395.          strupr (p);
  1396.  
  1397.       if ((strstr (msgt.to, stringa) != NULL) || (strstr (msgt.from, stringa) != NULL) ||
  1398.           (strstr (msgt.subj, stringa) != NULL) || (strstr (p, stringa) != NULL)) {
  1399.          memcpy ((char *)&msgt, (char *)&backup, sizeof (struct _msg));
  1400.          if ((line = msg_attrib (&msgt, i, line, 0)) == 0)
  1401.             break;
  1402.  
  1403.          m_print (bbstxt[B_ONE_CR]);
  1404.  
  1405.          if (!(line = more_question (line)) || !CARRIER && !RECVD_BREAK ())
  1406.             break;
  1407.  
  1408.          time_release ();
  1409.       }
  1410.  
  1411.       if (p != NULL)
  1412.          free (p);
  1413.    }
  1414.  
  1415.    if (line && CARRIER)
  1416.       press_enter ();
  1417. }
  1418.  
  1419. void xport_message ()
  1420. {
  1421.    char filename[30];
  1422.    int msgnum;
  1423.  
  1424.    sprintf (filename, "%d", lastread);
  1425.    m_print (bbstxt[B_XPRT_NUMBER]);
  1426.    chars_input (filename, 5, INPUT_FIELD|INPUT_UPDATE);
  1427.    if (!strlen (filename) || !CARRIER)
  1428.       return;
  1429.  
  1430.    msgnum = atoi (filename);
  1431.    if (!msgnum || msgnum < 1 || msgnum > last_msg)
  1432.       return;
  1433.  
  1434.    strcpy (filename, "LORA.OUT");
  1435.    m_print (bbstxt[B_XPRT_DEVICE]);
  1436.    chars_input (filename, 25, INPUT_FIELD|INPUT_UPDATE);
  1437.    if (!strlen (filename) || !CARRIER)
  1438.       return;
  1439.  
  1440.    m_print (bbstxt[B_XPRT_WRITING]);
  1441.  
  1442.    if (sys.quick_board)
  1443.       quick_write_message_text(msgnum, APPEND_TEXT|INCLUDE_HEADER, filename, NULL);
  1444.    else if (sys.pip_board)
  1445.       pip_write_message_text(msgnum, APPEND_TEXT|INCLUDE_HEADER, filename, NULL);
  1446.    else if (sys.squish)
  1447.       squish_write_message_text(msgnum, APPEND_TEXT|INCLUDE_HEADER, filename, NULL);
  1448.    else
  1449.       write_message_text(msgnum, APPEND_TEXT|INCLUDE_HEADER, filename, NULL);
  1450.  
  1451.    m_print (bbstxt[B_XPRT_DONE]);
  1452. }
  1453.  
  1454. int select_area_list (int flag, int sig)
  1455. {
  1456.    int fd, fdi, i, pari, area, linea, nsys, nm;
  1457.    char stringa[80], filename[50], dir[80], first;
  1458.    struct _sys tsys;
  1459.    struct _sys_idx sysidx[10];
  1460.  
  1461.    m_print ("\nPlease enter the area number to forward the message to.\n");
  1462.    memset (&tsys, 0, sizeof (struct _sys));
  1463.  
  1464.    first = 1;
  1465.  
  1466.    if (sig == -1) {
  1467.       read_system_file ("MGROUP");
  1468.  
  1469.       do {
  1470.          m_print (bbstxt[B_GROUP_LIST]);
  1471.          chars_input (stringa, 4, INPUT_FIELD);
  1472.          if (!CARRIER || (sig = atoi (stringa)) == 0)
  1473.                 return (0);
  1474.       } while (sig < 0);
  1475.  
  1476.       usr.msg_sig = sig;
  1477.    }
  1478.  
  1479.    sprintf(filename,"%sSYSMSG.DAT", config->sys_path);
  1480.    fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD);
  1481.    if (fd == -1)
  1482.       return (0);
  1483.  
  1484.    sprintf(filename,"%sSYSMSG.IDX", config->sys_path);
  1485.    fdi = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD);
  1486.    if (fdi == -1) {
  1487.       close (fd);
  1488.       return (0);
  1489.    }
  1490.  
  1491.    area = usr.msg;
  1492.  
  1493.    do {
  1494.       if (!get_command_word (stringa, 12)) {
  1495.          m_print ("\nForward area: [Area #, '?'=list, <enter>=Quit]: ");
  1496.          input (stringa, 12);
  1497.          if (!CARRIER || time_remain() <= 0) {
  1498.             close (fdi);
  1499.             close (fd);
  1500.             return (0);
  1501.          }
  1502.       }
  1503.  
  1504.       if (!stringa[0] && first) {
  1505.          first = 0;
  1506.          stringa[0] = area_change_key[2];
  1507.       }
  1508.  
  1509.       if (stringa[0] == area_change_key[2] || (!stringa[0] && !area)) {
  1510.          cls();
  1511.          m_print(bbstxt[B_AREAS_TITLE], bbstxt[B_MESSAGE]);
  1512.  
  1513.          first = 0;
  1514.          pari = 0;
  1515.          linea = 4;
  1516.          nm = 0;
  1517.             lseek(fdi, 0L, SEEK_SET);
  1518.  
  1519.          do {
  1520.             if (!CARRIER || time_remain() <= 0) {
  1521.                close (fdi);
  1522.                close (fd);
  1523.                return (0);
  1524.             }
  1525.  
  1526.             nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  1527.             nsys /= sizeof (struct _sys_idx);
  1528.  
  1529.             for (i=0; i < nsys; i++, nm++) {
  1530.                if (usr.priv < sysidx[i].priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags)
  1531.                   continue;
  1532.  
  1533.                if (sig) {
  1534.                   if (sysidx[i].sig != sig)
  1535.                      continue;
  1536.                }
  1537.  
  1538.                if (read_system_file ("MSGAREA"))
  1539.                   break;
  1540.  
  1541.                lseek(fd, (long)nm * SIZEOF_MSGAREA, SEEK_SET);
  1542.                read(fd, (char *)&tsys.msg_name, SIZEOF_MSGAREA);
  1543.  
  1544.                if (sig || tsys.msg_restricted) {
  1545.                   if (tsys.msg_sig != sig)
  1546.                      continue;
  1547.                }
  1548.  
  1549.                if (flag == 1) {
  1550.                   strcpy (dir, tsys.msg_name);
  1551.                   dir[31] = '\0';
  1552.  
  1553.                   sprintf (stringa, "ì%3d ... %-31s ", sysidx[i].area, dir);
  1554.  
  1555.                   if (pari) {
  1556.                      m_print ("%s\n", strtrim (stringa));
  1557.                      pari = 0;
  1558.                      if (!(linea = more_question(linea)))
  1559.                         break;
  1560.                   }
  1561.                         else {
  1562.                      m_print (stringa);
  1563.                      pari = 1;
  1564.                   }
  1565.                }
  1566.                else if (flag == 2) {
  1567.                   m_print("ì%3d ... %s\n", sysidx[i].area, tsys.msg_name);
  1568.                   if (!(linea = more_question(linea)))
  1569.                      break;
  1570.                }
  1571.                else if (flag == 3) {
  1572.                   m_print("ì%3d ...  %-12s %s\n", sysidx[i].area, sysidx[i].key, tsys.msg_name);
  1573.                   if (!(linea = more_question(linea)))
  1574.                      break;
  1575.                }
  1576.                else if (flag == 4) {
  1577.                   if (!sysidx[i].key[0])
  1578.                      sprintf (sysidx[i].key, "%d", sysidx[i].area);
  1579.                   m_print("ì%-12s ... %s\n", sysidx[i].key, tsys.msg_name);
  1580.                   if (!(linea = more_question(linea)))
  1581.                      break;
  1582.                }
  1583.             }
  1584.          } while (linea && nsys == 10);
  1585.  
  1586.          if (pari)
  1587.             m_print(bbstxt[B_ONE_CR]);
  1588.          area = -1;
  1589.       }
  1590.       else if (strlen (stringa) < 1) {
  1591.          close (fdi);
  1592.          close (fd);
  1593.          return (0);
  1594.       }
  1595.       else {
  1596.          lseek (fdi, 0L, SEEK_SET);
  1597.          area = atoi (stringa);
  1598.          if (area < 1) {
  1599.             area = -1;
  1600.             do {
  1601.                nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  1602.                nsys /= sizeof (struct _sys_idx);
  1603.  
  1604.                for(i=0;i<nsys;i++) {
  1605.                         if (usr.priv < sysidx[i].priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags)
  1606.                      continue;
  1607.                   if (sig) {
  1608.                      if (sysidx[i].sig != sig)
  1609.                         continue;
  1610.                   }
  1611.                   if (!stricmp(strbtrim (stringa), strbtrim (sysidx[i].key))) {
  1612.                      area = sysidx[i].area;
  1613.                      break;
  1614.                   }
  1615.                }
  1616.             } while (i == nsys && nsys == 10);
  1617.          }
  1618.          else {
  1619.             do {
  1620.                nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  1621.                nsys /= sizeof (struct _sys_idx);
  1622.  
  1623.                for(i=0;i<nsys;i++) {
  1624.                   if (usr.priv < sysidx[i].priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags)
  1625.                      continue;
  1626.                   if (sig) {
  1627.                      if (sysidx[i].sig != sig)
  1628.                         continue;
  1629.                   }
  1630.                   if (sysidx[i].area == area)
  1631.                      break;
  1632.                }
  1633.             } while (i == nsys && nsys == 10);
  1634.  
  1635.             if (i == nsys)
  1636.                area = -1;
  1637.          }
  1638.       }
  1639.    } while (area == -1 || !read_system2 (area, 1, &tsys));
  1640.  
  1641.    close (fdi);
  1642.    close (fd);
  1643.  
  1644.    return (area);
  1645. }
  1646.  
  1647. void forward_message_area (int sig, int flag)
  1648. {
  1649.     char filename[30];
  1650.    int msgnum, area;
  1651.    struct _sys tsys, bsys;
  1652.  
  1653.    sprintf (filename, "%d", lastread);
  1654.    m_print ("\nMessage number to forward: ");
  1655.    chars_input (filename, 5, INPUT_FIELD|INPUT_UPDATE);
  1656.    if (!strlen (filename) || !CARRIER)
  1657.       return;
  1658.  
  1659.    msgnum = atoi (filename);
  1660.    if (!msgnum || msgnum < 1 || msgnum > last_msg)
  1661.       return;
  1662.  
  1663.    sprintf (filename, "%sFWD%d.TMP", config->flag_dir, line_offset);
  1664.    if (sys.quick_board)
  1665.       quick_write_message_text (msgnum, APPEND_TEXT|INCLUDE_HEADER, filename, NULL);
  1666.    else if (sys.pip_board)
  1667.       pip_write_message_text (msgnum, APPEND_TEXT|INCLUDE_HEADER, filename, NULL);
  1668.    else if (sys.squish)
  1669.       squish_write_message_text (msgnum, APPEND_TEXT|INCLUDE_HEADER, filename, NULL);
  1670.    else
  1671.       write_message_text (msgnum, APPEND_TEXT|INCLUDE_HEADER, filename, NULL);
  1672.  
  1673.    area = select_area_list (flag, sig);
  1674.    if (area == 0 || !read_system2 (area, 1, &tsys) || !CARRIER) {
  1675.       unlink (filename);
  1676.       return;
  1677.    }
  1678.  
  1679.    memcpy (&bsys, &sys, SIZEOF_MSGAREA);
  1680.    memcpy (&sys, &tsys, SIZEOF_MSGAREA);
  1681.  
  1682.    if (sys.msg_num != bsys.msg_num) {
  1683.       if (sys.quick_board || sys.gold_board)
  1684.          quick_scan_message_base (sys.quick_board, sys.gold_board, sys.msg_num, 1);
  1685.       else if (sys.pip_board)
  1686.          pip_scan_message_base (sys.msg_num, 1);
  1687.       else if (sys.squish)
  1688.          squish_scan_message_base (sys.msg_num, sys.msg_path, 1);
  1689.       else
  1690.         scan_message_base (sys.msg_num, 1);
  1691.    }
  1692.  
  1693.     memset (&msg, 0, sizeof (struct _msg));
  1694.  
  1695.    if (get_message_data (0, NULL) == 1) {
  1696.       if (sys.quick_board || sys.gold_board)
  1697.          quick_save_message (filename);
  1698.       else if (sys.pip_board)
  1699.          pip_save_message (filename);
  1700.       else if (sys.squish)
  1701.          squish_save_message (filename);
  1702.       else
  1703.          save_message (filename);
  1704.  
  1705.       usr.msgposted++;
  1706.    }
  1707.  
  1708.    if (sys.msg_num != bsys.msg_num) {
  1709.       memcpy (&sys, &bsys, SIZEOF_MSGAREA);
  1710.       usr.msg = sys.msg_num;
  1711.    }
  1712.  
  1713.    if (sys.quick_board || sys.gold_board)
  1714.       quick_scan_message_base (sys.quick_board, sys.gold_board, usr.msg, 1);
  1715.    else if (sys.pip_board)
  1716.       pip_scan_message_base (usr.msg, 1);
  1717.    else if (sys.squish)
  1718.         squish_scan_message_base (usr.msg, sys.msg_path, 1);
  1719.     else
  1720.       scan_message_base(usr.msg, 1);
  1721.  
  1722.     unlink (filename);
  1723. }
  1724. #endif
  1725.  
  1726. int fido_export_mail (int maxnodes, struct _fwrd *forward)
  1727. {
  1728.     FILE *fpd, *fp;
  1729.     int i, pp, z, ne, no, n_seen, cnet, cnode, mi, msgnum, m, sent, ai;
  1730.     char buff[80], wrp[80], c, *p, buffer[2050], need_origin, need_seen, *flag;
  1731.     long fpos;
  1732.     struct _msghdr2 mhdr;
  1733.     struct _fwrd *seen;
  1734.  
  1735.     seen = (struct _fwrd *)malloc ((MAX_EXPORT_SEEN + 1) * sizeof (struct _fwrd));
  1736.     if (seen == NULL)
  1737.         return (maxnodes);
  1738.  
  1739.     fpd = fopen ("MSGTMP.EXP", "rb+");
  1740.     if (fpd == NULL) {
  1741.         fpd = fopen ("MSGTMP.EXP", "wb");
  1742.         fclose (fpd);
  1743.     }
  1744.     else
  1745.         fclose (fpd);
  1746.     fpd = mopen ("MSGTMP.EXP", "r+b");
  1747.  
  1748.     for (i = 0; i < maxnodes; i++)
  1749.         forward[i].receiveonly = forward[i].sendonly = forward[i].passive = forward[i].private = forward[i].reset = forward[i].export = 0;
  1750.  
  1751.     z = config->alias[sys.use_alias].zone;
  1752.     ne = config->alias[sys.use_alias].net;
  1753.     no = config->alias[sys.use_alias].node;
  1754.     pp = 0;
  1755.  
  1756.     p = strtok (sys.forward1, " ");
  1757.     if (p != NULL)
  1758.         do {
  1759.             flag = p;
  1760.             while (*p == '<' || *p == '>' || *p == '!' || *p == 'P' || *p == 'p')
  1761.                 p++;
  1762.             parse_netnode2 (p, &z, &ne, &no, &pp);
  1763.             for (i = 0; i < MAX_ALIAS; i++) {
  1764.                 if (config->alias[i].net == 0)
  1765.                     continue;
  1766.                 if (config->alias[i].zone == z && config->alias[i].net == ne && config->alias[i].node == no && config->alias[i].point == pp)
  1767.                     break;
  1768.                 if (config->alias[i].point && config->alias[i].fakenet) {
  1769.                     if (config->alias[i].zone == z && config->alias[i].fakenet == ne && config->alias[i].point == no)
  1770.                         break;
  1771.                 }
  1772.          }
  1773.             if (i < MAX_ALIAS && config->alias[i].net)
  1774.             continue;
  1775.          if ((i = is_here (z, ne, no, pp, forward, maxnodes)) != -1)
  1776.             forward[i].reset = forward[i].export = 1;
  1777.          else {
  1778.             i = maxnodes;
  1779.             forward[maxnodes].zone = z;
  1780.             forward[maxnodes].net = ne;
  1781.                 forward[maxnodes].node = no;
  1782.             forward[maxnodes].point = pp;
  1783.             forward[maxnodes].export = 1;
  1784.             forward[maxnodes].reset = 1;
  1785.             maxnodes++;
  1786.             }
  1787.          forward[i].receiveonly = forward[i].sendonly = forward[i].passive = forward[i].private = 0;
  1788.          while (*flag == '<' || *flag == '>' || *flag =='!'||*flag=='p'||*flag=='P') {
  1789.             if (*flag == '>')
  1790.                forward[i].receiveonly = 1;
  1791.             if (*flag == '<')
  1792.                forward[i].sendonly = 1;
  1793.             if (*flag == '!')
  1794.                forward[i].passive = 1;
  1795.             if (*flag == 'P' || *flag=='p')
  1796.                forward[i].private =1;
  1797.             flag++;
  1798.             }
  1799.       } while ((p = strtok (NULL, " ")) != NULL);
  1800.  
  1801.     z = config->alias[sys.use_alias].zone;
  1802.     ne = config->alias[sys.use_alias].net;
  1803.     no = config->alias[sys.use_alias].node;
  1804.    pp = 0;
  1805.  
  1806.    p = strtok (sys.forward2, " ");
  1807.    if (p != NULL)
  1808.       do {
  1809.          flag = p;
  1810.          while (*p == '<' || *p == '>' || *p == '!' || *p == 'P' || *p == 'p')
  1811.             p++;
  1812.          parse_netnode2 (p, &z, &ne, &no, &pp);
  1813.          for (i = 0; i < MAX_ALIAS; i++) {
  1814.                 if (config->alias[i].net == 0)
  1815.                continue;
  1816.                 if (config->alias[i].zone == z && config->alias[i].net == ne && config->alias[i].node == no && config->alias[i].point == pp)
  1817.                break;
  1818.                 if (config->alias[i].point && config->alias[i].fakenet) {
  1819.                     if (config->alias[i].zone == z && config->alias[i].fakenet == ne && config->alias[i].point == no)
  1820.                   break;
  1821.                 }
  1822.          }
  1823.             if (i < MAX_ALIAS && config->alias[i].net)
  1824.             continue;
  1825.          if ((i = is_here (z, ne, no, pp, forward, maxnodes)) != -1)
  1826.             forward[i].reset = forward[i].export = 1;
  1827.          else {
  1828.             i = maxnodes;
  1829.             forward[maxnodes].zone = z;
  1830.             forward[maxnodes].net = ne;
  1831.             forward[maxnodes].node = no;
  1832.             forward[maxnodes].point = pp;
  1833.             forward[maxnodes].export = 1;
  1834.             forward[maxnodes].reset = 1;
  1835.             maxnodes++;
  1836.          }
  1837.          forward[i].receiveonly = forward[i].sendonly = forward[i].passive = forward[i].private = 0;
  1838.          while (*flag == '<' || *flag == '>' || *flag =='!'||*flag=='p'||*flag=='P') {
  1839.             if (*flag == '>')
  1840.                forward[i].receiveonly = 1;
  1841.             if (*flag == '<')
  1842.                     forward[i].sendonly = 1;
  1843.             if (*flag == '!')
  1844.                forward[i].passive = 1;
  1845.             if (*flag == 'P' || *flag=='p')
  1846.                forward[i].private =1;
  1847.             flag++;
  1848.          }
  1849.       } while ((p = strtok (NULL, " ")) != NULL);
  1850.  
  1851.     z = config->alias[sys.use_alias].zone;
  1852.     ne = config->alias[sys.use_alias].net;
  1853.     no = config->alias[sys.use_alias].node;
  1854.    pp = 0;
  1855.  
  1856.     p = strtok (sys.forward3, " ");
  1857.    if (p != NULL)
  1858.       do {
  1859.          flag = p;
  1860.          while (*p == '<' || *p == '>' || *p == '!' || *p == 'P' || *p == 'p')
  1861.             p++;
  1862.          parse_netnode2 (p, &z, &ne, &no, &pp);
  1863.          for (i = 0; i < MAX_ALIAS; i++) {
  1864.                 if (config->alias[i].net == 0)
  1865.                continue;
  1866.                 if (config->alias[i].zone == z && config->alias[i].net == ne && config->alias[i].node == no && config->alias[i].point == pp)
  1867.                break;
  1868.                 if (config->alias[i].point && config->alias[i].fakenet) {
  1869.                     if (config->alias[i].zone == z && config->alias[i].fakenet == ne && config->alias[i].point == no)
  1870.                   break;
  1871.                 }
  1872.          }
  1873.             if (i < MAX_ALIAS && config->alias[i].net)
  1874.             continue;
  1875.          if ((i = is_here (z, ne, no, pp, forward, maxnodes)) != -1)
  1876.             forward[i].reset = forward[i].export = 1;
  1877.          else {
  1878.             i = maxnodes;
  1879.             forward[maxnodes].zone = z;
  1880.             forward[maxnodes].net = ne;
  1881.             forward[maxnodes].node = no;
  1882.             forward[maxnodes].point = pp;
  1883.             forward[maxnodes].export = 1;
  1884.             forward[maxnodes].reset = 1;
  1885.             maxnodes++;
  1886.             }
  1887.          forward[i].receiveonly = forward[i].sendonly = forward[i].passive = forward[i].private = 0;
  1888.          while (*flag == '<' || *flag == '>' || *flag =='!'||*flag=='p'||*flag=='P') {
  1889.             if (*flag == '>')
  1890.                forward[i].receiveonly = 1;
  1891.                 if (*flag == '<')
  1892.                forward[i].sendonly = 1;
  1893.             if (*flag == '!')
  1894.                     forward[i].passive = 1;
  1895.             if (*flag == 'P' || *flag=='p')
  1896.                forward[i].private =1;
  1897.             flag++;
  1898.          }
  1899.       } while ((p = strtok (NULL, " ")) != NULL);
  1900.  
  1901.    sprintf (buff, "%s1.MSG", sys.msg_path);
  1902.    i = open (buff, O_RDONLY|O_BINARY);
  1903.    if (i != -1) {
  1904.       read (i, (char *)&msg, sizeof (struct _msg));
  1905.       close (i);
  1906.       first_msg = msg.reply;
  1907.    }
  1908.    else
  1909.       first_msg = 1;
  1910.    if (first_msg > last_msg)
  1911.       first_msg = last_msg;
  1912.  
  1913.    strcpy (wrp, sys.echotag);
  1914.    wrp[14] = '\0';
  1915.    prints (8, 65, YELLOW|_BLACK, "              ");
  1916.    prints (8, 65, YELLOW|_BLACK, wrp);
  1917.  
  1918.    prints (7, 65, YELLOW|_BLACK, "              ");
  1919.    prints (9, 65, YELLOW|_BLACK, "              ");
  1920.    prints (9, 65, YELLOW|_BLACK, "Fido");
  1921.  
  1922.    sprintf (wrp, "%d / %d", first_msg, last_msg);
  1923.    prints (7, 65, YELLOW|_BLACK, wrp);
  1924.    sent = 0;
  1925.  
  1926.     for (msgnum = first_msg + 1; msgnum <= last_msg; msgnum++) {
  1927.       sprintf (wrp, "%d / %d", msgnum, last_msg);
  1928.       prints (7, 65, YELLOW|_BLACK, wrp);
  1929.  
  1930.         if ( !(msgnum % 20))
  1931.          time_release ();
  1932.  
  1933.       sprintf (buff, "%s%d.MSG", sys.msg_path, msgnum);
  1934.       i = sh_open (buff, SH_DENYWR, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  1935.       if (i == -1)
  1936.          continue;
  1937.  
  1938.         fp = fdopen (i, "r+b");
  1939.         if (fp == NULL)
  1940.             continue;
  1941.  
  1942.         for (i = 0; i < maxnodes; i++)
  1943.             if (forward[i].reset)
  1944.                 forward[i].export = 1;
  1945.  
  1946.         fread((char *)&msg,sizeof(struct _msg),1,fp);
  1947.  
  1948.         if (sys.echomail && (msg.attr & MSGSENT)) {
  1949.             fclose (fp);
  1950.             continue;
  1951.         }
  1952.             for (i=0;i<maxnodes;i++) {
  1953.             if (forward[i].passive||forward[i].sendonly) forward[i].export=0;
  1954.             if (forward[i].private) {
  1955.  
  1956.                 int ii;
  1957.  
  1958.                 forward[i].export=0;
  1959.                 if (!nametable) continue;
  1960.  
  1961.                 for(ii=0;ii<nodes_num;ii++) {
  1962.                     if (forward[i].zone==nametable[ii].zone&&
  1963.                          forward[i].net==nametable[ii].net&&
  1964.                          forward[i].node==nametable[ii].node&&
  1965.                          forward[i].point==nametable[ii].point&&
  1966.                          !stricmp(msg.to,nametable[ii].name)) {
  1967.                              forward[i].export=1;
  1968.                              break;
  1969.                     }
  1970.                 }
  1971.             }
  1972.  
  1973.  
  1974.         }
  1975.  
  1976.       sprintf (wrp, "%5d  %-22.22s Fido         ", msgnum, sys.echotag);
  1977.       wputs (wrp);
  1978.  
  1979.       need_seen = need_origin = 1;
  1980.  
  1981.       mseek (fpd, 0L, SEEK_SET);
  1982.       mprintf (fpd, "AREA:%s\r\n", sys.echotag);
  1983.  
  1984.       mi = i = 0;
  1985.       pp = 0;
  1986.         n_seen = 0;
  1987.       fpos = 0L;
  1988.  
  1989.       fpos = filelength(fileno(fp));
  1990.       setvbuf (fp, NULL, _IOFBF, 2048);
  1991.  
  1992.       while (ftell (fp) < fpos) {
  1993.          c = fgetc(fp);
  1994.  
  1995.          if (c == '\0')
  1996.                 break;
  1997.  
  1998.          if (c == 0x0A)
  1999.             continue;
  2000.          if((byte)c == 0x8D)
  2001.             c = ' ';
  2002.  
  2003.          buff[mi++] = c;
  2004.  
  2005.          if(c == 0x0D) {
  2006.             buff[mi - 1]='\0';
  2007.             if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  2008.                need_origin = 0;
  2009.  
  2010.             if (!strcmp (buff, "NOECHO")) {
  2011.                msg.attr |= MSGSENT;
  2012.                break;
  2013.             }
  2014.  
  2015.             if (!strncmp (buff, "SEEN-BY: ", 9)) {
  2016.                if (need_origin) {
  2017.                   mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  2018.                   if (strlen(sys.origin))
  2019.                             mprintf(fpd,msgtxt[M_ORIGIN_LINE],random_origins(),config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2020.                   else
  2021.                             mprintf(fpd,msgtxt[M_ORIGIN_LINE],system_name,config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2022.                   need_origin = 0;
  2023.                }
  2024.  
  2025.                p = strtok (buff, " ");
  2026.                     ne = config->alias[sys.use_alias].net;
  2027.                     no = config->alias[sys.use_alias].node;
  2028.                     pp = config->alias[sys.use_alias].point;
  2029.                     z = config->alias[sys.use_alias].zone;
  2030.  
  2031.                     while ((p = strtok (NULL, " ")) != NULL) {
  2032.                         parse_netnode2 (p, &z, &ne, &no, &pp);
  2033.  
  2034.                   seen[n_seen].net = ne;
  2035.                   seen[n_seen].node = no;
  2036.                   seen[n_seen].point = pp;
  2037.                   seen[n_seen].zone = z;
  2038.  
  2039.                   for (i = 0; i < maxnodes; i++) {
  2040.                      if (forward[i].net == seen[n_seen].net && forward[i].node == seen[n_seen].node && forward[i].point == seen[n_seen].point) {
  2041.                         forward[i].export = 0;
  2042.                         break;
  2043.                      }
  2044.                   }
  2045.  
  2046.                   if (n_seen + maxnodes >= MAX_EXPORT_SEEN)
  2047.                      continue;
  2048.  
  2049.                         if (seen[n_seen].net != config->alias[sys.use_alias].fakenet && !seen[n_seen].point)
  2050.                      n_seen++;
  2051.                }
  2052.             }
  2053.             else if (!strncmp (buff, "\001PATH: ", 7) && need_seen) {
  2054.                if (need_origin) {
  2055.                   mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  2056.                   if (strlen(sys.origin))
  2057.                             mprintf(fpd,msgtxt[M_ORIGIN_LINE],random_origins(),config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2058.                   else
  2059.                             mprintf(fpd,msgtxt[M_ORIGIN_LINE],system_name,config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2060.                   need_origin = 0;
  2061.                }
  2062.  
  2063.                     if (!config->alias[sys.use_alias].point) {
  2064.                         seen[n_seen].net = config->alias[sys.use_alias].net;
  2065.                         seen[n_seen++].node = config->alias[sys.use_alias].node;
  2066.                     }
  2067.                     else if (config->alias[sys.use_alias].fakenet) {
  2068.                         seen[n_seen].net = config->alias[sys.use_alias].fakenet;
  2069.                         seen[n_seen++].node = config->alias[sys.use_alias].point;
  2070.                }
  2071.  
  2072.                for (i = 0; i < maxnodes; i++) {
  2073.                         if (!forward[i].export || forward[i].net == config->alias[sys.use_alias].fakenet || forward[i].point)
  2074.                      continue;
  2075.                   seen[n_seen].net = forward[i].net;
  2076.                   seen[n_seen++].node = forward[i].node;
  2077.  
  2078.                   ai = sys.use_alias;
  2079.                   for (m = 0; m < maxakainfo; m++)
  2080.                      if (akainfo[m].zone == forward[i].zone && akainfo[m].net == forward[i].net && akainfo[m].node == forward[i].node && akainfo[m].point == forward[i].point) {
  2081.                         if (akainfo[m].aka)
  2082.                            ai = akainfo[m].aka - 1;
  2083.                         break;
  2084.                      }
  2085.                   if (ai != sys.use_alias) {
  2086.                             if (!config->alias[ai].point) {
  2087.                                 if (config->alias[ai].net != seen[n_seen - 1].net || config->alias[ai].node != seen[n_seen - 1].node) {
  2088.                                     seen[n_seen].net = config->alias[ai].net;
  2089.                                     seen[n_seen++].node = config->alias[ai].node;
  2090.                         }
  2091.                      }
  2092.                             else if (config->alias[ai].fakenet) {
  2093.                                 if (config->alias[ai].fakenet != seen[n_seen - 1].net || config->alias[ai].point != seen[n_seen - 1].node) {
  2094.                                     seen[n_seen].net = config->alias[ai].fakenet;
  2095.                                     seen[n_seen++].node = config->alias[ai].point;
  2096.                         }
  2097.                      }
  2098.                   }
  2099.                }
  2100.  
  2101.                     qsort (seen, n_seen, sizeof (struct _fwrd), mail_sort_func);
  2102.  
  2103.                cnet = cnode = 0;
  2104.                strcpy (wrp, "SEEN-BY: ");
  2105.  
  2106.                for (i = 0; i < n_seen; i++) {
  2107.                   if (strlen (wrp) > 65) {
  2108.                      mprintf (fpd, "%s\r\n", wrp);
  2109.                      cnet = cnode = 0;
  2110.                      strcpy (wrp, "SEEN-BY: ");
  2111.                   }
  2112.                   if (i && seen[i].net == seen[i - 1].net && seen[i].node == seen[i - 1].node)
  2113.                      continue;
  2114.  
  2115.                   if (cnet != seen[i].net) {
  2116.                      sprintf (buffer, "%d/%d ", seen[i].net, seen[i].node);
  2117.                      cnet = seen[i].net;
  2118.                      cnode = seen[i].node;
  2119.                   }
  2120.                   else if (cnet == seen[i].net && cnode != seen[i].node) {
  2121.                      sprintf (buffer, "%d ", seen[i].node);
  2122.                      cnode = seen[i].node;
  2123.                   }
  2124.                   else
  2125.                      strcpy (buffer, "");
  2126.  
  2127.                   strcat (wrp, buffer);
  2128.                }
  2129.  
  2130.                mprintf (fpd, "%s\r\n", wrp);
  2131.                mprintf (fpd, "%s\r\n", buff);
  2132.  
  2133.                need_seen = 0;
  2134.             }
  2135.             else if ((msg.attr & MSGLOCAL) && !strncmp (buff, "--- ", 4) && (config->replace_tear || !registered))
  2136.                     replace_tearline (fpd, buff);
  2137.             else
  2138.                mprintf (fpd, "%s\r\n", buff);
  2139.  
  2140.             mi = 0;
  2141.          }
  2142.          else {
  2143.             if (mi < 78)
  2144.                continue;
  2145.  
  2146.             if (!strncmp (buff, msgtxt[M_ORIGIN_LINE], 11))
  2147.                need_origin = 0;
  2148.  
  2149.             buff[mi] = '\0';
  2150.             mprintf (fpd, "%s", buff);
  2151.             mi = 0;
  2152.             buff[mi] = '\0';
  2153.          }
  2154.       }
  2155.  
  2156.       if (msg.attr & MSGSENT) {
  2157.          fseek (fp, 0L, SEEK_SET);
  2158.          msg.attr |= MSGSENT;
  2159.          fwrite ((char *)&msg, sizeof(struct _msg), 1, fp);
  2160.          fclose (fp);
  2161.          continue;
  2162.       }
  2163.  
  2164.       fseek (fp, 0L, SEEK_SET);
  2165.       msg.attr |= MSGSENT;
  2166.       fwrite ((char *)&msg, sizeof(struct _msg), 1, fp);
  2167.       fclose (fp);
  2168.  
  2169.       if (!n_seen) {
  2170.          if (need_origin) {
  2171.                 mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  2172.             if (strlen(sys.origin))
  2173.                     mprintf(fpd,msgtxt[M_ORIGIN_LINE],random_origins(),config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2174.             else
  2175.                     mprintf(fpd,msgtxt[M_ORIGIN_LINE],system_name,config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2176.             need_origin = 0;
  2177.          }
  2178.  
  2179.             if (!config->alias[sys.use_alias].point) {
  2180.                 seen[n_seen].net = config->alias[sys.use_alias].net;
  2181.                 seen[n_seen++].node = config->alias[sys.use_alias].node;
  2182.          }
  2183.             else if (config->alias[sys.use_alias].fakenet) {
  2184.                 seen[n_seen].net = config->alias[sys.use_alias].fakenet;
  2185.                 seen[n_seen++].node = config->alias[sys.use_alias].point;
  2186.          }
  2187.  
  2188.          ai = sys.use_alias;
  2189.          for (i = 0; i < maxnodes; i++) {
  2190.                 if (!forward[i].export || forward[i].net == config->alias[sys.use_alias].fakenet)
  2191.                continue;
  2192.             seen[n_seen].net = forward[i].net;
  2193.             seen[n_seen++].node = forward[i].node;
  2194.  
  2195.             for (m = 0; m < maxakainfo; m++)
  2196.                if (akainfo[m].zone == forward[i].zone && akainfo[m].net == forward[i].net && akainfo[m].node == forward[i].node && akainfo[m].point == forward[i].point) {
  2197.                   if (akainfo[m].aka)
  2198.                      ai = akainfo[m].aka - 1;
  2199.                   break;
  2200.                }
  2201.             if (ai != sys.use_alias) {
  2202.                     if (!config->alias[ai].point) {
  2203.                         if (config->alias[ai].net != seen[n_seen - 1].net || config->alias[ai].node != seen[n_seen - 1].node) {
  2204.                             seen[n_seen].net = config->alias[ai].net;
  2205.                             seen[n_seen++].node = config->alias[ai].node;
  2206.                         }
  2207.                }
  2208.                     else if (config->alias[ai].fakenet) {
  2209.                         if (config->alias[ai].fakenet != seen[n_seen - 1].net || config->alias[ai].point != seen[n_seen - 1].node) {
  2210.                             seen[n_seen].net = config->alias[ai].fakenet;
  2211.                             seen[n_seen++].node = config->alias[ai].point;
  2212.                   }
  2213.                }
  2214.             }
  2215.          }
  2216.  
  2217.          qsort (seen, n_seen, sizeof (struct _fwrd), mail_sort_func);
  2218.  
  2219.          cnet = cnode = 0;
  2220.          strcpy (wrp, "SEEN-BY: ");
  2221.  
  2222.          for (i = 0; i < n_seen; i++) {
  2223.             if (cnet != seen[i].net) {
  2224.                sprintf (buffer, "%d/%d ", seen[i].net, seen[i].node);
  2225.                cnet = seen[i].net;
  2226.                cnode = seen[i].node;
  2227.             }
  2228.             else if (cnet == seen[i].net && cnode != seen[i].node) {
  2229.                sprintf (buffer, "%d ", seen[i].node);
  2230.                cnode = seen[i].node;
  2231.             }
  2232.             else
  2233.                strcpy (buffer, "");
  2234.  
  2235.             strcat (wrp, buffer);
  2236.          }
  2237.  
  2238.          mprintf (fpd, "%s\r\n", wrp);
  2239.             if (config->alias[sys.use_alias].point && config->alias[sys.use_alias].fakenet)
  2240.                 mprintf (fpd, "\001PATH: %d/%d\r\n", config->alias[sys.use_alias].fakenet, config->alias[sys.use_alias].point);
  2241.             else if (!config->alias[sys.use_alias].point)
  2242.                 mprintf (fpd, "\001PATH: %d/%d\r\n", config->alias[sys.use_alias].net, config->alias[sys.use_alias].node);
  2243.       }
  2244.  
  2245.       mhdr.ver = PKTVER;
  2246.       mhdr.cost = 0;
  2247.       mhdr.attrib = 0;
  2248.  
  2249.       if (sys.private)
  2250.          mhdr.attrib |= MSGPRIVATE;
  2251.  
  2252.       for (i = 0; i < maxnodes; i++) {
  2253.          if (!forward[i].export || forward[i].passive || forward[i].sendonly)
  2254.             continue;
  2255.  
  2256.          ai = sys.use_alias;
  2257.          for (m = 0; m < maxakainfo; m++)
  2258.             if (akainfo[m].zone == forward[i].zone && akainfo[m].net == forward[i].net && akainfo[m].node == forward[i].node && akainfo[m].point == forward[i].point) {
  2259.                if (akainfo[m].aka)
  2260.                   ai = akainfo[m].aka - 1;
  2261.                break;
  2262.             }
  2263.  
  2264.             if (config->alias[ai].point && config->alias[ai].fakenet) {
  2265.                 mhdr.orig_node = config->alias[ai].point;
  2266.                 mhdr.orig_net = config->alias[ai].fakenet;
  2267.          }
  2268.          else {
  2269.                 mhdr.orig_node = config->alias[ai].node;
  2270.                 mhdr.orig_net = config->alias[ai].net;
  2271.          }
  2272.  
  2273.          if (forward[i].point)
  2274.             sprintf (wrp, "%d/%d.%d ", forward[i].net, forward[i].node, forward[i].point);
  2275.          else
  2276.                 sprintf (wrp, "%d/%d ", forward[i].net, forward[i].node);
  2277.          wreadcur (&z, &m);
  2278.          if ( (m + strlen (wrp)) > 78) {
  2279.             wputs ("\n");
  2280.             wputs ("                                           ");
  2281.          }
  2282.          wputs (wrp);
  2283.          if ( (m + strlen (wrp)) == 78)
  2284.             wputs ("                                           ");
  2285.  
  2286.          mi = open_packet (forward[i].zone, forward[i].net, forward[i].node, forward[i].point, ai);
  2287.  
  2288.          mhdr.dest_net = forward[i].net;
  2289.          mhdr.dest_node = forward[i].node;
  2290.          write (mi, (char *)&mhdr, sizeof (struct _msghdr2));
  2291.  
  2292.          write (mi, msg.date, strlen (msg.date) + 1);
  2293.          write (mi, msg.to, strlen (msg.to) + 1);
  2294.          write (mi, msg.from, strlen (msg.from) + 1);
  2295.          write (mi, msg.subj, strlen (msg.subj) + 1);
  2296.          mseek (fpd, 0L, SEEK_SET);
  2297.          do {
  2298.             z = mread(buffer, 1, 2048, fpd);
  2299.             write(mi, buffer, z);
  2300.          } while (z == 2048);
  2301.          buff[0] = buff[1] = buff[2] = 0;
  2302.          if (write (mi, buff, 3) != 3)
  2303.             return (-1);
  2304.          close (mi);
  2305.  
  2306.          totalmsg++;
  2307.          sprintf (wrp, "%d (%.1f/s) ", totalmsg, (float)totalmsg / ((float)(timerset (0) - totaltime) / 100));
  2308.          prints (10, 65, YELLOW|_BLACK, wrp);
  2309.  
  2310.          time_release ();
  2311.         }
  2312.  
  2313.       wputs ("\n");
  2314.       sent++;
  2315.    }
  2316.  
  2317.    sprintf (buff, "%s1.MSG", sys.msg_path);
  2318.    i = open (buff, O_RDWR|O_BINARY);
  2319.    if (i != -1)
  2320.       read (i, (char *)&msg, sizeof (struct _msg));
  2321.    else {
  2322.       i = open (buff, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
  2323.       memset ((char *)&msg, 0, sizeof (struct _msg));
  2324.       strcpy (msg.from, "LoraBBS");
  2325.       strcpy (msg.to, "Nobody");
  2326.       strcpy (msg.subj, "High water mark");
  2327.       data (msg.date);
  2328.       write (i, (char *)&msg, sizeof (struct _msg));
  2329.       write (i, "NOECHO\r\n", 9);
  2330.    }
  2331.    msg.reply = last_msg ? last_msg : 1;
  2332.    lseek (i, 0L, SEEK_SET);
  2333.    write (i, (char *)&msg, sizeof (struct _msg));
  2334.    close (i);
  2335.  
  2336.    if (sent)
  2337.       status_line (":   %-20.20s (Sent=%04d)", sys.echotag, sent);
  2338.  
  2339.    mclose (fpd);
  2340.    free (seen);
  2341.    unlink ("MSGTMP.EXP");
  2342.  
  2343.    return (maxnodes);
  2344. }
  2345.  
  2346. void fido_rescan_echomail (char *tag, int zone, int net, int node, int point)
  2347. {
  2348.    FILE *fpd, *fp;
  2349.    int i, pp, z, ne, no, n_seen, cnet, cnode, mi, msgnum, m, sent, fd, ai = 0;
  2350.    char buff[80], wrp[80], c, *p, buffer[2050], need_origin, need_seen;
  2351.    long fpos;
  2352.    struct _msghdr2 mhdr;
  2353.    struct _fwrd *seen;
  2354.    NODEINFO ni;
  2355.  
  2356.    sprintf (buff, "%sNODES.DAT", config->net_info);
  2357.    if ((fd = sh_open (buff, SH_DENYWR, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE)) != -1) {
  2358.       while (read (fd, (char *)&ni, sizeof (NODEINFO)) == sizeof (NODEINFO))
  2359.          if (zone == ni.zone && net == ni.net && node == ni.node && point == ni.point) {
  2360.             ai = ni.aka;
  2361.             break;
  2362.          }
  2363.  
  2364.       close (fd);
  2365.    }
  2366.  
  2367.    strcpy (buff, tag);
  2368.    memset ((char *)&sys, 0, sizeof (struct _sys));
  2369.    strcpy (sys.echotag, tag);
  2370.  
  2371.    seen = (struct _fwrd *)malloc ((MAX_EXPORT_SEEN + 1) * sizeof (struct _fwrd));
  2372.    if (seen == NULL)
  2373.       return;
  2374.  
  2375.    fpd = fopen ("MSGTMP.EXP", "rb+");
  2376.    if (fpd == NULL) {
  2377.       fpd = fopen ("MSGTMP.EXP", "wb");
  2378.       fclose (fpd);
  2379.    }
  2380.    else
  2381.         fclose (fpd);
  2382.    fpd = mopen ("MSGTMP.EXP", "r+b");
  2383.  
  2384.    first_msg = 1;
  2385.    if (first_msg > last_msg)
  2386.       first_msg = last_msg;
  2387.  
  2388.    strcpy (wrp, sys.echotag);
  2389.    wrp[14] = '\0';
  2390.    prints (8, 65, YELLOW|_BLACK, "              ");
  2391.    prints (8, 65, YELLOW|_BLACK, wrp);
  2392.  
  2393.    prints (7, 65, YELLOW|_BLACK, "              ");
  2394.    prints (9, 65, YELLOW|_BLACK, "              ");
  2395.    prints (9, 65, YELLOW|_BLACK, "Fido");
  2396.  
  2397.    sprintf (wrp, "%d / %d", first_msg, last_msg);
  2398.    prints (7, 65, YELLOW|_BLACK, wrp);
  2399.    sent = 0;
  2400.  
  2401.    for (msgnum = first_msg + 1; msgnum <= last_msg; msgnum++) {
  2402.       sprintf (wrp, "%d / %d", msgnum, last_msg);
  2403.       prints (7, 65, YELLOW|_BLACK, wrp);
  2404.  
  2405.       if ( !(msgnum % 20))
  2406.          time_release ();
  2407.  
  2408.       sprintf (buff, "%s%d.MSG", sys.msg_path, msgnum);
  2409.       i = sh_open (buff, SH_DENYWR, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  2410.       if (i == -1)
  2411.          continue;
  2412.  
  2413.       fp = fdopen (i, "r+b");
  2414.       if (fp == NULL)
  2415.          continue;
  2416.  
  2417.       fread((char *)&msg,sizeof(struct _msg),1,fp);
  2418.  
  2419.       sprintf (wrp, "%5d  %-22.22s Fido         ", msgnum, sys.echotag);
  2420.       wputs (wrp);
  2421.  
  2422.       need_seen = need_origin = 1;
  2423.  
  2424.       mseek (fpd, 0L, SEEK_SET);
  2425.       mprintf (fpd, "AREA:%s\r\n", sys.echotag);
  2426.  
  2427.       mi = i = 0;
  2428.       pp = 0;
  2429.       n_seen = 0;
  2430.       fpos = 0L;
  2431.  
  2432.       fpos = filelength(fileno(fp));
  2433.       setvbuf (fp, NULL, _IOFBF, 2048);
  2434.  
  2435.       while (ftell (fp) < fpos) {
  2436.          c = fgetc(fp);
  2437.  
  2438.          if (c == '\0')
  2439.             break;
  2440.  
  2441.          if (c == 0x0A)
  2442.             continue;
  2443.          if((byte)c == 0x8D)
  2444.             c = ' ';
  2445.  
  2446.          buff[mi++] = c;
  2447.  
  2448.          if(c == 0x0D) {
  2449.             buff[mi - 1]='\0';
  2450.             if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  2451.                     need_origin = 0;
  2452.  
  2453.             if (!strncmp (buff, "SEEN-BY: ", 9)) {
  2454.                if (need_origin) {
  2455.                   mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  2456.                   if (strlen(sys.origin))
  2457.                             mprintf(fpd,msgtxt[M_ORIGIN_LINE],random_origins(),config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2458.                   else
  2459.                             mprintf(fpd,msgtxt[M_ORIGIN_LINE],system_name,config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2460.                   need_origin = 0;
  2461.                }
  2462.  
  2463.                p = strtok (buff, " ");
  2464.                     ne = config->alias[sys.use_alias].net;
  2465.                     no = config->alias[sys.use_alias].node;
  2466.                     pp = config->alias[sys.use_alias].point;
  2467.                     z = config->alias[sys.use_alias].zone;
  2468.  
  2469.                while ((p = strtok (NULL, " ")) != NULL) {
  2470.                   parse_netnode2 (p, &z, &ne, &no, &pp);
  2471.  
  2472.                   seen[n_seen].net = ne;
  2473.                   seen[n_seen].node = no;
  2474.                   seen[n_seen].point = pp;
  2475.                   seen[n_seen].zone = z;
  2476.  
  2477.                   if (n_seen >= MAX_EXPORT_SEEN)
  2478.                      continue;
  2479.  
  2480.                         if (seen[n_seen].net != config->alias[sys.use_alias].fakenet && !seen[n_seen].point)
  2481.                      n_seen++;
  2482.                }
  2483.             }
  2484.             else if (!strncmp (buff, "\001PATH: ", 7) && need_seen) {
  2485.                if (need_origin) {
  2486.                         mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  2487.                   if (strlen(sys.origin))
  2488.                             mprintf(fpd,msgtxt[M_ORIGIN_LINE],random_origins(),config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2489.                   else
  2490.                             mprintf(fpd,msgtxt[M_ORIGIN_LINE],system_name,config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2491.                   need_origin = 0;
  2492.                }
  2493.  
  2494.                     if (!config->alias[sys.use_alias].point) {
  2495.                         seen[n_seen].net = config->alias[sys.use_alias].net;
  2496.                         seen[n_seen++].node = config->alias[sys.use_alias].node;
  2497.                }
  2498.                     else if (config->alias[sys.use_alias].fakenet) {
  2499.                         seen[n_seen].net = config->alias[sys.use_alias].fakenet;
  2500.                         seen[n_seen++].node = config->alias[sys.use_alias].point;
  2501.                }
  2502.  
  2503.                seen[n_seen].net = net;
  2504.                seen[n_seen++].node = node;
  2505.  
  2506.                qsort (seen, n_seen, sizeof (struct _fwrd), mail_sort_func);
  2507.  
  2508.                cnet = cnode = 0;
  2509.                strcpy (wrp, "SEEN-BY: ");
  2510.  
  2511.                for (i = 0; i < n_seen; i++) {
  2512.                   if (strlen (wrp) > 65) {
  2513.                      mprintf (fpd, "%s\r\n", wrp);
  2514.                      cnet = cnode = 0;
  2515.                      strcpy (wrp, "SEEN-BY: ");
  2516.                   }
  2517.                   if (i && seen[i].net == seen[i - 1].net && seen[i].node == seen[i - 1].node)
  2518.                      continue;
  2519.  
  2520.                   if (cnet != seen[i].net) {
  2521.                             sprintf (buffer, "%d/%d ", seen[i].net, seen[i].node);
  2522.                      cnet = seen[i].net;
  2523.                      cnode = seen[i].node;
  2524.                   }
  2525.                   else if (cnet == seen[i].net && cnode != seen[i].node) {
  2526.                      sprintf (buffer, "%d ", seen[i].node);
  2527.                      cnode = seen[i].node;
  2528.                   }
  2529.                   else
  2530.                      strcpy (buffer, "");
  2531.  
  2532.                   strcat (wrp, buffer);
  2533.                }
  2534.  
  2535.                mprintf (fpd, "%s\r\n", wrp);
  2536.                mprintf (fpd, "%s\r\n", buff);
  2537.  
  2538.                need_seen = 0;
  2539.             }
  2540.             else if ((msg.attr & MSGLOCAL) && !strncmp (buff, "--- ", 4) && (config->replace_tear || !registered))
  2541.                replace_tearline (fpd, buff);
  2542.             else
  2543.                mprintf (fpd, "%s\r\n", buff);
  2544.  
  2545.             mi = 0;
  2546.          }
  2547.          else {
  2548.             if(mi < 78)
  2549.                continue;
  2550.  
  2551.             if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  2552.                need_origin = 0;
  2553.  
  2554.             buff[mi]='\0';
  2555.             mprintf(fpd,"%s",buff);
  2556.                 mi=0;
  2557.             buff[mi] = '\0';
  2558.          }
  2559.       }
  2560.  
  2561.       fseek (fp, 0L, SEEK_SET);
  2562.       msg.attr |= MSGSENT;
  2563.       fwrite ((char *)&msg, sizeof(struct _msg), 1, fp);
  2564.       fclose (fp);
  2565.  
  2566.       if (!n_seen) {
  2567.          if (need_origin) {
  2568.             mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  2569.             if (strlen(sys.origin))
  2570.                     mprintf(fpd,msgtxt[M_ORIGIN_LINE],random_origins(),config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2571.             else
  2572.                     mprintf(fpd,msgtxt[M_ORIGIN_LINE],system_name,config->alias[sys.use_alias].zone,config->alias[sys.use_alias].net,config->alias[sys.use_alias].node, config->alias[sys.use_alias].point);
  2573.             need_origin = 0;
  2574.          }
  2575.  
  2576.             if (!config->alias[sys.use_alias].point) {
  2577.                 seen[n_seen].net = config->alias[sys.use_alias].net;
  2578.                 seen[n_seen++].node = config->alias[sys.use_alias].node;
  2579.          }
  2580.             else if (config->alias[sys.use_alias].fakenet) {
  2581.                 seen[n_seen].net = config->alias[sys.use_alias].fakenet;
  2582.                 seen[n_seen++].node = config->alias[sys.use_alias].point;
  2583.          }
  2584.  
  2585.          seen[n_seen].net = net;
  2586.          seen[n_seen++].node = node;
  2587.  
  2588.          qsort (seen, n_seen, sizeof (struct _fwrd), mail_sort_func);
  2589.  
  2590.          cnet = cnode = 0;
  2591.             strcpy (wrp, "SEEN-BY: ");
  2592.  
  2593.          for (i = 0; i < n_seen; i++) {
  2594.             if (cnet != seen[i].net) {
  2595.                sprintf (buffer, "%d/%d ", seen[i].net, seen[i].node);
  2596.                cnet = seen[i].net;
  2597.                cnode = seen[i].node;
  2598.             }
  2599.             else if (cnet == seen[i].net && cnode != seen[i].node) {
  2600.                sprintf (buffer, "%d ", seen[i].node);
  2601.                cnode = seen[i].node;
  2602.             }
  2603.             else
  2604.                strcpy (buffer, "");
  2605.  
  2606.             strcat (wrp, buffer);
  2607.          }
  2608.  
  2609.          mprintf (fpd, "%s\r\n", wrp);
  2610.             if (config->alias[sys.use_alias].point && config->alias[sys.use_alias].fakenet)
  2611.                 mprintf (fpd, "\001PATH: %d/%d\r\n", config->alias[sys.use_alias].fakenet, config->alias[sys.use_alias].point);
  2612.             else if (!config->alias[sys.use_alias].point)
  2613.                 mprintf (fpd, "\001PATH: %d/%d\r\n", config->alias[sys.use_alias].net, config->alias[sys.use_alias].node);
  2614.       }
  2615.  
  2616.       if (ai)
  2617.          sys.use_alias = ai - 1;
  2618.  
  2619.       mhdr.ver = PKTVER;
  2620.         if (config->alias[sys.use_alias].point && config->alias[sys.use_alias].fakenet) {
  2621.             mhdr.orig_node = config->alias[sys.use_alias].point;
  2622.             mhdr.orig_net = config->alias[sys.use_alias].fakenet;
  2623.       }
  2624.       else {
  2625.             mhdr.orig_node = config->alias[sys.use_alias].node;
  2626.             mhdr.orig_net = config->alias[sys.use_alias].net;
  2627.       }
  2628.       mhdr.cost = 0;
  2629.       mhdr.attrib = 0;
  2630.  
  2631.       if (sys.private)
  2632.          mhdr.attrib |= MSGPRIVATE;
  2633.  
  2634.       if (point)
  2635.          sprintf (wrp, "%d/%d.%d ", net, node, point);
  2636.       else
  2637.          sprintf (wrp, "%d/%d ", net, node);
  2638.       wreadcur (&z, &m);
  2639.       if ( (m + strlen (wrp)) > 78) {
  2640.          wputs ("\n");
  2641.          wputs ("                                           ");
  2642.       }
  2643.       wputs (wrp);
  2644.       if ( (m + strlen (wrp)) == 78)
  2645.          wputs ("                                           ");
  2646.  
  2647.       mi = open_packet (zone, net, node, point, sys.use_alias);
  2648.  
  2649.       mhdr.dest_net = net;
  2650.       mhdr.dest_node = node;
  2651.       write (mi, (char *)&mhdr, sizeof (struct _msghdr2));
  2652.  
  2653.       write (mi, msg.date, strlen (msg.date) + 1);
  2654.       write (mi, msg.to, strlen (msg.to) + 1);
  2655.       write (mi, msg.from, strlen (msg.from) + 1);
  2656.       write (mi, msg.subj, strlen (msg.subj) + 1);
  2657.       mseek (fpd, 0L, SEEK_SET);
  2658.       do {
  2659.          z = mread(buffer, 1, 2048, fpd);
  2660.          write(mi, buffer, z);
  2661.         } while (z == 2048);
  2662.       buff[0] = buff[1] = buff[2] = 0;
  2663.       if (write (mi, buff, 3) != 3)
  2664.          return;
  2665.       close (mi);
  2666.  
  2667.       totalmsg++;
  2668.       sprintf (wrp, "%d (%.1f/s) ", totalmsg, (float)totalmsg / ((float)(timerset (0) - totaltime) / 100));
  2669.       prints (10, 65, YELLOW|_BLACK, wrp);
  2670.  
  2671.       time_release ();
  2672.       wputs ("\n");
  2673.       sent++;
  2674.    }
  2675.  
  2676.    if (sent)
  2677.       status_line (":   %-20.20s (Sent=%04d)", sys.echotag, sent);
  2678.  
  2679.    mclose (fpd);
  2680.    free (seen);
  2681.    unlink ("MSGTMP.EXP");
  2682.  
  2683.    return;
  2684. }
  2685.  
  2686. void move_to_bad_message (char *netdir, int msgnum)
  2687. {
  2688.    int i, last;
  2689.    char filename[80], newname[80], *p;
  2690.    struct ffblk blk;
  2691.  
  2692.    last = 0;
  2693.    sprintf (filename, "%s*.MSG", config->bad_msgs);
  2694.  
  2695.    if (!findfirst (filename, &blk, 0))
  2696.         do {
  2697.          if ((p = strchr (blk.ff_name,'.')) != NULL)
  2698.             *p = '\0';
  2699.  
  2700.          i = atoi (blk.ff_name);
  2701.          if (last < i || !last)
  2702.             last = i;
  2703.       } while (!findnext (&blk));
  2704.  
  2705.    sprintf (newname, "%s%d.MSG", config->bad_msgs, ++last);
  2706.    sprintf (filename, "%s%d.MSG", netdir, msgnum);
  2707.  
  2708.    status_line (":Moved to bad message #%d", last);
  2709.  
  2710.    rename (filename, newname);
  2711. }
  2712.  
  2713. int check_afix (char *to)
  2714. {
  2715.    char *p, buffer[80];
  2716.  
  2717.    strcpy (buffer, config->areafix_watch);
  2718.    if ((p = strtok (buffer, " ")) == NULL)
  2719.       return (stricmp (to, "Areafix"));
  2720.    else {
  2721.       do {
  2722.          if (!stricmp (to, p))
  2723.             return (0);
  2724.       } while ((p = strtok (NULL, " ")) != NULL);
  2725.    }
  2726.  
  2727.    return (-1);
  2728. }
  2729.  
  2730. int check_tic (char *to)
  2731. {
  2732.    char *p, buffer[80];
  2733.  
  2734.     strcpy (buffer, config->tic_watch);
  2735.    if ((p = strtok (buffer, " ")) == NULL)
  2736.       return (stricmp (to, "Raid"));
  2737.    else {
  2738.       do {
  2739.          if (!stricmp (to, p))
  2740.                 return (0);
  2741.       } while ((p = strtok (NULL, " ")) != NULL);
  2742.     }
  2743.  
  2744.     return (-1);
  2745. }
  2746.  
  2747. #define XATTR_IMM  0x01
  2748. #define XATTR_DIR  0x02
  2749. #define XATTR_TFS  0x04
  2750. #define XATTR_XMA  0x08
  2751. #define XATTR_KFS  0x10
  2752. #define XATTR_ZON  0x20
  2753.  
  2754. int fido_export_netmail (void)
  2755. {
  2756.     FILE *fpd, *fp;
  2757.     int i, z, mi, msgnum, sent, fd, xattr, dne, dno, removesent;
  2758.     char buff[80], wrp[80], c, *p, buffer[2050], countlimit, ourpoint, *b;
  2759.     char intl_found = 0,reply,msgid;
  2760.     long fpos;
  2761.     struct _msg omsg;
  2762.     struct _msghdr2 mhdr;
  2763.     struct _pkthdr2 pkthdr;
  2764.     struct date datep;
  2765.     struct time timep;
  2766.     NODEINFO ni;
  2767.  
  2768.     scan_message_base (0, 0);
  2769.  
  2770.     status_line ("#Packing from %s (%d msgs)", sys.msg_path, last_msg);
  2771.     sent = 0;
  2772.  
  2773.     fpd = fopen ("MSGTMP.EXP", "rb+");
  2774.     if (fpd == NULL) {
  2775.         fpd = fopen ("MSGTMP.EXP", "wb");
  2776.         fclose (fpd);
  2777.     }
  2778.     else
  2779.         fclose (fpd);
  2780.     fpd = mopen ("MSGTMP.EXP", "r+b");
  2781.  
  2782.     prints (7, 65, YELLOW|_BLACK, "              ");
  2783.     prints (8, 65, YELLOW|_BLACK, "              ");
  2784.     prints (8, 65, YELLOW|_BLACK, "Netmail");
  2785.     prints (9, 65, YELLOW|_BLACK, "              ");
  2786.     prints (9, 65, YELLOW|_BLACK, "Fido");
  2787.  
  2788.     for (msgnum = 1; msgnum <= last_msg; msgnum++) {
  2789.         if ( !(msgnum % 6)) {
  2790.             sprintf (wrp, "%d / %d", msgnum, last_msg);
  2791.             prints (7, 65, YELLOW|_BLACK, wrp);
  2792.             time_release ();
  2793.         }
  2794.  
  2795.         sprintf (buff, "%s%d.MSG", sys.msg_path, msgnum);
  2796.         i = sh_open (buff, SH_DENYNONE, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  2797.         if (i == -1)
  2798.             continue;
  2799.  
  2800.         fp = fdopen (i, "r+b");
  2801.         if (fp == NULL)
  2802.             continue;
  2803.  
  2804.       removesent = 0;
  2805.         fread ((char *)&msg, sizeof (struct _msg), 1, fp);
  2806.  
  2807.         if (msg.attr & MSGSENT) {
  2808.             fclose (fp);
  2809.             continue;
  2810.         }
  2811.  
  2812.         for (i = 0; i < MAX_ALIAS && config->alias[i].net; i++) {
  2813.             if (config->alias[i].point && config->alias[i].fakenet) {
  2814.                 if (config->alias[i].fakenet == msg.dest_net && config->alias[i].point == msg.dest)
  2815.                     break;
  2816.             }
  2817.             if (config->alias[i].net == msg.dest_net && config->alias[i].node == msg.dest)
  2818.                 break;
  2819.         }
  2820.  
  2821.         if (i < MAX_ALIAS && config->alias[i].net == msg.dest_net && config->alias[i].node == msg.dest && !config->alias[i].point) {
  2822.             countlimit = 10;
  2823.             ourpoint = 1;
  2824.          removesent = 1;
  2825.       }
  2826.         else if (i < MAX_ALIAS && config->alias[i].fakenet == msg.dest_net && config->alias[i].point == msg.dest && config->alias[i].point) {
  2827.             fclose (fp);
  2828.             continue;
  2829.         }
  2830.         else {
  2831.             countlimit = 0;
  2832.             ourpoint = 0;
  2833.         }
  2834.  
  2835.         sprintf (wrp, "%d / %d", msgnum, last_msg);
  2836.         prints (7, 65, YELLOW|_BLACK, wrp);
  2837.  
  2838.         memcpy ((char *)&omsg, (char *)&msg, sizeof (struct _msg));
  2839.  
  2840.         mseek (fpd, 0L, SEEK_SET);
  2841.  
  2842.         msg_fzone = msg_tzone = 0;
  2843.         msg_fpoint = msg_tpoint = 0;
  2844.         mi = i = 0;
  2845.         fpos = 0L;
  2846.         xattr = 0;
  2847.       intl_found = msgid = reply = 0;
  2848.  
  2849.         fpos = filelength(fileno(fp));
  2850.  
  2851.         while (ftell (fp) < fpos) {
  2852.             c = fgetc(fp);
  2853.  
  2854.             if (c == '\0')
  2855.                 break;
  2856.  
  2857.             if (c == 0x0A)
  2858.                 continue;
  2859.             if((byte)c == 0x8D)
  2860.                 c = ' ';
  2861.  
  2862.             buff[mi++] = c;
  2863.  
  2864.             if(c == 0x0D) {
  2865.                 buff[mi - 1]='\0';
  2866.                 if(buff[0] == 0x01) {
  2867.                     if (!strncmp(&buff[1],"INTL",4)) {
  2868. //                        mprintf (fpd, "%s\r\n", buff);
  2869.                         p=strtok(buff," ");
  2870.                         if(p){
  2871.                             p=strtok(NULL," ");
  2872.                             if(p){
  2873.                                 dne=dno=0;
  2874.                                 parse_netnode(p,&msg_tzone,&dne,&dno,&i);
  2875.                                 p=strtok(NULL," ");
  2876.                                 if(p)
  2877.                                     parse_netnode(p,&msg_fzone,&i,&i,&i);
  2878.                             }
  2879.                         }
  2880.                         if (dne != msg.dest_net || dno != msg.dest) {
  2881.                             msg_tzone = msg_fzone;
  2882. //                            mprintf (fpd, "%s\r\n", buff);
  2883.                         }
  2884.                         intl_found = 1;
  2885.                     }
  2886.  
  2887.                     else if (!strncmp(&buff[1],"TOPT",4)) {
  2888.                         sscanf(&buff[6],"%d",&msg_tpoint);
  2889.                         countlimit = 0;
  2890.                   removesent = 0;
  2891.                   for (i = 0; i < MAX_ALIAS && config->alias[i].net; i++) {
  2892.                             if (config->alias[i].net == msg.dest_net && config->alias[i].node == msg.dest && config->alias[i].point == msg_tpoint)
  2893.                                 break;
  2894.                         }
  2895.                         if (i < MAX_ALIAS && config->alias[i].net) {
  2896.                             msg.attr |= MSGSENT;
  2897.                             break;
  2898.                         }
  2899.                     }
  2900.  
  2901.                     else if (!strncmp(&buff[1],"FMPT",4))
  2902.                         sscanf(&buff[6],"%d",&msg_fpoint);
  2903.  
  2904. //                    else if (!strncmp (&buff[1], "REALNAME:", 9))
  2905. //                        strcpy (msg.from, &buff[11]);
  2906.  
  2907.                     else
  2908.                         mprintf (fpd, "%s\r\n", buff);
  2909.  
  2910.                     if (!strncmp(&buff[1],"MSGID",5)) {
  2911.                         msgid=1;
  2912.                         if (!intl_found && strstr(buff,"/")){
  2913.                      parse_netnode (&buff[7],&msg_fzone,&i, &i, &i);
  2914.                             if(!reply)
  2915.                                 msg_tzone=msg_fzone;
  2916.                         }
  2917.                     }
  2918.  
  2919. /*                    if (!strncmp(&buff[1],"REPLY",5)) {
  2920.                         reply=1;
  2921.                         if (!intl_found && strstr(buff,"/")){
  2922.                      parse_netnode (&buff[7],&msg_tzone,&i, &i, &i);
  2923. //                     if(!msgid)
  2924. //                        msg_fzone=msg_tzone;
  2925.                         }
  2926.                     }
  2927. */
  2928.                     if (!strncmp (&buff[1], "FLAGS", 5)) {
  2929.                         if (strstr (buff, " IMM") != NULL)
  2930.                             xattr |= XATTR_IMM;
  2931.                         if (strstr (buff, " DIR") != NULL)
  2932.                             xattr |= XATTR_DIR;
  2933.                         if (strstr (buff, " TFS") != NULL)
  2934.                             xattr |= XATTR_TFS;
  2935.                         if (strstr (buff, " XMA") != NULL)
  2936.                             xattr |= XATTR_XMA;
  2937.                         if (strstr (buff, " KFS") != NULL)
  2938.                             xattr |= XATTR_KFS;
  2939.                         if (strstr (buff, " ZON") != NULL)
  2940.                             xattr |= XATTR_ZON;
  2941.                     }
  2942.                 }
  2943.                 else if ((msg.attr & MSGLOCAL) && !strncmp (buff, "--- ", 4) && (config->replace_tear || !registered))
  2944.                     replace_tearline (fpd, buff);
  2945.                 else
  2946.                     mprintf (fpd, "%s\r\n", buff);
  2947.  
  2948.                 mi = 0;
  2949.  
  2950.                 if (countlimit) {
  2951.                     countlimit--;
  2952.                if (!countlimit)
  2953.                         msg.attr |= MSGSENT;
  2954.                 }
  2955.             }
  2956.             else {
  2957.                 if(mi < 78)
  2958.                     continue;
  2959.  
  2960.                 buff[mi]='\0';
  2961.                 mprintf(fpd,"%s",buff);
  2962.                 mi=0;
  2963.                 buff[mi] = '\0';
  2964.  
  2965.                 if (countlimit) {
  2966.                     countlimit--;
  2967.                if (!countlimit)
  2968.                   msg.attr |= MSGSENT;
  2969.             }
  2970.             }
  2971.         }
  2972.         if (msg_fzone == 0 && msg_tzone == 0)
  2973.             msg_fzone = msg_tzone = config->alias[0].zone;
  2974.         else{
  2975.             if (msg_fzone == 0)
  2976.                 msg_fzone = msg_tzone;
  2977.             if (msg_tzone == 0)
  2978.                 msg_tzone = msg_fzone;
  2979.         }
  2980.  
  2981.         if (config->msgtrack)
  2982.             if (!track_outbound_messages (fpd, &msg, msg_fzone, msg_fpoint, msg_tzone, msg_tpoint)) {
  2983.                 omsg.attr |= MSGSENT;
  2984.                 fseek (fp, 0L, SEEK_SET);
  2985.                 fwrite ((char *)&omsg, sizeof(struct _msg), 1, fp);
  2986.  
  2987.                 fclose (fp);
  2988.  
  2989.                 move_to_bad_message (sys.msg_path, msgnum);
  2990.                 continue;
  2991.             }
  2992.  
  2993.         if (msg_tpoint && check_hold (msg_tzone, msg.dest_net, msg.dest, msg_tpoint))
  2994.             msg.attr |= MSGHOLD;
  2995.  
  2996.         if(msg_tzone && ourpoint){
  2997.             ourpoint=0;
  2998.             for (i = 0; i < MAX_ALIAS && config->alias[i].net; i++){
  2999.                 if (config->alias[i].zone == msg_tzone && config->alias[i].net == msg.dest_net && config->alias[i].node == msg.dest) {
  3000.                     ourpoint=1;
  3001.                     break;
  3002.                 }
  3003.             }
  3004.         }
  3005.  
  3006.         if (ourpoint && check_afix (msg.to) && check_tic (msg.to)) {
  3007.             sprintf (buff, "%sNODES.DAT", config->net_info);
  3008.             fd = open (buff, O_RDONLY|O_BINARY);
  3009.             if (fd != -1) {
  3010.                 fpos = -1L;
  3011.  
  3012.                 while (read (fd, (char *)&ni, sizeof (NODEINFO)) == sizeof (NODEINFO)) {
  3013.                     if ((!msg_tzone || msg_tzone == ni.zone) && !stricmp (ni.sysop_name, msg.to) && ni.remap4d) {
  3014.                         if (msg_tzone != ni.zone || msg.dest_net != ni.net || msg.dest != ni.node || msg_tpoint != ni.point) {
  3015.                             status_line ("#  Remap #%d %d:%d/%d.%d => %d:%d/%d.%d", msgnum, msg_tzone, msg.dest_net, msg.dest, msg_tpoint, ni.zone, ni.net, ni.node, ni.point);
  3016.                             mprintf (fpd, "\x01PointMap %d:%d/%d.%d => %d:%d/%d.%d\r\n", msg_tzone, msg.dest_net, msg.dest, msg_tpoint, ni.zone, ni.net, ni.node, ni.point);
  3017.                         }
  3018.                         msg_tzone = ni.zone;
  3019.                         msg.dest_net = ni.net;
  3020.                         msg.dest = ni.node;
  3021.                         msg_tpoint = ni.point;
  3022.                         if (!msg_tpoint)
  3023.                             ourpoint = 0;
  3024.                         msg.attr |= MSGFWD;
  3025.                         msg.attr &= ~MSGSENT;
  3026.                   removesent = 0;
  3027.                   fpos = -1L;
  3028.                         break;
  3029.                     }
  3030.                     else if (fpos == -1L && !stricmp (ni.sysop_name, msg.to) && ni.remap4d)
  3031.                         fpos = tell (fd) - sizeof (NODEINFO);
  3032.                 }
  3033.  
  3034.                 if (fpos != -1L) {
  3035.                     lseek (fd, fpos, SEEK_SET);
  3036.                     read (fd, (char *)&ni, sizeof (NODEINFO));
  3037.                     status_line ("#  Remap #%d %d:%d/%d.%d => %d:%d/%d.%d", msgnum, msg_tzone, msg.dest_net, msg.dest, msg_tpoint, ni.zone, ni.net, ni.node, ni.point);
  3038.                     mprintf (fpd, "\x01PointMap %d:%d/%d.%d => %d:%d/%d.%d\r\n", msg_tzone, msg.dest_net, msg.dest, msg_tpoint, ni.zone, ni.net, ni.node, ni.point);
  3039.                     msg_tzone = ni.zone;
  3040.                     msg.dest_net = ni.net;
  3041.                     msg.dest = ni.node;
  3042.                     msg_tpoint = ni.point;
  3043.                     if (!msg_tpoint)
  3044.                         ourpoint = 0;
  3045.                     msg.attr &= ~MSGSENT;
  3046.                     msg.attr |= MSGFWD;
  3047.                removesent = 0;
  3048.             }
  3049.  
  3050.                 close (fd);
  3051.             }
  3052.         }
  3053.  
  3054.         if (!msg_fzone && msg_tzone)
  3055.             msg_fzone = msg_tzone;
  3056.         else if (!msg_tzone && msg_fzone)
  3057.             msg_tzone = msg_fzone;
  3058.         else if (!msg_tzone && !msg_fzone)
  3059.             msg_tzone = msg_fzone = config->alias[sys.use_alias].zone;
  3060.  
  3061.         if (ourpoint && registered == 1 && !check_afix (msg.to) && !(msg.attr & MSGREAD) && config->areafix) {
  3062.             msg.attr |= MSGSENT|MSGREAD;
  3063.             fseek (fp, 0L, SEEK_SET);
  3064.             fwrite((char *)&msg,sizeof(struct _msg),1,fp);
  3065.  
  3066.             mclose (fpd);
  3067.  
  3068.             sprintf (wrp, "%5d  %-22.22s Fido         ", msgnum, "Areafix");
  3069.             wputs (wrp);
  3070.             fseek (fp, (long)sizeof (struct _msg), SEEK_SET);
  3071.             process_areafix_request (fp, msg_fzone, msg.orig_net, msg.orig, msg_fpoint, msg.subj);
  3072.             wputs ("\n");
  3073.  
  3074.             fclose (fp);
  3075.             fpd = mopen ("MSGTMP.EXP", "r+b");
  3076.             continue;
  3077.         }
  3078.         else if (ourpoint && registered == 1 && !check_tic (msg.to) && !(msg.attr & MSGREAD) && config->tic_active) {
  3079.             msg.attr |= MSGSENT|MSGREAD;
  3080.             fseek (fp, 0L, SEEK_SET);
  3081.             fwrite((char *)&msg,sizeof(struct _msg),1,fp);
  3082.  
  3083.             mclose (fpd);
  3084.  
  3085.             sprintf (wrp, "%5d  %-22.22s Fido         ", msgnum, "Raid");
  3086.             wputs (wrp);
  3087.             fseek (fp, (long)sizeof (struct _msg), SEEK_SET);
  3088.             process_raid_request (fp, msg_fzone, msg.orig_net, msg.orig, msg_fpoint, msg.subj);
  3089.             wputs ("\n");
  3090.  
  3091.             fclose (fp);
  3092.             fpd = mopen ("MSGTMP.EXP", "r+b");
  3093.             continue;
  3094.         }
  3095.  
  3096.         if ((msg.attr & MSGSENT) || (ourpoint && !msg_tpoint)) {
  3097.             omsg.attr = msg.attr;
  3098.             omsg.attr |= MSGSENT;
  3099.          if (removesent)
  3100.             omsg.attr &= ~MSGSENT;
  3101.          fseek (fp, 0L, SEEK_SET);
  3102.             fwrite ((char *)&omsg, sizeof(struct _msg), 1, fp);
  3103.             fclose (fp);
  3104.             continue;
  3105.         }
  3106.  
  3107.         omsg.attr = msg.attr;
  3108.         omsg.attr |= MSGSENT;
  3109.       if (removesent)
  3110.          omsg.attr &= ~MSGSENT;
  3111.         fseek (fp, 0L, SEEK_SET);
  3112.         fwrite ((char *)&omsg, sizeof(struct _msg), 1, fp);
  3113.  
  3114.         fclose (fp);
  3115.  
  3116.         if (sys.netmail)
  3117.             sprintf (wrp, "%5d  %-22.22s Fido         ", msgnum, "Netmail");
  3118.         else
  3119.             sprintf (wrp, "%5d  %-22.22s Fido         ", msgnum, "Internet");
  3120.         wputs (wrp);
  3121.  
  3122.         if ((msg.attr & MSGKILL) && !config->keeptransit) {
  3123.             sprintf (buff, "%s%d.MSG", sys.msg_path, msgnum);
  3124.             unlink (buff);
  3125.         }
  3126.  
  3127.         if (!msg_fzone)
  3128.             msg_fzone = config->alias[sys.use_alias].zone;
  3129.         if (!msg_tzone)
  3130.             msg_tzone = msg_fzone;
  3131.  
  3132.         mhdr.ver = PKTVER;
  3133.         mhdr.orig_node = msg.orig;
  3134.         mhdr.orig_net = msg.orig_net;
  3135.         mhdr.dest_node = msg.dest;
  3136.         mhdr.dest_net = msg.dest_net;
  3137.  
  3138.         mhdr.cost = 0;
  3139.  
  3140.         if (sys.public)
  3141.             msg.attr &= ~MSGPRIVATE;
  3142.         else if (sys.private)
  3143.             msg.attr |= MSGPRIVATE;
  3144.         mhdr.attrib = msg.attr & ~(MSGCRASH|MSGSENT|MSGFWD|MSGKILL|MSGLOCAL);
  3145.  
  3146.         sprintf (wrp, "%d:%d/%d.%d ", msg_tzone, msg.dest_net, msg.dest, msg_tpoint);
  3147.         wputs (wrp);
  3148.  
  3149.         gettime (&timep);
  3150.         getdate (&datep);
  3151.  
  3152.         if (!ourpoint && msg_tpoint && check_hold (msg_tzone, msg.dest_net, msg.dest, msg_tpoint))
  3153.             msg.attr |= MSGHOLD;
  3154.  
  3155.         p = HoldAreaNameMungeCreate (msg_tzone);
  3156.         if (ourpoint)
  3157.             sprintf (buff, "%s%04x%04x.PNT\\%08X.XPR", p, msg.dest_net, msg.dest, msg_tpoint);
  3158.         else if (msg_tpoint && (msg.attr & MSGHOLD))
  3159.             sprintf (buff, "%s%04x%04x.PNT\\%08X.%cUT", p, msg.dest_net, msg.dest, msg_tpoint, 'H');
  3160.         else {
  3161.             if (xattr & XATTR_DIR)
  3162.                 sprintf (buff, "%s%04x%04x.%cUT", p, msg.dest_net, msg.dest, 'D');
  3163.             else {
  3164.                 if (msg.attr & MSGCRASH)
  3165.                     sprintf (buff, "%s%04x%04x.%cUT", p, msg.dest_net, msg.dest, 'C');
  3166.                 else if (msg.attr & MSGHOLD)
  3167.                     sprintf (buff, "%s%04x%04x.%cUT", p, msg.dest_net, msg.dest, 'H');
  3168.                 else
  3169.                     sprintf (buff, "%s%04x%04x.XPR", p, msg.dest_net, msg.dest);
  3170.             }
  3171.         }
  3172.         mi = sh_open (buff, SH_DENYWR, O_RDWR|O_CREAT|O_BINARY, S_IREAD|S_IWRITE);
  3173.         if (mi == -1 && msg_tpoint && ((msg.attr & MSGHOLD) || ourpoint)) {
  3174.             sprintf (buff, "%s%04x%04x.PNT", p, msg.dest_net, msg.dest);
  3175.             mkdir (buff);
  3176.             if (msg.attr & MSGHOLD)
  3177.                 sprintf (buff, "%s%04x%04x.PNT\\%08X.%cUT", p, msg.dest_net, msg.dest, msg_tpoint, 'H');
  3178.             else
  3179.                 sprintf (buff, "%s%04x%04x.PNT\\%08X.XPR", p, msg.dest_net, msg.dest, msg_tpoint);
  3180.             mi = sh_open (buff, SH_DENYWR, O_RDWR|O_CREAT|O_BINARY, S_IREAD|S_IWRITE);
  3181.         }
  3182.         if (filelength (mi) > (long)sizeof (struct _pkthdr2))
  3183.             lseek(mi,filelength(mi)-2,SEEK_SET);
  3184.         else {
  3185.             memset ((char *)&pkthdr, 0, sizeof (struct _pkthdr2));
  3186.             pkthdr.ver = PKTVER;
  3187.             pkthdr.product = 0x4E;
  3188.             pkthdr.serial = 2 * 16 + 30;
  3189.             pkthdr.capability = 1;
  3190.             pkthdr.cwvalidation = 256;
  3191.  
  3192.             if (sys.msg_num == 0) {
  3193.                 for (i=0; i < MAX_ALIAS; i++)
  3194.                     if (msg_fzone && config->alias[i].zone == msg_fzone)
  3195.                         break;
  3196.                 if (i == MAX_ALIAS)
  3197.                     z = 0;
  3198.                 else
  3199.                     z = i;
  3200.  
  3201.                 for (i = 0; i < MAX_ALIAS; i++)
  3202.                     if ( config->alias[i].point && config->alias[i].net == msg.orig_net && config->alias[i].node == msg.orig && (!msg_fzone || config->alias[i].zone == msg_fzone) )
  3203.                         break;
  3204.  
  3205.                 if (i < MAX_ALIAS)
  3206.                     z = i;
  3207.             }
  3208.             else
  3209.                 z = sys.use_alias;
  3210.  
  3211.             pkthdr.orig_node = config->alias[z].node;
  3212.             pkthdr.orig_net = config->alias[z].net;
  3213.             pkthdr.orig_zone = config->alias[z].zone;
  3214.             pkthdr.orig_zone2 = config->alias[z].zone;
  3215.             pkthdr.orig_point = config->alias[z].point;
  3216.  
  3217.             pkthdr.dest_node = msg.dest;
  3218.             pkthdr.dest_net = msg.dest_net;
  3219.             pkthdr.dest_zone = msg_tzone;
  3220.             pkthdr.dest_zone2 = msg_tzone;
  3221.             if (ourpoint || (msg_tpoint && (msg.attr & MSGHOLD)))
  3222.                 pkthdr.dest_point = msg_tpoint;
  3223.             pkthdr.hour = timep.ti_hour;
  3224.             pkthdr.minute = timep.ti_min;
  3225.             pkthdr.second = timep.ti_sec;
  3226.             pkthdr.year = datep.da_year;
  3227.             pkthdr.month = datep.da_mon - 1;
  3228.             pkthdr.day = datep.da_day;
  3229.             add_packet_pw (&pkthdr);
  3230.  
  3231.             write (mi, (char *)&pkthdr, sizeof (struct _pkthdr2));
  3232.         }
  3233.  
  3234.         write (mi, (char *)&mhdr, sizeof (struct _msghdr2));
  3235.  
  3236.         write (mi, msg.date, strlen (msg.date) + 1);
  3237.         write (mi, msg.to, strlen (msg.to) + 1);
  3238.         write (mi, msg.from, strlen (msg.from) + 1);
  3239.         write (mi, msg.subj, strlen (msg.subj) + 1);
  3240.  
  3241. //        if (intl_modified||(!intl_found && (config->force_intl || msg_tzone != msg_fzone))) {
  3242.           if (!(!config->force_intl && !intl_found && (msg_tzone==msg_fzone))){
  3243.             sprintf (buffer, msgtxt[M_INTL], msg_tzone, msg.dest_net, msg.dest, msg_fzone, msg.orig_net, msg.orig);
  3244.             write (mi, buffer, strlen (buffer));
  3245.         }
  3246.       if (msg_fpoint) {
  3247.          sprintf (buffer, "\001FMPT %d\r\n", msg_fpoint);
  3248.          write (mi, buffer, strlen (buffer));
  3249.       }
  3250.       if (msg_tpoint) {
  3251.          sprintf (buffer, msgtxt[M_TOPT], msg_tpoint);
  3252.          write (mi, buffer, strlen (buffer));
  3253.       }
  3254.  
  3255.       mseek (fpd, 0L, SEEK_SET);
  3256.       do {
  3257.          z = mread(buffer, 1, 2048, fpd);
  3258.          write(mi, buffer, z);
  3259.       } while (z == 2048);
  3260.       buff[0] = buff[1] = buff[2] = 0;
  3261.       write (mi, buff, 3);
  3262.       close (mi);
  3263.  
  3264.       if (msg.attr & MSGFILE) {
  3265.          p = HoldAreaNameMungeCreate (msg_tzone);
  3266.          if (ourpoint)
  3267.             sprintf (buff, "%s%04x%04x.PNT\\%08X.%cLO", p, msg.dest_net, msg.dest, msg_tpoint, (msg.attr & MSGCRASH) ? 'C' : ((msg.attr & MSGHOLD) ? 'H' : 'F'));
  3268.          else if (msg_tpoint && (msg.attr & MSGHOLD))
  3269.             sprintf (buff, "%s%04x%04x.PNT\\%08X.%cLO", p, msg.dest_net, msg.dest, msg_tpoint, 'H');
  3270.          else
  3271.             sprintf (buff, "%s%04x%04x.%cLO", p, msg.dest_net, msg.dest, (msg.attr & MSGCRASH) ? 'C' : ((msg.attr & MSGHOLD) ? 'H' : 'F'));
  3272.          fp = fopen (buff, "at");
  3273.  
  3274.          if (msg.attr & MSGFWD) {
  3275.             if ((p = strtok (msg.subj, " ")) != NULL)
  3276.                do {
  3277.                   fnsplit (p, NULL, NULL, wrp, buff);
  3278.                   strcat (wrp, buff);
  3279.                   if (config->norm_filepath[0]) {
  3280.                      sprintf (buff, "%s%s", config->norm_filepath, wrp);
  3281.                      if (dexists (buff))
  3282.                         fprintf (fp, "^%s\n", buff);
  3283.                   }
  3284.                   if (config->know_filepath[0]) {
  3285.                      sprintf (buff, "%s%s", config->know_filepath, wrp);
  3286.              if (dexists (buff))
  3287.                         fprintf (fp, "^%s\n", buff);
  3288.                   }
  3289.                   if (config->prot_filepath[0]) {
  3290.                      sprintf (buff, "%s%s", config->prot_filepath, wrp);
  3291.                      if (dexists (buff))
  3292.                         fprintf (fp, "^%s\n", buff);
  3293.                   }
  3294.                } while ((p = strtok (NULL, " ")) != NULL);
  3295.          }
  3296.          else {
  3297.             if ((p = strtok (msg.subj, " ")) != NULL)
  3298.                do {
  3299.                   if (xattr & XATTR_KFS)
  3300.                      fprintf (fp, "^%s\n", p);
  3301.                   else if (xattr & XATTR_TFS)
  3302.                      fprintf (fp, "#%s\n", p);
  3303.                   else
  3304.                      fprintf (fp, "%s\n", p);
  3305.                } while ((p = strtok (NULL, " ")) != NULL);
  3306.          }
  3307.  
  3308.          fclose (fp);
  3309.       }
  3310.       else if (msg.attr & MSGFRQ) {
  3311.      p = HoldAreaNameMungeCreate (msg_tzone);
  3312.             if (ourpoint)
  3313.                 sprintf (buff, "%s%04x%04x.PNT\\%08X.REQ", p, msg.dest_net, msg.dest, msg_tpoint);
  3314.             else if (msg_tpoint && (msg.attr & MSGHOLD))
  3315.                 sprintf (buff, "%s%04x%04x.PNT\\%08X.REQ", p, msg.dest_net, msg.dest);
  3316.             else
  3317.                 sprintf (buff, "%s%04x%04x.REQ", p, msg.dest_net, msg.dest);
  3318.             fp = fopen (buff, "at");
  3319.  
  3320.             if ((p = strtok (msg.subj, " ")) != NULL)
  3321.                 do {
  3322.                     b = strtok (NULL, " ");
  3323.                     if (b != NULL && *b == '!') {
  3324.                         fprintf (fp, "%s %s\n", p, b);
  3325.                         p = strtok (NULL, " ");
  3326.                     }
  3327.                     else {
  3328.                         fprintf (fp, "%s\n", p);
  3329.                         p = b;
  3330.                     }
  3331.                 } while (p != NULL);
  3332.  
  3333.             fclose (fp);
  3334.         }
  3335.  
  3336.         wputs ("\n");
  3337.  
  3338.         sent++;
  3339.         sysinfo.today.emailsent++;
  3340.         sysinfo.week.emailsent++;
  3341.         sysinfo.month.emailsent++;
  3342.         sysinfo.year.emailsent++;
  3343.  
  3344.         time_release ();
  3345.     }
  3346.  
  3347.     status_line (":  Packed=%d", sent);
  3348.  
  3349.     mclose (fpd);
  3350.     unlink ("MSGTMP.EXP");
  3351.     return (0);
  3352. }
  3353.  
  3354.