1*16256Sralph static char *sccsid = "@(#)wall.c 4.8 (Berkeley) 84/03/30"; 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> 11*16256Sralph #include <errno.h> 12*16256Sralph #include <signal.h> 1313594Swnj #include <sys/time.h> 14*16256Sralph #include <fcntl.h> 15*16256Sralph 161159Sbill #define USERS 128 173884Sroot #define IGNOREUSER "sleeper" 181159Sbill 196200Sroot char hostname[32]; 201159Sbill char mesg[3000]; 211159Sbill int msize,sline; 221159Sbill struct utmp utmp[USERS]; 231159Sbill char *strcpy(); 241159Sbill char *strcat(); 25*16256Sralph char who[9] = "???"; 263660Smark long clock, time(); 271159Sbill struct tm *localtime(); 281159Sbill struct tm *localclock; 291159Sbill 30*16256Sralph extern errno; 31*16256Sralph 321159Sbill main(argc, argv) 331159Sbill char *argv[]; 341159Sbill { 35*16256Sralph register int i, c; 361159Sbill register struct utmp *p; 371159Sbill FILE *f; 381159Sbill 396200Sroot gethostname(hostname, sizeof (hostname)); 40*16256Sralph if ((f = fopen("/etc/utmp", "r")) == NULL) { 411159Sbill fprintf(stderr, "Cannot open /etc/utmp\n"); 421159Sbill exit(1); 431159Sbill } 441159Sbill clock = time( 0 ); 451159Sbill localclock = localtime( &clock ); 46*16256Sralph sline = ttyslot(); /* 'utmp' slot no. of sender */ 47*16256Sralph c = fread((char *)utmp, sizeof(struct utmp), USERS, f); 48*16256Sralph fclose(f); 49*16256Sralph if (sline) 50*16256Sralph strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name)); 51*16256Sralph sprintf(mesg, 52*16256Sralph "\nBroadcast Message from %s@%s (%.*s) at %d:%02d ...\r\n\n" 53*16256Sralph , who 54*16256Sralph , hostname 55*16256Sralph , sizeof(utmp[sline].ut_line) 56*16256Sralph , utmp[sline].ut_line 57*16256Sralph , localclock -> tm_hour 58*16256Sralph , localclock -> tm_min 59*16256Sralph ); 60*16256Sralph msize = strlen(mesg); 61*16256Sralph if (argc >= 2) { 621159Sbill /* take message from unix file instead of standard input */ 63*16256Sralph if (freopen(argv[1], "r", stdin) == NULL) { 64*16256Sralph perror(argv[1]); 651159Sbill exit(1); 661159Sbill } 671159Sbill } 68*16256Sralph while ((i = getchar()) != EOF) { 69*16256Sralph if (i == '\n') 70*16256Sralph mesg[msize++] = '\r'; 713176Swnj if (msize >= sizeof mesg) { 723176Swnj fprintf(stderr, "Message too long\n"); 733176Swnj exit(1); 743176Swnj } 753176Swnj mesg[msize++] = i; 763176Swnj } 77*16256Sralph fclose(stdin); 78*16256Sralph for (i=0; i<c; i++) { 791159Sbill p = &utmp[i]; 80*16256Sralph if (p->ut_name[0] == 0 || 81*16256Sralph strncmp(p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0) 821159Sbill continue; 831159Sbill sendmes(p->ut_line); 841159Sbill } 851159Sbill exit(0); 861159Sbill } 871159Sbill 881159Sbill sendmes(tty) 891159Sbill char *tty; 901159Sbill { 91*16256Sralph register f, flags; 92*16256Sralph static char t[50] = "/dev/"; 93*16256Sralph int e, i; 941159Sbill 95*16256Sralph strcpy(t + 5, tty); 96*16256Sralph 97*16256Sralph if ((f = open(t, O_WRONLY|O_NDELAY)) < 0) { 98*16256Sralph if (errno != EWOULDBLOCK) 99*16256Sralph perror(t); 100*16256Sralph return; 101*16256Sralph } 102*16256Sralph if ((flags = fcntl(f, F_GETFL, 0)) == -1) { 103*16256Sralph perror(t); 104*16256Sralph return; 105*16256Sralph } 106*16256Sralph if (fcntl(f, F_SETFL, flags | FNDELAY) == -1) 107*16256Sralph goto oldway; 108*16256Sralph i = write(f, mesg, msize); 109*16256Sralph e = errno; 110*16256Sralph (void) fcntl(f, F_SETFL, flags); 111*16256Sralph if (i == msize) { 112*16256Sralph (void) close(f); 113*16256Sralph return; 114*16256Sralph } 115*16256Sralph if (e != EWOULDBLOCK) { 116*16256Sralph errno = e; 117*16256Sralph perror(t); 118*16256Sralph (void) close(f); 119*16256Sralph return; 120*16256Sralph } 121*16256Sralph oldway: 1223176Swnj while ((i = fork()) == -1) 1233176Swnj if (wait((int *)0) == -1) { 1243176Swnj fprintf(stderr, "Try again\n"); 1253176Swnj return; 1263176Swnj } 127*16256Sralph if (i) { 128*16256Sralph (void) close(f); 1291159Sbill return; 1301159Sbill } 1311159Sbill 132*16256Sralph (void) write(f, mesg, msize); 1331159Sbill exit(0); 1341159Sbill } 135