17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 237c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* 287c478bd9Sstevel@tonic-gate * Copyright 1988-2003 Sun Microsystems, Inc. All rights reserved. 297c478bd9Sstevel@tonic-gate * Use is subject to license terms. 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate 32de6baaf5SJohn Sonnenschein /* 33de6baaf5SJohn Sonnenschein * Copyright 2012 Joyent, Inc. All rights reserved. 340a1278f2SGary Mills * 350a1278f2SGary Mills * Copyright (c) 2013 Gary Mills 36de6baaf5SJohn Sonnenschein */ 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #include <signal.h> 397c478bd9Sstevel@tonic-gate #include <stdio.h> 40de6baaf5SJohn Sonnenschein #include <stdlib.h> 417c478bd9Sstevel@tonic-gate #include <grp.h> 427c478bd9Sstevel@tonic-gate #include <sys/types.h> 437c478bd9Sstevel@tonic-gate #include <unistd.h> 447c478bd9Sstevel@tonic-gate #include <string.h> 457c478bd9Sstevel@tonic-gate #include <ctype.h> 467c478bd9Sstevel@tonic-gate #include <sys/stat.h> 477c478bd9Sstevel@tonic-gate #include <utmpx.h> 487c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 497c478bd9Sstevel@tonic-gate #include <dirent.h> 507c478bd9Sstevel@tonic-gate #include <pwd.h> 517c478bd9Sstevel@tonic-gate #include <fcntl.h> 527c478bd9Sstevel@tonic-gate #include <time.h> 537c478bd9Sstevel@tonic-gate #include <errno.h> 547c478bd9Sstevel@tonic-gate #include <locale.h> 557c478bd9Sstevel@tonic-gate #include <syslog.h> 567c478bd9Sstevel@tonic-gate #include <sys/wait.h> 577c478bd9Sstevel@tonic-gate #include <limits.h> 58de6baaf5SJohn Sonnenschein #include <libzonecfg.h> 59de6baaf5SJohn Sonnenschein #include <zone.h> 60de6baaf5SJohn Sonnenschein #include <sys/contract/process.h> 61de6baaf5SJohn Sonnenschein #include <libcontract.h> 62de6baaf5SJohn Sonnenschein #include <sys/ctfs.h> 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate /* 650a1278f2SGary Mills * Use the full lengths from utmpx for user and line. 667c478bd9Sstevel@tonic-gate */ 670a1278f2SGary Mills #define NMAX (sizeof (((struct utmpx *)0)->ut_user)) 680a1278f2SGary Mills #define LMAX (sizeof (((struct utmpx *)0)->ut_line)) 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate static char mesg[3000]; 717c478bd9Sstevel@tonic-gate static char *infile; 727c478bd9Sstevel@tonic-gate static int gflag; 737c478bd9Sstevel@tonic-gate static struct group *pgrp; 747c478bd9Sstevel@tonic-gate static char *grpname; 757c478bd9Sstevel@tonic-gate static char line[MAXNAMLEN+1] = "???"; 767c478bd9Sstevel@tonic-gate static char systm[MAXNAMLEN+1]; 777c478bd9Sstevel@tonic-gate static time_t tloc; 787c478bd9Sstevel@tonic-gate static struct utsname utsn; 790a1278f2SGary Mills static char who[NMAX+1] = "???"; 807c478bd9Sstevel@tonic-gate static char time_buf[50]; 817c478bd9Sstevel@tonic-gate #define DATE_FMT "%a %b %e %H:%M:%S" 827c478bd9Sstevel@tonic-gate 83de6baaf5SJohn Sonnenschein static void sendmes(struct utmpx *, zoneid_t); 84de6baaf5SJohn Sonnenschein static void sendmes_tozone(zoneid_t, int); 857c478bd9Sstevel@tonic-gate static int chkgrp(char *); 867c478bd9Sstevel@tonic-gate static char *copy_str_till(char *, char *, char, int); 877c478bd9Sstevel@tonic-gate 88de6baaf5SJohn Sonnenschein static int init_template(void); 89de6baaf5SJohn Sonnenschein int contract_abandon_id(ctid_t); 90de6baaf5SJohn Sonnenschein 917c478bd9Sstevel@tonic-gate int 927c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 937c478bd9Sstevel@tonic-gate { 947c478bd9Sstevel@tonic-gate FILE *f; 957c478bd9Sstevel@tonic-gate char *ptr, *start; 967c478bd9Sstevel@tonic-gate struct passwd *pwd; 977c478bd9Sstevel@tonic-gate char *term_name; 987c478bd9Sstevel@tonic-gate int c; 997c478bd9Sstevel@tonic-gate int aflag = 0; 1007c478bd9Sstevel@tonic-gate int errflg = 0; 101de6baaf5SJohn Sonnenschein int zflg = 0; 102de6baaf5SJohn Sonnenschein int Zflg = 0; 103de6baaf5SJohn Sonnenschein 104de6baaf5SJohn Sonnenschein char *zonename = NULL; 105de6baaf5SJohn Sonnenschein zoneid_t *zoneidlist = NULL; 106de6baaf5SJohn Sonnenschein uint_t nzids_saved, nzids = 0; 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1097c478bd9Sstevel@tonic-gate 110de6baaf5SJohn Sonnenschein while ((c = getopt(argc, argv, "g:az:Z")) != EOF) 1117c478bd9Sstevel@tonic-gate switch (c) { 1127c478bd9Sstevel@tonic-gate case 'a': 1137c478bd9Sstevel@tonic-gate aflag++; 1147c478bd9Sstevel@tonic-gate break; 1157c478bd9Sstevel@tonic-gate case 'g': 1167c478bd9Sstevel@tonic-gate if (gflag) { 1177c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1187c478bd9Sstevel@tonic-gate "Only one group allowed\n"); 119de6baaf5SJohn Sonnenschein return (1); 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate if ((pgrp = getgrnam(grpname = optarg)) == NULL) { 1227c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Unknown group %s\n", 1237c478bd9Sstevel@tonic-gate grpname); 124de6baaf5SJohn Sonnenschein return (1); 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate gflag++; 1277c478bd9Sstevel@tonic-gate break; 128de6baaf5SJohn Sonnenschein case 'z': 129de6baaf5SJohn Sonnenschein zflg++; 130de6baaf5SJohn Sonnenschein zonename = optarg; 131de6baaf5SJohn Sonnenschein if (getzoneidbyname(zonename) == -1) { 132de6baaf5SJohn Sonnenschein (void) fprintf(stderr, "Specified zone %s " 133de6baaf5SJohn Sonnenschein "is invalid", zonename); 134de6baaf5SJohn Sonnenschein return (1); 135de6baaf5SJohn Sonnenschein } 136de6baaf5SJohn Sonnenschein break; 137de6baaf5SJohn Sonnenschein case 'Z': 138de6baaf5SJohn Sonnenschein Zflg++; 139de6baaf5SJohn Sonnenschein break; 1407c478bd9Sstevel@tonic-gate case '?': 1417c478bd9Sstevel@tonic-gate errflg++; 1427c478bd9Sstevel@tonic-gate break; 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate if (errflg) { 1467c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 147de6baaf5SJohn Sonnenschein "Usage: wall [-a] [-g group] [-z zone] [-Z] [files...]\n"); 148de6baaf5SJohn Sonnenschein return (1); 149de6baaf5SJohn Sonnenschein } 150de6baaf5SJohn Sonnenschein 151de6baaf5SJohn Sonnenschein if (zflg && Zflg) { 152de6baaf5SJohn Sonnenschein (void) fprintf(stderr, "Cannot use -z with -Z\n"); 1537c478bd9Sstevel@tonic-gate return (1); 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate if (optind < argc) 1577c478bd9Sstevel@tonic-gate infile = argv[optind]; 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate if (uname(&utsn) == -1) { 1607c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "wall: uname() failed, %s\n", 1617c478bd9Sstevel@tonic-gate strerror(errno)); 162de6baaf5SJohn Sonnenschein return (2); 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate (void) strcpy(systm, utsn.nodename); 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate /* 1677c478bd9Sstevel@tonic-gate * Get the name of the terminal wall is running from. 1687c478bd9Sstevel@tonic-gate */ 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate if ((term_name = ttyname(fileno(stderr))) != NULL) { 1717c478bd9Sstevel@tonic-gate /* 1727c478bd9Sstevel@tonic-gate * skip the leading "/dev/" in term_name 1737c478bd9Sstevel@tonic-gate */ 1747c478bd9Sstevel@tonic-gate (void) strncpy(line, &term_name[5], sizeof (line) - 1); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate if (who[0] == '?') { 1787c478bd9Sstevel@tonic-gate if (pwd = getpwuid(getuid())) 1797c478bd9Sstevel@tonic-gate (void) strncpy(&who[0], pwd->pw_name, sizeof (who)); 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate f = stdin; 1837c478bd9Sstevel@tonic-gate if (infile) { 1847c478bd9Sstevel@tonic-gate f = fopen(infile, "r"); 1857c478bd9Sstevel@tonic-gate if (f == NULL) { 1867c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Cannot open %s\n", infile); 187de6baaf5SJohn Sonnenschein return (1); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate start = &mesg[0]; 1927c478bd9Sstevel@tonic-gate ptr = start; 1937c478bd9Sstevel@tonic-gate while ((ptr - start) < 3000) { 1947c478bd9Sstevel@tonic-gate size_t n; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate if (fgets(ptr, &mesg[sizeof (mesg)] - ptr, f) == NULL) 1977c478bd9Sstevel@tonic-gate break; 1987c478bd9Sstevel@tonic-gate if ((n = strlen(ptr)) == 0) 1997c478bd9Sstevel@tonic-gate break; 2007c478bd9Sstevel@tonic-gate ptr += n; 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate (void) fclose(f); 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate /* 2057c478bd9Sstevel@tonic-gate * If the request is from the rwall daemon then use the caller's 2067c478bd9Sstevel@tonic-gate * name and host. We determine this if all of the following is true: 2077c478bd9Sstevel@tonic-gate * 1) First 5 characters are "From " 2087c478bd9Sstevel@tonic-gate * 2) Next non-white characters are of the form "name@host:" 2097c478bd9Sstevel@tonic-gate */ 2107c478bd9Sstevel@tonic-gate if (strcmp(line, "???") == 0) { 2117c478bd9Sstevel@tonic-gate char rwho[MAXNAMLEN+1]; 2127c478bd9Sstevel@tonic-gate char rsystm[MAXNAMLEN+1]; 2137c478bd9Sstevel@tonic-gate char *cp; 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate if (strncmp(mesg, "From ", 5) == 0) { 2167c478bd9Sstevel@tonic-gate cp = &mesg[5]; 2177c478bd9Sstevel@tonic-gate cp = copy_str_till(rwho, cp, '@', MAXNAMLEN + 1); 2187c478bd9Sstevel@tonic-gate if (rwho[0] != '\0') { 2197c478bd9Sstevel@tonic-gate cp = copy_str_till(rsystm, ++cp, ':', 2207c478bd9Sstevel@tonic-gate MAXNAMLEN + 1); 2217c478bd9Sstevel@tonic-gate if (rsystm[0] != '\0') { 2227c478bd9Sstevel@tonic-gate (void) strcpy(systm, rsystm); 2230a1278f2SGary Mills (void) strncpy(rwho, who, 2240a1278f2SGary Mills sizeof (who)); 2257c478bd9Sstevel@tonic-gate (void) strcpy(line, "rpc.rwalld"); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate (void) time(&tloc); 2317c478bd9Sstevel@tonic-gate (void) strftime(time_buf, sizeof (time_buf), 2327c478bd9Sstevel@tonic-gate DATE_FMT, localtime(&tloc)); 2337c478bd9Sstevel@tonic-gate 234de6baaf5SJohn Sonnenschein if (zflg != 0) { 235de6baaf5SJohn Sonnenschein if ((zoneidlist = 236de6baaf5SJohn Sonnenschein malloc(sizeof (zoneid_t))) == NULL || 237de6baaf5SJohn Sonnenschein (*zoneidlist = getzoneidbyname(zonename)) == -1) 238de6baaf5SJohn Sonnenschein return (errno); 239de6baaf5SJohn Sonnenschein nzids = 1; 240de6baaf5SJohn Sonnenschein } else if (Zflg != 0) { 241de6baaf5SJohn Sonnenschein if (zone_list(NULL, &nzids) != 0) 242de6baaf5SJohn Sonnenschein return (errno); 243de6baaf5SJohn Sonnenschein again: 244de6baaf5SJohn Sonnenschein nzids *= 2; 245de6baaf5SJohn Sonnenschein if ((zoneidlist = malloc(nzids * sizeof (zoneid_t))) == NULL) 246de6baaf5SJohn Sonnenschein exit(errno); 247de6baaf5SJohn Sonnenschein nzids_saved = nzids; 248de6baaf5SJohn Sonnenschein if (zone_list(zoneidlist, &nzids) != 0) { 249de6baaf5SJohn Sonnenschein (void) free(zoneidlist); 250de6baaf5SJohn Sonnenschein return (errno); 2517c478bd9Sstevel@tonic-gate } 252de6baaf5SJohn Sonnenschein if (nzids > nzids_saved) { 253de6baaf5SJohn Sonnenschein free(zoneidlist); 254de6baaf5SJohn Sonnenschein goto again; 255de6baaf5SJohn Sonnenschein } 256de6baaf5SJohn Sonnenschein } 257de6baaf5SJohn Sonnenschein if (zflg || Zflg) { 258de6baaf5SJohn Sonnenschein for (; nzids > 0; --nzids) 259de6baaf5SJohn Sonnenschein sendmes_tozone(zoneidlist[nzids-1], aflag); 260de6baaf5SJohn Sonnenschein free(zoneidlist); 261de6baaf5SJohn Sonnenschein } else 262de6baaf5SJohn Sonnenschein sendmes_tozone(getzoneid(), aflag); 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate return (0); 2657c478bd9Sstevel@tonic-gate } 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate /* 2687c478bd9Sstevel@tonic-gate * Copy src to destination upto but not including the delim. 2697c478bd9Sstevel@tonic-gate * Leave dst empty if delim not found or whitespace encountered. 2707c478bd9Sstevel@tonic-gate * Return pointer to next character (delim, whitespace, or '\0') 2717c478bd9Sstevel@tonic-gate */ 2727c478bd9Sstevel@tonic-gate static char * 2737c478bd9Sstevel@tonic-gate copy_str_till(char *dst, char *src, char delim, int len) 2747c478bd9Sstevel@tonic-gate { 2757c478bd9Sstevel@tonic-gate int i = 0; 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate while (*src != '\0' && i < len) { 2787c478bd9Sstevel@tonic-gate if (isspace(*src)) { 2797c478bd9Sstevel@tonic-gate dst[0] = '\0'; 2807c478bd9Sstevel@tonic-gate return (src); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate if (*src == delim) { 2837c478bd9Sstevel@tonic-gate dst[i] = '\0'; 2847c478bd9Sstevel@tonic-gate return (src); 2857c478bd9Sstevel@tonic-gate } 2867c478bd9Sstevel@tonic-gate dst[i++] = *src++; 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate dst[0] = '\0'; 2897c478bd9Sstevel@tonic-gate return (src); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate 292de6baaf5SJohn Sonnenschein static void 293de6baaf5SJohn Sonnenschein sendmes_tozone(zoneid_t zid, int aflag) { 294de6baaf5SJohn Sonnenschein int i = 0; 295de6baaf5SJohn Sonnenschein char zonename[ZONENAME_MAX], root[MAXPATHLEN]; 296de6baaf5SJohn Sonnenschein struct utmpx *p; 297de6baaf5SJohn Sonnenschein 298de6baaf5SJohn Sonnenschein if (zid != getzoneid()) { 299de6baaf5SJohn Sonnenschein root[0] = '\0'; 300de6baaf5SJohn Sonnenschein (void) getzonenamebyid(zid, zonename, ZONENAME_MAX); 301de6baaf5SJohn Sonnenschein (void) zone_get_rootpath(zonename, root, sizeof (root)); 302de6baaf5SJohn Sonnenschein (void) strlcat(root, UTMPX_FILE, sizeof (root)); 303de6baaf5SJohn Sonnenschein if (!utmpxname(root)) { 304de6baaf5SJohn Sonnenschein (void) fprintf(stderr, "Cannot open %s\n", root); 305de6baaf5SJohn Sonnenschein return; 306de6baaf5SJohn Sonnenschein } 307de6baaf5SJohn Sonnenschein } else { 308de6baaf5SJohn Sonnenschein (void) utmpxname(UTMPX_FILE); 309de6baaf5SJohn Sonnenschein } 310de6baaf5SJohn Sonnenschein setutxent(); 311de6baaf5SJohn Sonnenschein while ((p = getutxent()) != NULL) { 312de6baaf5SJohn Sonnenschein if (p->ut_type != USER_PROCESS) 313de6baaf5SJohn Sonnenschein continue; 314de6baaf5SJohn Sonnenschein /* 315de6baaf5SJohn Sonnenschein * if (-a option OR NOT pty window login), send the message 316de6baaf5SJohn Sonnenschein */ 317*1eabc4beSSachidananda Urs if (aflag || !nonuserx(*p)) 318de6baaf5SJohn Sonnenschein sendmes(p, zid); 319de6baaf5SJohn Sonnenschein } 320de6baaf5SJohn Sonnenschein endutxent(); 321de6baaf5SJohn Sonnenschein 322de6baaf5SJohn Sonnenschein (void) alarm(60); 323de6baaf5SJohn Sonnenschein do { 324de6baaf5SJohn Sonnenschein i = (int)wait((int *)0); 325de6baaf5SJohn Sonnenschein } while (i != -1 || errno != ECHILD); 326de6baaf5SJohn Sonnenschein 327de6baaf5SJohn Sonnenschein } 328de6baaf5SJohn Sonnenschein 3297c478bd9Sstevel@tonic-gate /* 3307c478bd9Sstevel@tonic-gate * Note to future maintainers: with the change of wall to use the 3317c478bd9Sstevel@tonic-gate * getutxent() API, the forked children (created by this function) 3327c478bd9Sstevel@tonic-gate * must call _exit as opposed to exit. This is necessary to avoid 3337c478bd9Sstevel@tonic-gate * unwanted fflushing of getutxent's stdio stream (caused by atexit 3347c478bd9Sstevel@tonic-gate * processing). 3357c478bd9Sstevel@tonic-gate */ 3367c478bd9Sstevel@tonic-gate static void 337de6baaf5SJohn Sonnenschein sendmes(struct utmpx *p, zoneid_t zid) 3387c478bd9Sstevel@tonic-gate { 3397c478bd9Sstevel@tonic-gate int i; 3407c478bd9Sstevel@tonic-gate char *s; 3417c478bd9Sstevel@tonic-gate static char device[LMAX + 6]; 3427c478bd9Sstevel@tonic-gate char *bp; 3437c478bd9Sstevel@tonic-gate int ibp; 3447c478bd9Sstevel@tonic-gate FILE *f; 345de6baaf5SJohn Sonnenschein int fd, tmpl_fd; 346de6baaf5SJohn Sonnenschein boolean_t zoneenter = B_FALSE; 3477c478bd9Sstevel@tonic-gate 348de6baaf5SJohn Sonnenschein if (zid != getzoneid()) { 349de6baaf5SJohn Sonnenschein zoneenter = B_TRUE; 350de6baaf5SJohn Sonnenschein tmpl_fd = init_template(); 351de6baaf5SJohn Sonnenschein if (tmpl_fd == -1) { 352de6baaf5SJohn Sonnenschein (void) fprintf(stderr, "Could not initialize " 353de6baaf5SJohn Sonnenschein "process contract"); 3547c478bd9Sstevel@tonic-gate return; 355de6baaf5SJohn Sonnenschein } 356de6baaf5SJohn Sonnenschein } 357de6baaf5SJohn Sonnenschein 3587c478bd9Sstevel@tonic-gate while ((i = (int)fork()) == -1) { 3597c478bd9Sstevel@tonic-gate (void) alarm(60); 3607c478bd9Sstevel@tonic-gate (void) wait((int *)0); 3617c478bd9Sstevel@tonic-gate (void) alarm(0); 3627c478bd9Sstevel@tonic-gate } 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate if (i) 3657c478bd9Sstevel@tonic-gate return; 3667c478bd9Sstevel@tonic-gate 367de6baaf5SJohn Sonnenschein if (zoneenter && zone_enter(zid) == -1) { 368de6baaf5SJohn Sonnenschein char zonename[ZONENAME_MAX]; 369de6baaf5SJohn Sonnenschein (void) getzonenamebyid(zid, zonename, ZONENAME_MAX); 370de6baaf5SJohn Sonnenschein (void) fprintf(stderr, "Could not enter zone " 371de6baaf5SJohn Sonnenschein "%s\n", zonename); 372de6baaf5SJohn Sonnenschein } 373de6baaf5SJohn Sonnenschein if (zoneenter) 374de6baaf5SJohn Sonnenschein (void) ct_tmpl_clear(tmpl_fd); 375de6baaf5SJohn Sonnenschein 376de6baaf5SJohn Sonnenschein if (gflag) 377de6baaf5SJohn Sonnenschein if (!chkgrp(p->ut_user)) 378de6baaf5SJohn Sonnenschein _exit(0); 379de6baaf5SJohn Sonnenschein 3807c478bd9Sstevel@tonic-gate (void) signal(SIGHUP, SIG_IGN); 3817c478bd9Sstevel@tonic-gate (void) alarm(60); 3827c478bd9Sstevel@tonic-gate s = &device[0]; 3837c478bd9Sstevel@tonic-gate (void) snprintf(s, sizeof (device), "/dev/%.*s", LMAX, p->ut_line); 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate /* check if the device is really a tty */ 3867c478bd9Sstevel@tonic-gate if ((fd = open(s, O_WRONLY|O_NOCTTY|O_NONBLOCK)) == -1) { 3877c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Cannot send to %.*s on %s\n", 3887c478bd9Sstevel@tonic-gate NMAX, p->ut_user, s); 3897c478bd9Sstevel@tonic-gate perror("open"); 3907c478bd9Sstevel@tonic-gate (void) fflush(stderr); 3917c478bd9Sstevel@tonic-gate _exit(1); 3927c478bd9Sstevel@tonic-gate } else { 3937c478bd9Sstevel@tonic-gate if (!isatty(fd)) { 3947c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 3957c478bd9Sstevel@tonic-gate "Cannot send to device %.*s %s\n", 3967c478bd9Sstevel@tonic-gate LMAX, p->ut_line, 3977c478bd9Sstevel@tonic-gate "because it's not a tty"); 3987c478bd9Sstevel@tonic-gate openlog("wall", 0, LOG_AUTH); 3997c478bd9Sstevel@tonic-gate syslog(LOG_CRIT, "%.*s in utmpx is not a tty\n", 4007c478bd9Sstevel@tonic-gate LMAX, p->ut_line); 4017c478bd9Sstevel@tonic-gate closelog(); 4027c478bd9Sstevel@tonic-gate (void) fflush(stderr); 4037c478bd9Sstevel@tonic-gate _exit(1); 4047c478bd9Sstevel@tonic-gate } 4057c478bd9Sstevel@tonic-gate } 4067c478bd9Sstevel@tonic-gate #ifdef DEBUG 4077c478bd9Sstevel@tonic-gate (void) close(fd); 4087c478bd9Sstevel@tonic-gate f = fopen("wall.debug", "a"); 4097c478bd9Sstevel@tonic-gate #else 4107c478bd9Sstevel@tonic-gate f = fdopen(fd, "w"); 4117c478bd9Sstevel@tonic-gate #endif 4127c478bd9Sstevel@tonic-gate if (f == NULL) { 4137c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Cannot send to %-.*s on %s\n", 4147c478bd9Sstevel@tonic-gate NMAX, &p->ut_user[0], s); 4157c478bd9Sstevel@tonic-gate perror("open"); 4167c478bd9Sstevel@tonic-gate (void) fflush(stderr); 4177c478bd9Sstevel@tonic-gate _exit(1); 4187c478bd9Sstevel@tonic-gate } 4197c478bd9Sstevel@tonic-gate (void) fprintf(f, 4207c478bd9Sstevel@tonic-gate "\07\07\07Broadcast Message from %s (%s) on %s %19.19s", 4217c478bd9Sstevel@tonic-gate who, line, systm, time_buf); 4227c478bd9Sstevel@tonic-gate if (gflag) 4237c478bd9Sstevel@tonic-gate (void) fprintf(f, " to group %s", grpname); 4247c478bd9Sstevel@tonic-gate (void) fprintf(f, "...\n"); 4257c478bd9Sstevel@tonic-gate #ifdef DEBUG 4260a1278f2SGary Mills (void) fprintf(f, "DEBUG: To %.*s on %s\n", NMAX, p->ut_user, s); 4277c478bd9Sstevel@tonic-gate #endif 4287c478bd9Sstevel@tonic-gate i = strlen(mesg); 4297c478bd9Sstevel@tonic-gate for (bp = mesg; --i >= 0; bp++) { 4307c478bd9Sstevel@tonic-gate ibp = (unsigned int)((unsigned char) *bp); 4317c478bd9Sstevel@tonic-gate if (*bp == '\n') 4327c478bd9Sstevel@tonic-gate (void) putc('\r', f); 4337c478bd9Sstevel@tonic-gate if (isprint(ibp) || *bp == '\r' || *bp == '\013' || 4347c478bd9Sstevel@tonic-gate *bp == ' ' || *bp == '\t' || *bp == '\n' || *bp == '\007') { 4357c478bd9Sstevel@tonic-gate (void) putc(*bp, f); 4367c478bd9Sstevel@tonic-gate } else { 4377c478bd9Sstevel@tonic-gate if (!isascii(*bp)) { 4387c478bd9Sstevel@tonic-gate (void) fputs("M-", f); 4397c478bd9Sstevel@tonic-gate *bp = toascii(*bp); 4407c478bd9Sstevel@tonic-gate } 4417c478bd9Sstevel@tonic-gate if (iscntrl(*bp)) { 4427c478bd9Sstevel@tonic-gate (void) putc('^', f); 4437c478bd9Sstevel@tonic-gate (void) putc(*bp + 0100, f); 4447c478bd9Sstevel@tonic-gate } 4457c478bd9Sstevel@tonic-gate else 4467c478bd9Sstevel@tonic-gate (void) putc(*bp, f); 4477c478bd9Sstevel@tonic-gate } 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate if (*bp == '\n') 4507c478bd9Sstevel@tonic-gate (void) fflush(f); 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate if (ferror(f) || feof(f)) { 4537c478bd9Sstevel@tonic-gate (void) printf("\n\007Write failed\n"); 4547c478bd9Sstevel@tonic-gate (void) fflush(stdout); 4557c478bd9Sstevel@tonic-gate _exit(1); 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate (void) fclose(f); 4597c478bd9Sstevel@tonic-gate (void) close(fd); 4607c478bd9Sstevel@tonic-gate _exit(0); 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate static int 4657c478bd9Sstevel@tonic-gate chkgrp(char *name) 4667c478bd9Sstevel@tonic-gate { 4677c478bd9Sstevel@tonic-gate int i; 4680a1278f2SGary Mills char user[NMAX + 1]; 4697c478bd9Sstevel@tonic-gate 4700a1278f2SGary Mills (void) strlcpy(user, name, sizeof (user)); 4717c478bd9Sstevel@tonic-gate for (i = 0; pgrp->gr_mem[i] && pgrp->gr_mem[i][0]; i++) { 4720a1278f2SGary Mills if (strcmp(user, pgrp->gr_mem[i]) == 0) 4737c478bd9Sstevel@tonic-gate return (1); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate return (0); 4777c478bd9Sstevel@tonic-gate } 478de6baaf5SJohn Sonnenschein 479de6baaf5SJohn Sonnenschein static int 480de6baaf5SJohn Sonnenschein init_template(void) { 481de6baaf5SJohn Sonnenschein int fd = 0; 482de6baaf5SJohn Sonnenschein int err = 0; 483de6baaf5SJohn Sonnenschein 484de6baaf5SJohn Sonnenschein fd = open64(CTFS_ROOT "/process/template", O_RDWR); 485de6baaf5SJohn Sonnenschein if (fd == -1) 486de6baaf5SJohn Sonnenschein return (-1); 487de6baaf5SJohn Sonnenschein 488de6baaf5SJohn Sonnenschein err |= ct_tmpl_set_critical(fd, 0); 489de6baaf5SJohn Sonnenschein err |= ct_tmpl_set_informative(fd, 0); 490de6baaf5SJohn Sonnenschein err |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR); 491de6baaf5SJohn Sonnenschein err |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT); 492de6baaf5SJohn Sonnenschein if (err || ct_tmpl_activate(fd)) { 493de6baaf5SJohn Sonnenschein (void) close(fd); 494de6baaf5SJohn Sonnenschein return (-1); 495de6baaf5SJohn Sonnenschein } 496de6baaf5SJohn Sonnenschein 497de6baaf5SJohn Sonnenschein return (fd); 498de6baaf5SJohn Sonnenschein } 499