1*3660Smark static char *sccsid = "@(#)wall.c 4.4 (Berkeley) 81/05/06"; 21159Sbill /* 31159Sbill * wall.c - Broadcast a message to all users. 41159Sbill * 51159Sbill * This program is not related to David Wall, whose Stanford Ph.D. thesis 61159Sbill * is entitled "Mechanisms for Broadcast and Selective Broadcast". 71159Sbill */ 81159Sbill 91159Sbill #include <stdio.h> 101159Sbill #include <utmp.h> 111159Sbill #include <time.h> 123176Swnj #include <whoami.h> 133176Swnj #include <signal.h> 141159Sbill #define USERS 128 151159Sbill 161159Sbill char mesg[3000]; 171159Sbill int msize,sline; 181159Sbill struct utmp utmp[USERS]; 191159Sbill char *strcpy(); 201159Sbill char *strcat(); 211159Sbill char who[9] = "???"; 22*3660Smark long clock, time(); 231159Sbill struct tm *localtime(); 241159Sbill struct tm *localclock; 251159Sbill 261159Sbill main(argc, argv) 271159Sbill char *argv[]; 281159Sbill { 291159Sbill register i; 301159Sbill register char c; 311159Sbill register struct utmp *p; 321159Sbill FILE *f; 333176Swnj FILE *mf; 341159Sbill 351159Sbill if((f = fopen("/etc/utmp", "r")) == NULL) { 361159Sbill fprintf(stderr, "Cannot open /etc/utmp\n"); 371159Sbill exit(1); 381159Sbill } 391159Sbill clock = time( 0 ); 401159Sbill localclock = localtime( &clock ); 413176Swnj mf = stdin; 421159Sbill if(argc >= 2) { 431159Sbill /* take message from unix file instead of standard input */ 443176Swnj if((mf = fopen(argv[1], "r")) == NULL) { 451159Sbill fprintf(stderr,"Cannot open %s\n", argv[1]); 461159Sbill exit(1); 471159Sbill } 481159Sbill } 493176Swnj while((i = getc(mf)) != EOF) { 503176Swnj if (msize >= sizeof mesg) { 513176Swnj fprintf(stderr, "Message too long\n"); 523176Swnj exit(1); 533176Swnj } 543176Swnj mesg[msize++] = i; 553176Swnj } 563176Swnj fclose(mf); 573176Swnj sline = ttyslot(2); /* 'utmp' slot no. of sender */ 583176Swnj fread((char *)utmp, sizeof(struct utmp), USERS, f); 591159Sbill fclose(f); 603176Swnj if (sline) 613176Swnj strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name)); 621159Sbill for(i=0; i<USERS; i++) { 631159Sbill p = &utmp[i]; 641159Sbill if(p->ut_name[0] == 0) 651159Sbill continue; 663176Swnj /*** this might be nice, but utmp gets so out of date !! 671159Sbill sleep(1); 683176Swnj ***/ 691159Sbill sendmes(p->ut_line); 701159Sbill } 711159Sbill exit(0); 721159Sbill } 731159Sbill 741159Sbill sendmes(tty) 751159Sbill char *tty; 761159Sbill { 771159Sbill register i; 781159Sbill char t[50], buf[BUFSIZ]; 791159Sbill register char *cp; 801159Sbill register int c, ch; 811159Sbill FILE *f; 821159Sbill 833176Swnj /*** you can't do this with lots of users & MAXUPROC 841159Sbill i = fork(); 851159Sbill if(i == -1) { 861159Sbill fprintf(stderr, "Try again\n"); 871159Sbill return; 881159Sbill } 893176Swnj ***/ 903176Swnj while ((i = fork()) == -1) 913176Swnj if (wait((int *)0) == -1) { 923176Swnj fprintf(stderr, "Try again\n"); 933176Swnj return; 943176Swnj } 951159Sbill if(i) 961159Sbill return; 971159Sbill strcpy(t, "/dev/"); 981159Sbill strcat(t, tty); 991159Sbill 1003176Swnj signal(SIGALRM, SIG_DFL); /* blow away if open hangs */ 1013176Swnj alarm(10); 1023176Swnj 1031159Sbill if((f = fopen(t, "w")) == NULL) { 1041159Sbill fprintf(stderr,"cannot open %s\n", t); 1051159Sbill exit(1); 1061159Sbill } 1071159Sbill setbuf(f, buf); 1083176Swnj fprintf(f, 1093176Swnj "\nBroadcast Message from %s!%s (%.*s) at %d:%02d ...\r\n\n" 1103176Swnj , sysname 1113176Swnj , who 1123176Swnj , sizeof(utmp[sline].ut_line) 1133176Swnj , utmp[sline].ut_line 1143176Swnj , localclock -> tm_hour 1153176Swnj , localclock -> tm_min 1163176Swnj ); 1171159Sbill /* fwrite(mesg, msize, 1, f); */ 1181159Sbill for (cp = mesg, c = msize; c-- > 0; cp++) { 1191159Sbill ch = *cp; 1201159Sbill if (ch == '\n') 1211159Sbill putc('\r', f); 1221159Sbill putc(ch, f); 1231159Sbill } 1241159Sbill 1251159Sbill /* 1261159Sbill * Bitchin'. 1271159Sbill */ 1281159Sbill 1291159Sbill exit(0); 1301159Sbill } 131