int main(int argc, char **argv) { extern int optind; int ch; struct iovec iov; struct utmp *utmpptr; char *p; char line[sizeof(utmpptr->ut_line) + 1]; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while ((ch = getopt(argc, argv, "n")) != -1) { switch (ch) { case 'n': if (geteuid() == 0) nobanner = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc > 1) usage(); makemsg(*argv); setutent(); iov.iov_base = mbuf; iov.iov_len = mbufsize; while((utmpptr = getutent())) { if (!utmpptr->ut_name[0] || !strncmp(utmpptr->ut_name, IGNOREUSER, sizeof(utmpptr->ut_name))) continue; #ifdef USER_PROCESS if (utmpptr->ut_type != USER_PROCESS) continue; #endif /* Joey Hess reports that use-sessreg in /etc/X11/wdm/ produces ut_line entries like :0, and a write to /dev/:0 fails. */ if (utmpptr->ut_line[0] == ':') continue; xstrncpy(line, utmpptr->ut_line, sizeof(utmpptr->ut_line)); if ((p = ttymsg(&iov, 1, line, 60*5)) != NULL) warnx("%s", p); } endutent(); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { int ch; struct iovec iov; struct utmp *utmpptr; char *p; char line[sizeof(utmpptr->ut_line) + 1]; int print_banner = TRUE; char *mbuf; size_t mbufsize; unsigned timeout = WRITE_TIME_OUT; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); static const struct option longopts[] = { { "nobanner", no_argument, 0, 'n' }, { "timeout", required_argument, 0, 't' }, { "version", no_argument, 0, 'V' }, { "help", no_argument, 0, 'h' }, { NULL, 0, 0, 0 } }; while ((ch = getopt_long(argc, argv, "nt:Vh", longopts, NULL)) != -1) { switch (ch) { case 'n': if (geteuid() == 0) print_banner = FALSE; else warnx(_("--nobanner is available only for root")); break; case 't': timeout = strtou32_or_err(optarg, _("invalid timeout argument")); if (timeout < 1) errx(EXIT_FAILURE, _("invalid timeout argument: %s"), optarg); break; case 'V': printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING); exit(EXIT_SUCCESS); case 'h': usage(stdout); default: usage(stderr); } } argc -= optind; argv += optind; if (argc > 1) usage(stderr); mbuf = makemsg(*argv, &mbufsize, print_banner); iov.iov_base = mbuf; iov.iov_len = mbufsize; while((utmpptr = getutent())) { if (!utmpptr->ut_name[0] || !strncmp(utmpptr->ut_name, IGNOREUSER, sizeof(utmpptr->ut_name))) continue; #ifdef USER_PROCESS if (utmpptr->ut_type != USER_PROCESS) continue; #endif /* Joey Hess reports that use-sessreg in /etc/X11/wdm/ produces ut_line entries like :0, and a write to /dev/:0 fails. */ if (utmpptr->ut_line[0] == ':') continue; xstrncpy(line, utmpptr->ut_line, sizeof(utmpptr->ut_line)); if ((p = ttymsg(&iov, 1, line, timeout)) != NULL) warnx("%s", p); } endutent(); free(mbuf); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { int ch; struct iovec iov; struct utmpx *utmpptr; char *p; char line[sizeof(utmpptr->ut_line) + 1]; int print_banner = TRUE; struct group_workspace *group_buf = NULL; char *mbuf, *fname = NULL; size_t mbufsize; unsigned timeout = WRITE_TIME_OUT; char **mvec = NULL; int mvecsz = 0; static const struct option longopts[] = { { "nobanner", no_argument, NULL, 'n' }, { "timeout", required_argument, NULL, 't' }, { "group", required_argument, NULL, 'g' }, { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } }; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); while ((ch = getopt_long(argc, argv, "nt:g:Vh", longopts, NULL)) != -1) { switch (ch) { case 'n': if (geteuid() == 0) print_banner = FALSE; else warnx(_("--nobanner is available only for root")); break; case 't': timeout = strtou32_or_err(optarg, _("invalid timeout argument")); if (timeout < 1) errx(EXIT_FAILURE, _("invalid timeout argument: %s"), optarg); break; case 'g': group_buf = init_group_workspace(optarg); break; case 'V': printf(UTIL_LINUX_VERSION); exit(EXIT_SUCCESS); case 'h': usage(); default: errtryhelp(EXIT_FAILURE); } } argc -= optind; argv += optind; if (argc == 1 && access(argv[0], F_OK) == 0) fname = argv[0]; else if (argc >= 1) { mvec = argv; mvecsz = argc; } mbuf = makemsg(fname, mvec, mvecsz, &mbufsize, print_banner); iov.iov_base = mbuf; iov.iov_len = mbufsize; while((utmpptr = getutxent())) { if (!utmpptr->ut_user[0]) continue; #ifdef USER_PROCESS if (utmpptr->ut_type != USER_PROCESS) continue; #endif /* Joey Hess reports that use-sessreg in /etc/X11/wdm/ produces ut_line entries like :0, and a write to /dev/:0 fails. */ if (utmpptr->ut_line[0] == ':') continue; if (group_buf && !is_gr_member(utmpptr->ut_user, group_buf)) continue; mem2strcpy(line, utmpptr->ut_line, sizeof(utmpptr->ut_line), sizeof(line)); if ((p = ttymsg(&iov, 1, line, timeout)) != NULL) warnx("%s", p); } endutxent(); free(mbuf); free_group_workspace(group_buf); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct iovec iov; struct utmpentry *ep; int ch; int ingroup; struct wallgroup *g; struct group *grp; char **np; const char *p; struct passwd *pw; (void)setlocale(LC_CTYPE, ""); while ((ch = getopt(argc, argv, "g:n")) != -1) switch (ch) { case 'n': /* undoc option for shutdown: suppress banner */ if (geteuid() == 0) nobanner = 1; break; case 'g': g = (struct wallgroup *)malloc(sizeof *g); g->next = grouplist; g->name = optarg; g->gid = -1; grouplist = g; break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc > 1) usage(); for (g = grouplist; g; g = g->next) { grp = getgrnam(g->name); if (grp != NULL) g->gid = grp->gr_gid; else warnx("%s: no such group", g->name); } makemsg(*argv); iov.iov_base = mbuf; iov.iov_len = mbufsize; getutentries(NULL, &ep); /* NOSTRICT */ for (; ep; ep = ep->next) { if (grouplist) { ingroup = 0; pw = getpwnam(ep->name); if (!pw) continue; for (g = grouplist; g && ingroup == 0; g = g->next) { if (g->gid == (gid_t)-1) continue; if (g->gid == pw->pw_gid) ingroup = 1; else if ((grp = getgrgid(g->gid)) != NULL) { for (np = grp->gr_mem; *np; np++) { if (strcmp(*np, ep->name) == 0) { ingroup = 1; break; } } } } if (ingroup == 0) continue; } /* skip [xgk]dm/xserver entries (":0", ":1", etc.) */ if (ep->line[0] == ':' && isdigit((unsigned char)ep->line[1])) continue; if ((p = ttymsg(&iov, 1, ep->line, 60*5)) != NULL) warnx("%s", p); } exit(0); }
int main(int argc, char *argv[]) { struct iovec iov; struct utmpx *utmp; int ch; int ingroup; struct wallgroup *g; struct group *grp; char **np; const char *p; struct passwd *pw; (void)setlocale(LC_CTYPE, ""); while ((ch = getopt(argc, argv, "g:n")) != -1) switch (ch) { case 'n': /* undoc option for shutdown: suppress banner */ if (geteuid() == 0) nobanner = 1; break; case 'g': g = (struct wallgroup *)malloc(sizeof *g); g->next = grouplist; g->name = optarg; g->gid = -1; grouplist = g; break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc > 1) usage(); for (g = grouplist; g; g = g->next) { grp = getgrnam(g->name); if (grp != NULL) g->gid = grp->gr_gid; else warnx("%s: no such group", g->name); } makemsg(*argv); iov.iov_base = mbuf; iov.iov_len = mbufsize; /* NOSTRICT */ while ((utmp = getutxent()) != NULL) { if (utmp->ut_type != USER_PROCESS) continue; if (ttystat(utmp->ut_line) != 0) continue; if (grouplist) { ingroup = 0; pw = getpwnam(utmp->ut_user); if (!pw) continue; for (g = grouplist; g && ingroup == 0; g = g->next) { if (g->gid == (gid_t)-1) continue; if (g->gid == pw->pw_gid) ingroup = 1; else if ((grp = getgrgid(g->gid)) != NULL) { for (np = grp->gr_mem; *np; np++) { if (strcmp(*np, utmp->ut_user) == 0) { ingroup = 1; break; } } } } if (ingroup == 0) continue; } if ((p = ttymsg(&iov, 1, utmp->ut_line, 60*5)) != NULL) warnx("%s", p); } exit(0); }
/* * Build a block of characters containing the message. * It is sent blank filled and in a single block to * try to keep the message in one piece if the recipient * in vi at the time */ int print_mesg(const char *tty, CTL_MSG *request, const char *remote_machine) { struct timeval now; time_t clock_sec; struct tm *localclock; struct iovec iovec; char line_buf[N_LINES][N_CHARS]; int sizes[N_LINES]; char big_buf[N_LINES*N_CHARS]; char *bptr, *lptr, *vis_user; int i, j, max_size; i = 0; max_size = 0; gettimeofday(&now, NULL); clock_sec = now.tv_sec; localclock = localtime(&clock_sec); (void)snprintf(line_buf[i], N_CHARS, " "); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; (void)snprintf(line_buf[i], N_CHARS, "Message from Talk_Daemon@%s at %d:%02d on %d/%.2d/%.2d ...", hostname, localclock->tm_hour , localclock->tm_min, localclock->tm_year + 1900, localclock->tm_mon + 1, localclock->tm_mday); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; vis_user = malloc(strlen(request->l_name) * 4 + 1); strvis(vis_user, request->l_name, VIS_CSTYLE); (void)snprintf(line_buf[i], N_CHARS, "talk: connection requested by %s@%s", vis_user, remote_machine); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; (void)snprintf(line_buf[i], N_CHARS, "talk: respond with: talk %s@%s", vis_user, remote_machine); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; (void)snprintf(line_buf[i], N_CHARS, " "); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); bptr = big_buf; *bptr++ = '\007'; /* send something to wake them up */ *bptr++ = '\r'; /* add a \r in case of raw mode */ *bptr++ = '\n'; for (i = 0; i < N_LINES; i++) { /* copy the line into the big buffer */ lptr = line_buf[i]; while (*lptr != '\0') *(bptr++) = *(lptr++); /* pad out the rest of the lines with blanks */ for (j = sizes[i]; j < max_size + 2; j++) *(bptr++) = ' '; *(bptr++) = '\r'; /* add a \r in case of raw mode */ *(bptr++) = '\n'; } *bptr = '\0'; iovec.iov_base = big_buf; iovec.iov_len = bptr - big_buf; /* * we choose a timeout of RING_WAIT-5 seconds so that we don't * stack up processes trying to write messages to a tty * that is permanently blocked. */ if (ttymsg(&iovec, 1, tty, RING_WAIT - 5) != NULL) return (FAILED); return (SUCCESS); }
int main(int argc, char *argv[]) { struct iovec iov; #ifdef __APPLE__ // rdar://problem/4433603 struct utmpx *u; #else struct utmp utmp; #endif int ch; int ingroup; #ifndef __APPLE__ FILE *fp; #endif struct wallgroup *g; struct group *grp; char **np; const char *p; struct passwd *pw; #ifdef __APPLE__ char line[sizeof(u->ut_line) + 1]; char username[sizeof(u->ut_user) + 1]; #else char line[sizeof(utmp.ut_line) + 1]; char username[sizeof(utmp.ut_name) + 1]; #endif (void)setlocale(LC_CTYPE, ""); while ((ch = getopt(argc, argv, "g:n")) != -1) switch (ch) { case 'n': /* undoc option for shutdown: suppress banner */ if (geteuid() == 0) nobanner = 1; break; case 'g': g = (struct wallgroup *)malloc(sizeof *g); g->next = grouplist; g->name = optarg; g->gid = -1; grouplist = g; break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc > 1) usage(); for (g = grouplist; g; g = g->next) { grp = getgrnam(g->name); if (grp != NULL) g->gid = grp->gr_gid; else warnx("%s: no such group", g->name); } makemsg(*argv); #ifdef __APPLE__ setutxent(); #else if (!(fp = fopen(_PATH_UTMP, "r"))) err(1, "cannot read %s", _PATH_UTMP); #endif iov.iov_base = mbuf; iov.iov_len = mbufsize; /* NOSTRICT */ #ifdef __APPLE__ while ((u = getutxent()) != NULL) { if (!u->ut_user[0] || u->ut_type != USER_PROCESS) continue; #else while (fread((char *)&utmp, sizeof(utmp), 1, fp) == 1) { if (!utmp.ut_name[0]) continue; if (ttystat(utmp.ut_line, UT_LINESIZE) != 0) continue; #endif if (grouplist) { ingroup = 0; #ifdef __APPLE__ strlcpy(username, u->ut_user, sizeof(username)); #else strlcpy(username, utmp.ut_name, sizeof(utmp.ut_name)); #endif pw = getpwnam(username); if (!pw) continue; for (g = grouplist; g && ingroup == 0; g = g->next) { if (g->gid == (gid_t)-1) continue; if (g->gid == pw->pw_gid) ingroup = 1; else if ((grp = getgrgid(g->gid)) != NULL) { for (np = grp->gr_mem; *np; np++) { if (strcmp(*np, username) == 0) { ingroup = 1; break; } } } } if (ingroup == 0) continue; } #ifdef __APPLE__ strlcpy(line, u->ut_line, sizeof(line)); #else strncpy(line, utmp.ut_line, sizeof(utmp.ut_line)); line[sizeof(utmp.ut_line)] = '\0'; #endif if ((p = ttymsg(&iov, 1, line, 60*5)) != NULL) warnx("%s", p); } exit(0); } static void usage() { (void)fprintf(stderr, "usage: wall [-g group] [file]\n"); exit(1); }