|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 4441 (0x1159) Types: TextFile Notes: UNIX file Names: »msg.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─⟦this⟧ »cmd/msg.c«
/* * Rec'd from Lauren Weinstein, 7-16-84. * Send a one-line message to * another user or a number of users. * This is setuid in order to * use execute permission on the * terminal to allow/disallow msgs. * * The super user may use the "-s" flag to suppress the user id * prefix on messages, which also suppresses any error messages, * and forces an exit code of 0 unless an error condition occurs. * This is mainly for use by other programs (e.g. "rmail"). */ #include <stdio.h> #include <utmp.h> #include <sys/stat.h> #include <signal.h> #define MAXMSG 256 /* Longest message allowable */ #define NUSER 100 /* Maximum number of users to send to */ #define ALARMT 10 /* Message send timeout in seconds */ char msgbuf[MAXMSG]; struct users { char *u_name; int u_flag; } users[NUSER]; int wtimeout; /* non-zero for timeout on tty write */ int suppress; /* non-zero to suppress id headers, etc. */ char usemsg[] = "\ Usage: msg user\n\ msg user ... message\n\ "; char *getlogin(); char *ttyname(); int catch(); main(argc, argv) char *argv[]; { char *fromuname; register int i; register struct users *ulp = users; /* are we the superuser and was the "-s" flag given? */ if (!geteuid() && argc > 1 && !strcmp(argv[1], "-s")) { suppress++; /* set "suppress user id" prefix flag */ close(2); /* close error output */ open("/dev/null", 1); /* reopen fd 2 on /dev/null */ argc--; /* adjust args */ argv++; } if (argc < 2) usage(); if ((fromuname = getlogin()) == NULL) fromuname = "daemon"; if (argc==2 || strcmp(argv[argc-1], "-")==0) fgets(msgbuf, MAXMSG, stdin); else { strcpy(msgbuf, argv[argc-1]); strcat(msgbuf, "\r\n"); } if (argc == 2) (ulp++)->u_name = argv[1]; else for (i=1; i<argc-1; i++) (ulp++)->u_name = argv[i]; exit(msg(suppress ? 0 : fromuname)); } /* * Find out terminal names for the * given user-list and complain about * those not logged in. */ msg(f) char *f; { register struct users *up; register FILE *fp; register int st = 0; static struct utmp ut; if ((fp = fopen("/etc/utmp", "r")) == NULL) { fprintf(stderr, "msg: /etc/utmp not accessible\n"); exit(2); } while (fread(&ut, sizeof ut, 1, fp) == 1) { if (ut.ut_name[0] == '\0') continue; for (up = users; up->u_name != NULL; up++) if (strncmp(ut.ut_name, up->u_name, DIRSIZ) == 0) break; if (up->u_name == NULL) continue; send(f, &ut); up->u_flag = 1; } for (up = users; up->u_name != NULL; up++) if (up->u_flag == 0) { fprintf(stderr, "%s: not logged in\n", up->u_name); if (!suppress) st = 1; /* indicate user not logged in */ } return(st); } /* * Send the message. Return non-zero if * it does not work or is not allowed. */ send(f, up) char *f; register struct utmp *up; { FILE *tf; register struct stat sb; char tty[40], c; register char abortf = 0; sprintf(tty, "/dev/%.*s", sizeof up->ut_line, up->ut_line); if ((tf = fopen(tty, "w")) == NULL) { fprintf(stderr, "msg: cannot open %.*s\n", sizeof up->ut_line, up->ut_line); return; } if (fstat(fileno(tf), &sb) < 0) { fprintf(stderr, "msg: can't send to %.*s\n", sizeof up->ut_name, up->ut_name); fclose(tf); return; } if ((sb.st_mode&S_IEXEC) == 0) { if (!getuid()) /* is our real uid su? */ { fprintf(stderr, "User \"%.*s\" is denying messages. Override? ", sizeof up->ut_name, up->ut_name); if ((c = getchar()) != 'y') abortf++; /* flag abort */ while (c != EOF && c != '\n') /* flush remaining input */ c = getchar(); if (abortf) /* don't want override? */ { fclose(tf); return; } } else { fprintf(stderr, "write: no permission to write to %.*s\n", sizeof up->ut_name, up->ut_name); fclose(tf); return; } } signal(SIGALRM, &catch); /* catch alarms */ alarm(ALARMT); /* set timeout */ if (f == NULL) fprintf(tf, "\r\n\007%s", msgbuf); /* send the msg */ else fprintf(tf, "\r\n\007%s: %s", f, msgbuf); alarm(0); /* turn off timeout */ if (wtimeout) /* timeout on write? */ { wtimeout = 0; /* clear timeout flag */ fprintf(stderr, "msg: can't send to %.*s\n", sizeof up->ut_name, up->ut_name); } fclose(tf); } /* for alarm timeout */ catch() { wtimeout++; /* set write timeout flag */ } usage() { fprintf(stderr, usemsg); exit(2); }