[net.sources] PD checkmail

ries@trwrba.UUCP (Marc A. Ries) (02/28/86)

[LE]
# ---cut_here-----cut_here-----cut_here-----cut_here-----
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	Makefile
#	checkmail.1
#	checkmail.c
#	getopt.c
export PATH; PATH=/bin:$PATH
echo shar: extracting "'Makefile'" '(481 characters)'
if test -f 'Makefile'
then
	echo shar: over-writing existing file "'Makefile'"
fi
cat << \RIESES_PIECES > 'Makefile'
#
# Makefile: checkmail
#  Created: January 1986
#       By: Marc Ries
#
CC     = /bin/cc
OPTS   = -O -s 
DEFS   = -DBSD
CFLAGS = $(OPTS) $(DEFS)
SRCS   = getopt.c checkmail.c
OBJS   = getopt.o checkmail.o
LIBS   = 

all:	checkmail

checkmail:	$(OBJS)
	$(CC) $(CFLAGS) -o checkmail $(OBJS) $(LIBS)

clean:
	rm -f $(OBJS) a.out core

lint:
	lint -uvhp $(DEFS) $(SRCS)

shar:
	shar -v Makefile checkmail.[1clyh] getopt.c > checkmail.shr

edit:
	vi $(SRCS)
 
checkmail.o:	checkmail.c
RIESES_PIECES
echo shar: extracting "'checkmail.1'" '(1471 characters)'
if test -f 'checkmail.1'
then
	echo shar: over-writing existing file "'checkmail.1'"
fi
cat << \RIESES_PIECES > 'checkmail.1'
.TH CHECKMAIL "1" "February 1986" 
.SH NAME
checkmail \- check for the existence of email 
.SH USAGE
\fIcheckmail\fB [-b [-n\fIn\fB] [-s\fIn\fB] ] [-h] [-l\fIname\fB]
.SH OPTIONS
The following options are recognized:
.de OP\" option-letter [optional value]
.TP
.BI \\$1 \\$2
..
.OP -b 
Background mode: checkmail is placed in background for continuous
email checking.
.OP -n  n
Checkmail is invoked with a nice value of \fIn\fR.  The default
for \fIn\fR is 4.
.OP -s  n 
Checkmail is invoked with a sleep interval of \fIn\fR seconds.  
The default for \fIn\fR is 300 seconds.
.OP -l name 
The mailbox of an alternate login \fIname\fR will be checked.
The default is the current user's logname.
.OP -h 
A simple help/usage screen is displayed
.SH DESCRIPTION
.PP
.I checkmail
checks for the arrival of mail.  
By default 
the current user's mailbox is scanned for the existence of \fIany\fR mail. 
Options allow for the checking of an alternate user's mailbox and/or
continuously checking in the background for new email.
.SH SEE ALSO
getopt(1)
.SH DIAGNOSTICS
.I Checkmail
prints an error message on \fIstderr\fR if it can not get the current
\fIlogname\fR or change to the appropriate \fImail\fR directory.
.SH EXAMPLE
.nf
Continuously check \fIjohnd\fR's mailbox every 5 minutes:
	checkmail -l johnd -b -s 600 
.fi
.SH HISTORY
Written by Marc Ries.  Based upon a program of similar name presented 
by Brian Kernighan and Rob Pike in "The UNIX Programming Environment".
RIESES_PIECES
echo shar: extracting "'checkmail.c'" '(3106 characters)'
if test -f 'checkmail.c'
then
	echo shar: over-writing existing file "'checkmail.c'"
fi
cat << \RIESES_PIECES > 'checkmail.c'
/*
 * checkmail: watch user(s) mailbox
 *	      By M. Ries
 *            Based upon a program of similar name,
 *            Kernighan & Pike, "The UNIX Programming Environment".
 *
 * No warranty of suitability for any purpose, either expressed
 * or implied, is made.
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>

char   *progname;
char   *maildir = "/usr/spool/mail";/* system dependent */

#define	OPTSTRING "bhl:n:p:s:"
#define	FOREVER for(;;) 

