11159Sbill /* 2*19909Sdist * Copyright (c) 1980 Regents of the University of California. 3*19909Sdist * All rights reserved. The Berkeley software License Agreement 4*19909Sdist * specifies the terms and conditions for redistribution. 5*19909Sdist */ 6*19909Sdist 7*19909Sdist #ifndef lint 8*19909Sdist char copyright[] = 9*19909Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10*19909Sdist All rights reserved.\n"; 11*19909Sdist #endif not lint 12*19909Sdist 13*19909Sdist #ifndef lint 14*19909Sdist static char sccsid[] = "@(#)wall.c 5.1 (Berkeley) 05/02/85"; 15*19909Sdist #endif not lint 16*19909Sdist 17*19909Sdist /* 181159Sbill * wall.c - Broadcast a message to all users. 191159Sbill * 201159Sbill * This program is not related to David Wall, whose Stanford Ph.D. thesis 211159Sbill * is entitled "Mechanisms for Broadcast and Selective Broadcast". 221159Sbill */ 231159Sbill 241159Sbill #include <stdio.h> 251159Sbill #include <utmp.h> 2616256Sralph #include <errno.h> 2716256Sralph #include <signal.h> 2813594Swnj #include <sys/time.h> 2916256Sralph #include <fcntl.h> 3016256Sralph 311159Sbill #define USERS 128 323884Sroot #define IGNOREUSER "sleeper" 331159Sbill 346200Sroot char hostname[32]; 351159Sbill char mesg[3000]; 361159Sbill int msize,sline; 371159Sbill struct utmp utmp[USERS]; 381159Sbill char *strcpy(); 391159Sbill char *strcat(); 4016256Sralph char who[9] = "???"; 413660Smark long clock, time(); 421159Sbill struct tm *localtime(); 431159Sbill struct tm *localclock; 441159Sbill 4516256Sralph extern errno; 4616256Sralph 471159Sbill main(argc, argv) 481159Sbill char *argv[]; 491159Sbill { 5016256Sralph register int i, c; 511159Sbill register struct utmp *p; 521159Sbill FILE *f; 531159Sbill 546200Sroot gethostname(hostname, sizeof (hostname)); 5516256Sralph if ((f = fopen("/etc/utmp", "r")) == NULL) { 561159Sbill fprintf(stderr, "Cannot open /etc/utmp\n"); 571159Sbill exit(1); 581159Sbill } 591159Sbill clock = time( 0 ); 601159Sbill localclock = localtime( &clock ); 6116256Sralph sline = ttyslot(); /* 'utmp' slot no. of sender */ 6216256Sralph c = fread((char *)utmp, sizeof(struct utmp), USERS, f); 6316256Sralph fclose(f); 6416256Sralph if (sline) 6516256Sralph strncpy(who, utmp[sline].ut_name, sizeof(utmp[sline].ut_name)); 6616256Sralph sprintf(mesg, 6716256Sralph "\nBroadcast Message from %s@%s (%.*s) at %d:%02d ...\r\n\n" 6816256Sralph , who 6916256Sralph , hostname 7016256Sralph , sizeof(utmp[sline].ut_line) 7116256Sralph , utmp[sline].ut_line 7216256Sralph , localclock -> tm_hour 7316256Sralph , localclock -> tm_min 7416256Sralph ); 7516256Sralph msize = strlen(mesg); 7616256Sralph if (argc >= 2) { 771159Sbill /* take message from unix file instead of standard input */ 7816256Sralph if (freopen(argv[1], "r", stdin) == NULL) { 7916256Sralph perror(argv[1]); 801159Sbill exit(1); 811159Sbill } 821159Sbill } 8316256Sralph while ((i = getchar()) != EOF) { 8416256Sralph if (i == '\n') 8516256Sralph mesg[msize++] = '\r'; 863176Swnj if (msize >= sizeof mesg) { 873176Swnj fprintf(stderr, "Message too long\n"); 883176Swnj exit(1); 893176Swnj } 903176Swnj mesg[msize++] = i; 913176Swnj } 9216256Sralph fclose(stdin); 9316256Sralph for (i=0; i<c; i++) { 941159Sbill p = &utmp[i]; 9516256Sralph if (p->ut_name[0] == 0 || 9616256Sralph strncmp(p->ut_name, IGNOREUSER, sizeof(p->ut_name)) == 0) 971159Sbill continue; 981159Sbill sendmes(p->ut_line); 991159Sbill } 1001159Sbill exit(0); 1011159Sbill } 1021159Sbill 1031159Sbill sendmes(tty) 1041159Sbill char *tty; 1051159Sbill { 10616256Sralph register f, flags; 10716256Sralph static char t[50] = "/dev/"; 10816256Sralph int e, i; 1091159Sbill 11016256Sralph strcpy(t + 5, tty); 11116256Sralph 11216256Sralph if ((f = open(t, O_WRONLY|O_NDELAY)) < 0) { 11316256Sralph if (errno != EWOULDBLOCK) 11416256Sralph perror(t); 11516256Sralph return; 11616256Sralph } 11716256Sralph if ((flags = fcntl(f, F_GETFL, 0)) == -1) { 11816256Sralph perror(t); 11916256Sralph return; 12016256Sralph } 12116256Sralph if (fcntl(f, F_SETFL, flags | FNDELAY) == -1) 12216256Sralph goto oldway; 12316256Sralph i = write(f, mesg, msize); 12416256Sralph e = errno; 12516256Sralph (void) fcntl(f, F_SETFL, flags); 12616256Sralph if (i == msize) { 12716256Sralph (void) close(f); 12816256Sralph return; 12916256Sralph } 13016256Sralph if (e != EWOULDBLOCK) { 13116256Sralph errno = e; 13216256Sralph perror(t); 13316256Sralph (void) close(f); 13416256Sralph return; 13516256Sralph } 13616256Sralph oldway: 1373176Swnj while ((i = fork()) == -1) 1383176Swnj if (wait((int *)0) == -1) { 1393176Swnj fprintf(stderr, "Try again\n"); 1403176Swnj return; 1413176Swnj } 14216256Sralph if (i) { 14316256Sralph (void) close(f); 1441159Sbill return; 1451159Sbill } 1461159Sbill 14716256Sralph (void) write(f, mesg, msize); 1481159Sbill exit(0); 1491159Sbill } 150