home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / AREAFIX2.C < prev    next >
C/C++ Source or Header  |  1998-05-17  |  44KB  |  1,272 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 <stdlib.h>
  22. #include <io.h>
  23. #include <fcntl.h>
  24. #include <time.h>
  25. #include <sys\stat.h>
  26.  
  27. #include <cxl\cxlwin.h>
  28. #include <cxl\cxlstr.h>
  29.  
  30. #include "lsetup.h"
  31. #include "sched.h"
  32. #include "msgapi.h"
  33. #include "prototyp.h"
  34. #include "externs.h"
  35.  
  36. void fido_save_message2 (FILE *, char *);
  37. FILE *mopen (char *filename, char *mode);
  38. int mclose (FILE *fp);
  39. void mprintf (FILE *fp, char *format, ...);
  40. long mseek (FILE *fp, long position, int offset);
  41. int mputs (char *s, FILE *fp);
  42. int mread (char *s, int n, int e, FILE *fp);
  43. char *packet_fgets (char *, int, FILE *fp);
  44. void write_areasbbs (void);
  45.  
  46. void generate_echomail_status (FILE *, int , int, int, int, int);
  47. void forward_message (int num, int ozo, int one, int ono, int opo, char *alertnodes);
  48.  
  49. struct _fwd_alias {
  50.    int zone;
  51.    int net;
  52.    int node;
  53.    int point;
  54.    bit passive :1;
  55.    bit receive :1;
  56.    bit send    :1;
  57. };
  58.  
  59. static int areafix_level = -1;
  60. static long areafix_flags = 0;
  61.  
  62. static int sort_func (const void *a1, const void *b1)
  63. {
  64.    struct _fwd_alias *a, *b;
  65.    a = (struct _fwd_alias *)a1;
  66.    b = (struct _fwd_alias *)b1;
  67.    if (a->zone != b->zone)   return (a->zone - b->zone);
  68.    if (a->net != b->net)   return (a->net - b->net);
  69.    if (a->node != b->node)   return (a->node - b->node);
  70.    return ( (int)(a->point - b->point) );
  71. }
  72.  
  73. #define MAX_FORWARD   128
  74.  
  75. int add_tic_link (char *area, int zo, int ne, int no, int po)
  76. {
  77.    int fd, n_forw, m, czone, cnet, cnode, cpoint, cf, add_area = 1, i, level;
  78.    char linea[80], addr[40], *p, c;
  79.    long flags;
  80.    struct _fwd_alias *forward;
  81.    struct _sys tsys;
  82.  
  83.    level = areafix_level;
  84.    flags = areafix_flags;
  85.  
  86.    if (*area == '-') {
  87.       add_area = 0;
  88.       area++;
  89.    }
  90.    else {
  91.       add_area = 1;
  92.       if (*area == '+')
  93.          area++;
  94.    }
  95.  
  96.    forward = (struct _fwd_alias *)malloc (MAX_FORWARD * sizeof (struct _fwd_alias));
  97.    if (forward == NULL)
  98.       return (0);
  99.    memset (forward, 0, MAX_FORWARD * sizeof (struct _fwd_alias));
  100.  
  101.    sprintf (linea, "%sSYSFILE.DAT", config->sys_path);
  102.    fd = sh_open (linea, SH_DENYWR, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  103.    if (fd == -1) {
  104.       free (forward);
  105.       return (-1);
  106.    }
  107.  
  108.    while (read (fd, (char *)&tsys.file_name, SIZEOF_FILEAREA) == SIZEOF_FILEAREA) {
  109.       if (!tsys.tic_tag[0])
  110.          continue;
  111.       if (!stricmp (tsys.tic_tag, area))
  112.          break;
  113.    }
  114.  
  115.    if (stricmp (tsys.tic_tag, area)) {
  116.       close (fd);
  117.       free (forward);
  118.       return (-1);
  119.    }
  120.  
  121.    if (add_area && (tsys.tic_level > level || (flags & tsys.tic_flags) != tsys.tic_flags)) {
  122.       close (fd);
  123.       free (forward);
  124.       return (-4);
  125.    }
  126.  
  127.    n_forw = 0;
  128.    forward[n_forw].zone = config->alias[0].zone;
  129.    forward[n_forw].net = config->alias[0].net;
  130.    forward[n_forw].node = config->alias[0].node;
  131.    forward[n_forw].point = config->alias[0].point;
  132.  
  133.    p = strtok (tsys.tic_forward1, " ");
  134.    if (p != NULL)
  135.       do {
  136.          if (n_forw) {
  137.             forward[n_forw].zone = forward[n_forw - 1].zone;
  138.             forward[n_forw].net = forward[n_forw - 1].net;
  139.             forward[n_forw].node = forward[n_forw - 1].node;
  140.             forward[n_forw].point = forward[n_forw - 1].point;
  141.          }
  142.          if (*p == '<') {
  143.             forward[n_forw].send = 1;
  144.             p++;
  145.          }
  146.          if (*p == '>') {
  147.             forward[n_forw].receive = 1;
  148.             p++;
  149.          }
  150.          if (*p == '!') {
  151.             forward[n_forw].passive = 1;
  152.             p++;
  153.          }
  154.          parse_netnode2 (p, &forward[n_forw].zone, &forward[n_forw].net, &forward[n_forw].node, &forward[n_forw].point);
  155.          n_forw++;
  156.       } while ((p = strtok (NULL, " ")) != NULL);
  157.    p = strtok (tsys.tic_forward2, " ");
  158.    if (p != NULL)
  159.       do {
  160.          if (n_forw) {
  161.             forward[n_forw].zone = forward[n_forw - 1].zone;
  162.             forward[n_forw].net = forward[n_forw - 1].net;
  163.             forward[n_forw].node = forward[n_forw - 1].node;
  164.             forward[n_forw].point = forward[n_forw - 1].point;
  165.          }
  166.          if (*p == '<') {
  167.             forward[n_forw].send = 1;
  168.             p++;
  169.          }
  170.          if (*p == '>') {
  171.             forward[n_forw].receive = 1;
  172.             p++;
  173.          }
  174.          if (*p == '!') {
  175.             forward[n_forw].passive = 1;
  176.             p++;
  177.          }
  178.          parse_netnode2 (p, &forward[n_forw].zone, &forward[n_forw].net, &forward[n_forw].node, &forward[n_forw].point);
  179.          n_forw++;
  180.       } while ((p = strtok (NULL, " ")) != NULL);
  181.    p = strtok (tsys.tic_forward3, " ");
  182.    if (p != NULL)
  183.       do {
  184.          if (n_forw) {
  185.             forward[n_forw].zone = forward[n_forw - 1].zone;
  186.             forward[n_forw].net = forward[n_forw - 1].net;
  187.             forward[n_forw].node = forward[n_forw - 1].node;
  188.             forward[n_forw].point = forward[n_forw - 1].point;
  189.          }
  190.          if (*p == '<') {
  191.             forward[n_forw].send = 1;
  192.             p++;
  193.          }
  194.          if (*p == '>') {
  195.             forward[n_forw].receive = 1;
  196.             p++;
  197.          }
  198.          if (*p == '!') {
  199.             forward[n_forw].passive = 1;
  200.             p++;
  201.          }
  202.          parse_netnode2 (p, &forward[n_forw].zone, &forward[n_forw].net, &forward[n_forw].node, &forward[n_forw].point);
  203.          n_forw++;
  204.       } while ((p = strtok (NULL, " ")) != NULL);
  205.  
  206.    if (add_area) {
  207.       for (i = 0; i < n_forw; i++)
  208.          if (forward[i].zone == zo && forward[i].net == ne && forward[i].node == no && forward[i].point == po)
  209.             break;
  210.       if (i < n_forw) {
  211.          close (fd);
  212.          free (forward);
  213.          return (-3);
  214.       }
  215.       forward[n_forw].zone = zo;
  216.       forward[n_forw].net = ne;
  217.       forward[n_forw].node = no;
  218.       forward[n_forw].point = po;
  219.       n_forw++;
  220.    }
  221.    else {
  222.       for (i = 0; i < n_forw; i++)
  223.          if (forward[i].zone == zo && forward[i].net == ne && forward[i].node == no && forward[i].point == po)
  224.             break;
  225.       if (i >= n_forw) {
  226.          close (fd);
  227.          free (forward);
  228.          return (-2);
  229.       }
  230.  
  231.       for (m = i + 1; m < n_forw; m++)
  232.          memcpy (&forward[m - 1], &forward[m], sizeof (struct _fwd_alias));
  233.       n_forw--;
  234.    }
  235.  
  236.    qsort (forward, n_forw, sizeof (struct _fwd_alias), sort_func);
  237.  
  238.    czone = cpoint = cnet = cnode = 0;
  239.    strcpy (linea, "");
  240.    cf = 1;
  241.    tsys.tic_forward1[0] = tsys.tic_forward2[0] = tsys.tic_forward3[0] = '\0';
  242.  
  243.    for (m = 0; m < n_forw; m++) {
  244.       if (czone != forward[m].zone) {
  245.          if (forward[m].send || forward[m].receive || forward[m].passive) {
  246.             if (forward[m].send)
  247.                c = '<';
  248.             else if (forward[m].receive)
  249.                c = '>';
  250.             else if (forward[m].passive)
  251.                c = '!';
  252.             if (forward[m].point)
  253.                sprintf (addr, "%c%d:%d/%d.%d ", c, forward[m].zone, forward[m].net, forward[m].node, forward[m].point);
  254.             else
  255.                sprintf (addr, "%c%d:%d/%d ", c, forward[m].zone, forward[m].net, forward[m].node);
  256.          }
  257.          else {
  258.             if (forward[m].point)
  259.                sprintf (addr, "%d:%d/%d.%d ", forward[m].zone, forward[m].net, forward[m].node, forward[m].point);
  260.             else
  261.                sprintf (addr, "%d:%d/%d ", forward[m].zone, forward[m].net, forward[m].node);
  262.          }
  263.          czone = forward[m].zone;
  264.          cnet = forward[m].net;
  265.          cnode = forward[m].node;
  266.          cpoint = forward[m].point;
  267.       }
  268.       else if (cnet != forward[m].net) {
  269.          if (forward[m].send || forward[m].receive || forward[m].passive) {
  270.             if (forward[m].send)
  271.                c = '<';
  272.             else if (forward[m].receive)
  273.                c = '>';
  274.             else if (forward[m].passive)
  275.                c = '!';
  276.             if (forward[m].point)
  277.                sprintf (addr, "%c%d/%d.%d ", c, forward[m].net, forward[m].node, forward[m].point);
  278.             else
  279.                sprintf (addr, "%c%d/%d ", c, forward[m].net, forward[m].node);
  280.          }
  281.          else {
  282.             if (forward[m].point)
  283.                sprintf (addr, "%d/%d.%d ", forward[m].net, forward[m].node, forward[m].point);
  284.             else
  285.                sprintf (addr, "%d/%d ", forward[m].net, forward[m].node);
  286.          }
  287.          cnet = forward[m].net;
  288.          cnode = forward[m].node;
  289.          cpoint = forward[m].point;
  290.       }
  291.       else if (cnode != forward[m].node) {
  292.          if (forward[m].send || forward[m].receive || forward[m].passive) {
  293.             if (forward[m].send)
  294.                c = '<';
  295.             else if (forward[m].receive)
  296.                c = '>';
  297.             else if (forward[m].passive)
  298.                c = '!';
  299.             if (forward[m].point)
  300.                sprintf (addr, "%c%d.%d ", c, forward[m].node, forward[m].point);
  301.             else
  302.                sprintf (addr, "%c%d ", c, forward[m].node);
  303.          }
  304.          else {
  305.             if (forward[m].point)
  306.                sprintf (addr, "%d.%d ", forward[m].node, forward[m].point);
  307.             else
  308.                sprintf (addr, "%d ", forward[m].node);
  309.          }
  310.          cnode = forward[m].node;
  311.          cpoint = forward[m].point;
  312.       }
  313.       else if (forward[m].point && cpoint != forward[m].point) {
  314.          if (forward[m].send || forward[m].receive || forward[m].passive) {
  315.             if (forward[m].send)
  316.                c = '<';
  317.             else if (forward[m].receive)
  318.                c = '>';
  319.             else if (forward[m].passive)
  320.                c = '!';
  321.             sprintf (addr, "%c.%d ", c, forward[m].point);
  322.          }
  323.          else
  324.             sprintf (addr, ".%d ", forward[m].point);
  325.          cpoint = forward[m].point;
  326.       }
  327.       else
  328.          strcpy (addr, "");
  329.  
  330.         if (strlen (linea) + strlen (addr) >= 68) {
  331.          if (cf == 1) {
  332.             strcpy (tsys.tic_forward1, linea);
  333.             cf++;
  334.          }
  335.          else if (cf == 2) {
  336.             strcpy (tsys.tic_forward2, linea);
  337.             cf++;
  338.          }
  339.          else if (cf == 3) {
  340.             strcpy (tsys.tic_forward3, linea);
  341.             cf++;
  342.          }
  343.  
  344.          linea[0] = '\0';
  345.  
  346.          if (forward[m].send || forward[m].receive || forward[m].passive) {
  347.             if (forward[m].send)
  348.                c = '<';
  349.             else if (forward[m].receive)
  350.                c = '>';
  351.             else if (forward[m].passive)
  352.                c = '!';
  353.             if (forward[m].point)
  354.                sprintf (addr, "%c%d:%d/%d.%d ", c, forward[m].zone, forward[m].net, forward[m].node, forward[m].point);
  355.             else
  356.                sprintf (addr, "%c%d:%d/%d ", c, forward[m].zone, forward[m].net, forward[m].node);
  357.          }
  358.          else {
  359.             if (forward[m].point)
  360.                sprintf (addr, "%d:%d/%d.%d ", forward[m].zone, forward[m].net, forward[m].node, forward[m].point);
  361.             else
  362.                sprintf (addr, "%d:%d/%d ", forward[m].zone, forward[m].net, forward[m].node);
  363.          }
  364.          czone = forward[m].zone;
  365.          cnet = forward[m].net;
  366.          cnode = forward[m].node;
  367.          cpoint = forward[m].point;
  368.       }
  369.  
  370.       strcat (linea, addr);
  371.    }
  372.  
  373.    if (strlen (linea) > 2) {
  374.       if (cf == 1) {
  375.          strcpy (tsys.tic_forward1, linea);
  376.          cf++;
  377.       }
  378.       else if (cf == 2) {
  379.          strcpy (tsys.tic_forward2, linea);
  380.          cf++;
  381.       }
  382.       else if (cf == 3) {
  383.          strcpy (tsys.tic_forward3, linea);
  384.          cf++;
  385.       }
  386.    }
  387.  
  388.    lseek (fd, -1L * SIZEOF_FILEAREA, SEEK_CUR);
  389.    write (fd, (char *)&tsys.file_name, SIZEOF_FILEAREA);
  390.    close (fd);
  391.  
  392.    if (add_area)
  393.       status_line (":  %s added", strupr (tsys.tic_tag));
  394.    else
  395.       status_line (":  %s removed", strupr (tsys.tic_tag));
  396.  
  397.    free (forward);
  398.    return (1);
  399. }
  400.  
  401. void scan_all_tic (FILE *fp, int add_area, int zo, int ne, int no, int po)
  402. {
  403.    int fd, n_forw, m, czone, cnet, cnode, cpoint, cf, i, level;
  404.    char linea[80], addr[40], *p, c;
  405.    long flags;
  406.    struct _fwd_alias *forward;
  407.    struct _sys tsys;
  408.  
  409.    level = areafix_level;
  410.    flags = areafix_flags;
  411.  
  412.    forward = (struct _fwd_alias *)malloc (MAX_FORWARD * sizeof (struct _fwd_alias));
  413.    if (forward == NULL)
  414.       return;
  415.    memset (forward, 0, MAX_FORWARD * sizeof (struct _fwd_alias));
  416.  
  417.    sprintf (linea, "%sSYSFILE.DAT", config->sys_path);
  418.    fd = sh_open (linea, SH_DENYNONE, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  419.    if (fd == -1) {
  420.       free (forward);
  421.       return;
  422.    }
  423.  
  424.    while (read (fd, (char *)&tsys.file_name, SIZEOF_FILEAREA) == SIZEOF_FILEAREA) {
  425.       if (!tsys.tic_tag[0])
  426.          continue;
  427.       if (tsys.tic_level > level || (flags & tsys.tic_flags) != tsys.tic_flags)
  428.          continue;
  429.  
  430.       n_forw = 0;
  431.       forward[n_forw].zone = config->alias[0].zone;
  432.       forward[n_forw].net = config->alias[0].net;
  433.       forward[n_forw].node = config->alias[0].node;
  434.       forward[n_forw].point = config->alias[0].point;
  435.  
  436.       p = strtok (tsys.tic_forward1, " ");
  437.       if (p != NULL)
  438.          do {
  439.             if (n_forw) {
  440.                forward[n_forw].zone = forward[n_forw - 1].zone;
  441.                forward[n_forw].net = forward[n_forw - 1].net;
  442.                forward[n_forw].node = forward[n_forw - 1].node;
  443.                forward[n_forw].point = forward[n_forw - 1].point;
  444.             }
  445.             forward[n_forw].receive = forward[n_forw].send = forward[n_forw].passive = 0;
  446.             while (*p == '<' || *p == '>' || *p == '!') {
  447.                if (*p == '>')
  448.                   forward[n_forw].receive = 1;
  449.                if (*p == '<')
  450.                   forward[n_forw].send = 1;
  451.                if (*p == '!')
  452.                   forward[n_forw].passive = 1;
  453.                p++;
  454.             }
  455.             parse_netnode2 (p, &forward[n_forw].zone, &forward[n_forw].net, &forward[n_forw].node, &forward[n_forw].point);
  456.             n_forw++;
  457.          } while ((p = strtok (NULL, " ")) != NULL);
  458.       p = strtok (tsys.tic_forward2, " ");
  459.       if (p != NULL)
  460.          do {
  461.             if (n_forw) {
  462.                forward[n_forw].zone = forward[n_forw - 1].zone;
  463.                forward[n_forw].net = forward[n_forw - 1].net;
  464.                forward[n_forw].node = forward[n_forw - 1].node;
  465.                forward[n_forw].point = forward[n_forw - 1].point;
  466.             }
  467.             forward[n_forw].receive = forward[n_forw].send = forward[n_forw].passive = 0;
  468.             while (*p == '<' || *p == '>' || *p == '!') {
  469.                if (*p == '>')
  470.                   forward[n_forw].receive = 1;
  471.                if (*p == '<')
  472.                   forward[n_forw].send = 1;
  473.                if (*p == '!')
  474.                   forward[n_forw].passive = 1;
  475.                p++;
  476.             }
  477.             parse_netnode2 (p, &forward[n_forw].zone, &forward[n_forw].net, &forward[n_forw].node, &forward[n_forw].point);
  478.             n_forw++;
  479.          } while ((p = strtok (NULL, " ")) != NULL);
  480.       p = strtok (tsys.tic_forward3, " ");
  481.       if (p != NULL)
  482.          do {
  483.             if (n_forw) {
  484.                forward[n_forw].zone = forward[n_forw - 1].zone;
  485.                forward[n_forw].net = forward[n_forw - 1].net;
  486.                forward[n_forw].node = forward[n_forw - 1].node;
  487.                forward[n_forw].point = forward[n_forw - 1].point;
  488.             }
  489.             forward[n_forw].receive = forward[n_forw].send = forward[n_forw].passive = 0;
  490.             while (*p == '<' || *p == '>' || *p == '!') {
  491.                if (*p == '>')
  492.                   forward[n_forw].receive = 1;
  493.                if (*p == '<')
  494.                   forward[n_forw].send = 1;
  495.                if (*p == '!')
  496.                   forward[n_forw].passive = 1;
  497.                p++;
  498.             }
  499.             parse_netnode2 (p, &forward[n_forw].zone, &forward[n_forw].net, &forward[n_forw].node, &forward[n_forw].point);
  500.             n_forw++;
  501.          } while ((p = strtok (NULL, " ")) != NULL);
  502.  
  503.       if (add_area) {
  504.          for (i = 0; i < n_forw; i++)
  505.             if (forward[i].zone == zo && forward[i].net == ne && forward[i].node == no && forward[i].point == po)
  506.                break;
  507.          if (i < n_forw)
  508.             continue;
  509.          forward[n_forw].zone = zo;
  510.          forward[n_forw].net = ne;
  511.          forward[n_forw].node = no;
  512.          forward[n_forw].point = po;
  513.          n_forw++;
  514.       }
  515.       else {
  516.          for (i = 0; i < n_forw; i++)
  517.             if (forward[i].zone == zo && forward[i].net == ne && forward[i].node == no && forward[i].point == po)
  518.                break;
  519.          if (i >= n_forw)
  520.             continue;
  521.  
  522.          for (m = i + 1; m < n_forw; m++)
  523.             memcpy (&forward[m - 1], &forward[m], sizeof (struct _fwd_alias));
  524.          n_forw--;
  525.       }
  526.  
  527.       qsort (forward, n_forw, sizeof (struct _fwd_alias), sort_func);
  528.  
  529.       czone = cpoint = cnet = cnode = 0;
  530.       strcpy (linea, "");
  531.       cf = 1;
  532.       tsys.tic_forward1[0] = tsys.tic_forward2[0] = tsys.tic_forward3[0] = '\0';
  533.  
  534.       for (m = 0; m < n_forw; m++) {
  535.          if (czone != forward[m].zone) {
  536.             if (forward[m].send || forward[m].receive || forward[m].passive) {
  537.                if (forward[m].send)
  538.                   c = '<';
  539.                else if (forward[m].receive)
  540.                   c = '>';
  541.                else if (forward[m].passive)
  542.                   c = '!';
  543.                if (forward[m].point)
  544.                   sprintf (addr, "%c%d:%d/%d.%d ", c, forward[m].zone, forward[m].net, forward[m].node, forward[m].point);
  545.                else
  546.                   sprintf (addr, "%c%d:%d/%d ", c, forward[m].zone, forward[m].net, forward[m].node);
  547.             }
  548.             else {
  549.                if (forward[m].point)
  550.                   sprintf (addr, "%d:%d/%d.%d ", forward[m].zone, forward[m].net, forward[m].node, forward[m].point);
  551.                else
  552.                   sprintf (addr, "%d:%d/%d ", forward[m].zone, forward[m].net, forward[m].node);
  553.             }
  554.             czone = forward[m].zone;
  555.             cnet = forward[m].net;
  556.             cnode = forward[m].node;
  557.             cpoint = forward[m].point;
  558.          }
  559.          else if (cnet != forward[m].net) {
  560.             if (forward[m].send || forward[m].receive || forward[m].passive) {
  561.                if (forward[m].send)
  562.                   c = '<';
  563.                else if (forward[m].receive)
  564.                   c = '>';
  565.                else if (forward[m].passive)
  566.                   c = '!';
  567.                if (forward[m].point)
  568.                   sprintf (addr, "%c%d/%d.%d ", c, forward[m].net, forward[m].node, forward[m].point);
  569.                else
  570.                   sprintf (addr, "%c%d/%d ", c, forward[m].net, forward[m].node);
  571.             }
  572.             else {
  573.                if (forward[m].point)
  574.                   sprintf (addr, "%d/%d.%d ", forward[m].net, forward[m].node, forward[m].point);
  575.                else
  576.                   sprintf (addr, "%d/%d ", forward[m].net, forward[m].node);
  577.             }
  578.             cnet = forward[m].net;
  579.             cnode = forward[m].node;
  580.             cpoint = forward[m].point;
  581.          }
  582.          else if (cnode != forward[m].node) {
  583.             if (forward[m].send || forward[m].receive || forward[m].passive) {
  584.                if (forward[m].send)
  585.                   c = '<';
  586.                else if (forward[m].receive)
  587.                   c = '>';
  588.                else if (forward[m].passive)
  589.                   c = '!';
  590.                if (forward[m].point)
  591.                   sprintf (addr, "%c%d.%d ", c, forward[m].node, forward[m].point);
  592.                else
  593.                   sprintf (addr, "%c%d ", c, forward[m].node);
  594.             }
  595.             else {
  596.                if (forward[m].point)
  597.                   sprintf (addr, "%d.%d ", forward[m].node, forward[m].point);
  598.                else
  599.                   sprintf (addr, "%d ", forward[m].node);
  600.             }
  601.             cnode = forward[m].node;
  602.             cpoint = forward[m].point;
  603.          }
  604.          else if (forward[m].point && cpoint != forward[m].point) {
  605.             if (forward[m].send || forward[m].receive || forward[m].passive) {
  606.                if (forward[m].send)
  607.                   c = '<';
  608.                else if (forward[m].receive)
  609.                   c = '>';
  610.                else if (forward[m].passive)
  611.                   c = '!';
  612.                sprintf (addr, "%c.%d ", c, forward[m].point);
  613.             }
  614.             else
  615.                sprintf (addr, ".%d ", forward[m].point);
  616.             cpoint = forward[m].point;
  617.          }
  618.          else
  619.             strcpy (addr, "");
  620.  
  621.             if (strlen (linea) + strlen (addr) >= 68) {
  622.             if (cf == 1) {
  623.                strcpy (tsys.tic_forward1, linea);
  624.                cf++;
  625.             }
  626.             else if (cf == 2) {
  627.                strcpy (tsys.tic_forward2, linea);
  628.                cf++;
  629.             }
  630.             else if (cf == 3) {
  631.                strcpy (tsys.tic_forward3, linea);
  632.                cf++;
  633.             }
  634.  
  635.             linea[0] = '\0';
  636.  
  637.             if (forward[m].send || forward[m].receive || forward[m].passive) {
  638.                if (forward[m].send)
  639.                   c = '<';
  640.                else if (forward[m].receive)
  641.                   c = '>';
  642.                else if (forward[m].passive)
  643.                   c = '!';
  644.                if (forward[m].point)
  645.                   sprintf (addr, "%c%d:%d/%d.%d ", c, forward[m].zone, forward[m].net, forward[m].node, forward[m].point);
  646.                else
  647.                   sprintf (addr, "%c%d:%d/%d ", c, forward[m].zone, forward[m].net, forward[m].node);
  648.             }
  649.             else {
  650.                if (forward[m].point)
  651.                   sprintf (addr, "%d:%d/%d.%d ", forward[m].zone, forward[m].net, forward[m].node, forward[m].point);
  652.                else
  653.                   sprintf (addr, "%d:%d/%d ", forward[m].zone, forward[m].net, forward[m].node);
  654.             }
  655.             czone = forward[m].zone;
  656.             cnet = forward[m].net;
  657.             cnode = forward[m].node;
  658.             cpoint = forward[m].point;
  659.          }
  660.  
  661.          strcat (linea, addr);
  662.       }
  663.  
  664.       if (strlen (linea) > 2) {
  665.          if (cf == 1) {
  666.             strcpy (tsys.tic_forward1, linea);
  667.             cf++;
  668.          }
  669.          else if (cf == 2) {
  670.             strcpy (tsys.tic_forward2, linea);
  671.             cf++;
  672.          }
  673.          else if (cf == 3) {
  674.             strcpy (tsys.tic_forward3, linea);
  675.             cf++;
  676.          }
  677.       }
  678.  
  679.       lseek (fd, -1L * SIZEOF_FILEAREA, SEEK_CUR);
  680.       write (fd, (char *)&tsys.file_name, SIZEOF_FILEAREA);
  681.  
  682.       if (add_area) {
  683.             status_line (":  %s added", strupr (tsys.tic_tag));
  684.             mprintf (fp, "Area %s has been added.\r\n", strupr (tsys.tic_tag));
  685.         }
  686.         else {
  687.             status_line (":  %s removed", strupr (tsys.tic_tag));
  688.             mprintf (fp, "Area %s has been removed.\r\n", strupr (tsys.tic_tag));
  689.       }
  690.    }
  691.  
  692.    free (forward);
  693.    close (fd);
  694.  
  695.    return;
  696. }
  697.  
  698. int utility_add_tic_link (char *area, int zo, int ne, int no, int po, FILE *fpr)
  699. {
  700.    int fd;
  701.    char linea[80];
  702.    NODEINFO ni;
  703.  
  704.    areafix_level = -1;
  705.  
  706.    sprintf (linea, "%sNODES.DAT", config->net_info);
  707.    fd = sh_open (linea, SH_DENYWR, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  708.    if (fd != -1) {
  709.       while (read (fd, (char *)&ni, sizeof (NODEINFO)) == sizeof (NODEINFO))
  710.          if (zo == ni.zone && ne == ni.net && no == ni.node && po == ni.point) {
  711.             areafix_level = ni.tic_level;
  712.             areafix_flags = ni.tic_flags;
  713.             break;
  714.          }
  715.  
  716.       close (fd);
  717.    }
  718.  
  719.    if (!stricmp (area, "%-ALL")) {
  720.       scan_all_tic (fpr, 0, zo, ne, no, po);
  721.       return (0);
  722.    }
  723.  
  724.    else if (!stricmp (area, "%+ALL") || !stricmp (area, "%ALL")) {
  725.       scan_all_tic (fpr, 1, zo, ne, no, po);
  726.       return (0);
  727.    }
  728.  
  729.    return (add_tic_link (area, zo, ne, no, po));
  730. }
  731.  
  732. /*
  733.    Genera una lista con lo stato del link echomail.
  734.  
  735.    type = 1 - Aree disponibili (agganciate e non)
  736.           2 - Aree agganciate
  737.           3 - Aree non agganciate
  738. */
  739.  
  740. void generate_tic_status (FILE *fp, int zo, int ne, int no, int po, int type)
  741. {
  742.    int fd, czone, cnet, cnode, cpoint, nlink, level;
  743.    char linea[80], *p, found;
  744.    long flags;
  745.    struct _sys tsys;
  746.  
  747.    level = areafix_level;
  748.    flags = areafix_flags;
  749.  
  750.    if (type == 1)
  751.       mprintf (fp, "Area(s) available to %d:%d/%d.%d:\r\n\r\n", zo, ne, no, po);
  752.    else if (type == 2)
  753.       mprintf (fp, "%d:%d/%d.%d is now linked to the following area(s):\r\n\r\n", zo, ne, no, po);
  754.    else if (type == 3)
  755.       mprintf (fp, "Area(s) not linked to %d:%d/%d.%d:\r\n\r\n", zo, ne, no, po);
  756.  
  757.    sprintf (linea, "%sSYSFILE.DAT", config->sys_path);
  758.    fd = sh_open (linea, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  759.    if (fd == -1)
  760.       return;
  761.  
  762.    nlink = 0;
  763.  
  764.    while (read (fd, (char *)&tsys.file_name, SIZEOF_FILEAREA) == SIZEOF_FILEAREA) {
  765.       if (!tsys.tic_tag[0])
  766.          continue;
  767.  
  768.       czone = config->alias[tsys.use_alias].zone;
  769.       cnet = config->alias[tsys.use_alias].net;
  770.       cnode = config->alias[tsys.use_alias].node;
  771.       cpoint = config->alias[tsys.use_alias].point;
  772.       found = 0;
  773.  
  774.       if (!found) {
  775.          p = strtok (tsys.tic_forward1, " ");
  776.          if (p != NULL)
  777.            do {
  778.                if (*p == '<' || *p == '>' || *p == '!')
  779.                   p++;
  780.                parse_netnode2 (p, &czone, &cnet, &cnode, &cpoint);
  781.                if (czone == zo && cnet == ne && cnode == no && cpoint == po) {
  782.                   found = 1;
  783.                   break;
  784.                }
  785.             } while ((p = strtok (NULL, " ")) != NULL);
  786.       }
  787.  
  788.       if (!found) {
  789.          p = strtok (tsys.tic_forward2, " ");
  790.          if (p != NULL)
  791.            do {
  792.                if (*p == '<' || *p == '>' || *p == '!')
  793.                   p++;
  794.                parse_netnode2 (p, &czone, &cnet, &cnode, &cpoint);
  795.                if (czone == zo && cnet == ne && cnode == no && cpoint == po) {
  796.                   found = 1;
  797.                   break;
  798.                }
  799.             } while ((p = strtok (NULL, " ")) != NULL);
  800.       }
  801.  
  802.       if (!found) {
  803.          p = strtok (tsys.tic_forward3, " ");
  804.          if (p != NULL)
  805.            do {
  806.                if (*p == '<' || *p == '>' || *p == '!')
  807.                   p++;
  808.                parse_netnode2 (p, &czone, &cnet, &cnode, &cpoint);
  809.                if (czone == zo && cnet == ne && cnode == no && cpoint == po) {
  810.                   found = 1;
  811.                   break;
  812.                }
  813.             } while ((p = strtok (NULL, " ")) != NULL);
  814.       }
  815.  
  816.       if (type == 1 && (tsys.tic_level <= level && (flags & tsys.tic_flags) == tsys.tic_flags)) {
  817.          if (strlen (tsys.file_name) > 52)
  818.             tsys.file_name[52] = '\0';
  819.          mprintf (fp, "%-25.25s %s\r\n", tsys.tic_tag, tsys.file_name);
  820.          nlink++;
  821.       }
  822.       else if (type == 2) {
  823.          if (found) {
  824.             if (strlen (tsys.file_name) > 52)
  825.                tsys.file_name[52] = '\0';
  826.             mprintf (fp, "%-25.25s %s\r\n", tsys.tic_tag, tsys.file_name);
  827.             nlink++;
  828.          }
  829.       }
  830.       else if (type == 3 && (tsys.tic_level <= level && (flags & tsys.tic_flags) == tsys.tic_flags)) {
  831.          if (!found) {
  832.             if (strlen (tsys.file_name) > 52)
  833.                tsys.file_name[52] = '\0';
  834.             mprintf (fp, "%-25.25s %s\r\n", tsys.tic_tag, tsys.file_name);
  835.             nlink++;
  836.          }
  837.       }
  838.    }
  839.  
  840.    close (fd);
  841.  
  842.    if (type == 1)
  843.       mprintf (fp, "\r\n%d TIC area(s) available.\r\n", nlink);
  844.    else if (type == 2)
  845.       mprintf (fp, "\r\n%d TIC area(s) linked.\r\n", nlink);
  846.    else if (type == 3)
  847.       mprintf (fp, "\r\n%d TIC area(s) not linked.\r\n", nlink);
  848. }
  849.  
  850. int change_tictag (char *oldname, char *newname)
  851. {
  852.    int fd, found = 0;
  853.    char filename[80];
  854.    long pos;
  855.    struct _sys tsys;
  856.  
  857.    sprintf (filename, "%sSYSFILE.DAT", config->sys_path);
  858.    fd = sh_open (filename, SH_DENYNONE, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  859.    if (fd == -1)
  860.       return (0);
  861.  
  862.    pos = tell (fd);
  863.    while (read (fd, (char *)&tsys.file_name, SIZEOF_FILEAREA) == SIZEOF_FILEAREA) {
  864.       if (!tsys.tic_tag[0])
  865.          continue;
  866.       if (!stricmp (tsys.tic_tag, oldname)) {
  867.          found = 1;
  868.          break;
  869.       }
  870.       pos = tell (fd);
  871.    }
  872.  
  873.    if (found) {
  874.       strcpy (tsys.tic_tag, strupr (newname));
  875.       status_line (":  %s changed to %s", strupr (oldname), newname);
  876.       lseek (fd, pos, SEEK_SET);
  877.       write (fd, (char *)&tsys.file_name, SIZEOF_MSGAREA);
  878.    }
  879.  
  880.    close (fd);
  881.  
  882.    return (found);
  883. }
  884.  
  885. void process_raid_request (fpm, zo, ne, no, po, subj)
  886. FILE *fpm;
  887. int zo, ne, no, po;
  888. char *subj;
  889. {
  890.    FILE *fp, *fph;
  891.     int fd, i, level = -1, use_aka = 0;
  892.    char linea[80], filename[80], *p, doquery = 0, *o, postmsg = 0;
  893.    long npos;
  894.    NODEINFO ni;
  895.    struct _msg tmsg;
  896.  
  897.    areafix_level = -1;
  898.    areafix_flags = 0;
  899.    status_line ("#Process Raid requests for %d:%d/%d.%d", zo, ne, no, po);
  900.  
  901.    p = strtok (subj, " ");
  902.    if (p == NULL)
  903.       return;
  904.    strcpy (linea, p);
  905.    while ((p = strtok (NULL, " ")) != NULL) {
  906.       if (!stricmp (p, "-Q"))
  907.          doquery = 1;
  908.    }
  909.  
  910.    sprintf (filename, "%sNODES.DAT", config->net_info);
  911.    fd = sh_open (filename, SH_DENYWR, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  912.  
  913.    while (read (fd, (char *)&ni, sizeof (NODEINFO)) == sizeof (NODEINFO))
  914.       if (zo == ni.zone && ne == ni.net && no == ni.node && po == ni.point) {
  915.          level = ni.tic_level;
  916.          areafix_level = level;
  917.          areafix_flags = ni.tic_flags;
  918.             use_aka = ni.tic_aka;
  919.             if (use_aka > 0)
  920.                 use_aka--;
  921.          break;
  922.       }
  923.  
  924.    if (level == -1 && po) {
  925.       for (i = 0; config->alias[i].net && i < MAX_ALIAS; i++) {
  926.          if (zo == config->alias[i].zone && ne == config->alias[i].net && no == config->alias[i].node && config->alias[i].fakenet)
  927.             break;
  928.       }
  929.  
  930.       if (config->alias[i].net && i < MAX_ALIAS) {
  931.          no = po;
  932.          ne = config->alias[i].fakenet;
  933.          po = 0;
  934.  
  935.          lseek (fd, 0L, SEEK_SET);
  936.  
  937.          while (read (fd, (char *)&ni, sizeof (NODEINFO)) == sizeof (NODEINFO))
  938.             if (zo == ni.zone && ne == ni.net && no == ni.node && po == ni.point) {
  939.                level = ni.afx_level;
  940.                areafix_level = level;
  941.                areafix_flags = ni.afx_flags;
  942.                     use_aka = ni.tic_aka;
  943.                     if (use_aka > 0)
  944.                         use_aka--;
  945.                break;
  946.             }
  947.       }
  948.    }
  949.  
  950.    close (fd);
  951.  
  952.    strcpy (ni.sysop_name, msg.from);
  953.    memset ((char *)&msg, 0, sizeof (struct _msg));
  954.    strcpy (msg.to, ni.sysop_name);
  955.    strcpy (msg.from, VERSION);
  956.    strcpy (msg.subj, "TIC changes report");
  957.    msg.attr = MSGLOCAL|MSGPRIVATE;
  958.    data (msg.date);
  959.    msg.dest_net = ne;
  960.    msg.dest = no;
  961.    msg_tzone = zo;
  962.    msg_tpoint = po;
  963. //   if (use_aka)
  964. //      use_aka--;
  965.     msg_fzone = config->alias[use_aka].zone;
  966.     if (config->alias[use_aka].point && config->alias[use_aka].fakenet) {
  967.         msg.orig = config->alias[use_aka].point;
  968.         msg.orig_net = config->alias[use_aka].fakenet;
  969.         msg_fpoint = 0;
  970.     }
  971.     else {
  972.         msg.orig = config->alias[use_aka].node;
  973.         msg.orig_net = config->alias[use_aka].net;
  974.         msg_fpoint = config->alias[use_aka].point;
  975.    }
  976.    memcpy ((char *)&tmsg, (char *)&msg, sizeof (struct _msg));
  977.  
  978.    if (level == -1 || stricmp (linea, ni.pw_tic)) {
  979.       if (level != -1)
  980.          status_line (msgtxt[M_PWD_ERROR], zo, ne, no, po, linea, ni.pw_areafix);
  981.       else
  982.          status_line ("!TIC password not found for %d:%d/%d.%d", zo, ne, no, po);
  983.  
  984.       sprintf (filename, "ECHOR%d.TMP", config->line_offset);
  985.       fp = mopen (filename, "w+t");
  986.  
  987.       if (msg_tzone != msg_fzone || config->force_intl)
  988.          mprintf(fp,msgtxt[M_INTL], msg_tzone, msg.dest_net, msg.dest, msg_fzone, msg.orig_net, msg.orig);
  989.       if (msg_tpoint)
  990.          mprintf(fp,"\001TOPT %d\r\n", msg_tpoint);
  991.       mprintf(fp,msgtxt[M_PID], VERSION, registered ? "" : NOREG);
  992.         mprintf(fp,msgtxt[M_MSGID], config->alias[use_aka].zone, config->alias[use_aka].net, config->alias[use_aka].node, config->alias[use_aka].point, time(NULL));
  993.  
  994.       mprintf (fp, "\r\nNode %d:%d/%d.%d isn't authorized to use raid at %d:%d/%d.%d\r\n\r\n", zo, ne, no, po, msg_fzone, msg.orig_net, msg.orig, msg_fpoint);
  995.  
  996.       mprintf (fp, "\r\n");
  997.       mprintf(fp,msgtxt[M_TEAR_LINE],VERSION, registered ? "" : NOREG);
  998.  
  999.       mseek (fp, 0L, SEEK_SET);
  1000.       fido_save_message2 (fp, NULL);
  1001.       mclose (fp);
  1002.  
  1003.       sprintf (filename, "ECHOR%d.TMP", config->line_offset);
  1004.       unlink (filename);
  1005.  
  1006.       forward_message (last_msg, zo, ne, no, po, config->tic_alert_nodes);
  1007.  
  1008.       return;
  1009.    }
  1010.  
  1011.    get_bbs_record (zo, ne, no, po);
  1012.  
  1013.    sprintf (filename, "ECHOR%d.TMP", config->line_offset);
  1014.    fp = mopen (filename, "w+t");
  1015.  
  1016.    if (msg_tzone != msg_fzone || config->force_intl)
  1017.       mprintf(fp,msgtxt[M_INTL], msg_tzone, msg.dest_net, msg.dest, msg_fzone, msg.orig_net, msg.orig);
  1018.    if (msg_tpoint)
  1019.       mprintf(fp,"\001TOPT %d\r\n", msg_tpoint);
  1020.    mprintf(fp,msgtxt[M_PID], VERSION, registered ? "" : NOREG);
  1021.     mprintf(fp,msgtxt[M_MSGID], config->alias[use_aka].zone, config->alias[use_aka].net, config->alias[use_aka].node, config->alias[use_aka].point, time(NULL));
  1022.  
  1023.    mprintf (fp, "Following is a summary from %d:%d/%d.%d of changes in TIC topology:\r\n\r\n", msg_fzone, msg.orig_net, msg.orig, msg_fpoint);
  1024.  
  1025.    while (packet_fgets (linea, 70, fpm) != NULL) {
  1026.       if (linea[0] == 0x01)
  1027.          continue;
  1028.  
  1029.       while (linea[strlen (linea) -1] == 0x0D || linea[strlen (linea) -1] == 0x0A)
  1030.          linea[strlen (linea) -1] = '\0';
  1031.  
  1032.       p = strtok (linea, " ");
  1033.       if (p == NULL || *p == 0x01 || !strncmp (p, "---", 3))
  1034.          continue;
  1035.  
  1036.       if (p[0] != '%' && p[0] != '#') {
  1037.          postmsg = 1;
  1038.          i = add_tic_link (p, zo, ne, no, po);
  1039.          if (i == 1) {
  1040.             if (p[0] != '-')
  1041.                mprintf (fp, "Area %s has been added.\r\n", p[0] == '+' ? strupr (&p[1]) : strupr (p));
  1042.             else
  1043.                mprintf (fp, "Area %s has been removed.\r\n", p[0] == '-' ? strupr (&p[1]) : strupr (p));
  1044.          }
  1045.          else if (i == -1)
  1046.             mprintf (fp, "Area %s not found.\r\n", (p[0] == '+' || p[0] == '-') ? strupr (&p[1]) : strupr (p));
  1047.          else if (i == -2)
  1048.             mprintf (fp, "Area %s never linked.\r\n", (p[0] == '+' || p[0] == '-') ? strupr (&p[1]) : strupr (p));
  1049.          else if (i == -3)
  1050.             mprintf (fp, "Area %s already linked.\r\n", (p[0] == '+' || p[0] == '-') ? strupr (&p[1]) : strupr (p));
  1051.          else if (i == -4)
  1052.             mprintf (fp, "Area %s not linked: level too low.\r\n", (p[0] == '+' || p[0] == '-') ? strupr (&p[1]) : strupr (p));
  1053.       }
  1054.  
  1055.       else if (!stricmp (p, "%-ALL")) {
  1056.          postmsg = 1;
  1057.          scan_all_tic (fp, 0, zo, ne, no, po);
  1058.       }
  1059.  
  1060.       else if (!stricmp (p, "%+ALL") || !stricmp (p, "%ALL")) {
  1061.          postmsg = 1;
  1062.          scan_all_tic (fp, 1, zo, ne, no, po);
  1063.       }
  1064.  
  1065.       else if (p[0] == '#') {
  1066.          postmsg = 1;
  1067.          if (level >= config->tic_change_tag) {
  1068.             o = strtok (NULL, ": ");
  1069.             if (o != NULL)
  1070.                o = strbtrim (o);
  1071.  
  1072.             p = strtok (&p[1], ": ");
  1073.             if (p != NULL)
  1074.                p = strbtrim (p);
  1075.  
  1076.             if (p != NULL && o != NULL) {
  1077.                if (change_tictag (strbtrim (p), strbtrim (o)))
  1078.                   mprintf (fp, "Area %s changed to %s.\r\n", p, o);
  1079.                else
  1080.                   mprintf (fp, "Area %s not found.\r\n", p);
  1081.             }
  1082.          }
  1083.          else
  1084.             mprintf (fp, "Remote maintenance not allowed.\r\n");
  1085.       }
  1086.  
  1087.       else if (!stricmp (p, "%FROM")) {
  1088.          postmsg = 1;
  1089.          if (level >= config->tic_remote_maint) {
  1090.             p = strtok (NULL, "");
  1091.             parse_netnode2 (p, &zo, &ne, &no, &po);
  1092.             mprintf (fp, "Remote maintenance for %d:%d/%d.%d.\r\n", zo, ne, no, po);
  1093.          }
  1094.          else
  1095.             mprintf (fp, "Remote maintenance not allowed.\r\n");
  1096.       }
  1097.  
  1098.       else if (!stricmp (p, "%PWD")) {
  1099.          postmsg = 1;
  1100.          if ((p = strtok (NULL, " ")) != NULL) {
  1101.             sprintf (filename, "%sNODES.DAT", config->net_info);
  1102.             fd = sh_open (filename, SH_DENYRW, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  1103.  
  1104.             npos = tell (fd);
  1105.             while (read (fd, (char *)&ni, sizeof (NODEINFO)) == sizeof (NODEINFO)) {
  1106.                if (zo == ni.zone && ne == ni.net && no == ni.node && po == ni.point) {
  1107.                   strcpy (ni.pw_tic, strupr (p));
  1108.                   lseek (fd, npos, SEEK_SET);
  1109.                   write (fd, (char *)&ni, sizeof (NODEINFO));
  1110.                   break;
  1111.                }
  1112.                npos = tell (fd);
  1113.             }
  1114.  
  1115.             close (fd);
  1116.  
  1117.             if (zo == ni.zone && ne == ni.net && no == ni.node && po == ni.point)
  1118.                     mprintf (fp, "Raid password %s selected.\r\n", p);
  1119.          }
  1120.       }
  1121.  
  1122.       else if (!stricmp (p, "%SESSIONPWD")) {
  1123.          postmsg = 1;
  1124.          if ((p = strtok (NULL, " ")) != NULL) {
  1125.             sprintf (filename, "%sNODES.DAT", config->net_info);
  1126.             fd = sh_open (filename, SH_DENYRW, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  1127.  
  1128.             npos = tell (fd);
  1129.             while (read (fd, (char *)&ni, sizeof (NODEINFO)) == sizeof (NODEINFO)) {
  1130.                if (zo == ni.zone && ne == ni.net && no == ni.node && po == ni.point) {
  1131.                   strcpy (ni.pw_session, strupr (p));
  1132.                   lseek (fd, npos, SEEK_SET);
  1133.                   write (fd, (char *)&ni, sizeof (NODEINFO));
  1134.                   break;
  1135.                }
  1136.                npos = tell (fd);
  1137.             }
  1138.  
  1139.             close (fd);
  1140.  
  1141.             if (zo == ni.zone && ne == ni.net && no == ni.node && po == ni.point)
  1142.                mprintf (fp, "Session password %s selected.\r\n", p);
  1143.          }
  1144.       }
  1145.    }
  1146.  
  1147.    if (doquery) {
  1148.       if (postmsg) {
  1149.          mprintf (fp, "\r\n");
  1150.          mprintf (fp, "------------------------------------------------\r\n");
  1151.       }
  1152.       generate_echomail_status (fp, zo, ne, no, po, 2);
  1153.       postmsg = 1;
  1154.    }
  1155.  
  1156.    mprintf (fp, "\r\n");
  1157.    mprintf(fp,msgtxt[M_TEAR_LINE],VERSION, registered ? "" : NOREG);
  1158.  
  1159.    mseek (fp, 0L, SEEK_SET);
  1160.    if (postmsg)
  1161.       fido_save_message2 (fp, NULL);
  1162.    mclose (fp);
  1163.  
  1164.    if (postmsg)
  1165.       forward_message (last_msg, zo, ne, no, po, config->tic_alert_nodes);
  1166.    memcpy ((char *)&msg, (char *)&tmsg, sizeof (struct _msg));
  1167.  
  1168.    sprintf (filename, "ECHOR%d.TMP", config->line_offset);
  1169.    unlink (filename);
  1170.  
  1171.    fseek (fpm, (long)sizeof (struct _msg), SEEK_SET);
  1172.  
  1173.    while (packet_fgets (linea, 70, fpm) != NULL) {
  1174.       while (linea[strlen (linea) -1] == 0x0D || linea[strlen (linea) -1] == 0x0A)
  1175.          linea[strlen (linea) -1] = '\0';
  1176.  
  1177.       if (!stricmp (linea, "%LIST")) {
  1178.          sprintf (filename, "ECHOR%d.TMP", config->line_offset);
  1179.          fp = mopen (filename, "w+t");
  1180.  
  1181.          if (msg_tzone != msg_fzone || config->force_intl)
  1182.             mprintf(fp,msgtxt[M_INTL], msg_tzone, msg.dest_net, msg.dest, msg_fzone, msg.orig_net, msg.orig);
  1183.          if (msg_tpoint)
  1184.             mprintf(fp,"\001TOPT %d\r\n", msg_tpoint);
  1185.          mprintf(fp,msgtxt[M_PID], VERSION, registered ? "" : NOREG);
  1186.             mprintf(fp,msgtxt[M_MSGID], config->alias[use_aka].zone, config->alias[use_aka].net, config->alias[use_aka].node, config->alias[use_aka].point, time(NULL));
  1187.  
  1188.          generate_tic_status (fp, zo, ne, no, po, 1);
  1189.  
  1190.          mprintf (fp, "\r\n");
  1191.          mprintf(fp,msgtxt[M_TEAR_LINE],VERSION, registered ? "" : NOREG);
  1192.  
  1193.          mseek (fp, 0L, SEEK_SET);
  1194.          fido_save_message2 (fp, NULL);
  1195.          mclose (fp);
  1196.       }
  1197.       else if (!stricmp (linea, "%QUERY")) {
  1198.          sprintf (filename, "ECHOR%d.TMP", config->line_offset);
  1199.          fp = mopen (filename, "w+t");
  1200.  
  1201.          if (msg_tzone != msg_fzone || config->force_intl)
  1202.             mprintf(fp,msgtxt[M_INTL], msg_tzone, msg.dest_net, msg.dest, msg_fzone, msg.orig_net, msg.orig);
  1203.          if (msg_tpoint)
  1204.             mprintf(fp,"\001TOPT %d\r\n", msg_tpoint);
  1205.          mprintf(fp,msgtxt[M_PID], VERSION, registered ? "" : NOREG);
  1206.             mprintf(fp,msgtxt[M_MSGID], config->alias[use_aka].zone, config->alias[use_aka].net, config->alias[use_aka].node, config->alias[use_aka].point, time(NULL));
  1207.  
  1208.          generate_tic_status (fp, zo, ne, no, po, 2);
  1209.  
  1210.          mprintf (fp, "\r\n");
  1211.          mprintf(fp,msgtxt[M_TEAR_LINE],VERSION, registered ? "" : NOREG);
  1212.  
  1213.          mseek (fp, 0L, SEEK_SET);
  1214.          fido_save_message2 (fp, NULL);
  1215.          mclose (fp);
  1216.       }
  1217.       else if (!stricmp (linea, "%UNLINKED")) {
  1218.          sprintf (filename, "ECHOR%d.TMP", config->line_offset);
  1219.          fp = mopen (filename, "w+t");
  1220.  
  1221.          if (msg_tzone != msg_fzone || config->force_intl)
  1222.             mprintf(fp,msgtxt[M_INTL], msg_tzone, msg.dest_net, msg.dest, msg_fzone, msg.orig_net, msg.orig);
  1223.          if (msg_tpoint)
  1224.             mprintf(fp,"\001TOPT %d\r\n", msg_tpoint);
  1225.          mprintf(fp,msgtxt[M_PID], VERSION, registered ? "" : NOREG);
  1226.             mprintf(fp,msgtxt[M_MSGID], config->alias[use_aka].zone, config->alias[use_aka].net, config->alias[use_aka].node, config->alias[use_aka].point, time(NULL));
  1227.  
  1228.          generate_tic_status (fp, zo, ne, no, po, 3);
  1229.  
  1230.          mprintf (fp, "\r\n");
  1231.          mprintf(fp,msgtxt[M_TEAR_LINE],VERSION, registered ? "" : NOREG);
  1232.  
  1233.          mseek (fp, 0L, SEEK_SET);
  1234.          fido_save_message2 (fp, NULL);
  1235.          mclose (fp);
  1236.       }
  1237.       else if (!stricmp (linea, "%HELP")) {
  1238.          sprintf (filename, "ECHOR%d.TMP", config->line_offset);
  1239.          fp = mopen (filename, "w+t");
  1240.  
  1241.          if (msg_tzone != msg_fzone || config->force_intl)
  1242.             mprintf(fp,msgtxt[M_INTL], msg_tzone, msg.dest_net, msg.dest, msg_fzone, msg.orig_net, msg.orig);
  1243.          if (msg_tpoint)
  1244.             mprintf(fp,"\001TOPT %d\r\n", msg_tpoint);
  1245.          mprintf(fp,msgtxt[M_PID], VERSION, registered ? "" : NOREG);
  1246.             mprintf(fp,msgtxt[M_MSGID], config->alias[use_aka].zone, config->alias[use_aka].net, config->alias[use_aka].node, config->alias[use_aka].point, time(NULL));
  1247.  
  1248.          fph = fopen (config->tic_help, "rb");
  1249.          if (fph == NULL)
  1250.             mprintf (fp, "\r\n   No help file provided by Sysop.\r\n");
  1251.          else {
  1252.             while (fgets (filename, 70, fph) != NULL) {
  1253.                filename[70] = '\0';
  1254.                mputs (filename, fp);
  1255.             }
  1256.             fclose (fph);
  1257.          }
  1258.  
  1259.          mprintf (fp, "\r\n");
  1260.          mprintf(fp,msgtxt[M_TEAR_LINE],VERSION, registered ? "" : NOREG);
  1261.  
  1262.          mseek (fp, 0L, SEEK_SET);
  1263.          fido_save_message2 (fp, NULL);
  1264.          mclose (fp);
  1265.       }
  1266.    }
  1267.  
  1268.    sprintf (filename, "ECHOR%d.TMP", config->line_offset);
  1269.    unlink (filename);
  1270. }
  1271.  
  1272.