home *** CD-ROM | disk | FTP | other *** search
/ synchro.net / synchro.net.tar / synchro.net / modem.madness / SMMNETML / AMAX_230.ZIP / SOURCES.ZIP / AMAXOUT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-15  |  22.1 KB  |  839 lines

  1. /*---------------------------------------------------------------------------*/
  2. /*                                                                           */
  3. /* Module Name:   AMAXOUT.C                                                  */
  4. /* Program Name:  AMAX                                                       */
  5. /* Revision:      2.xx                                                       */
  6. /* Purpose:       Auxiliary Routines for Outbound Checker 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 <ctype.h>
  28. #include "amax.h"
  29.  
  30.  
  31. extern unsigned int entries;
  32.  
  33.  
  34. char *lookinfo(int, int, char, char *);
  35. char moreinfo(struct list_style  *, int, int);
  36. int select_entry(struct list_style  *, int, int);
  37. int list_contents(FILE *, int, char);
  38. void show_packet(FILE *);
  39. void fgetstring(FILE *, char *);
  40.  
  41. // Returns name and location on successful find, or "Unknown System"
  42. // on failure.  Also displays complete information if mode is true.
  43. // (mode is true only if display nodelist record contents)
  44. // This function is also where editing of the nodelist display is
  45. // implemented.  instring is passed when doing a nodelist record
  46. // edit and the sysop name is already known so it doesn't have to
  47. // do a lookup.  Since the sysop name is part of V7 nodelists, it's
  48. // a moot point now.  It's not been removed because I didn't want
  49. // to make the corrections in all calling routines.
  50.  
  51.  
  52.  
  53. char *lookinfo(int looknet, int looknode, char mode, char *instring)
  54. {
  55.     unsigned int x;
  56.     unsigned int y;
  57.     unsigned int a;
  58.     unsigned int b;
  59.     unsigned int c;
  60.     unsigned long seekval;
  61.     int counter;
  62.  
  63.     int address[3];
  64.     char table[50] = " EANROSTILCHBDMUGPKYWFVJXZQ-'0123456789";
  65.     char temp[100];
  66.     char input[100];
  67.     char disp[100];
  68.     char retstring[100];
  69.     char ch;
  70.  
  71.     FILE *stream;
  72.  
  73.     struct v7fixed {
  74.         unsigned int zone;
  75.         unsigned int net;
  76.         unsigned int node;
  77.         unsigned int hubnode;
  78.         unsigned int callcost;
  79.         unsigned int msgfee;
  80.         unsigned int nodeflags;
  81.         unsigned char modemtype;
  82.         unsigned char phonelen;
  83.         unsigned char passwordlen;
  84.         unsigned char bnamelen;
  85.         unsigned char snamelen;
  86.         unsigned char cnamelen;
  87.         unsigned char packlen;
  88.         unsigned char baudrate;
  89.     } n;
  90.  
  91.  
  92.  
  93.     address[0] = zone_num;
  94.     address[1] = looknet;
  95.     address[2] = looknode;
  96.  
  97.  
  98.     status = cbfind(nodexindex, address, sizeof(address), &item);
  99.  
  100.     if (status == FOUND) {
  101.         fseek(nodexdata, item, SEEK_SET);
  102.         fread(&n, sizeof(n), 1, nodexdata);
  103.     }
  104.     else {
  105.         return "Unknown System";
  106.     }
  107.  
  108.     for (x = 0; x < n.phonelen; x++) {
  109.         ch = fgetc(nodexdata);
  110.         temp[x] = ch;
  111.     }
  112.     temp[x] = 0x00;
  113.  
  114.     strcpy(retstring, "");
  115.  
  116.     if (nlflags & 8) {
  117.         strcat(retstring, temp);
  118.         strcat(retstring, ", ");
  119.     }
  120.  
  121.  
  122.     for (x = 0; x < n.passwordlen; x++) {
  123.         ch = fgetc(nodexdata);
  124.         temp[x] = ch;
  125.     }
  126.     temp[x] = 0x00;
  127.  
  128.     if (nlflags & 16) {
  129.         strcat(retstring, temp);
  130.         strcat(retstring, ", ");
  131.     }
  132.  
  133.  
  134.     for (x = 0; x < n.packlen; x++) {
  135.         a = getw(nodexdata);
  136.         b = a / 40;
  137.         c = a - (b * 40);
  138.         temp[(x * 3) + 2] = table[c];
  139.  
  140.         a = b;
  141.         b = a / 40;
  142.         c = a - (b * 40);
  143.         temp[(x * 3) + 1] = table[c];
  144.  
  145.         a = b;
  146.         b = a / 40;
  147.         c = a - (b * 40);
  148.         temp[(x * 3) + 0] = table[c];
  149.     }
  150.     temp[n.snamelen + n.cnamelen + n.bnamelen] = 0x00;
  151.  
  152.     for (x = 0; x < n.bnamelen; x++) {
  153.         input[x] = temp[x];
  154.     }
  155.     input[x] = 0x00;
  156.  
  157.     if (nlflags & 1) {
  158.         strcat(retstring, input);
  159.         strcat(retstring, ", ");
  160.     }
  161.  
  162.     for (x = 0; x < n.snamelen; x++) {
  163.         input[x] = temp[x + n.bnamelen];
  164.     }
  165.     input[x] = 0x00;
  166.  
  167.     if (nlflags & 4) {
  168.         strcat(retstring, input);
  169.         strcat(retstring, ", ");
  170.     }
  171.  
  172.  
  173.     for (x = 0; x < n.cnamelen; x++) {
  174.         input[x] = temp[x + n.bnamelen + n.snamelen];
  175.     }
  176.     input[x] = 0x00;
  177.  
  178.     if (nlflags & 2) {
  179.         strcat(retstring, input);
  180.     }
  181.     return retstring;
  182. }
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189. #include <io.h>
  190.  
  191. char moreinfo(struct list_style *list, int max, int a)
  192. {
  193.     FILE *stream;
  194.     FILE *stream2;
  195.  
  196.     int number = 0;  /* entry number for moreinfo  */
  197.     int x = 0;
  198.     int entry_num;
  199.     int file_entries;
  200.  
  201.     long length;
  202.  
  203. /*    char entry[5] = "";   */
  204.  
  205.     char entry_sel[5] = "";
  206.     char open[150] = "";
  207.     char out[100] = "";
  208. /*
  209.     char info[60] = "";
  210.     char type[15] = "";
  211.     char flav[20] = "";
  212. */
  213.     char ch = 0x00;
  214.  
  215.     struct list_style *p;
  216.     struct ftime g;
  217.  
  218.     p = list;
  219.  
  220. /*
  221.  
  222.     bottomcls(22);
  223.     cursor(22, 0);
  224.     output("Which entry number? ");
  225.     vpanel(4);
  226.     getln(entry, 4);
  227.     for (x = 0; x < strlen(entry); x++) {
  228.         if (entry[x] < 48 || entry[x] > 57) {
  229.             output("Invalid entry...");
  230.             pressanykey();
  231.             return 0;
  232.             }
  233.         }
  234.  
  235.     number = atoi(entry);
  236.  
  237.     if (number < 1 || number > max) {
  238.         output("Entry out of range...");
  239.         pressanykey();
  240.         return 0;
  241.         }
  242.  
  243. */
  244.  
  245.     number = select_entry(list, max, a);
  246.     if (number == -1) return 0;
  247.     ++number;
  248.  
  249. /*
  250.  
  251.     bottomcls(4);
  252.     cursor(4, 0);
  253.  
  254. */
  255.  
  256.     p = p + (number - 1);
  257.  
  258.  
  259. /*
  260.  
  261.     strcpy(info, lookinfo(p -> net, p -> node, 0));
  262.     strcpy(type, return_type_file(p -> type_file));
  263.     strcpy(flav, return_type_flavor(p -> type_flavor));
  264.  
  265.     sprintf(out, "%03d %5d/%-5d %-34.34s %-10s %-16s\r\n\r\n", number, p -> net,
  266.             p -> node, info, type, flav);
  267.  
  268.     output(out);
  269.  
  270. */
  271.  
  272.     strcpy(open, outbound);
  273.     strcat(open, p -> filename);
  274.  
  275.     stream = fopen(open, "rb");
  276.     if (stream == NULL) {
  277.         output("Error extracting information about this entry...");
  278.         pressanykey();
  279.         return 0;
  280.     }
  281.  
  282.     getftime(fileno(stream), &g);
  283.     length = filelength(fileno(stream));
  284.  
  285.     fclose(stream);
  286.  
  287.  
  288.  
  289.     // ---------------------------------------------------
  290.  
  291.     x = nlflags;
  292.     nlflags = 15;
  293.     sprintf(out, "To:    %s\r\n", lookinfo(p -> net, p -> node, 0, ""));
  294.     output(out);
  295.     nlflags = x;
  296.  
  297.  
  298.  
  299.     strupr(p -> filename);
  300.  
  301.     sprintf(out, "Name:  %s  Date: %02d/%02d/%02d  Time: %02d:%02d  Length: %ld\r\n\r\n", p -> filename, g.ft_month, g.ft_day, g.ft_year + 80, g.ft_hour,
  302.         g.ft_min, length);
  303.     output(out);
  304.  
  305.  
  306.     if (p -> type_file == 2 || p -> type_file == 3 || p -> type_file == 6 || p -> type_file == 8) {
  307.         stream = fopen(open, "rb");
  308.         if (stream != NULL) {
  309.             file_entries = list_contents(stream, 8, p -> type_file);
  310.             fclose(stream);
  311.         }
  312.     }
  313.  
  314.     if (p -> type_file == 2 || p -> type_file == 3 || p -> type_file == 8) {
  315.         ch = 0x00;
  316.         while (ch != 'C' && ch != '\r') {
  317.             output("\r\n");
  318.             if (file_entries > 2) output("$1D$0)elete an Entry from File  ");
  319.             output("$1C$0)ontinue  ");
  320.             if (file_entries > 2) ch = menu_select("DC\r\x1B");
  321.             else ch = menu_select("C\r\x1B");
  322.             if (ch == 0x1B) return 0;
  323.             if (ch == 'D') {
  324.                 clearline();
  325.                 output("Input entry number:  ");
  326.                 entry_sel[0] = 0x00;
  327.                 vpanel(3);
  328.                 getln(entry_sel, 3);
  329.                 entry_num = atoi(entry_sel);
  330.                 if (entry_num > 0 && entry_num < file_entries) delete_file_ref(entry_num, p -> filename);
  331.                 else {
  332.                     clearline();
  333.                     output("No such entry...please wait...");
  334.                     sleep(1);
  335.                     clearline();
  336.                 }
  337.                 stream = fopen(open, "rb");
  338.                 if (stream != NULL) {
  339.                     file_entries = list_contents(stream, 8, p -> type_file);
  340.                     fclose(stream);
  341.                 }
  342.             }
  343.         }
  344.     }
  345.    
  346.     if (p -> type_file == 4) {
  347.         stream = fopen(open, "rb");
  348.         if (stream != NULL) {
  349.             sprintf(out, "Call Progress Data:  %d Call Attempts  %c Bad Connects\r\n",
  350.                     getw(stream), p -> filename[11]);
  351.             output(out);
  352.             fclose(stream);
  353.         }
  354.     }
  355.  
  356.     if (p -> type_file == 5 || p -> type_file == 7 || p -> type_file == 9 || p -> type_file == 0x0A) {
  357.         output("Unpack this compressed mail packet for manual handling?  ");
  358.         ch = menu_select("YN\r");
  359.         if (ch == 'Y') {
  360.             arcmail(open, p -> net, p -> node);
  361.             cls();
  362.             output("$1AMAX $4View/Edit Outbound Area$0\r\n\r\n");
  363.             print_header();
  364.             return 1;
  365.         }
  366.     }
  367.  
  368.     if (p -> type_file == 4 || p -> type_file == 6 || p -> type_file == 7) {
  369.         output("\r\nPress any key to return to listing... ");
  370.         agetch();
  371.     }
  372.  
  373.     if (p -> type_file == 1) {
  374.         output("Invoke PacketView Mode?  $1Y$0)es  $1N$0)o  ");
  375.         ch = 0x00;
  376.         while (ch != 'Y' && ch != 'N' && ch != 0x1B && ch != 0x0D) {
  377.             ch = agetch();
  378.             if (ch > 90) ch -= 32;
  379.         }
  380.         if (ch == 'Y' || ch == 0x0D) {
  381.             cursor(8, 0);
  382.             clearline();
  383.             stream = fopen(open, "rb");
  384.             if (stream != NULL) {
  385.                 show_packet(stream);
  386.                 fclose(stream);
  387.             }
  388.         }
  389.  
  390.         cls();
  391.         output("$1AMAX $4View/Edit Outbound Area$0\r\n\r\n");
  392.         print_header();
  393.     }
  394.     return 0;
  395. }
  396.  
  397.  
  398.  
  399.  
  400. int select_entry(struct list_style  *list, int max, int current)
  401. {
  402.     extern char extkey;
  403.  
  404.     int x = 0;
  405.     int number = 0;
  406.     int counter = 1;
  407.  
  408.     char ch = 0;
  409.     char entry[5] = "";
  410.     char info[60] = "";
  411.     char out[100] = "";
  412.     char flav[15] = "";
  413.     char type[15] = "";
  414.     char address[20] = "";
  415.  
  416.     struct list_style  *p;
  417.  
  418.     p = list;
  419.  
  420.     bottomcls(22);
  421.     cursor(22, 0);
  422.     output("Which entry number? ");
  423.     ch = 0x00;
  424.  
  425.     while (! ch) ch = agetch();
  426.  
  427.     if (ch == 0x18 || ch == 0x19) {
  428.         ch = 0x00;
  429.         while (! ch) {
  430.             cursor(counter + 2, 3);
  431.             output(" ");
  432.             cursor(counter + 4, 3);
  433.             output(" ");
  434.             cursor(counter + 3, 3);
  435.             output("$5*$0");
  436.             ch = agetch();
  437.             if (ch == 0x18) {    /* up */
  438.                 if (counter > 1) --counter;
  439.             }
  440.             if (ch == 0x19) {    /* down */
  441.                 if ((counter < 16) && (counter + current < max)) ++counter;
  442.             }
  443.             if (ch == '\r') {
  444.                 number = counter + current;
  445.                 break;
  446.             }
  447.             ch = 0x00;
  448.         }
  449.     }
  450.  
  451.     else {
  452.  
  453.         if (extkey) {
  454.             entry[0] = ch;
  455.             entry[1] = 0x00;
  456.         }
  457.  
  458.         else ungetch(ch);
  459.  
  460.         vpanel(4);
  461.         getln(entry, 4);
  462.  
  463.         for (x = 0; x < strlen(entry); x++) {
  464.             if (entry[x] < 48 || entry[x] > 57) {
  465.                 output("Invalid entry...");
  466.                 pressanykey();
  467.                 return -1;
  468.                 }
  469.             }
  470.         number = atoi(entry);
  471.     }
  472.  
  473.     if (number < 1 || number > max) {
  474.         output("Entry out of range...");
  475.         pressanykey();
  476.         return -1;
  477.         }
  478.  
  479.     bottomcls(4);
  480.     cursor(4, 0);
  481.  
  482.     p = p + (number - 1);
  483.  
  484.     strcpy(info, lookinfo(p -> net, p -> node, 0, NULL));
  485.     strcpy(type, return_type_file(p -> type_file));
  486.     strcpy(flav, return_type_flavor(p -> type_flavor));
  487.  
  488.     sprintf(address, "%d:%d/%d", zone_num, p -> net, p -> node);
  489.  
  490.     if (usenl) sprintf(out, "%03d %-13s %-32.32s %-10s %-14.14s\r\n\r\n", number, address, info, type, flav);
  491.     else sprintf(out, "%03d %-13s %-10s %-14.14s\r\n\r\n", number, address, type, flav);
  492.  
  493.     output(out);
  494.  
  495.     return number - 1;
  496.  
  497. }
  498.  
  499.  
  500.  
  501. int list_contents(FILE *stream, int start_pos, char type_file)
  502. {
  503.  
  504.     FILE *stream2;
  505.     char line[100] = "";
  506.     char out[100] = "";
  507.     char eolarea[3] = "";
  508.     int counter = 0;
  509.     int return_val = 1;
  510.  
  511.     struct ftime g;
  512.     long length;
  513.     unsigned long cum = 0;
  514.  
  515.     bottomcls(start_pos);
  516.     cursor(start_pos, 0);
  517.     output("Contents:\r\n\r\n");
  518.     while(! feof(stream)) {
  519.         fgetln(line, 70, eolarea, stream);
  520.         strupr(line);
  521.         if (strlen(line) > 1) {
  522.             if (counter > 9) {
  523.                 output("\r\nPress any key to continue... ");
  524.                 agetch();
  525.                 bottomcls(start_pos + 2);
  526.                 cursor(start_pos + 2, 0);
  527.                 counter = 0;
  528.             }
  529.             ++counter;
  530.             sprintf(out, "   %d - %s  ", return_val, line);
  531.             ++return_val;
  532.             output(out);
  533.             if (type_file == 2) {
  534.                 if (isalpha(line[0])) {
  535.                     stream2 = fopen(line, "rb");
  536.                 }
  537.                 else {
  538.                     stream2 = fopen(line + 1, "rb");
  539.                 }
  540.                 if (stream2 != NULL) {
  541.                     getftime(fileno(stream2), &g);
  542.                     length = filelength(fileno(stream2));
  543.                     sprintf(out, "%02d/%02d/%02d  %ld bytes", g.ft_month,
  544.                         g.ft_day, g.ft_year + 80, length);
  545.                     cum = cum + length;
  546.                     output(out);
  547.                     fclose(stream2);
  548.                 }
  549.                 else output("???");
  550.             }
  551.             output("\r\n");
  552.         }
  553.     }
  554.     sprintf(out, "\r\nTotal of %ld bytes to be sent.\r\n", cum);
  555.     output(out);
  556.     return return_val;
  557. }
  558.  
  559.  
  560. void show_packet(FILE *stream)
  561. {
  562.     unsigned char out[100];
  563.     unsigned char ch;
  564.     unsigned char input;
  565.     int counter = 0;
  566.     int char_count = 0;
  567.     int success;
  568.     int number = 0;
  569.  
  570.     struct packet_header {
  571.         int origNode;
  572.         int destNode;
  573.         int year;
  574.         int month;
  575.         int day;
  576.         int hour;
  577.         int minute;
  578.         int second;
  579.         int baud;
  580.         int type;
  581.         int origNet;
  582.         int destNet;
  583.         char ProductCode;
  584.         char fill[33];
  585.     } header;
  586.  
  587.     struct packed_message {
  588.         int type;
  589.         int origNode;
  590.         int destNode;
  591.         int origNet;
  592.         int destNet;
  593.         int Attribute;
  594.         int cost;
  595.         char dateTime[20];
  596.     } message;
  597.  
  598.     char toUserName[37];
  599.     char fromUserName[37];
  600.     char subject[73];
  601.  
  602.     cls();
  603.     output("$1AMAX $4PacketView $0");
  604.     fread(&header, sizeof(header), 1, stream);
  605.     output("         This Packet Built by ");
  606.     switch (header.ProductCode) {
  607.         case 0x00:
  608.             output("Fido");
  609.             break;
  610.         case 0x01:
  611.             output("Rover/ConfMail");
  612.             break;
  613.         case 0x05:
  614.             output("Opus/oMMM");
  615.             break;
  616.         case 0x06:
  617.             output("Dutchie");
  618.             break;
  619.         case 0x09:
  620.             output("Hoster");
  621.             break;
  622.         case 0x0C:
  623.             output("FrontDoor");
  624.             break;
  625.         case 0x11:
  626.             output("MailMan");
  627.             break;
  628.         case 0x12:
  629.             output("OOPS");
  630.             break;
  631.         case 0x14:
  632.             output("BGMail");
  633.             break;
  634.         case 0x15:
  635.             output("Crossbow");
  636.             break;
  637.         case 0x19:
  638.             output("BinkScan");
  639.             break;
  640.         case 0x1A:
  641.             output("D'Bridge");
  642.             break;
  643.         case 0x1B:
  644.             output("BinkleyTerm");
  645.             break;
  646.         case 0x1C:
  647.             output("Yankee");
  648.             break;
  649.         case 0x1D:
  650.             output("FGet/Send");
  651.             break;
  652.         case 0x1F:
  653.             output("Polar Bear");
  654.             break;
  655.         case 0x21:
  656.             output("STARgate");
  657.             break;
  658.         case 0x22:
  659.             output("TMail");
  660.             break;
  661.         case 0x23:
  662.             output("TCOMMail");
  663.             break;
  664.         case 0x25:
  665.             output("RBBSMail");
  666.             break;
  667.         case 0x28:
  668.             output("Majik");
  669.             break;
  670.         case 0x29:
  671.             output("Qmail");
  672.             break;
  673.         case 0x2B:
  674.             output("Aurora 3");
  675.             break;
  676.         case 0x2C:
  677.             output("FourDog");
  678.             break;
  679.         case 0x2D:
  680.             output("MSG-PACK");
  681.             break;
  682.         case 0x2E:
  683.             output("AMAX/Aware");
  684.             break;
  685.         case 0x2F:
  686.             output("Domain");
  687.             break;
  688.         case 0x30:
  689.             output("LESRobot");
  690.             break;
  691.         case 0x31:
  692.             output("Rose");
  693.             break;
  694.         case 0x35:
  695.             output("Zmail");
  696.             break;
  697.         case 0x36:
  698.             output("QuickBBS");
  699.             break;
  700.         case 0x37:
  701.             output("BOOM");
  702.             break;
  703.         case 0x3B:
  704.             output("NetGate");
  705.             break;
  706.         case 0x3C:
  707.             output("Odie");
  708.             break;
  709.         case 0x3D:
  710.             output("Quick Gimme");
  711.             break;
  712.         case 0x3E:
  713.             output("dbLink");
  714.             break;
  715.         case 0x3F:
  716.             output("FD/TosScan");
  717.             break;
  718.         case 0x40:
  719.             output("Beagle");
  720.             break;
  721.         case 0x41:
  722.             output("Igor");
  723.             break;
  724.         case 0x42:
  725.             output("TIMS");
  726.             break;
  727.         case 0x43:
  728.             output("Isis");
  729.             break;
  730.         case 0x44:
  731.             output("AirMail");
  732.             break;
  733.         case 0x45:
  734.             output("XRS");
  735.             break;
  736.         default:
  737.             output("Unknown Packer");
  738.             break;
  739.     }
  740.  
  741.  
  742.  
  743.     cursor(2, 0);
  744.  
  745.     while (! feof(stream)) {
  746.         ++number;
  747.         bottomcls(2);
  748.         cursor(2, 0);
  749.         success = fread(&message, sizeof(message) - 20, 1, stream);
  750.         if (success != 1) return;
  751.         fgetstring(stream, message.dateTime);
  752.         fgetstring(stream, toUserName);
  753.         fgetstring(stream, fromUserName);
  754.         fgetstring(stream, subject);
  755.         sprintf(out, "%s ", message.dateTime);
  756.         output(out);
  757.         sprintf(out, " Msg. %d  ", number);
  758.         output(out);
  759.         if (message.Attribute & 1) output("(PRIV) ");
  760.         if (message.Attribute & 2) output("(CRASH) ");
  761.         if (message.Attribute & 16) output("(FILE ATT) ");
  762.         if (message.Attribute & 2048) output("(F'REQ) ");
  763.         if (message.Attribute & 4096) output("(RCP REQ) ");
  764.         if (message.Attribute & 8192) output("(RET REQ) ");
  765.         if (message.Attribute & 16384) output("(AUD REQ) ");
  766.         output("\r\n");
  767.  
  768.         sprintf(out, "From:  %s of %d/%d\r\n", fromUserName, message.origNet, message.origNode);
  769.         output(out);
  770.  
  771.         sprintf(out, "To:    %s of %d/%d\r\n", toUserName, message.destNet, message.destNode);
  772.         output(out);
  773.  
  774.         if (message.Attribute & 16) output("Attch: ");
  775.         else if (message.Attribute & 2048) output("Req:   ");
  776.         else output("Re:    ");
  777.         sprintf(out, "%s\r\n\r\n", subject);
  778.         output(out);
  779.         ch = 0x01;
  780.         counter = 7;
  781.         while (ch != 0x00 && ! feof(stream)) {
  782.             if (counter == 22) {
  783.                 output("\r\n$1Q$0)uit  $1C$0)ontinue");
  784.                 input = menu_select("QC\x1B\r");
  785.                 if (input == 'Q' || input == 0x1B) return;
  786.                 bottomcls(7);
  787.                 cursor(7, 0);
  788.                 counter = 7;
  789.             }
  790.             ch = fgetc(stream);
  791.             if (ch == 0x8D) {
  792.                 continue;
  793.             }
  794.             if (ch == 0x0D) {
  795.                 output("\r\n");
  796.                 ++counter;
  797.                 char_count = 0;
  798.                 continue;
  799.             }
  800.             if (ch != 0x0A) {
  801.                 sprintf(out, "%c", ch);
  802.                 output(out);
  803.                 ++char_count;
  804.             }
  805.             if (char_count > 60 && ch == ' ') {
  806.                 output("\r\n");
  807.                 ++counter;
  808.                 char_count = 0;
  809.             }
  810.             if (char_count == 75) {
  811.                 output("\r\n");
  812.                 ++counter;
  813.                 char_count = 0;
  814.             }
  815.         }
  816.         output("\r\n\r\n$1Q$0)uit  $1C$0)ontinue to Next Packed Message ");
  817.         input = menu_select("QC\x1B\r");
  818.         if (input == 'Q' || input == 0x1B) return;
  819.     }
  820.  
  821. }
  822.  
  823.  
  824. void fgetstring(FILE *stream, char *string)
  825. {
  826.     unsigned char ch = 0x01;
  827.     unsigned int counter = 0;
  828.     while (ch != 0x00 && ! feof(stream)) {
  829.         ch = fgetc(stream);
  830.         string[counter] = ch;
  831.         ++counter;
  832.     }
  833.     if (feof(stream)) string[0] = 0x00;
  834.     return;
  835. }
  836.  
  837.  
  838.  
  839.