#include <stdio.h>
#include <string.h>

struct myutmp{
           char ut_line[9];
           char ut_name[9];
           char ut_host[17];
           char ut_time[5];
}record;
FILE *fp;
unsigned long fsize,t=(unsigned long) 0,m;
char *buffer,*IPaddress;
char Line[9],Name[9],Host[17];
char Line1[9],Name1[9],Host1[17];
int  lineflg,nameflg,hostflg,clearflg;
int  line1flg,name1flg,host1flg;

int  ReadUtmp();
int  Check();
void Update();

void main(argc,argv)
     int argc; char *argv[];
{
     long i;
     int  c,errflg;
     extern char *optarg;
     extern int   optind;

     errflg=lineflg=nameflg=hostflg=clearflg=0;
     line1flg=name1flg=host1flg=0;
     while((c=getopt(argc,argv,"u:t:a:v:y:d:c")) != -1)
	 switch(c) {
	     case 'u': strncpy(Name,optarg,8);
		       nameflg++;
		       break;
	     case 't': strncpy(Line,optarg,8);
		       lineflg++;
		       break;
	     case 'a': strncpy(Host,optarg,16);
		       hostflg++;
		       break;
	     case 'v': strncpy(Name1,optarg,8);
		       name1flg++;
		       break;
	     case 'y': strncpy(Line1,optarg,8);
		       line1flg++;
		       break;
	     case 'd': strncpy(Host1,optarg,16);
		       host1flg++;
		       break;
	     case 'c': clearflg++;
		       break;
             case '?': errflg++;
		       break;
         }
     if(errflg|| (argc<2) || !(nameflg||lineflg||hostflg)) {
         printf("Usage: cwho [-c] ((-u usr)(-t tty)(-a hos)) ");
         printf("[-v nusr] [-y ntty] [-d nhos]\n");
         exit(1);
     }
     fp=fopen("/etc/utmp","r+");
     if(fp==NULL) {
         printf("Cannot open file /etc/utmp !\n");
         exit(1);
     }
     fseek(fp,(long) 0,2);
     fsize=(unsigned long) ftell(fp);
     fseek(fp,(long) 0,0);
     buffer=(char *) malloc(fsize);
     for(i=0;i<fsize;i++) buffer[i]=fgetc(fp);
     fseek(fp,(long) 0,0);
     record.ut_line[8]='\0';
     record.ut_name[8]='\0';
     record.ut_host[16]='\0';
     record.ut_time[4]='\0';
     while(ReadUtmp()) if(Check()) Update();
     for(i=0;i<fsize;i++) fputc(buffer[i],fp);
     free(buffer);
     fclose(fp);
     system("who");
} 

int  ReadUtmp()
{
     int i;

     if(t>=fsize) return 0;
     for(i=0;i<8;i++)  record.ut_line[i]=buffer[t++];
     for(i=0;i<8;i++)  record.ut_name[i]=buffer[t++];
     for(i=0;i<16;i++) record.ut_host[i]=buffer[t++];
     for(i=0;i<4;i++)  record.ut_time[i]=buffer[t++];
     return 1;
}

int  Check()
{
     if(nameflg && strncmp(record.ut_name,Name,8)) return 0;          
     if(lineflg && strncmp(record.ut_line,Line,8)) return 0;          
     if(hostflg && strncmp(record.ut_host,Host,16)) return 0;          
     return 1;
}
     
void Update()
{
     int i,m;

     m = t-36;
     if(clearflg) for(i=0;i<36;i++) buffer[m++]='\0';
     else {
	 if(line1flg) for(i=0;i<8;i++) buffer[m++]=Line1[i];
	 else m+=8;
         if(name1flg) for(i=0;i<8;i++) buffer[m++]=Name1[i];
	 else m+=8;
         if(host1flg) for(i=0;i<16;i++) buffer[m++]=Host1[i];
     }
}
