🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.utils.bug
Article #561

(none)

#561
From: Norbert Kiesel
Date: Fri, 24 Nov 1989 16:05
670 lines
22877 bytes
The follwing patch to DIFF-1.7 adds a -v option for printing
the version number and gives a better usage message.
It's not perfect, but better than no documentation at all.

so long

		Norbert







*** Makefile~	Fri Nov 24 16:07:17 1989
--- Makefile	Fri Nov 24 16:07:18 1989
***************
*** 35,43 ****
  
  # All source files
  srcs=diff.c analyze.c io.c context.c ed.c normal.c util.c dir.c diff.h \
! 	regex.c regex.h limits.h diff3.c
  # Object files for diff only.
! objs=diff.o analyze.o io.o context.o ed.o normal.o util.o dir.o regex.o
  tapefiles = $(srcs) README diagmeet.note Makefile COPYING
  
  all: diff diff3
--- 35,44 ----
  
  # All source files
  srcs=diff.c analyze.c io.c context.c ed.c normal.c util.c dir.c diff.h \
! 	regex.c regex.h limits.h diff3.c version.c getopt.c
  # Object files for diff only.
! objs=diff.o analyze.o io.o context.o ed.o normal.o util.o dir.o regex.o\
! 	version.o getopt.o
  tapefiles = $(srcs) README diagmeet.note Makefile COPYING
  
  all: diff diff3
*** diff.c~	Fri Nov 24 16:07:18 1989
--- diff.c	Fri Nov 24 16:07:18 1989
***************
*** 76,81 ****
--- 76,82 ----
  
    extern int optind;
    extern char *optarg;
+   extern char *version_string;
  
    program = argv[0];
  
***************
*** 103,111 ****
    msg_chain_end = NULL;
    no_discards = 0;
  
    /* Decode the options.  */
  
