home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume5
/
cronsort
< prev
next >
Wrap
Text File
|
1989-02-03
|
8KB
|
267 lines
Path: xanth!nic.MR.NET!hal!ncoast!allbery
From: gordon@prls.UUCP (Gordon Vickers)
Newsgroups: comp.sources.misc
Subject: v05i011: cronsort - chronologically sort the crontab file
Message-ID: <8810241638.AA10328@mips.mips.com>
Date: 28 Oct 88 02:37:04 GMT
Sender: allbery@ncoast.UUCP
Reply-To: gordon@prls.UUCP (Gordon Vickers)
Lines: 255
Approved: allbery@ncoast.UUCP
Posting-number: Volume 5, Issue 11
Submitted-by: "Gordon Vickers" <gordon@prls.UUCP>
Archive-name: cronsort
#! /bin/sh
#
# Program Name: Cronsort - Sorts crontab file chronologically
# Syntex: cronsort [-[mw]]
# Written in 'C' , should be highly portable (though I'm no expert).
# Developed on : VAX 11/750 under Ultrix 2.0-1
# Source Size: Just 5,217 bytes when un-shar'ed
# Article size: Less than 8K bytes
#
# Submitted by: Gordon Vickers ; {mips|pyramid|philabs}!prls!gordon
#
# 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:
# README
# cronsort.c
# This archive created: Wed Oct 19 13:27:15 1988
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'README'" '(994 characters)'
if test -f 'README'
then
echo shar: "will not over-write existing file 'README'"
else
sed 's/^ X//' << \SHAR_EOF > 'README'
X
XProgram Name: Cronsort - Sorts crontab entries chronologically
XSyntex: cronsort [-[mw]]
XWritten in 'C' , should be highly portable (though I'm no expert).
XDeveloped on : VAX 11/750 under Ultrix
XSource Size: Just 5,217 bytes when un-shar'ed
X
X Each crontab entry is sorted on four of the five time fields.
X These fields are (in order of precedents) month of year,
X day of month (default, else day of week), hour, minute.
X
X The command line option -w will cause a sort by day of week rather than
X by day of month. In any event, the other three fields are also sorted on.
X The -m option is for those who have difficulty remembering that a sort
X on day of month is the default.
X
X The output of this program is a cronological list of all crontab entries
X and these entries are printed to stdout.
X
X There is no manual page. Sorry, but I think the program's simplistic
X use doesn't warrent the time required to fight with nroff again.
X
X Flames, thanks, and suggestions to :
SHAR_EOF
if test 994 -ne "`wc -c < 'README'`"
then
echo shar: "error transmitting 'README'" '(should have been 994 characters)'
fi
fi
echo shar: "extracting 'cronsort.c'" '(5217 characters)'
if test -f 'cronsort.c'
then
echo shar: "will not over-write existing file 'cronsort.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'cronsort.c'
X/*
X * cronsort - chronilogically sort the crontab file by
X * record, and by fields within each record
X*/
X#include <stdio.h>
X
X#ifdef DEBUG
X#define CRONTAB "crontab"
X#else
X#define CRONTAB "/usr/lib/crontab"
X#endif
X
X#define FS 50 /* Maximum field size for each crontab field */
X
X#define RECSIZ BUFSIZ /* RECSIZ must be at least as long as longest
X CRONTAB entry. BUFSIZ if from <stdio.h> */
Xstruct entry {
X int num; /* encoded value of time */
X char record[BUFSIZ]; /* a crontab entry */
X struct entry *next; /* next entry in chain */
X } ;
X
Xstruct eplist {
X int num; /* encoded accumlitive time values */
X struct entry *pentry; /* points to struct that num came from */
X } *eplist;
Xint entries = 0; /* will need to know how many struct entries there are */
X
Xmain(argc,argv)
X int argc;
X char **argv;
X{
X void Sortmoy(), Swaps();
X int i,error = 0, wflag = 0;
X char c;
X char dow[FS],moy[FS],dom[FS],hr[FS],min[FS];
X char record[RECSIZ], progname[BUFSIZ];
X struct entry *entry, *top;
X struct eplist *teplist;
X FILE *fd;
X
X strcat(progname,*argv);
X for(++argv; *argv!=NULL; argv++){
X if(!strcmp(*argv,"-w"))
X wflag = 1;
X else if (!strcmp(*argv,"-m"))
X wflag = 0;
X else
X error = 1;
X }
X
X if(error) {
X fprintf(stderr,"Syntex: %s [ -[wm] ] \n",progname);
X fprintf(stderr," where -w will sort by day of week\n");
X fprintf(stderr," -m will sort by day of month (default)\n");
X exit(0);
X }
X
X if( (fd = fopen(CRONTAB,"r")) == NULL) {
X perror(*argv);
X exit(0);
X }
X
X top = (struct entry *)NULL; /* intialize pointer to NULL, keep lint happy */
X while( (fgets(record,RECSIZ,fd)) != NULL) { /* read the records */
X sscanf(record,"%c %*s",&c);
X if( !Isdigit(c) && c != '*')
X continue; /* crontab record format error or just a comment */
X
X if(top == NULL) {
X entry = (struct entry *)malloc(sizeof(struct entry));
X top = entry; /* top; i.e. top of list. Value should never be changed */
X }
X else { /* add another structure to hold the record and stuf */
X entry->next = (struct entry *)malloc(sizeof(struct entry));
X entry = entry->next;
X entry->next = NULL;
X }
X entries++;
X
X /* store it for printing later */
X strcat(entry->record,record); /* source of later output */
X
X /* break it up into manageable pieces */
X sscanf(record,"%s%s%s%s%s%*s",min,hr,dom,moy,dow);
X
X /* store the pieces so we can sort them later */
X entry->num = (Parse(moy) * 100000) +
X ( (wflag ? Parse(dow) : Parse(dom)) * 10000) +
X (Parse(hr) * 100 ) + Parse(min) ;
X }
X
X /* create an array of struct pointers and integers so we will only
X * need a single sort routine */
X eplist = (struct eplist *)malloc(sizeof(struct eplist) * entries );
X
X /* load eplist with addresses for each struct entry */
X for(teplist=eplist,entry = top; ; teplist++,entry=entry->next) {
X teplist->num = entry->num;
X teplist->pentry = entry;
X if(entry->next == NULL)
X break;
X }
X Sortint(eplist);
X
X /**** Print the resulting sort ****/
X for(i=0,teplist=eplist; i < entries ; i++, teplist++) {
X entry = teplist->pentry;
X printf("%s",entry->record); /* Don't need newline, it's in record */
X }
X}
X
X/****** Isdigit() ********/
XIsdigit(c)
X char c;
X{
X return( c>='0' && c<='9' ? c : NULL);
X}
X
X/******* Parse() *******/
XParse(field)
X char *field;
X{
X int num, Num = 99; /* Num set to some out-of-range value */
X char *p;
X
X p = field;
X
X /* align pointer to first digit */
X if(*p == '*') /* wild card, takes precedent over explicit values */
X return(0);
X
X
X while(*p) { /* scan the field til NULL, find lowest value within */
X if(Isdigit(*p)) {
X num = (int)( (*p) - '0');
X p++;
X if(Isdigit(*p)) {
X num = (num *10) + (int)( (*p) - '0');
X }
X }
X p++;
X Num = num < Num ? num : Num;
X }
X return(Num + 1); /* since an asteric is evaluated as zero (above) */
X}
X
X/******* Sortint() ********
X sort numeric data, swapping order also requires swapping the pointer
X to the struct entry that contains a copy of the data.
X*/
XSortint(list)
X struct eplist *list;
X{
X register struct eplist *top, *chain;
X register int ol, il ; /* Outter Loop, Inner Loop */
X register struct entry *tmp;
X int tmpnum, swapped = 0;
X
X chain = list;
X for(ol=entries; ol > 0 ;ol--) {
X if( chain->pentry == NULL )
X break;
X for(il=0,chain = list; il < ol; il++,chain++) {
X if( (chain + 1)->pentry == NULL )
X break;
X if(chain->num > (chain + 1)->num) {
X /* do a swap */
X tmp = chain->pentry;
X tmpnum = chain->num;
X
X chain->pentry = (chain + 1)->pentry;
X chain->num = (chain + 1)->num;
X
X (chain + 1)->pentry = tmp;
X (chain + 1)->num = tmpnum;
X swapped = 1;
X }
X }
X if(!swapped) /* A pass with no swapping means we've finnished early */
X break;
X }
X}
SHAR_EOF
if test 5217 -ne "`wc -c < 'cronsort.c'`"
then
echo shar: "error transmitting 'cronsort.c'" '(should have been 5217 characters)'
fi
fi
exit 0
# End of shell archive