#include #include #include #include #define TRUE -1 #define FALSE 0 #define COPYBUFFSIZE 1024 #define FILENAMELEN 40 #define LINELEN 160 #ifdef DEBUG #define TTYTYPE "/g/don/ttyset/ttytype" #define TTYWHERE "/g/don/ttyset/ttywhere" #define TTYS "/g/don/ttyset/ttys" #define GETTYTAB "/g/don/ttyset/gettytab" #else #define TTYTYPE "/etc/ttytype" #define TTYWHERE "/etc/ttywhere" #define TTYS "/etc/ttys" #define GETTYTAB "/etc/gettytab" #endif #define NEXTARGV ((argc-- > 0) ? *(++argv) : (char *)NULL) #define SHORT_TTY_NAME (strcmp(tty_name,"console") ? tty_name + 3 : "co") char *my_name,*tty_name = NULL,ability,speed,speed_name[LINELEN],ref[3], lnk[3],dev[3],who[14],where[41],what[LINELEN - 57],type[LINELEN], search_gettytab_by_name(),*search_gettytab_by_key(),*ttyname(), *index(),*rindex(); int errno; FILE *gettytab; struct file_of_lines { char file_name[LINELEN],temp_name[LINELEN]; int changed; FILE *fp,*temp_fp; char line[LINELEN]; } ttytype = {TTYTYPE,"",FALSE,NULL,NULL,""}, ttywhere = {TTYWHERE,"",FALSE,NULL,NULL,""}, ttys = {TTYS,"",FALSE,NULL,NULL,""}; main(argc,argv) int argc; char **argv; { my_name = *argv++; argc--; if((argc == 0) || (**argv == '-')) { if((tty_name = rindex(ttyname(0),'/')) < 0) bomb("No tty\n"); tty_name++; get_tty_info(); } else { tty_name = *argv++; argc--; get_tty_info(); } for(; argc-- != 0; argv++) if(**argv == '-') switch(argv[0][1]) { case 'e': ability = '1'; ttys.changed = TRUE; break; case 'd': ability = '0'; ttys.changed = TRUE; break; case 't': if(argv++, argc-- == 0) bomb("You must give a terminal type after -t\n"); if(index(*argv,' ') != NULL) bomb("Spaces are not allowed in the terminal type \"%s\".\n",*argv); strcpy(type,*argv); ttytype.changed = TRUE; break; case 's': if(argv++, argc-- == 0) bomb("You must give a speed after -s\n"); if((speed = search_gettytab_by_name(*argv)) == NULL) bomb("%s is not a valid speed\n",*argv); ttys.changed = ttywhere.changed = TRUE; break; case 'w': if(argv[0][2] == 'h') switch(argv[0][3]) { case 'o': if(argv++, argc-- == 0) bomb("You must give a name after -who\n"); strncpy(who,*argv,14); ttywhere.changed = TRUE; break; case 'e': if(argv++, argc-- == 0) bomb("You must give a location after -where\n"); strncpy(where,*argv,41); ttywhere.changed = TRUE; break; case 'a': if(argv++, argc-- == 0) bomb("You must give a description after -what\n"); strncpy(what,*argv,LINELEN - 57); ttywhere.changed = TRUE; break; case 'y': bomb("Why not, ostrich breath?\n"); break; default: goto bad_switch; } else goto bad_switch; break; default: bad_switch: bomb("Silly switch: %s\n",*argv); break; } else { put_tty_info(); tty_name = *argv; get_tty_info(); } put_tty_info(); } get_tty_info() { char *word_end; int starts_in_third_column(),ends_with(),starts_with(); search_file(&ttys,starts_in_third_column,tty_name); ability = ttys.line[0]; speed = ttys.line[1]; *speed_name = '\0'; search_file(&ttytype,ends_with,tty_name); if((word_end = index(ttytype.line,' ')) == NULL) bomb("Bad format in %s\n",ttytype.file_name); *word_end = '\0'; strcpy(type,ttytype.line); search_file(&ttywhere,starts_with,SHORT_TTY_NAME); ttywhere.line[strlen(ttywhere.line) - 1] = '\0'; get_field(ref,ttywhere.line+4,3); get_field(lnk,ttywhere.line+8,3); get_field(dev,ttywhere.line+12,3); get_field(who,ttywhere.line+26,14); get_field(where,ttywhere.line+41,15); get_field(what,ttywhere.line+57,22); } put_tty_info() { list_tty_info(); if(ttys.changed == TRUE) { ttys.line[0] = ability; ttys.line[1] = speed; write_back(&ttys); } else clean_up(&ttys); if(ttytype.changed == TRUE) { sprintf(ttytype.line,"%s %s\n",type,tty_name); write_back(&ttytype); } else clean_up(&ttytype); if(ttywhere.changed == TRUE) { sprintf(ttywhere.line, "%-3.3s %3.3s %-3.3s %-3.3s %-9.9s %-14.14s %-15.15s %.22s\n", SHORT_TTY_NAME,ref,lnk,dev,speed_name,who,where,what); write_back(&ttywhere); } else clean_up(&ttywhere); } list_tty_info() { if(*speed_name == '\0') search_gettytab_by_key(speed); printf("%s: %sabled, speed \"%s\", type \"%s\",\n", tty_name,ability == '1' ? "en" : "dis",speed_name,type); printf("who \"%s\", where \"%s\", what \"%s\".\n", who,where,what); } FILE *open_file(file_name,mode) char *file_name,*mode; { FILE *fp; if((fp = fopen(file_name,mode)) == NULL) bomb("Error opening %s\n",file_name); return(fp); } starts_with(line,string) char *line,*string; { return(!strncmp(line,string,strlen(string))); } ends_with(line,string) char *line,*string; { return(!strncmp(line + strlen(line) - strlen(string) - 1, string,strlen(string))); } starts_in_third_column(line,string) char *line,*string; { return(!strncmp(line+2,string,strlen(string))); } search_file(this_file,compare,string) struct file_of_lines *this_file; int (*compare)(); char *string; { struct stat st; int temp_fd; this_file->changed = FALSE; this_file->fp = open_file(this_file->file_name,"r"); if(fstat(fileno(this_file->fp),&st) < 0) bomb("Error doing fstat to %s\n",this_file->file_name); sprintf(this_file->temp_name,"%s.%d",this_file->file_name,getpid()); temp_fd = open(this_file->temp_name,O_CREAT|O_RDWR|O_TRUNC,st.st_mode); if(temp_fd < 0) bomb("Error opening %s\n",this_file->temp_name); if(fchown(temp_fd,st.st_uid,st.st_gid) < 0) bomb("Error doing chown on %s\n",this_file->temp_name); if((this_file->temp_fp = fdopen(temp_fd,"w")) < 0) bomb("Error doing fdopen on %s\n",this_file->temp_name); while((fgets(this_file->line,LINELEN,this_file->fp ) != NULL) && !(*compare)(this_file->line,string)) if(fputs(this_file->line,this_file->temp_fp) == EOF) bomb("Error doing fputs to %s\n",this_file->temp_name); if(feof(this_file->fp)) bomb("Can't find %s in %s\n",string,this_file->file_name); strncpy(this_file->line + strlen(this_file->line),"", LINELEN - strlen(this_file->line)); } write_back(this_file) struct file_of_lines *this_file; { char copy_buff[COPYBUFFSIZE]; int transfered; if(fwrite(this_file->line,1,strlen(this_file->line), this_file->temp_fp) != strlen(this_file->line)) bomb("Error writing line to %s\n",this_file->temp_name); while((transfered = fread(copy_buff,1,COPYBUFFSIZE,this_file->fp)) > 0) if(fwrite(copy_buff,1,transfered,this_file->temp_fp) != transfered) bomb("Error writing to %s\n",this_file->temp_name); if(fclose(this_file->temp_fp)) bomb("Error closing %s\n",this_file->temp_name); if(rename(this_file->temp_name,this_file->file_name) < 0) bomb("Error renaming %s to %s\n",this_file->temp_name, this_file->file_name); } clean_up(this_file) struct file_of_lines *this_file; { if(this_file->temp_fp != NULL) fclose(this_file->temp_fp); if(*this_file->temp_name != '\0') unlink(this_file->temp_name); } sub_string(line,string) char *line,*string; { int string_len = strlen(string), line_len = strlen(line); while(line_len-- >= string_len) if(!strncmp(line++,string,string_len)) return(TRUE); return(FALSE); } bomb(msg,a1,a2) char *msg,*a1,*a2; { fprintf(stderr,"%s: errno=%d: ",my_name,errno); fprintf(stderr,msg,a1,a2); clean_up(&ttytype); clean_up(&ttywhere); clean_up(&ttys); exit(-1); } char search_gettytab_by_name(name) char *name; { char line[LINELEN],*lp,*pp,*strcat(); FILE *this_file; this_file = open_file(GETTYTAB,"r"); while(fgets(line,LINELEN,this_file) != NULL) { if(line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0'; if((*line != '\0') && (*line != '#')) { lp = line; while((*lp != '\0') && (*lp != ':')) { pp = name; while((*lp != '\0') && (*lp != '|') && (*lp != ':') && (*pp != '\0') && (*pp == *lp)) pp++, lp++; if((*pp == '\0') && ((*lp == '|') || (*lp == ':'))) return(*line); while((*lp != '|') && (*lp != ':')) lp++; lp++; } while((line[strlen(line)-1] == '\\') && (fgets(line,LINELEN,this_file) != NULL)) if(line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0'; } } bomb("Can't find speed %s in %s\n",name,GETTYTAB); } char *search_gettytab_by_key(key) char key; { char line[LINELEN],*lb,*lp,*strip(); FILE *gettytab; gettytab = open_file(GETTYTAB,"r"); while(fgets(line,LINELEN,gettytab) != NULL) if(line[0] != '#') if((line[0] == key) && (line[1] == '|')) { lp = line; lb = line + 2; while((*lp != '\0') && (*lp != ':')) if(*(lp++) == '|') lb = lp; if(*lp == '\0') bomb("Bad format in %s\n",GETTYTAB); *lp = '\0'; strcpy(speed_name,lb); return(speed_name); } bomb("Can't find speed %c in %s\n",key,GETTYTAB); } get_field(into,from,len) char *into,*from; int len; { char *string_end; from[len] = '\0'; for(string_end = from; *string_end != '\0'; string_end++); while((from < string_end) && (*from == ' ')) from++; while((string_end > from) && (*(string_end - 1) == ' ')) string_end--; *string_end = '\0'; return(strncpy(into,from,len)); }