util.c revision d71dbb732372504daff1f1783bc0d8864ce9bd50
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck/*
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * CDDL HEADER START
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck *
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * The contents of this file are subject to the terms of the
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Common Development and Distribution License (the "License").
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * You may not use this file except in compliance with the License.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck *
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * or http://www.opensolaris.org/os/licensing.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * See the License for the specific language governing permissions
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * and limitations under the License.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck *
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * When distributing Covered Code, include this CDDL HEADER in each
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * If applicable, add the following below this CDDL HEADER, with the
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * fields enclosed by brackets "[]" replaced with your own identifying
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * information: Portions Copyright [yyyy] [name of copyright owner]
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck *
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * CDDL HEADER END
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck */
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck/*
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Use is subject to license terms.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck */
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#pragma ident "%Z%%M% %I% %E% SMI"
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck/*
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * util.c contains a set of miscellaneous utility functions which:
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * - syslog(LOG_DEBUG, ...) if debugging is enabled
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * - check for an IP interface being marked running
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * - look up all flags for an IP interface
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * - start a child process
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * - schedule a timer
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * - check to see if a user is logged in to a graphical console
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * - look up the zone name
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck */
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <stdarg.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <stdio.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <stdlib.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <unistd.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <pthread.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <string.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <strings.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <stropts.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <syslog.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <sys/types.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <sys/socket.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <sys/sockio.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <net/if.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <spawn.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <wait.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <inetcfg.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <utmpx.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <pwd.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <limits.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <errno.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include <zone.h>
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include "defines.h"
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include "structures.h"
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include "functions.h"
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck#include "variables.h"
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckextern char **environ;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckboolean_t debug = B_FALSE;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckvoid
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckdprintf(const char *fmt, ...)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck{
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck va_list ap;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck char vbuf[1024];
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck va_start(ap, fmt);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (debug) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (void) vsnprintf(vbuf, sizeof (vbuf), fmt, ap);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck syslog(LOG_DEBUG, "%d: %s", pthread_self(), vbuf);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck va_end(ap);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck}
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckboolean_t
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckis_plugged_in(struct interface *i)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck{
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (i->if_type == IF_WIRELESS)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (B_TRUE);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return ((get_ifflags(i->if_name, i->if_family) & IFF_RUNNING) != 0);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck}
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckuint64_t
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckget_ifflags(const char *name, sa_family_t family)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck{
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck icfg_if_t intf;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck icfg_handle_t h;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck uint64_t flags = 0;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (void) strlcpy(intf.if_name, name, sizeof (intf.if_name));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck intf.if_protocol = family;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (icfg_open(&h, &intf) != ICFG_SUCCESS)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (0);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (icfg_get_flags(h, &flags) != ICFG_SUCCESS) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck /*
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Interfaces can be ripped out from underneath us (for example
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * by DHCP). We don't want to spam the console for those.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck */
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (errno == ENOENT)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck dprintf("get_ifflags: icfg_get_flags failed for '%s'",
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck name);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck else
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck syslog(LOG_ERR, "get_ifflags: icfg_get_flags %s af "
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck "%d: %m", name, family);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck /* just to be sure... */
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck flags = 0;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck icfg_close(h);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (flags);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck}
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck/*
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck *
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * This starts a child process determined by command. If command contains a
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * slash then it is assumed to be a full path; otherwise the path is searched
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * for an executable file with the name command. Command is also used as
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * argv[0] of the new process. The rest of the arguments of the function
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * up to the first NULL make up pointers to arguments of the new process.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck *
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * This function returns child exit status on success and -1 on failure.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck *
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * NOTE: original_sigmask must be set before this function is called.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck */
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckint
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstart_childv(const char *command, char const * const *argv)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck{
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck posix_spawnattr_t attr;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck sigset_t fullset;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck int i, rc, status, n;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck pid_t pid;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck char vbuf[1024];
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck vbuf[0] = 0;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck n = sizeof (vbuf);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck for (i = 1; argv[i] != NULL && n > 2; i++) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck n -= strlcat(vbuf, " ", n);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck n -= strlcat(vbuf, argv[i], n);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (argv[i] != NULL || n < 0)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck syslog(LOG_ERR, "start_childv can't log full arg vector");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if ((rc = posix_spawnattr_init(&attr)) != 0) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck dprintf("posix_spawnattr_init %d %s\n", rc, strerror(rc));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (-1);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (void) sigfillset(&fullset);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if ((rc = posix_spawnattr_setsigdefault(&attr, &fullset)) != 0) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck dprintf("setsigdefault %d %s\n", rc, strerror(rc));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (-1);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if ((rc = posix_spawnattr_setsigmask(&attr, &original_sigmask)) != 0) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck dprintf("setsigmask %d %s\n", rc, strerror(rc));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (-1);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if ((rc = posix_spawnattr_setflags(&attr,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK)) != 0) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck dprintf("setflags %d %s\n", rc, strerror(rc));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (-1);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if ((rc = posix_spawnp(&pid, command, NULL, &attr, (char * const *)argv,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck environ)) > 0) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck dprintf("posix_spawnp failed errno %d", rc);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (-1);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if ((rc = posix_spawnattr_destroy(&attr)) != 0) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck dprintf("posix_spawn_attr_destroy %d %s\n", rc, strerror(rc));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (-1);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (void) waitpid(pid, &status, 0);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (WIFSIGNALED(status) || WIFSTOPPED(status)) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck i = WIFSIGNALED(status) ? WTERMSIG(status) : WSTOPSIG(status);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck syslog(LOG_ERR, "'%s%s' %s with signal %d (%s)", command, vbuf,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (WIFSIGNALED(status) ? "terminated" : "stopped"), i,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck strsignal(i));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (-2);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck } else {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck syslog(LOG_INFO, "'%s%s' completed normally: %d", command, vbuf,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck WEXITSTATUS(status));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (WEXITSTATUS(status));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck}
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckint
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstart_child(const char *command, ...)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck{
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck const char **argv = NULL;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck int argv_len = 0;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck va_list ap;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck int i = 1, rc;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck va_start(ap, command);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck do {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (i >= argv_len) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck void *p;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck argv_len = argv_len != 0 ? argv_len * 2 : 4;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck p = realloc(argv, sizeof (*argv)*argv_len);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (p != NULL) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck argv = p;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck } else {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck syslog(LOG_ERR, "Out of memory in start_child");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck free(argv);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (-1);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck argv[i] = va_arg(ap, const char *);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck } while (argv[i++] != NULL);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck va_end(ap);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck argv[0] = command;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck rc = start_childv(command, argv);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck free(argv);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (rc);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck}
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckuint32_t timer_expire = TIMER_INFINITY;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck/*
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Schedules a SIGALRM in delay seconds, unless one is already
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * scheduled sooner. If one is already scheduled later than
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * delay seconds from now, that one will be replaced.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck */
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckvoid
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckstart_timer(uint32_t now, uint32_t delay)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck{
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (now + delay > timer_expire)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck timer_expire = now + delay;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (void) alarm(delay);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck}
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckboolean_t
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckvalid_graphical_user(boolean_t query)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck{
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck struct utmpx *utp;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck char *user = NULL;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck const char HOMESTR[] = "HOME=";
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck char buf[1024]; /* == sysconf(_SC_GETPW_R_SIZE_MAX) == NSS_BUFSIZ */
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck static char home_dir[PATH_MAX + sizeof (HOMESTR)];
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck struct passwd passwd;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck struct passwd *pw;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck boolean_t popup_ok;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck /*
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Check to see if our SMF property says popups are OK.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck */
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if ((lookup_boolean_property(OUR_PG, query ? "popup_query" :
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck "popup_info", &popup_ok) == 0) && !popup_ok)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (B_FALSE);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck /*
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * Look for someone logged into the console from host ":0" (i.e.,
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * the X display. Down the road, we should generalize this so
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * ":0" is not hard-coded.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck */
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck setutxent();
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck while ((utp = getutxent()) != NULL) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if ((utp->ut_type == USER_PROCESS) &&
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (strcmp(utp->ut_line, "console") == 0) &&
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (strcmp(utp->ut_host, ":0") == 0)) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck user = strdup(utp->ut_user);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck break;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck endutxent();
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck dprintf("utmpx: done %s", user != NULL ? user : "");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (user == NULL)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (B_FALSE);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck pw = getpwnam_r(user, &passwd, buf, sizeof (buf));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (pw == NULL) {
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck syslog(LOG_ERR, "couldn't get user %s: %m", user);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck free(user);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (B_FALSE);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck }
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck free(user);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck /*
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * We shouldn't be dumping this into our environment or changing
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * our uid/gid but instead starting up the zenity processes with
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck * this display as this user. RFE to change this.
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck */
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (void) putenv("DISPLAY=:0.0");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (void) strlcpy(home_dir, HOMESTR, sizeof (home_dir));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (void) strlcat(home_dir, pw->pw_dir, sizeof (home_dir));
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (void) putenv(home_dir);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return (pw != NULL);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck}
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeckvoid
d71dbb732372504daff1f1783bc0d8864ce9bd50jbecklookup_zonename(char *zonename, size_t zonesize)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck{
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck zoneid_t zoneid = getzoneid();
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck if (getzonenamebyid(zoneid, zonename, zonesize) >= 0)
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck return;
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck syslog(LOG_ERR, "could not determine zone name");
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck (void) strlcpy(zonename, GLOBAL_ZONENAME, zonesize);
d71dbb732372504daff1f1783bc0d8864ce9bd50jbeck}