home *** CD-ROM | disk | FTP | other *** search
Lex Description | 1989-10-26 | 7.7 KB | 384 lines |
- %{
- /*
- peg.y
-
- Copyright 1989 RFM Microplex Systems Ltd.
- RFM Microplex Systems Ltd.
- 265 E. 1st Ave.
- Vancouver, B.C. CANADA
- V5T 1A7
- (604)875-1461
- Fax: (604)875-9029
- Email: uunet!mplex!ror
-
- These documents are copyrighted. However, they may be distributed freely
- as long as the following is understood and followed:
-
- A; They may not be distributed for financial or other gain under any
- circumstances.
- B; The author(s) and RFM Microplex Systems Ltd. will not be held liable
- for any damage or loss of data arising from their use
- C; Anyone who applies improvements or "bug fixes" shall make an attempt
- to return these changes to the author listed above
- D. This copyright applies to all of the documents listed below, and any
- other information created by compilers or other programs that are
- applied to them:
- peg.man peg.y tfix.c peg.h pegio.c
- */
- #include "peg.h"
-
- #define YYSTYPE long
-
- char *invkst; /* Name of the executable */
- char *pegdir; /* Directory name for various files */
- char *pegfnm; /* File name where pegs go */
- char *comment; /* User's reason for leaving, if given */
- char lb[BUFSIZ]; /* Lines for yylex */
- int chk; /* Check run only */
- int eod; /* Log off till tomorrow */
- int admupd; /* Administrator updating mortals peg */
- int quiet; /* No header, don't print time when done */
- int vrbse; /* Verbose output (this is not the opposite of quiet) */
- int normpeg; /* Set if login tty is on no pegout list */
- /*
- Start times for invoking user stored here by rcinit
- */
- long starts [] = { -1, -1, -1, -1, -1, -1, -1 };
- long int duback; /* Running count in seconds of the date determined */
- struct tm today; /* */
- struct tm *s;
- %}
- %token NUMBER
- %right ':'
- %left '+'
- %right '/'
- %right 'p'
- %%
- nothing:
- | nothing expr
- ;
- expr: NUMBER {
- $$ = fixhm( $1, 0L );
- }
- | NUMBER ':' NUMBER {
- $$ = fixhm( $1, $3 );
- }
- | NUMBER ':' NUMBER 'p' {
- $$ = fixhm( $1 < 12 ? $1 + 12 : $1 , $3 );
- }
- | NUMBER '/' NUMBER {
- $$ = fixymd(
- (( $1 < today.tm_mon + 1 ||
- ( $1 == today.tm_mon + 1 && $3 < today.tm_mday ))
- ? (long)today.tm_year + 1 : (long)today.tm_year ), $1 , $3 );
- }
- | NUMBER '/' NUMBER '/' NUMBER {
- $$ = fixymd( $1, $3 , $5 );
- }
- | NUMBER 'p' {
- $$ = fixhm( $1 < 12 ? $1 + 12 : $1 , 0L );
- }
-
- | '+' NUMBER {
- s = localtime( &duback );
- $$ = fixhm( (long)s->tm_hour + $2, (long)s->tm_min );
- }
- | '+' NUMBER 'h' {
- s = localtime( &duback );
- $$ = fixhm( (long)s->tm_hour + $2, (long)s->tm_min );
- }
- | '+' NUMBER 'm' {
- s = localtime( &duback );
- $$ = fixhm( (long)s->tm_hour, (long)s->tm_min + $2 );
- }
- | '+' NUMBER 'd' {
- $$ = fixday( $2 );
- }
- | '+' NUMBER 'w' {
- $$ = fixday( $2 * 7L );
- }
- ;
- %%
- /*
- BUGS TO FIX:
- none (ha)
- */
-
- main( argc, argv )
- int argc;
- char *argv[];
- {
- extern struct tm today;
- extern long duback;
- extern char lb[];
- extern char *pegfnm;
- extern char *pegdir;
- extern char *invkst;
- extern char *optarg;
- extern char *sys_errlist[];
- extern int sys_nerr;
- extern int errno;
- extern int eod;
- extern int vrbse;
- extern int admupd;
- struct passwd *rpu = NULL;
- int i;
- int exp = 0;
- extern int chk;
- extern int normpeg;
- int logout = 1;
-
- invkst = (( strrchr( argv[0], '/' ) == NULL )
- ? argv[0] : strrchr( argv[0], '/' ) + 1 );
- /*
- Read "rc" files
- */
- pegfnm = NULL;
- comment = NULL;
- pegdir = NULL;
- rcinit( );
-
- # define LGLOPTS "c:i:u:lnqtvx"
- opterr=0;
- while(( i = getopt( argc, argv, LGLOPTS )) != EOF ) {
- switch( i ) {
- /*
- Suppress start time rounding
- */
- case 't':
- eod++;
- break;
- /*
- Peg invoking user as back at site (delete pegboard entry)
- */
- case 'x':
- exp++;
- break;
- /*
- Report due back date for specified userm unless invoker
- is root. If root then diddle other users peg
- */
- case 'u':
- if( ! getuid( )) {
- if( setuid( getpwnam( optarg )->pw_uid ))
- faterr( "setuid call failed" );
- admupd++;
- break;
- }
- if(( rpu = getpwnam( optarg )) == NULL )
- fprintf( stderr,
- "\n%s: user \"%.*s\" not found\n",
- invkst, strspn( optarg, OKCS ), optarg );
- break;
- /*
- Don't log the user off after updtaing pegboard
- */
- case 'n':
- logout = 0;
- break;
- /*
- Supress printing of header and time
- */
- case 'q':
- quiet = ( ! quiet );
- break;
- /*
- Check run only, no update, no logout
- */
- case 'v':
- chk++;
- break;
- /*
- Print long format
- */
- case 'l':
- vrbse++;
- break;
- /*
- Read comment
- */
- case 'c':
- comment = ( strlen( optarg ) > BUFSIZ ? "" : optarg );
- break;
- /*
- Interrogate pegboard. Return 0 if invoker pegged.
- */
- case 'i':
- if( ! *optarg )
- exit( 1 );
- exit( chkpeg( getpwnam( optarg )->pw_uid ));
-
- case '?':
- default:
- fprintf( stderr,
- "\n%s: Unrecognized option \"%c\"\n",
- invkst, i );
- use( ); /* Exits */
- } /* End of switch */
- } /* End of while */
-
- if( ! normpeg && exp ) {
- upddbdf( getuid( ), 1 );
- exit( 0 );
- }
- if ( exp )
- exit( 0 );
-
- /* Report for specific user */
- if( rpu != NULL) {
- report( rpu->pw_uid, quiet );
- exit( 0 );
- }
-
- if((( argc - optind ) < 1 ) && ( ! eod )) {
- /* No arguments, report all pegged users */
- report( 0, quiet );
- exit( 0 );
- }
-
- lb[0] = '\0';
- fixargs( &argv[optind] );
- if(( ! lb[0] ) && eod )
- sprintf( lb, "+1d" );
- time( &duback );
- copytime( localtime( &duback ), &today );
-
- yyparse( );
-
- if( chk ) {
- showtime( &duback );
- exit( 0 );
- }
- /*
- Update the pegboard. If it fails then don't die.
- */
- if( upddbdf( getuid( ), 0 ))
- logout = 0;
- /*
- Don't die if root
- */
- if( ! getuid( ) || admupd )
- exit( 0 );
-
- if( logout )
- kill( -1, SIGKILL );
- exit( 0 );
- }
-
- yylex( )
- {
- static char *lp;
- static int init=1;
- char copy[ BUFSIZ ];
- int lah1;
- int lah2;
- extern char lb[];
-
- if( init ) {
- init=( ! init );
- lp = lb;
- }
-
- while( *lp == ' ' || *lp == '\t' )
- lp++;
- if( ! *lp || *lp == '\n' )
- return( 0 );
- if( isdigit( *lp )) {
- sscanf( lp, "%ld", &yylval );
- lp = ( lp + strspn( lp, "0123456789" ));
- return( NUMBER );
- }
- /*
- Look for a literal month name and day number
- */
- if(( lah1 = ismonth( lp ))) {
- do {
- if( ! *lp++ )
- specerr( "month name must be followed by day of month" );
- } while ( ! isdigit( *lp ));
-
- sscanf( lp, "%d", &lah2 );
-
- lp = strpbrk( lp, " \t\n" ); /* SP, TAB, NL */
- strcpy( copy, lp ); /* If this is NULL that's exactly what we want */
- if(( lah1 - 1 ) < today.tm_mon ||
- (( lah1 - 1 ) == today.tm_mon && lah2 < today.tm_mday ))
- sprintf( lp, "%d/%d/%d %s", today.tm_year + 1, lah1, lah2, copy );
- else
- sprintf( lp, "%d/%d/%d %s", today.tm_year, lah1, lah2, copy );
- sscanf( lp, "%ld", &yylval );
- lp = strchr( lp, '/' );
- return( NUMBER );
- }
- if(( lah1 = isday( lp )) != (-1)) {
- lp = strpbrk( lp, " \t\n" ); /* SP, TAB, NL */
- strcpy( copy, lp ); /* If this is NULL that's exactly what we want */
- if( lah1 < today.tm_wday )
- lah1 += 7;
- lah1 -= today.tm_wday;
- sprintf( lp, "+%dd %s", lah1, copy );
- }
- return( (int)*lp++ );
- }
-
- /*
- Consolidate string list
- */
- char *fixargs( ss )
- char **ss;
- {
- extern char lb[];
-
- while( **ss ) {
- strcat( lb, *ss++ );
- if(( strlen( lb )) >= BUFSIZ )
- specerr( "argument string to long" );
- strcat( lb, " " );
- }
- return( lows( lb ));
- }
-
- /*
- Make s lowercase.
- */
- char *lows( s )
- char *s;
- {
- int i;
-
- for( i = 0 ; s[i] ; i++ )
- s[i] = tolower( s[i] );
- return( s );
- }
-
- yyerror( m )
- char *m;
- {
- specerr(m);
- }
-
- void specerr( m )
- char *m;
- {
- extern char *invkst;
-
- fprintf( stderr,
- "\n%s: Bad specification (%.*s)\n",
- invkst, strspn( m, OKCS ), m );
- use( );
- }
-
- void use( s )
- char *s;
- {
- extern char *invkst;
-
- /* LGLOPTS "tc:xu:vnqli:" */
- fprintf( stderr,
- "\n%s: maintains an \"on-line pegboard\"\n", invkst );
- fprintf( stderr,
- "use: %s [-u|i user -c \"comment\" [-qnxtvl] [date time]\n", invkst );
-
- exit( 1 );
- }
-