home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / ZOO21E.EXE / ZOOLIST.C < prev    next >
C/C++ Source or Header  |  1991-07-11  |  19KB  |  590 lines

  1. #ifndef LINT
  2. /* derived from: zoolist.c 2.27 88/08/15 11:03:16 */
  3. static char sccsid[]="$Source: /usr/home/dhesi/zoo/RCS/zoolist.c,v $\n\
  4. $Id: zoolist.c,v 1.4 91/07/09 01:54:16 dhesi Exp $";
  5. #endif /* LINT */
  6.  
  7. /*
  8. If TRACE_LIST is defined, any list command may be followed
  9. by 'D' to show verbose information about each directory
  10. entry in the archive.   Do not define both TRACE_LIST and
  11. TRACE_IO else a symbol conflict will occur and in any case
  12. duplicate information will be dumped.
  13. */
  14.  
  15. /* #define TRACE_LIST */
  16.  
  17. /*
  18. Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  19. (C) Copyright 1988 Rahul Dhesi -- All rights reserved
  20. */
  21. #include "options.h"
  22. #include "portable.h"
  23. #include "zoomem.h"  /* to get ZOOCOUNT */
  24.  
  25. /* Lists files in archive */
  26. #include "zoo.h"
  27. #include "errors.i"
  28. #include "zooio.h"
  29. #include "various.h"
  30. #include "zoofns.h"
  31.  
  32. #ifdef TRACE_LIST
  33. void show_dir PARMS ((struct direntry *direntry));
  34. static int trace_list = 0;
  35. #endif /* TRACE_LIST */
  36.  
  37. static char tot_fmt[] = "%8lu %3u%% %8lu  %4d file";
  38. static char tot_line[] =
  39.    /* "------------  --------  ---  --------  --------- --------\n"; */
  40.    "--------  --- --------  --------- --------\n";
  41.  
  42. static char dbl_percent[] = "Archive %s:  %s";
  43.  
  44. extern int quiet;                /* assumed initialized to zero */
  45.  
  46. void show_comment PARMS((struct direntry *, ZOOFILE, int, char *));
  47. int ver_too_high PARMS((struct zoo_header *));
  48. int needed PARMS((char *, struct direntry *, struct zoo_header *));
  49. void printtz PARMS((int));
  50.  
  51. void zoolist (argv, option, argc)
  52. char **argv, *option;
  53. int argc;
  54. {
  55. char whichname[PATHSIZE];  /* which name to use */
  56. char *this_zoo;            /* currently matched archive name */
  57. register ZOOFILE zoo_file;
  58. char *flist[ZOOCOUNT];       /* list of ptrs to input archive names */
  59. int fptr;                  /* will point to within list of archive names */
  60.  
  61. struct direntry direntry;
  62. struct zoo_header zoo_header;
  63. int size_factor;
  64. unsigned long tot_org_siz = 0L, tot_siz_now = 0L;
  65. int   tot_sf;
  66. int file_count = 0;
  67. int del_count = 0;                  /* number of deleted entries */
  68. int bad_pack;                 /* 1 if packing method is unknown */
  69. static char *month_list="000JanFebMarAprMayJunJulAugSepOctNovDec";
  70. static char dashes[] = "------------\n";
  71. int year, month, day, hours, min, sec;
  72. int list_deleted = 0;         /* list deleted files too */
  73. int fast = 0;                 /* fast list */
  74. long fiz_ofs = 0;             /* offset where to start */
  75. long dat_ofs = 0;             /* ... data offset of file data */
  76. int verb_list = 0;            /* if verbose listing needed */
  77. int show_name = 0;            /* if archive name to be included in listing */
  78. int show_crc = 0;                    /* if crc should be listed */
  79. int zoocount = 1;             /* number of archives to list */
  80. int biglist = 0;              /* multiarchive listing */
  81. int one_col = 0;                    /* one column listing requested */
  82. int showdir = 0;                    /* show directory name in fast listing */
  83. int longest;                  /* length of longest archive name */
  84. int talking;                        /* opposite of quiet */
  85. int column = 0;               /* for column printing */
  86. int first_ever = 1;                /* first time ever -- very special case */
  87. int neednl = 0;                    /* whether to print a newline */
  88. int need_acmt = 0;                /* show archive comment */
  89. int show_gen = 0;                    /* show generation count */
  90. int genson = 1;                    /* enable/disable generations */
  91. #ifdef FATTR
  92. int show_mode = 0;                /* show file protection */
  93. #endif
  94. int first_dir = 1;                /* if first direntry -- to adjust dat_ofs */
  95.  
  96. while (*option) {
  97.    switch (*option) {
  98.       case 'a': show_name++; break;
  99. #ifdef TRACE_LIST
  100.         case 'D': trace_list++; break;
  101. #endif /* TRACE_LIST */
  102.       case 'd': list_deleted++; break;
  103.       case 'f': fast++; break;
  104.         case 'g': show_gen++; break;
  105.         case '/': showdir++; break;
  106.         case 'A':
  107.         case 'v': need_acmt++; break;
  108.       case 'V': need_acmt++; /* fall through */
  109.       case 'c': verb_list++; break;
  110.         case 'C': show_crc++; break;
  111.       case 'l': break;
  112.       case 'L': biglist++; zoocount = argc; break;
  113. #ifdef FATTR
  114.         case 'm': show_mode++; break;
  115. #endif
  116.         case '1': one_col++; break;
  117.         case '+': genson = 1; break;
  118.         case '-': genson = 0; break;
  119.         /* following code same as in zooext.c */
  120.       case '@':     /* if @m,n specified, fiz_ofs = m, dat_ofs = n */
  121.             {
  122.                 char *comma_pos;
  123.                 ++option;
  124.                 comma_pos = strchr(option, ',');
  125.                 if (comma_pos != NULL) {
  126.                     dat_ofs = calc_ofs (comma_pos + 1);
  127.                     *comma_pos = '\0';
  128.                 }
  129.                 fiz_ofs = calc_ofs(option);
  130.                 goto no_more;
  131.             }
  132.         case 'q': quiet++; break;
  133.       default:
  134.          prterror ('w', option_ignored, *option);
  135.    }
  136.    option++;
  137. }
  138.  
  139. no_more:  /* come from exit from while loop above */
  140.  
  141. if (fast && show_name) {      /* don't allow 'a' with 'f' */
  142.    show_name = 0;
  143.    prterror ('w', option_ignored, 'a');
  144. }
  145.  
  146. talking = !quiet;                    /* for convenience */
  147.  
  148. #ifdef WILDCARD
  149.    /* For each archive name supplied, if it is not a char range and
  150.       does not contain a dot, append "*.zoo". */
  151.    {
  152.       int i;
  153.       for (i = 0; i < argc;  i++) {
  154.          if (strchr (nameptr (argv[i]), EXT_CH) == NULL &&
  155.                            !match_half (nameptr (argv[0]), "?-?"))
  156.             argv[i] = newcat (argv[i], "*.zoo");
  157.       }
  158.    }
  159. #endif
  160.  
  161. makelist (zoocount, argv, flist,        ZOOCOUNT-2,   (char *) NULL,".","..", &longest);
  162. /*        ^argc     ^argv ^list_pointer ^max_no_files   ^exclude */
  163.  
  164. for (fptr = 0;  (this_zoo = flist[fptr]) != NULL; fptr++) {
  165.    int ercount;                  /* count of errors */
  166.    int entrycount;               /* count of directory entries */
  167.    int expl_deleted;             /* explain what D means */
  168.    int expl_comment;             /* explain what comment means */
  169.    int expl_ver;                 /* Explain what V means */
  170.    int expl_star;                /* Explain what * means */
  171.    int first_time;               /* first time through loop for an archive */
  172.  
  173.    ercount = entrycount = del_count =
  174.       expl_deleted = expl_comment = expl_ver = expl_star = 0;
  175.  
  176.     if (talking)
  177.         column = 0;                        /* if quiet, names will run together */
  178.  
  179.    first_time = 1;
  180.  
  181. #ifndef WILDCARD
  182.    /* Add default extension if none supplied */
  183.    if (strchr (nameptr (this_zoo), EXT_CH) == NULL)
  184.       this_zoo = newcat (this_zoo, EXT_DFLT);
  185. #endif
  186.  
  187.    zoo_file = zooopen (this_zoo, Z_READ);
  188.  
  189.    if (zoo_file == NOFILE) {
  190.       prterror ('e', could_not_open, this_zoo);
  191.       continue;
  192.    } else if (!show_name && talking)
  193.       printf ("\nArchive %s:\n", this_zoo);
  194.  
  195. if (fiz_ofs != 0L) {                /* if offset specified, start there */
  196.     prterror ('m', start_ofs, fiz_ofs, dat_ofs);
  197.    zooseek (zoo_file, fiz_ofs, 0);
  198. } else {
  199.    if (frd_zooh (&zoo_header, zoo_file) == -1 ||
  200.                                              zoo_header.zoo_tag != ZOO_TAG) {
  201.       prterror ('e', dbl_percent, this_zoo, invalid_header);
  202.       goto loop_end;
  203.    }
  204. #if 0
  205.     if (talking && (!show_name || verb_list || need_acmt))
  206. #else
  207.     if (need_acmt && talking)
  208. #endif
  209.     {
  210.         void show_acmt PARMS ((struct zoo_header *, ZOOFILE, int));
  211.         show_acmt (&zoo_header, zoo_file, 0);        /* show archive comment */
  212.     }
  213.  
  214.    /* Seek to the beginning of the first directory entry */
  215.    if (zooseek (zoo_file, zoo_header.zoo_start, 0) != 0) {
  216.       ercount++;
  217.       prterror ('e', dbl_percent, this_zoo, bad_directory);
  218.       goto loop_end;
  219.    }
  220.    if (!show_name && ver_too_high (&zoo_header)) {
  221.       ercount++;
  222.       if (ercount < 2)
  223.          prterror ('M', wrong_version,
  224.                                         zoo_header.major_ver, zoo_header.minor_ver);
  225.    }
  226. } /* end if (fiz_ofs !- 0L) */
  227.  
  228.    /* Now we print information about each file in the archive */
  229.  
  230.    if (!show_name) { /* initialize for each file only if not disk catalog */
  231.       tot_org_siz = 0L;
  232.       tot_siz_now = 0L;
  233.       file_count = 0;
  234.       del_count = 0;
  235.    }
  236.  
  237.    while (1) {
  238.       if (readdir (&direntry, zoo_file, 0) == -1) {
  239.          prterror ('F', dbl_percent, this_zoo, bad_directory);
  240.          goto givesummary;
  241.       }
  242.       if (direntry.zoo_tag != ZOO_TAG) {
  243.          long currpos, zoolength;
  244.          prterror ('F', dbl_percent, this_zoo, invalid_header);
  245.          if ((currpos = zootell (zoo_file)) != -1L)
  246.             if (zooseek (zoo_file, 0L, 2) == 0)
  247.                if ((zoolength = zootell (zoo_file)) != -1L)
  248.                   printf (cant_process, zoolength - currpos);
  249.          goto givesummary;
  250.       }
  251.  
  252.       if (direntry.next == 0L)      /* EXIT on end of chain */
  253.          break;
  254.       else
  255.          entrycount++;              /* Number of directory entries */
  256.         /* first direntry read, change dat_ofs from abs. pos. to rel. offset */
  257.         if (first_dir && dat_ofs != 0) {
  258.             dat_ofs -= direntry.offset;
  259.             first_dir = 0;
  260.         }
  261.         direntry.next += dat_ofs;                /* allow for user-specified offset */
  262.         if (direntry.comment != 0L)
  263.             direntry.comment += dat_ofs;        /* so show_comment finds it */
  264.  
  265.       if (direntry.deleted)
  266.          ++del_count;
  267.  
  268. #ifdef TRACE_LIST
  269.         if (trace_list)
  270.             show_dir (&direntry);
  271. #endif /* TRACE_LIST */
  272.  
  273.         /* Into `whichname' put the filename to display. Use long filename if
  274.         it exists, else use short filename.  */
  275.             strcpy (whichname, fullpath (&direntry));
  276.             if (zoo_header.vdata & VFL_ON)
  277.                 add_version (whichname, &direntry);    /* add version suffix */
  278. #ifdef DEBUG
  279.       printf("matching against [%s] and [%s]\n",
  280.                nameptr(whichname), whichname);
  281. #endif
  282.  
  283.       if ( ( (list_deleted && direntry.deleted) ||
  284.                (list_deleted < 2 && !direntry.deleted)
  285.            )
  286.               && (biglist || needed(whichname, &direntry, &zoo_header))) {
  287.             /* if generations forced off, then strip added version field */
  288.             if (!genson) {    /* HORRENDOUSLY INEFFICIENT AND REPETITIOUS */
  289.                 char *ver_pos;
  290.                 ver_pos = findlast (whichname, VER_DISPLAY);
  291.                 if (ver_pos != NULL)
  292.                     *ver_pos = '\0';
  293.             }
  294.  
  295.          file_count++;
  296.  
  297.          if (direntry.packing_method > MAX_PACK) {
  298.             bad_pack = 1;
  299.             expl_ver = 1;
  300.          }  else
  301.             bad_pack = 0;
  302.  
  303.          size_factor = cfactor (direntry.org_size, direntry.size_now);
  304.  
  305.          year  =  ((unsigned int) direntry.date >> 9) & 0x7f;
  306.          month =  ((unsigned int) direntry.date >> 5) & 0x0f;
  307.          day   =  direntry.date        & 0x1f;
  308.  
  309.          hours =  ((unsigned int) direntry.time >> 11)& 0x1f;
  310.          min   =  ((unsigned int) direntry.time >> 5) & 0x3f;
  311.          sec   =  ((unsigned int) direntry.time & 0x1f) * 2;
  312.  
  313.             /* Alignment in columns is a horrendously complex undertaking. */
  314.  
  315.          if (fast) {
  316.                 int space_left;
  317.                 int namelen;
  318.                 int next_col;
  319. #if 0
  320.             if ( (quiet && !first_ever || !first_time) && one_col)
  321.                fputchar ('\n');
  322.                 first_ever = 0;
  323. #endif
  324.                 /* If we are showing directories, whichname already contains the
  325.                 full pathname string.  Else we only use the filename as follows:
  326.                 long filename if possible, else short filename */
  327.                 if (!showdir) {
  328.                    strcpy (whichname,
  329.                       (direntry.namlen != 0) ? direntry.lfname : direntry.fname);
  330.                     if (genson && zoo_header.vdata & VFL_ON)
  331.                         add_version (whichname, &direntry);    /* add version suffix */
  332.                 }
  333.                 namelen = strlen (whichname);
  334.  
  335. #define MARGIN            78
  336. #define COL_WIDTH        16
  337. #if 1
  338.                 /* if not enough space left, move to next line */
  339.                 if (!one_col && column != 0) {
  340.                     space_left = MARGIN - column;
  341.                     if (namelen > space_left) {
  342.                         neednl = 1;
  343.                         column = 0;
  344.                     }
  345.                 }
  346. #endif
  347.             if ( (quiet && !first_ever || !first_time) && (neednl || one_col))
  348.                     printf ("\n");
  349.                 first_ever = 0;
  350.                 neednl = 0;
  351.  
  352.             printf("%s", whichname);
  353.                 fflush (stdout);
  354.                 /* move to next column stop */
  355.                 column += namelen;
  356.                 next_col = ((column + (COL_WIDTH - 1)) / COL_WIDTH) * COL_WIDTH;
  357.                 if (next_col - column < 2)        /* need at least 2 spaces */
  358.                     next_col += COL_WIDTH;
  359.                 if (next_col > MARGIN) {
  360.                     neednl = 1;
  361.                     column = 0;
  362.                 } else {
  363.                     if (!one_col)
  364.                         printf ("%*s", (next_col - column), " ");
  365.                     column = next_col;
  366.                 }
  367.  
  368.          } else {
  369.             if (talking && first_time && !show_name) {/*print archive header */
  370.                printf ("Length    CF  Size Now  Date      Time\n");
  371.                printf (tot_line);
  372.             }
  373.             printf ("%8lu %3u%% %8lu  %2d %-.3s %02d %02d:%02d:%02d",
  374.                      direntry.org_size,
  375.                      size_factor, direntry.size_now,
  376.                      day, &month_list[month*3],
  377.                      (day && month) ?  (year+80) % 100 : 0,
  378.                      hours, min, sec);
  379.                tot_org_siz += direntry.org_size;
  380.                tot_siz_now += direntry.size_now;
  381. #ifdef GETTZ
  382.                 printtz ((int) direntry.tz);    /* show timezone */
  383. #else
  384.                 printf (" ");
  385. #endif
  386.  
  387.                 if (show_crc)
  388.                     printf ("%04x ", direntry.file_crc);
  389.                 if (show_gen) {
  390.                     if (direntry.vflag & VFL_ON)
  391.                         printf ("%2dg ", direntry.vflag & VFL_GEN);
  392.                     else
  393.                         printf ("--g ");
  394.                 }
  395.  
  396.             if (direntry.cmt_size) {
  397.                expl_comment++;
  398.                printf ("C");
  399.             } else
  400.                printf (" ");
  401.  
  402.             if (direntry.deleted) {
  403.                expl_deleted++;
  404.                printf ("D");
  405.             }  else
  406.                printf (" ");
  407.             if (list_deleted)
  408.                printf (" ");
  409.             if (show_name)
  410.                printf ("%-*s ", longest, this_zoo);
  411.  
  412. #ifdef FATTR
  413.                 if (show_mode) {
  414.                     if (direntry.fattr == 0)
  415.                         printf ("--- ");
  416.                     else if ((direntry.fattr >> 22) == 1)
  417.                         printf ("%03o ", direntry.fattr & 0x1ff);
  418.                     else
  419.                         printf ("??? ");
  420.                 }
  421. #endif /* FATTR */
  422.  
  423.                 /* new code to get around a common compiler bug */
  424.                 printf ("%s", whichname);
  425.                 if (direntry.dir_crc != 0) {
  426.                     expl_star++;
  427.                     printf ("*");
  428.                 }
  429.  
  430.             if (bad_pack)
  431.                printf (" (V%d.%d)", direntry.major_ver, direntry.minor_ver);
  432.             printf ("\n");
  433.          }
  434.          first_time = 0;
  435.  
  436.          /* if verbose listing requested show any comment.  f overrrides v */
  437.          if (verb_list && !fast)
  438.             show_comment (&direntry, zoo_file, 0, (char *) NULL);
  439.       } /* end if (lots of conditions) */
  440.  
  441.         /* ..seek to next dir entry */
  442.       zooseek (zoo_file, direntry.next, 0);
  443.    } /* end while */
  444.  
  445.    givesummary:
  446.  
  447.     if (fast && talking) {
  448.        if (file_count) {
  449.            if (del_count || (show_gen && zoo_header.type > 0))
  450.               printf ("\n-----\n");
  451.             else
  452.               fputchar ('\n');
  453.         }
  454.         if (del_count)
  455.             printf ("%d deleted.\n", del_count);
  456.         if (show_gen && zoo_header.type > 0) {
  457.             printf ("Generation limit %u",
  458.                         zoo_header.vdata & VFL_GEN);
  459.             if ((zoo_header.vdata & VFL_ON) == 0)
  460.                 printf (" (off).\n");
  461.             else
  462.                 printf (".\n");
  463.         }
  464.     } /* end if (fast && talking) */
  465.  
  466.    if (talking && !show_name) {
  467.       if (!fast && file_count) {
  468.          tot_sf = cfactor (tot_org_siz, tot_siz_now);
  469.          printf (tot_line);
  470.  
  471.          printf (tot_fmt, tot_org_siz, tot_sf, tot_siz_now, file_count);
  472.             if (file_count > 1)
  473.                 printf ("s\n");
  474.             else
  475.                 printf ("\n");
  476.  
  477.          if (del_count || expl_ver || expl_deleted || expl_comment ||
  478.                     expl_star || (show_gen && (zoo_header.type > 0)))
  479.             printf (dashes);
  480.       }
  481.  
  482.       if (!fast) {
  483.          if (del_count) {
  484.             if (expl_deleted)
  485.                printf ("D: deleted file.\n");
  486.             else {
  487.                if (del_count == 1)
  488.                   printf ("There is 1 deleted file.\n");
  489.                else
  490.                   printf ("There are %d deleted files.\n", del_count);
  491.             }
  492.          }
  493.       }
  494.       if (expl_comment && !fast && !verb_list)
  495.          printf ("C: file has attached comment.\n");
  496.       if (expl_ver && !fast)
  497.          printf ("V: minimum version of Zoo needed to extract this file.\n");
  498.       if (expl_star && !fast)
  499.          printf ("*: directory entry may be corrupted.\n");
  500.       if (!file_count)
  501.          printf ("Zoo:  %s", no_match);
  502.  
  503.       if (!entrycount && !fiz_ofs)
  504.          printf ("(The archive is empty.)\n");
  505.         if (show_gen && (zoo_header.type > 0) && !fast) {
  506.             printf ("Archive generation limit is %u",
  507.                         zoo_header.vdata & VFL_GEN);
  508.             if ((zoo_header.vdata & VFL_ON) == 0)
  509.                 printf (" (generations off).\n");
  510.             else
  511.                 printf (".\n");
  512.         }
  513.    } /* end if (talking && !show_name) */
  514. loop_end:            /* jump here on badly structured archive */
  515.    zooclose (zoo_file);
  516. } /* end for */
  517.  
  518. if (talking && show_name) {
  519.    if (file_count) {
  520.       tot_sf = cfactor (tot_org_siz, tot_siz_now);
  521.       printf (tot_line);
  522.       printf (tot_fmt, tot_org_siz, tot_sf, tot_siz_now, file_count);
  523.         if (file_count > 1)
  524.             printf ("s\n");
  525.         else
  526.             printf ("\n");
  527.    }
  528. } else if (fast && quiet)
  529.     fputchar ('\n');
  530.  
  531.  
  532. if (!file_count)
  533.    zooexit (1);            /* Consider it an error if there were no files */
  534. } /* zoolist() */
  535.  
  536. #ifdef GETTZ
  537. void printtz (file_tz)
  538. int file_tz;
  539. {
  540.     long gettz();
  541.     int diff_tz;                /* timezone difference */
  542.     if (file_tz == NO_TZ)     /* if no timezone stored ..*/
  543.         printf ("   ");            /* .. just pad with blanks */
  544.     else {
  545.         diff_tz = (file_tz / 4) - (int) (gettz() / 3600);
  546.         if (diff_tz == 0)
  547.             printf ("   ");                    /* print nothing if same */
  548.         else if (diff_tz > 0)            /* else print signed difference */
  549.             printf ("+%1d ", diff_tz);
  550.         else
  551.             printf ("-%1d ", -diff_tz);
  552.     }
  553. }
  554. #endif
  555.  
  556. /*
  557. FOLLOWING CODE IS FOR DEBUGGING ONLY.  IT IS COMPILED IN ONLY
  558. IF THE SYMBOL TRACE_LIST IS DEFINED
  559. */
  560.  
  561. #ifdef TRACE_LIST
  562. /* code copied from portable.c near end */
  563. /* dump contents of directory entry */
  564. void show_dir (direntry)
  565. struct direntry *direntry;
  566. {
  567.    printf ("Directory entry for file [%s][%s]:\n",
  568.             direntry->fname, direntry->lfname);
  569.    printf ("tag = [%8lx] type = [%d] PM = [%d] Next = [%8lx] Offset = [%8lx]\n",
  570.             direntry->zoo_tag, (int) direntry->type,
  571.             (int) direntry->packing_method, direntry->next,
  572.             direntry->offset);
  573.    printf ("Orig size = [%ld] Size now = [%ld] dmaj_v.dmin_v = [%d.%d]\n",
  574.          direntry->org_size, direntry->size_now,
  575.          (int) direntry->major_ver, (int) direntry->minor_ver);
  576.    printf ("Struc = [%d] DEL = [%d] comment_offset = [%8lx] cmt_size = [%d]\n",
  577.          (int) direntry->struc, (int) direntry->deleted, direntry->comment,
  578.          direntry->cmt_size);
  579.    printf ("var_dir_len = [%d] TZ = [%d] dir_crc = [%4x]\n",
  580.             direntry->var_dir_len, (int) direntry->tz, direntry->dir_crc);
  581.    printf ("system_id = [%d]  dirlen = [%d]  namlen = [%d] fattr=[%24lx]\n",
  582.         direntry->system_id, direntry->dirlen, direntry->namlen, direntry->fattr);
  583.     printf ("vflag = [%4x] version_no = [%4x]\n",
  584.                 direntry->vflag, direntry->version_no);
  585.    if (direntry->dirlen > 0)
  586.       printf ("dirname = [%s]\n", direntry->dirname);
  587.    printf ("---------\n");
  588. }
  589. #endif   /* TRACE_IO */
  590.