home *** CD-ROM | disk | FTP | other *** search
- 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
-