home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / pegboard / peg.y < prev    next >
Encoding:
Lex Description  |  1989-10-26  |  7.7 KB  |  384 lines

  1. %{
  2. /*
  3.     peg.y
  4.  
  5.     Copyright 1989 RFM Microplex Systems Ltd.
  6.     RFM Microplex Systems Ltd.
  7.     265 E. 1st Ave.
  8.     Vancouver, B.C. CANADA
  9.     V5T 1A7
  10.     (604)875-1461
  11.     Fax: (604)875-9029
  12.     Email: uunet!mplex!ror
  13.  
  14.     These documents are copyrighted.  However, they may be distributed freely
  15.     as long as the following is understood and followed:
  16.  
  17.     A; They may not be distributed for financial or other gain under any
  18.        circumstances.
  19.     B; The author(s) and RFM Microplex Systems Ltd. will not be held liable
  20.        for any damage or loss of data arising from their use
  21.     C; Anyone who applies improvements or "bug fixes" shall make an attempt
  22.        to return these changes to the author listed above
  23.     D. This copyright applies to all of the documents listed below, and any
  24.        other information created by compilers or other programs that are
  25.        applied to them:
  26.             peg.man peg.y tfix.c peg.h pegio.c
  27. */
  28. #include "peg.h"
  29.  
  30. #define YYSTYPE long
  31.  
  32. char *invkst;    /* Name of the executable    */
  33. char *pegdir;    /* Directory name for various files    */
  34. char *pegfnm;    /* File name where pegs go    */
  35. char *comment;    /* User's reason for leaving, if given    */
  36. char lb[BUFSIZ];    /* Lines for yylex    */
  37. int chk;    /* Check run only    */
  38. int eod;    /* Log off till tomorrow    */
  39. int admupd;    /* Administrator updating mortals peg    */
  40. int quiet;    /* No header, don't print time when done    */
  41. int vrbse;    /* Verbose output (this is not the opposite of quiet)    */
  42. int normpeg;    /* Set if login tty is on no pegout list    */
  43. /*
  44.     Start times for invoking user stored here by rcinit
  45. */
  46. long starts [] = { -1, -1, -1, -1, -1, -1, -1 };    
  47. long int duback;    /* Running count in seconds of the date determined    */
  48. struct tm today;    /* */
  49. struct    tm *s;
  50. %}
  51. %token    NUMBER
  52. %right    ':'
  53. %left    '+'
  54. %right    '/'
  55. %right    'p'
  56. %%
  57. nothing:
  58.     |    nothing expr
  59.         ;
  60. expr:     NUMBER {
  61.             $$ = fixhm( $1, 0L );
  62.         }
  63.     |    NUMBER ':' NUMBER    {
  64.             $$ = fixhm( $1, $3 );
  65.         }
  66.     |    NUMBER ':' NUMBER 'p'    {
  67.             $$ = fixhm( $1 < 12 ? $1 + 12 : $1 , $3 );
  68.         }
  69.     |    NUMBER '/' NUMBER    {
  70.             $$ = fixymd(
  71.             (( $1 < today.tm_mon + 1 ||
  72.             ( $1 == today.tm_mon + 1 && $3 < today.tm_mday ))
  73.              ? (long)today.tm_year + 1 : (long)today.tm_year ), $1 , $3 );
  74.         }
  75.     |    NUMBER '/' NUMBER '/' NUMBER    {
  76.             $$ = fixymd( $1, $3 , $5 );
  77.         }
  78.     |    NUMBER 'p'    {
  79.             $$ = fixhm( $1 < 12 ? $1 + 12 : $1 , 0L );
  80.         }
  81.             
  82.     |    '+' NUMBER    {
  83.             s = localtime( &duback );
  84.             $$ = fixhm( (long)s->tm_hour + $2, (long)s->tm_min );
  85.         }
  86.     |    '+' NUMBER 'h'    {
  87.             s = localtime( &duback );
  88.             $$ = fixhm( (long)s->tm_hour + $2, (long)s->tm_min );
  89.         }
  90.     |    '+' NUMBER 'm'    {
  91.             s = localtime( &duback );
  92.             $$ = fixhm( (long)s->tm_hour, (long)s->tm_min + $2 );
  93.         }
  94.     |    '+' NUMBER 'd'    {
  95.             $$ = fixday( $2 );
  96.         }
  97.     |    '+' NUMBER 'w'    {
  98.             $$ = fixday( $2 * 7L );
  99.         }
  100.         ;
  101. %%
  102. /*
  103.     BUGS TO FIX:
  104.         none (ha)
  105. */
  106.  
  107. main( argc, argv )
  108. int argc;
  109. char *argv[];
  110. {
  111.     extern struct    tm today;
  112.     extern long    duback;
  113.     extern char    lb[];
  114.     extern char    *pegfnm;
  115.     extern char *pegdir;
  116.     extern char    *invkst;
  117.     extern char    *optarg;
  118.     extern char    *sys_errlist[];
  119.     extern int    sys_nerr;
  120.     extern int    errno;
  121.     extern int    eod;
  122.     extern int    vrbse;
  123.     extern int    admupd;
  124.     struct passwd    *rpu = NULL;
  125.     int i;
  126.     int exp = 0;
  127.     extern int    chk;
  128.     extern int    normpeg;
  129.     int logout    = 1;
  130.  
  131.     invkst = (( strrchr( argv[0], '/' ) == NULL )
  132.     ? argv[0] : strrchr( argv[0], '/' ) + 1 );
  133.     /*
  134.         Read "rc" files
  135.     */
  136.     pegfnm    =    NULL;
  137.     comment    =    NULL;
  138.     pegdir    =    NULL;
  139.     rcinit( );
  140.  
  141. #    define LGLOPTS    "c:i:u:lnqtvx"
  142.     opterr=0;
  143.     while(( i = getopt( argc, argv, LGLOPTS )) != EOF )    {
  144.         switch( i )    {
  145.             /*
  146.                 Suppress start time rounding
  147.             */
  148.             case 't':
  149.                 eod++;
  150.                 break;
  151.             /*
  152.                 Peg invoking user as back at site (delete pegboard entry)
  153.             */
  154.             case 'x':
  155.                 exp++;
  156.                 break;
  157.             /*
  158.                 Report due back date for specified userm unless invoker
  159.                 is root.  If root then diddle other users peg
  160.             */
  161.             case 'u':
  162.                 if( ! getuid( ))    {
  163.                     if( setuid( getpwnam( optarg )->pw_uid ))
  164.                         faterr( "setuid call failed" );
  165.                     admupd++;
  166.                     break;
  167.                 }
  168.                 if(( rpu = getpwnam( optarg )) == NULL )
  169.                     fprintf( stderr,
  170.                     "\n%s: user \"%.*s\" not found\n",
  171.                     invkst, strspn( optarg, OKCS ), optarg );
  172.                 break;
  173.             /*
  174.                 Don't log the user off after updtaing pegboard
  175.             */
  176.             case 'n':
  177.                 logout = 0;
  178.                 break;
  179.             /*
  180.                 Supress printing of header and time
  181.             */
  182.             case 'q':
  183.                 quiet = ( ! quiet );
  184.                 break;
  185.             /*
  186.                 Check run only, no update, no logout
  187.             */
  188.             case 'v':
  189.                 chk++;
  190.                 break;
  191.             /*
  192.                 Print long format
  193.             */
  194.             case 'l':
  195.                 vrbse++;
  196.                 break;
  197.             /*
  198.                 Read comment
  199.             */
  200.             case 'c':
  201.                 comment = ( strlen( optarg ) > BUFSIZ ? "" : optarg );
  202.                 break;
  203.             /*
  204.                 Interrogate pegboard.  Return 0 if invoker pegged.
  205.             */
  206.             case 'i':
  207.                 if( ! *optarg )
  208.                     exit( 1 );
  209.                 exit( chkpeg( getpwnam( optarg )->pw_uid ));
  210.  
  211.             case '?':
  212.             default:
  213.                 fprintf( stderr,
  214.                 "\n%s: Unrecognized option \"%c\"\n",
  215.                 invkst, i );
  216.                 use( );    /* Exits    */
  217.         }    /* End of switch    */
  218.     }    /* End of while    */
  219.  
  220.     if( ! normpeg && exp )    {
  221.         upddbdf( getuid( ), 1 );
  222.         exit( 0 );
  223.     }
  224.     if ( exp )
  225.         exit( 0 );
  226.  
  227.     /* Report for specific user    */
  228.     if( rpu != NULL)    {
  229.         report( rpu->pw_uid, quiet );
  230.         exit( 0 );
  231.     }
  232.  
  233.     if((( argc - optind ) < 1 ) && ( ! eod ))    {
  234.         /* No arguments, report all pegged users    */
  235.         report( 0, quiet );
  236.         exit( 0 );
  237.     }
  238.  
  239.     lb[0] = '\0';
  240.     fixargs( &argv[optind] );
  241.     if(( ! lb[0] ) && eod )
  242.         sprintf( lb, "+1d" );
  243.     time( &duback );
  244.     copytime( localtime( &duback ), &today );
  245.  
  246.     yyparse( );
  247.  
  248.     if( chk )    {
  249.         showtime( &duback );
  250.         exit( 0 );
  251.     }
  252.     /*
  253.         Update the pegboard.  If it fails then don't die.
  254.     */
  255.     if( upddbdf( getuid( ), 0 ))
  256.         logout = 0;
  257.     /*
  258.         Don't die if root
  259.     */
  260.     if( ! getuid( ) || admupd )
  261.         exit( 0 );
  262.     
  263.     if( logout )
  264.         kill( -1, SIGKILL );
  265.     exit( 0 );
  266. }
  267.  
  268. yylex( )
  269. {
  270.     static char *lp;
  271.     static int init=1;
  272.     char copy[ BUFSIZ ];
  273.     int lah1;
  274.     int lah2;
  275.     extern char lb[];
  276.  
  277.     if( init )    {
  278.         init=( ! init );
  279.         lp = lb;
  280.     }
  281.  
  282.     while( *lp == ' ' || *lp == '\t' )
  283.         lp++;
  284.     if( ! *lp || *lp == '\n' )
  285.         return( 0 );
  286.     if( isdigit( *lp ))    {
  287.         sscanf( lp, "%ld", &yylval );
  288.         lp = ( lp + strspn( lp, "0123456789" ));
  289.         return( NUMBER );
  290.     }
  291.     /*
  292.         Look for a literal month name and day number
  293.     */
  294.     if(( lah1 = ismonth( lp )))    {
  295.         do    {
  296.             if( ! *lp++ ) 
  297.                 specerr( "month name must be followed by day of month" );
  298.         }    while ( ! isdigit( *lp ));
  299.  
  300.         sscanf( lp, "%d", &lah2 );
  301.  
  302.         lp = strpbrk( lp, " \t\n" );    /* SP, TAB, NL    */
  303.         strcpy( copy, lp );    /* If this is NULL that's exactly what we want    */
  304.         if(( lah1 - 1 ) < today.tm_mon ||
  305.         (( lah1 - 1 )  == today.tm_mon && lah2 < today.tm_mday ))
  306.             sprintf( lp, "%d/%d/%d %s", today.tm_year + 1, lah1, lah2, copy );
  307.         else
  308.             sprintf( lp, "%d/%d/%d %s", today.tm_year, lah1, lah2, copy );
  309.         sscanf( lp, "%ld", &yylval );
  310.         lp = strchr( lp, '/' );
  311.         return( NUMBER );
  312.     }
  313.     if(( lah1 = isday( lp )) != (-1))    {
  314.         lp = strpbrk( lp, " \t\n" );    /* SP, TAB, NL    */
  315.         strcpy( copy, lp );    /* If this is NULL that's exactly what we want    */
  316.         if( lah1 < today.tm_wday )
  317.             lah1 += 7;
  318.         lah1 -= today.tm_wday;
  319.         sprintf( lp, "+%dd %s", lah1, copy );
  320.     }
  321.     return( (int)*lp++ );
  322. }
  323.  
  324. /*
  325.     Consolidate string list
  326. */
  327. char *fixargs( ss )
  328. char **ss;
  329. {
  330.     extern char lb[];
  331.  
  332.     while( **ss )    {
  333.         strcat( lb, *ss++ );
  334.         if(( strlen( lb )) >= BUFSIZ )
  335.             specerr( "argument string to long" );
  336.         strcat( lb, " " );
  337.     }
  338.     return( lows( lb ));
  339. }
  340.  
  341. /*
  342.     Make s lowercase.
  343. */
  344. char *lows( s )
  345. char *s;
  346. {
  347.     int i;
  348.  
  349.     for( i = 0 ; s[i] ; i++ )
  350.         s[i] = tolower( s[i] );
  351.     return( s );
  352. }
  353.  
  354. yyerror( m )
  355. char *m;
  356. {
  357.     specerr(m);
  358. }
  359.  
  360. void specerr( m )
  361. char *m;
  362. {
  363.     extern char *invkst;
  364.  
  365.     fprintf( stderr,
  366.     "\n%s: Bad specification (%.*s)\n",
  367.     invkst, strspn( m, OKCS ), m );
  368.     use( );
  369. }
  370.  
  371. void use( s )
  372. char *s;
  373. {
  374.     extern char *invkst;
  375.  
  376.     /* LGLOPTS    "tc:xu:vnqli:"    */
  377.     fprintf( stderr,
  378.     "\n%s: maintains an \"on-line pegboard\"\n", invkst );
  379.     fprintf( stderr,
  380.     "use: %s [-u|i user -c \"comment\" [-qnxtvl] [date time]\n", invkst );
  381.  
  382.     exit( 1 );
  383. }
  384.