[net.sources] Gloria for Unix shar format, 1 part

mlm@cmu-cs-cad.ARPA (Michael Mauldin) (02/24/85)

#!/bin/sh
#
# This is a shell archive.  Use the unshar command to unpack it, or
# remove the mail header and pipe the message through the "sh" command.
# 
# This message contains two files:
# 
# 	gloria.c			The C code for Gloria
# 	gloria.1			Manual entry
# 
# Gloria is a facility for perusing plan files which have changed
# recently.  It is based on the original TOPS10 Gloria program
# written by Mike Kazar at CMU.
# 
# Every time gloria is run, it prints out all plan files on the system
# which have been modified since the last time Gloria was run.  Options
# provide the ability to skip very large plan files, or plan files from
# users whose plans and opinions you wish not to see.
# 
# Share and Enjoy!
# 
# Michael L. Mauldin (Fuzzy)		Department of Computer Science
# Mauldin@CMU-CS-CAD.ARPA			Carnegie-Mellon University
# (412) 578-3065				Pittsburgh, PA  15213
#
echo 'Start of Gloria distribution:'
echo 'x - gloria.1'
sed 's/^X//' > gloria.1 << '/'
X.TH GLORIA 1 02/20/85
X.CM 3
X.SH "NAME"
XGloria \- print new plan files.
X.SH "SYNOPSIS"
Xgloria [ -r ] [ -t<tasteful> ] [ list of userids to ignore ]
X.SH "DESCRIPTION"
X.PP
X.I Gloria
Xprints out the plan files which have changed since Gloria
Xwas last run. Files larger than
X.I tasteful
Xare not printed, and files belonging to userids listed in the command
Xline are ignored completely.
X.PP
XForm feeds are not echoed, and adjacent multiple entries in /etc/passwd do
Xnot result in multiple plan file listings.
X.SH OPTIONS
X.TP
X.B -r
X.I restart
Xoption, print all plan files regardless of when Gloria was last run.
X.TP
X.B -tNNN
X.I tasteful
Xoption.  Restricts printing of plan files to a given size. For example:
X.sp
X	gloria -t2000
X.sp
Xwill print all new plan files not larger than 2000 bytes.
XThe default is 5000 bytes, and can be overridden using the TASTEFUL
Xenvironment variable.
X.TP
X.I ignore
Xoption, the rest of the command line is a list of userids to ignore.
XAny userids in the IGNORE environment variable are also ignored.
XThis can be useful if certain plan files contain massive amounts of
Xuseless flaming.
X.PP
X.SH "FILES"
X.PP
X.I Gloria
Xcreates a file .gloria.glo in the user's home directory, as specified by
Xthe HOME environment variable.
X.SH "SEE ALSO"
X.PP
X"Doc Gloria" on CMU-CS-A.
X.SH HISTORY
X.TP
X22-Feb-85  Michael Mauldin (mlm) at Carnegie-Mellon University
XAdded the TASTEFUL and IGNORE options.
X.TP
X20-Sep-82  Michael Mauldin (mlm) at Carnegie-Mellon University
XCreated.  Original concept from Michael Kazar at CMU-CS-A.
X
/
echo 'x - gloria.c'
sed 's/^X//' > gloria.c << '/'
X/* 
X * Gloria: Display all plan files that have changed since gloria was
X * last run. A plan file is .plan in the user's home directory. 
X * A file called .gloria.glo is kept in the home directory and modified
X * each time gloria is run so the last time can be found using stat.
X * If no plan file is found, or if it has not changed, it is skipped over.
X *
X * If any argument is given, Gloria will display all plan files, and
X * reset the last time run.
X *
X * HISTORY
X * 06-Jun-82  Michael Mauldin (mlm) at Carnegie-Mellon University
X *	Created, original concept by Mike Kazar.
X */
X
X# include <stdio.h>
X# include <ctype.h>
X# include <sys/types.h>
X# include <sys/stat.h>
X# include <pwd.h>
X
X# define PLANFILE	".plan"
X# define GLOFILE	".gloria.glo"
X# define TASTEFUL	5000
X# define SKIPARG	while (*++(*argv)); --(*argv)
X# define foldupper(c)	(isupper(c) ? c : toupper(c))
X
Xmain (argc, argv)
Xint   argc;
Xchar *argv[];
X{ struct passwd *userent, *getpwent();
X  time_t lastread;
X  struct stat pbuf;
X  char planfn[128], lastfile[128], badusers[BUFSIZ], *sindex(), *getenv();
X  register char *s;
X  int restart=0, taste=TASTEFUL;
X  register int ch, lastch=0;
X  register FILE *planfile;
X
X  *badusers = '\0';
X
X  /* set defaults from environment variables */
X  if ((s = getenv ("TASTEFUL")) && isdigit (*s)) taste = atoi (s);
X  if ((s = getenv ("IGNORE"))) strcat (badusers, s);
X
X  /* get the arguments */
X  while (--argc > 0 && (*++argv)[0] == '-')
X  { while (*++(*argv))
X    { switch (**argv)
X      {	case 'r': restart++;
X        case 't': taste = atoi (*argv+1); SKIPARG; break;
X        default:  fprintf (stderr, 
X		   "Usage: gloria [-r] [-t<tasteful>] [userids to ignore]\n");
X		  exit (1);
X      }
X    }
X  }
X
X  while (argc-- > 0)
X  { strcat (badusers, " ");
X    strcat (badusers, *argv++);
X  }
X
X  printf ("Sic Transit Gloria Thursdi\n\n");
X
X  /* Getlastgloria finds the time we last ran gloria */
X  getlastgloria (&lastread);
X
X  /* Now loop through all users */
X  while ((userent = getpwent ()) != NULL)
X  { /* Build a plan file name from the users HOME and PLANFILE */
X    sprintf (planfn, "%s/%s", userent->pw_dir, PLANFILE);
X
X    /* 
X     * If the user is not in the bad user list and the file is not the
X     * same as the last file (for systems where users can have multiple
X     * entries in /etc/passwd) AND the plan file exists AND the file is
X     * more recent than our last gloria run (or reset option), then
X     * print the file out, stripping form feeds.
X     */
X 
X    if (sindex (badusers, userent->pw_name) == NULL &&
X        strcmp (lastfile, planfn) != 0 &&
X        stat (planfn, &pbuf) == 0 &&
X        (restart || lastread <= pbuf.st_mtime))
X    { if (pbuf.st_size > taste)
X      { printf ("[ plan file too long to be tastefully printed ]\n");
X      }
X      else
X      { if ((planfile = fopen (planfn, "r")) == NULL)
X	{ printf ("File %s not accessable.\n", planfn); }
X	else
X	{ while ((ch = fgetc (planfile)) != EOF)
X	    if (ch != '\f')  putchar (lastch=ch);
X
X	  /* Check for file with missing newline at end */
X	  if (lastch != '\n') putchar ('\n');
X	  fclose (planfile); 
X	}
X      }
X
X      strcpy (lastfile, planfn);
X
X      /* 
X       * Get the name of the owner of the file and print a trailer;
X       * NULs and commas terminate the name, and '&' expands to
X       * the userid (capitalized).
X       */
X
X      printf ("  **==> That was ");
X      for (s=userent->pw_gecos; *s && *s != ','; s++)
X      { if (*s == '&')	printf ("%c%s", foldupper (*(userent->pw_name)),
X				(userent->pw_name)+1);
X	else		putchar (*s);
X      }
X      printf ("'s plan file\n\n");
X    }
X  }
X}
X
X/*
X * Getlastgloria: Keeps a file '.gloria.glo' in the users HOME directory
X * and touches it every time gloria is run. It returns the last time
X * the file was touched. Note that this routine is independent of the
X * restart mechanism, and always reports the last time gloria was run
X * (or 0 for the first time).
X */
X
Xgetlastgloria (readtime)
Xtime_t *readtime;
X{ struct stat statbuf;
X  char gloriafile[BUFSIZ], *getenv();  
X  int fd;
X
X  /* Construct the Gloria.glo file name */
X  sprintf (gloriafile, "%s/%s", getenv ("HOME"), GLOFILE);
X
X  /* Get the last time modified */
X  if (stat (gloriafile, &statbuf) == 0)
X    *readtime = statbuf.st_mtime;
X  else
X    *readtime = 0;
X
X  /* Now set the last time modified by "creat"ing the GLO file */
X  if ((fd = creat (gloriafile, 666)) < 0)
X    perror (gloriafile);
X  else
X    close (fd);
X}
X
X/*
X *  sindex  --  find index of one string within another
X *
X *  Usage:  p = sindex (big, small)
X *	char *p, *big, *small;
X *
X *  Sindex searches for a substring of big which matches small,
X *  and returns a pointer to this substring.  If no matching
X *  substring is found, 0 is returned.
X *
X * HISTORY
X * 02-Feb-85  Michael Mauldin (mlm) at Carnegie-Mellon University
X *	Ripped out of libcmu for portability.
X *
X * 26-Jun-81  David Smith (drs) at Carnegie-Mellon University
X *	Rewritten to avoid call on strlen(), and generally speed up things.
X *
X * 20-Nov-79  Steven Shafer (sas) at Carnegie-Mellon University
X *	Adapted for VAX from indexs() on the PDP-11 (thanx to Ralph
X *	Guggenheim).  The name has changed to be more like the index()
X *	and rindex() functions from Bell Labs; the return value (pointer
X *	rather than integer) has changed partly for the same reason,
X *	and partly due to popular usage of this function.
X *
X *  Originally from rjg (Ralph Guggenheim) on IUS/SUS UNIX.
X */
X
Xchar *sindex (big, small)
Xchar *big, *small;
X{ register char *bp, *bp1, *sp;
X  register char c = *small++;
X
X  if (c == NULL) return (NULL);
X
X  for (bp = big;  *bp;  bp++)
X  { if (*bp == c)
X    { for (sp = small, bp1 = bp+1;   *sp && *sp == *bp1++;  sp++) ;
X      if  (*sp == NULL) return (bp);
X    }
X  }
X
X  return (NULL);
X}
/
echo 'Gloria distribution complete.'
exit