1*3176Swnj static char *sccsid = "@(#)wall.c 4.2 (Berkeley) 81/03/10"; 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> 12*3176Swnj #include <whoami.h> 13*3176Swnj #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] = "???"; 221159Sbill long clock; 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; 33*3176Swnj 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 ); 41*3176Swnj mf = stdin; 421159Sbill if(argc >= 2) { 431159Sbill /* take message from unix file instead of standard input */ 44*3176Swnj if((mf = fopen(argv[1], "r")) == NULL) { 451159Sbill fprintf(stderr,"Cannot open %s\n", argv[1]); 461159Sbill exit(1); 471159Sbill } 481159Sbill } 49*3176Swnj while((i = getc(mf)) != EOF) { 50*3176Swnj if (msize >= sizeof mesg) { 51*3176Swnj fprintf(stderr, "Message too long\n"); 52*3176Swnj exit(1); 53*3176Swnj } 54*3176Swnj mesg[msize++] = i; 55*3176Swnj } 56*3176Swnj fclose(mf); 57*3176Swnj sline = ttyslot(2); /* 'utmp' slot no. of sender */ 58*3176Swnj fread((char *)utmp, sizeof(struct utmp), USERS, f); 591159Sbill fclose(f); 60*3176Swnj if (sline) 61*3176Swnj 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; 66*3176Swnj /*** this might be nice, but utmp gets so out of date !! 671159Sbill sleep(1); 68*3176Swnj ***/ 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 83*3176Swnj /*** 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 } 89*3176Swnj ***/ 90*3176Swnj while ((i = fork()) == -1) 91*3176Swnj if (wait((int *)0) == -1) { 92*3176Swnj fprintf(stderr, "Try again\n"); 93*3176Swnj return; 94*3176Swnj } 951159Sbill if(i) 961159Sbill return; 971159Sbill strcpy(t, "/dev/"); 981159Sbill strcat(t, tty); 991159Sbill 100*3176Swnj signal(SIGALRM, SIG_DFL); /* blow away if open hangs */ 101*3176Swnj alarm(10); 102*3176Swnj 1031159Sbill if((f = fopen(t, "w")) == NULL) { 1041159Sbill fprintf(stderr,"cannot open %s\n", t); 1051159Sbill exit(1); 1061159Sbill } 1071159Sbill setbuf(f, buf); 108*3176Swnj fprintf(f, 109*3176Swnj "\nBroadcast Message from %s!%s (%.*s) at %d:%02d ...\r\n\n" 110*3176Swnj , sysname 111*3176Swnj , who 112*3176Swnj , sizeof(utmp[sline].ut_line) 113*3176Swnj , utmp[sline].ut_line 114*3176Swnj , localclock -> tm_hour 115*3176Swnj , localclock -> tm_min 116*3176Swnj ); 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