14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
24
25
26
27 /*
28 * Copyright 1988-2003 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
30 */
31
32 /*
33 * Copyright 2012 Joyent, Inc. All rights reserved.
34 */
35
36 #include <signal.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <grp.h>
40 #include <sys/types.h>
41 #include <unistd.h>
42 #include <string.h>
43 #include <ctype.h>
44 #include <sys/stat.h>
45 #include <utmpx.h>
46 #include <sys/utsname.h>
47 #include <dirent.h>
48 #include <pwd.h>
49 #include <fcntl.h>
50 #include <time.h>
51 #include <errno.h>
52 #include <locale.h>
53 #include <syslog.h>
54 #include <sys/wait.h>
55 #include <limits.h>
56 #include <libzonecfg.h>
57 #include <zone.h>
58 #include <sys/contract/process.h>
59 #include <libcontract.h>
60 #include <sys/ctfs.h>
61
62 /*
63 * utmpx defines wider fields for user and line. For compatibility of output,
64 * we are limiting these to the old maximums in utmp. Define UTMPX_NAMELEN
65 * to use the full lengths.
66 */
67 #ifndef UTMPX_NAMELEN
68 /* XXX - utmp -fix name length */
69 #define NMAX (_POSIX_LOGIN_NAME_MAX - 1)
70 #define LMAX 12
71 #else /* UTMPX_NAMELEN */
72 #define NMAX (sizeof (((struct utmpx *)0)->ut_user)
73 #define LMAX (sizeof (((struct utmpx *)0)->ut_line)
74 #endif /* UTMPX_NAMELEN */
75
76 static char mesg[3000];
77 static char *infile;
78 static int gflag;
79 static struct group *pgrp;
80 static char *grpname;
81 static char line[MAXNAMLEN+1] = "???";
82 static char systm[MAXNAMLEN+1];
83 static time_t tloc;
84 static struct utsname utsn;
85 static char who[9] = "???";
86 static char time_buf[50];
87 #define DATE_FMT "%a %b %e %H:%M:%S"
88
89 static void sendmes(struct utmpx *, zoneid_t);
90 static void sendmes_tozone(zoneid_t, int);
91 static int chkgrp(char *);
92 static char *copy_str_till(char *, char *, char, int);
93
94 static int init_template(void);
95 int contract_abandon_id(ctid_t);
96
97 int
98 main(int argc, char *argv[])
99 {
100 FILE *f;
101 char *ptr, *start;
102 struct passwd *pwd;
103 char *term_name;
104 int c;
105 int aflag = 0;
209
210 /*
211 * If the request is from the rwall daemon then use the caller's
212 * name and host. We determine this if all of the following is true:
213 * 1) First 5 characters are "From "
214 * 2) Next non-white characters are of the form "name@host:"
215 */
216 if (strcmp(line, "???") == 0) {
217 char rwho[MAXNAMLEN+1];
218 char rsystm[MAXNAMLEN+1];
219 char *cp;
220
221 if (strncmp(mesg, "From ", 5) == 0) {
222 cp = &mesg[5];
223 cp = copy_str_till(rwho, cp, '@', MAXNAMLEN + 1);
224 if (rwho[0] != '\0') {
225 cp = copy_str_till(rsystm, ++cp, ':',
226 MAXNAMLEN + 1);
227 if (rsystm[0] != '\0') {
228 (void) strcpy(systm, rsystm);
229 (void) strncpy(rwho, who, 9);
230 (void) strcpy(line, "rpc.rwalld");
231 }
232 }
233 }
234 }
235 (void) time(&tloc);
236 (void) strftime(time_buf, sizeof (time_buf),
237 DATE_FMT, localtime(&tloc));
238
239 if (zflg != 0) {
240 if ((zoneidlist =
241 malloc(sizeof (zoneid_t))) == NULL ||
242 (*zoneidlist = getzoneidbyname(zonename)) == -1)
243 return (errno);
244 nzids = 1;
245 } else if (Zflg != 0) {
246 if (zone_list(NULL, &nzids) != 0)
247 return (errno);
248 again:
249 nzids *= 2;
411 #ifdef DEBUG
412 (void) close(fd);
413 f = fopen("wall.debug", "a");
414 #else
415 f = fdopen(fd, "w");
416 #endif
417 if (f == NULL) {
418 (void) fprintf(stderr, "Cannot send to %-.*s on %s\n",
419 NMAX, &p->ut_user[0], s);
420 perror("open");
421 (void) fflush(stderr);
422 _exit(1);
423 }
424 (void) fprintf(f,
425 "\07\07\07Broadcast Message from %s (%s) on %s %19.19s",
426 who, line, systm, time_buf);
427 if (gflag)
428 (void) fprintf(f, " to group %s", grpname);
429 (void) fprintf(f, "...\n");
430 #ifdef DEBUG
431 (void) fprintf(f, "DEBUG: To %.8s on %s\n", p->ut_user, s);
432 #endif
433 i = strlen(mesg);
434 for (bp = mesg; --i >= 0; bp++) {
435 ibp = (unsigned int)((unsigned char) *bp);
436 if (*bp == '\n')
437 (void) putc('\r', f);
438 if (isprint(ibp) || *bp == '\r' || *bp == '\013' ||
439 *bp == ' ' || *bp == '\t' || *bp == '\n' || *bp == '\007') {
440 (void) putc(*bp, f);
441 } else {
442 if (!isascii(*bp)) {
443 (void) fputs("M-", f);
444 *bp = toascii(*bp);
445 }
446 if (iscntrl(*bp)) {
447 (void) putc('^', f);
448 (void) putc(*bp + 0100, f);
449 }
450 else
451 (void) putc(*bp, f);
453
454 if (*bp == '\n')
455 (void) fflush(f);
456
457 if (ferror(f) || feof(f)) {
458 (void) printf("\n\007Write failed\n");
459 (void) fflush(stdout);
460 _exit(1);
461 }
462 }
463 (void) fclose(f);
464 (void) close(fd);
465 _exit(0);
466 }
467
468
469 static int
470 chkgrp(char *name)
471 {
472 int i;
473 char *p;
474
475 for (i = 0; pgrp->gr_mem[i] && pgrp->gr_mem[i][0]; i++) {
476 for (p = name; *p && *p != ' '; p++)
477 ;
478 *p = 0;
479 if (strncmp(name, pgrp->gr_mem[i], 8) == 0)
480 return (1);
481 }
482
483 return (0);
484 }
485
486 static int
487 init_template(void) {
488 int fd = 0;
489 int err = 0;
490
491 fd = open64(CTFS_ROOT "/process/template", O_RDWR);
492 if (fd == -1)
493 return (-1);
494
495 err |= ct_tmpl_set_critical(fd, 0);
496 err |= ct_tmpl_set_informative(fd, 0);
497 err |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR);
498 err |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT);
499 if (err || ct_tmpl_activate(fd)) {
|
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
24
25
26
27 /*
28 * Copyright 1988-2003 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
30 */
31
32 /*
33 * Copyright 2012 Joyent, Inc. All rights reserved.
34 *
35 * Copyright (c) 2013 Gary Mills
36 */
37
38 #include <signal.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <grp.h>
42 #include <sys/types.h>
43 #include <unistd.h>
44 #include <string.h>
45 #include <ctype.h>
46 #include <sys/stat.h>
47 #include <utmpx.h>
48 #include <sys/utsname.h>
49 #include <dirent.h>
50 #include <pwd.h>
51 #include <fcntl.h>
52 #include <time.h>
53 #include <errno.h>
54 #include <locale.h>
55 #include <syslog.h>
56 #include <sys/wait.h>
57 #include <limits.h>
58 #include <libzonecfg.h>
59 #include <zone.h>
60 #include <sys/contract/process.h>
61 #include <libcontract.h>
62 #include <sys/ctfs.h>
63
64 /*
65 * Use the full lengths from utmpx for user and line.
66 */
67 #define NMAX (sizeof (((struct utmpx *)0)->ut_user))
68 #define LMAX (sizeof (((struct utmpx *)0)->ut_line))
69
70 static char mesg[3000];
71 static char *infile;
72 static int gflag;
73 static struct group *pgrp;
74 static char *grpname;
75 static char line[MAXNAMLEN+1] = "???";
76 static char systm[MAXNAMLEN+1];
77 static time_t tloc;
78 static struct utsname utsn;
79 static char who[NMAX+1] = "???";
80 static char time_buf[50];
81 #define DATE_FMT "%a %b %e %H:%M:%S"
82
83 static void sendmes(struct utmpx *, zoneid_t);
84 static void sendmes_tozone(zoneid_t, int);
85 static int chkgrp(char *);
86 static char *copy_str_till(char *, char *, char, int);
87
88 static int init_template(void);
89 int contract_abandon_id(ctid_t);
90
91 int
92 main(int argc, char *argv[])
93 {
94 FILE *f;
95 char *ptr, *start;
96 struct passwd *pwd;
97 char *term_name;
98 int c;
99 int aflag = 0;
203
204 /*
205 * If the request is from the rwall daemon then use the caller's
206 * name and host. We determine this if all of the following is true:
207 * 1) First 5 characters are "From "
208 * 2) Next non-white characters are of the form "name@host:"
209 */
210 if (strcmp(line, "???") == 0) {
211 char rwho[MAXNAMLEN+1];
212 char rsystm[MAXNAMLEN+1];
213 char *cp;
214
215 if (strncmp(mesg, "From ", 5) == 0) {
216 cp = &mesg[5];
217 cp = copy_str_till(rwho, cp, '@', MAXNAMLEN + 1);
218 if (rwho[0] != '\0') {
219 cp = copy_str_till(rsystm, ++cp, ':',
220 MAXNAMLEN + 1);
221 if (rsystm[0] != '\0') {
222 (void) strcpy(systm, rsystm);
223 (void) strncpy(rwho, who,
224 sizeof (who));
225 (void) strcpy(line, "rpc.rwalld");
226 }
227 }
228 }
229 }
230 (void) time(&tloc);
231 (void) strftime(time_buf, sizeof (time_buf),
232 DATE_FMT, localtime(&tloc));
233
234 if (zflg != 0) {
235 if ((zoneidlist =
236 malloc(sizeof (zoneid_t))) == NULL ||
237 (*zoneidlist = getzoneidbyname(zonename)) == -1)
238 return (errno);
239 nzids = 1;
240 } else if (Zflg != 0) {
241 if (zone_list(NULL, &nzids) != 0)
242 return (errno);
243 again:
244 nzids *= 2;
406 #ifdef DEBUG
407 (void) close(fd);
408 f = fopen("wall.debug", "a");
409 #else
410 f = fdopen(fd, "w");
411 #endif
412 if (f == NULL) {
413 (void) fprintf(stderr, "Cannot send to %-.*s on %s\n",
414 NMAX, &p->ut_user[0], s);
415 perror("open");
416 (void) fflush(stderr);
417 _exit(1);
418 }
419 (void) fprintf(f,
420 "\07\07\07Broadcast Message from %s (%s) on %s %19.19s",
421 who, line, systm, time_buf);
422 if (gflag)
423 (void) fprintf(f, " to group %s", grpname);
424 (void) fprintf(f, "...\n");
425 #ifdef DEBUG
426 (void) fprintf(f, "DEBUG: To %.*s on %s\n", NMAX, p->ut_user, s);
427 #endif
428 i = strlen(mesg);
429 for (bp = mesg; --i >= 0; bp++) {
430 ibp = (unsigned int)((unsigned char) *bp);
431 if (*bp == '\n')
432 (void) putc('\r', f);
433 if (isprint(ibp) || *bp == '\r' || *bp == '\013' ||
434 *bp == ' ' || *bp == '\t' || *bp == '\n' || *bp == '\007') {
435 (void) putc(*bp, f);
436 } else {
437 if (!isascii(*bp)) {
438 (void) fputs("M-", f);
439 *bp = toascii(*bp);
440 }
441 if (iscntrl(*bp)) {
442 (void) putc('^', f);
443 (void) putc(*bp + 0100, f);
444 }
445 else
446 (void) putc(*bp, f);
448
449 if (*bp == '\n')
450 (void) fflush(f);
451
452 if (ferror(f) || feof(f)) {
453 (void) printf("\n\007Write failed\n");
454 (void) fflush(stdout);
455 _exit(1);
456 }
457 }
458 (void) fclose(f);
459 (void) close(fd);
460 _exit(0);
461 }
462
463
464 static int
465 chkgrp(char *name)
466 {
467 int i;
468 char user[NMAX + 1];
469
470 (void) strlcpy(user, name, sizeof (user));
471 for (i = 0; pgrp->gr_mem[i] && pgrp->gr_mem[i][0]; i++) {
472 if (strcmp(user, pgrp->gr_mem[i]) == 0)
473 return (1);
474 }
475
476 return (0);
477 }
478
479 static int
480 init_template(void) {
481 int fd = 0;
482 int err = 0;
483
484 fd = open64(CTFS_ROOT "/process/template", O_RDWR);
485 if (fd == -1)
486 return (-1);
487
488 err |= ct_tmpl_set_critical(fd, 0);
489 err |= ct_tmpl_set_informative(fd, 0);
490 err |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR);
491 err |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT);
492 if (err || ct_tmpl_activate(fd)) {
|