!   while ((c = getopt (argc, argv, "0123456789abBcC:defF:hHiI:lnNprsS:tTw"))
  	 != EOF)
      {
        switch (c)
--- 104,113 ----
    msg_chain_end = NULL;
    no_discards = 0;
  
+ 
    /* Decode the options.  */
  
!   while ((c = getopt (argc, argv, "v0123456789abBcC:defF:hHiI:lnNprsS:tTw"))
  	 != EOF)
      {
        switch (c)
***************
*** 266,275 ****
--- 268,328 ----
  	  tab_align_flag = 1;
  	  break;
  
+ 	case 'v':
+ 	  /* Print version number and exit. */
+ 	  printf("%s",version_string);
+ 	  exit(0);
+ 	  break;
+ 
  	case 'w':
  	  /* Ignore horizontal whitespace when comparing lines.  */
  	  ignore_all_space_flag = 1;
  	  length_varies = 1;
+ 	  break;
+ 
+ 	case '?':
+ 	  /* Give a list of all possible options and exit */
+ 	  printf("%s",version_string);
+ 	  printf("-[0-9]+\tSpecify context length.\n");
+ 	  printf("-a\tTreat all files as text files; never treat as binary.\n");
+ 	  printf("-b\tIgnore changes in amount of whitespace.\n");
+ 	  printf("-B\tIgnore changes affecting only blank lines.\n");
+ 	  printf("-c\tMake context-style output.\n");
+ 	  printf("-C\tDon't discard lines.  This makes things slower (sometimes much\
+ \n\tslower) but will find a guaranteed minimal set of changes.\n");
+ 	  printf("-e\tMake output that is a valid `ed' script.\n");
+ 	  printf("-f\tMake output that looks vaguely like an `ed' script\
+ \n\tbut has changes in the order they appear in the file.\n");
+ 	  printf("-F\tShow, for each set of changes, the previous line that\
+ \n\tmatches the specified regexp.  Currently affects only\
+ \n\tcontext-style output.\n");
+ 	  printf("-h\tSplit the files into chunks of around 1500 lines\
+ \n\tfor faster processing.  Usually does not change the result.\
+ \n\tThis currently has no effect.\n");
+ 	  printf("-H\tTurn on heuristics that speed processing of large files\
+ \n\twith a small density of changes.\n");
+ 	  printf("-i\tIgnore changes in case.\n");
+ 	  printf("-I\tIgnore changes affecting only lines that match the\
+ \n\tspecified regexp.\n");
+ 	  printf("-l\tPass the output through `pr' to paginate it.\n");
+ 	  printf("-n\tOutput RCS-style diffs, like `-f' except that each command\
+ \n\tspecifies the number of lines affected.\n");
+ 	  printf("-N\tWhen comparing directories, if a file appears only in one\
+ \n\tdirectory, treat it as present but empty in the other.\n");
+ 	  printf("-p\tMake context-style output and show name of last C function.\n");
+ 	  printf("-r\tWhen comparing directories, \
+ \n\trecursively compare any subdirectories found.\n");
+ 	  printf("-s\tPrint a message if the files are the same.\n");
+ 	  printf("-S\tWhen comparing directories, start with the specified\
+ \n\tfile name.  This is used for resuming an aborted comparison.\n");
+ 	  printf("-t\tExpand tabs to spaces in the output so that it preserves\
+ \n\tthe alignment of the input files.\n");
+ 	  printf("-T\tUse a tab in the output, rather than a space, before the\
+ \n\ttext of an input line, so as to keep the proper alignment\
+ \n\tin the input line without changing the characters in it.\n");
+ 	  printf("-v\tPrint version number and exit.\n");
+ 	  printf("-w\tIgnore horizontal whitespace when comparing lines.\n");
+ 	  exit(0);
  	  break;
  	}
        prev = c;
*** /dev/null	Fri Nov 24 15:00:58 1989
--- version.c	Fri Nov 24 16:07:18 1989
***************
*** 0 ****
--- 1,23 ----
+ /* GNU DIFF main routine.
+    Copyright (C) 1988, 1989 Free Software Foundation, Inc.
+ 
+ This file is part of GNU DIFF.
+ 
+ GNU DIFF is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+ 
+ GNU DIFF is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GNU DIFF; see the file COPYING.  If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ /* GNU DIFF was written by Mike Haertel, David Hayes,
+    Richard Stallman and Len Tower.  */
+ 
+ char *version_string="GNU Diff version 1.7\n";
*** /dev/null	Fri Nov 24 15:00:58 1989
--- getopt.c	Fri Nov 24 16:07:18 1989
***************
*** 0 ****
--- 1,489 ----
+ /* Getopt for GNU.
+    Copyright (C) 1987, 1989 Free Software Foundation, Inc.
+ 
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 1, or (at your option)
+    any later version.
+ 
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+ 
+ 
+ 
+ /* This version of `getopt' appears to the caller like standard Unix `getopt'
+    but it behaves differently for the user, since it allows the user
+    to intersperse the options with the other arguments.
+ 
+    As `getopt' works, it permutes the elements of `argv' so that,
+    when it is done, all the options precede everything else.  Thus
+    all application programs are extended to handle flexible argument order.
+ 
+    Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
+    Then the behavior is completely standard.
+ 
+    GNU application programs can use a third alternative mode in which
+    they can distinguish the relative order of options and other arguments.  */
+ 
+ #include <stdio.h>
+ 
+ /* If compiled with GNU C, use the built-in alloca */
+ #ifdef __GNUC__
+ #define alloca __builtin_alloca
+ #else /* not __GNUC__ */
+ #ifdef sparc
+ #include <alloca.h>
+ #endif
+ #endif /* not __GNUC__ */
+ 
+ #ifdef USG
+ #define bcopy(s, d, l) memcpy((d), (s), (l))
+ #define index strchr
+ #endif
+ 
+ /* For communication from `getopt' to the caller.
+    When `getopt' finds an option that takes an argument,
+    the argument value is returned here.
+    Also, when `ordering' is RETURN_IN_ORDER,
+    each non-option ARGV-element is returned here.  */
+ 
+ char *optarg = 0;
+ 
+ /* Index in ARGV of the next element to be scanned.
+    This is used for communication to and from the caller
+    and for communication between successive calls to `getopt'.
+ 
+    On entry to `getopt', zero means this is the first call; initialize.
+ 
+    When `getopt' returns EOF, this is the index of the first of the
+    non-option elements that the caller should itself scan.
+ 
+    Otherwise, `optind' communicates from one call to the next
+    how much of ARGV has been scanned so far.  */
+ 
+ int optind = 0;
+ 
+ /* The next char to be scanned in the option-element
+    in which the last option character we returned was found.
+    This allows us to pick up the scan where we left off.
+ 
+    If this is zero, or a null string, it means resume the scan
+    by advancing to the next ARGV-element.  */
+ 
+ static char *nextchar;
+ 
+ /* Callers store zero here to inhibit the error message
+    for unrecognized options.  */
+ 
+ int opterr = 1;
+ 
+ /* Describe how to deal with options that follow non-option ARGV-elements.
+ 
+    UNSPECIFIED means the caller did not specify anything;
+    the default is then REQUIRE_ORDER if the environment variable
+    _OPTIONS_FIRST is defined, PERMUTE otherwise.
+ 
+    REQUIRE_ORDER means don't recognize them as options.
+    Stop option processing when the first non-option is seen.
+    This is what Unix does.
+ 
+    PERMUTE is the default.  We permute the contents of `argv' as we scan,
+    so that eventually all the options are at the end.  This allows options
+    to be given in any order, even with programs that were not written to
+    expect this.
+ 
+    RETURN_IN_ORDER is an option available to programs that were written
+    to expect options and other ARGV-elements in any order and that care about
+    the ordering of the two.  We describe each non-option ARGV-element
+    as if it were the argument of an option with character code zero.
+    Using `-' as the first character of the list of option characters
+    requests this mode of operation.
+ 
+    The special argument `--' forces an end of option-scanning regardless
+    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+    `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
+ 
+ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering;
+ 
+ /* Describe the long-named options requested by the application.
+    _GETOPT_LONG_OPTIONS is a vector of `struct option' terminated by an
+    element containing a name which is zero.
+    The field `has_arg' is 1 if the option takes an argument, 
+    2 if it takes an optional argument.  */
+ 
+ struct option
+ {
+   char *name;
+   int has_arg;
+   int *flag;
+   int val;
+ };
+ 
+ struct option *_getopt_long_options;
+ 
+ /* Name of long-named option actually found.  */
+ 
+ char *_getopt_option_name = '\0';
+ 
+ int  option_index = 0;
+ 
+ /* Handle permutation of arguments.  */
+ 
+ /* Describe the part of ARGV that contains non-options that have
+    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+    `last_nonopt' is the index after the last of them.  */
+ 
+ static int first_nonopt;
+ static int last_nonopt;
+ 
+ /* Exchange two adjacent subsequences of ARGV.
+    One subsequence is elements [first_nonopt,last_nonopt)
+     which contains all the non-options that have been skipped so far.
+    The other is elements [last_nonopt,optind), which contains all
+     the options processed since those non-options were skipped.
+ 
+    `first_nonopt' and `last_nonopt' are relocated so that they describe
+     the new indices of the non-options in ARGV after they are moved.  */
+ 
+ static void
+ exchange (argv)
+      char **argv;
+ {
+   int nonopts_size
+     = (last_nonopt - first_nonopt) * sizeof (char *);
+   char **temp = (char **) alloca (nonopts_size);
+ 
+   /* Interchange the two blocks of data in argv.  */
+ 
+   bcopy (&argv[first_nonopt], temp, nonopts_size);
+   bcopy (&argv[last_nonopt], &argv[first_nonopt],
+ 	 (optind - last_nonopt) * sizeof (char *));
+   bcopy (temp, &argv[first_nonopt + optind - last_nonopt],
+ 	 nonopts_size);
+ 
+   /* Update records for the slots the non-options now occupy.  */
+ 
+   first_nonopt += (optind - last_nonopt);
+   last_nonopt = optind;
+ }
+ 
+ /* Scan elements of ARGV (whose length is ARGC) for option characters
+    given in OPTSTRING.
+ 
+    If an element of ARGV starts with '-', and is not exactly "-" or "--",
+    then it is an option element.  The characters of this element
+    (aside from the initial '-') are option characters.  If `getopt'
+    is called repeatedly, it returns successively each of theoption characters
+    from each of the option elements.
+ 
+    If `getopt' finds another option character, it returns that character,
+    updating `optind' and `nextchar' so that the next call to `getopt' can
+    resume the scan with the following option character or ARGV-element.
+ 
+    If there are no more option characters, `getopt' returns `EOF'.
+    Then `optind' is the index in ARGV of the first ARGV-element
+    that is not an option.  (The ARGV-elements have been permuted
+    so that those that are not options now come last.)
+ 
+    OPTSTRING is a string containing the legitimate option characters.
+    A colon in OPTSTRING means that the previous character is an option
+    that wants an argument.  The argument is taken from the rest of the
+    current ARGV-element, or from the following ARGV-element,
+    and returned in `optarg'.
+ 
+    If an option character is seen that is not listed in OPTSTRING,
+    return '?' after printing an error message.  If you set `opterr' to
+    zero, the error message is suppressed but we still return '?'.
+ 
+    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+    so the following text in the same ARGV-element, or the text of the following
+    ARGV-element, is returned in `optarg.  Two colons mean an option that
+    wants an optional arg; if there is text in the current ARGV-element,
+    it is returned in `optarg'.
+ 
+    If OPTSTRING starts with `-', it requests a different method of handling the
+    non-option ARGV-elements.  See the comments about RETURN_IN_ORDER, above.  */
+ 
+ int
+ getopt (argc, argv, optstring)
+      int argc;
+      char **argv;
+      char *optstring;
+ {
+   optarg = 0;
+ 
+   /* Initialize the internal data when the first call is made.
+      Start processing options with ARGV-element 1 (since ARGV-element 0
+      is the program name); the sequence of previously skipped
+      non-option ARGV-elements is empty.  */
+ 
+   if (optind == 0)
+     {
+       first_nonopt = last_nonopt = optind = 1;
+ 
+       nextchar = 0;
+ 
+       /* Determine how to handle the ordering of options and nonoptions.  */
+ 
+       if (optstring[0] == '-')
+ 	ordering = RETURN_IN_ORDER;
+       else if (getenv ("_POSIX_OPTION_ORDER") != 0)
+ 	ordering = REQUIRE_ORDER;
+       else
+ 	ordering = PERMUTE;
+     }
+ 
+   if (nextchar == 0 || *nextchar == 0)
+     {
+       if (ordering == PERMUTE)
+ 	{
+ 	  /* If we have just processed some options following some non-options,
+ 	     exchange them so that the options come first.  */
+ 
+ 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+ 	    exchange (argv);
+ 	  else if (last_nonopt != optind)
+ 	    first_nonopt = optind;
+ 
+ 	  /* Now skip any additional non-options
+ 	     and extend the range of non-options previously skipped.  */
+ 
+ 	  while (optind < argc
+ 		 && (argv[optind][0] != '-'
+ 		     || argv[optind][1] == 0)
+ 		 && (argv[optind][0] != '+'
+ 		     || argv[optind][1] == 0))
+ 	    optind++;
+ 	  last_nonopt = optind;
+ 	}
+ 
+       /* Special ARGV-element `--' means premature end of options.
+ 	 Skip it like a null option,
+ 	 then exchange with previous non-options as if it were an option,
+ 	 then skip everything else like a non-option.  */
+ 
+       if (optind != argc && !strcmp (argv[optind], "--"))
+ 	{
+ 	  optind++;
+ 
+ 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+ 	    exchange (argv);
+ 	  else if (first_nonopt == last_nonopt)
+ 	    first_nonopt = optind;
+ 	  last_nonopt = argc;
+ 
+ 	  optind = argc;
+ 	}
+ 
+       /* If we have done all the ARGV-elements, stop the scan
+ 	 and back over any non-options that we skipped and permuted.  */
+ 
+       if (optind == argc)
+ 	{
+ 	  /* Set the next-arg-index to point at the non-options
+ 	     that we previously skipped, so the caller will digest them.  */
+ 	  if (first_nonopt != last_nonopt)
+ 	    optind = first_nonopt;
+ 	  return EOF;
+ 	}
+ 	 
+       /* If we have come to a non-option and did not permute it,
+ 	 either stop the scan or describe it to the caller and pass it by.  */
+ 
+       if ((argv[optind][0] != '-' || argv[optind][1] == 0)
+ 	  && (argv[optind][0] != '+' || argv[optind][1] == 0))
+ 	{
+ 	  if (ordering == REQUIRE_ORDER)
+ 	    return EOF;
+ 	  optarg = argv[optind++];
+ 	  return 0;
+ 	}
+ 
+       /* We have found another option-ARGV-element.
+ 	 Start decoding its characters.  */
+ 
+       nextchar = argv[optind] + 1;
+     }
+ 
+   if (_getopt_long_options != 0 && argv[optind][0] == '+') {
+       struct option *p;
+       char *s = nextchar;
+       while (*s && *s != '=') s++;
+ 
+       for (p = _getopt_long_options, option_index = 0; p->name; 
+       		p++, option_index++) {
+ 
+ 	if (!strncmp (p->name, nextchar, s - nextchar))
+ 	  {
+ 	    optind++;
+ 	    if (*s)
+ 	      {
+ 		if (p->has_arg > 0)
+ 		  optarg = s + 1;
+ 		else {
+ 		    fprintf (stderr, "%s: option +%s doesn't allow an argument\n",
+ 			   argv[0], p->name);
+ 		    nextchar += strlen (nextchar);			   
+ 		    return '?';
+ 		  }
+ 	      }
+ 	    else if (p->has_arg)
+ 	      {
+ 		if (optind + 1 < argc)
+ 		  optarg = argv[optind++];
+ 		else if (p->has_arg != 2) {
+ 		    fprintf (stderr, "%s: option +%s requires an argument\n",
+ 			   argv[0], p->name);
+ 		    nextchar += strlen (nextchar);		   
+ 		    return '?';
+ 		}
+ 	    }
+ 	    _getopt_option_name = p->name;
+ 	    nextchar += strlen (nextchar);
+ 	    if (p->flag)
+ 	      *(p->flag) = p->val;
+ 	    return 0;
+ 	 }
+       }
+    }
+  
+   /* Look at and handle the next option-character.  */
+ 
+   {
+     char c = *nextchar++;
+     char *temp = (char *) index (optstring, c);
+ 
+     /* Increment `optind' when we start to process its last character.  */
+     if (*nextchar == 0)
+       optind++;
+ 
+     if (temp == 0 || c == ':')
+       {
+ 	if (opterr != 0)
+ 	  {
+ 	    if (c < 040 || c >= 0177)
+ 	      fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+ 		       argv[0], c);
+ 	    else
+ 	      fprintf (stderr, "%s: unrecognized option `-%c'\n",
+ 		       argv[0], c);
+ 	  }
+ 	return '?';
+       }
+     if (temp[1] == ':')
+       {
+ 	if (temp[2] == ':')
+ 	  {
+ 	    /* This is an option that accepts an argument optionally.  */
+ 	    if (*nextchar != 0)
+ 	      {
+ 	        optarg = nextchar;
+ 		optind++;
+ 	      }
+ 	    else
+ 	      optarg = 0;
+ 	    nextchar = 0;
+ 	  }
+ 	else
+ 	  {
+ 	    /* This is an option that requires an argument.  */
+ 	    if (*nextchar != 0)
+ 	      {
+ 		optarg = nextchar;
+ 		/* If we end this ARGV-element by taking the rest as an arg,
+ 		   we must advance to the next element now.  */
+ 		optind++;
+ 	      }
+ 	    else if (optind == argc)
+ 	      {
+ 		if (opterr != 0)
+ 		  fprintf (stderr, "%s: no argument for `-%c' option\n",
+ 			   argv[0], c);
+ 		c = '?';
+ 	      }
+ 	    else
+ 	      /* We already incremented `optind' once;
+ 		 increment it again when taking next ARGV-elt as argument.  */
+ 	      optarg = argv[optind++];
+ 	    nextchar = 0;
+ 	  }
+       }
+     return c;
+   }
+ }
+ 
+ #ifdef TEST
+ 
+ /* Compile with -DTEST to make an executable for use in testing
+    the above definition of `getopt'.  */
+ 
+ int
+ main (argc, argv)
+      int argc;
+      char **argv;
+ {
+   char c;
+   int digit_optind = 0;
+ 
+   while (1)
+     {
+       int this_option_optind = optind;
+       if ((c = getopt (argc, argv, "abc:d:0123456789")) == EOF)
+ 	break;
+ 
+       switch (c)
+ 	{
+ 	case '0':
+ 	case '1':
+ 	case '2':
+ 	case '3':
+ 	case '4':
+ 	case '5':
+ 	case '6':
+ 	case '7':
+ 	case '8':
+ 	case '9':
+ 	  if (digit_optind != 0 && digit_optind != this_option_optind)
+ 	    printf ("digits occur in two different argv-elements.\n");
+ 	  digit_optind = this_option_optind;
+ 	  printf ("option %c\n", c);
+ 	  break;
+ 
+ 	case 'a':
+ 	  printf ("option a\n");
+ 	  break;
+ 
+ 	case 'b':
+ 	  printf ("option b\n");
+ 	  break;
+ 
+ 	case 'c':
+ 	  printf ("option c with value `%s'\n", optarg);
+ 	  break;
+ 
+ 	case '?':
+ 	  break;
+ 
+ 	default:
+ 	  printf ("?? getopt returned character code 0%o ??\n", c);
+ 	}
+     }
+ 
+   if (optind < argc)
+     {
+       printf ("non-option ARGV-elements: ");
+       while (optind < argc)
+ 	printf ("%s ", argv[optind++]);
+       printf ("\n");
+     }
+ 
+   return 0;
+ }
+ 
+ #endif /* TEST */


