1 static char *sccsid = "@(#)wall.c 4.8 (Berkeley) 84/03/30"; 2 /* 3 * wall.c - Broadcast a message to all users. 4 * 5 * This program is not related to David Wall, whose Stanford Ph.D. thesis 6 * is entitled "Mechanisms for Broadcast and Selective Broadcast". 7 */ 8 9 #include <stdio.h> 10 #include <utmp.h> 11 #include <errno.h> 12 #include <signal.h> 13 #include <sys/time.h> 14 #include <fcntl.h> 15 16 #define USERS 128 17 #define IGNOREUSER "sleeper" 18 19 char hostname[32]; 20 char mesg[3000]; 21 int msize,sline; 22 struct utmp utmp[USERS]; 23 char *strcpy(); 24 char *strcat(); 25 char who[9] = "???"; 26 long clock, time(); 27 struct tm *localtime(); 28 struct tm *localclock; 29 30 extern errno; 31 32 main(argc, argv) 33 char *argv[]; 34 { 35 register int i, c; 36 register struct utmp *p; 37 FILE *f; 38 39 gethostname(hostname, sizeof (hostname)); 40 if ((f = fopen("/etc/utmp", "r")) == NULL) { 41 fprintf(stderr, "Cannot open /etc/utmp\n"); 42 exit(1); 43 } 44 clock = time( 0 ); 45 localclock = localtime( &clock ); 46 sline = ttyslot(); /* 'utmp' slot no. of sender */ 47 c = fread((char *)utmp, sizeof(struct utmp), USERS, f); 48 fclose(f); 49 if (sline) 50 strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name)); 51 sprintf(mesg, 52 "\nBroadcast Message from %s@%s (%.*s) at %d:%02d ...\r\n\n" 53 , who 54 , hostname 55 , sizeof(utmp[sline].ut_line) 56 , utmp[sline].ut_line 57 , localclock -> tm_hour 58 , localclock -> tm_min 59 ); 60 msize = strlen(mesg); 61 if (argc >= 2) { 62 /* take message from unix file instead of standard input */ 63 if (freopen(argv[1], "r", stdin) == NULL) { 64 perror(argv[1]); 65 exit(1); 66 } 67 } 68 while ((i = getchar()) != EOF) { 69 if (i == '\n') 70 mesg[msize++] = '\r'; 71 if (msize >= sizeof mesg) { 72 fprintf(stderr, "Message too long\n"); 73 exit(1); 74 } 75 mesg[msize++] = i; 76 } 77 fclose(stdin); 78 for (i=0; i<c; i++) { 79 p = &utmp[i]; 80 if (p->ut_name[0] == 0 || 81 strncmp(p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0) 82 continue; 83 sendmes(p->ut_line); 84 } 85 exit(0); 86 } 87 88 sendmes(tty) 89 char *tty; 90 { 91 register f, flags; 92 static char t[50] = "/dev/"; 93 int e, i; 94 95 strcpy(t + 5, tty); 96 97 if ((f = open(t, O_WRONLY|O_NDELAY)) < 0) { 98 if (errno != EWOULDBLOCK) 99 perror(t); 100 return; 101 } 102 if ((flags = fcntl(f, F_GETFL, 0)) == -1) { 103 perror(t); 104 return; 105 } 106 if (fcntl(f, F_SETFL, flags | FNDELAY) == -1) 107 goto oldway; 108 i = write(f, mesg, msize); 109 e = errno; 110 (void) fcntl(f, F_SETFL, flags); 111 if (i == msize) { 112 (void) close(f); 113 return; 114 } 115 if (e != EWOULDBLOCK) { 116 errno = e; 117 perror(t); 118 (void) close(f); 119 return; 120 } 121 oldway: 122 while ((i = fork()) == -1) 123 if (wait((int *)0) == -1) { 124 fprintf(stderr, "Try again\n"); 125 return; 126 } 127 if (i) { 128 (void) close(f); 129 return; 130 } 131 132 (void) write(f, mesg, msize); 133 exit(0); 134 } 135