#include #include #include #include #include #include #define MAXPLAN 20 #define DELIMITER "\n---8<---\n" char host[MAXHOSTNAMELEN+1]; char path[MAXPATHLEN]; int planpos[MAXPLAN]; char *programname; void emsg(); int main(argc,argv) int argc; char **argv; { FILE *fp; char *plandata; int planno; char *hostdata; char *home; char *ptr,*p; char *logdata; struct stat st; int len; int flg=0; int i; int last; programname=argv[0]; /* for error messages */ if((ptr=strrchr(programname,'/')))programname=ptr+1; /* the following lines set flg to 1 on login, 2 on logout. */ if(argc>1&&!(argc==2&&((strstr(argv[1],"login")&&(flg=1))|| (strstr(argv[1],"logout")&&(flg=2))))){ fprintf(stderr,"Usage: %s [login|logout]\n",programname); exit(1); } if(gethostname(host,sizeof host))emsg("gethostname"); if(!(home=getenv("HOME"))){ fprintf(stderr,"%s: HOME: undefined environment variable\n",programname); exit(1); } sprintf(path,"%s/.plans",home); if(stat(path,&st))planno=0; else{ /* slurp in the whole .plans file, and separate it into sections */ if(!(plandata=malloc((size_t)st.st_size+1)))emsg("malloc"); if(!(fp=fopen(path,"r")))emsg(path); if((len=fread(plandata,1,(int)st.st_size,fp))!=st.st_size){ fprintf(stderr,"%s: %s: read error\n",programname,path); exit(1); } fclose(fp); plandata[len]=0; planpos[0]=0; for(planno=1,ptr=plandata;(ptr=strstr(ptr,DELIMITER)); planpos[planno++]=(ptr+=sizeof DELIMITER-1)-plandata)ptr[1]=0; } /* allocate memory and read in the .logins file. There will be some extra allocated space to store another host name, in case of a login. */ sprintf(path,"%s/.logins",home); if(stat(path,&st)){ if(!(hostdata=malloc((size_t)MAXHOSTNAMELEN+2))) emsg("malloc"); hostdata[len=0]=0; } else{ if(!(hostdata=malloc((size_t)st.st_size+MAXHOSTNAMELEN+2))) emsg("malloc"); if(!(fp=fopen(path,"r")))emsg(path); if((len=fread(hostdata,1,(int)st.st_size,fp))!=st.st_size){ fprintf(stderr,"%s: %s: read error\n",programname,path); exit(1); } fclose(fp); hostdata[len]=0; } switch(flg){ case 1: if(len)hostdata[len++]=' '; /* add host name */ strcpy(hostdata+len,host); break; case 2: if((ptr=strstr(hostdata,host))) /* delete host name */ if(!ptr[i=strlen(host)])ptr[-(ptr>hostdata)]=0; else for(i++;(ptr[0]=ptr[i]);ptr++); /* default: do nothing */ } if(flg){ /* write the new .logins, or remove if it is empty */ if(!(len=strlen(hostdata))) if(unlink(path))emsg(path); else; else { if(!(fp=fopen(path,"w")))emsg(path); if(fwrite(hostdata,1,len,fp)!=len)emsg(path); fclose(fp); } } /* Write a plan to the .plans file; free plan storage */ sprintf(path,"%s/.plan",home); if(!(fp=fopen(path,"w")))emsg(path); if(planno){ i=getpid()%planno; len=strlen(ptr=plandata+planpos[i]); if(fwrite(ptr,1,len,fp)!=len)emsg(path); free(plandata); } else fputs("No plan.\n",fp); /* if there are logins, construct the list, avoiding repetitions */ if((ptr=hostdata)[0]){ if(!(logdata=malloc((size_t)strlen(hostdata)+50))) emsg("malloc"); strcpy(logdata,"\nCurrently logged on at:"); last=0; while(!last){ if(!(p=strchr(ptr,' ')))p=strchr(ptr,0),last=1; *p=0; if(last||!strstr(p+1,ptr)) strcat(logdata," "), strcat(logdata,ptr); ptr=p+1; } ptr=logdata; /* add the list to the plan, splitting up long lines */ while(strlen(ptr)>72){ for(p=ptr+72;*--p!=' ';); *p=0; fprintf(fp,"%s\n",ptr); ptr=p+1; } fprintf(fp,"%s\n",ptr); free(logdata); } fclose(fp); free(hostdata); return 0; } void emsg(data) char *data; { extern int errno; int e=errno; fprintf(stderr,"%s: ",programname); errno=e; /* just in case printf spoiled the error number */ perror(data); exit(1); }