/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Reparsed daemon
*/
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <memory.h>
#include <alloca.h>
#include <ucontext.h>
#include <errno.h>
#include <syslog.h>
#include <string.h>
#include <strings.h>
#include <door.h>
#include <wait.h>
#include <libintl.h>
#include <locale.h>
#include <sys/systeminfo.h>
#include <priv.h>
#include <sys/fs_reparse.h>
#include <priv_utils.h>
#include <rpcsvc/daemon_utils.h>
static char *MyName;
static int verbose = 0;
static int start_reparsed_svcs();
static void daemonize(void);
static void
usage()
{
exit(1);
}
static void
warn_hup(int i)
{
}
/*
* Processing for daemonization
*/
static void
daemonize(void)
{
switch (fork()) {
case -1:
exit(2);
/* NOTREACHED */
case 0: /* child */
break;
default: /* parent */
_exit(0);
}
(void) chdir("/");
/*
* Close stdin, stdout, and stderr.
* Open again to redirect input+output
*/
(void) close(0);
(void) close(1);
(void) close(2);
(void) dup(1);
(void) setsid();
}
int
{
int c, error;
char *defval;
/*
* There is no check for non-global zone and Trusted Extensions.
* Reparsed works in both of these environments as long as the
* services that use reparsed are supported.
*/
if (geteuid() != 0) {
exit(1);
}
switch (c) {
case 'v':
verbose++;
break;
default:
usage();
}
}
daemonize();
switch (_enter_daemon_lock(REPARSED)) {
case 0:
break;
case -1:
exit(2);
default:
/* daemon was already running */
exit(0);
}
/*
* Make the process a privilege aware daemon.
* Only "basic" privileges are required.
*
*/
(char *)NULL) == -1) {
exit(3);
}
/*
* Clear basic privileges not required by reparsed.
*/
return (start_reparsed_svcs());
}
static void
{
/* NOTREACHED */
}
/*
* reparsed_doorfunc
*
* argp: "service_type:service_data" string
* dp & n_desc: not used.
*/
static void
{
int err;
/* NOTREACHED */
}
if (verbose)
/* NOTREACHED */
}
/*
* Door argument string comes in "service_type:service_data" format.
* Need to break it into separate "service_type" and "service_data"
* string before passing them to reparse_deref() to process them.
*/
/* NOTREACHED */
}
*cp++ = '\0';
/*
* Setup buffer for reparse_deref(). 'bufsz' is the actual
* buffer size to hold the result returned by reparse_deref().
*/
/*
* reparse_deref() calls the service type plugin library to process
* the service data. The plugin library function should understand
* the context of the service data and should be the one to XDR the
* results before returning it to the caller.
*/
if (verbose)
"reparsed_deref(svc_type: %s, data: %s, size: %d) -> %d",
switch (err) {
case 0:
break;
case EOVERFLOW:
/*
* bufsz was returned with size needed by reparse_deref().
*
* We cannot use malloc() here because door_return() never
* returns, and memory allocated by malloc() would get leaked.
*/
SAFETY_BUFFER - 1) == 0) {
/* NOTREACHED */
}
&bufsz)) == 0)
break;
/* fall through */
default:
/* NOTREACHED */
}
if (verbose)
resp->res_status = 0;
NULL, 0);
/* NOTREACHED */
}
static int
{
int doorfd;
int dfd;
return (1);
}
/*
* Create a file system path for the door
*/
return (1);
}
/*
* Clean up any stale associations
*/
(void) fdetach(REPARSED_DOOR);
/*
* Register in the kernel namespace for door_ki_open().
*/
return (1);
}
/*
* Wait for incoming calls
*/
/*CONSTCOND*/
while (1)
(void) pause();
return (10);
}