home *** CD-ROM | disk | FTP | other *** search
/ synchro.net / synchro.net.tar / synchro.net / modem.madness / SMMNETML / AMAX_230.ZIP / SOURCES.ZIP / AMAX.C next >
Encoding:
C/C++ Source or Header  |  1992-11-15  |  36.3 KB  |  1,024 lines

  1. /*---------------------------------------------------------------------------*/
  2. /*                                                                           */
  3. /* Module Name:   AMAX.C                                                     */
  4. /* Program Name:  AMAX                                                       */
  5. /* Revision:      2.xx                                                       */
  6. /* Purpose:       Primary Program Module                                     */
  7. /* Programmer:    Alan D. Bryant                                             */
  8. /*                                                                           */
  9. /* Copyright (C) 1988, 89, 90, 92 Alan D. Bryant, All Rights Reserved.       */
  10. /*                                                                           */
  11. /* NOTICE:  This source code is copyrighted material.  You are granted a     */
  12. /* limited license to use and distribute the code.  The complete text of     */
  13. /* the license can be found in the document LICENSE.DOC which accompanies    */
  14. /* this source code, or can be obtained directly from the author.            */
  15. /*                                                                           */
  16. /* Inquiries regarding this package should be directed to:                   */
  17. /*                                                                           */
  18. /*     AMAX                                                                  */
  19. /*     Alan D. Bryant                                                        */
  20. /*     P. O. Box 101612                                                      */
  21. /*     Denver, CO  80250                                                     */
  22. /*     USA                                                                   */
  23. /*                                                                           */
  24. /*---------------------------------------------------------------------------*/
  25.  
  26. #include <stdio.h>
  27. #include <dos.h>
  28. #include <dir.h>
  29. #include <sys\stat.h>
  30. #include <alloc.h>
  31. #include <time.h>
  32. #include "amax.h"
  33.  
  34. void display_header(char *, int);
  35. void display_warning(void);
  36. int keycomp(int *, int, int *, int);
  37.  
  38.  
  39. Cbtree *sysopindex;         //  pointer to sysop index
  40. Cbtree *nodexindex;         //  pointer to node index
  41. FILE *nodexdata;          //  pointer to nodex data
  42.  
  43. Item item;               //  btree stuff
  44. int status;
  45.  
  46.  
  47.  
  48. unsigned char outbound[80];
  49. unsigned char orig_outbound[80];
  50. unsigned char nodelist[80];
  51. unsigned char series[80];
  52. unsigned char sysname[100];
  53. unsigned int entries;
  54. char direct = 0;
  55. int zone_num = 0;
  56. int our_zone = 0;
  57. char tearline = 1;
  58. int net = -1;
  59. int node = -1;
  60. char disptime = 0;
  61. char unarctype = 0;   /* 0 = arce, 1 = pkxarc, 2 = pak  */
  62. char displzero = 0;
  63. char usenl = 1;
  64. char usecolor = 1;
  65. char extkey = 0;
  66. char series_pos = 0;
  67. unsigned char nlflags = 3;
  68.  
  69. main(int argc, char *argv[])
  70. {
  71.  
  72.     /* ----------------------------------------------- */
  73.     /* declarations                                    */
  74.     /* ----------------------------------------------- */
  75.  
  76.     FILE *stream;
  77.  
  78.     int offset;
  79.     unsigned int i;
  80.     unsigned int x;
  81.     int y;
  82.     int done;
  83.     int file_status;
  84.     int alias_zone = 0;   /*  used to id zone for alias addresses only  */
  85.  
  86.     int a = 0;
  87.     int b = 0;
  88.     int c = 0;
  89.     int d = 0;
  90.     int arcnet = -1;
  91.     int arcnode = -1;
  92.  
  93.     struct stat f;
  94.     struct ffblk ffblk;
  95.     time_t foobarn;
  96.  
  97.     struct binfile {
  98.         char ident[35];
  99.         char binkvar[50];
  100.         char direct;
  101.         char bypass;
  102.         char packer[100];
  103.         char courtesy;
  104.         char tearline;
  105.         char sortmode;
  106.         char selection[5];
  107.         char unarctype;
  108.         char displzero;
  109.         char usenl;
  110.         char ARCmail;
  111.         char noselect;
  112.         char usecolor;
  113.         char extkey;
  114.     } w;
  115.  
  116.     unsigned char ch;
  117.     char bypass = 0;
  118.     char noselect = 0;
  119.     char courtesy = 0;
  120.     char *binkley;
  121.  
  122.     char sortmode = 'A';
  123.     char addr = 0;
  124.     unsigned char point[15] = "";
  125.     unsigned char *prompt_pointer;
  126.     unsigned char prompt[250] = "";
  127.     unsigned char *comspec_pointer;
  128.     unsigned char comspec[100] = "";
  129.     unsigned char binkvar[50] = "";
  130.     unsigned char packer[100] = "";
  131.     unsigned char string[100] = "";
  132.     unsigned char out[100] = "";
  133.     unsigned char item[255] = "";
  134.     unsigned char eolarea[3] = "";
  135.     unsigned char zone[3] = "";
  136.     unsigned char boss[15] = "";
  137.     unsigned char address[25] = "";
  138.     unsigned char privatenet[10] = "";
  139.     unsigned char sysop[80] = "";
  140.     unsigned char zone_name[6] = "";
  141.     unsigned char selection[5] = "";
  142.     unsigned char hexname[15] = "";
  143.     unsigned char ARCmail = 1;
  144.     unsigned char statbox = 0;
  145.     unsigned char alt_address[9][25];
  146.     unsigned char dummyprompt[3] = "C>";
  147.     char writechange = 0;
  148.  
  149.     int value;
  150.     int addr_count = 0;
  151.  
  152.     char fileopen[60];
  153.  
  154.     /* ----------------------------------------------- */
  155.     /* binary config file loading                      */
  156.     /* ----------------------------------------------- */
  157.  
  158.     strcpy(w.ident, "AMAX Binary Config File Ver. 1.2\r\n\x1A");
  159.  
  160.     /*  binary file version stored in previous line, and below!!!  */
  161.  
  162.     stream = fopen("amax.cfg", "rb");
  163.     if (stream) {
  164.         fread(&w, sizeof(struct binfile), 1, stream);
  165.         if (! strstr(w.ident, "1.2")) {
  166.             output("AMAX:  Incompatible version of AMAX.CFG!  Delete and resave!\r\n\r\n");
  167.             fclose(stream);
  168.             exit(1);
  169.         }
  170.         strcpy(binkvar, w.binkvar);
  171.         direct = w.direct;
  172.         bypass = w.bypass;
  173.         strcpy(packer, w.packer);
  174.         courtesy = w.courtesy;
  175.         tearline = w.tearline;
  176.         sortmode = w.sortmode;
  177.         strcpy(selection, w.selection);
  178.         unarctype = w.unarctype;
  179.         displzero = w.displzero;
  180.         usenl = w.usenl;
  181.         ARCmail = w.ARCmail;
  182.         noselect = w.noselect;
  183.         usecolor = w.usecolor;
  184.         extkey = w.extkey;
  185.         fclose(stream);
  186.     }
  187.  
  188.     /* ----------------------------------------------- */
  189.     /* general junk                                    */
  190.     /* ----------------------------------------------- */
  191.  
  192.     /*  build value for prompt for exit to DOS  */
  193.  
  194.     prompt_pointer = (char *) getenv("PROMPT");
  195.     strcpy(prompt, "PROMPT=");
  196.     strcat(prompt, "Enter \"EXIT\" to return to AMAX.$_");
  197.     if (prompt_pointer) strcat(prompt, (char *) prompt_pointer);
  198.     else {
  199.         dummyprompt[0] = getdisk() + 65;
  200.         strcat(prompt, dummyprompt);
  201.     }
  202.     if (! strstr(prompt_pointer, "AMAX")) putenv(prompt);
  203.  
  204.     /*  get and store comspec  */
  205.  
  206.     comspec_pointer = (char *) getenv("COMSPEC");
  207.     if (comspec_pointer) strcpy (comspec, comspec_pointer);
  208.     else strcpy(comspec, "COMMAND");
  209.  
  210.     /*  read in version for display  */
  211.  
  212.     sprintf(string, "$1AMAX $4Version %s $0", VERSION);
  213.  
  214.     /*  get environment variable; if there use it, otherwise, curr dir  */
  215.  
  216.     binkley = (char *) getenv("BINKLEY");
  217.     strcpy(binkvar, binkley);
  218.     if (strlen(binkvar) != 0) {
  219.         if (binkvar[strlen(binkvar) - 1] != 0x5C) strcat(binkvar, "\\");
  220.         }
  221.     strcat(binkvar, "binkley.cfg");
  222.  
  223.  
  224.     /* ----------------------------------------------- */
  225.     /* command line argument parser                    */
  226.     /* ----------------------------------------------- */
  227.  
  228.     if (argc > 1) {
  229.         for (y = 1; y < argc; y++) {
  230.             if (argv[y][1] == 'c' || argv[y][1] == 'C') {
  231.                 for (x = 0; x < strlen(argv[y]); x++) {
  232.                     binkvar[x] = argv[y][x + 2];
  233.                 }
  234.                 binkvar[x] = NULL;
  235.             }
  236.             if (argv[y][1] == 'g' || argv[y][1] == 'G') {
  237.                 for (x = 0; x < strlen(argv[y]); x++) {
  238.                     series[x] = argv[y][x + 2];
  239.                 }
  240.                 series[x] = NULL;
  241.                 strupr(series);
  242.             }
  243.             if (argv[y][1] == 'p' || argv[y][1] == 'P') {
  244.                 for (x = 0; x < strlen(argv[y]); x++) {
  245.                     packer[x] = argv[y][x + 2];
  246.                 }
  247.                 packer[x] = NULL;
  248.             }
  249.             if (argv[y][1] == 'd' || argv[y][1] == 'D') {
  250.                 direct = 1;
  251.             }
  252.             if (argv[y][1] == 'k' || argv[y][1] == 'K') {
  253.                 selection[0] = argv[y][2];
  254.                 selection[1] = 0x00;
  255.             }
  256.             if (argv[y][1] == 'f' || argv[y][1] == 'F') {
  257.                 strcpy(out, &argv[y][2]);
  258.                 nlflags = atoi(out);
  259.                 if (nlflags == 0) nlflags = 3;
  260.             }
  261.             if (argv[y][1] == 'u' || argv[y][1] == 'U') {
  262.                 unarctype = argv[y][2];
  263.                 unarctype = unarctype - 48;
  264.                 if (unarctype < 0 || unarctype > 3) unarctype = 0;
  265.             }
  266.             if (argv[y][1] == 's' || argv[y][1] == 'S') {
  267.                 sortmode = toupper(argv[y][2]);
  268.             }
  269.             if (argv[y][1] == 'b' || argv[y][1] == 'B') {
  270.                 bypass = 1;
  271.             }
  272.             if (argv[y][1] == 't' || argv[y][1] == 'T') {
  273.                 tearline = 0;
  274.             }
  275.             if (argv[y][1] == 'i' || argv[y][1] == 'I') {
  276.                 noselect = 1;
  277.             }
  278.             if (argv[y][1] == 'e' || argv[y][1] == 'E') {
  279.                 extkey = 1;
  280.             }
  281.             if (argv[y][1] == 'l' || argv[y][1] == 'L') {
  282.                 usecolor = 0;
  283.             }
  284.             if (argv[y][1] == 'z' || argv[y][1] == 'Z') {
  285.                 displzero = 1;
  286.             }
  287.             if (argv[y][1] == 'm' || argv[y][1] == 'M') {
  288.                 courtesy = 1;
  289.             }
  290.             if (argv[y][1] == 'a' || argv[y][1] == 'A') {
  291.                 ARCmail = 0;
  292.             }
  293.             if (argv[y][1] == 'n' || argv[y][1] == 'N') {
  294.                 usenl = 0;
  295.             }
  296.             if (argv[y][1] == '?') {
  297.                 usecolor = 0;
  298.                 output("\r\n\r\n\r\n\r\n");
  299.                 output(string);
  300.                 output("\r\nCopyright (C) 1988, 89, 90, 92 Alan D. Bryant, All Rights Reserved\r\n\r\n");
  301.                 output("Optional command line parameters:\r\n\r\n");
  302.                 output("     $2-a  $0Exclude compressed mail from outbound listing.\r\n");
  303.                 output("     $2-b  $0Bypass initial start-up; use default address.\r\n");
  304.                 output("     $2-c  $0Designate alternate configuration filespec.\r\n");
  305.                 output("     $2-d  $0Use direct hardware screen writes. \r\n");
  306.                 output("     $2-e  $0Use extended keyboard calls.\r\n");
  307.                 output("     $2-f  $0Designate nodelist parts to use.\r\n");
  308.                 output("     $2-g  $0Specify grouping for batch command processing.\r\n");
  309.                 output("     $2-i  $0Ignore address selection (use primary).\r\n");
  310.                 output("     $2-k  $0Select 'Address' statement default.\r\n");
  311.                 output("     $2-l  $0Do not change color attributes (color off).\r\n");
  312.                 output("     $2-m  $0Create courtesy message for file requests.\r\n");
  313.                 output("     $2-n  $0Operate in 'nodelist-less' mode.\r\n");
  314.                 output("     $2-p  $0Designate packer filespec.\r\n");
  315.                 output("     $2-s  $0Outbound examine sort mode.\r\n");
  316.                 output("     $2-t  $0Omit tearline from messages.\r\n");
  317.                 output("     $2-u  $0Select ARCmail unpacking program.\r\n");
  318.                 output("     $2-z  $0Display zero-length compressed mail.\r\n");
  319.                 output("\r\nTo continue, ");
  320.                 pressanykey();
  321.                 output("\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n");
  322.                 output(string);
  323.                 output("\r\n\r\nCommand line example:\r\n\r\n");
  324.                 output("     amax -cc:\\opus\\mybink.cfg -d -b -ppack.bat -m -t -sa -a -k1 -u0 -z -n \r\n\r\n");
  325.                 output("NOTE:  All parameters can be used alone, in any combination, or not at all.\r\n\r\n");
  326.                 output("NOTE:  Direct screen writes require 100% IBM-PC compatible hardware.\r\n\r\n");
  327.                 output("\"IBM-PC\" is a trademark of Int'l. Business Machines Corp.\r\n\r\n\r\n\r\n");
  328.                 exit(0);
  329.             }
  330.         }
  331.     }
  332.  
  333. /*   This should remain out of line until a command line switch is present
  334.      for remote operation or something....
  335.  
  336.     if (! direct) {
  337.         printf("\x1B[6n");
  338.         if (! kbhit()) {
  339.             output("\r\nAMAX: ANSI.SYS must be loaded.  See DOS manual for details.\r\n\r\n");
  340.             exit(1);
  341.         }
  342.         while (kbhit()) agetch();
  343.     }
  344.  
  345. */
  346.  
  347.  
  348.  
  349.  
  350.     /*  we require DOS level 3  */
  351.  
  352.     if (_osmajor < 3) {
  353.         output("\r\nAMAX: DOS 3.x or higher required.\r\n\r\n");
  354.         exit(1);
  355.     }
  356.  
  357.     /*  start screen display  */
  358.     
  359.     cls();
  360.     output(string);
  361.     output("\r\nCopyright (C) 1988, 89, 90, 92 Alan D. Bryant, All Rights Reserved\r\n\r\n");
  362.     output("Refer to program documentation for complete licensing information.\r\n\r\n");
  363.     if (! bypass) {
  364.         output("          --------------------------------------------------------\r\n");
  365.         output("              $1WARNING! YOU USE AMAX ENTIRELY AT YOUR OWN RISK!$0\r\n");
  366.         output("          --------------------------------------------------------\r\n");
  367.         output("          The author will NOT be responsible for any loss of data, \r\n");
  368.         output("          loss of business,  loss of monies,  or any other damages \r\n");
  369.         output("          resulting from the use of, or inability to use AMAX.  By \r\n");
  370.         output("          operating  this  program,  you  accept  and  acknowledge \r\n");
  371.         output("          responsibility  IN FULL  for all  occurances  related to \r\n");
  372.         output("          your use  of this program.   In any  jurisdiction  where \r\n");
  373.         output("          such limitation of liability is restricted or forbidden, \r\n");
  374.         output("          this program IS NOT licensed for legal use.\r\n\r\n");
  375.         output("Press any key to continue... ");
  376.         agetch();
  377.     }
  378.     else {
  379.         output("One moment please...\r\n\r\n");
  380.         sleep(1);
  381.     }
  382.  
  383.     if (courtesy) display_warning();
  384.  
  385.  
  386.     bottomcls(2);
  387.     cursor(3, 0);
  388.  
  389.  
  390.  
  391.     /* ----------------------------------------------- */
  392.     /* configuration file handler                      */
  393.     /* ----------------------------------------------- */
  394.  
  395.     if (! bypass) output("AMAX: Finding configuration file...\r\n");
  396.  
  397.     /*  config file stuff */
  398.  
  399.     stream = fopen(binkvar, "rb");
  400.     if (stream == NULL) {
  401.         output("\r\nCannot find configuration file...refer to the docs for information!");
  402.         exit(1);
  403.         }
  404.     if (! bypass) output("AMAX: Reading configuration file...\r\n");
  405.  
  406.     /*  read config file  */
  407.  
  408.     while(! feof(stream)) {
  409.         fscanf(stream, "%s", item);
  410.         strupr(item);
  411.         if (! strncmp(item, ";", 1)) {
  412.             fgetln(item, sizeof(item), eolarea, stream);
  413.             continue;
  414.         }
  415.         if (! strcmp(item, "ADDRESS") || ! strcmp(item, "NODE")) {
  416.             if (! addr) fscanf(stream, "%s", address);
  417.             else {
  418.                 if (addr_count < 9) {
  419.                     fscanf(stream, "%s", alt_address[addr_count]);
  420.                     ++addr_count;
  421.                 }
  422.             }
  423.             addr = 1;
  424.             continue;
  425.         }
  426.         if (! strcmp(item, "PRIVATENET")) {
  427.             fscanf(stream, "%s", privatenet);
  428.             continue;
  429.         }
  430.         if (! strcmp(item, "HOLD") || ! strcmp(item, "OUTBOUND")) {
  431.             fscanf(stream, "%s", outbound);
  432.             if (! check_backslash(outbound)) {
  433.                 strcat(outbound, "\\");
  434.             }
  435.             strcpy(orig_outbound, outbound);
  436.             continue;
  437.         }
  438.         if (! strcmp(item, "NODELIST")) {
  439.             fscanf(stream, "%s", nodelist);
  440.             if (! check_backslash(nodelist)) {
  441.                 strcat(nodelist, "\\");
  442.             }
  443.             continue;
  444.         }
  445.         if (! strcmp(item, "ZONE")) {
  446.             fscanf(stream, "%s", zone);
  447.             continue;
  448.         }
  449.         if (! strcmp(item, "POINT")) {
  450.             if (! addr) fscanf(stream, "%s", point);
  451.             continue;
  452.         }
  453.         if (! strcmp(item, "BOSS")) {
  454.             if (! addr) fscanf(stream, "%s", boss);
  455.             continue;
  456.         }
  457.         if (! strcmp(item, "SYSOP") || ! strcmp(item, "ADMIN")) {
  458.             ch = 0x20;
  459.             while (ch == 0x20) {
  460.                 ch = getc(stream);
  461.             }
  462.             ungetc(ch, stream);
  463.             fgetln(sysop, sizeof(sysop), eolarea, stream);
  464.             continue;
  465.         }
  466.         if (! strcmp(item, "SYSTEM")) {
  467.             ch = 0x20;
  468.             while (ch == 0x20) {
  469.                 ch = getc(stream);
  470.             }
  471.             ungetc(ch, stream);
  472.             fgetln(sysname, sizeof(sysname), eolarea, stream);
  473.             continue;
  474.         }
  475.  
  476.  
  477.         fgetln(item, sizeof(item), eolarea, stream);
  478.     }
  479.  
  480.     fclose(stream);
  481.  
  482.  
  483.     /* ---------------------------------------- */
  484.     /* check for nodelist                       */
  485.     /* ---------------------------------------- */
  486.  
  487.     output("AMAX: Checking for nodelist files...\r\n");
  488.     strcpy(out, nodelist);
  489.     strcat(out, "NODEX.DAT");
  490.     done = findfirst(out, &ffblk, 0);
  491.     if (done) {
  492.         output("AMAX: Version 7 nodelist not found; operating in \"nodelistless\" mode\r\n");
  493.         usenl = 0;
  494.     }
  495.     else {
  496.         output("AMAX: Located what looks like a Version 7 nodelist...\r\n");
  497.  
  498.         if (cbinit(DEFAULT_BUFCNT, DEFAULT_BUFSIZE) != OK) {
  499.             output("AMAX: Btree system init failure\r\n");
  500.             exit(0);
  501.         }
  502.  
  503.  
  504.         nodexdata = fopen(out, "rb");
  505.         if (nodexdata == NULL) {
  506.             output("AMAX: Nodelist data file init failure\r\n");
  507.             exit(0);
  508.         }
  509.         strcpy(out, nodelist);
  510.         strcat(out, "NODEX.NDX");
  511.         nodexindex = cbopen(out, keycomp);
  512.         if (nodexindex == NULL) {
  513.             output("AMAX: Btree node index init failure\r\n");
  514.             exit(0);
  515.         }
  516.         strcpy(out, nodelist);
  517.         strcat(out, "SYSOP.NDX");
  518.         sysopindex = cbopen(out, DEFAULT_COMPARE);
  519.  
  520.     }
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.     /* ----------------------------------------------- */
  530.     /* address parsing                                 */
  531.     /* ----------------------------------------------- */
  532.  
  533.     /*  The general concept of the address parser is as follows.   */
  534.     /*  boss holds our network address (string form) with zone     */
  535.     /*  designator.  point holds our fake address, if any, with    */
  536.     /*  zone designation.  Neither boss nor point come out of the  */
  537.     /*  config file with a zone, so we add one later.  net is an   */
  538.     /*  int with our net number, node has our node number, and     */
  539.     /*  our_zone has out zone number.  If we come out the config   */
  540.     /*  file without boss or point, we use address and privatenet  */
  541.     /*  to construct them.                                         */
  542.  
  543.     /*  if we are using the 'address' verb  */
  544.  
  545.     if (addr) {
  546.         if (privatenet[0]) {
  547.  
  548.             /*  we're here with 'address' AND 'privatenet'  */
  549.             /*  copy privatenet to point, and add the point */
  550.             /*  node (fake) from address                    */
  551.  
  552.             strcpy(point, privatenet);
  553.             strcat(point, "/");
  554.  
  555.             /*  !!!!! this code is suspect  !!!!! */
  556.  
  557.             strcat(point, strchr(address, '.') + sizeof(char));
  558.  
  559.             /*  if no point address, then make point null  */
  560.  
  561.             if (strlen(point) == strlen(privatenet) + 1) point[0] = 0x00;
  562.  
  563.             /*  if point node number begins with 0, make point null  */
  564.  
  565.             if (point[strlen(privatenet) + 1] == '0') point[0] = 0x00;
  566.         }
  567.  
  568.         /*  we're here with 'address' and with or without 'privatenet'  */
  569.  
  570.         add_parse(address, &a, &b, &c, &d);
  571.  
  572.         if (a) sprintf(zone, "%d", a);
  573.         sprintf(boss, "%d/%d", b, c);
  574.  
  575.         arcnet = b;
  576.         arcnode = c;
  577.  
  578.         if (! privatenet[0]) strcpy(point, boss);
  579.  
  580.     }
  581.  
  582.     /*  we must have a zone from someplace  */
  583.  
  584.     if (! zone[0]) {
  585.         output("AMAX: Zone not specified by 'Zone' or 'Address' statements.  Aborting...\r\n\r\n");
  586.         exit(1);
  587.     }
  588.  
  589.     /*  if we do have a point, then put the zone into it  */
  590.  
  591.     if (strlen(point) > 0) {
  592.         strcpy(out, point);
  593.         strcpy(point, zone);
  594.         strcat(point, ":");
  595.         strcat(point, out);
  596.     }
  597.  
  598.     /*  set value for our_zone to our zone number  */
  599.  
  600.     our_zone = atoi(zone);
  601.  
  602.     /*  set current zone number to our zone number  */
  603.  
  604.     zone_num = our_zone;
  605.  
  606.     /*  place objects into system_name variable  */
  607.  
  608.     /*  find, extract, set values for node and net numbers  */
  609.  
  610.     if (strlen(point) > 0) {
  611.         strcpy(hexname, parseaddress(point));
  612.         node = extractnode(hexname);
  613.         net = extractnet(hexname);
  614.     }
  615.  
  616.     else {
  617.         strcpy(hexname, parseaddress(boss));
  618.         node = extractnode(hexname);
  619.         net = extractnet(hexname);
  620.     }
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.     /* ----------------------------------------------- */
  632.     /* alternate address handler                       */
  633.     /* ----------------------------------------------- */
  634.  
  635.     alias_zone = our_zone;
  636.  
  637.     if (addr_count > 0) {
  638.         if (! selection[0] && ! noselect) {
  639.             output("AMAX: Alternate addresses found...\r\n\r\n");
  640.             if (point[0]) {
  641.                 sprintf(out, "      1 - %s\r\n", point);
  642.                 output(out);
  643.             }
  644.             else {
  645.                 sprintf(out, "      1 - %d:%s\r\n", our_zone, boss);
  646.                 output(out);
  647.             }
  648.             for (x = 0; x < addr_count; x++) {
  649.                 sprintf(out, "      %d - %s\r\n", x + 2, alt_address[x]);
  650.                 output(out);
  651.             }
  652.             output("\r\n   Which address to use?  Select by line number...  ");
  653.             vpanel(2);
  654.             getln(selection, 2);
  655.         }
  656.         if (noselect) strcpy(selection, "1");
  657.         if (strlen(selection) == 0) x = 0;
  658.         x = atoi(selection);
  659.         if (x > 1 && x < addr_count + 2) {
  660.             add_parse(alt_address[x - 2], &a, &b, &c, &d);
  661.             net = b;
  662.             node = c;
  663.             alias_zone = a;
  664.             if (alias_zone == 0) alias_zone = our_zone;
  665.             newzone(alias_zone);
  666.         }
  667.     }
  668.  
  669.     /* ----------------------------------------------- */
  670.     /* menu handler                                    */
  671.     /* ----------------------------------------------- */
  672.  
  673.     ch = ' ';
  674.  
  675.     offset = 0;
  676.  
  677.     /* add address to sysname for origin line */
  678.  
  679.     sprintf(out, " (%d:%d/%d)", alias_zone, net, node);
  680.     strcat(sysname, out);
  681.  
  682.  
  683.     while (ch != 'q' && ch != 'Q') {
  684.         cls();
  685.         display_header(string, alias_zone);
  686.         cursor(offset + 2, 0);
  687.         if (statbox == 0) {
  688.             output("Main Menu   $3Dir: ");
  689.             strupr(outbound);
  690.             output(outbound);
  691.             cursor(2, 53);
  692.             output("$0Press \"-\" to Restart AMAX\r\n\r\n");
  693.             sprintf(out, "   $1V$0)iew        $0View/Edit Outbound Area for Zone %d\r\n", zone_num);
  694.             outputi(out);
  695.             outputi("   $1R$0)equest     $0Request Files from a System\r\n");
  696.             outputi("   $1S$0)end        $0Send a File to a System\r\n");
  697.             outputi("   $1E$0)nter       $0Enter a Message Directly to Outbound Area\r\n");
  698.             outputi("   $1L$0)ist Send   $0Send Message or File to Mailing List Members\r\n");
  699.             outputi("   $1P$0)oll        $0Build Attach to Poll a System\r\n");
  700.             outputi("   $1U$0)ndialable  $0Maintain Undialable Systems List\r\n");
  701.             if (usenl) outputi("   $1D$0)isplay     $0Display Nodelist Record\r\n");
  702.             outputi("   $1Z$0)one        $0Change Current Zone\r\n");
  703.             outputi("   $1J$0)ump        $0Jump to DOS Temporarily\r\n");
  704.             outputi("   $1A$0)lternate   $0Display Alternate Menu\r\n");
  705.             outputi("   $1O$0)ptions     $0Display Options Menu\r\n");
  706.             outputi("   $1Q$0)uit        $0Quit AMAX\r\n\r\n");
  707.         }
  708.         if (statbox == 1) {
  709.             outputi("Alternate Menu\r\n\r\n");
  710.             if (packer[0]) outputi("   $1P$0)acker      $0Invoke Packer Designated on Command Line\r\n");
  711.             outputi("   $1N$0)otes       $0Notes on AMAX\r\n");
  712.  
  713.             outputi("   $1W$0)rite       $0Change to ");
  714.             if (direct) outputi("DOS Screen Writes (Currently BIOS)");
  715.             else outputi("BIOS Screen Writes (Currently DOS) !!! DANGER !!!");
  716.             outputi("\r\n");
  717.  
  718.             outputi("   $1C$0)ourtesy    $0Turn File Request Courtesy Message ");
  719.             if (courtesy) outputi("OFF (Currently ON)");
  720.             else outputi("ON (Currently OFF)");
  721.             outputi("\r\n");
  722.  
  723.  
  724.             outputi("   $1T$0)earline    $0Turn Message Entry Tearline ");
  725.             if (tearline) outputi("OFF (Currently ON)");
  726.             else outputi("ON (Currently OFF)");
  727.             outputi("\r\n");
  728.  
  729.             outputi("   $1B$0)inary      $0Save Settings to Binary Config File \r\n");
  730.  
  731.             outputi("   $1R$0)eturn      $0Return to Main Menu\r\n\r\n");
  732.         }
  733.  
  734.         if (statbox == 2) {
  735.             outputi("Options Menu\r\n\r\n");
  736.  
  737.             outputi("   $1S$0)ort        $0Change Outbound Sort to ");
  738.             if (sortmode == 'A') outputi("TYPE (Currently ADDRESS)");
  739.             if (sortmode == 'T') outputi("FLAVOR (Currently TYPE)");
  740.             if (sortmode == 'F') outputi("NONE (Currently FLAVOR)");
  741.             if (sortmode == 1) outputi("ADDRESS (Currently NONE)");
  742.             outputi("\r\n");
  743.  
  744.  
  745.             outputi("   $1M$0)ail        $0Turn Compressed Mail Display ");
  746.             if (ARCmail) outputi("OFF (Currently ON)");
  747.             else outputi("ON (Currently OFF)");
  748.             outputi("\r\n");
  749.  
  750.             outputi("   $1Z$0)ero       $0 ");
  751.             if (displzero) outputi("$0DO NOT");
  752.             else outputi("$0DO");
  753.             outputi(" Display Zero-Length Compressed Mail ");
  754.             if (displzero) outputi("(Currently DO)\r\n");
  755.             else outputi("(Currently DO NOT)\r\n");
  756.  
  757.  
  758.             outputi("   $1R$0)eturn      $0Return to Main Menu\r\n\r\n");
  759.  
  760.         }
  761.  
  762.         outputi("Make a selection from the menu.  Your choice... ");
  763.  
  764.         disptime = 1;
  765.  
  766.         if (statbox == 0 && ! usenl) ch = menu_select("VRSELPUZJAOQ\x1B\r-");
  767.         if (statbox == 0 && usenl) ch = menu_select("VRSELPUDZJAOQ\x1B\r-");
  768.         if (statbox == 1 && packer[0]) ch = menu_select("PNWCTRB\x1B\r");
  769.         if (statbox == 1 && ! packer[0]) ch = menu_select("NWCTRB\x1B\r");
  770.         if (statbox == 2) ch = menu_select("SMRZ\x1B\r");
  771.  
  772.         disptime = 0;
  773.         cursor(19, 0);
  774.  
  775.         switch (ch) {
  776.             case '\r':
  777.             case 0x1B:
  778.                 if (statbox == 0) ch = 'Q';
  779.                 else statbox = 0;
  780.                 break;
  781.             case '-':
  782.                 execl(argv[0], argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
  783.                 output("Error reinvoking AMAX.  ");
  784.                 output(reterror());
  785.                 output("  Press any key...  ");
  786.                 agetch();
  787.                 break;
  788.             case 'J':
  789.                 clearline();
  790.                 output("Jumping to DOS.  Type \"EXIT\" at the DOS prompt to return to AMAX.\r\n\r\n");
  791.                 system(comspec);
  792.                 break;
  793.             case 'R':
  794.                 if (statbox == 0) {
  795.                     freq(courtesy, net, node, sysop);
  796.                     break;
  797.                 }
  798.                 else {
  799.                     statbox = 0;
  800.                     break;
  801.                 }
  802.             case 'V':
  803.                 ch = 0x01;
  804.                 while (ch) {
  805.                     ch = chek(arcnet, arcnode, ARCmail, outbound, sortmode, ch);
  806.                 }
  807.                 break;
  808.             case 'U':
  809.                 clr();
  810.                 break;
  811.             case 'C':
  812.                 if (courtesy == 0) courtesy = 1;
  813.                 else courtesy = 0;
  814.                 if (courtesy) display_warning();
  815.                 break;
  816.             case 'D':
  817.                 display_nl_info();
  818.                 break;
  819.             case 'A':
  820.                 statbox = 1;
  821.                 break;
  822.             case 'O':
  823.                 statbox = 2;
  824.                 break;
  825.             case 'S':
  826.                 if (statbox == 0) {
  827.                     file(NULL, NULL);
  828.                     break;
  829.                 }
  830.                 if (statbox == 2) {
  831.                     switch (sortmode) {
  832.                         case 1:
  833.                             sortmode = 'A';
  834.                             break;
  835.                         case 'A':
  836.                             sortmode = 'T';
  837.                             break;
  838.                         case 'T':
  839.                             sortmode = 'F';
  840.                             break;
  841.                         case 'F':
  842.                             sortmode = 1;
  843.                             break;
  844.                     }
  845.                 }
  846.                 break;
  847.             case 'T':
  848.                 if (tearline == 0) tearline = 1;
  849.                 else tearline = 0;
  850.                 break;
  851.             case 'W':
  852.                 if (direct == 0) direct = 1;
  853.                 else direct = 0;
  854.                 writechange = 1;
  855.                 break;
  856.             case 'M':
  857.                 if (ARCmail == 0) ARCmail = 1;
  858.                 else ARCmail = 0;
  859.                 break;
  860.             case 'Z':
  861.                 if (statbox == 0) {
  862.                     clearline();
  863.                     output("Input new zone number:  ");
  864.                     zone_name[0] = 0x00;
  865.                     vpanel(4);
  866.                     getln(zone_name, 4);
  867.                     if (strlen(zone_name) == 0) break;
  868.                     newzone(atoi(zone_name));
  869.                     break;
  870.                 }
  871.                 if (statbox == 2) {
  872.                     if (displzero == 0) displzero = 1;
  873.                     else displzero = 0;
  874.                     break;
  875.                 }
  876.             case 'E':
  877.                 qmsg(net, node, sysop, 0, NULL, NULL);
  878.                 break;
  879.             case 'B':
  880.                 stream = fopen("amax.cfg", "wb");
  881.                 if (stream) {
  882.                     strcpy(w.binkvar, binkvar);
  883.                     w.direct = direct;
  884.                     w.bypass = bypass;
  885.                     strcpy(w.packer, packer);
  886.                     w.courtesy = courtesy;
  887.                     w.tearline = tearline;
  888.                     w.sortmode = sortmode;
  889.                     strcpy(w.selection, selection);
  890.                     w.unarctype = unarctype;
  891.                     w.displzero = displzero;
  892.                     w.usenl = usenl;
  893.                     w.ARCmail = ARCmail;
  894.                     w.noselect = noselect;
  895.                     w.usecolor = usecolor;
  896.                     w.extkey = extkey;
  897.                     fwrite(&w, sizeof(struct binfile), 1, stream);
  898.                     fclose(stream);
  899.                 }
  900.                 break;
  901.             case 'L':
  902.                 bomb(net, node, sysop);
  903.                 break;
  904.             case 'P':
  905.                 if (! statbox) {
  906.                     poll();
  907.                     break;
  908.                 }
  909.                 else {
  910.                     clearline();
  911.                     if (strlen(packer) == 0) {
  912.                         output("No packer specified on command line...");
  913.                         pressanykey();
  914.                     }
  915.                     else {
  916.                         sprintf(out, "Spawning to %s...", packer);
  917.                         output(out);
  918.                         system(packer);
  919.                         output("\r\n\r\nPacker has returned to AMAX...one moment, please...");
  920.                         sleep(2);
  921.                         cls();
  922.                         output(string);
  923.                         cursor(offset + 2, 0);
  924.                     }
  925.                     break;
  926.                 }
  927.             case 'N':
  928.                 cursor(0, 50);
  929.                 output("                             ");
  930.  
  931.                 minicls();
  932.                 cursor(2, 0);
  933.  
  934. /*                output("AMAX has the distinction of being the first program to directly support\r\n");
  935.                 output("BinkleyTerm by way of its control file.  AMAX endeavors to continue that\r\n");
  936.                 output("tradition with periodic updating reflecting the current trends, technology\r\n");
  937.                 output("and features of BinkleyTerm itself.\r\n\r\n");  */
  938.  
  939.  
  940.                 output("AMAX is a copyrighted computer software program.  You are licensed to use the\r\n");
  941.                 output("program under certain conditions.  These conditions are contained in the\r\n");
  942.                 output("documentation that accompanies the program; please refer to the documentation\r\n");
  943.                 output("for this licensing information, as well as complete operating instructions.\r\n\r\n");
  944.                 output("AMAX, Copyright (C) 1988, 89, 90, 92 Alan D. Bryant, All Rights Reserved.\r\n\r\n");
  945.                 output("\"AMAX\" and \"PacketView\" are trademarks of Alan D. Bryant.\r\n\r\n");
  946.                 output("PLEASE REFER TO THE DOCUMENTATION FOR IMPORTANT PRODUCT SUPPORT INFORMATION!");
  947.                 agetch();
  948.                 minicls();
  949.                 cursor(2, 0);
  950.                 output("Send inquiries, comments and suggestions regarding the AMAX program\r\n");
  951.                 output("to:\r\n\r\n");
  952.                 output("     AMAX\r\n");
  953.                 output("     c/o Alan D. Bryant   \r\n");
  954.                 output("     P. O. Box 101612\r\n");
  955.                 output("     Denver, CO  80250\r\n\r\n");
  956.                 output("You may also direct them to FidoNet 1:104/36.0 if you prefer.\r\n\r\n");
  957.                 output("Refer to the documentation for policies and procedures regarding your\r\n");
  958.                 output("inquiries, comments and suggestions.\r\n");
  959.                 agetch();
  960.                 break;
  961.             }
  962.         /*  minicls();  */
  963.         }
  964.     if (! direct || writechange) printf("\x1B[0m\x1B[0H\x1B[2J");
  965.     if (direct || writechange) {
  966.         if (usecolor) textattr(7);
  967.         clrscr();
  968.     }
  969.     output("\r\nThanks for using AMAX!\r\n\r\n");
  970.     output("If you enjoy and have obtained benefit from using AMAX, please consider\r\n");
  971.     output("sending a donation to your local Humane Society chapter.\r\n\r\n");
  972.     output("If you're considering the addition of a pet to your family, please\r\n");
  973.     output("contact your local Humane Society chapter first, and help prevent\r\n");
  974.     output("the daily destruction of thousands of unwanted animals.\r\n\r\n");
  975.     output("PLEASE!  Have your pet spayed or neutered.\r\n\r\n");
  976.     output("Thank you for your support!\r\n\r\n");
  977.     return 0;
  978. }
  979.  
  980.  
  981. void display_header(char *string, int alias)
  982. {
  983.     char displ[100];
  984.  
  985.     sprintf(displ, "$1%s    $3Using %d:%d/%d $0", string, alias, net, node);
  986.     output(displ);
  987. }
  988.  
  989.  
  990.  
  991. void display_warning(void)
  992. {
  993.     minicls();
  994.     cursor(3, 0);
  995.  
  996.     output("$1WARNING!!!  $0You have enabled the courtesy message function which will\r\n");
  997.     output("force the sending of a message for every file request you generate.\r\n");
  998.     output("some Sysops feel that this message is a$2 courtesy$0, letting them know\r\n");
  999.     output("which files are being requested and how often.  Others are $2extremely\r\n");
  1000.     output("annoyed$0 by such messages, and feel that they unnecessarily \"trash up\"\r\n");
  1001.     output("their NetMail message area.\r\n\r\n");
  1002.     output("$1USE THIS FEATURE AT YOUR OWN RISK, AND WITH THE UNDERSTANDING THAT SOME\r\n");
  1003.     output("PEOPLE MAY BECOME ANNOYED BY YOUR USE OF IT.$0\r\n\r\n");
  1004.     output("Press any key to continue...");
  1005.     agetch();
  1006. }
  1007.  
  1008.  
  1009. int keycomp(int *a, int lena, int *b, int lenb)
  1010. {
  1011.     if (a[0] < b[0]) return LESS;
  1012.     if (a[0] > b[0]) return GREATER;
  1013.  
  1014.     if (a[1] < b[1]) return LESS;
  1015.     if (a[1] > b[1]) return GREATER;
  1016.  
  1017.     if (a[2] < b[2]) return LESS;
  1018.     if (a[2] > b[2]) return GREATER;
  1019.  
  1020.     return EQUAL;
  1021.  
  1022. }
  1023.  
  1024.