home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / SQUISH.C < prev    next >
Text File  |  1998-05-17  |  75KB  |  2,379 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 <time.h>
  27. #include <dos.h>
  28. #include <sys\stat.h>
  29.  
  30. #include <cxl\cxlvid.h>
  31. #include <cxl\cxlwin.h>
  32.  
  33. #include "lsetup.h"
  34. #include "sched.h"
  35. #include "msgapi.h"
  36. #include "externs.h"
  37. #include "prototyp.h"
  38. #include "msgapi.h"
  39. #include "bluewave.h"
  40.  
  41. extern int maxakainfo, msg_parent, msg_child;
  42. extern struct _akainfo *akainfo;
  43. extern char *internet_to;
  44.  
  45. extern struct _node2name *nametable; // Gestione nomi per aree PRIVATE
  46. extern int nodes_num;
  47.  
  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. long memlength (void);
  55. void replace_tearline (FILE *fpd, char *buf);
  56. void add_quote_string (char *str, char *from);
  57. void add_quote_header (FILE *fp, char *from, char *to, char *subj, char *dt, char *tm);
  58. int open_packet (int zone, int net, int node, int point, int ai);
  59. void bluewave_header (int fdi, long startpos, long numbytes, int msgnum, struct _msg *msgt);
  60.  
  61. void squish_scan_message_base (area, name, upd)
  62. int area;
  63. char *name, upd;
  64. {
  65.     int i;
  66.  
  67.     if (sq_ptr != NULL) {
  68.         MsgUnlock (sq_ptr);
  69.         MsgCloseArea (sq_ptr);
  70.     }
  71.  
  72.     sq_ptr = MsgOpenArea (name, MSGAREA_CRIFNEC, MSGTYPE_SQUISH);
  73.  
  74.     if(sq_ptr == NULL){
  75.         status_line("! Critical: Unable to open %s",name);
  76.     }
  77.  
  78.     MsgUnlock (sq_ptr);
  79.  
  80.     num_msg = (int)MsgGetNumMsg (sq_ptr);
  81.     if (num_msg)
  82.         first_msg = 1;
  83.     else
  84.         first_msg = 0;
  85.     last_msg = num_msg;
  86.     msg_parent = msg_child = 0;
  87.  
  88.     for (i=0;i<MAXLREAD;i++)
  89.         if (usr.lastread[i].area == area)
  90.             break;
  91.     if (i != MAXLREAD) {
  92.         if (usr.lastread[i].msg_num > last_msg)
  93.             usr.lastread[i].msg_num = last_msg;
  94.         lastread = usr.lastread[i].msg_num;
  95.     }
  96.     else {
  97.         for (i=0;i<MAXDLREAD;i++)
  98.             if (usr.dynlastread[i].area == area)
  99.                 break;
  100.         if (i != MAXDLREAD) {
  101.             if (usr.dynlastread[i].msg_num > last_msg)
  102.                 usr.dynlastread[i].msg_num = last_msg;
  103.             lastread = usr.dynlastread[i].msg_num;
  104.         }
  105.         else if (upd) {
  106.             lastread = 0;
  107.             for (i=1;i<MAXDLREAD;i++) {
  108.                 usr.dynlastread[i-1].area = usr.dynlastread[i].area;
  109.                 usr.dynlastread[i-1].msg_num = usr.dynlastread[i].msg_num;
  110.             }
  111.  
  112.             usr.dynlastread[i-1].area = area;
  113.             usr.dynlastread[i-1].msg_num = 0;
  114.         }
  115.         else
  116.             lastread = 0;
  117.     }
  118.  
  119.     if (lastread < 0)
  120.         lastread = 0;
  121. }
  122.  
  123. #ifndef POINT
  124. static void date_conversion (XMSG *xmsg)
  125. {
  126.     sprintf (xmsg->ftsc_date, "%2d %3s %2d %2d:%2d:%2d", xmsg->date_written.date.da, mtext[xmsg->date_written.date.mo - 1], xmsg->date_written.date.yr + 80, xmsg->date_written.time.hh, xmsg->date_written.time.mm, xmsg->date_written.time.ss);
  127. }
  128.  
  129. int squish_read_message(msg_num, flag, fakenum)
  130. int msg_num, flag, fakenum;
  131. {
  132.     int i, z, m, line, colf=0, xx, rd;
  133.     char c, buff[80], wrp[80], *p, sqbuff[80];
  134.     long fpos;
  135.     MSGH *sq_msgh;
  136.     XMSG xmsg;
  137.  
  138.     if (sq_ptr == NULL) {
  139.         squish_scan_message_base (sys.msg_num, sys.msg_path, 1);
  140.         if (sq_ptr == NULL)
  141.             return (0);
  142.     }
  143.  
  144.     if (usr.full_read && !flag)
  145.         return (squish_full_read_message(msg_num, fakenum));
  146.  
  147.     line = 1;
  148.     msg_fzone = msg_tzone = config->alias[0].zone;
  149.     msg_fpoint = msg_tpoint = 0;
  150.  
  151.     sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_RW, (dword)msg_num);
  152.     if (sq_msgh == NULL)
  153.         return(0);
  154.  
  155.    if (MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 0, NULL) == -1) {
  156.       MsgCloseMsg (sq_msgh);
  157.       return (0);
  158.    }
  159.  
  160.    if (!stricmp (xmsg.from,"ARCmail") && !stricmp (xmsg.to, "Sysop")) {
  161.       MsgCloseMsg (sq_msgh);
  162.       return (0);
  163.    }
  164.  
  165.    if (xmsg.attr & MSGPRIVATE)
  166.       if (stricmp(xmsg.from,usr.name) && stricmp(xmsg.to,usr.name) && stricmp(xmsg.from,usr.handle) && stricmp(xmsg.to,usr.handle) && usr.priv != SYSOP) {
  167.          MsgCloseMsg (sq_msgh);
  168.          return (0);
  169.       }
  170.  
  171.    if (!flag)
  172.       cls ();
  173.  
  174.    memset ((char *)&msg, 0, sizeof (struct _msg));
  175.    strcpy (msg.from, xmsg.from);
  176.    strcpy (msg.to, xmsg.to);
  177.    strcpy (msg.subj, xmsg.subj);
  178.    if (!xmsg.ftsc_date[0])
  179.       date_conversion (&xmsg);
  180.    strcpy (msg.date, xmsg.ftsc_date);
  181.    msg_fzone = xmsg.orig.zone;
  182.    msg.orig = xmsg.orig.node;
  183.    msg.orig_net = xmsg.orig.net;
  184.    msg_fpoint = xmsg.orig.point;
  185.    msg_tzone = xmsg.dest.zone;
  186.    msg.dest = xmsg.dest.node;
  187.    msg.dest_net = xmsg.dest.net;
  188.    msg_tpoint = xmsg.dest.point;
  189.    msg.attr = (word)xmsg.attr;
  190.    msg_parent = (int)MsgUidToMsgn (sq_ptr, xmsg.replyto, UID_EXACT);
  191.    msg_child = (int)MsgUidToMsgn (sq_ptr, xmsg.replies[0], UID_EXACT);
  192.  
  193.    if (flag)
  194.       m_print(bbstxt[B_TWO_CR]);
  195.  
  196.    change_attr (WHITE|_BLACK);
  197.    m_print (" * %s\n", sys.msg_name);
  198.  
  199.    change_attr (CYAN|_BLACK);
  200.    line = msg_attrib (&msg, fakenum ? fakenum : msg_num, line, 0);
  201.    m_print(bbstxt[B_ONE_CR]);
  202.  
  203.    allow_reply = 1;
  204.    i = 0;
  205.    fpos = 0L;
  206.  
  207.    do {
  208.       rd = (int)MsgReadMsg (sq_msgh, NULL, fpos, 80L, sqbuff, 0, NULL);
  209.       fpos += (long)rd;
  210.  
  211.       for (xx = 0; xx < rd; xx++) {
  212.          c = sqbuff[xx];
  213.          if ((byte)c == 0x8D || c == 0x0A || c == '\0')
  214.             continue;
  215.  
  216.          buff[i++]=c;
  217.  
  218.          if(c == 0x0D) {
  219.             buff[i-1]='\0';
  220.  
  221.             if (!usr.kludge && (!strncmp (buff, "SEEN-BY", 7) || buff[0] == 0x01)) {
  222.                i = 0;
  223.                continue;
  224.             }
  225.  
  226.             p = &buff[0];
  227.  
  228.             if (((strchr (buff, '>') - p) < 6) && (strchr (buff, '>'))) {
  229.                if (!colf) {
  230.                   change_attr (LGREY|BLACK);
  231.                   colf = 1;
  232.                }
  233.             }
  234.             else {
  235.                if (colf) {
  236.                   change_attr (CYAN|BLACK);
  237.                   colf = 0;
  238.                }
  239.             }
  240.  
  241.             if (!strncmp (buff, msgtxt[M_TEAR_LINE], 4) || !strncmp (buff, msgtxt[M_ORIGIN_LINE], 11))
  242.                m_print ("%s\n", buff);
  243.             else if (buff[0] == 0x01)
  244.                m_print (" %s\n", &buff[1]);
  245.             else if (!strncmp (buff, "SEEN-BY", 7)) {
  246.                m_print (" %s\n", buff);
  247.                change_attr (LGREY|BLACK);
  248.             }
  249.             else
  250.                m_print ("%s\n", buff);
  251.  
  252.             if (!strncmp (buff, msgtxt[M_ORIGIN_LINE], 11))
  253.                gather_origin_netnode (buff);
  254.  
  255.             i = 0;
  256.  
  257.             if (flag == 1)
  258.                line = 1;
  259.  
  260.             if (!(++line < (usr.len - 1)) && usr.more) {
  261.                line = 1;
  262.                if (!continua ()) {
  263.                   flag = 1;
  264.                   rd = 0;
  265.                   break;
  266.                }
  267.             }
  268.          }
  269.          else {
  270.             if (i < (usr.width - 1))
  271.                continue;
  272.  
  273.             buff[i] = '\0';
  274.             while (i > 0 && buff[i] != ' ')
  275.                i--;
  276.  
  277.             m = 0;
  278.  
  279.             if (i != 0)
  280.                for (z = i + 1; buff[z]; z++)
  281.                   wrp[m++] = buff[z];
  282.  
  283.             buff[i] = '\0';
  284.             wrp[m] = '\0';
  285.  
  286.             if (((strchr (buff, '>') - buff) < 6) && (strchr (buff, '>'))) {
  287.                if (!colf) {
  288.                   change_attr (LGREY|_BLACK);
  289.                   colf = 1;
  290.                }
  291.             }
  292.             else {
  293.                if (colf) {
  294.                   change_attr (CYAN|_BLACK);
  295.                   colf = 0;
  296.                }
  297.             }
  298.  
  299.             if (!strncmp (buff, msgtxt[M_TEAR_LINE],4) || !strncmp (buff, msgtxt[M_ORIGIN_LINE], 11))
  300.                m_print ("%s\n", buff);
  301.             else
  302.                m_print ("%s\n", buff);
  303.  
  304.             if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  305.                gather_origin_netnode (buff);
  306.  
  307.             if (flag == 1)
  308.                line = 1;
  309.  
  310.             if (!(++line < (usr.len - 1)) && usr.more) {
  311.                line = 1;
  312.                if (!continua ()) {
  313.                   flag = 1;
  314.                   rd = 0;
  315.                   break;
  316.                }
  317.             }
  318.  
  319.             strcpy (buff, wrp);
  320.             i = strlen(wrp);
  321.          }
  322.       }
  323.    } while (rd == 80);
  324.  
  325.    if ((!stricmp(xmsg.to, usr.name) || !stricmp(xmsg.to, usr.handle)) && !(xmsg.attr & MSGREAD)) {
  326.       xmsg.attr |= MSGREAD;
  327.       MsgWriteMsg (sq_msgh, 1, &xmsg, NULL, 0, 0, 0, NULL);
  328.    }
  329.  
  330.    MsgCloseMsg (sq_msgh);
  331.  
  332.    if (line > 1 && !flag && usr.more)
  333.       press_enter();
  334.  
  335.    return(1);
  336. }
  337.  
  338. int squish_full_read_message(msg_num, fakenum)
  339. int msg_num, fakenum;
  340. {
  341.    int i, z, m, line, colf=0, xx, rd;
  342.    char c, buff[80], wrp[80], *p, sqbuff[80];
  343.    long fpos;
  344.    MSGH *sq_msgh;
  345.    XMSG xmsg;
  346.  
  347.    line = 2;
  348.    msg_fzone = msg_tzone = config->alias[0].zone;
  349.    msg_fpoint = msg_tpoint = 0;
  350.  
  351.    sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_RW, (dword)msg_num);
  352.    if (sq_msgh == NULL)
  353.       return(0);
  354.  
  355.    if (MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 0, NULL) == -1) {
  356.       MsgCloseMsg (sq_msgh);
  357.       return (0);
  358.    }
  359.  
  360.    if (!stricmp (xmsg.from,"ARCmail") && !stricmp (xmsg.to, "Sysop")) {
  361.       MsgCloseMsg (sq_msgh);
  362.       return (0);
  363.    }
  364.  
  365.    if (xmsg.attr & MSGPRIVATE)
  366.       if (stricmp(xmsg.from,usr.name) && stricmp(xmsg.to,usr.name) && stricmp(xmsg.from,usr.handle) && stricmp(xmsg.to,usr.handle) && usr.priv != SYSOP) {
  367.          MsgCloseMsg (sq_msgh);
  368.          return (0);
  369.       }
  370.  
  371.    memset ((char *)&msg, 0, sizeof (struct _msg));
  372.    strcpy (msg.from, xmsg.from);
  373.    strcpy (msg.to, xmsg.to);
  374.    strcpy (msg.subj, xmsg.subj);
  375.    if (!xmsg.ftsc_date[0])
  376.       date_conversion (&xmsg);
  377.    strcpy (msg.date, xmsg.ftsc_date);
  378.    msg_fzone = xmsg.orig.zone;
  379.    msg.orig = xmsg.orig.node;
  380.    msg.orig_net = xmsg.orig.net;
  381.    msg_fpoint = xmsg.orig.point;
  382.    msg_tzone = xmsg.dest.zone;
  383.    msg.dest = xmsg.dest.node;
  384.    msg.dest_net = xmsg.dest.net;
  385.    msg_tpoint = xmsg.dest.point;
  386.    msg.attr = (word)xmsg.attr;
  387.    msg_parent = (int)MsgUidToMsgn (sq_ptr, xmsg.replyto, UID_EXACT);
  388.    msg_child = (int)MsgUidToMsgn (sq_ptr, xmsg.replies[0], UID_EXACT);
  389.  
  390.    cls ();
  391.    change_attr (BLUE|_LGREY);
  392.    del_line ();
  393.    m_print (" * %s\n", sys.msg_name);
  394.    change_attr (CYAN|_BLACK);
  395.    line = msg_attrib (&msg, fakenum ? fakenum : msg_num, line, 0);
  396.    change_attr (LGREY|_BLUE);
  397.    del_line ();
  398.    change_attr (CYAN|_BLACK);
  399.    m_print(bbstxt[B_ONE_CR]);
  400.  
  401.    allow_reply = 1;
  402.    i = 0;
  403.    fpos = 0L;
  404.  
  405.    do {
  406.       rd = (int)MsgReadMsg (sq_msgh, NULL, fpos, 80L, sqbuff, 0, NULL);
  407.       fpos += (long)rd;
  408.  
  409.       for (xx = 0; xx < rd; xx++) {
  410.          c = sqbuff[xx];
  411.          if ((byte)c == 0x8D || c == 0x0A || c == '\0')
  412.             continue;
  413.  
  414.          buff[i++]=c;
  415.  
  416.          if(c == 0x0D) {
  417.             buff[i-1]='\0';
  418.  
  419.             if (!usr.kludge && (!strncmp (buff, "SEEN-BY", 7) || buff[0] == 0x01)) {
  420.                i = 0;
  421.                continue;
  422.             }
  423.  
  424.             p = &buff[0];
  425.  
  426.             if (((strchr (buff, '>') - p) < 6) && (strchr (buff, '>'))) {
  427.                if (!colf) {
  428.                   change_attr (LGREY|BLACK);
  429.                   colf = 1;
  430.                }
  431.             }
  432.             else {
  433.                if (colf) {
  434.                   change_attr (CYAN|BLACK);
  435.                   colf = 0;
  436.                }
  437.             }
  438.  
  439.             if (!strncmp (buff, msgtxt[M_TEAR_LINE], 4) || !strncmp (buff, msgtxt[M_ORIGIN_LINE], 11))
  440.                m_print ("%s\n", buff);
  441.             else if (buff[0] == 0x01)
  442.                m_print (" %s\n", &buff[1]);
  443.             else if (!strncmp (buff, "SEEN-BY", 7)) {
  444.                m_print (" %s\n", buff);
  445.                change_attr (LGREY|BLACK);
  446.             }
  447.             else
  448.                m_print ("%s\n", buff);
  449.  
  450.             if (!strncmp (buff, msgtxt[M_ORIGIN_LINE], 11))
  451.                gather_origin_netnode (buff);
  452.  
  453.             i = 0;
  454.  
  455.             if (!(++line < (usr.len - 1)) && usr.more) {
  456.                if (!continua ()) {
  457.                   line = 1;
  458.                   rd = 0;
  459.                   break;
  460.                }
  461.                else
  462.                   while (line > 5) {
  463.                      cpos (line--, 1);
  464.                      del_line ();
  465.                   }
  466.             }
  467.          }
  468.          else {
  469.             if (i < (usr.width - 1))
  470.                continue;
  471.  
  472.             buff[i] = '\0';
  473.             while (i > 0 && buff[i] != ' ')
  474.                i--;
  475.  
  476.             m = 0;
  477.  
  478.             if (i != 0)
  479.                for (z = i + 1; buff[z]; z++)
  480.                   wrp[m++] = buff[z];
  481.  
  482.             buff[i] = '\0';
  483.             wrp[m] = '\0';
  484.  
  485.             if (((strchr (buff, '>') - buff) < 6) && (strchr (buff, '>'))) {
  486.                if (!colf) {
  487.                   change_attr (LGREY|_BLACK);
  488.                   colf = 1;
  489.                }
  490.             }
  491.             else {
  492.                if (colf) {
  493.                   change_attr (CYAN|_BLACK);
  494.                   colf = 0;
  495.                }
  496.             }
  497.  
  498.             if (!strncmp (buff, msgtxt[M_TEAR_LINE],4) || !strncmp (buff, msgtxt[M_ORIGIN_LINE], 11))
  499.                m_print ("%s\n", buff);
  500.             else
  501.                m_print ("%s\n", buff);
  502.  
  503.             if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  504.                gather_origin_netnode (buff);
  505.  
  506.             if (!(++line < (usr.len - 1)) && usr.more) {
  507.                if (!continua ()) {
  508.                   line = 1;
  509.                   rd = 0;
  510.                   break;
  511.                     }
  512.                else
  513.                   while (line > 5) {
  514.                      cpos (line--, 1);
  515.                      del_line ();
  516.                   }
  517.             }
  518.  
  519.             strcpy (buff, wrp);
  520.             i = strlen(wrp);
  521.          }
  522.       }
  523.    } while (rd == 80);
  524.  
  525.    if ((!stricmp(xmsg.to, usr.name) || !stricmp(xmsg.to,usr.name)||
  526.    !stricmp(xmsg.to, usr.handle) || !stricmp(xmsg.to, usr.handle)) && !(xmsg.attr & MSGREAD)) {
  527.       xmsg.attr |= MSGREAD;
  528.       MsgWriteMsg (sq_msgh, 1, &xmsg, NULL, 0, 0, 0, NULL);
  529.    }
  530.  
  531.    MsgCloseMsg (sq_msgh);
  532.  
  533.    if (line > 1 && usr.more)
  534.         press_enter();
  535.  
  536.     return(1);
  537. }
  538.  
  539. void squish_save_message(txt)
  540. char *txt;
  541. {
  542.     int i, dest;
  543.     char origin[128], tear[50], signature[100], pid[40], msgid[40], string[50];
  544.     long totlen;
  545.     unsigned long crc;
  546.     struct date da;
  547.     struct time ti;
  548.     MSGH *sq_msgh;
  549.     XMSG xmsg;
  550.  
  551.     if (!sq_ptr){
  552.         sq_ptr = MsgOpenArea (sys.msg_path, MSGAREA_CRIFNEC, MSGTYPE_SQUISH);
  553.         if (sq_ptr == NULL)
  554.         return;
  555.     }
  556.  
  557.     while (MsgLock (sq_ptr) == -1 && msgapierr != MERR_NOMEM)
  558.         ;
  559.  
  560.     m_print(bbstxt[B_SAVE_MESSAGE]);
  561.     dest = (int)MsgGetNumMsg (sq_ptr) + 1;
  562.     activation_key ();
  563.     m_print(" #%d ...",dest);
  564.  
  565.     sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_CREATE, (dword)0);
  566.     if (sq_msgh == NULL) {
  567.         MsgUnlock (sq_ptr);
  568.         return;
  569.     }
  570.  
  571.     memset ((char *)&xmsg, 0, sizeof (XMSG));
  572.     strcpy (xmsg.from, msg.from);
  573.     strcpy (xmsg.to, msg.to);
  574.     strcpy (xmsg.subj, msg.subj);
  575.     strcpy (xmsg.ftsc_date, msg.date);
  576.     getdate (&da);
  577.     gettime (&ti);
  578.     xmsg.date_written.date.da = xmsg.date_arrived.date.da = da.da_day;
  579.     xmsg.date_written.date.mo = xmsg.date_arrived.date.mo = da.da_mon;
  580.     xmsg.date_written.date.yr = xmsg.date_arrived.date.yr = (da.da_year % 100) - 80;
  581.     xmsg.date_written.time.hh = xmsg.date_arrived.time.hh = ti.ti_hour;
  582.     xmsg.date_written.time.mm = xmsg.date_arrived.time.mm = ti.ti_min;
  583.     xmsg.date_written.time.ss = xmsg.date_arrived.time.ss = ti.ti_sec;
  584.     xmsg.orig.zone = config->alias[sys.use_alias].zone;
  585.     xmsg.orig.node = config->alias[sys.use_alias].node;
  586.     xmsg.orig.net = config->alias[sys.use_alias].net;
  587.     xmsg.dest.zone = msg_tzone;
  588.     xmsg.dest.node = msg.dest;
  589.     xmsg.dest.net = msg.dest_net;
  590.     xmsg.dest.point = msg_tpoint;
  591.     xmsg.attr = msg.attr;
  592.  
  593.     totlen = 2L;
  594.  
  595.     if (strlen(usr.signature) && registered) {
  596.         sprintf (signature, msgtxt[M_SIGNATURE], usr.signature);
  597.         totlen += (long)strlen (signature);
  598.     }
  599.  
  600.     if (sys.echomail) {
  601.         sprintf (tear, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  602.         if (strlen (sys.origin))
  603.             sprintf (origin, 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);
  604.         else
  605.             sprintf (origin, 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);
  606.  
  607.         sprintf(pid,msgtxt[M_PID], VERSION, registered ? "" : NOREG);
  608.  
  609.         crc = time (NULL);
  610.         crc = string_crc(msg.from,crc);
  611.         crc = string_crc(msg.to,crc);
  612.         crc = string_crc(msg.subj,crc);
  613.         crc = string_crc(msg.date,crc);
  614.  
  615.         sprintf(msgid,msgtxt[M_MSGID], config->alias[sys.use_alias].zone, config->alias[sys.use_alias].net, config->alias[sys.use_alias].node, config->alias[sys.use_alias].point, crc);
  616.  
  617.         totlen += (long)strlen (tear);
  618.         totlen += (long)strlen (origin);
  619.         totlen += (long)strlen (pid);
  620.         totlen += (long)strlen (msgid);
  621.     }
  622.  
  623.     if (sys.internet_mail && internet_to != NULL) {
  624.         sprintf (string, "To: %s\r\n\r\n", internet_to);
  625.         free (internet_to);
  626.         totlen += (long)strlen (string);
  627.     }
  628.  
  629.     if (txt == NULL) {
  630.         i = 0;
  631.         while (messaggio[i] != NULL) {
  632.             totlen += (long)strlen (messaggio[i]);
  633.             i++;
  634.         }
  635.  
  636.         MsgWriteMsg (sq_msgh, 0, &xmsg, NULL, 0L, totlen, 1L, "\x00");
  637.  
  638.         if (sys.echomail) {
  639.             MsgWriteMsg (sq_msgh, 1, NULL, pid, strlen (pid), totlen, 0L, NULL);
  640.             MsgWriteMsg (sq_msgh, 1, NULL, msgid, strlen (msgid), totlen, 0L, NULL);
  641.         }
  642.  
  643.         if (sys.internet_mail)
  644.             MsgWriteMsg (sq_msgh, 1, NULL, string, strlen (string), totlen, 0L, NULL);
  645.  
  646.         i = 0;
  647.         while (messaggio[i] != NULL) {
  648.             MsgWriteMsg (sq_msgh, 1, NULL, messaggio[i], (long)strlen(messaggio[i]), totlen, 0L, NULL);
  649.             i++;
  650.       }
  651.    }
  652.    else {
  653.       int fptxt, m;
  654.       char buffer[2050];
  655.  
  656.       fptxt = shopen (txt, O_RDONLY|O_BINARY);
  657.       if (fptxt == -1) {
  658.          MsgUnlock (sq_ptr);
  659.          return;
  660.       }
  661.  
  662.       MsgWriteMsg (sq_msgh, 0, &xmsg, NULL, 0L, totlen + filelength (fptxt), 1L, "\x00");
  663.  
  664.       if (sys.echomail) {
  665.          MsgWriteMsg (sq_msgh, 1, NULL, pid, strlen (pid), totlen, 0L, NULL);
  666.          MsgWriteMsg (sq_msgh, 1, NULL, msgid, strlen (msgid), totlen, 0L, NULL);
  667.       }
  668.  
  669.       do {
  670.          i = read (fptxt, buffer, 2048);
  671.          for (m = 0; m < i; m++) {
  672.             if (buffer[m] == 0x1A)
  673.                buffer[m] = ' ';
  674.          }
  675.  
  676.          MsgWriteMsg (sq_msgh, 1, NULL, buffer, (long)i, totlen, 0L, NULL);
  677.       } while (i == 2048);
  678.  
  679.       close(fptxt);
  680.    }
  681.  
  682.    MsgWriteMsg (sq_msgh, 1, NULL, "\r\n", 2L, totlen, 0L, NULL);
  683.  
  684.    if (strlen(usr.signature) && registered)
  685.       MsgWriteMsg (sq_msgh, 1, NULL, signature, strlen (signature), totlen, 0L, NULL);
  686.  
  687.    if (sys.echomail) {
  688.       MsgWriteMsg (sq_msgh, 1, NULL, tear, strlen (tear), totlen, 0L, NULL);
  689.       MsgWriteMsg (sq_msgh, 1, NULL, origin, strlen (origin), totlen, 0L, NULL);
  690.    }
  691.  
  692.    MsgCloseMsg (sq_msgh);
  693.    MsgUnlock (sq_ptr);
  694.  
  695.    m_print (bbstxt[B_XPRT_DONE]);
  696.    status_line(msgtxt[M_INSUFFICIENT_DATA], dest, sys.msg_num);
  697.    num_msg = last_msg = dest;
  698. }
  699.  
  700. int squish_write_message_text (msg_num, flags, quote_name, sm)
  701. int msg_num, flags;
  702. char *quote_name;
  703. FILE *sm;
  704. {
  705.    FILE *fpq;
  706.    int i, z, m, pos, blks, xx, rd;
  707.    char c, buff[80], wrp[80], qwkbuffer[130], sqbuff[80];
  708.    long fpos, qpos;
  709.    struct _msg msgt;
  710.    struct QWKmsghd QWK;
  711.    MSGH *sq_msgh;
  712.    XMSG xmsg;
  713.  
  714.    msg_fzone = msg_tzone = config->alias[0].zone;
  715.    msg_fpoint = msg_tpoint = 0;
  716.  
  717.    sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_RW, (dword)msg_num);
  718.    if (sq_msgh == NULL)
  719.       return(0);
  720.  
  721.    if (MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 0, NULL) == -1) {
  722.       MsgCloseMsg (sq_msgh);
  723.       return (0);
  724.    }
  725.  
  726.    if (!stricmp (xmsg.from,"ARCmail") && !stricmp (xmsg.to, "Sysop")) {
  727.       MsgCloseMsg (sq_msgh);
  728.       return (0);
  729.    }
  730.  
  731.    if (xmsg.attr & MSGPRIVATE)
  732.       if (stricmp(xmsg.from,usr.name) && stricmp(xmsg.to,usr.name) 
  733.       && stricmp(xmsg.from,usr.handle) && stricmp(xmsg.to,usr.handle) && usr.priv != SYSOP) {
  734.          MsgCloseMsg (sq_msgh);
  735.          return (0);
  736.       }
  737.  
  738.    memset ((char *)&msgt, 0, sizeof (struct _msg));
  739.    strcpy (msgt.from, xmsg.from);
  740.    strcpy (msgt.to, xmsg.to);
  741.    strcpy (msgt.subj, xmsg.subj);
  742.    if (!xmsg.ftsc_date[0])
  743.       date_conversion (&xmsg);
  744.    strcpy (msgt.date, xmsg.ftsc_date);
  745.    msg_fzone = xmsg.orig.zone;
  746.    msgt.orig = xmsg.orig.node;
  747.    msgt.orig_net = xmsg.orig.net;
  748.    msg_fpoint = xmsg.orig.point;
  749.    msg_tzone = xmsg.dest.zone;
  750.    msgt.dest = xmsg.dest.node;
  751.    msgt.dest_net = xmsg.dest.net;
  752.    msg_tpoint = xmsg.dest.point;
  753.    msg.attr = (word)xmsg.attr;
  754.  
  755.    blks = 1;
  756.    pos = 0;
  757.    memset (qwkbuffer, ' ', 128);
  758.  
  759.    if (sm == NULL) {
  760.       fpq = fopen (quote_name, (flags & APPEND_TEXT) ? "at" : "wt");
  761.       if (fpq == NULL) {
  762.          MsgCloseMsg (sq_msgh);
  763.          return (0);
  764.       }
  765.    }
  766.    else
  767.       fpq = sm;
  768.  
  769.    if (flags & QUOTE_TEXT) {
  770.       add_quote_string (buff, msgt.from);
  771.       i = strlen (buff);
  772.    }
  773.    else
  774.       i = 0;
  775.  
  776.    fpos = 0L;
  777.  
  778.    if (flags & INCLUDE_HEADER) {
  779.       text_header (&msgt, msg_num, fpq);
  780.    }
  781.    else if (flags & QWK_TEXTFILE)
  782.       qwk_header (&msgt, &QWK, msg_num, fpq, &qpos);
  783.    else if (flags & QUOTE_TEXT)
  784.       add_quote_header (fpq, msgt.from, msgt.to, msgt.subj, msgt.date, NULL);
  785.  
  786.    do {
  787.       rd = (int)MsgReadMsg (sq_msgh, NULL, fpos, 80L, sqbuff, 0, NULL);
  788.       fpos += (long)rd;
  789.  
  790.       for (xx = 0; xx < rd; xx++) {
  791.          c = sqbuff[xx];
  792.          if ((byte)c == 0x8D || c == 0x0A || c == '\0')
  793.             continue;
  794.  
  795.          buff[i++]=c;
  796.  
  797.          if (c == 0x0D) {
  798.             buff[i-1] = '\0';
  799.             if (!strnicmp (buff, msgtxt[M_TEAR_LINE], 4))
  800.                buff[1] = '+';
  801.             if (!strnicmp (buff, msgtxt[M_ORIGIN_LINE], 10))
  802.                buff[3] = '0';
  803.  
  804.             if (strchr (buff, 0x01) != NULL || stristr (buff, "SEEN-BY") != NULL) {
  805.                if (flags & QUOTE_TEXT) {
  806.                   add_quote_string (buff, msgt.from);
  807.                   i = strlen (buff);
  808.                }
  809.                else
  810.                   i = 0;
  811.                continue;
  812.             }
  813.  
  814.             if (flags & QWK_TEXTFILE) {
  815.                write_qwk_string (buff, qwkbuffer, &pos, &blks, fpq);
  816.                write_qwk_string ("\r\n", qwkbuffer, &pos, &blks, fpq);
  817.             }
  818.             else
  819.                fprintf (fpq, "%s\n", buff);
  820.  
  821.             if (flags & QUOTE_TEXT) {
  822.                add_quote_string (buff, msgt.from);
  823.                i = strlen(buff);
  824.             }
  825.             else
  826.                i = 0;
  827.          }
  828.          else {
  829.             if (i < (usr.width - 1))
  830.                continue;
  831.  
  832.             buff[i] = '\0';
  833.             while (i > 0 && buff[i] != ' ')
  834.                i--;
  835.  
  836.             m = 0;
  837.  
  838.             if (i != 0)
  839.                for (z = i + 1; buff[z]; z++)
  840.                   wrp[m++] = buff[z];
  841.  
  842.             buff[i] = '\0';
  843.             wrp[m] = '\0';
  844.             if (!strnicmp (buff, msgtxt[M_TEAR_LINE], 4))
  845.                buff[1] = '+';
  846.             if (!strnicmp (buff, msgtxt[M_ORIGIN_LINE], 10))
  847.                buff[3] = '0';
  848.  
  849.             if (flags & QWK_TEXTFILE) {
  850.                write_qwk_string (buff, qwkbuffer, &pos, &blks, fpq);
  851.                write_qwk_string ("\r\n", qwkbuffer, &pos, &blks, fpq);
  852.             }
  853.             else
  854.                fprintf (fpq, "%s\n", buff);
  855.  
  856.             if (flags & QUOTE_TEXT)
  857.                add_quote_string (buff, msgt.from);
  858.             else
  859.                buff[0] = '\0';
  860.  
  861.             strcat (buff, wrp);
  862.             i = strlen (buff);
  863.          }
  864.       }
  865.    } while (rd == 80);
  866.  
  867.    if ((!stricmp(xmsg.to, usr.name)||!stricmp(xmsg.to, usr.handle)) && !(xmsg.attr & MSGREAD)) {
  868.       xmsg.attr |= MSGREAD;
  869.       MsgWriteMsg (sq_msgh, 1, &xmsg, NULL, 0, 0, 0, NULL);
  870.    }
  871.  
  872.    MsgCloseMsg (sq_msgh);
  873.  
  874.    if (flags & QWK_TEXTFILE) {
  875.       qwkbuffer[128] = 0;
  876.       fwrite (qwkbuffer, 128, 1, fpq);
  877.       blks++;
  878.  
  879.    /* Now update with record count */
  880.       fseek (fpq, qpos, SEEK_SET);          /* Restore back to header start */
  881.       sprintf (buff, "%d", blks);
  882.       ljstring (QWK.Msgrecs, buff, 6);
  883.       fwrite ((char *)&QWK, 128, 1, fpq);           /* Write out the header */
  884.       fseek (fpq, 0L, SEEK_END);               /* Bump back to end of file */
  885.  
  886.       if (sm == NULL)
  887.          fclose(fpq);
  888.  
  889.       return (blks);
  890.    }
  891.    else
  892.       fprintf(fpq,bbstxt[B_TWO_CR]);
  893.  
  894.    if (sm == NULL)
  895.       fclose(fpq);
  896.  
  897.    return(1);
  898. }
  899.  
  900. void squish_list_headers (m, verbose)
  901. int m, verbose;
  902. {
  903.     int i, line = verbose ? 2 : 5, l = 0;
  904.     struct _msg msgt;
  905.     MSGH *sq_msgh;
  906.     XMSG xmsg;
  907.  
  908.     if (!sq_ptr){
  909.         sq_ptr = MsgOpenArea (sys.msg_path, MSGAREA_CRIFNEC, MSGTYPE_SQUISH);
  910.         if (sq_ptr == NULL)
  911.         return;
  912.     }
  913.  
  914.  
  915.     for (i = m; i <= last_msg; i++) {
  916.       sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_RW, (dword)i);
  917.       if (sq_msgh == NULL)
  918.          continue;
  919.  
  920.       if (MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 0, NULL) == -1) {
  921.          MsgCloseMsg (sq_msgh);
  922.          continue;
  923.       }
  924.  
  925.       MsgCloseMsg (sq_msgh);
  926.  
  927.       if (!stricmp (xmsg.from,"ARCmail") && !stricmp (xmsg.to, "Sysop"))
  928.          continue;
  929.  
  930.       if (xmsg.attr & MSGPRIVATE)
  931.          if (stricmp(xmsg.from,usr.name) && stricmp(xmsg.to,usr.name) &&
  932.          stricmp(xmsg.from,usr.handle) && stricmp(xmsg.to,usr.handle) && usr.priv != SYSOP)
  933.             continue;
  934.  
  935.       memset ((char *)&msgt, 0, sizeof (struct _msg));
  936.       strcpy (msgt.from, xmsg.from);
  937.       strcpy (msgt.to, xmsg.to);
  938.       strcpy (msgt.subj, xmsg.subj);
  939.       if (!xmsg.ftsc_date[0])
  940.          date_conversion (&xmsg);
  941.       strcpy (msgt.date, xmsg.ftsc_date);
  942.       msg_fzone = xmsg.orig.zone;
  943.       msgt.orig = xmsg.orig.node;
  944.       msgt.orig_net = xmsg.orig.net;
  945.       msg_fpoint = xmsg.orig.point;
  946.       msg_tzone = xmsg.dest.zone;
  947.       msgt.dest = xmsg.dest.node;
  948.       msgt.dest_net = xmsg.dest.net;
  949.       msg_tpoint = xmsg.dest.point;
  950.       msg.attr = (word)xmsg.attr;
  951.  
  952.       if (verbose) {
  953.          if ((line = msg_attrib (&msgt, i, line, 0)) == 0)
  954.             break;
  955.  
  956.          m_print (bbstxt[B_ONE_CR]);
  957.       }
  958.       else
  959.          m_print ("%-4d %c%-20.20s %c%-20.20s  %-32.32s\n",
  960.                    i,
  961.                    stricmp (msgt.from, usr.name) ? 'è' : 'Ä',
  962.                    msgt.from,
  963.                    stricmp (msgt.to, usr.name) ? 'è' : 'î',
  964.                    msgt.to,
  965.                    msgt.subj);
  966.  
  967.       if (!(l=more_question(line)) || !CARRIER && !RECVD_BREAK())
  968.          break;
  969.  
  970.       if (!verbose && l < line) {
  971.          l = 5;
  972.  
  973.          cls ();
  974.          m_print (bbstxt[B_LIST_AREAHEADER], usr.msg, sys.msg_name);
  975.          m_print(bbstxt[B_LIST_HEADER1]);
  976.          m_print(bbstxt[B_LIST_HEADER2]);
  977.       }
  978.  
  979.       line = l;
  980.    }
  981.  
  982.    m_print (bbstxt[B_ONE_CR]);
  983.  
  984.    if (line && CARRIER)
  985.       press_enter();
  986. }
  987.  
  988. int squish_mail_list_headers (m, line, ovrmsgn)
  989. int m, line, ovrmsgn;
  990. {
  991.    struct _msg msgt;
  992.    MSGH *sq_msgh;
  993.    XMSG xmsg;
  994.  
  995.    sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_RW, (dword)m);
  996.    if (sq_msgh == NULL)
  997.       return (line);
  998.  
  999.    if (MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 0, NULL) == -1) {
  1000.       MsgCloseMsg (sq_msgh);
  1001.       return (line);
  1002.    }
  1003.  
  1004.    MsgCloseMsg (sq_msgh);
  1005.  
  1006.    if (!stricmp (xmsg.from,"ARCmail") && !stricmp (xmsg.to, "Sysop"))
  1007.       return (line);
  1008.  
  1009.    if (xmsg.attr & MSGPRIVATE)
  1010.       if (stricmp(xmsg.from,usr.name) && stricmp(xmsg.to,usr.name) &&
  1011.       stricmp(xmsg.from,usr.handle) && stricmp(xmsg.to,usr.handle) && usr.priv != SYSOP)
  1012.          return (line);
  1013.  
  1014.    memset ((char *)&msgt, 0, sizeof (struct _msg));
  1015.    strcpy (msgt.from, xmsg.from);
  1016.    strcpy (msgt.to, xmsg.to);
  1017.    strcpy (msgt.subj, xmsg.subj);
  1018.    if (!xmsg.ftsc_date[0])
  1019.       date_conversion (&xmsg);
  1020.    strcpy (msgt.date, xmsg.ftsc_date);
  1021.    msg_fzone = xmsg.orig.zone;
  1022.    msgt.orig = xmsg.orig.node;
  1023.    msgt.orig_net = xmsg.orig.net;
  1024.    msg_fpoint = xmsg.orig.point;
  1025.    msg_tzone = xmsg.dest.zone;
  1026.    msgt.dest = xmsg.dest.node;
  1027.    msgt.dest_net = xmsg.dest.net;
  1028.    msg_tpoint = xmsg.dest.point;
  1029.    msg.attr = (word)xmsg.attr;
  1030.  
  1031.    if ((line = msg_attrib (&msgt, ovrmsgn ? ovrmsgn : m, line, 0)) == 0)
  1032.       return (0);
  1033.  
  1034.    return (line);
  1035. }
  1036.  
  1037. void squish_message_inquire (stringa)
  1038. char *stringa;
  1039. {
  1040.    int i, line=4;
  1041.    char *p;
  1042.    struct _msg msgt, backup;
  1043.    MSGH *sq_msgh;
  1044.     XMSG xmsg;
  1045.  
  1046.     if (!sq_ptr){
  1047.         sq_ptr = MsgOpenArea (sys.msg_path, MSGAREA_CRIFNEC, MSGTYPE_SQUISH);
  1048.         if (sq_ptr == NULL)
  1049.         return;
  1050.     }
  1051.  
  1052.  
  1053.     for (i = first_msg; i <= last_msg; i++) {
  1054.         sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_RW, (dword)i);
  1055.         if (sq_msgh == NULL)
  1056.             continue;
  1057.  
  1058.         if (MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 0, NULL) == -1) {
  1059.             MsgCloseMsg (sq_msgh);
  1060.             continue;
  1061.         }
  1062.  
  1063.       if (!stricmp (xmsg.from,"ARCmail") && !stricmp (xmsg.to, "Sysop")) {
  1064.          MsgCloseMsg (sq_msgh);
  1065.          continue;
  1066.       }
  1067.  
  1068.       if (xmsg.attr & MSGPRIVATE)
  1069.          if (stricmp(xmsg.from,usr.name) && stricmp(xmsg.to,usr.name) &&
  1070.          stricmp(xmsg.from,usr.handle) && stricmp(xmsg.to,usr.handle) && usr.priv != SYSOP) {
  1071.             MsgCloseMsg (sq_msgh);
  1072.             continue;
  1073.          }
  1074.  
  1075.       memset ((char *)&msgt, 0, sizeof (struct _msg));
  1076.       strcpy (msgt.from, xmsg.from);
  1077.       strcpy (msgt.to, xmsg.to);
  1078.       strcpy (msgt.subj, xmsg.subj);
  1079.       if (!xmsg.ftsc_date[0])
  1080.          date_conversion (&xmsg);
  1081.       strcpy (msgt.date, xmsg.ftsc_date);
  1082.       msg_fzone = xmsg.orig.zone;
  1083.       msgt.orig = xmsg.orig.node;
  1084.       msgt.orig_net = xmsg.orig.net;
  1085.       msg_fpoint = xmsg.orig.point;
  1086.       msg_tzone = xmsg.dest.zone;
  1087.       msgt.dest = xmsg.dest.node;
  1088.       msgt.dest_net = xmsg.dest.net;
  1089.       msg_tpoint = xmsg.dest.point;
  1090.       msg.attr = (word)xmsg.attr;
  1091.  
  1092.       p = (char *)malloc((unsigned int)MsgGetTextLen (sq_msgh) + 1);
  1093.       if (p != NULL) {
  1094.          MsgReadMsg (sq_msgh, NULL, 0L, MsgGetTextLen (sq_msgh), p, 0, NULL);
  1095.          p[(unsigned int)MsgGetTextLen (sq_msgh)] = '\0';
  1096.       }
  1097.       else
  1098.          p = NULL;
  1099.  
  1100.       MsgCloseMsg (sq_msgh);
  1101.  
  1102.       memcpy ((char *)&backup, (char *)&msgt, sizeof (struct _msg));
  1103.       strupr (msgt.to);
  1104.       strupr (msgt.from);
  1105.       strupr (msgt.subj);
  1106.       strupr (p);
  1107.  
  1108.       if ((strstr(msgt.to,stringa) != NULL) || (strstr(msgt.from,stringa) != NULL) ||
  1109.           (strstr(msgt.subj,stringa) != NULL) || (strstr(p,stringa) != NULL)) {
  1110.          memcpy ((char *)&msgt, (char *)&backup, sizeof (struct _msg));
  1111.          if ((line = msg_attrib (&msgt, i, line, 0)) == 0)
  1112.             break;
  1113.  
  1114.          m_print(bbstxt[B_ONE_CR]);
  1115.  
  1116.          if (!(line=more_question(line)) || !CARRIER && !RECVD_BREAK())
  1117.             break;
  1118.  
  1119.          time_release();
  1120.       }
  1121.  
  1122.       if (p != NULL)
  1123.          free(p);
  1124.    }
  1125.  
  1126.    if (line && CARRIER)
  1127.       press_enter();
  1128. }
  1129.  
  1130. int squish_kill_message (msg_num)
  1131. int msg_num;
  1132. {
  1133.    MSGH *sq_msgh;
  1134.    XMSG xmsg;
  1135.  
  1136.    sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_RW, (dword)msg_num);
  1137.    if (sq_msgh == NULL)
  1138.       return (0);
  1139.  
  1140.    if (MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 0, NULL) == -1) {
  1141.       MsgCloseMsg (sq_msgh);
  1142.       return (0);
  1143.    }
  1144.  
  1145.    MsgCloseMsg (sq_msgh);
  1146.  
  1147.    if (!stricmp (xmsg.from, usr.name) || !stricmp (xmsg.to, usr.name) ||
  1148.    !stricmp (xmsg.from, usr.handle) || !stricmp (xmsg.to, usr.handle) || usr.priv == SYSOP) {
  1149.       MsgKillMsg (sq_ptr, msg_num);
  1150.       return (1);
  1151.    }
  1152.  
  1153.    return (0);
  1154. }
  1155.  
  1156. int squish_scan_messages (total, personal, start, fdi, fdp, totals, fpq, qwk)
  1157. int *total, *personal, start, fdi, fdp, totals;
  1158. FILE *fpq;
  1159. char qwk;
  1160. {
  1161.    float in, out;
  1162.    int i, z, m, pos, blks, xx, rd, tt, pp, msg_num;
  1163.    char c, buff[80], wrp[80], qwkbuffer[130], sqbuff[80];
  1164.    long fpos, qpos, bw_start;
  1165.    struct _msg msgt;
  1166.    struct QWKmsghd QWK;
  1167.    MSGH *sq_msgh;
  1168.    XMSG xmsg;
  1169.  
  1170.    tt = 0;
  1171.    pp = 0;
  1172.  
  1173.    if (start > last_msg) {
  1174.       *personal = pp;
  1175.       *total = tt;
  1176.  
  1177.       return (totals);
  1178.    }
  1179.  
  1180.    MsgLock (sq_ptr);
  1181.  
  1182.    for (msg_num = start; msg_num <= last_msg; msg_num++) {
  1183.       if (!(msg_num % 5))
  1184.          display_percentage (msg_num - start, last_msg - start);
  1185.  
  1186.       sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_RW, (dword)msg_num);
  1187.       if (sq_msgh == NULL)
  1188.          continue;
  1189.  
  1190.       if (MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 0, NULL) == -1) {
  1191.          MsgCloseMsg (sq_msgh);
  1192.          continue;
  1193.       }
  1194.  
  1195.       if (!stricmp (xmsg.from,"ARCmail") && !stricmp (xmsg.to, "Sysop")) {
  1196.          MsgCloseMsg (sq_msgh);
  1197.          continue;
  1198.       }
  1199.  
  1200.       if (xmsg.attr & MSGPRIVATE)
  1201.          if (stricmp(xmsg.from,usr.name) && stricmp(xmsg.to,usr.name) &&
  1202.          stricmp(xmsg.from,usr.handle) && stricmp(xmsg.to,usr.handle) && usr.priv != SYSOP) {
  1203.             MsgCloseMsg (sq_msgh);
  1204.             continue;
  1205.          }
  1206.  
  1207.       totals++;
  1208.       if (qwk == 1 && fdi != -1) {
  1209.          sprintf(buff,"%u",totals);   /* Stringized version of current position */
  1210.          in = (float) atof(buff);
  1211.          out = IEEToMSBIN(in);
  1212.          write(fdi,&out,sizeof(float));
  1213.  
  1214.          c = 0;
  1215.          write(fdi,&c,sizeof(char));              /* Conference # */
  1216.       }
  1217.       else if (qwk == 2) {
  1218.          bw_start = ftell (fpq);
  1219.          fputc (' ', fpq);
  1220.       }
  1221.  
  1222.       if (!stricmp(xmsg.to,usr.name)||!stricmp(xmsg.to,usr.handle)) {
  1223.          pp++;
  1224.          if (qwk == 1 && fdi != -1 && fdp != -1) {
  1225.             write(fdp,&out,sizeof(float));
  1226.             write(fdp,&c,sizeof(char));              /* Conference # */
  1227.          }
  1228.       }
  1229.  
  1230.       memset ((char *)&msgt, 0, sizeof (struct _msg));
  1231.       strcpy (msgt.from, xmsg.from);
  1232.       strcpy (msgt.to, xmsg.to);
  1233.       strcpy (msgt.subj, xmsg.subj);
  1234.       if (!xmsg.ftsc_date[0])
  1235.          date_conversion (&xmsg);
  1236.       strcpy (msgt.date, xmsg.ftsc_date);
  1237.       msg_fzone = xmsg.orig.zone;
  1238.       msgt.orig = xmsg.orig.node;
  1239.       msgt.orig_net = xmsg.orig.net;
  1240.       msg_fpoint = xmsg.orig.point;
  1241.       msg_tzone = xmsg.dest.zone;
  1242.       msgt.dest = xmsg.dest.node;
  1243.       msgt.dest_net = xmsg.dest.net;
  1244.       msg_tpoint = xmsg.dest.point;
  1245.       msg.attr = (word)xmsg.attr;
  1246.  
  1247.       blks = 1;
  1248.       pos = 0;
  1249.       memset (qwkbuffer, ' ', 128);
  1250.  
  1251.       i = 0;
  1252.       fpos = 0L;
  1253.  
  1254.       if (qwk == 1)
  1255.          qwk_header (&msgt, &QWK, msg_num, fpq, &qpos);
  1256.       else if (qwk == 0)
  1257.          text_header (&msgt,msg_num,fpq);
  1258.  
  1259.       do {
  1260.          rd = (int)MsgReadMsg (sq_msgh, NULL, fpos, 80L, sqbuff, 0, NULL);
  1261.          fpos += (long)rd;
  1262.  
  1263.          for (xx = 0; xx < rd; xx++) {
  1264.             c = sqbuff[xx];
  1265.             if ((byte)c == 0x8D || c == 0x0A || c == '\0')
  1266.                continue;
  1267.  
  1268.             buff[i++]=c;
  1269.  
  1270.             if(c == 0x0D) {
  1271.                buff[i-1]='\0';
  1272.  
  1273.                if (!strncmp (buff, "SEEN-BY", 7) || buff[0] == 0x01) {
  1274.                   i = 0;
  1275.                   continue;
  1276.                }
  1277.  
  1278.                if (qwk == 1) {
  1279.                   write_qwk_string (buff, qwkbuffer, &pos, &blks, fpq);
  1280.                   write_qwk_string ("\r\n", qwkbuffer, &pos, &blks, fpq);
  1281.                }
  1282.                else
  1283.                   fprintf (fpq, "%s\n", buff);
  1284.  
  1285.                i = 0;
  1286.             }
  1287.             else {
  1288.                if (i < (usr.width - 1))
  1289.                   continue;
  1290.  
  1291.                buff[i] = '\0';
  1292.                while (i > 0 && buff[i] != ' ')
  1293.                   i--;
  1294.  
  1295.                m = 0;
  1296.  
  1297.                if (i != 0)
  1298.                   for (z = i + 1; buff[z]; z++) {
  1299.                      wrp[m++] = buff[z];
  1300.                      buff[i] = '\0';
  1301.                   }
  1302.  
  1303.                wrp[m] = '\0';
  1304.  
  1305.                if (qwk == 1) {
  1306.                   write_qwk_string (buff, qwkbuffer, &pos, &blks, fpq);
  1307.                   write_qwk_string ("\r\n", qwkbuffer, &pos, &blks, fpq);
  1308.                }
  1309.                else
  1310.                   fprintf (fpq, "%s\n", buff);
  1311.  
  1312.                strcpy (buff, wrp);
  1313.                i = strlen (buff);
  1314.             }
  1315.          }
  1316.       } while (rd == 80);
  1317.  
  1318.       if ((!stricmp(xmsg.to, usr.name)||!stricmp(xmsg.to, usr.handle)) && !(xmsg.attr & MSGREAD)) {
  1319.          xmsg.attr |= MSGREAD;
  1320.          MsgWriteMsg (sq_msgh, 1, &xmsg, NULL, 0, 0, 0, NULL);
  1321.       }
  1322.  
  1323.       MsgCloseMsg (sq_msgh);
  1324.  
  1325.       if (qwk == 1) {
  1326.          qwkbuffer[128] = 0;
  1327.          fwrite (qwkbuffer, 128, 1, fpq);
  1328.          blks++;
  1329.  
  1330.       /* Now update with record count */
  1331.          fseek (fpq, qpos, SEEK_SET);          /* Restore back to header start */
  1332.          sprintf (buff, "%d", blks);
  1333.          ljstring (QWK.Msgrecs, buff, 6);
  1334.          fwrite ((char *)&QWK, 128, 1, fpq);           /* Write out the header */
  1335.          fseek (fpq, 0L, SEEK_END);               /* Bump back to end of file */
  1336.  
  1337.          totals += blks - 1;
  1338.       }
  1339.       else if (qwk == 2)
  1340.          bluewave_header (fdi, bw_start, ftell (fpq) - bw_start, msg_num, &msgt);
  1341.       else
  1342.          fprintf(fpq,bbstxt[B_TWO_CR]);
  1343.  
  1344.       tt++;
  1345.    }
  1346.  
  1347.    MsgUnlock (sq_ptr);
  1348.  
  1349.    *personal = pp;
  1350.    *total = tt;
  1351.  
  1352.    return (totals);
  1353. }
  1354. #endif
  1355.  
  1356. int squish_save_message2 (FILE *txt)
  1357. {
  1358.     int i, dest, m, dd, hh, mm, ss, aa, mo;
  1359.     char buffer[2050];
  1360.     long totlen;
  1361.     struct date da;
  1362.     struct time ti;
  1363.     MSGH *sq_msgh;
  1364.     XMSG xmsg;
  1365.  
  1366.     dest = (int)MsgGetNumMsg (sq_ptr) + 1;
  1367.  
  1368.     sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_CREATE, (dword)0);
  1369.     if (sq_msgh == NULL)
  1370.         return (0);
  1371.  
  1372.     memset ((char *)&xmsg, 0, sizeof (XMSG));
  1373.     strcpy (xmsg.from, msg.from);
  1374.     strcpy (xmsg.to, msg.to);
  1375.     strcpy (xmsg.subj, msg.subj);
  1376.     strcpy (xmsg.ftsc_date, msg.date);
  1377.     sscanf(msg.date, "%2d %3s %2d %2d:%2d:%2d", &dd, buffer, &aa, &hh, &mm, &ss);
  1378.     buffer[3] = '\0';
  1379.     for (mo = 0; mo < 12; mo++)
  1380.         if (!stricmp(buffer, mtext[mo]))
  1381.             break;
  1382.     if (mo == 12)
  1383.         mo = 0;
  1384.     xmsg.date_written.date.da = dd;
  1385.     xmsg.date_written.date.mo = mo + 1;
  1386.     xmsg.date_written.date.yr = (aa % 100) - 80;
  1387.     xmsg.date_written.time.hh = hh;
  1388.     xmsg.date_written.time.mm = mm;
  1389.     xmsg.date_written.time.ss = ss;
  1390.     getdate (&da);
  1391.     gettime (&ti);
  1392.     xmsg.date_arrived.date.da = da.da_day;
  1393.     xmsg.date_arrived.date.mo = da.da_mon;
  1394.     xmsg.date_arrived.date.yr = (da.da_year % 100) - 80;
  1395.     xmsg.date_arrived.time.hh = ti.ti_hour;
  1396.     xmsg.date_arrived.time.mm = ti.ti_min;
  1397.     xmsg.date_arrived.time.ss = ti.ti_sec;
  1398.     xmsg.orig.zone = msg_fzone;
  1399.     xmsg.orig.node = msg.orig;
  1400.     xmsg.orig.net = msg.orig_net;
  1401.     xmsg.dest.zone = msg_tzone;
  1402.     xmsg.dest.node = msg.dest;
  1403.     xmsg.dest.net = msg.dest_net;
  1404.     xmsg.dest.point = msg_tpoint;
  1405.     xmsg.attr = msg.attr;
  1406.     if (sys.public)
  1407.         xmsg.attr &= ~MSGPRIVATE;
  1408.     else if (sys.private)
  1409.         xmsg.attr |= MSGPRIVATE;
  1410.     if (sys.echomail && (msg.attr & MSGSENT)) {
  1411.         xmsg.attr |= MSGSCANNED;
  1412.         xmsg.attr &= ~MSGSENT;
  1413.     }
  1414.  
  1415.     totlen = memlength ();
  1416.  
  1417.     if (MsgWriteMsg (sq_msgh, 0, &xmsg, NULL, 0L, totlen, 1L, "\x00"))
  1418.         return (0);
  1419.  
  1420.     do {
  1421.         i = mread (buffer, 1, 2048, txt);
  1422.         for (m = 0; m < i; m++) {
  1423.             if (buffer[m] == 0x1A)
  1424.                 buffer[m] = ' ';
  1425.         }
  1426.  
  1427.         if (MsgWriteMsg (sq_msgh, 1, NULL, buffer, (long)i, totlen, 0L, NULL))
  1428.             return (0);
  1429.     } while (i == 2048);
  1430.  
  1431.     MsgCloseMsg (sq_msgh);
  1432.  
  1433.     num_msg = last_msg = dest;
  1434.     return (1);
  1435. }
  1436.  
  1437. int squish_export_mail (int maxnodes, struct _fwrd *forward)
  1438. {
  1439.     FILE *fpd;
  1440.     int i, pp, z, ne, no, n_seen, cnet, cnode, mi, msgnum, xx, rd, m, sent, ai;
  1441.     char buff[82], wrp[82], c, *p, buffer[2050], sqbuff[82], need_origin;
  1442.     char need_seen, *flag;
  1443.     long fpos;
  1444.     MSGH *sq_msgh;
  1445.     XMSG xmsg;
  1446.     struct _msghdr2 mhdr;
  1447.     struct _fwrd *seen;
  1448.  
  1449.     seen = (struct _fwrd *)malloc ((MAX_EXPORT_SEEN + 1) * sizeof (struct _fwrd));
  1450.     if (seen == NULL)
  1451.         return (maxnodes);
  1452.  
  1453.     fpd = fopen ("MSGTMP.EXP", "rb+");
  1454.     if (fpd == NULL) {
  1455.         fpd = fopen ("MSGTMP.EXP", "wb");
  1456.         fclose (fpd);
  1457.     }
  1458.     else
  1459.         fclose (fpd);
  1460.     fpd = mopen ("MSGTMP.EXP", "r+b");
  1461.  
  1462.     for (i = 0; i < maxnodes; i++)
  1463.         forward[i].receiveonly = forward[i].sendonly = forward[i].passive = forward[i].private = forward[i].reset = forward[i].export = 0;
  1464.  
  1465.     z = config->alias[sys.use_alias].zone;
  1466.     ne = config->alias[sys.use_alias].net;
  1467.     no = config->alias[sys.use_alias].node;
  1468.     pp = 0;
  1469.  
  1470.     p = strtok (sys.forward1, " ");
  1471.     if (p != NULL)
  1472.         do {
  1473.             flag = p;
  1474.             while (*p == '<' || *p == '>' || *p == '!' || *p == 'p' || *p == 'P')
  1475.                 p++;
  1476.             parse_netnode2 (p, &z, &ne, &no, &pp);
  1477.             for (i = 0; i < MAX_ALIAS; i++) {
  1478.                 if (config->alias[i].net == 0)
  1479.                     continue;
  1480.                 if (config->alias[i].zone == z && config->alias[i].net == ne && config->alias[i].node == no && config->alias[i].point == pp)
  1481.                     break;
  1482.                 if (config->alias[i].point && config->alias[i].fakenet) {
  1483.                     if (config->alias[i].zone == z && config->alias[i].fakenet == ne && config->alias[i].point == no)
  1484.                         break;
  1485.                 }
  1486.             }
  1487.             if (i < MAX_ALIAS && config->alias[i].net)
  1488.                 continue;
  1489.             if ((i = is_here (z, ne, no, pp, forward, maxnodes)) != -1)
  1490.                 forward[i].reset = forward[i].export = 1;
  1491.             else {
  1492.                 i = maxnodes;
  1493.                 forward[maxnodes].zone = z;
  1494.                 forward[maxnodes].net = ne;
  1495.                 forward[maxnodes].node = no;
  1496.                 forward[maxnodes].point = pp;
  1497.                 forward[maxnodes].export = 1;
  1498.                 forward[maxnodes].reset = 1;
  1499.                 maxnodes++;
  1500.             }
  1501.             forward[i].receiveonly = forward[i].sendonly = forward[i].passive = forward[i].private = 0;
  1502.             while (*flag=='<'||*flag=='>'||*flag=='!'||*flag=='P'||*flag=='p') {
  1503.                 if (*flag == '>')
  1504.                     forward[i].receiveonly = 1;
  1505.                 if (*flag == '<')
  1506.                     forward[i].sendonly = 1;
  1507.                 if (*flag == '!')
  1508.                     forward[i].passive = 1;
  1509.                 if (*flag == 'p' || *flag == 'P')
  1510.                     forward[i].private = 1;
  1511.                 flag++;
  1512.             }
  1513.         } while ((p = strtok (NULL, " ")) != NULL);
  1514.  
  1515.     z = config->alias[sys.use_alias].zone;
  1516.     ne = config->alias[sys.use_alias].net;
  1517.     no = config->alias[sys.use_alias].node;
  1518.     pp = 0;
  1519.  
  1520.     p = strtok (sys.forward2, " ");
  1521.     if (p != NULL)
  1522.         do {
  1523.             flag = p;
  1524.             while (*p == '<' || *p == '>' || *p == '!' || *p == 'p' || *p == 'P')
  1525.                 p++;
  1526.             parse_netnode2 (p, &z, &ne, &no, &pp);
  1527.             for (i = 0; i < MAX_ALIAS; i++) {
  1528.                 if (config->alias[i].net == 0)
  1529.                     continue;
  1530.                 if (config->alias[i].zone == z && config->alias[i].net == ne && config->alias[i].node == no && config->alias[i].point == pp)
  1531.                     break;
  1532.                 if (config->alias[i].point && config->alias[i].fakenet) {
  1533.                     if (config->alias[i].zone == z && config->alias[i].fakenet == ne && config->alias[i].point == no)
  1534.                         break;
  1535.                 }
  1536.             }
  1537.             if (i < MAX_ALIAS && config->alias[i].net)
  1538.                 continue;
  1539.             if ((i = is_here (z, ne, no, pp, forward, maxnodes)) != -1)
  1540.                 forward[i].reset = forward[i].export = 1;
  1541.             else {
  1542.                 i = maxnodes;
  1543.                 forward[maxnodes].zone = z;
  1544.                 forward[maxnodes].net = ne;
  1545.                 forward[maxnodes].node = no;
  1546.                 forward[maxnodes].point = pp;
  1547.                 forward[maxnodes].export = 1;
  1548.                 forward[maxnodes].reset = 1;
  1549.                 maxnodes++;
  1550.             }
  1551.             forward[i].receiveonly = forward[i].sendonly = forward[i].passive = forward[i].private = 0;
  1552.             while (*flag=='<'||*flag=='>'||*flag=='!'||*flag=='P'||*flag=='p') {
  1553.                 if (*flag == '>')
  1554.                     forward[i].receiveonly = 1;
  1555.                 if (*flag == '<')
  1556.                     forward[i].sendonly = 1;
  1557.                 if (*flag == '!')
  1558.                     forward[i].passive = 1;
  1559.                 if (*flag == 'p' || *flag == 'P')
  1560.                     forward[i].private = 1;
  1561.                 flag++;
  1562.             }
  1563.  
  1564.         } while ((p = strtok (NULL, " ")) != NULL);
  1565.  
  1566.     z = config->alias[sys.use_alias].zone;
  1567.     ne = config->alias[sys.use_alias].net;
  1568.     no = config->alias[sys.use_alias].node;
  1569.     pp = 0;
  1570.  
  1571.     p = strtok (sys.forward3, " ");
  1572.     if (p != NULL)
  1573.         do {
  1574.             flag = p;
  1575.             while (*p == '<' || *p == '>' || *p == '!' || *p == 'p' || *p == 'P')
  1576.                 p++;
  1577.             parse_netnode2 (p, &z, &ne, &no, &pp);
  1578.             for (i = 0; i < MAX_ALIAS; i++) {
  1579.                 if (config->alias[i].net == 0)
  1580.                     continue;
  1581.                 if (config->alias[i].zone == z && config->alias[i].net == ne && config->alias[i].node == no && config->alias[i].point == pp)
  1582.                     break;
  1583.                 if (config->alias[i].point && config->alias[i].fakenet) {
  1584.                     if (config->alias[i].zone == z && config->alias[i].fakenet == ne && config->alias[i].point == no)
  1585.                         break;
  1586.                 }
  1587.             }
  1588.             if (i < MAX_ALIAS && config->alias[i].net)
  1589.                 continue;
  1590.             if ((i = is_here (z, ne, no, pp, forward, maxnodes)) != -1)
  1591.                 forward[i].reset = forward[i].export = 1;
  1592.             else {
  1593.                 i = maxnodes;
  1594.                 forward[maxnodes].zone = z;
  1595.                 forward[maxnodes].net = ne;
  1596.                 forward[maxnodes].node = no;
  1597.                 forward[maxnodes].point = pp;
  1598.                 forward[maxnodes].export = 1;
  1599.                 forward[maxnodes].reset = 1;
  1600.                 maxnodes++;
  1601.             }
  1602.             forward[i].receiveonly = forward[i].sendonly = forward[i].passive = forward[i].private = 0;
  1603.             while (*flag=='<'||*flag=='>'||*flag=='!'||*flag=='P'||*flag=='p') {
  1604.                 if (*flag == '>')
  1605.                     forward[i].receiveonly = 1;
  1606.                 if (*flag == '<')
  1607.                     forward[i].sendonly = 1;
  1608.                 if (*flag == '!')
  1609.                     forward[i].passive = 1;
  1610.                 if (*flag == 'p' || *flag == 'P')
  1611.                     forward[i].private = 1;
  1612.                 flag++;
  1613.             }
  1614.  
  1615.         } while ((p = strtok (NULL, " ")) != NULL);
  1616.  
  1617.     msgnum = (int)MsgGetHighWater(sq_ptr) + 1;
  1618.  
  1619.     strcpy (wrp, sys.echotag);
  1620.     wrp[14] = '\0';
  1621.     prints (8, 65, YELLOW|_BLACK, "              ");
  1622.     prints (8, 65, YELLOW|_BLACK, wrp);
  1623.  
  1624.     prints (7, 65, YELLOW|_BLACK, "              ");
  1625.     prints (9, 65, YELLOW|_BLACK, "              ");
  1626.     prints (9, 65, YELLOW|_BLACK, "Squish<tm>");
  1627.  
  1628.     sprintf (wrp, "%d / %d", msgnum, last_msg);
  1629.     prints (7, 65, YELLOW|_BLACK, wrp);
  1630.     sent = 0;
  1631.  
  1632.     for (; msgnum <= last_msg; msgnum++) {
  1633.         sprintf (wrp, "%d / %d", msgnum, last_msg);
  1634.         prints (7, 65, YELLOW|_BLACK, wrp);
  1635.  
  1636.         for (i = 0; i < maxnodes; i++)
  1637.             if (forward[i].reset)
  1638.                 forward[i].export = 1;
  1639.  
  1640.         for (i = 0; i < maxnodes; i++) {
  1641.             if (forward[i].sendonly||forward[i].passive) forward[i].export=0;
  1642.         }
  1643.  
  1644.  
  1645.         sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_RW, (dword)msgnum);
  1646.         if (sq_msgh == NULL)
  1647.             continue;
  1648.  
  1649.         if (MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 0, NULL) == -1) {
  1650.             MsgCloseMsg (sq_msgh);
  1651.             continue;
  1652.         }
  1653.  
  1654.         if (xmsg.attr & MSGSCANNED) {
  1655.             MsgCloseMsg (sq_msgh);
  1656.             continue;
  1657.         }
  1658.         else {
  1659.             xmsg.attr |= MSGSCANNED;
  1660.             MsgWriteMsg (sq_msgh, 1, &xmsg, NULL, 0, 0, 0, NULL);
  1661.         }
  1662.         for (i=0;i<maxnodes;i++) {
  1663.             if (forward[i].private) {
  1664.  
  1665.                 int ii;
  1666.  
  1667.                 forward[i].export=0;
  1668.                 if (!nametable) continue;
  1669.  
  1670.                 for(ii=0;ii<nodes_num;ii++) {
  1671.                     if (forward[i].zone==nametable[ii].zone&&
  1672.                          forward[i].net==nametable[ii].net&&
  1673.                          forward[i].node==nametable[ii].node&&
  1674.                          forward[i].point==nametable[ii].point&&
  1675.                          !stricmp(xmsg.to,nametable[ii].name)) {
  1676.                              forward[i].export=1;
  1677.                              break;
  1678.                     }
  1679.                 }
  1680.             }
  1681.  
  1682.  
  1683.         }
  1684.  
  1685.         sprintf (wrp, "%5d  %-22.22s Squish<tm>   ", msgnum, sys.echotag);
  1686.         wputs (wrp);
  1687.  
  1688.         need_seen = need_origin = 1;
  1689.  
  1690.         mseek (fpd, 0L, SEEK_SET);
  1691.       mprintf (fpd, "AREA:%s\r\n", sys.echotag);
  1692.  
  1693.       mi = i = 0;
  1694.       pp = 0;
  1695.       n_seen = 0;
  1696.       fpos = 0L;
  1697.  
  1698.       MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 1024, buffer);
  1699.       if ((p = strtok (buffer, "\x01")) != NULL)
  1700.          do {
  1701.             mprintf (fpd, "\x01%s\r\n", p);
  1702.          } while ((p = strtok (NULL, "\x01")) != NULL);
  1703.  
  1704.       do {
  1705.          rd = (int)MsgReadMsg (sq_msgh, NULL, fpos, 80L, sqbuff, 0, NULL);
  1706.          fpos += (long)rd;
  1707.  
  1708.          for (xx = 0; xx < rd; xx++) {
  1709.             c = sqbuff[xx];
  1710.             if (c == '\0')
  1711.                break;
  1712.  
  1713.             if (c == 0x0A)
  1714.                continue;
  1715.             if((byte)c == 0x8D)
  1716.                c = ' ';
  1717.  
  1718.             buff[mi++] = c;
  1719.  
  1720.             if(c == 0x0D) {
  1721.                buff[mi - 1]='\0';
  1722.                if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  1723.                   need_origin = 0;
  1724.  
  1725.                if (!strncmp (buff, "SEEN-BY: ", 9)) {
  1726.                   if (need_origin) {
  1727.                      mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  1728.                      if (strlen(sys.origin))
  1729.                         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);
  1730.                      else
  1731.                         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);
  1732.                      need_origin = 0;
  1733.                   }
  1734.  
  1735.                   p = strtok (buff, " ");
  1736.                   ne = config->alias[sys.use_alias].net;
  1737.                   no = config->alias[sys.use_alias].node;
  1738.                   pp = config->alias[sys.use_alias].point;
  1739.                   z = config->alias[sys.use_alias].zone;
  1740.  
  1741.                   while ((p = strtok (NULL, " ")) != NULL) {
  1742.                      parse_netnode2 (p, &z, &ne, &no, &pp);
  1743.  
  1744.                      seen[n_seen].net = ne;
  1745.                      seen[n_seen].node = no;
  1746.                      seen[n_seen].point = pp;
  1747.                      seen[n_seen].zone = z;
  1748.  
  1749.                      for (i = 0; i < maxnodes; i++) {
  1750.                         if (forward[i].net == seen[n_seen].net && forward[i].node == seen[n_seen].node && forward[i].point == seen[n_seen].point) {
  1751.                            forward[i].export = 0;
  1752.                            break;
  1753.                         }
  1754.                      }
  1755.                      
  1756.                      if (n_seen + maxnodes >= MAX_EXPORT_SEEN)
  1757.                         continue;
  1758.  
  1759.                      if (seen[n_seen].net != config->alias[sys.use_alias].fakenet && !seen[n_seen].point)
  1760.                         n_seen++;
  1761.                   }
  1762.                }
  1763.                else if (!strncmp (buff, "\001PATH: ", 7) && need_seen) {
  1764.                   if (need_origin) {
  1765.                      mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  1766.                      if (strlen(sys.origin))
  1767.                         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);
  1768.                      else
  1769.                         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);
  1770.                      need_origin = 0;
  1771.                   }
  1772.  
  1773.                   if (!config->alias[sys.use_alias].point) {
  1774.                      seen[n_seen].net = config->alias[sys.use_alias].net;
  1775.                      seen[n_seen++].node = config->alias[sys.use_alias].node;
  1776.                   }
  1777.                   else if (config->alias[sys.use_alias].fakenet) {
  1778.                      seen[n_seen].net = config->alias[sys.use_alias].fakenet;
  1779.                      seen[n_seen++].node = config->alias[sys.use_alias].point;
  1780.                   }
  1781.  
  1782.                   for (i = 0; i < maxnodes; i++) {
  1783.                      if (!forward[i].export || forward[i].net == config->alias[sys.use_alias].fakenet || forward[i].point)
  1784.                         continue;
  1785.                      seen[n_seen].net = forward[i].net;
  1786.                      seen[n_seen++].node = forward[i].node;
  1787.  
  1788.                      ai = sys.use_alias;
  1789.                      for (m = 0; m < maxakainfo; m++)
  1790.                         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) {
  1791.                            if (akainfo[m].aka)
  1792.                               ai = akainfo[m].aka - 1;
  1793.                            break;
  1794.                         }
  1795.                      if (ai != sys.use_alias) {
  1796.                         if (!config->alias[ai].point) {
  1797.                            if (config->alias[ai].net != seen[n_seen - 1].net || config->alias[ai].node != seen[n_seen - 1].node) {
  1798.                               seen[n_seen].net = config->alias[ai].net;
  1799.                               seen[n_seen++].node = config->alias[ai].node;
  1800.                            }
  1801.                         }
  1802.                         else if (config->alias[ai].fakenet) {
  1803.                            if (config->alias[ai].fakenet != seen[n_seen - 1].net || config->alias[ai].point != seen[n_seen - 1].node) {
  1804.                               seen[n_seen].net = config->alias[ai].fakenet;
  1805.                               seen[n_seen++].node = config->alias[ai].point;
  1806.                            }
  1807.                         }
  1808.                      }
  1809.                   }
  1810.  
  1811.                   qsort (seen, n_seen, sizeof (struct _fwrd), mail_sort_func);
  1812.  
  1813.                   cnet = cnode = 0;
  1814.                   strcpy (wrp, "SEEN-BY: ");
  1815.  
  1816.                   for (i = 0; i < n_seen; i++) {
  1817.                      if (strlen (wrp) > 65) {
  1818.                         mprintf (fpd, "%s\r\n", wrp);
  1819.                         cnet = cnode = 0;
  1820.                         strcpy (wrp, "SEEN-BY: ");
  1821.                      }
  1822.                      if (i && seen[i].net == seen[i - 1].net && seen[i].node == seen[i - 1].node)
  1823.                         continue;
  1824.  
  1825.                      if (cnet != seen[i].net) {
  1826.                         sprintf (buffer, "%d/%d ", seen[i].net, seen[i].node);
  1827.                         cnet = seen[i].net;
  1828.                         cnode = seen[i].node;
  1829.                      }
  1830.                      else if (cnet == seen[i].net && cnode != seen[i].node) {
  1831.                         sprintf (buffer, "%d ", seen[i].node);
  1832.                         cnode = seen[i].node;
  1833.                      }
  1834.                      else
  1835.                         strcpy (buffer, "");
  1836.  
  1837.                      strcat (wrp, buffer);
  1838.                   }
  1839.  
  1840.                   mprintf (fpd, "%s\r\n", wrp);
  1841.                   mprintf (fpd, "%s\r\n", buff);
  1842.  
  1843.                   need_seen = 0;
  1844.                }
  1845.                else if ((xmsg.attr & MSGLOCAL) && !strncmp (buff, "--- ", 4) && (config->replace_tear || !registered))
  1846.                   replace_tearline (fpd, buff);
  1847.                else
  1848.                   mprintf (fpd, "%s\r\n", buff);
  1849.  
  1850.                mi = 0;
  1851.             }
  1852.             else {
  1853.                if(mi < 78)
  1854.                   continue;
  1855.  
  1856.                if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  1857.                   need_origin = 0;
  1858.  
  1859.                buff[mi]='\0';
  1860.                mprintf(fpd,"%s",buff);
  1861.                mi=0;
  1862.                buff[mi] = '\0';
  1863.             }
  1864.          }
  1865.       } while (rd == 80);
  1866.  
  1867.       if (!n_seen) {
  1868.          if (need_origin) {
  1869.             mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  1870.             if (strlen(sys.origin))
  1871.                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);
  1872.             else
  1873.                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);
  1874.             need_origin = 0;
  1875.          }
  1876.  
  1877.          if (!config->alias[sys.use_alias].point) {
  1878.             seen[n_seen].net = config->alias[sys.use_alias].net;
  1879.             seen[n_seen++].node = config->alias[sys.use_alias].node;
  1880.          }
  1881.          else if (config->alias[sys.use_alias].fakenet) {
  1882.             seen[n_seen].net = config->alias[sys.use_alias].fakenet;
  1883.             seen[n_seen++].node = config->alias[sys.use_alias].point;
  1884.          }
  1885.  
  1886.          for (i = 0; i < maxnodes; i++) {
  1887.             if (!forward[i].export || forward[i].net == config->alias[sys.use_alias].fakenet)
  1888.                continue;
  1889.             seen[n_seen].net = forward[i].net;
  1890.             seen[n_seen++].node = forward[i].node;
  1891.  
  1892.             ai = sys.use_alias;
  1893.             for (m = 0; m < maxakainfo; m++)
  1894.                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) {
  1895.                   if (akainfo[m].aka)
  1896.                      ai = akainfo[m].aka - 1;
  1897.                   break;
  1898.                }
  1899.             if (ai != sys.use_alias) {
  1900.                if (!config->alias[ai].point) {
  1901.                   if (config->alias[ai].net != seen[n_seen - 1].net || config->alias[ai].node != seen[n_seen - 1].node) {
  1902.                      seen[n_seen].net = config->alias[ai].net;
  1903.                      seen[n_seen++].node = config->alias[ai].node;
  1904.                   }
  1905.                }
  1906.                else if (config->alias[ai].fakenet) {
  1907.                   if (config->alias[ai].fakenet != seen[n_seen - 1].net || config->alias[ai].point != seen[n_seen - 1].node) {
  1908.                      seen[n_seen].net = config->alias[ai].fakenet;
  1909.                      seen[n_seen++].node = config->alias[ai].point;
  1910.                   }
  1911.                }
  1912.             }
  1913.          }
  1914.  
  1915.          qsort (seen, n_seen, sizeof (struct _fwrd), mail_sort_func);
  1916.  
  1917.          cnet = cnode = 0;
  1918.          strcpy (wrp, "SEEN-BY: ");
  1919.  
  1920.          for (i = 0; i < n_seen; i++) {
  1921.             if (cnet != seen[i].net) {
  1922.                sprintf (buffer, "%d/%d ", seen[i].net, seen[i].node);
  1923.                cnet = seen[i].net;
  1924.                cnode = seen[i].node;
  1925.             }
  1926.             else if (cnet == seen[i].net && cnode != seen[i].node) {
  1927.                sprintf (buffer, "%d ", seen[i].node);
  1928.                cnode = seen[i].node;
  1929.             }
  1930.             else
  1931.                strcpy (buffer, "");
  1932.  
  1933.             strcat (wrp, buffer);
  1934.          }
  1935.  
  1936.          mprintf (fpd, "%s\r\n", wrp);
  1937.          if (config->alias[sys.use_alias].point && config->alias[sys.use_alias].fakenet)
  1938.             mprintf (fpd, "\001PATH: %d/%d\r\n", config->alias[sys.use_alias].fakenet, config->alias[sys.use_alias].point);
  1939.          else if (!config->alias[sys.use_alias].point)
  1940.             mprintf (fpd, "\001PATH: %d/%d\r\n", config->alias[sys.use_alias].net, config->alias[sys.use_alias].node);
  1941.       }
  1942.  
  1943.       mhdr.ver = PKTVER;
  1944.       mhdr.cost = 0;
  1945.       mhdr.attrib = 0;
  1946.  
  1947.       if (sys.public)
  1948.          xmsg.attr &= ~MSGPRIVATE;
  1949.       else if (sys.private)
  1950.          xmsg.attr |= MSGPRIVATE;
  1951.  
  1952.       if (xmsg.attr & MSGPRIVATE)
  1953.          mhdr.attrib |= MSGPRIVATE;
  1954.  
  1955.       for (i = 0; i < maxnodes; i++) {
  1956.          if (!forward[i].export)
  1957.             continue;
  1958.  
  1959.          ai = sys.use_alias;
  1960.          for (m = 0; m < maxakainfo; m++)
  1961.             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) {
  1962.                if (akainfo[m].aka)
  1963.                   ai = akainfo[m].aka - 1;
  1964.                break;
  1965.             }
  1966.  
  1967.          if (config->alias[ai].point && config->alias[ai].fakenet) {
  1968.             mhdr.orig_node = config->alias[ai].point;
  1969.             mhdr.orig_net = config->alias[ai].fakenet;
  1970.          }
  1971.          else {
  1972.             mhdr.orig_node = config->alias[ai].node;
  1973.             mhdr.orig_net = config->alias[ai].net;
  1974.          }
  1975.  
  1976.          if (forward[i].point)
  1977.             sprintf (wrp, "%d/%d.%d ", forward[i].net, forward[i].node, forward[i].point);
  1978.          else
  1979.             sprintf (wrp, "%d/%d ", forward[i].net, forward[i].node);
  1980.          wreadcur (&z, &m);
  1981.          if ( (m + strlen (wrp)) > 78) {
  1982.             wputs ("\n");
  1983.             wputs ("                                           ");
  1984.          }
  1985.          wputs (wrp);
  1986.          if ( (m + strlen (wrp)) == 78)
  1987.             wputs ("                                           ");
  1988.  
  1989.          mi = open_packet (forward[i].zone, forward[i].net, forward[i].node, forward[i].point, ai);
  1990.  
  1991.          mhdr.dest_net = forward[i].net;
  1992.          mhdr.dest_node = forward[i].node;
  1993.          write (mi, (char *)&mhdr, sizeof (struct _msghdr2));
  1994.  
  1995.          write (mi, xmsg.ftsc_date, strlen (xmsg.ftsc_date) + 1);
  1996.          write (mi, xmsg.to, strlen (xmsg.to) + 1);
  1997.          write (mi, xmsg.from, strlen (xmsg.from) + 1);
  1998.          write (mi, xmsg.subj, strlen (xmsg.subj) + 1);
  1999.          mseek (fpd, 0L, SEEK_SET);
  2000.          do {
  2001.             z = mread(buffer, 1, 2048, fpd);
  2002.             write(mi, buffer, z);
  2003.          } while (z == 2048);
  2004.          buff[0] = buff[1] = buff[2] = 0;
  2005.          if (write (mi, buff, 3) != 3)
  2006.             return (-1);
  2007.          close (mi);
  2008.  
  2009.          totalmsg++;
  2010.          sprintf (wrp, "%d (%.1f/s) ", totalmsg, (float)totalmsg / ((float)(timerset (0) - totaltime) / 100));
  2011.          prints (10, 65, YELLOW|_BLACK, wrp);
  2012.  
  2013.          time_release ();
  2014.       }
  2015.  
  2016.       MsgCloseMsg (sq_msgh);
  2017.  
  2018.       wputs ("\n");
  2019.       sent++;
  2020.    }
  2021.  
  2022.    MsgSetHighWater(sq_ptr, (dword)last_msg);
  2023.  
  2024.    if (sent)
  2025.       status_line (":   %-20.20s (Sent=%04d)", sys.echotag, sent);
  2026.  
  2027.    mclose (fpd);
  2028.    free (seen);
  2029.    unlink ("MSGTMP.EXP");
  2030.  
  2031.    return (maxnodes);
  2032. }
  2033.  
  2034. void squish_rescan_echomail (char *tag, int zone, int net, int node, int point)
  2035. {
  2036.    FILE *fpd;
  2037.    int i, pp, z, ne, no, n_seen, cnet, cnode, mi, msgnum, xx, rd, m, sent, fd, ai = 0;
  2038.    char buff[80], wrp[80], c, *p, buffer[2050], sqbuff[80], need_origin;
  2039.    char need_seen;
  2040.    long fpos;
  2041.    MSGH *sq_msgh;
  2042.    XMSG xmsg;
  2043.    struct _msghdr2 mhdr;
  2044.    struct _fwrd *seen;
  2045.    NODEINFO ni;
  2046.  
  2047.    sprintf (buff, "%sNODES.DAT", config->net_info);
  2048.    if ((fd = sh_open (buff, SH_DENYWR, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE)) != -1) {
  2049.       while (read (fd, (char *)&ni, sizeof (NODEINFO)) == sizeof (NODEINFO))
  2050.          if (zone == ni.zone && net == ni.net && node == ni.node && point == ni.point) {
  2051.             ai = ni.aka;
  2052.             break;
  2053.          }
  2054.  
  2055.       close (fd);
  2056.    }
  2057.  
  2058.    strcpy (buff, tag);
  2059.    memset ((char *)&sys, 0, sizeof (struct _sys));
  2060.    strcpy (sys.echotag, buff);
  2061.  
  2062.    seen = (struct _fwrd *)malloc ((MAX_EXPORT_SEEN + 1) * sizeof (struct _fwrd));
  2063.    if (seen == NULL)
  2064.       return;
  2065.  
  2066.    fpd = fopen ("MSGTMP.EXP", "rb+");
  2067.    if (fpd == NULL) {
  2068.       fpd = fopen ("MSGTMP.EXP", "wb");
  2069.       fclose (fpd);
  2070.    }
  2071.    else
  2072.       fclose (fpd);
  2073.    fpd = mopen ("MSGTMP.EXP", "r+b");
  2074.  
  2075.    msgnum = 1;
  2076.  
  2077.    strcpy (wrp, sys.echotag);
  2078.    wrp[14] = '\0';
  2079.    prints (8, 65, YELLOW|_BLACK, "              ");
  2080.    prints (8, 65, YELLOW|_BLACK, wrp);
  2081.  
  2082.    prints (7, 65, YELLOW|_BLACK, "              ");
  2083.    prints (9, 65, YELLOW|_BLACK, "              ");
  2084.    prints (9, 65, YELLOW|_BLACK, "Squish<tm>");
  2085.  
  2086.    sprintf (wrp, "%d / %d", msgnum, last_msg);
  2087.    prints (7, 65, YELLOW|_BLACK, wrp);
  2088.    sent = 0;
  2089.  
  2090.    for (; msgnum <= last_msg; msgnum++) {
  2091.       sprintf (wrp, "%d / %d", msgnum, last_msg);
  2092.       prints (7, 65, YELLOW|_BLACK, wrp);
  2093.  
  2094.       if ( !(msgnum % 20))
  2095.          time_release ();
  2096.  
  2097.       sq_msgh = MsgOpenMsg (sq_ptr, MOPEN_RW, (dword)msgnum);
  2098.       if (sq_msgh == NULL)
  2099.          continue;
  2100.  
  2101.       if (MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 0, NULL) == -1) {
  2102.          MsgCloseMsg (sq_msgh);
  2103.          continue;
  2104.       }
  2105.  
  2106.       sprintf (wrp, "%5d  %-22.22s Squish<tm>   ", msgnum, sys.echotag);
  2107.       wputs (wrp);
  2108.  
  2109.       need_seen = need_origin = 1;
  2110.  
  2111.       mseek (fpd, 0L, SEEK_SET);
  2112.       mprintf (fpd, "AREA:%s\r\n", sys.echotag);
  2113.  
  2114.       mi = i = 0;
  2115.       pp = 0;
  2116.       n_seen = 0;
  2117.       fpos = 0L;
  2118.  
  2119.       MsgReadMsg (sq_msgh, &xmsg, 0L, 0L, NULL, 1024, buffer);
  2120.       if ((p = strtok (buffer, "\x01")) != NULL)
  2121.          do {
  2122.             mprintf (fpd, "\x01%s\r\n", p);
  2123.          } while ((p = strtok (NULL, "\x01")) != NULL);
  2124.  
  2125.       do {
  2126.          rd = (int)MsgReadMsg (sq_msgh, NULL, fpos, 80L, sqbuff, 0, NULL);
  2127.          fpos += (long)rd;
  2128.  
  2129.          for (xx = 0; xx < rd; xx++) {
  2130.             c = sqbuff[xx];
  2131.             if (c == '\0')
  2132.                break;
  2133.  
  2134.             if (c == 0x0A)
  2135.                continue;
  2136.             if((byte)c == 0x8D)
  2137.                c = ' ';
  2138.  
  2139.             buff[mi++] = c;
  2140.  
  2141.             if(c == 0x0D) {
  2142.                buff[mi - 1]='\0';
  2143.                if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  2144.                   need_origin = 0;
  2145.  
  2146.                if (!strncmp (buff, "SEEN-BY: ", 9)) {
  2147.                   if (need_origin) {
  2148.                      mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  2149.                      if (strlen(sys.origin))
  2150.                         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);
  2151.                      else
  2152.                         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);
  2153.                      need_origin = 0;
  2154.                   }
  2155.  
  2156.                   p = strtok (buff, " ");
  2157.                   ne = config->alias[sys.use_alias].net;
  2158.                   no = config->alias[sys.use_alias].node;
  2159.                   pp = config->alias[sys.use_alias].point;
  2160.                   z = config->alias[sys.use_alias].zone;
  2161.  
  2162.                   while ((p = strtok (NULL, " ")) != NULL) {
  2163.                      parse_netnode2 (p, &z, &ne, &no, &pp);
  2164.  
  2165.                      seen[n_seen].net = ne;
  2166.                      seen[n_seen].node = no;
  2167.                      seen[n_seen].point = pp;
  2168.                      seen[n_seen].zone = z;
  2169.  
  2170.                      if (n_seen >= MAX_EXPORT_SEEN)
  2171.                         continue;
  2172.  
  2173.                      n_seen++;
  2174.                   }
  2175.                }
  2176.                else if (!strncmp (buff, "\001PATH: ", 7) && need_seen) {
  2177.                   if (need_origin) {
  2178.                      mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  2179.                      if (strlen(sys.origin))
  2180.                         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);
  2181.                      else
  2182.                         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);
  2183.                      need_origin = 0;
  2184.                   }
  2185.  
  2186.                   if (!config->alias[sys.use_alias].point) {
  2187.                      seen[n_seen].net = config->alias[sys.use_alias].net;
  2188.                      seen[n_seen++].node = config->alias[sys.use_alias].node;
  2189.                   }
  2190.                   else if (config->alias[sys.use_alias].fakenet) {
  2191.                      seen[n_seen].net = config->alias[sys.use_alias].fakenet;
  2192.                      seen[n_seen++].node = config->alias[sys.use_alias].point;
  2193.                   }
  2194.  
  2195.                   seen[n_seen].net = net;
  2196.                   seen[n_seen++].node = node;
  2197.  
  2198.                   qsort (seen, n_seen, sizeof (struct _fwrd), mail_sort_func);
  2199.  
  2200.                   cnet = cnode = 0;
  2201.                   strcpy (wrp, "SEEN-BY: ");
  2202.  
  2203.                   for (i = 0; i < n_seen; i++) {
  2204.                      if (strlen (wrp) > 65) {
  2205.                         mprintf (fpd, "%s\r\n", wrp);
  2206.                         cnet = cnode = 0;
  2207.                         strcpy (wrp, "SEEN-BY: ");
  2208.                      }
  2209.                      if (i && seen[i].net == seen[i - 1].net && seen[i].node == seen[i - 1].node)
  2210.                         continue;
  2211.  
  2212.                      if (cnet != seen[i].net) {
  2213.                         sprintf (buffer, "%d/%d ", seen[i].net, seen[i].node);
  2214.                         cnet = seen[i].net;
  2215.                         cnode = seen[i].node;
  2216.                      }
  2217.                      else if (cnet == seen[i].net && cnode != seen[i].node) {
  2218.                         sprintf (buffer, "%d ", seen[i].node);
  2219.                         cnode = seen[i].node;
  2220.                      }
  2221.                      else
  2222.                         strcpy (buffer, "");
  2223.  
  2224.                      strcat (wrp, buffer);
  2225.                   }
  2226.  
  2227.                   mprintf (fpd, "%s\r\n", wrp);
  2228.                   mprintf (fpd, "%s\r\n", buff);
  2229.  
  2230.                   need_seen = 0;
  2231.                }
  2232.                else if ((xmsg.attr & MSGLOCAL) && !strncmp (buff, "--- ", 4) && (config->replace_tear || !registered))
  2233.                   replace_tearline (fpd, buff);
  2234.                else
  2235.                   mprintf (fpd, "%s\r\n", buff);
  2236.  
  2237.                mi = 0;
  2238.             }
  2239.             else {
  2240.                if(mi < 78)
  2241.                   continue;
  2242.  
  2243.                if (!strncmp(buff,msgtxt[M_ORIGIN_LINE],11))
  2244.                   need_origin = 0;
  2245.  
  2246.                buff[mi]='\0';
  2247.                mprintf(fpd,"%s",buff);
  2248.                mi=0;
  2249.                buff[mi] = '\0';
  2250.             }
  2251.          }
  2252.       } while (rd == 80);
  2253.  
  2254.       if (!n_seen) {
  2255.          if (need_origin) {
  2256.             mprintf (fpd, msgtxt[M_TEAR_LINE],VERSION, registered ? "+" : NOREG);
  2257.             if (strlen(sys.origin))
  2258.                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);
  2259.             else
  2260.                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);
  2261.             need_origin = 0;
  2262.          }
  2263.  
  2264.          if (!config->alias[sys.use_alias].point) {
  2265.             seen[n_seen].net = config->alias[sys.use_alias].net;
  2266.             seen[n_seen++].node = config->alias[sys.use_alias].node;
  2267.          }
  2268.          else if (config->alias[sys.use_alias].fakenet) {
  2269.             seen[n_seen].net = config->alias[sys.use_alias].fakenet;
  2270.             seen[n_seen++].node = config->alias[sys.use_alias].point;
  2271.          }
  2272.  
  2273.          seen[n_seen].net = net;
  2274.          seen[n_seen++].node = node;
  2275.  
  2276.          qsort (seen, n_seen, sizeof (struct _fwrd), mail_sort_func);
  2277.  
  2278.          cnet = cnode = 0;
  2279.          strcpy (wrp, "SEEN-BY: ");
  2280.  
  2281.          for (i = 0; i < n_seen; i++) {
  2282.             if (cnet != seen[i].net) {
  2283.                sprintf (buffer, "%d/%d ", seen[i].net, seen[i].node);
  2284.                cnet = seen[i].net;
  2285.                cnode = seen[i].node;
  2286.             }
  2287.             else if (cnet == seen[i].net && cnode != seen[i].node) {
  2288.                sprintf (buffer, "%d ", seen[i].node);
  2289.                cnode = seen[i].node;
  2290.             }
  2291.             else
  2292.                strcpy (buffer, "");
  2293.  
  2294.             strcat (wrp, buffer);
  2295.          }
  2296.  
  2297.          mprintf (fpd, "%s\r\n", wrp);
  2298.          if (config->alias[sys.use_alias].point && config->alias[sys.use_alias].fakenet)
  2299.             mprintf (fpd, "\001PATH: %d/%d\r\n", config->alias[sys.use_alias].fakenet, config->alias[sys.use_alias].point);
  2300.          else if (!config->alias[sys.use_alias].point)
  2301.             mprintf (fpd, "\001PATH: %d/%d\r\n", config->alias[sys.use_alias].net, config->alias[sys.use_alias].node);
  2302.       }
  2303.  
  2304.       if (ai)
  2305.          sys.use_alias = ai - 1;
  2306.  
  2307.       mhdr.ver = PKTVER;
  2308.       if (config->alias[sys.use_alias].point && config->alias[sys.use_alias].fakenet) {
  2309.          mhdr.orig_node = config->alias[sys.use_alias].point;
  2310.          mhdr.orig_net = config->alias[sys.use_alias].fakenet;
  2311.       }
  2312.       else {
  2313.          mhdr.orig_node = config->alias[sys.use_alias].node;
  2314.          mhdr.orig_net = config->alias[sys.use_alias].net;
  2315.       }
  2316.       mhdr.cost = 0;
  2317.       mhdr.attrib = 0;
  2318.  
  2319.       if (sys.public)
  2320.          xmsg.attr &= ~MSGPRIVATE;
  2321.       else if (sys.private)
  2322.          xmsg.attr |= MSGPRIVATE;
  2323.  
  2324.       if (xmsg.attr & MSGPRIVATE)
  2325.          mhdr.attrib |= MSGPRIVATE;
  2326.  
  2327.       if (point)
  2328.          sprintf (wrp, "%d/%d.%d ", net, node, point);
  2329.       else
  2330.          sprintf (wrp, "%d/%d ", net, node);
  2331.       wreadcur (&z, &m);
  2332.       if ( (m + strlen (wrp)) > 78) {
  2333.          wputs ("\n");
  2334.          wputs ("                                           ");
  2335.       }
  2336.       wputs (wrp);
  2337.       if ( (m + strlen (wrp)) == 78)
  2338.          wputs ("                                           ");
  2339.  
  2340.       mi = open_packet (zone, net, node, point, sys.use_alias);
  2341.  
  2342.       mhdr.dest_net = net;
  2343.       mhdr.dest_node = node;
  2344.       write (mi, (char *)&mhdr, sizeof (struct _msghdr2));
  2345.  
  2346.       write (mi, xmsg.ftsc_date, strlen (xmsg.ftsc_date) + 1);
  2347.       write (mi, xmsg.to, strlen (xmsg.to) + 1);
  2348.       write (mi, xmsg.from, strlen (xmsg.from) + 1);
  2349.       write (mi, xmsg.subj, strlen (xmsg.subj) + 1);
  2350.       mseek (fpd, 0L, SEEK_SET);
  2351.       do {
  2352.          z = mread(buffer, 1, 2048, fpd);
  2353.          write(mi, buffer, z);
  2354.       } while (z == 2048);
  2355.       buff[0] = buff[1] = buff[2] = 0;
  2356.       if (write (mi, buff, 3) != 3)
  2357.          return;
  2358.       close (mi);
  2359.  
  2360.       totalmsg++;
  2361.       sprintf (wrp, "%d (%.1f/s) ", totalmsg, (float)totalmsg / ((float)(timerset (0) - totaltime) / 100));
  2362.       prints (10, 65, YELLOW|_BLACK, wrp);
  2363.  
  2364.       time_release ();
  2365.       MsgCloseMsg (sq_msgh);
  2366.  
  2367.       wputs ("\n");
  2368.       sent++;
  2369.    }
  2370.  
  2371.    if (sent)
  2372.       status_line (":   %-20.20s (Sent=%04d)", sys.echotag, sent);
  2373.  
  2374.    mclose (fpd);
  2375.    free (seen);
  2376.    unlink ("MSGTMP.EXP");
  2377. }
  2378.  
  2379.