Annotation of 43BSDTahoe/games/dm/dm.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1987 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that the above copyright notice and this paragraph are
                      7:  * duplicated in all such forms and that any documentation,
                      8:  * advertising materials, and other materials related to such
                      9:  * distribution and use acknowledge that the software was developed
                     10:  * by the University of California, Berkeley.  The name of the
                     11:  * University may not be used to endorse or promote products derived
                     12:  * from this software without specific prior written permission.
                     13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     16:  */
                     17: 
                     18: #ifndef lint
                     19: char copyright[] =
                     20: "@(#) Copyright (c) 1987 Regents of the University of California.\n\
                     21:  All rights reserved.\n";
                     22: #endif /* not lint */
                     23: 
                     24: #ifndef lint
                     25: static char sccsid[] = "@(#)dm.c       5.8 (Berkeley) 6/18/88";
                     26: #endif /* not lint */
                     27: 
                     28: #include <sys/param.h>
                     29: #include <sys/file.h>
                     30: #include <sys/time.h>
                     31: #include <sys/resource.h>
                     32: #include <pwd.h>
                     33: #include <utmp.h>
                     34: #include <nlist.h>
                     35: #include <stdio.h>
                     36: #include <ctype.h>
                     37: 
                     38: static time_t  now;                    /* current time value */
                     39: static int     priority = 0;           /* priority game runs at */
                     40: static char    *game,                  /* requested game */
                     41:                *gametty;               /* from tty? */
                     42: 
                     43: /*ARGSUSED*/
                     44: main(argc, argv)
                     45:        int argc;
                     46:        char **argv;
                     47: {
                     48:        char *cp, *rindex(), *ttyname();
                     49:        time_t time();
                     50: 
                     51:        nogamefile();
                     52:        game = (cp = rindex(*argv, '/')) ? ++cp : *argv;
                     53: 
                     54:        if (!strcmp(game, "dm"))
                     55:                exit(0);
                     56: 
                     57:        gametty = ttyname(0);
                     58:        (void)time(&now);
                     59:        read_config();
                     60: #ifdef LOG
                     61:        logfile();
                     62: #endif
                     63:        play(argv);
                     64:        /*NOTREACHED*/
                     65: }
                     66: 
                     67: /*
                     68:  * play --
                     69:  *     play the game
                     70:  */
                     71: #define        GAMEHIDE        "/usr/games/hide/"
                     72: static
                     73: play(args)
                     74:        char **args;
                     75: {
                     76:        char pbuf[MAXPATHLEN], *strcpy();
                     77: 
                     78:        (void)strcpy(pbuf, GAMEHIDE);
                     79:        (void)strcpy(pbuf + sizeof(GAMEHIDE) - 1, game);
                     80:        if (priority > 0)       /* < 0 requires root */
                     81:                (void)setpriority(PRIO_PROCESS, 0, priority);
                     82:        setgid(getgid());       /* we run setgid kmem; lose it */
                     83:        execv(pbuf, args);
                     84:        perror("dm");
                     85:        exit(1);
                     86: }
                     87: 
                     88: /*
                     89:  * read_config --
                     90:  *     read through config file, looking for key words.
                     91:  */
                     92: #define        CONTROL         "/usr/games/dm.config"
                     93: static
                     94: read_config()
                     95: {
                     96:        FILE *cfp;
                     97:        char *control, *host, *index(), *strcpy();
                     98:        char lbuf[BUFSIZ], path[MAXHOSTNAMELEN + sizeof(CONTROL)];
                     99:        char f1[40], f2[40], f3[40], f4[40], f5[40];
                    100: 
                    101:        host = &path[sizeof(CONTROL)];
                    102:        if (gethostname(host, MAXHOSTNAMELEN)) {
                    103:                perror("dm: gethostname");
                    104:                exit(1);
                    105:        }
                    106:        (void)strcpy(path, control = CONTROL);
                    107:        host[-1] = '.';
                    108:        if (host = index(host, '.'))
                    109:                *host = '\0';
                    110:        if (!(cfp = fopen(path, "r")) && !(cfp = fopen(control, "r"))) {
                    111:                fprintf(stderr, "dm: unable to read %s or %s.\n",
                    112:                    path, control);
                    113:                exit(1);
                    114:        }
                    115:        while (fgets(lbuf, sizeof(lbuf), cfp))
                    116:                switch(*lbuf) {
                    117:                case 'b':               /* badtty */
                    118:                        if (sscanf(lbuf, "%s%s", f1, f2) != 2 ||
                    119:                            strcasecmp(f1, "badtty"))
                    120:                                break;
                    121:                        c_tty(f2);
                    122:                        break;
                    123:                case 'g':               /* game */
                    124:                        if (sscanf(lbuf, "%s%s%s%s%s",
                    125:                            f1, f2, f3, f4, f5) != 5 || strcasecmp(f1, "game"))
                    126:                                break;
                    127:                        c_game(f2, f3, f4, f5);
                    128:                        break;
                    129:                case 't':               /* time */
                    130:                        if (sscanf(lbuf, "%s%s%s%s", f1, f2, f3, f4) != 4 ||
                    131:                            strcasecmp(f1, "time"))
                    132:                                break;
                    133:                        c_day(f2, f3, f4);
                    134:                }
                    135:        (void)fclose(cfp);
                    136: }
                    137: 
                    138: /*
                    139:  * c_day --
                    140:  *     if day is today, see if okay to play
                    141:  */
                    142: static
                    143: c_day(s_day, s_start, s_stop)
                    144:        char *s_day, *s_start, *s_stop;
                    145: {
                    146:        static char *days[] = {
                    147:                "sunday", "monday", "tuesday", "wednesday",
                    148:                "thursday", "friday", "saturday",
                    149:        };
                    150:        static struct tm *ct;
                    151:        int start, stop;
                    152: 
                    153:        if (!ct)
                    154:                ct = localtime(&now);
                    155:        if (strcasecmp(s_day, days[ct->tm_wday]))
                    156:                return;
                    157:        if (!isdigit(*s_start) || !isdigit(*s_stop))
                    158:                return;
                    159:        start = atoi(s_start);
                    160:        stop = atoi(s_stop);
                    161:        if (ct->tm_hour >= start && ct->tm_hour <= stop) {
                    162:                fputs("dm: Sorry, games are not available from ", stderr);
                    163:                hour(start);
                    164:                fputs(" to ", stderr);
                    165:                hour(stop);
                    166:                fputs(" today.\n", stderr);
                    167:                exit(0);
                    168:        }
                    169: }
                    170: 
                    171: /*
                    172:  * c_tty --
                    173:  *     decide if this tty can be used for games.
                    174:  */
                    175: static
                    176: c_tty(tty)
                    177:        char *tty;
                    178: {
                    179:        static int first = 1;
                    180:        static char *p_tty;
                    181:        char *rindex();
                    182: 
                    183:        if (first) {
                    184:                p_tty = rindex(gametty, '/');
                    185:                first = 0;
                    186:        }
                    187: 
                    188:        if (!strcmp(gametty, tty) || p_tty && !strcmp(p_tty, tty)) {
                    189:                fprintf(stderr, "dm: Sorry, you may not play games on %s.\n", gametty);
                    190:                exit(0);
                    191:        }
                    192: }
                    193: 
                    194: /*
                    195:  * c_game --
                    196:  *     see if game can be played now.
                    197:  */
                    198: static
                    199: c_game(s_game, s_load, s_users, s_priority)
                    200:        char *s_game, *s_load, *s_users, *s_priority;
                    201: {
                    202:        static int found;
                    203:        double load();
                    204: 
                    205:        if (found)
                    206:                return;
                    207:        if (strcmp(game, s_game) && strcasecmp("default", s_game))
                    208:                return;
                    209:        ++found;
                    210:        if (isdigit(*s_load) && atoi(s_load) < load()) {
                    211:                fputs("dm: Sorry, the load average is too high right now.\n", stderr);
                    212:                exit(0);
                    213:        }
                    214:        if (isdigit(*s_users) && atoi(s_users) <= users()) {
                    215:                fputs("dm: Sorry, there are too many users logged on right now.\n", stderr);
                    216:                exit(0);
                    217:        }
                    218:        if (isdigit(*s_priority))
                    219:                priority = atoi(s_priority);
                    220: }
                    221: 
                    222: static struct nlist nl[] = {
                    223:        { "_avenrun" },
                    224: #define        X_AVENRUN       0
                    225:        { "" },
                    226: };
                    227: 
                    228: /*
                    229:  * load --
                    230:  *     return 15 minute load average
                    231:  */
                    232: static double
                    233: load()
                    234: {
                    235:        double avenrun[3];
                    236:        int kmem;
                    237:        long lseek();
                    238: 
                    239:        if (nlist("/vmunix", nl)) {
                    240:                fputs("dm: nlist of /vmunix failed.\n", stderr);
                    241:                exit(1);
                    242:        }
                    243:        if ((kmem = open("/dev/kmem", O_RDONLY, 0)) < 0) {
                    244:                perror("dm: /dev/kmem");
                    245:                exit(1);
                    246:        }
                    247:        (void)lseek(kmem, (long)nl[X_AVENRUN].n_value, L_SET);
                    248:        (void)read(kmem, (char *)avenrun, sizeof(avenrun));
                    249:        return(avenrun[2]);
                    250: }
                    251: 
                    252: /*
                    253:  * users --
                    254:  *     return current number of users
                    255:  *     todo: check idle time; if idle more than X minutes, don't
                    256:  *     count them.
                    257:  */
                    258: static
                    259: users()
                    260: {
                    261:        register int nusers, utmp;
                    262:        struct utmp buf;
                    263: 
                    264:        if ((utmp = open("/etc/utmp", O_RDONLY, 0)) < 0) {
                    265:                perror("dm: /etc/utmp");
                    266:                exit(1);
                    267:        }
                    268:        for (nusers = 0; read(utmp, (char *)&buf, sizeof(struct utmp)) > 0;)
                    269:                if (buf.ut_name[0] != '\0')
                    270:                        ++nusers;
                    271:        return(nusers);
                    272: }
                    273: 
                    274: /*
                    275:  * nogamefile --
                    276:  *     if the file NOGAMING exists, no games allowed.
                    277:  *     file may also contain a message for the user.
                    278:  */
                    279: #define        NOGAMING        "/usr/games/nogames"
                    280: static
                    281: nogamefile()
                    282: {
                    283:        register int fd, n;
                    284:        char buf[BUFSIZ];
                    285: 
                    286:        if ((fd = open(NOGAMING, O_RDONLY, 0)) >= 0) {
                    287: #define        MESG    "Sorry, no games right now.\n\n"
                    288:                (void)write(2, MESG, sizeof(MESG) - 1);
                    289:                while ((n = read(fd, buf, sizeof(buf))) > 0)
                    290:                        (void)write(2, buf, n);
                    291:                exit(1);
                    292:        }
                    293: }
                    294: 
                    295: /*
                    296:  * hour --
                    297:  *     print out the hour in human form
                    298:  */
                    299: static
                    300: hour(h)
                    301:        int h;
                    302: {
                    303:        switch(h) {
                    304:        case 0:
                    305:                fputs("midnight", stderr);
                    306:                break;
                    307:        case 12:
                    308:                fputs("noon", stderr);
                    309:                break;
                    310:        default:
                    311:                if (h > 12)
                    312:                        fprintf(stderr, "%dpm", h - 12);
                    313:                else
                    314:                        fprintf(stderr, "%dam", h);
                    315:        }
                    316: }
                    317: 
                    318: #ifdef LOG
                    319: /*
                    320:  * logfile --
                    321:  *     log play of game
                    322:  */
                    323: #define        LOGFILE         "/usr/adm/dm.log"
                    324: static
                    325: logfile()
                    326: {
                    327:        struct passwd *pw, *getpwuid();
                    328:        FILE *lp;
                    329:        uid_t uid;
                    330:        int lock_cnt;
                    331:        char *ctime();
                    332: 
                    333:        if (lp = fopen(LOGFILE, "a")) {
                    334:                for (lock_cnt = 0;; ++lock_cnt) {
                    335:                        if (!flock(fileno(lp), LOCK_EX))
                    336:                                break;
                    337:                        if (lock_cnt == 4) {
                    338:                                perror("dm: log lock");
                    339:                                (void)fclose(lp);
                    340:                                return;
                    341:                        }
                    342:                        sleep((u_int)1);
                    343:                }
                    344:                if (pw = getpwuid(uid = getuid()))
                    345:                        fputs(pw->pw_name, lp);
                    346:                else
                    347:                        fprintf(lp, "%u", uid);
                    348:                fprintf(lp, "\t%s\t%s\t%s", game, gametty, ctime(&now));
                    349:                (void)fclose(lp);
                    350:                (void)flock(fileno(lp), LOCK_UN);
                    351:        }
                    352: }
                    353: #endif /* LOG */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.