pkgserv.c revision 2
/*
* 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
*/
/*
*/
#include <pkglib.h>
#include <alloca.h>
#include <assert.h>
#include <door.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <spawn.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <libintl.h>
#define ERR_PATH_TOO_BIG "alternate root path is too long"
#define ERR_OPEN_DOOR "cannot open pkgserv door"
#define ERR_START_SERVER "cannot start pkgserv daemon: %s"
#define ERR_START_FILTER "cannot enumerate database entries"
#define ERR_FIND_SADM "cannot find sadm directory"
struct pkg_server {
char *curbuf;
int buflen;
int door;
};
static PKGserver current_server;
static void
const char *file)
{
exit(99);
}
}
static void
{
}
static void
{
/*
* Copy everything and then strdup the strings we later use and NULL
* the ones we don't.
*/
}
static int
{
int dir;
int fd;
int res;
if (dir == -1)
return (-1);
if (fd == -1)
return (-1);
return (res);
}
/*
* We need to make sure that we can locate the pkgserv and the door;
* lofs mounts makes this more difficult: "nosub" mounts don't propagate
* the door and doors created in lofs mounts are not propagated back to
* the original filesystem.
* Here we peel off the lofs mount points until we're
* we find a working door or
* there's nothing more to peel off.
* The fullpath parameter is used to return the result (stored in *sadmdir),
* root is used but returned in the computed sadmdir and so the caller should
* not use "root" any longer or set it to NULL.
*/
static void
const char **sadmdir)
{
exit(99);
}
exit(99);
}
/*
* To find the underlying mount point, you will need to
* search the mnttab and find our mountpoint and the underlying
* filesystem.
* To find the mount point: use the longest prefix but limit
* To find the underlying mount point: find a non-lofs file
* system or a <mnt> <mnt> entry (fake mountpoint for zones).
*/
for (;;) {
exit(99);
}
break;
break;
else
continue;
continue;
}
}
exit(99);
}
break;
}
/* Create a new path in the underlying filesystem. */
exit(99);
}
}
}
}
static void
pkgexit_close(void)
{
if (current_server != NULL)
}
static PKGserver
{
int stat;
char *cmd[16];
int args;
char realsadmdir[PATH_MAX];
extern char **environ;
char *prog;
char pidbuf[12];
if (current_server != NULL)
return (current_server);
if (!registered) {
registered = B_TRUE;
(void) atexit(pkgexit_close);
}
if (readonly) {
int fd;
return (NULL);
}
} else {
}
goto return_null;
pkgcmd_t n;
return (NULL);
}
return (current_server = server);
}
}
goto return_null;
args = 0;
}
}
if (readonly) {
}
prog = get_prog_name();
}
switch (mode) {
case FLUSH_LOG:
break;
case RUN_ONCE:
break;
case PERMANENT:
break;
default:
break;
}
if (master_pid != -1) {
}
int s = WEXITSTATUS(stat);
if (s == 0 || s == 1)
goto return_null;
else
goto openserver;
if (s == 2)
goto return_null;
break;
} else if (WIFSIGNALED(stat)) {
break;
}
}
}
if (readonly)
return (NULL);
}
{
}
pkgparsemode(const char *mode)
{
return (PERMANENT);
sizeof (MODE_TIMEOUT) - 1) == 0) {
if (pidstr[0] != '\0') {
master_pid = -1;
}
return (TIMEOUT);
return (RUN_ONCE);
} else {
exit(99);
/*NOTREACHED*/
}
}
char *
{
switch (mode) {
case PERMANENT:
return (PKGSERV_MODE MODE_PERMANENT);
case TIMEOUT:
getpid());
return (timebuf);
case RUN_ONCE:
return (PKGSERV_MODE MODE_RUN_ONCE);
}
exit(99);
}
void
{
else
} else {
}
}
pkgservergetmode(void)
{
return (defmode);
}
void
{
}
if (server == current_server)
}
int
int *fd)
{
return (0);
return (-1);
}
int i = 0;
}
/* Error return */
if (x != 0) {
return (x);
}
}
/* Other result */
/* Make sure that the result is at the start of the buffer. */
}
return (0);
}
/*
* Pkgsync:
* If the server is running, make sure that the contents
* file is written.
* If the server is not running, check for the log file;
* if there's a non-empty log file, we need to start the server
* as it will incorporate the log file into the contents file.
* And then check if the door is present. If it doesn't, we don't
* need to call it.
*/
{
int fd;
if (!sync_needed && !want_quit)
return (B_FALSE);
/* sync_needed == B_TRUE || want_quit == B_TRUE */
if (fd >= 0) {
/* It's mounted, so the server is likely there */
}
}
return (running || sync_needed);
}
int
{
void *server;
/* No need to write contents file; don't start if not running */
return (0);
/*
* We're assuming that it started the server and exited immediately.
* If that didn't work, there's nothing we can do.
*/
return (0);
(void) pkgcloseserver(server);
return (0);
}
int
{
if (len < PKGADD_MAX)
else
off = 0;
while (rem > 0) {
if (len >= PKGADD_MAX) {
len--;
if (p[len] != '\n')
return (-1);
len++;
}
return (-1);
}
}
return (-1);
/* Mark it unmodified. */
(void) vfpClearModified(a_vfp);
return (0);
}
int
{
int fd;
}
fd = -1;
return (-1);
}
return (-1);
}
return (0);
}
void
{
}
}
/*
* Report the next entry from the contents file.
*/
char *
{
int num[2];
return (NULL);
return (NULL);
return (NULL);
return (NULL);
}
return (NULL);
}
char *
{
char *result;
unsigned int rlen;
return (NULL);
}
if (rlen == 0)
return (NULL);
/* Result too big */
return (NULL);
}
}