#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define PIDFILE  "/etc/process"
#define TIMEFILE "/etc/usertimes"
#define TEMPFILE "/etc/usertimes.new"
#define MAXUSERS 100
#define GUESTUID 500
#define GUESTTIME 2

void main()
{
 FILE *pfile, *ufile, *tfile;
 int dummy,uid,uuid,ppid,t,users[MAXUSERS],ucount,count;
 char rest[80];
 char command[80];
 int guest_here;
 
 /* create process list */
 sprintf (command,"ps -lxOUT >%s",PIDFILE);
 system (command); 
 
 /* loop through all processes collecting userids */
 pfile = fopen (PIDFILE,"r");
 ucount=-1;
 guest_here=0;
 while ( !feof(pfile) )
 {
  fscanf (pfile,"%i %i %i",&dummy,&uid,&ppid);
  fgets (rest,80,pfile);
  if (!feof(pfile))
  {
   if (((ucount==-1) || (users[ucount] != uid)) && (ucount<(MAXUSERS-1)))
   {
    ucount++;
    users[ucount]=uid;
    if (uid==GUESTUID) guest_here++;
   }    
  } 
 }
 fclose(pfile);

 /* loop through all user, updating times to new file */
 ufile = fopen (TIMEFILE,"r");
 tfile = fopen (TEMPFILE,"w+");
 while ( !feof(ufile) )
 {
  uuid=0;
  fscanf (ufile,"%i %i\n",&uuid,&t);
  /* always skip root */
  if (uuid != 0)
  {
   /* scan if user is logged in */
   for (count=0; count<=ucount; count++) if (uuid==users[count]) 
   {
    /* found one, decrease his time count */
    t=t-1;
    if (t<0) t=0;
    /* kick user 'uuid' out by killing all his processes */
    if (t==0)
    {     
     pfile = fopen (PIDFILE,"r");
     while ( !feof(pfile) )
     {
      fscanf (pfile,"%i %i %i",&dummy,&uid,&ppid);
      fgets (rest,80,pfile);
      if (!feof(pfile) && (uid==uuid))
      {
       sprintf (command,"kill -s SIGTERM %i 2>/dev/null",ppid);
       system (command);
       sprintf (command,"kill -s SIGKILL %i 2>/dev/null",ppid);
       system (command);
      }
     } 
     fclose (pfile);
    }
   } 
   /* update tempfile, let guest in */
   if ((guest_here==0) && (uuid==GUESTUID)) t=GUESTTIME;
   fprintf (tfile,"%i %i\n",uuid,t);
  } 
 } 
 fclose (ufile);
 fclose (tfile);
 
 /* update usertimes and clean up */
 sprintf (command,"cp %s %s",TEMPFILE,TIMEFILE);
 system (command);
 sprintf (command,"rm %s",TEMPFILE);
 system (command); 
 sprintf (command,"rm %s",PIDFILE);
 system (command); 
}
