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