1*3884Sroot static char *sccsid = "@(#)wall.c 4.5 (Berkeley) 81/06/12"; 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 15*3884Sroot #define IGNOREUSER "sleeper" 161159Sbill 171159Sbill char mesg[3000]; 181159Sbill int msize,sline; 191159Sbill struct utmp utmp[USERS]; 201159Sbill char *strcpy(); 211159Sbill char *strcat(); 221159Sbill char who[9] = "???"; 233660Smark long clock, time(); 241159Sbill struct tm *localtime(); 251159Sbill struct tm *localclock; 261159Sbill 271159Sbill main(argc, argv) 281159Sbill char *argv[]; 291159Sbill { 301159Sbill register i; 311159Sbill register char c; 321159Sbill register struct utmp *p; 331159Sbill FILE *f; 343176Swnj FILE *mf; 351159Sbill 361159Sbill if((f = fopen("/etc/utmp", "r")) == NULL) { 371159Sbill fprintf(stderr, "Cannot open /etc/utmp\n"); 381159Sbill exit(1); 391159Sbill } 401159Sbill clock = time( 0 ); 411159Sbill localclock = localtime( &clock ); 423176Swnj mf = stdin; 431159Sbill if(argc >= 2) { 441159Sbill /* take message from unix file instead of standard input */ 453176Swnj if((mf = fopen(argv[1], "r")) == NULL) { 461159Sbill fprintf(stderr,"Cannot open %s\n", argv[1]); 471159Sbill exit(1); 481159Sbill } 491159Sbill } 503176Swnj while((i = getc(mf)) != EOF) { 513176Swnj if (msize >= sizeof mesg) { 523176Swnj fprintf(stderr, "Message too long\n"); 533176Swnj exit(1); 543176Swnj } 553176Swnj mesg[msize++] = i; 563176Swnj } 573176Swnj fclose(mf); 583176Swnj sline = ttyslot(2); /* 'utmp' slot no. of sender */ 593176Swnj fread((char *)utmp, sizeof(struct utmp), USERS, f); 601159Sbill fclose(f); 613176Swnj if (sline) 623176Swnj strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name)); 631159Sbill for(i=0; i<USERS; i++) { 641159Sbill p = &utmp[i]; 65*3884Sroot if ((p->ut_name[0] == 0) || 66*3884Sroot (strncmp (p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0)) 671159Sbill continue; 683176Swnj /*** this might be nice, but utmp gets so out of date !! 691159Sbill sleep(1); 703176Swnj ***/ 711159Sbill sendmes(p->ut_line); 721159Sbill } 731159Sbill exit(0); 741159Sbill } 751159Sbill 761159Sbill sendmes(tty) 771159Sbill char *tty; 781159Sbill { 791159Sbill register i; 801159Sbill char t[50], buf[BUFSIZ]; 811159Sbill register char *cp; 821159Sbill register int c, ch; 831159Sbill FILE *f; 841159Sbill 853176Swnj /*** you can't do this with lots of users & MAXUPROC 861159Sbill i = fork(); 871159Sbill if(i == -1) { 881159Sbill fprintf(stderr, "Try again\n"); 891159Sbill return; 901159Sbill } 913176Swnj ***/ 923176Swnj while ((i = fork()) == -1) 933176Swnj if (wait((int *)0) == -1) { 943176Swnj fprintf(stderr, "Try again\n"); 953176Swnj return; 963176Swnj } 971159Sbill if(i) 981159Sbill return; 991159Sbill strcpy(t, "/dev/"); 1001159Sbill strcat(t, tty); 1011159Sbill 1023176Swnj signal(SIGALRM, SIG_DFL); /* blow away if open hangs */ 1033176Swnj alarm(10); 1043176Swnj 1051159Sbill if((f = fopen(t, "w")) == NULL) { 1061159Sbill fprintf(stderr,"cannot open %s\n", t); 1071159Sbill exit(1); 1081159Sbill } 1091159Sbill setbuf(f, buf); 1103176Swnj fprintf(f, 1113176Swnj "\nBroadcast Message from %s!%s (%.*s) at %d:%02d ...\r\n\n" 1123176Swnj , sysname 1133176Swnj , who 1143176Swnj , sizeof(utmp[sline].ut_line) 1153176Swnj , utmp[sline].ut_line 1163176Swnj , localclock -> tm_hour 1173176Swnj , localclock -> tm_min 1183176Swnj ); 1191159Sbill /* fwrite(mesg, msize, 1, f); */ 1201159Sbill for (cp = mesg, c = msize; c-- > 0; cp++) { 1211159Sbill ch = *cp; 1221159Sbill if (ch == '\n') 1231159Sbill putc('\r', f); 1241159Sbill putc(ch, f); 1251159Sbill } 1261159Sbill 1271159Sbill /* 1281159Sbill * Bitchin'. 1291159Sbill */ 1301159Sbill 1311159Sbill exit(0); 1321159Sbill } 133