home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 214_01 / typexxr.c < prev    next >
Text File  |  1979-12-31  |  16KB  |  788 lines

  1. /* TYPEXXR.C   VERS:- 01.00  DATE:- 09/26/86  TIME:- 09:37:26 PM */
  2. /*
  3. %CC1 $1.C -O -X -E3B00
  4. %CLINK $1 WILDEXP -S -E3B00
  5. %DELETE $1.CRL 
  6. */
  7. /* 
  8. Description:
  9.  
  10. Sequential display of a wildcard filelist, with option for printing.
  11.  
  12. Rewrite of TYPE20, by sfk, W. Earnest, and others.
  13.  
  14. Restored user number prefixes and introduced recognition of <du:> form
  15.     (new versions of DEFFx.CRL and WILDEXP).
  16. Introduced command_line options and flags toggled or set through them.
  17. Revised dochar() and xxxx_putchar() for efficiency.
  18. Sort filelist before display.
  19. Changed format of display, to accomodate printing.
  20. Option to add formfeed if needed to maintain phase of fanfold paper.
  21. OUT_BDOS option, so can print with cp/m ^p; route input also through bdos.
  22. General changes in code.
  23.  
  24. Examples of option settings:
  25.  
  26.     option = -S        option = -T        option = -U
  27.  
  28.     display 19 lines    display all file    display all file
  29.     no pausing        no pausing        pause at page/file
  30.     no form feed output    maintain paper phase    form feed output
  31.     <-----allow routing of output to printer through bdos ^p----->
  32.  
  33. LINES_MAX   21            0            0
  34. PAGE        0            0            1
  35. FILE_PAUSE  0            0            1    
  36. FORM_FEEDS  0            1            0
  37. EXPAND        0            0            0
  38. NOSYS        0            0            0
  39. OUT_BDOS    1            1            1
  40.  
  41.  
  42.  
  43. By J.A. Rupley, Tucson, Arizona
  44. Coded for BDS C compiler, version 1.50a
  45. */
  46.  
  47.         /* page eject */
  48.  
  49. #include <bdscio.h>
  50.  
  51. #undef NSECTS
  52. #undef BUFSIZ
  53. #define NSECTS 64 /* Number of sectors to buffer up in ram */
  54. #define BUFSIZ (NSECTS * SECSIZ + 6) 
  55. #define TAB 9
  56. #define LF 10
  57. #define FF 12
  58. #define CR 13
  59. #define BACKSPACE 8
  60. #define SPACE 32
  61. #define CNTRL_C 3
  62. #define CNTRL_S 19
  63. #define CNTRL_X 24
  64. #define    CONST    2
  65. #define CONIN    3
  66. #define CONOUT    4
  67. #define RECOGNIZE 0xFF76    /* unlikely pattern */
  68. #define DLE 0x90        /* repeat byte flag */
  69. #define    CHAR_AVAILABLE 0xff
  70. #define SPEOF 256        /* special endfile token */
  71. #define NUMVALS 257        /* 256 data values plus SPEOF*/
  72. #define LARGE 30000
  73. #define PATHLEN 20    /* file string size */
  74. #define TLENGTH 24    /* number of lines on screen */
  75. #define PAGE_LENGTH 66         /* number of lines per printed page*/
  76. #define COLUMNS 80    /* number of columns per line*/
  77. #define TAB_SPACES 8    /* number of spaces separating tab positions*/
  78.  
  79. #define EXPAND FALSE    /* expand tabs */
  80. #define NOSYS FALSE    /* display system files */
  81. #define LINES_MAX 21     /* default line limit if select option = screen */
  82. #define PAGE TRUE    /* stop at full screen */
  83. #define FILE_PAUSE TRUE        /* pause before each file */
  84. #define FORM_FEEDS FALSE        /* print form feeds & maintain paper phase*/
  85.  
  86. #define OUT_BDOS    /* comment out for output through bios */
  87.  
  88. struct _sqleaf        /* Decoding tree */
  89. {
  90.     int _children[2];        /* left, right */
  91. }
  92. ;
  93. struct _sqleaf Dnode[NUMVALS -1];
  94. unsigned Sqcksum;
  95. int Bpos;        /* last bit position read */
  96. int Curin;        /* last byte value read */
  97. int Repct;        /* Number of times to retirn value */
  98. int Value;        /* current byte value or EOF */
  99.  
  100. char File_buf[BUFSIZ];
  101.  
  102. int col, line_cnt, page_cnt, last_pause, early_exit;
  103. int expand, tab_spaces, nosys, maxlines, page, file_pause, form_feeds;
  104. int optionerr;
  105. int c, yy;
  106.  
  107. main(argc, argv)
  108. int argc;
  109. char **argv;
  110. {
  111.     char file[PATHLEN];
  112.     int x, y;
  113.     int string_compare();
  114.  
  115.     nosys = NOSYS;        /*OPTION FLAGS*/
  116.     maxlines = 0;        /*no output line limit unless set by option*/
  117.     expand = EXPAND;
  118.     tab_spaces = TAB_SPACES;
  119.     page = PAGE;
  120.     file_pause = FILE_PAUSE;
  121.     form_feeds = FORM_FEEDS;
  122.     optionerr = 0;
  123.  
  124.     get_options(&argc, argv);        /*RESET OPTION FLAGS*/
  125.     if (optionerr || (argc < 2))
  126.         help_mess();
  127.  
  128.     wildexp(&argc, &argv);        /*WILDCARD & SORT COMMAND LINE*/
  129.     qsort(&argv[1], argc - 1, 2, &string_compare);
  130.  
  131.     early_exit = 0;        /*FLOW CONTROL FLAGS*/
  132.     col = 0;
  133.     line_cnt = 0;
  134.     page_cnt = -1;
  135.     last_pause = 0;
  136.  
  137.     for (x = 1; x < argc; ++x)
  138.     {
  139.         switch (catvalid(file, argv[x]))
  140.         {
  141.         case 'q' :
  142.             if (qsend(file) == 'a')
  143.                 send_text(file);
  144.             break;
  145.         case 'a' :
  146.             send_text(file);
  147.             break;
  148.         case 'x' :
  149.             break;
  150.         case ERROR :
  151.         default :
  152.             y = 3;
  153.             while (y--)
  154.             {
  155.                 printf("\n");
  156.                 up_line_cnt();
  157.             }
  158.             printf("\tcan't type %s...", argv[x]);
  159.         }
  160.  
  161.         if (file_pause && (early_exit != 2))
  162.         {
  163.             printf("\n[next file?]");
  164.             up_line_cnt();
  165.             while ((y = bdos(1, 0)) == 0)
  166.                 ;
  167.             printf("\r             \r");
  168.             if (y == 0x03)
  169.             {
  170.                 printf("that's all folks...");
  171.                 exit();
  172.             }
  173.         }
  174.     }
  175.     return (OK);
  176. }
  177.         /* page eject */
  178.  
  179. int send_text(file)
  180. char *file;
  181. {
  182.     int i;
  183.  
  184.     if (page_cnt >= 0)
  185.     {
  186.         /*3-line spacer between files*/
  187.         i = 3;
  188.         while (i--)
  189.         {
  190.             printf("\n");
  191.             up_line_cnt();
  192.         }
  193.         /*FF if needed to maintain phase of paper*/
  194.         if (form_feeds)
  195.         {
  196.             if ((page_cnt % 2) == 0)
  197.                 printf("\f");
  198.             /* form feed at start of file*/
  199.             printf("\f");
  200.         }
  201.     }
  202.     printf("\rListing file %s\n\n", file);
  203.     page_cnt = 0;
  204.     last_pause = 0;
  205.     line_cnt = 2;
  206.     early_exit = 0;
  207.     col = 0;
  208.     while (((c = getc(File_buf)) != EOF) && (!early_exit))
  209.         dochar();
  210.     fclose(File_buf);
  211.     return (OK);
  212. }
  213.  
  214.  
  215.  
  216. void dochar()
  217. {
  218.     if ((c = (c & 0x7f)) > 0x1f)
  219.     {
  220. #ifdef OUT_BDOS
  221.         bdos(2, c);        /*some direct output calls for speed*/
  222. #else
  223.         bios(CONOUT, c);
  224. #endif
  225.         if (++col >= COLUMNS)
  226.         {
  227.             col %= COLUMNS;
  228.             up_line_cnt();
  229.         }
  230.     }
  231.     else
  232.         switch (c)
  233.     {
  234.     case TAB :
  235.         yy = (tab_spaces - col % tab_spaces);
  236.         if ((col += yy) >= COLUMNS)
  237.         {
  238.             col %= COLUMNS;
  239.             up_line_cnt();
  240.         }
  241.         if (!expand)
  242.         {
  243. #ifdef OUT_BDOS
  244.             bdos(2, c);
  245. #else    
  246.             bios(CONOUT, c);
  247. #endif
  248.         }
  249.         else
  250.             {
  251.             while (yy--)
  252.             {
  253. #ifdef OUT_BDOS
  254.                 bdos(2, SPACE);
  255. #else    
  256.                 bios(CONOUT, SPACE);
  257. #endif
  258.             }
  259.         }
  260.         break;
  261.     case CR :
  262.         b_putchar(c);
  263.         col = 0;
  264.         break;
  265.     case 0x1a :
  266.         early_exit = 1;
  267.         break;
  268.     case LF :
  269.         b_putchar(c);
  270.         up_line_cnt();
  271.         if (maxlines)
  272.         {
  273.             yy = page_cnt * PAGE_LENGTH + line_cnt;
  274.             if (yy >= maxlines)
  275.                 early_exit = 1;
  276.         }
  277.         if (page)
  278.         {
  279.             yy = page_cnt * PAGE_LENGTH + line_cnt;
  280.             if ((yy - last_pause) >= (TLENGTH - 2))
  281.             {
  282.                 last_pause = yy;
  283.                 printf("\r[more..]");
  284.                 switch (bios(CONIN, 0))
  285.                 {
  286.                 case CNTRL_C :
  287.                     printf("\rthat's all folks...");
  288.                     exit();
  289.                 case CNTRL_X :
  290.                     early_exit = 2;
  291.                     printf("\rno more...");
  292.                     break;
  293.                 default :
  294.                     yy = 8;
  295.                     while (yy--)
  296.                     {
  297.                         b_putchar(BACKSPACE);
  298.                         b_putchar(SPACE);
  299.                         b_putchar(BACKSPACE);
  300.                     }
  301.                 }
  302.             }
  303.         }
  304.         break;
  305.     case FF :
  306.         if (form_feeds)
  307.         {
  308.             b_putchar(c);
  309.             col = 0;
  310.             line_cnt = 0;
  311.             page_cnt++;
  312.         }
  313.         break;
  314.     }
  315.  
  316. }
  317.  
  318.  
  319.  
  320. /*  type.c will use its own version of getc.*/
  321. /*  This is so we can have a bigger buffer.*/
  322.  
  323. int getc(iobuf)
  324. struct _buf *iobuf;
  325. {
  326.     int nsecs;
  327.  
  328.     IF(!iobuf->_nleft--)
  329.     {
  330.         if ((nsecs = read(iobuf->_fd, iobuf->_buff, NSECTS)) <= 0)
  331.             return iobuf->_nleft++;
  332.         iobuf->_nleft = nsecs * SECSIZ - 1;
  333.         iobuf->_nextp = iobuf->_buff;
  334.     }
  335.     return *iobuf->_nextp++;
  336. }
  337.  
  338.  
  339.  
  340. int up_line_cnt()
  341. {
  342.     if (++line_cnt >= PAGE_LENGTH)
  343.     {
  344.         page_cnt++;
  345.         line_cnt = 0;
  346.     }
  347.     return line_cnt;
  348. }
  349.  
  350.  
  351.  
  352. void b_putchar(cc)
  353. int cc;
  354. {
  355. #ifdef    OUT_BDOS
  356.     int t;
  357.  
  358.     bdos(2, cc);
  359.     if (bdos(11, 0))
  360.     {
  361.         if ((t = bdos(1, 0)) == CNTRL_C)
  362.             exit();
  363.         else
  364.             if (t == CNTRL_X)
  365.                 early_exit = 2;
  366.     }
  367. #else
  368.     int t;
  369.  
  370.     bios(CONOUT, cc);
  371.     if (bios(CONST, 0) == CHAR_AVAILABLE)
  372.     {
  373.         if ((t = bios(CONIN, 0)) == CNTRL_C)
  374.             exit();
  375.         else
  376.             if (t == CNTRL_S)
  377.             {
  378.                 while (bios(CONST, 0) != CHAR_AVAILABLE)
  379.                     ;
  380.                 t = bios(CONIN, 0);
  381.             }
  382.         else
  383.             if (t == CNTRL_X)
  384.             early_exit = 2;
  385.     }
  386. #endif
  387. }
  388.         /* page eject*/
  389.  
  390. int catvalid(pname, name)
  391. char *pname;
  392. char *name;
  393. {
  394.     char *pptr, *qptr, *npnt;
  395.     int fd;
  396.     int y;
  397.  
  398.     if (strlen(name) > 17)
  399.     {
  400.         y = 3;
  401.         while (y--)
  402.         {
  403.             printf("\n");
  404.             up_line_cnt();
  405.         }
  406.         printf("\t'%s' bad name, (name too long)", name);
  407.         return 'x';
  408.     }
  409.     if ((fd = fopen(name, File_buf)) == ERROR)
  410.     {
  411.         y = 3;
  412.         while (y--)
  413.         {
  414.             printf("\n");
  415.             up_line_cnt();
  416.         }
  417.         printf("\tCan't find %s on disk - check your spelling.", name);
  418.         return 'x';
  419.     }
  420.     npnt = fcbaddr(fd);
  421.     if (nosys && (npnt[10] > 127))
  422.     {
  423.         y = 3;
  424.         while (y--)
  425.         {
  426.             printf("\n");
  427.             up_line_cnt();
  428.         }
  429.         printf("\tCan't find %s on disk - check your spelling.", name);
  430.         fclose(File_buf);
  431.         return 'x';
  432.     }
  433.     if (npnt[1] > 127 || npnt[2] > 127)
  434.     {
  435.         if (npnt[10] < 128)
  436.         {
  437.             y = 3;
  438.             while (y--)
  439.             {
  440.                 printf("\n");
  441.                 up_line_cnt();
  442.             }
  443.             printf("\tFile %s not for distribution.", name);
  444.         }
  445.         fclose(File_buf);
  446.         return 'x';
  447.     }
  448.  
  449.     strcpy(pname, name);
  450.     if ((y = bad_type(name)) == ERROR)
  451.         fclose(File_buf);
  452.     return y;
  453. }
  454.  
  455.  
  456. int bad_type(name)
  457. char *name;
  458. {
  459.     char *ss, *tt, *bad;
  460.  
  461.     bad = ".COM.OBJ.BAD.LOG.SYS.OV?.SEN.REL.CRL.LBR.ARC.NDX.DBF.ZIP.ZBA.HEX.DIC.IO .?Q*.";
  462.  
  463.     for (; *name; name++)
  464.         if (*name == '.')
  465.             break;
  466.     if (*name)
  467.         if (*(name + 2) == 'Q')
  468.             return 'q';
  469.     for (; *bad; bad++)
  470.         if (*bad == *name)
  471.             for (ss = bad, tt = name;; ss++, tt++)
  472.             {
  473.                 while (*tt == ' ')
  474.                     tt++;
  475.                 while (*ss == ' ')
  476.                     ss++;
  477.                 if (!*tt)
  478.                 {
  479.                     if ((*ss == '.') || (*ss == '*'))
  480.                         return ERROR;
  481.                     else
  482.                         break;
  483.                 }
  484.                 if ((*ss == '?') || (*ss == '*'))
  485.                     continue;
  486.                 if (*ss != *tt)
  487.                     break;
  488.             }
  489.     return 'a';
  490. }
  491.  
  492.         /* page eject*/
  493.  
  494. /*
  495. The following code is primarily from typesq.c and utr.c.  Typesq
  496. is a modification of USQ by Dick Greenlaw.  Those modifications (usq
  497. to typesq) were made by Bob Mathias, I am responsible for the butchery
  498. done to make it work with cat.
  499. */
  500.  
  501. int qsend(infile)        /* #define VERSION "1.3   07/21/81" */
  502. char *infile;
  503. {
  504.     char origname[14];        /* Original file name without drive */
  505.     int y, i;
  506.     char *p;
  507.     unsigned filecksum;        /* checksum */
  508.     int numnodes;        /* size of decoding tree */
  509.  
  510.     Sqcksum = 0;        /* Initialization */
  511.     init_cr();
  512.     init_huff();
  513.  
  514.     if (getw(File_buf) != RECOGNIZE)        /* Process header */
  515.     {
  516.         fclose(File_buf);
  517.         return 'a';        /* not squeezed after all */
  518.     }
  519.     filecksum = getw(File_buf);
  520.     p = origname;        /* Get original file name */
  521.     do        /* send it to array */
  522.     {
  523.         *p = getc(File_buf);
  524.     }
  525.     while (*p++ != '\0')
  526.         ;
  527.  
  528.     numnodes = getw(File_buf);
  529.     if (numnodes < 0 || numnodes >= NUMVALS)
  530.     {
  531.         y = 3;
  532.         while (y--)
  533.         {
  534.             printf("\n");
  535.             up_line_cnt();
  536.         }
  537.         printf("\t%s has invalid decode tree size", infile);
  538.         fclose(File_buf);
  539.         return ERROR;
  540.     }
  541.     /* Initialize for possible empty tree (SPEOF only) */
  542.     Dnode[0]._children[0] = -(SPEOF + 1);
  543.     Dnode[0]._children[1] = -(SPEOF + 1);
  544.  
  545.     for (i = 0; i < numnodes; ++i)        /* Get decoding tree from file */
  546.     {
  547.         Dnode[i]._children[0] = getw(File_buf);
  548.         Dnode[i]._children[1] = getw(File_buf);
  549.     }
  550.  
  551.     if (page_cnt >= 0)
  552.     {
  553.         /*3-line spacer between files*/
  554.         i = 3;
  555.         while (i--)
  556.         {
  557.             printf("\n");
  558.             up_line_cnt();
  559.         }
  560.         /*FF if needed to maintain phase of paper*/
  561.         if (form_feeds)
  562.         {
  563.             if ((page_cnt % 2) == 0)
  564.                 printf("\f");
  565.             /* form feed at start of file*/
  566.             printf("\f");
  567.         }
  568.     }
  569.     printf("\r%s -> %s\n\n", infile, origname);
  570.     page_cnt = 0;
  571.     last_pause = 0;
  572.     line_cnt = 2;
  573.     early_exit = 0;
  574.     col = 0;
  575.     while (((c = getcr(File_buf)) != EOF) && (!early_exit))
  576.         dochar();
  577.     fclose(File_buf);
  578.     return OK;
  579. }
  580.  
  581.  
  582. /*** from utr.c - */
  583. /* initialize decoding functions */
  584.  
  585. init_cr()
  586. {
  587.     Repct = 0;
  588. }
  589.  
  590.  
  591.  
  592. init_huff()
  593. {
  594.     Bpos = 99;        /* force initial read */
  595. }
  596.  
  597.  
  598.  
  599. /*
  600. Get bytes with decoding - this decodes repetition,
  601. calls getuhuff to decode file stream into byte
  602. level code with only repetition encoding.
  603.  *
  604. The code is simple passing through of bytes except
  605. that DLE is encoded as DLE-zero and other values
  606. repeated more than twice are encoded as value-DLE-count.
  607. */
  608.  
  609. int getcr(ib)
  610. char *ib;
  611. {
  612.     int cc;
  613.  
  614.     if (Repct > 0)
  615.     {
  616.         /* Expanding a repeated char */
  617.         --Repct;
  618.         return Value;
  619.     }
  620.     else
  621.         {
  622.         /* Nothing unusual */
  623.         if ((cc = getuhuff(ib)) != DLE)
  624.         {
  625.             /* It's not the special delimiter */
  626.             Value = cc;
  627.             if (Value == EOF)
  628.                 Repct = LARGE;
  629.             return Value;
  630.         }
  631.         else
  632.             {
  633.             /* Special token */
  634.             if ((Repct = getuhuff(ib)) == 0)
  635.                 /* DLE, zero represents DLE */
  636.                 return DLE;
  637.             else
  638.                 {
  639.                 /* Begin expanding repetition */
  640.                 Repct -= 2;        /* 2nd time */
  641.                 return Value;
  642.             }
  643.         }
  644.     }
  645. }
  646.  
  647.  
  648.  
  649. /* 
  650. Decode file stream into a byte level code with only
  651. repetition encoding remaining.
  652. */
  653.  
  654. int getuhuff(ib)
  655. char *ib;
  656. {
  657.     int i;
  658.     int bitval;
  659.  
  660.     /* Follow bit stream in tree to a leaf*/
  661.     i = 0;        /* Start at root of tree */
  662.     do
  663.         {
  664.         if (++Bpos > 7)
  665.         {
  666.             if ((Curin = getc(ib)) == ERROR)
  667.                 return ERROR;
  668.             Bpos = 0;
  669.             /* move a level deeper in tree */
  670.             i = Dnode[i]._children[1 & Curin];
  671.         }
  672.         else
  673.             i = Dnode[i]._children[1 & (Curin >>= 1)];
  674.     }
  675.     while (i >= 0)
  676.         ;
  677.  
  678.     /* Decode fake node index to original data value */
  679.     i = -(i + 1);
  680.     /* Decode special endfile token to normal EOF */
  681.     i = (i == SPEOF) ? EOF : i;
  682.     return i;
  683. }
  684.         /* page eject */
  685.  
  686. void get_options(argcpntr, argv)
  687. char **argv;
  688. int *argcpntr;
  689. {
  690.     char *ss;
  691.     int jj, ii;
  692.  
  693.     for (ii = *argcpntr - 1; ii > 0; ii--)
  694.         if (argv[ii][0] == '-')
  695.         {
  696.             for (ss = &argv[ii][1]; *ss != '\0';)
  697.             {
  698.                 switch (toupper(*ss++))
  699.                 {
  700.                 case 'S' :
  701.                     maxlines = LINES_MAX;
  702.                     page = file_pause = 0;
  703.                     form_feeds = 0;
  704.                     break;
  705.                 case 'T' :
  706.                     maxlines = 0;
  707.                     page = file_pause = 0;
  708.                     form_feeds = 1;
  709.                     break;
  710.                 case 'U' :
  711.                     maxlines = 0;
  712.                     page = file_pause = 1;
  713.                     form_feeds = 0;
  714.                     break;
  715.                 case 'F' :
  716.                     form_feeds = !form_feeds;
  717.                     break;
  718.                 case 'P' :
  719.                     page = !page;
  720.                     file_pause = !file_pause;
  721.                     break;
  722.                 case 'L' :
  723.                     if (!(maxlines = atoi(ss)))
  724.                         maxlines = LINES_MAX;
  725.                     break;
  726.                 case 'E' :
  727.                     if (expand = atoi(ss))
  728.                         tab_spaces = expand;
  729.                     else
  730.                         tab_spaces = expand = TAB_SPACES;
  731.                     break;
  732.                 case 'H' :
  733.                     optionerr = TRUE;
  734.                     break;
  735.                 default :
  736.                     printf("\tillegal option %c.\n", *--ss);
  737.                     ss++;
  738.                     optionerr = TRUE;
  739.                     break;
  740.                 }
  741.                 while (isdigit(*ss))
  742.                     ss++;
  743.             }
  744.             for (jj = ii; jj < (*argcpntr - 1); jj++)
  745.                 argv[jj] = argv[jj + 1];
  746.             (*argcpntr)--;
  747.         }
  748.     return;
  749. }
  750.  
  751.  
  752. int string_compare(s, t)
  753. char **s, **t;
  754. {
  755.     char *s1, *t1;
  756.     int i;
  757.     s1 = *s;
  758.     t1 = *t;
  759.     for (i = 0; i < MAXLINE; i++)
  760.     {
  761.         if (t1[i] != s1[i])
  762.             return s1[i] - t1[i];
  763.         if (s1[i] == '\0')
  764.             return 0;
  765.     }
  766.     return 0;
  767. }
  768.  
  769.  
  770.  
  771. void help_mess()
  772. {
  773.     printf("USAGE: TYPE  filname.typ  [-options = STUFPL[#]E[#]H]\n\n");
  774.     printf("Options: -S  = print without pause first 19 lines of files\n");
  775.     printf("         -T  = print without pause, with form feeds and phase\n");
  776.     printf("         -U  = page through file; default setting\n");
  777.     printf("         -F  = toggle print of form feeds and paper phasing\n");
  778.     printf("         -P  = toggle paging \n");
  779.     printf("         -L# = print only first # lines of a file; if no #, # = 19\n");
  780.     printf("         -E# = expand tabs to # spaces; if no #, # = 8\n");
  781.     printf("         -H  = print this help message\n\n");
  782.     printf("Wild chars. (* and ?) OK,\n");
  783.     printf("Multiple file names OK,\n");
  784.     printf("User numbers and <du:> form OK;\n");
  785.     printf("During output, Ctrl-S pauses, Ctrl-C aborts, Ctrl-X skips to next file.\n");
  786.     exit();
  787. }
  788.