*******************************************************************************
* Norbert Kiesel                                       NN       NN    KK   KK *
* Institut fuer Informatik III         		       NNN      NN    KK  KK  *
* RWTH Aachen                          		       NN N     NN    KK KK   *
*                                      		       NN  N    NN    KKKK    *
* Tel.: (0241) 80-7266                 		       NN   N   NN    KKKK    *
*                                      		       NN    N  NN    KK KK   *
* EUNET: norbert@rwthi3.uucp           		       NN     N NN    KK  KK  *
*        ...!mcvax!unido!rwthi3!norbert		       NN      NNN    KK   KK *
*******************************************************************************
Technical Details
Message-ID: <8911241605.AA02268@rwthi3.informatik.rwth-aachen.de>
Path: arc1-ca.pugleaf.net!utzoo!telly!philmtl!uunet!tut.cis.ohio-state.edu!uunet.uu.net!rwthinf!norbert%rwthi3

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!telly!philmtl!uunet!tut.cis.ohio-state.edu!uunet.uu.net!rwthinf!norbert%rwthi3
From: rwthinf!norbert%rwthi3@uunet.uu.net (Norbert Kiesel)
Newsgroups: gnu.utils.bug
Subject: (none)
Message-ID: <8911241605.AA02268@rwthi3.informatik.rwth-aachen.de>
Date: 24 Nov 89 16:05:50 GMT
Sender: daemon@tut.cis.ohio-state.edu
Distribution: gnu
Organization: GNUs Not Usenet
Lines: 670