main (argc, argv)
int     argc;
char  **argv;
{
    struct stat buf;
    char   *name,
           *getlogin ();
    extern int  optind;
    extern char *optarg;
    int     C;
    int     lastsize = 0;
    int     nmflg  = 0;		/* new mail flag */
    int     errflg = 0;		/* error flag */
    int     bkgflg = 0;		/* background-mode flag */
    int     nvalue = 4;		/* default nice value */
    unsigned    svalue = 300;	/* default sleep interval */

    if ((name = getlogin ()) == NULL) {
	error ("* Can't get login name", (char *) 0);
    }
    while ((C = getopt (argc, argv, OPTSTRING)) != EOF)
	switch (C) {
	    case 'b': 		/* background-mode flag */
		bkgflg++;
		break;
	    case 'h': 		/* help flag */
		errflg++;
		break;
	    case 'l': 		/* login name to check */
		name = optarg;
		break;
	    case 'n': 		/* called as nice_value */
	    case 'p': 		/* called as priority? */
		nvalue = atoi (optarg);
		break;
	    case 's': 		/* sleep interval */
		svalue = atoi (optarg);
		break;
	    default: 		/* flag usage */
		errflg++;
	}
    if (errflg) {
	printf ("  USAGE:\n");
	printf ("\t-b  => place program in background mode\n");
	printf ("\t-h  => this display\n");
	printf ("\t-l  => indicate alternate login to check for new mail (default=logname)\n");
	printf ("\t-n  => indicate nice value for background execution (default=4)\n");
	printf ("\t-s  => indicate sleep interval to use in background mode (default=60)\n");
	exit (1);
    } /*endif error*/

    if (chdir (maildir) == -1)
	error ("* Can't change directory to %s", maildir);
    if (bkgflg) {
	(void) signal (SIGINT, SIG_IGN);
	(void) nice (nvalue);
	if (fork ())
	    exit (0);
    } /*endif background*/

    FOREVER {
	/* really should just loop through an argv name array */
	if (stat (name, &buf) == -1)/* no mailbox */
	    buf.st_size = 0;
	if (buf.st_size > lastsize) {
	    if (!nmflg) {/* must be old mail */
	         printf ("\n  ***** THERE IS MAIL!  (%s) *****\n", name);
		 nmflg = 1; /* set new mail flag for next pass */
            } else {
	         printf ("\n  ** NEW MAIL HAS ARRIVED! (%s) **\n", name);
            }
	}/*endif*/
	lastsize = buf.st_size;
	if (!bkgflg)
	    exit (0);
	(void) sleep (svalue);
    } /*end FOREVER*/
} /*end main*/

error (s1, s2)
char   *s1,
       *s2;
{
    extern int  errno,
                sys_nerr;
    extern char *sys_errlist[],
               *progname;

    if (progname)
	fprintf (stderr, "%s: ", progname);
    fprintf (stderr, s1, s2);
    if (errno > 0 && errno < sys_nerr)
	fprintf (stderr, " (%s)", sys_errlist[errno]);
    exit (1);
} /*end error */
RIESES_PIECES
chmod +x 'checkmail.c'
echo shar: extracting "'getopt.c'" '(1503 characters)'
if test -f 'getopt.c'
then
	echo shar: over-writing existing file "'getopt.c'"
fi
cat << \RIESES_PIECES > 'getopt.c'
/* got this off net.sources */
#include <stdio.h>

#ifndef BSD
#define  index strchr
#endif  BSD

/*
 * get option letter from argument vector
 */
int	opterr = 1,		/* useless, never set or used */
	optind = 1,		/* index into parent argv vector */
	optopt;			/* character checked for validity */
char	*optarg;		/* argument associated with option */

#define BADCH	(int)'?'
#define EMSG	""
#define tell(s)	fputs("  ",stderr);fputs(*nargv,stderr);fputs(s,stderr); \
		fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);

getopt(nargc,nargv,ostr)
int	nargc;
char	**nargv,
	*ostr;
{
	static char	*place = EMSG;	/* option letter processing */
	register char	*oli;		/* option letter list index */
	char	*index();

	if(!*place) {			/* update scanning pointer */
		if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF);
		if (*place == '-') {	/* found "--" */
			++optind;
			return(EOF);
		}
	}				/* option letter okay? */
	if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) {
		if(!*place) ++optind;
		tell(": illegal option -- ");
	}
	if (*++oli != ':') {		/* don't need argument */
		optarg = NULL;
		if (!*place) ++optind;
	}
	else {				/* need an argument */
		if (*place) optarg = place;	/* no white space */
		else if (nargc <= ++optind) {	/* no arg */
			place = EMSG;
			tell(": option requires an argument -- ");
		}
	 	else optarg = nargv[optind];	/* white space */
		place = EMSG;
		++optind;
	}
	return(optopt);			/* dump back option letter */
}
RIESES_PIECES
#	End of shell archive
exit 0