home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / ECO30603.ZIP / ECO30603.LZH / ECOLIBNG / SOURCE / ECO_BBS.DAT next >
Encoding:
Text File  |  1992-09-26  |  63.7 KB  |  1,888 lines

  1.  
  2. !short ASYNC UNIT
  3.  
  4.   This unit interfaces directly with the UART 8250, 16540 or 16550.
  5.   Therefore it is highly platform dependent.
  6.   It has been written so, that it might be emulated easily on
  7.   other platforms. Do use the same functions and parameters, and
  8.   dependents from this unit continue to function normally.
  9.  
  10.  
  11. !short   contants used
  12. const { 8086/8088 hardware flags }
  13.   ff   =  12; { form feed       }   cr   =  13; { carriage return }
  14.   dle  =  16; { data link esc.  }   xon  =  17; { xon             }
  15.   xoff =  19; { xoff            }   sub  =  26; { end of file     }
  16.   esc  =  27; { escape          }   del  = 127; { delete          }
  17.   fk_cr          :       char =  '|'; { function key definition cr        }
  18.   fk_delay       :       char =  '~'; { function key def. 1 second wait   }
  19.   fk_wait_for    :       char =  '`'; { function key wait for next char   }
  20.   fk_ctrl_mark   :       char =  '^'; { marks next char as ctrl character }
  21.   fk_script_ch   :       char =  '@'; { script to execute follows         }
  22.   fk_delay_time  :    integer =   10; { delay to insert between each char }
  23.   bs_string      :     string =   ^h; { string to send when back space hit}
  24.   ctrl_bs_string :     string = #127; { string to send when ctrl bs hit   }
  25.  
  26.   half_second_delay       =  500;    one_second_delay        = 1000;
  27.   two_second_delay        = 2000;    three_second_delay      = 3000;
  28.   tenth_of_a_second_delay =  100;    on   = true; off  = false;
  29.  
  30.   data_bits     : 5..8 = 8;          parity        : char = 'N';
  31.   stop_bits     : 0..2 = 1;          comm_port     : 1..4 = 1;
  32.   baud_rate     : 110..38400 = 2400; cmd_line_port : 0..4 = 0;
  33.  
  34.   n_baud_rates = 11;
  35.   baud_rates: array[ 1 .. n_baud_rates ] of word = (
  36.     110, 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600
  37.   );
  38.  
  39.   modem_init          : string   = 'ATZ|~ATX1|';
  40.   modem_dial          : string[30] = 'ATDT';
  41.   modem_dial_end      : string[30] = '|';
  42.   modem_busy          : string[30] = 'BUSY';
  43.   modem_connect       : string[30] = 'CONNECT';
  44.   modem_no_carrier    : string[30] = 'NO CARRIER';
  45.   modem_escape        : string[30] = '+++';
  46.   modem_escape_time   : integer  = 1500;
  47.   modem_hang_up       : string[30] = 'ATH0|';
  48.   modem_time_out      : longint  = 60;
  49.   modem_redial_delay  : longint  = 45;
  50.   modem_answer        : string[30] = 'ATA|';
  51.   modem_host_set      : string   = 'ATZ|~ATX1|~ATS0=1|';
  52.   modem_host_unset    : string   = 'ATZ|~ATX1|~ATS0=0|';
  53.   modem_command_delay : integer  = 10;
  54.   modem_carrier_high  : boolean  = false;
  55.   modem_ring          : string[30] = 'RING';
  56.   host_auto_baud      : boolean  = true;
  57.   modem_hold_line     : boolean  = false;
  58.  
  59.   {               communications hardware addresses                   }
  60.   {     these are specific to IBM PCs and Close compatibles.          }
  61.   uart_thr = $00;       { offset from base of uart registers for ibm pc }
  62.   uart_rbr = $00; uart_ier = $01; uart_iir = $02; uart_lcr = $03;
  63.   uart_mcr = $04; uart_lsr = $05; uart_msr = $06;
  64.  
  65.   i8088_imr = $21;      { port address of the interrupt mask register }
  66.  
  67.   com1_base = $03f8;    { port addresses for the uart }
  68.   com2_base = $02f8; com3_base = $03e8; com4_base = $02e8;
  69.   com1_irq = 4;         { interrupt line for the uart }
  70.   com2_irq = 3; com3_irq = 4; com4_irq = 3;
  71.   com1_int = $0c;       { interrupt number for the uart }
  72.   com2_int = $0b; com3_int = $0c; com4_int = $0b;
  73.  
  74.   rs232_base = $0400    { address of rs 232 com port pointer };
  75.   maxcomports = 4       { four ports allowed by this code    };
  76.                                   { port addresses of each com port }
  77.   default_com_base : array[1..maxcomports] of word =
  78.     ( com1_base, com2_base, com3_base, com4_base );
  79.                                   { irq line for each port }
  80.   default_com_irq  : array[1..maxcomports] of integer =
  81.     ( com1_irq, com2_irq, com3_irq, com4_irq );
  82.                                   { interrupt for each port }
  83.   default_com_int  : array[1..maxcomports] of integer =
  84.     ( com1_int, com2_int, com3_int, com4_int );
  85.  
  86.   {──────────────────────────────────────────────────────────────────────────}
  87.   {                                                                          }
  88.   {                    communications buffer variables                       }
  89.   {                                                                          }
  90.   {      the communications buffers are implemented as circular (ring)       }
  91.   {      buffers, or double-ended queues.  the asynchronous i/o routines     }
  92.   {      enter characters in the receive buffer as they arrive at the        }
  93.   {      serial port.  higher-level routines may extract characters from     }
  94.   {      the receive buffer at leisure.  higher-level routines insert        }
  95.   {      characters into the send buffer.  the asynchronous i/o routines     }
  96.   {      then send characters out the serial port when possible.             }
  97.   {                                                                          }
  98.   {──────────────────────────────────────────────────────────────────────────}
  99.  
  100.   timeout             = 256;          { timeout value                        }
  101.   async_xon           =  ^Q;          { xon character                        }
  102.   async_xoff          =  ^S;          { xoff character                       }
  103.   async_overrun_error =   2;          {   overrun                            }
  104.   async_parity_error  =   4;          {   parity error                       }
  105.   async_framing_error =   8;          {   framing error                      }
  106.   async_break_found   =  16;          {   break interrupt                    }
  107.   async_cts           = $10;          {   clear to send                      }
  108.   async_rts           = $20;          {   request to send                    }
  109.   async_dsr           = $20;          {   data set ready                     }
  110.   async_dtr           = $10;          {   data terminal ready                }
  111.   async_rtsdtr        = $30;          {   rts + dtr                          }
  112.  
  113.  
  114. type                                  { i/o buffer type for serial port      }
  115.   async_buffer_type = array[0..1] of char;
  116.   async_ptr         = ^async_buffer_type;
  117.  
  118. var                                   { port addresses for serial ports      }
  119.   com_base               : array[1..maxcomports] of word;
  120.                                       { irq line for each serial port        }
  121.   com_irq                : array[1..maxcomports] of integer;
  122.                                       { interrupt for each serial port       }
  123.   com_int                : array[1..maxcomports] of integer;
  124.   async_buffer_ptr       : async_ptr; { input buffer address                 }
  125.   async_obuffer_ptr      : async_ptr; { output buffer address                }
  126.   async_open_flag        :   boolean; { true if port opened                  }
  127.   async_port             :   integer; { current open port number (1 ── 4)    }
  128.   async_base             :   integer; { base for current open port           }
  129.   async_irq              :   integer; { irq for current open port            }
  130.   async_int              :   integer; { interrupt # for current port         }
  131.   async_rs232            :   integer; { rs232 address for current port       }
  132.   async_buffer_overflow  :   boolean; { true if buffer overflow's happened   }
  133.   async_buffer_used      :   integer; { amount of input buffer used so far   }
  134.   async_maxbufferused    :   integer; { maximum amount of input buffer used  }
  135.                                       { async_buffer empty if head = tail    }
  136.   async_buffer_head      :   integer; { loc in async_buf to put next char    }
  137.   async_buffer_tail      :   integer; { loc in async_buf to get next char    }
  138.   async_buffer_newtail   :   integer; { for updating tail value              }
  139.   async_obuffer_overflow :   boolean; { true if buffer overflow's happened   }
  140.   async_obuffer_used     :   integer; { amount of output buffer used         }
  141.   async_maxobufferused   :   integer; { max amount of output buffer used     }
  142.                                       { async_buffer empty if head = tail    }
  143.   async_obuffer_head     :   integer; { loc in async_buf to put next char    }
  144.   async_obuffer_tail     :   integer; { loc in async_buf to get next char    }
  145.   async_obuffer_newtail  :   integer; { for updating tail value              }
  146.   async_buffer_low       :   integer; { low point in receive buffer for xon  }
  147.   async_buffer_high      :   integer; { high point in rec'buffer for xoff    }
  148.   async_buffer_high_2    :   integer; { emergency point for xoff             }
  149.   async_xoff_sent        :   boolean; { if xoff sent                         }
  150.   async_sender_on        :   boolean; { if sender is enabled                 }
  151.   async_send_xoff        :   boolean; { true to send xoff asap               }
  152.   async_xoff_received    :   boolean; { if xoff received                     }
  153.   async_xoff_rec_display :   boolean; { if xoff received and displayed       }
  154.   async_xon_rec_display  :   boolean; { if xon received                      }
  155.   async_baud_rate        :      word; { current baud rate                    }
  156.                                       { save prev serial interrupt status    }
  157.   async_save_iaddr       :   pointer;
  158.   async_do_cts           :   boolean; { true to do clear-to-send checking    }
  159.   async_do_dsr           :   boolean; { true to do data-set-ready checking   }
  160.   async_do_xonxoff       :   boolean; { true to do xon/xoff flow checking    }
  161.   async_ov_xonxoff       :   boolean; { true to do xon/xoff if buf overflow  }
  162.   async_hard_wired_on    :   boolean; { true if hard-wired connection        }
  163.   async_break_length     :   integer; { length of break in 1/10 seconds      }
  164.   async_line_status      :      byte; { line status reg at interrupt         }
  165.   async_modem_status     :      byte; { modem status reg at interrupt        }
  166.   async_line_error_flags :      byte; { line status bits accumulated         }
  167.   async_buffer_size      :   integer; { stores input buffer size             }
  168.   async_obuffer_size     :   integer; { stores output buffer size            }
  169.   async_uart_ier         :   integer; { interrupt enable register address    }
  170.   async_uart_mcr         :   integer; { interrupt enable register address    }
  171.   async_uart_iir         :   integer; { interrupt id register address        }
  172.   async_uart_msr         :   integer; { modem status register address        }
  173.   async_uart_lsr         :   integer; { line status register address         }
  174.   async_output_delay     :   integer; { delay in ms when output buffer full  }
  175.   async_onemsdelay       :   integer; { loop count value to effect 1 ms delay}
  176.   async_buffer_length    :   integer; { receive buffer length                }
  177.   async_obuffer_length   :   integer; { send buffer length                   }
  178.                                       { pointer to async_send routine        }
  179.   async_send_addr        : async_ptr;
  180.   break_length           :   integer;
  181.   current_carrier_status,
  182.   new_carrier_status,
  183.   attended_mode,
  184.   hard_wired,
  185.   reset_comm_port,
  186.   comm_port_changed,
  187.   check_cts,check_dsr,
  188.   do_xon_xoff_checks     :   boolean;
  189.  
  190.  
  191.  
  192.   {──────────────────────────────────────────────────────────────────────}
  193.   {                       multitasker definitions                        }
  194.   {──────────────────────────────────────────────────────────────────────}
  195.  
  196. type
  197.   multitaskertype = (
  198.     multitasker_none, doubledos, desqview, topview,
  199.     mswindows, apxcore, ezdosit, concurrent_dos,
  200.     taskview, multilink, other
  201.   );
  202.  
  203.  
  204. var
  205.   timesharingactive: boolean;    { true if multitasker active        }
  206.                                  { which multitasker active          }
  207.   multitasker: multitaskertype;
  208.  
  209.  
  210.   {──────────────────────────────────────────────────────────────────────}
  211.   {              dos jump stuff                                          }
  212.   {──────────────────────────────────────────────────────────────────────}
  213. {var}const
  214.   heaptop           : pointer = nil   { top of heap at program start       };
  215.   stacksafetymargin : word    = 1000  { safety margin for stack            };
  216.   minspacefordos    : word    = 20000 { minimum bytes for dos shell to run };
  217.  
  218.  
  219. !short   procedures used
  220.   procedure bios_rs232_init(comport: integer; comparm: word);
  221.   procedure async_close(drop_dtr: boolean);
  222.   procedure async_clear_errors;
  223.   procedure async_reset_port(
  224.     comport  : integer;
  225.     baudrate : word;
  226.     parity   : char;
  227.     wordsize : integer;
  228.     stopbits : integer
  229.   );
  230.   function  async_open(
  231.     comport  : integer;
  232.     baudrate : word;
  233.     parity   : char;
  234.     wordsize : integer;
  235.     stopbits : integer
  236.   ): boolean;
  237.   procedure async_send(c: char);
  238.   function async_receive(var c: char): boolean;
  239.   procedure async_receive_with_timeout(secs: integer; var c: integer);
  240.   procedure async_stuff(ch: char);
  241.   procedure async_find_delay(var one_ms_delay: integer);
  242.   procedure async_init(
  243.     async_buffer_max : integer;
  244.     async_obuffer_max: integer;
  245.     async_high_lev1  : integer;
  246.     async_high_lev2  : integer;
  247.     async_low_lev    : integer
  248.   );
  249.   function  async_carrier_detect: boolean;
  250.   function  async_carrier_drop: boolean;
  251.   procedure async_term_ready(ready_status: boolean);
  252.   function  async_buffer_check: boolean;
  253.   function  async_line_error(var error_flags: byte): boolean;
  254.   function  async_ring_detect: boolean;
  255.   procedure async_send_break;
  256.   procedure async_send_string(s: string);
  257.   procedure async_send_string_with_delays(
  258.     s          : string;
  259.     char_delay : integer;
  260.     eos_delay  : integer
  261.   );
  262.   function  async_percentage_used: real;
  263.   procedure async_purge_buffer;
  264.   function  async_peek(nchars: integer): char;
  265.   procedure async_setup_port(
  266.     comport      : integer;
  267.     base_address : integer;
  268.     irq_line     : integer;
  269.     int_numb     : integer
  270.   );
  271.   procedure async_release_buffers;
  272.   procedure async_flush_output_buffer;
  273.   procedure async_drain_output_buffer(max_wait_time: integer);
  274.   function  async_port_address_given(com_port: integer): boolean;
  275.   procedure async_send_now(c: char);
  276.   function  async_wait_for_quiet(
  277.     max_wait: longint; wait_time: longint
  278.   ): boolean;
  279.   { --- }
  280.   procedure send_modem_command(modem_text: string);
  281.   function  set_params(first_time: boolean): boolean;
  282.   procedure initialize_modem;
  283.  
  284.  
  285. !short FIDO UNIT
  286.  
  287.   This unit defines some functions to work with standard
  288.   IFNA/FIDO packages.
  289.   For example, the name of a mailbag has to be named using
  290.   certain codes, depicting the senders nodenumber.
  291.  
  292.  
  293. !short   contants used
  294.  
  295. type
  296.   netmsg = record        { netmessage record structure }
  297.     from,
  298.     too        : string[35];
  299.     subject    : string[71];
  300.     date       : string[19];
  301.     timesread,
  302.     destnode,
  303.     orignode,
  304.     cost,
  305.     orignet,
  306.     destnet,
  307.     replyto,
  308.     attr,
  309.     nextreply  : word;
  310.     areaname   : string[20];
  311.   end;
  312.  
  313.   pktheader = record        { packet header of packet }
  314.     orignode,
  315.     destnode,
  316.     year,
  317.     month,
  318.     day,
  319.     hour,
  320.     minute,
  321.     second,
  322.     baud,
  323.     orignet,
  324.     destnet     : word;
  325.   end;
  326.  
  327.   pktmessage = record        { packet header of each individual message }
  328.     orignode,
  329.     destnode,
  330.     orignet,
  331.     destnet,
  332.     attr,
  333.     cost        : word;
  334.     date        : string[19];
  335.     too         : string[35];
  336.     from        : string[35];
  337.     subject     : string[71];
  338.     areaname    : string[20];
  339.   end;
  340.  
  341.   archivename = record        { internal record structure used for     }
  342.     mynet,       { determining the name of of an echomail }
  343.     mynode,      { archive. i.e. 00fa1fd3.mo1             }
  344.     hisnet,
  345.     hisnode     : word;
  346.   end;
  347.  
  348.  
  349. const                        { attribute flags }
  350.   _private  = $0001;
  351.   _crash    = $0002;
  352.   _recvd    = $0004;
  353.   _sent     = $0008;
  354.   _file     = $0010;
  355.   _forward  = $0020;     { also know as in-transit }
  356.   _orphan   = $0040;
  357.   _killsent = $0080;
  358.   _local    = $0100;
  359.   _hold     = $0200;
  360.   _freq     = $0800;
  361.  
  362.   months    : array[1..12] of string[3] = (
  363.     'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'
  364.   );
  365.  
  366.  
  367. var
  368.   net    :      netmsg;
  369.   ph     :   pktheader;
  370.   pm     :  pktmessage;
  371.   arcn   : archivename;
  372.  
  373. !short   procedures used
  374.  
  375.   function  packetname_                      :  string;
  376.   function  packetmessage_                   :  string;
  377.   function  packetheader_                    :  string;
  378.   function  netmessage_                      :  string;
  379.   function  getpath_(var fname : string)     : boolean;
  380.   function  getnet_(gn : string)             :  string;
  381.   function  getnode_(gn : string)            :  string;
  382.   function  msgdatestamp_                    :  string;
  383.   function  lastmsgnum_( _netpath : string ) : integer;
  384.   function  hex_ (n : word)                  :  string;
  385.   function  archivename_                     :  string;
  386.   procedure expandnodenumbers_(var list : string; var totalnumber : integer );
  387.   procedure convertnetnode_(netnode : string; var net, node : word);
  388.  
  389.  
  390. !short FOSL UNIT
  391.  
  392.   This unit interfaces with the FOSSIL
  393.   (Fido Opus Seadog Standard Interface Layer) and
  394.   is therefore quite platform dependent.
  395.   However, since the DOS / OS/2(VDM) platform are
  396.   the only OS platforms to support FOSSIL, this is
  397.   a obsolete hinder in multiplatform development.
  398.  
  399. !short   procedures used
  400.  
  401.   procedure fos_ansi_       (character : char);
  402.   function  fos_atcmd_      (comport_  : byte;  command_: string): boolean;
  403.   function  fos_avail_      (comport_  : byte): boolean;
  404.   procedure fos_bios_       (character : char);
  405.   function  fos_cd_         (comport_  : byte): boolean;
  406.   function  fos_checkmodem_ (comport_  : byte): boolean;
  407.   procedure fos_clear_regs_;
  408.   procedure fos_close_      (comport_  : byte);
  409.   procedure fos_dtr_        (comport_  : byte;  state: boolean);
  410.   function  fos_empty_      (comport_  : byte): boolean;
  411.   procedure fos_flow_       (comport_  : byte;  state: boolean);
  412.   procedure fos_flush_      (comport_  : byte);
  413.   function  fos_hangup_     (comport_  : byte): boolean;
  414.   function  fos_init_       (comport_  : byte): boolean;
  415.   procedure fos_kill_out_   (comport_  : byte);
  416.   procedure fos_kill_in_    (comport_  : byte);
  417.   function  fos_oktosend_   (comport_  : byte): boolean;
  418.   procedure fos_parms_      (comport_  : byte;  baud: integer; databits: byte;
  419.                                                 parity: char;   stopbit: byte);
  420.   function  fos_present_    (comport_  : byte): boolean;
  421.   procedure fos_reboot_;
  422.   function  fos_receive_    (comport_  : byte): char;
  423.   procedure fos_string_     (comport_  : byte;  outstring: string);
  424.   procedure fos_stringcrlf_ (comport_  : byte;  outstring: string);
  425.   procedure fos_watchdog_   (comport_  : byte;  state: boolean);
  426.   procedure fos_write_      (comport_  : byte;  character: char);
  427.   function  fos_name_(comport: byte) : string;
  428.  
  429.  
  430.  
  431. !short HDSN UNIT
  432.  
  433.    This unit interfaces with a Hudson MSG*.BBS messagebase,
  434.    including inspecting, reading, writing and updating to
  435.    and from the 5-file database.
  436.  
  437.  
  438. !short   constants used
  439.  
  440. {$I rastruct.inc}
  441.  
  442.  
  443. type
  444.   msgattrs = set of (
  445.     m_del, m_transit, m_netm, m_priv, m_rcvd, m_echotr, m_local, m_r1
  446.   );
  447.   netattrs = set of (
  448.     n_kill, n_sent, n_file, n_crash, n_reqrec, n_audreq, n_retrec, n_r2
  449.   );
  450.   namestring = string[35];
  451.   subjstring = string[72];
  452.  
  453.  
  454. type
  455.   lastcall = record
  456.     line   :            byte;
  457.     name   :  msgtoidxrecord;
  458.     city   :      string[25];
  459.     baud   :            word;
  460.     times  :         longint;
  461.     logon  :       string[5];
  462.     logoff :       string[5];
  463.   end;
  464.  
  465.  
  466.   msgboardsarray = array[1..200] of messagerecord;
  467.   msgboardsarrayptr = ^msgboardsarray;
  468.  
  469.  
  470.  
  471.  
  472. const
  473.   boardlim = 200;       {maximum number of boards}
  474.   ok = 0;               {ioresult value}
  475.  
  476.   defaultmsgattr: array[msgtype] of msgattrs=(          {may be modified}
  477.         [m_transit, m_netm],     {netmail}
  478.         [m_echotr],             {echomail}
  479.         [m_local]);             {local mail}
  480.   defaultnetattr: array[msgtype] of netattrs=(
  481.         [],                     {netmail}
  482.         [],                     {echomail}
  483.         []);                    {local mail}
  484.  
  485.  
  486. !short   procedures used
  487.  
  488.   {- set the location of the *.bbs files, default is current directory -}
  489.   procedure setbbspath(path: pathstr);
  490.  
  491.   {- set the location of the users*.bbs files, default is current directory -}
  492.   procedure setuserspath(path: pathstr);
  493.  
  494.   {- set the user related files support -}
  495.   procedure setusersupport(name: namestring;  lastread, current: boolean);
  496.  
  497.   {-
  498.     open all the files associated with the quickbbs message base.
  499.     this function looks for the files in the bbspath directory and 
  500.     returns 0 iff everything went ok.
  501.   -}
  502.  
  503.   function openmsgbase: integer;
  504.   function flushmsgbase: integer;
  505.   function closemsgbase: integer;
  506.  
  507.   {- create a header for a new message -}
  508.   procedure createnewheader(var hdr: msghdrrecord;  whofrom, whoto: namestring;
  509.                             subj: subjstring;  brd: byte;  typ: msgtype);
  510.  
  511.   {- update a header before calling writemessage after changing a message -}
  512.   procedure changeheader(var hdr: msghdrrecord);
  513.  
  514.   {- create a new message or modify an old message -}
  515.   function writemessage(var hdr: msghdrrecord;  var t: textbuffer): integer;
  516.  
  517.   {- read a message -}
  518.   function readmessage(msgno: integer; var hdr: msghdrrecord;  var t: textbuffer): integer;
  519.  
  520.   {- get information about messages from index files -}
  521.   function firstmsg(brd: byte): integer;
  522.   function lastmsg(brd: byte): integer;
  523.   function countmsg(brd: byte): integer;
  524.   function lastreadmsg(brd: byte): integer;
  525.   function curmsg(brd: byte): integer;
  526.   function boardmsg(brd: byte;  cur: integer): integer;
  527.  
  528.   {- set message pointers -}
  529.   procedure setlastread(brd: byte;  msgno: integer);
  530.   procedure setcur(brd: byte;  msgno: integer);
  531.  
  532.   {- get next/previous message, returns 0 if empty, -1 if not found -}
  533.   function msgnext(brd: byte;  cur: integer): integer;
  534.   function msgprev(brd: byte;  cur: integer): integer;
  535.  
  536.   {- return true iff there is a message at 'msgno' in board 'brd' -}
  537.   function msgat(brd: byte;  msgno: integer): boolean;
  538.  
  539.   {- read and write a message header, return 0 iff ok -}
  540.   function readheader(msgno: integer;  var hdr: msghdrrecord): integer;
  541.   function writeheader(var hdr: msghdrrecord): integer;
  542.  
  543.   {- read message text, return 0 iff ok.  return empty buffer on error. -}
  544.   function readtext(var hdr: msghdrrecord; var t: textbuffer): integer;
  545.  
  546.   {- search for a message to a person -}
  547.   function searchto(
  548.     board: byte; var msgnum: integer; name: namestring
  549.   ): integer;
  550.  
  551.   {- delete a message -}
  552.   function msgdelete(msgnum: integer): integer;
  553.  
  554.  
  555.  
  556. !short SQSH UNIT
  557.  
  558.    This unit interfaces with a Squish messagebase,
  559.    including inspecting, reading, writing and updating to
  560.    and from the N*3-file databases. Every Squish-area
  561.    is provided with its own set of 3 files, 2 index and
  562.    1 text-base files.
  563.  
  564.  
  565. !short   constants used
  566.  
  567. type
  568.   _fido_fromtype = string[35];
  569.   _fido_totype   = string[35];
  570.   _fido_subtype  = string[71];
  571.   _fido_datetype = string[19];
  572.  
  573.  
  574.   _fidomsgtype = record
  575.     from         : _fido_fromtype; (* 0 *)
  576.     towhom       : _fido_totype;   (* 35 *)
  577.     subject      : _fido_subtype;  (* 71 *)
  578.     azdate       : _fido_datetype; (* 142 obsolete/unused ascii date information        *)
  579.     timesread    : word;           (* 162 fido<tm>: number of times read                *)
  580.     dest_node    : word;           (* 164 destination node                              *)
  581.     orig_node    : word;           (* 166 origination node number                       *)
  582.     cost         : word;           (* 168 unit cost charged to send the message         *)
  583.     orig_net     : word;           (* 170 origination network number                    *)
  584.     dest_net     : word;           (* 172 destination network number                    *)
  585.  
  586.     date_written : longint;        (* 176 when user wrote the msg              *)
  587.     date_arrived : longint;        (* 180 when msg arrived on-line             *)
  588.     reply        : word;           (* 184 current msg is a reply to this msg number     *)
  589.     attr         : word;           (* 186 attribute (behavior) of the message           *)
  590.     up           : word;           (* 188 Next message in the thread              *)
  591.   end;
  592.  
  593.  
  594.  
  595.  
  596. const
  597.   msgprivate  = $0001; (* for addressee *only*    * 0000 0000 0000 0001 *)
  598.   msgcrash    = $0002; (* high priority           * 0000 0000 0000 0010 *)
  599.   msgread     = $0004; (* was read by addressee   * 0000 0000 0000 0100 *)
  600.   msgsent     = $0008; (* was sent by fidomail      0000 0000 0000 1000 *)
  601.   msgfile     = $0010; (* subj=file(s) to send    * 0000 0000 0001 0000 *)
  602.   msgfwd      = $0020; (* msg from & to elsewhere   0000 0000 0010 0000 *)
  603.   msgorphan   = $0040; (* msg destination unknown   0000 0000 0100 0000 *)
  604.   msgkill     = $0080; (* delete after sending    * 0000 0000 1000 0000 *)
  605.   msglocal    = $0100; (* msg is local, not net     0000 0001 0000 0000 *)
  606.   msghold     = $0200; (* hold msg for pickup     * 0000 0010 0000 0000 *)
  607.   msgcrap     = $0400; (* ---------------------- x  0000 0100 0000 0000 *)
  608.   msgfrq      = $0800; (* subj=file(s) to get     * 0000 1000 0000 0000 *)
  609.   msgrrq      = $1000; (* msg receipt requested  x* 0001 0000 0000 0000 *)
  610.   msgcpt      = $2000; (* msg is a msg receipt   x* 0010 0000 0000 0000 *)
  611.   msgarq      = $4000; (* audit trail requested  x* 0100 0000 0000 0000 *)
  612.   msgurq      = $8000; (* subj=files(s) to upd   x* 1000 0000 0000 0000 *)
  613.                                                  (*------------------------*)
  614.                                                  (* ^^                     *)
  615.                                                  (* ||                     *)
  616.                                                  (* ||* = preserved by     *)
  617.                                                  (* ||    the network      *)
  618.                                                  (* ||? = stripped by the  *)
  619.                                                  (* |     net (ftsc spec)  *)
  620.                                                  (* |     but preserved    *)
  621.                                                  (* |     by seadog<tm>    *)
  622.                                                  (* |x  = not used by opus *)
  623.                                                  (*------------------------*)
  624.  
  625.  
  626. const
  627.   sysmail      = $0001; (* is a mail area                                *)
  628.   p_rep        = $0002; (* opus: net mail private echomail back          *)
  629.   nopublic     = $0004; (* opus: disallow public messages                *)
  630.   noprivate    = $0008; (* opus: disallow private messages               *)
  631.   anon_ok      = $0010; (* opus: enable anonymous messages               *)
  632.   echomail     = $0020; (* opus: set=echomail clear=not echomail         *)
  633.   opus_ualias  = $0040; (* opus170: use user's alias in this area        *)
  634.   highbit      = $0040; (* max:  allow high-bit chars in this area       *)
  635.   passthrough  = $0080; (* opus170: passthough area only                 *)
  636.   inbound      = $0100; (* opus170: inbound only area                    *)
  637.   nrealname    = $0200; (* max:  don't use ^aREALNAME for this area      *)
  638.   userealname  = $0400; (* max:  use usr.name instead of alias           *)
  639.   conf         = $0800; (* max:  conference-type area (no origin/sb's)   *)
  640.   max_ualias   = $1000; (* max:  use usr.alias instead of usr.name       *)
  641.  
  642.  
  643.  
  644. type
  645.   umsgid_type     = longint;
  646.   recpos_type     = longint;
  647.   _address        = record zone,net,node,point : word end;
  648.   msgbuftype      = array[0..0] of char;
  649.   msgbufptrtype   = ^msgbuftype;
  650.  
  651.  
  652. const
  653.   sqhdrid         = $afae4453;  (* squish headers must have this number *)
  654.   linknext        = 0;
  655.   linkprev        = 1;
  656.   nullframe       = 0;
  657.   frame_msg       = 0;          (* it's a live message *)
  658.   frame_free      = 1;          (* the message is dead, avail for new msg *)
  659.   frame_rle       = 2;          (* type of compression, not implemented *)
  660.   frame_lzw       = 3;          (* type of compression, not implemented *)
  661.   sqmsg_from_size = 36;
  662.   sqmsg_to_size   = 36;
  663.   sqmsg_subj_size = 72;
  664.   max_reply       = 10;         (* max number of stored replies to one msg  *)
  665.  
  666. (* this is the first record in the *.sqd file *)
  667.  
  668. type
  669.   _sqbasetype = record
  670.     len     : word;           (* length of this structure!   0   2 *)
  671.     rsvd1   : word;           (* reserved word   2   4 *)
  672.     num_msg,                  (* number of msgs   4   8 *)
  673.     high_msg,                 (* highest msg -  always equal to num_msg   8  12 *)
  674.     skip_msg: longint;        (* # of msgs to keep in beginning of area  12  16 *)
  675.     high_water : umsgid_type; (* high water marker (umsgid)  16  20 *)
  676.     uid        : umsgid_type; (* last usmgid  20  24 *)
  677.     base       : string[79];  (* base name for squishfile  24 104 *)
  678.     begin_frame,              (* offset of first frame in file 104 108 *)
  679.     last_frame,               (* offset to last frame in file 108 112 *)
  680.     first_free,               (* offset of first free frame in file 112 116 *)
  681.     last_free,                (* ofs of the last free frame 116 120 *)
  682.     end_frame  : recpos_type; (* pointer to end of file 120 124 *)
  683.     max_msg    : longint;     (* maximum number of messages 124 128 *)
  684.     keep_days  : word;        (* max age of messages 128 130 *)
  685.     sz_sqhdr   : word;        (* size of fram header 130 132 *)
  686.     rsvd2      : array[1..124] of byte       (* reserved area 132 256 *)
  687.    end;
  688.  
  689.  
  690. (*
  691.  After thge BASE record, follows a frame record for EACH message. The
  692.  begin_frame in the base should point to the first frame header, and
  693.  the next_frame in the frame header should point to the next one, etc.
  694. *)
  695.  
  696.   _sqfhdrtype = record
  697.     id          : longint;        (* sqhdr.id must always equal sqhdrid *)
  698.     next_frame,                   (* pointer to next msg in base *)
  699.     prev_frame  : recpos_type;    (* pointer to prior msg in base *)
  700.     frame_length,                 (* length of this frame (not counting header) *)
  701.     msg_length,                   (* length of msg in frame. may be less than
  702.                                      frame_length if this frame has been recycled. *)
  703.     clen        : longint;        (* length of the control information. *)
  704.     frame_type  : word;           (* Either FRAME_MESSAGE or FRAME_FREE. The API
  705.                                      has been designed to allow things such
  706.                                      as FRAME_LZSS or FRAME_LZH to be hacked on
  707.                                      later, without changing the application. *)
  708.     rsvd        : word;           (* reserved *)
  709.   end;
  710.  
  711.  
  712. (*
  713.  
  714. But right after each frame header, follows the squish message header,
  715. then the control info, then the text.
  716.  
  717. *)
  718.  
  719.   _sqmhdrtype = record
  720.       attr      : longint;
  721.       fromwhom  : string[sqmsg_from_size-1];
  722.       towhom    : string[sqmsg_to_size-1];
  723.       subj      : string[sqmsg_subj_size-1];
  724.       orig,
  725.       dest      : _address;                   (* origination and destination addresses *)
  726.       date_written,                       (* when user wrote the msg (utc) *)
  727.       date_arrived  : longint;            (* when msg arrived on-line (utc) *)
  728.       utc_ofs   : word;                   (* minutes offset from utc of message writer *)
  729.       replyto   : umsgid_type;
  730.       replies   : array[1..max_reply] of umsgid_type;
  731.       azdate    : string[19];             (* ascii date *)
  732.     end;
  733.  
  734.  
  735. (*
  736.   Each SQD file has a SQI FILES.  The message number YOU see (the user)
  737.   in MAX is really the counter starting from 1 of each record in SQI.
  738.   But the TRUE UNIQUE Message ID is in umsgid. The ofs value will
  739.   point to the frame header in SQD.  These files are small and you
  740.   may read them into a array SqiPtrArrayType using the functions
  741.   below.
  742.  
  743. *)
  744.  
  745.   _sqidxtype = record
  746.     ofs    : recpos_type;           (* offset of frame header *)
  747.     umsgid : umsgid_type;           (* unique message identifier *)
  748.     hash   : longint;               (* 'To' name hash value *)
  749.   end;
  750.  
  751.   sqiptrarraytype = array[1..1] of _sqidxtype;
  752.   sqiptrtype      = ^sqiptrarraytype;
  753.  
  754.  
  755. (*
  756.  
  757. Sizes of various structures.  WARNING, alot of the routines use these
  758. variables. You should be more dynamic and reading the true sizes SCOTT
  759. puts in the squish structures (if any).
  760.  
  761. *)
  762.  
  763.  
  764. const
  765.   _sqbsize : word = sizeof(_sqbasetype);
  766.   _sqfsize : word = sizeof(_sqfhdrtype);
  767.   _sqmsize : word = sizeof(_sqmhdrtype);
  768.   _sqisize : word = sizeof(_sqidxtype);
  769.   _sdmsize : word = sizeof(_fidomsgtype);
  770.  
  771.  
  772. (*
  773.  
  774. Function Prototypes in this unit.
  775.  
  776. *)
  777.  
  778. !short   procedures used
  779.  
  780.  
  781.   function sqsetsqbsize(var fd: file): integer;
  782.   function sqopensqd(name: string; var fd: file; lock : boolean): integer;
  783.   function sqclosesqd(var fd: file): integer;
  784.   function sqreadbhdr(var fd: file; var sb: _sqbasetype): integer;
  785.   function sqwritebhdr(var fd: file; var sb: _sqbasetype): integer;
  786.   function sqreadfhdr(var fd: file; var sf: _sqfhdrtype; fp: longint): integer;
  787.   function sqwritefhdr(var fd: file; var sf: _sqfhdrtype; fp: longint): integer;
  788.   function sqreadmhdr(var fd: file; var sm: _sqmhdrtype; fp: longint): integer;
  789.   function sqwritemhdr(var fd: file; var sm: _sqmhdrtype; fp: longint): integer;
  790.   function sqreadmtxt(var fd: file; var st; fp: longint; ml: longint): integer;
  791.   function sqwritemtxt(var fd: file; var st; fp: longint; ml: longint): integer;
  792.   function sqopensqi(name: string; var fd: file): integer;
  793.   function sqclosesqi(var fd: file): integer;
  794.   function sqreadsqi(var fd: file; var si: _sqidxtype; fp: longint): integer;
  795.   function sqwritesqi(var fd: file; var si: _sqidxtype; fp: longint): integer;
  796.   function sdmread(name: string; var mh: _fidomsgtype; var mb: msgbufptrtype; var mz: longint): integer;
  797.   function squnlinkframe(var fd: file; var sf: _sqfhdrtype): integer;
  798.   function sqlinkframe(var fd: file; var sf: _sqfhdrtype; tp, lp: longint; op: word): integer;
  799.   function sqfreeframe(var fd: file; var sb: _sqbasetype; rp: longint): integer;
  800.   function sqfindframe(var fd: file; var sb: _sqbasetype; var fl, rp: longint): integer;
  801.   function sqnewframe(var fd: file; var sb: _sqbasetype; var sf: _sqfhdrtype; var ml, rp: longint): integer;
  802.   function sqreplaceframe(var fd: file; var sb: _sqbasetype; var sf: _sqfhdrtype; var rp, ml: longint): integer;
  803.   
  804.   function sqazhashname(var s): longint;
  805.   function sqhashname (name : string) : longint;
  806.   procedure squishsqiptr(var sqiptr : sqiptrtype; fn :pathstr; var sqisize : longint);
  807.   function squishmsgntouid(var sqiptr : sqiptrtype; msgn : word ; totalsqi : word) : longint;
  808.   function squishuidtomsgn(var sqiptr : sqiptrtype; uid : longint; totalsqi : word) : word;
  809.   function getsquishbaserec(fn : pathstr; var sqbaserec : _sqbasetype) : integer;
  810.   function setsquishmsgattribute(var fvsqd : file; var fpos : longint; newattr : longint) : integer;
  811.  
  812.  
  813.   { conversion from MSG to Squish }
  814.   function sdmtosqd(
  815.     mname,
  816.     sname: string;
  817.     var mh : _fidomsgtype;
  818.     var newnum : word;
  819.     lockit : boolean
  820.   ): integer;
  821.  
  822.   procedure arrangetxt(var msg: msgbufptrtype; var msiz, csiz: longint);
  823.  
  824.  
  825.  
  826.  
  827.  The BASE RECORD and the FRAME RECORD are potentially dynamic records.
  828.  When a squish file SQD is open, you should call SQSetSQBSize to reset
  829.  the SQBSIZE variable to proper the length, and when do you read in the
  830.  BASE RECORD, set the SBFSIZE variable to the value defined in the base
  831.  record. Doing so, will atleast conform to the way MAX today is setup for
  832.  the future changes in the base structure.
  833.  
  834.  There is no critical error trap routines here. It is your programming
  835.  responsibility to TRAP and CLOSE, and especially UNLOCK any open SQUISH
  836.  file if a critical error occurs.  There is a local unit variable
  837.  _SQD_FILE_LOCKED which is used here to determine if a message based is
  838.  locked when a closing function is called.  It is suggested that you test
  839.  for this variable's logical state in your critical error trap routine.
  840.  
  841.   Description:
  842.  
  843.     Squish has four files:
  844.  
  845.      *.SQL   - the lastread pointers are stored for the user. The lastus00.dat
  846.                file has the user's record number. Seek to it and read a word
  847.                to get lastread value for the user for the message base.
  848.  
  849.      *.SQI   - is a index of LIVE MESSAGES in the Squish *.SQD file. It
  850.                basically stores the 'unique' message id for each message,
  851.                the offset of the SQUISH messahe header (sqhdr) and the
  852.                HASH of the TOWHOM user's name.
  853.  
  854.      *.SQD   - has all the mail. The basic layout is:
  855.  
  856.                 BASE_RECORD
  857.  
  858.                 then for each message
  859.  
  860.                   SQUISH MESSAGE HEADER
  861.                   CONTROL INFORMATION   Where all ^A stuff is stored
  862.                   TEXT MESSAGE          may not always be null terminated
  863.  
  864.                The base record will tell you where the first squish msg header
  865.                is at, and each msg header will point to the next or prev one.
  866.  
  867.                In addition, the base record also will point to the first FREE
  868.                (one that was marked deleted) Squish Message Header and so on.
  869.  
  870.                So from the base record, you can get a "Doublely linked list"
  871.                of both the live messages and free messages.
  872.  
  873.       *.SQB  - something to do with dupe checking and I think it's for the
  874.                squish mail processor. Not discussed or used in the this API.
  875.  
  876.  
  877.  
  878. !short ZMOD UNIT
  879.  
  880.    This unit interfaces with another system, via either
  881.    FOSSIL or direct UART, using the ZModem protocol.
  882.    It support error-trapping, direct recovering, line faults and
  883.    afterwards Error-recovering from broken transmission.
  884.    It uses ECO_LIB.TPU for a nice directscreen real-time display.
  885.    A version will be written, undependent from ECO_LIB, where
  886.    a pointer to a display routine can be used for either
  887.    no-, direct or stdio screenwrites.
  888.  
  889.  
  890. !short   constants used
  891.  
  892. const
  893.   zmodemlogging: boolean = false;
  894.  
  895. var
  896.   alreadycarrier : boolean;
  897.   filenum        :    word;
  898.  
  899. !short   procedures used
  900.  
  901.   function zmodem_receive(
  902.     path: string; comport: word; baudrate: longint; init: boolean
  903.   ): boolean;
  904.  
  905.  
  906.   function zmodem_send(
  907.     pathname: string; lastfile: boolean; comport: word; baudrate: longint;
  908.     init: boolean
  909.   ): boolean;
  910.  
  911.   procedure z_message(s: string);
  912.   procedure z_setcomport(port: byte; fossiloverride: boolean);
  913.   procedure z_sendcan;
  914.  
  915.  
  916. !short
  917. !short PutEMSI
  918.  
  919.   This is an ECO_LIB using, shining example on how to use EMSI, whilst
  920.   calling.
  921.   Receiving part is being written.
  922.  
  923.  
  924.  
  925.   procedure putemsi;
  926.   var
  927.     i    :   byte;
  928.     ch   :   char;
  929.     res  : string;
  930.     pp   :   word;
  931.     pack : ar1024;
  932.  
  933.   begin
  934.     writeln('° Writing EMSI-enquiry...');
  935.     if debugmode then __logapp('Writing EMSI-enquiry...');
  936.     __clr1024(pack); __app1024(pack, emsi_inq + #13); send1024(pack);
  937.     
  938.     __clr1024(pack);
  939.     __app1024(pack, 'EMSI_DAT');
  940.     __app1024(pack, length_emsi_dat);
  941.     __app1024(pack, emsi_dat);
  942.     crc := hex(crc16(pack));
  943.  
  944.     __clr1024(pack);
  945.     __app1024(pack, '**EMSI_DAT');
  946.     __app1024(pack, length_emsi_dat);
  947.     __app1024(pack, emsi_dat);
  948.     __app1024(pack, crc + #13);
  949.     send1024(pack);
  950.  
  951.     comwait;
  952.     repeat
  953.       inc(tries); res := '';
  954.       while (
  955.         comreceive(ch) and not(pos(emsi_req, __up(res)) > 0)
  956.       ) do begin
  957.         res := res + ch; delay(12);
  958.         if debugmode then write(ch);
  959.         capturewrite(ch);
  960.         ch := #00;
  961.       end;
  962.     until (pos(emsi_req, __up(res)) > 0) or (tries = maxemsitries);
  963.  
  964.     if res <> '' then __logapp('Response to inquiry: ' + res);
  965.     if (pos(emsi_req, __up(res)) > 0) then begin
  966.       res := '';
  967.       if debugmode then begin
  968.         writeln('° Yonder site has acknowledged receipt of EMSI_INQ');
  969.         __logapp('Yonder site has acknowledged receipt of EMSI_INQ');
  970.       end;
  971.     end else begin
  972.       writeln('! Host system failed to acknowledge the inquiry sequence.');
  973.       __logapp('Host system failed to acknowledge the inquiry sequence.');
  974.       if fossil then fos_hangup_(comport) else hangup232; __eos;
  975.       { send_modem_command(modem_hang_up); absorb232response(false, tmp); }
  976.     end;
  977.  
  978.     writeln('° Sending EMSI data...');
  979.     if debugmode then __logapp('Sending EMSI data...');
  980.     tries := 0;
  981.  
  982.     __clr1024(pack); __app1024(pack, emsi_inq + #13); send1024(pack);
  983.  
  984.     __clr1024(pack); __app1024(pack, 'EMSI_DAT'); __app1024(pack, length_emsi_dat);
  985.     __app1024(pack, emsi_dat); crc := hex(crc16(pack));
  986.     __clr1024(pack); __app1024(pack, '**EMSI_DAT');
  987.     __app1024(pack, length_emsi_dat); __app1024(pack, emsi_dat); 
  988.     __app1024(pack, crc + #13); send1024(pack);
  989.  
  990.     comwait;
  991.     repeat
  992.       inc(tries); res := ''; ch := #00;
  993.       while comreceive(ch) and (ch <> '*') do begin
  994.         if debugmode then write(ch); capturewrite(ch);
  995.       end;
  996.       ch := '*'; res := '*';
  997.       comwait;
  998.       while (
  999.         comreceive(ch) and not(pos(emsi_ack, __up(res)) > 0)
  1000.       ) do begin
  1001.         res := addtolast20(res, ch); delay(12);
  1002.         if debugmode then write(ch);
  1003.         capturewrite(ch);
  1004.         ch := #00;
  1005.       end;
  1006.     until (pos(emsi_ack, __up(res)) > 0) or (tries >= maxemsitries);
  1007.     if (res <> '') then __logapp('Response to EMSI data (Acq?): ' + res);
  1008.  
  1009.     if tries >= maxemsitries then begin
  1010.       writeln('Host system failed to acknowledge the EMSI_DAT packet.');
  1011.       __logapp('Host system failed to acknowledge the EMSI_DAT packet.');
  1012.       if fossil then fos_hangup_(comport) else hangup232; __eos;
  1013.     end else begin
  1014.       writeln('° Boss has acknowledged receipt of EMSI_DAT');
  1015.       __logapp('Boss has acknowledged receipt of EMSI_DAT');
  1016.     end; 
  1017.  
  1018.     temp := '*';                                    { read in '**EMSI_DAT' }
  1019.     repeat comreceive(ch); capturewrite(ch) until (ch = '*');
  1020.     repeat
  1021.       if comreceive(ch) then temp := temp + ch;
  1022.       capturewrite(ch);
  1023.     until(pos('**EMSI_DAT', temp) > 0);
  1024.     pp := 8;                                     { no '**' }
  1025.     pack[1] := 'E'; pack[2] := 'M'; pack[3] := 'S'; pack[4] := 'I';
  1026.     pack[5] := '_'; pack[6] := 'D'; pack[7] := 'A'; pack[8] := 'T';
  1027.     len := '';                              { read in the length   }
  1028.  
  1029.     for loop := 1 to 4 do begin
  1030.       delay(12); if comreceive(ch) then len := len + ch;
  1031.       inc(pp); pack[pp] := ch; capturewrite(ch);
  1032.     end;
  1033.  
  1034.     len_rec_emsi_dat := hex2dec(len);
  1035.  
  1036.     if debugmode then begin
  1037.       writeln('Length of DAT: (', len, ') ', len_rec_emsi_dat, '.');
  1038.       __logapp('Length of DAT: (' + len + ') ' + __num(len_rec_emsi_dat) + '.');
  1039.     end;
  1040.     packet := '';
  1041.     for loop := 1 to len_rec_emsi_dat do begin   { read in the packet   }
  1042.       delay(12); comreceive(ch); inc(pp); pack[pp] := ch; capturewrite(ch);
  1043.     end;
  1044.     crc := '';                                   { read in the crc      }
  1045.     for loop := 1 to 4 do begin
  1046.       delay(12); comreceive(ch); crc := crc + ch; capturewrite(ch);
  1047.     end;
  1048.  
  1049.     if hex(crc16(pack)) <> crc then begin
  1050.       writeln('! The recieved EMSI_DAT is corrupt!!!!');
  1051.       __logapp('The recieved EMSI_DAT is corrupt!!!!');
  1052.     end;
  1053.  
  1054.     __clr1024(pack); __app1024(pack, emsi_ack + #13); send1024(pack);
  1055.   end; { EMSI mode }
  1056.  
  1057.  
  1058. !short QuickBBS struct DOC
  1059.  
  1060.  
  1061. Type
  1062.   FlagType = Array[1..4] of Byte;
  1063.  
  1064.   UserRecord = Record
  1065.     Name:               String[35];
  1066.     City:               String[25];
  1067.     Pwd:                String[15];
  1068.     DataPhone,
  1069.     HomePhone:          String[12];
  1070.     LastTime:           String[5];
  1071.     LastDate:           String[8];
  1072.     Attrib:             Byte;
  1073.     Flags:              FlagType;
  1074.     Credit,
  1075.     Pending,
  1076.     TimesPosted,
  1077.     HighMsgRead,
  1078.     SecLvl,
  1079.     Times,
  1080.     Ups,
  1081.     Downs,
  1082.     UpK,
  1083.     DownK,
  1084.     TodayK,
  1085.     Elapsed,
  1086.     Len:                Integer;
  1087.     CombinedPtr:        Word; (* Record number in COMBINED.BBS *)
  1088.     Age:                Byte; (* Not yet implemented *)
  1089.     ExtraSpace:         Array[1..5] of Byte;
  1090.   End;
  1091.  
  1092. (*  Attrib:
  1093.  
  1094.       Bit 0: Deleted
  1095.       Bit 1: Screen Clear Codes
  1096.       Bit 2: More Prompt
  1097.       Bit 3: ANSI
  1098.       Bit 4: No-Kill
  1099.       Bit 5: Ignore Download Hours
  1100.       Bit 6: ANSI Full Screen Editor
  1101.       Bit 7: [ Reserved ]
  1102.  
  1103. *)
  1104.  
  1105. { Nodelist Records *************************************************** }
  1106.  
  1107.    NodeIdxRecord = Record
  1108.      Zone,
  1109.      Net,
  1110.      Node:      Integer;
  1111.      NodeType:  Byte;
  1112.    End;
  1113.  
  1114.    NodelistRecord = Record
  1115.      NodeType:  Byte;
  1116.      Zone,
  1117.      Net,
  1118.      Node:      Integer;
  1119.      Name:      String[20];
  1120.      City:      String[40];
  1121.      Phone:     String[40];
  1122.      Password:  String[8];
  1123.      Flags:     Integer;
  1124.      BaudRate:  Integer;
  1125.      Cost:      Integer;
  1126.    End;
  1127.  
  1128. { Message Records ******************************************************}
  1129.  
  1130.    CombSelectType = Array[1..200] of Boolean; (* for COMBINED.BBS *)
  1131.  
  1132.    InfoRecord = Record
  1133.      LowMsg:      Integer;     { Lowest Message in File }
  1134.      HighMsg:     Integer;     { Highest Message in File }
  1135.  
  1136.      TotalActive: Integer;     { Total Active Messages }
  1137.  
  1138.      ActiveMsgs:  Array[1..200] of Integer;
  1139.    End;
  1140.  
  1141.    IdxRecord = Record
  1142.      MsgNum:       Integer;
  1143.      Board:        Byte;
  1144.    End;
  1145.  
  1146.    HdrRecord = Record
  1147.      MsgNum,
  1148.      ReplyTo,
  1149.      SeeAlsoNum,
  1150.      TRead:              Integer;
  1151.      StartRec:           Word;
  1152.      NumRecs,
  1153.      DestNet,
  1154.      DestNode,
  1155.      OrigNet,
  1156.      OrigNode:           Integer;
  1157.      DestZone,
  1158.      OrigZone:           Byte;
  1159.      Cost:               Integer;
  1160.      MsgAttr,
  1161.      NetAttr,
  1162.      Board:              Byte;
  1163.      PostTime:           String[5];
  1164.      PostDate:           String[8];
  1165.      WhoTo,
  1166.      WhoFrom:            String[35];
  1167.      Subj:               String[72];
  1168.    End;
  1169.  
  1170.  
  1171. (* Msg Attributes:
  1172.  
  1173.       Bit 0: Deleted
  1174.       Bit 1: Unmoved Outgoing Net Message
  1175.       Bit 2: Is a Net Mail Message
  1176.       Bit 3: Private
  1177.       Bit 4: Received
  1178.       Bit 5: Unmoved Outgoing Echo Message
  1179.       Bit 6: Local Bit
  1180.       Bit 7: [ Reserved ]
  1181.  
  1182.    Net Attributes:
  1183.  
  1184.       Bit 0: Kill Message after it's been sent
  1185.       Bit 1: Sent OK
  1186.       Bit 2: File(s) Attached
  1187.       Bit 3: Crash Priority
  1188.       Bit 4: Request Receipt
  1189.       Bit 5: Audit Request
  1190.       Bit 6: Is a Return Receipt
  1191.       Bit 7: [ Reserved ]
  1192.  
  1193. *)
  1194.  
  1195. { Other Stuff *********************************************************** }
  1196.  
  1197.   SysInfoRecord = Record
  1198.     CallCount:    LongInt;
  1199.     LastCaller:   String[35];
  1200.     ExtraSpace:   Array[1..128] of Byte;
  1201.   End;
  1202.  
  1203.   TimeLogRecord = Record
  1204.     StartDate:        String[8];
  1205.     BusyPerHour:      Array[0..23] of Integer;
  1206.     BusyPerDay:       Array[0..6] of Integer;
  1207.   End;
  1208.  
  1209.   MenuRecord = Record
  1210.     Typ:      Byte;
  1211.     Sec:      Integer;
  1212.     Flags:    FlagType;
  1213.     Str:      String[75];
  1214.     Key:      Char;
  1215.     Data:     String[80];
  1216.     Fg,
  1217.     Bg:       Byte;
  1218.   End;
  1219.  
  1220. { Configuration Information ********************************************** }
  1221.  
  1222.   EventRecord = Record
  1223.     Status:       Byte; { 0=Deleted 1=Enabled 2=Disabled }
  1224.     RunTime:      String[5];
  1225.     ErrorLevel:   Byte;
  1226.     Days:         Byte;
  1227.     Forced:       Boolean;
  1228.     LastTimeRun:  String[8];
  1229.   End;
  1230.  
  1231.   BoardRecord = Record
  1232.     Name:         String[16];
  1233.     Typ:          Byte; { 0=Standard 1=Net 3=Echo }
  1234.     Kinds:        Byte; { 0=Both 1=Pvt 2=Pub 3=Read-Only }
  1235.     Combined:     Boolean;
  1236.     Aliases:      Boolean;
  1237.  
  1238.     ReadSecLvl:   Integer;
  1239.     ReadFlags:    FlagType;
  1240.  
  1241.     WriteSecLvl:  Integer;
  1242.     WriteFlags:   FlagType;
  1243.  
  1244.     SysopSecLvl:  Integer;
  1245.     SysopFlags:   FlagType;
  1246.   End;
  1247.  
  1248.   ConfigRecord = Record
  1249.     (*  Modem Parameters  *)
  1250.     CommPort:      Integer;
  1251.     InitBaud,
  1252.     InitTimes,
  1253.     AnswerWait:    Integer;
  1254.     ModemInitStr,
  1255.     ModemBusyStr:  String[70];
  1256.     ModemInitResp,
  1257.     ModemBusyResp,
  1258.     Resp300,
  1259.     Resp1200,
  1260.     Resp2400:      String[40];
  1261.  
  1262.     (*  System Paths  *)
  1263.     MenuPath,
  1264.     TextPath,
  1265.     NetPath:      String[66];
  1266.  
  1267.     (*  Restriction Parameters  *)
  1268.     MinBaud,
  1269.     GraphicsBaud,
  1270.     XferBaud:      Integer;
  1271.     LowBaudStart,
  1272.     LowBaudEnd,
  1273.     DownloadStart,
  1274.     DownloadEnd,
  1275.     PagingStart,
  1276.     PagingEnd:     String[5];
  1277.  
  1278.     (*  Matrix Information  *)
  1279.     MatrixZone,
  1280.     MatrixNet,
  1281.     MatrixNode:    Integer;
  1282.     AkaNet,
  1283.     AkaNode:       Array[1..5] of Integer;
  1284.     NetMailBoard:  Integer;
  1285.  
  1286.     (*  Default Information for New Users  *)
  1287.     DefaultSec:                Integer;
  1288.     DefaultCredit:             Integer;
  1289.     DefaultFlags:              FlagType;
  1290.  
  1291.     (*  Sysop Security Levels  *)
  1292.     EditorCmdStr:    String[70];
  1293.     OriginLine:      String[60];
  1294.     SysopName:       String[35];
  1295.     AutoLogonChar,
  1296.     FastLogon,
  1297.     ScreenBlanking,
  1298.     UseLastRead,
  1299.     MonoMode,
  1300.     DirectWrite,
  1301.     SnowCheck,
  1302.     NetEchoExit,
  1303.     OneWordNames,
  1304.     CheckMail,
  1305.     AskHomePhone,
  1306.     AskDataPhone,
  1307.     GraphicsAvail:   Boolean;
  1308.     InactiveTimeOut: Integer;
  1309.     LogonTime:       Integer;
  1310.     DefFgColor:      Integer;
  1311.     DefBgColor:      Integer;
  1312.     PasswordTries:   Integer;
  1313.     MaxPageTimes:    Integer;
  1314.     PageBellLen:     Integer;
  1315.  
  1316.     Use_Xmodem:      Boolean;
  1317.     Use_Xmodem1k:    Boolean;
  1318.     Use_Ymodem:      Boolean;
  1319.     Use_YmodemG:     Boolean;
  1320.     Use_Sealink:     Boolean;     { Changed for 2.04 }
  1321.     Use_Zmodem:      Boolean;     { "              " }
  1322.     Inp_Fields:      Boolean;     { "              " }
  1323.     QuoteStr:        String[3];
  1324.     UploadCredit:    Integer;
  1325.     LoadingMessage:  String[70];
  1326.     SelectionPrompt: String[70];
  1327.  
  1328.     VersionID:       Word;
  1329.  
  1330.     { Added for 2.04: }
  1331.  
  1332.     Resp4800,
  1333.     Resp9600:        String[40];   
  1334.  
  1335.     AkaZone:         Array[1..5] of Integer;
  1336.  
  1337.     { Added for 2.60: }
  1338.  
  1339.     MatrixPoint:     Integer;
  1340.     AkaPoint:        Array[1..5] of Integer;
  1341.  
  1342.     UseAka:          Array[1..200] of Byte;
  1343.     AskAge:          Boolean; (* Not yet Implemented *)
  1344.     SystemName:      String[40];
  1345.     RegKey:          Longint;
  1346.  
  1347.     ExtraSpace:      Array[1..5] of Byte;
  1348.  
  1349.     EventRec:        Array[1..30] of EventRecord;
  1350.     BoardRec:        Array[1..200] of BoardRecord;
  1351.   End;
  1352.  
  1353.   GosubDataType = Array[1..20] of String[8];
  1354.  
  1355.   ExitRecord = Record
  1356.     BaudRate:        Integer;
  1357.     SysInfo:         SysInfoRecord;
  1358.     TimeLogInfo:     TimeLogRecord;
  1359.     UserInfo:        UserRecord;
  1360.     EventInfo:       EventRecord;
  1361.     NetMailEntered:  Boolean;
  1362.     EchoMailEntered: Boolean;
  1363.     LoginTime:       String[5];
  1364.     LoginDate:       String[8];
  1365.     TmLimit:         Integer;
  1366.     LoginSec:        LongInt;
  1367.     Credit:          LongInt;
  1368.     UserRecNum:      Integer;
  1369.     ReadThru:        Integer;
  1370.     PageTimes:       Integer;
  1371.     DownLimit:       Integer;
  1372.     WantChat:        Boolean;
  1373.     GosubLevel:      Byte;
  1374.     GosubData:       GosubDataType;
  1375.     Menu:            String[8];
  1376.   End;
  1377.  
  1378.  
  1379. !short RemoteAccess struct DOC
  1380.  
  1381.  
  1382. type
  1383.   asktype        = (yes, no, ask, only);
  1384.   videotype      = (auto, short, long);
  1385.   msgtype        = (localmail, netmail, echomail);
  1386.   msgkindstype   = (both, private, public, ronly);
  1387.   orphantype     = (ignore, create, kill);
  1388.   flagtype       = array[1..4] of byte;
  1389.   time           = string[5];
  1390.   date           = string[8];
  1391.   longdate       = string[9];
  1392.  
  1393.   netaddress     = record
  1394.     zone,
  1395.     net,
  1396.     node,
  1397.     point          : word;
  1398.   end;
  1399.  
  1400.   languagerecord = record
  1401.     name           : string[20];
  1402.     attribute      : byte;
  1403.     defname,
  1404.     menupath,
  1405.     textpath,
  1406.     quespath       : string[60];
  1407.     freespace      : array[1..200] of byte;
  1408.   end;
  1409.  
  1410.   msginforecord  = record
  1411.     lowmsg,
  1412.     highmsg,
  1413.     totalmsgs      : word;
  1414.     totalonboard   : array[1..200] of word;
  1415.   end;
  1416.  
  1417.   msgidxrecord   = record
  1418.     msgnum         : integer;
  1419.     board          : byte;
  1420.   end;
  1421.  
  1422.   msgtoidxrecord = string[35];
  1423.  
  1424.   msghdrrecord   = record
  1425.     msgnum         : integer;
  1426.     prevreply,
  1427.     nextreply,
  1428.     timesread      : word;
  1429.     startblock     : word;
  1430.     numblocks,
  1431.     destnet,
  1432.     destnode,
  1433.     orignet,
  1434.     orignode       : word;
  1435.     destzone,
  1436.     origzone       : byte;
  1437.     cost           : word;
  1438.     msgattr,
  1439.     netattr,
  1440.     board          : byte;
  1441.     posttime       : time;
  1442.     postdate       : date;
  1443.     whoto,
  1444.     whofrom        : msgtoidxrecord;
  1445.     subject        : string[72];
  1446.   end;
  1447.  
  1448.   msgtxtrecord   = string[255];
  1449.  
  1450.   useronrecord   = record
  1451.     name,
  1452.     handle         : msgtoidxrecord;
  1453.     line           : byte;
  1454.     baud           : word;
  1455.     city           : string[25];
  1456.     donotdisturb   : boolean;
  1457.     status         : byte;
  1458.     attribute      : byte;
  1459.   end;
  1460.  
  1461.   { status byte - 0 : browsing (in a menu)
  1462.                   1 : uploading/downloading
  1463.                   2 : reading/posting messages
  1464.                   3 : in a door/external utility
  1465.                   4 : chatting with sysop
  1466.                   5 : answering questionnaire
  1467.                   6 : system ready (0=busy)
  1468.  
  1469.     attribute   - bit 0 : hidden }
  1470.  
  1471.   lastcallrecord = record
  1472.     line           : byte;
  1473.     name,
  1474.     handle         : msgtoidxrecord;
  1475.     city           : string[25];
  1476.     baud           : word;
  1477.     times          : longint;
  1478.     logon          : string[5];
  1479.     logoff         : string[5];
  1480.     attribute      : byte;
  1481.   end;
  1482.  
  1483.                 { attribute - bit 0 : hidden }
  1484.  
  1485.   lastreadrecord = array[1..200] of word;
  1486.  
  1487.   combinedrecord = array[1..25] of byte;
  1488.  
  1489.   usersidxrecord = record
  1490.     namecrc32,
  1491.     handlecrc32    : longint;
  1492.   end;
  1493.  
  1494.   usersxirecord  = record
  1495.     handle         : string[35];
  1496.     comment        : string[80];
  1497.     firstdate      : date;
  1498.     combinedinfo   : combinedrecord;
  1499.     birthdate,
  1500.     subdate        : date;
  1501.     screenwidth,
  1502.     msgarea,
  1503.     filearea,
  1504.     language,
  1505.     dateformat     : byte;
  1506.     forwardto      : string[35];
  1507.     extraspace     : array[1..43] of byte;
  1508.   end;
  1509.  
  1510.   usersrecord    = record
  1511.     name           : msgtoidxrecord;
  1512.     location       : string[25];
  1513.     password       : string[15];
  1514.     dataphone,
  1515.     voicephone     : string[12];
  1516.     lasttime       : time;
  1517.     lastdate       : date;
  1518.     attribute      : byte;
  1519.  
  1520.      { bit 0 : deleted
  1521.            1 : clear screen
  1522.            2 : more prompt
  1523.            3 : ansi
  1524.            4 : no-kill
  1525.            5 : xfer priority
  1526.            6 : full screen msg editor
  1527.            7 : quiet mode }
  1528.  
  1529.     flags          : flagtype;
  1530.     credit,
  1531.     pending        : word;
  1532.     msgsposted,
  1533.     lastread,
  1534.     security,
  1535.     nocalls,
  1536.     uploads,
  1537.     downloads,
  1538.     uploadsk,
  1539.     downloadsk     : word;
  1540.     todayk,
  1541.     elapsed        : integer;
  1542.     screenlength   : word;
  1543.     lastpwdchange,
  1544.     attribute2,
  1545.  
  1546.      { bit 0 : hot-keys
  1547.            1 : avt/0
  1548.            2 : full screen message viewer
  1549.            3 : hidden from userlist }
  1550.  
  1551.  
  1552.     group          : byte;
  1553.     xirecord       : word;
  1554.     extraspace     : array[1..3] of byte;
  1555.   end;
  1556.  
  1557.   sysinforecord  = record
  1558.     totalcalls     : longint;
  1559.     lastcaller     : msgtoidxrecord;
  1560.     extraspace     : array[1..128] of byte;
  1561.   end;
  1562.  
  1563.   timelogrecord  = record
  1564.     startdate      : date;
  1565.     busyperhour    : array[0..23] of word;
  1566.     busyperday     : array[0..6] of word;
  1567.   end;
  1568.  
  1569.   mnurecord      = record
  1570.     typ            : byte;
  1571.     security       : word;
  1572.     flags          : flagtype;
  1573.     display        : string[75];
  1574.     hotkey         : char;
  1575.     miscdata       : string[80];
  1576.     foreground,
  1577.     background     : byte;
  1578.   end;
  1579.  
  1580.   eventrecord    = record
  1581.     status         : byte; { 0=deleted 1=enabled 2=disabled }
  1582.     starttime      : time;
  1583.     errorlevel     : byte;
  1584.     days           : byte;
  1585.     forced         : boolean;
  1586.     lasttimerun    : date;
  1587.   end;
  1588.  
  1589.   eventrecordarray = array[1..20] of eventrecord;
  1590.  
  1591.   messagerecord  = record
  1592.     name           : string[40];
  1593.     typ            : msgtype;
  1594.     msgkinds       : msgkindstype;
  1595.     attribute      : byte;
  1596.  
  1597.      { bit 0 : enable echoinfo
  1598.            1 : combined access
  1599.            2 : file attaches
  1600.            3 : allow aliases
  1601.            4 : use softcrs as characters
  1602.            5 : force handle
  1603.            6 : allow deletes }
  1604.  
  1605.     dayskill,    { kill older than 'x' days }
  1606.     recvkill       : byte; { kill recv msgs, recv for more than 'x' days }
  1607.     countkill      : word;
  1608.  
  1609.     readsecurity   : word;
  1610.     readflags      : flagtype;
  1611.  
  1612.     writesecurity  : word;
  1613.     writeflags     : flagtype;
  1614.  
  1615.     sysopsecurity  : word;
  1616.     sysopflags     : flagtype;
  1617.  
  1618.     originline     : string[60];
  1619.     akaaddress     : byte;
  1620.   end;
  1621.  
  1622.   filesrecord    = record
  1623.     name           : string[30];
  1624.     attrib         : byte;
  1625.  
  1626.      { bit 0 : include in new files scan
  1627.            1 : include in upload dupe scan
  1628.            2 : permit long descriptions }
  1629.  
  1630.     filepath       : string[40];
  1631.     freespace      : array[1..35] of byte;
  1632.     uploadsecurity : word;
  1633.     uploadflags    : flagtype;
  1634.     security       : word;
  1635.     flags          : flagtype;
  1636.     listsecurity   : word;
  1637.     listflags      : flagtype;
  1638.   end;
  1639.  
  1640.   configrecord = record
  1641.     versionid           : word;
  1642.     commport            : byte;
  1643.     baud                : longint;
  1644.     inittries           : byte;
  1645.     initstr,
  1646.     busystr             : string[70];
  1647.     initresp,
  1648.     busyresp,
  1649.     connect300,
  1650.     connect1200,
  1651.     connect2400,
  1652.     connect4800,
  1653.     connect9600,
  1654.     connect19k,
  1655.     connect38k          : string[40];
  1656.     answerphone         : boolean;
  1657.     ring,
  1658.     answerstr           : string[20];
  1659.     flushbuffer         : boolean;
  1660.     modemdelay          : integer;
  1661.  
  1662.     minimumbaud,
  1663.     graphicsbaud,
  1664.     transferbaud        : integer;
  1665.     slowbaudtimestart,
  1666.     slowbaudtimeend,
  1667.     downloadtimestart,
  1668.     downloadtimeend     : time;
  1669.  
  1670.     pagestart           : array[0..6] of time;
  1671.     pageend             : array[0..6] of time;
  1672.  
  1673. {}  freespace1          : array[1..70] of byte;
  1674.     pwdexpiry           : word;
  1675.  
  1676.     menupath,
  1677.     textpath,
  1678.     attachpath,
  1679.     nodelistpath,
  1680.     msgbasepath,
  1681.     syspath,
  1682.     externaledcmd       : string[60];
  1683.  
  1684.     address             : array[0..9] of netaddress;
  1685.     systemname          : string[30];
  1686.  
  1687.     newsecurity         : word;
  1688.     newcredit           : word;
  1689.     newflags            : flagtype;
  1690.  
  1691.     originline          : string[60];
  1692.     quotestring         : string[15];
  1693.     sysop               : string[35];
  1694.     logfilename         : string[60];
  1695.     fastlogon,
  1696.     allowsysrem,
  1697.     monomode,
  1698.     strictpwdchecking,
  1699.     directwrite,
  1700.     snowcheck           : boolean;
  1701.     creditfactor        : integer;
  1702.  
  1703.     usertimeout,
  1704.     logontime,
  1705.     passwordtries,
  1706.     maxpage,
  1707.     pagelength          : word;
  1708.     checkformultilogon,
  1709.     excludesysopfromlist,
  1710.     onewordnames        : boolean;
  1711.     checkmail           : asktype;
  1712.     askvoicephone,
  1713.     askdataphone,
  1714.     dofullmailcheck,
  1715.     allowfileshells,
  1716.     fixuploaddates,
  1717.     freezechat          : boolean;
  1718.     ansi,                       { ansi: yes, no, or ask new users     }
  1719.     clearscreen,                { clear:        "                     }
  1720.     moreprompt          : asktype;    { more:         "                     }
  1721.     uploadmsgs          : boolean;
  1722.     killsent            : asktype;    { kill/sent     "                     }
  1723.  
  1724.     crashasksec         : word;       { min sec# to ask 'Crash Mail ?'      }
  1725.     crashaskflags       : flagtype;
  1726.     crashsec            : word;       { min sec# to always send crash mail. }
  1727.     crashflags          : flagtype;
  1728.     fattachsec          : word;       {        "    ask 'File Attach ?'     }
  1729.     fattachflags        : flagtype;
  1730.  
  1731.     normfore,
  1732.     normback,
  1733.     statfore,
  1734.     statback,
  1735.     hiback,
  1736.     hifore,
  1737.     windfore,
  1738.     windback,
  1739.     exitlocal,
  1740.     exit300,
  1741.     exit1200,
  1742.     exit2400,
  1743.     exit4800,
  1744.     exit9600,
  1745.     exit19k,
  1746.     exit38k             : byte;
  1747.  
  1748.     multiline           : boolean;
  1749.     minpwdlen           : byte;
  1750.     minupspace          : word;
  1751.     hotkeys             : asktype;
  1752.     borderfore,
  1753.     borderback,
  1754.     barfore,
  1755.     barback,
  1756.     logstyle,
  1757.     multitasker,
  1758.     pwdboard            : byte;
  1759.     buffersize          : word;
  1760.     fkeys               : array[1..10] of string[60];
  1761.  
  1762.     whypage             : boolean;
  1763.     leavemsg            : byte;
  1764.     showmissingfiles    : boolean;
  1765. {}  freespace2          : array[1..11] of byte;
  1766.     allownetmailreplies : boolean;
  1767.     logonprompt         : string[40];
  1768.     checknewfiles       : asktype;
  1769.     replyheader         : string[60];
  1770.     blanksecs           : byte;
  1771.     protocolattrib      : array[1..6] of byte;
  1772.     errorfreestring     : string[15];
  1773.     defaultcombined     : combinedrecord;
  1774.     renumthreshold      : word;
  1775.     leftbracket,
  1776.     rightbracket        : char;
  1777.     askforhandle        : boolean;
  1778.     askforbirthdate     : boolean;
  1779.  
  1780.     groupmailsec        : word;
  1781.  
  1782.     confirmmsgdeletes   : boolean;
  1783.     freespace3          : array[1..163] of byte;
  1784.     newusergroup        : byte;
  1785.     avatar              : asktype;
  1786.     badpwdarea          : byte;
  1787.     location            : string[40];
  1788.     doafteraction       : byte; {0 = wait for cr, > 0 = wait for x seconds}
  1789.     fileline            : string[40];
  1790.     crfore,
  1791.     crback              : byte;
  1792.     langhdr             : string[40];
  1793.     sendbreak           : boolean;
  1794.     listpath            : string[60];
  1795.     fullmsgview         : asktype;
  1796.     emsi_enable         : asktype;
  1797.     emsi_newuser        : boolean;
  1798.  
  1799.     echochar            : string[1];
  1800.     connect7200,
  1801.     connect12000,
  1802.     connect14400        : string[40];
  1803.     exit7200,
  1804.     exit12000,
  1805.     exit14400           : byte;
  1806.     chatcommand         : string[60];
  1807.     exted               : asktype;
  1808.     newuserlanguage     : byte;
  1809.     languageprompt      : string[40];
  1810.     videomode           : videotype;
  1811.     autodetectansi      : boolean;
  1812.     offhook             : boolean;
  1813.     newuserdateformat   : byte;
  1814.     keyboardpwd         : string[15];
  1815.     caplocation         : boolean;
  1816.     newusersub          : byte;
  1817.     printername         : string[4];
  1818.     hilitepromptfore,
  1819.     hilitepromptback    : byte;
  1820.     initstr2            : string[70];
  1821.     altjswap            : boolean;
  1822.     sempath             : string[60];
  1823.     autochatcapture     : boolean;
  1824.  
  1825.     futureexpansion : array[1..97] of byte;
  1826.   end;
  1827.  
  1828.   exitinforecord = record
  1829.     baud             : word;
  1830.     sysinfo          : sysinforecord;
  1831.     timeloginfo      : timelogrecord;
  1832.     userinfo         : usersrecord;
  1833.     eventinfo        : eventrecord;
  1834.     netmailentered,
  1835.     echomailentered  : boolean;
  1836.     logintime        : time;
  1837.     logindate        : date;
  1838.     timelimit        : word;
  1839.     loginsec,
  1840.     credit           : longint;
  1841.     userrecord       : integer;
  1842.     readthru,
  1843.     numberpages,
  1844.     downloadlimit    : word;
  1845.     timeofcreation   : time;
  1846.     logonpassword    : string[15];
  1847.     wantchat         : boolean;
  1848.  
  1849.     deductedtime     : integer;
  1850.     menustack        : array[1..50] of string[8];
  1851.     menustackpointer : byte;
  1852.     userxiinfo       : usersxirecord;
  1853.     errorfreeconnect,
  1854.     sysopnext        : boolean;
  1855.  
  1856.     emsi_session     : boolean;        { these fields hold  }
  1857.     emsi_crtdef,                       { data related to an }
  1858.     emsi_protocols,                    { emsi session       }
  1859.     emsi_capabilities,
  1860.     emsi_requests,
  1861.     emsi_software    : string[40];
  1862.     hold_attr1,
  1863.     hold_attr2,
  1864.     hold_len         : byte;
  1865.  
  1866.     extraspace       : array[1..100] of byte;
  1867.   end;
  1868.  
  1869.   protocolrecord = record
  1870.     name           : string[15];
  1871.     activekey      : char;
  1872.     opustypectlfile,
  1873.     batchavailable : boolean;
  1874.     attribute      : byte; { 0=disabled, 1=enabled }
  1875.     logfilename,
  1876.     ctlfilename,
  1877.     dncmdstring,
  1878.     dnctlstring,
  1879.     upcmdstring,
  1880.     upctlstring    : string[80];
  1881.     uplogkeyword,
  1882.     dnlogkeyword   : string[20];
  1883.     xferdescwordnum,
  1884.     xfernamewordnum : byte;
  1885.   end;
  1886.  
  1887.  
  1888.