volmissing.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1991-2002 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Program to report that a volume has been requested.
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <string.h>
#include <locale.h>
#include <libintl.h>
#include <syslog.h>
#include <pwd.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/systeminfo.h>
#include <errno.h>
#include <limits.h>
#ifdef bool_t
#endif
typedef enum {false = 0, true = 1} bool_t;
static char *vol_username = NULL;
static bool_t vol_user_is_root = false;
static char *vol_volumename = NULL;
static char *vol_mediatype = NULL;
static char *vol_message1 = NULL;
static char *vol_message1_nogecos = NULL;
static char *vol_message1_system = NULL;
static char *vol_syslogmessage = NULL;
static char vol_hostname[MAXNAMELEN];
#define SYSTEM_HANDLE "The System"
#define STD_MSG1 \
"User %s, (%s) has requested that a %s volume\n\
named %s be loaded into a drive on %s.\n"
#define STD_MSG1_NOGECOS \
"User %s has requested that a %s volume\n\
named %s be loaded into a drive on %s.\n"
#define STD_MSG1_SYSTEM \
"The system has requested that a %s volume\n\
named %s be loaded into a drive on %s.\n"
#define STD_MSG_SYSLOG "%s@%s requested %s named %s\n"
#define ENV_ERROR_MSG "failed due to undefined environment variables"
/* the windows popup program to call (by path and by name) */
#define VOLMISSING_POPUP_PATH "/usr/dt/lib/volmissing_popup"
#define VOLMISSING_POPUP "volmissing_popup"
/* the "check for windows" program to call (by path and by name) */
#define OW_WINSYSCK_PATH "/usr/openwin/bin/winsysck"
#define OW_WINSYSCK "winsysck"
#define OW_WINSYSCK_PROTOCOL "x11"
#define BIT_BUCKET "/dev/null"
int
{
extern int sysinfo(int, char *, long);
static void usage(void);
static void console_msg(void);
static void syslog_msg(void);
static void mail_msg(char *);
extern char *optarg;
int c;
char *m_alias;
bool_t do_console = false;
#ifdef DEBUG
#endif
bool_t do_manual_message = false;
#ifdef DEBUG
} else {
}
#endif
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
/* process arguments */
switch (c) {
case 's':
do_syslog = true;
break;
case 'c':
do_console = true;
break;
case 'p':
do_popup = true;
break;
case 'm':
do_mail = true;
break;
default:
usage();
return (-1);
}
}
/*
* Can't run this puppy if no Environment variables
* are defined.
*/
(vol_mediatype == NULL)) {
return (-1);
}
/* can't get an entry for this user name! */
} else {
/* root -- let's pretty that up */
vol_user_is_root = true;
} else {
/* non-root user who's name is found in passwd map */
}
}
#ifdef DEBUG
#endif
/*
* If this is a volmissing event was caused by the system
* the user id will be "root". "root" processes will
* not be able to connect to a display owned by a non-root
* user. So, we have to fake it out and make it think
* the new process is really owned by the user. We'll
* the user who'll own this process.
*/
#ifdef DEBUG
#endif
return (1);
} else {
#ifdef DEBUG
"volmissing: stat on dev console worked\n");
#endif
/*
* Now we need to get the passwd struct for the
* getpwuid returns null we'll catch it later.
*/
#ifdef DEBUG
"volmissing: getpwuid failed for console owner\n");
#endif
/*
* We couldn't get the passwd struct for
* console owner. We better reset the vol env
* vars as they are dependent on pw struct
* contents. This way the console_msg()
* will still work.
*/
}
}
}
if (do_syslog) {
syslog_msg();
}
if (do_console) {
console_msg();
}
if (do_mail) {
}
if (do_popup) {
/*
* We can only display a popup if a windows session
* is running and we know the user's uid from the
* passwd structure. We need to know the uid so
* we can setuid to the user and get access to
* his X display for the popup.
*
* (To keep from having to actually check for X
* running, we'll just try to run the popup, assuming
* it will fail if windows are not running.)
*/
do_manual_message = true;
}
if (!do_manual_message) {
do_manual_message = true;
}
}
if (!do_manual_message) {
do_manual_message = true;
}
}
if (do_manual_message) {
/*
* Don't want to display the same message twice.
*/
if (!do_console) {
console_msg();
}
}
}
console_msg();
}
#ifdef DEBUG
#endif
return (0);
}
static void
usage(void)
{
}
static void
syslog_msg(void)
{
closelog();
}
static void
console_msg(void)
{
return;
}
if (vol_user_is_root) {
} else if (vol_gecos) {
} else {
}
}
/*
* try to exec the popup message
* return false on error, else true
*/
static bool_t
{
int exit_code;
int fd;
char ld_lib_path[MAXNAMELEN];
char *home_dir;
/*
* fork a simple X Windows program to display gui for
* notifying the user that the specified media is missing.
*/
#ifdef DEBUG
#endif
gettext("volmissing: error: can't fork a process\n"));
goto dun;
}
if (pid == 0) {
/*
* Error messages to console
*/
}
/*
* Set up the users environment.
*/
(void) putenv(display_name);
(void) putenv(ld_lib_path);
/*
* We need to set $HOME so the users .Xauthority file
* can be located. This is especially needed for a user
* user MIT Magic Cookie authentication security.
*/
perror("malloc");
exit(1);
}
/*
* We need the volmissing popup to be owned
* by the owner of the X display.
* Don't want x program doing anything nasty.
*
* Note - have to set gid stuff first as effective uid
* must belong to root for this to work correctly.
*/
#ifdef DEBUG
#endif
gettext("exec of %s failed; errno = %d"),
exit(1);
}
/* the parent - will wait for child (volmissing_popup) to exit */
if (WEXITSTATUS(exit_code) == 0) {
ret_val = true; /* success */
}
}
}
dun:
return (ret_val);
}
static void
{
if (pipe(p) == -1) {
perror("pipe");
return;
}
perror("fork");
return;
}
if (pid == 0) {
(void) dup2(p[0], 0);
(void) close(p[1]);
perror("mail");
exit(1);
}
(void) close(p[0]);
outfd = p[1];
if (vol_user_is_root) {
} else if (vol_gecos) {
} else {
}
}
/*
* Use a popup window to display the "manually ejectable"
* message for X86 machines.
*
* return flase if the popup fails, else return true
*/
static bool_t
{
int exit_code = -1;
int fd;
char *home_dir;
char ld_lib_path[MAXNAMELEN];
gettext("error: can't fork a process (errno %d)\n"),
errno);
goto dun;
}
if (pid == 0) {
/*
* error messages to console
*/
#ifndef DEBUG
}
#endif
/*
* set up the users environment
*/
(void) putenv("DISPLAY=:0.0");
(void) putenv(ld_lib_path);
/*
* we need to set $HOME so the users .Xauthority file
* can be located. This is especially needed for a user
* user MIT Magic Cookie authentication security
*/
perror("malloc");
exit(1);
}
/*
* We need the X application to be able to connect to
* the user's display so we better run as if we are
* the user (effectively).
* Don't want x program doing anything nasty.
*
* Note - have to set gid stuff first as effective uid
* must belong to root for this to work correctly.
*/
#ifdef DEBUG
"DEBUG: \"%s\" being execl'ed with protocol = \"%s\"\n",
#endif
gettext("error: exec of \"%s\" failed (errno = %d)\n"),
exit(-1);
}
/* the parent -- wait for the child */
if (WEXITSTATUS(exit_code) == 0) {
ret_val = true;
}
}
}
dun:
/* all done */
#ifdef DEBUG
#endif
return (ret_val);
}