home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / game_reg / gr.c next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  5.8 KB  |  315 lines

  1. #ifndef lint
  2. static char *RCSid = "$Header: gr.c,v 1.16 86/04/26 17:30:53 mcooper Exp $";
  3. #endif
  4.  
  5. /*
  6.  *------------------------------------------------------------------
  7.  *
  8.  * $Source: /usr/src/local/gr/RCS/gr.c,v $
  9.  * $Revision: 1.16 $
  10.  * $Date: 86/04/26 17:30:53 $
  11.  * $State: Exp $
  12.  * $Author: mcooper $
  13.  * $Locker: mcooper $
  14.  *
  15.  *------------------------------------------------------------------
  16.  *
  17.  * Michael Cooper (mcooper@usc-oberon.arpa)
  18.  * University Computing Services,
  19.  * University of Southern California,
  20.  * Los Angeles, California,   90089-0251
  21.  * (213) 743-3469
  22.  *
  23.  *------------------------------------------------------------------
  24.  * $Log:    gr.c,v $
  25.  * Revision 1.16  86/04/26  17:30:53  mcooper
  26.  * This version adds a new field to the gr.control
  27.  * file that specifies the priority that the game will
  28.  * run at.
  29.  * 
  30.  * Revision 1.15  86/03/25  18:50:08  mcooper
  31.  * Added #ifdef LOGFILE.
  32.  * 
  33.  * Revision 1.14  86/03/25  15:48:49  mcooper
  34.  * New headers.
  35.  * 
  36.  *------------------------------------------------------------------
  37.  */
  38.  
  39. #include <stdio.h>
  40. #include <signal.h>
  41. #include <sys/wait.h>
  42. #include <sys/types.h>
  43. #include <sys/stat.h>
  44. #include <sys/time.h>
  45. #include <sys/resource.h>
  46. #include <utmp.h>
  47. #include <nlist.h>
  48. #include "gr.h"
  49.  
  50.  
  51. static int ufd = 0;
  52. static int max_users;
  53. static int priority = 0;
  54. static lfd = 0;
  55. static double avenrun[3];
  56. static double max_load;
  57. static struct utmp buf;
  58. static struct nlist nl[] = {
  59.     { "_avenrun" },
  60.     { "" },
  61. };
  62.  
  63. int was_tod;
  64. int was_load;
  65. int was_users;
  66. char *rindex();
  67. long time();
  68.  
  69. main(argc, argv)
  70. int argc;
  71. char **argv;
  72. {
  73.     char *game = rindex(argv[0], '/');
  74.  
  75.     if (game == 0)
  76.         game = argv[0];
  77.     else
  78.         game++;    /* Skip the '/' */
  79.     setup(game);
  80.     if(checkfor(NOGAMING))
  81.         exit(2);
  82.     if (tod() || users() || load()) {
  83.         fprintf(stderr, "Sorry, no games now.\n");
  84.         if (was_load)
  85.             fprintf(stderr, 
  86.                 "The system load is greater than %.2lf.\n",
  87.                 max_load);
  88.         if (was_users)
  89.             fprintf(stderr, 
  90.                 "There are more than %d users logged in.\n",
  91.                 max_users);
  92.         if (was_tod)
  93.             fprintf(stderr, 
  94. "Game playing is not permitted between %d00 and %d00 hours on weekdays.\n", 
  95.                 MORNING, EVENING);
  96.         exit(1);
  97.     }
  98. #ifdef LOGFILE
  99.     logfile(game);
  100. #endif
  101.     play(game, argv);
  102. }
  103.  
  104. play(game, args)
  105. char *game;
  106. char **args;
  107. {
  108.     int pid;
  109.     char tmp[128];
  110.  
  111.     switch (pid = fork()) {
  112.     case -1:
  113.         fprintf(stderr, "Cannot fork.\n");
  114.         exit(1);
  115.     case 0:
  116.         strcpy(tmp, HIDEDIR);
  117.         strcat(tmp, "/");
  118.         strcat(tmp, game);
  119.         signal(SIGINT, SIG_DFL);
  120.         signal(SIGQUIT, SIG_DFL);
  121.         signal(SIGTSTP, SIG_DFL);
  122.         setuid(getuid());
  123.         if(setpriority(PRIO_PROCESS, 0, priority) < 0) {
  124.             perror("setpriority");
  125.             exit(1);
  126.         }
  127.         execv(tmp, args);
  128.         perror(tmp);
  129.         exit(1);
  130.     }
  131.     for (;;) {
  132.         sleep(60);
  133.         if (load() || users() || tod()) {
  134.             warn(0);
  135.             sleep(60);
  136.             if (reprieve())
  137.                 continue;
  138.             sleep(60);
  139.             if (reprieve())
  140.                 continue;
  141.             warn(1);
  142.             sleep(60);
  143.             if (reprieve())
  144.                 continue;
  145.             warn(2);
  146.             sleep(60);
  147.             if (reprieve())
  148.                 continue;
  149.             blast(pid);
  150.         }
  151.     }
  152. }
  153.  
  154. reprieve()
  155. {
  156.     static char mess[] = "\rYou have a reprieve.  Continue playing.\r\n";
  157.  
  158.     if (load() || users() || tod())
  159.         return (0);
  160.     write(2, mess, sizeof(mess));
  161.     return (1);
  162. }
  163.  
  164. warn(which)
  165. int which;
  166. {
  167.     static char buff[512];
  168.     static char *mesg = "to save your game.  If you do not leave\r\n\
  169. the game within this period, your game will be terminated.\r\n";
  170.     static char *t[3] = {
  171.         "4 minutes ",
  172.         "2 minutes ",
  173.         "1 minute "
  174.     };
  175.  
  176.     if (was_load)
  177.         sprintf(buff, "\rThe system load is greater than %.2lf.\r\n",
  178.             max_load);
  179.     if (was_users)
  180.         sprintf(buff, "\rThere are more than %d users logged in.\r\n",
  181.             max_users);
  182.     if (was_tod)
  183.         sprintf(buff, "\rGame time is over.\r\n");
  184.     strcat(buff, "You have ");
  185.     strcat(buff, t[which]);
  186.     strcat(buff, mesg);
  187.     write(2, buff, strlen(buff));
  188. }
  189.  
  190. blast(pid)
  191. int pid;
  192. {
  193.     static char mess[] = "\rYour game is forfeit.\r\n";
  194.  
  195.     write(2, mess, sizeof(mess));
  196.     kill(pid, SIGHUP);
  197.     sleep(60);
  198.     kill(pid, SIGKILL);
  199. }
  200.  
  201. death(n)
  202. int n;
  203. {
  204.     union wait status;
  205.  
  206.     if (wait3(&status, WNOHANG | WUNTRACED, (char *)0) == 0) {
  207.         return;
  208.     }
  209.     if (status.w_stopval == WSTOPPED) {
  210.         signal(SIGTSTP, SIG_DFL);
  211.         kill(getpid(), SIGTSTP);
  212.         signal(SIGTSTP, SIG_IGN);
  213.         return;
  214.     } else
  215.         exit(0);
  216. }
  217.  
  218.  
  219. setup(game)
  220. char *game;
  221. {
  222.     char tmp[16];
  223.     char lbuf[BUFSIZ];
  224.     int n;
  225.     FILE *list;
  226.  
  227.     if ((ufd = open("/etc/utmp", 0)) < 0) {
  228.         perror("/etc/utmp");
  229.         exit(1);
  230.     }
  231.     if ((lfd = open("/dev/kmem", 0)) < 0) {
  232.         perror("/dev/kmem");
  233.         exit(1);
  234.     }
  235.     nlist("/vmunix", nl);
  236.     if (nl[0].n_type == 0) {
  237.         perror("/vmunix");
  238.         exit(1);
  239.     }
  240.     if ((list = fopen(CONTROL, "r")) == NULL) {
  241.         perror(CONTROL);
  242.         exit(1);
  243.     }
  244.     while (fgets(lbuf, sizeof(lbuf), list)) {
  245.         if(lbuf[0] == COMMENT)
  246.             continue;
  247.         sscanf(lbuf, "%s%lf%d%d", 
  248.             tmp, &max_load, &max_users, &priority);
  249.         if (strcmp(tmp, game) == 0)
  250.             break;
  251.     }
  252.     fclose(list);
  253.     signal(SIGCHLD, death);
  254.     signal(SIGINT, SIG_IGN);
  255.     signal(SIGQUIT, SIG_IGN);
  256.     signal(SIGTSTP, SIG_IGN);
  257. }
  258.  
  259. load()
  260. {
  261.     lseek(lfd, (long)nl[0].n_value, 0);
  262.     read(lfd, avenrun, sizeof(avenrun));
  263.     return (was_load = (avenrun[1] >= max_load));
  264. }
  265.  
  266. users()
  267. {
  268.     char tmp[32];
  269.     int count = 0;
  270.     long l = time((long *)0);
  271.     struct stat sbuf;
  272.  
  273.     lseek(ufd, (long)0, 0);
  274.     while (read(ufd, &buf, sizeof(buf)) > 0) {
  275.         if (buf.ut_name[0] != '\0') {
  276.             count++;
  277.         }
  278.     }
  279.     return (was_users = (count > max_users));
  280. }
  281.  
  282. tod()
  283. {
  284. #ifdef TOD
  285.     long now;
  286.     struct tm *localtime();
  287.     struct tm *ntime;
  288.  
  289.     time(&now);
  290.     ntime = localtime(&now);
  291.     if(ntime->tm_wday == 0 || ntime->tm_wday == 6)
  292.         return(was_tod = FALSE);/* OK on Sat & Sun */
  293.     if(ntime->tm_hour < MORNING || ntime->tm_hour >= EVENING)
  294.         return(was_tod = FALSE);/* OK during non working hours */
  295.     
  296.     return(was_tod = TRUE);
  297. #endif
  298. }
  299.  
  300. checkfor(file)
  301. char *file;
  302. {
  303.     char buf[200];
  304.     FILE *fd, *fopen();
  305.  
  306.     if((fd = fopen(file, "r")) != NULL) {
  307.         fprintf(stderr, "Sorry, no games now...\n");
  308.         while(fgets(buf, sizeof(buf), fd))
  309.             fprintf(stderr, buf);
  310.         fclose(fd);
  311.         return(TRUE);
  312.     }
  313.     return(FALSE);
  314. }
  315.