62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik/*
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * CDDL HEADER START
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik *
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * The contents of this file are subject to the terms of the
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * Common Development and Distribution License (the "License").
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * You may not use this file except in compliance with the License.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik *
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * or http://www.opensolaris.org/os/licensing.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * See the License for the specific language governing permissions
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * and limitations under the License.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik *
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * When distributing Covered Code, include this CDDL HEADER in each
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * If applicable, add the following below this CDDL HEADER, with the
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * fields enclosed by brackets "[]" replaced with your own identifying
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * information: Portions Copyright [yyyy] [name of copyright owner]
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik *
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * CDDL HEADER END
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik/*
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * Use is subject to license terms.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <pkglib.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <alloca.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <assert.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <door.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <errno.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <fcntl.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <pthread.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <spawn.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <stdio.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <stdlib.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <strings.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <sys/mman.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <sys/param.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <sys/stat.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <sys/wait.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <unistd.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#include <libintl.h>
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik#include <sys/mnttab.h>
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik#include <sys/mkdev.h>
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#define PKGADD_MAX (512 * 1024)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#define SADM_DIR "/var/sadm/install"
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#define PKGSERV_PATH "/usr/sadm/install/bin/pkgserv"
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#define ERR_PATH_TOO_BIG "alternate root path is too long"
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#define ERR_OPEN_DOOR "cannot open pkgserv door"
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#define ERR_START_SERVER "cannot start pkgserv daemon: %s"
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik#define ERR_START_FILTER "cannot enumerate database entries"
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik#define ERR_FIND_SADM "cannot find sadm directory"
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikstruct pkg_server {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik FILE *fp;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik char *curbuf;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int buflen;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int door;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik boolean_t onetime;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik};
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikstatic PKGserver current_server;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikstatic start_mode_t defmode = INVALID;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikstatic boolean_t registered = B_FALSE;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikstatic pid_t master_pid = -1;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikstatic void
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgfilename(char path[PATH_MAX], const char *root, const char *sadmdir,
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik const char *file)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (snprintf(path, PATH_MAX, "%s%s/%s", root == NULL ? "" : root,
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik sadmdir == NULL ? SADM_DIR : sadmdir, file) >= PATH_MAX) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik progerr(gettext(ERR_PATH_TOO_BIG));
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik exit(99);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dikstatic void
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dikfree_xmnt(struct extmnttab *xmnt)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik{
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik free(xmnt->mnt_special);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik free(xmnt->mnt_mountp);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik free(xmnt->mnt_fstype);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik}
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dikstatic void
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dikcopy_xmnt(const struct extmnttab *xmnt, struct extmnttab *saved)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik{
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik free_xmnt(saved);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik /*
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * Copy everything and then strdup the strings we later use and NULL
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * the ones we don't.
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik */
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik *saved = *xmnt;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (saved->mnt_special != NULL)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik saved->mnt_special = strdup(saved->mnt_special);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (saved->mnt_mountp != NULL)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik saved->mnt_mountp = strdup(saved->mnt_mountp);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (saved->mnt_fstype != NULL)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik saved->mnt_fstype = strdup(saved->mnt_fstype);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik saved->mnt_mntopts = NULL;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik saved->mnt_time = NULL;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik}
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dikstatic int
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Diktestdoor(char *path)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik{
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik int dir;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik int fd;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik struct door_info di;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik int res;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik dir = open(path, O_RDONLY);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (dir == -1)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik return (-1);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik fd = openat(dir, PKGDOOR, O_RDWR);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik (void) close(dir);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (fd == -1)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik return (-1);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik res = door_info(fd, &di);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik (void) close(fd);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik return (res);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik}
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik/*
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * We need to make sure that we can locate the pkgserv and the door;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * lofs mounts makes this more difficult: "nosub" mounts don't propagate
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * the door and doors created in lofs mounts are not propagated back to
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * the original filesystem.
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * Here we peel off the lofs mount points until we're
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * at /var/sadm/install or
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * we find a working door or
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * there's nothing more to peel off.
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * The fullpath parameter is used to return the result (stored in *sadmdir),
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * root is used but returned in the computed sadmdir and so the caller should
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * not use "root" any longer or set it to NULL.
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik */
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dikstatic void
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dikpkgfindrealsadmdir(char fullpath[PATH_MAX], const char *root,
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik const char **sadmdir)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik{
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik struct stat buf;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik struct extmnttab xmnt;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik FILE *mnttab = NULL;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik char temp[PATH_MAX];
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik struct extmnttab saved = {NULL, NULL, NULL, NULL, NULL, 0, 0};
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (snprintf(temp, PATH_MAX, "%s%s",
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik root == NULL ? "" : root,
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik *sadmdir == NULL ? SADM_DIR : *sadmdir) >= PATH_MAX) {
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik progerr(gettext(ERR_PATH_TOO_BIG));
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik exit(99);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik }
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (stat(temp, &buf) != 0) {
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik progerr(gettext(ERR_FIND_SADM));
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik exit(99);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik }
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik /*
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * To find the underlying mount point, you will need to
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * search the mnttab and find our mountpoint and the underlying
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * filesystem.
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * To find the mount point: use the longest prefix but limit
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * us to the filesystems with the same major/minor numbers.
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * To find the underlying mount point: find a non-lofs file
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik * system or a <mnt> <mnt> entry (fake mountpoint for zones).
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik */
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik for (;;) {
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik size_t max = 0;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (realpath(temp, fullpath) == NULL) {
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik progerr(gettext(ERR_FIND_SADM));
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik exit(99);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik }
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (strcmp(fullpath, SADM_DIR) == 0)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik break;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (testdoor(fullpath) == 0)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik break;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (mnttab == NULL)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik mnttab = fopen(MNTTAB, "r");
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik else
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik resetmnttab(mnttab);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik while (getextmntent(mnttab, &xmnt, 0) == 0) {
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik size_t len;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (major(buf.st_dev) != xmnt.mnt_major ||
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik minor(buf.st_dev) != xmnt.mnt_minor)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik continue;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik len = strlen(xmnt.mnt_mountp);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (len < max)
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik continue;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (strncmp(xmnt.mnt_mountp, fullpath, len) == 0 &&
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik (len == 1 || fullpath[len] == '/' ||
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik fullpath[len] == '\0')) {
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik max = len;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik copy_xmnt(&xmnt, &saved);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik }
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik }
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (strcmp(saved.mnt_fstype, "lofs") != 0 ||
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik strcmp(saved.mnt_mountp, saved.mnt_special) == 0) {
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik break;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik }
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik /* Create a new path in the underlying filesystem. */
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (snprintf(temp, PATH_MAX, "%s%s", saved.mnt_special,
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik &fullpath[max]) >= PATH_MAX) {
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik progerr(gettext(ERR_PATH_TOO_BIG));
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik exit(99);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik }
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik }
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik if (mnttab != NULL) {
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik free_xmnt(&saved);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik (void) fclose(mnttab);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik }
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik *sadmdir = fullpath;
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik}
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikstatic void
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgexit_close(void)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (current_server != NULL)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgcloseserver(current_server);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikstatic PKGserver
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgopenserver_i(const char *root, const char *sadmdir, boolean_t readonly,
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik start_mode_t mode)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik PKGserver server;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik struct door_info di;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pid_t pid;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int stat;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int first = B_TRUE;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik char *cmd[16];
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int args;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik char pkgdoor[PATH_MAX];
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik char realsadmdir[PATH_MAX];
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik extern char **environ;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik char *prog;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik char pidbuf[12];
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (current_server != NULL)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (current_server);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (!registered) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik registered = B_TRUE;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) atexit(pkgexit_close);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (readonly) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int fd;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) strcpy(pkgdoor, "/tmp/pkgdoor.XXXXXX");
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if ((fd = mkstemp(pkgdoor)) < 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik progerr(gettext(ERR_OPEN_DOOR));
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) close(fd);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik } else {
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik pkgfindrealsadmdir(realsadmdir, root, &sadmdir);
7706a9bf5155da553880e1d88bef039daa6fc46cCasper H.S. Dik root = NULL;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgfilename(pkgdoor, root, sadmdir, PKGDOOR);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server = malloc(sizeof (*server));
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server == NULL)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik goto return_null;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->fp = NULL;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->onetime = readonly;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikopenserver:
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->door = open(pkgdoor, O_RDWR);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server->door >= 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (door_info(server->door, &di) == 0 && di.di_target >= 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgcmd_t n;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik n.cmd = PKG_NOP;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->buflen = 1024;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->curbuf = malloc(1024);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server->curbuf == NULL ||
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgcmd(server, &n, sizeof (n), NULL, NULL, NULL)) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgcloseserver(server);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (current_server = server);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) close(server->door);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (!first || mode == NEVER)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik goto return_null;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik first = B_FALSE;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik args = 0;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = strrchr(PKGSERV_PATH, '/') + 1;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (root != NULL && strcmp(root, "/") != 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = "-R";
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = (char *)root;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (sadmdir != NULL && strcmp(sadmdir, SADM_DIR) != 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = "-d";
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = (char *)sadmdir;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (readonly) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = "-r";
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = pkgdoor;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik prog = get_prog_name();
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (prog != NULL) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = "-N";
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = prog;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik switch (mode) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik case FLUSH_LOG:
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = "-e";
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik break;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik case RUN_ONCE:
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = "-o";
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik break;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik case PERMANENT:
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = "-p";
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik break;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik default:
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik break;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (master_pid != -1) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = "-P";
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) snprintf(pidbuf, sizeof (pidbuf), "%d", master_pid);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = pidbuf;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd[args++] = NULL;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik assert(args <= sizeof (cmd)/sizeof (char *));
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (posix_spawn(&pid, PKGSERV_PATH, NULL, NULL, cmd, environ) == 0) {
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore server->onetime |= (mode == RUN_ONCE);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik while (wait4(pid, &stat, 0, NULL) != -1) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (WIFEXITED(stat)) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int s = WEXITSTATUS(stat);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (s == 0 || s == 1)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (mode == FLUSH_LOG)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik goto return_null;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik else
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik goto openserver;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (s == 2)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik goto return_null;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik break;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik } else if (WIFSIGNALED(stat)) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik break;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik progerr(gettext(ERR_START_SERVER), strerror(errno));
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikreturn_null:
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (readonly)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) unlink(pkgdoor);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik free(server);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. DikPKGserver
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgopenserver(const char *root, const char *sadmdir, boolean_t ro)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (pkgopenserver_i(root, sadmdir, ro, pkgservergetmode()));
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikstart_mode_t
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgparsemode(const char *mode)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (strcasecmp(mode, MODE_PERMANENT) == 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (PERMANENT);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik } else if (strncasecmp(mode, MODE_TIMEOUT,
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik sizeof (MODE_TIMEOUT) - 1) == 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik const char *pidstr = mode + sizeof (MODE_TIMEOUT) - 1;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (pidstr[0] != '\0') {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik master_pid = atoi(pidstr);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (master_pid <= 1 || kill(master_pid, 0) != 0)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik master_pid = -1;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (TIMEOUT);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik } else if (strcasecmp(mode, MODE_RUN_ONCE) == 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (RUN_ONCE);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik } else {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik progerr(gettext("invalid pkgserver mode: %s"), mode);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik exit(99);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik /*NOTREACHED*/
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikchar *
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgmodeargument(start_mode_t mode)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik static char timebuf[sizeof (PKGSERV_MODE) + sizeof (MODE_TIMEOUT) + 10];
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik switch (mode) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik case PERMANENT:
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (PKGSERV_MODE MODE_PERMANENT);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik case TIMEOUT:
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) snprintf(timebuf, sizeof (timebuf),
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik PKGSERV_MODE MODE_TIMEOUT "%d",
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (master_pid > 1 && kill(master_pid, 0) == 0) ? master_pid :
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik getpid());
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (timebuf);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik case RUN_ONCE:
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (PKGSERV_MODE MODE_RUN_ONCE);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik progerr(gettext("Bad pkgserv mode: %d"), (int)mode);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik exit(99);
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore /*NOTREACHED*/
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikvoid
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgserversetmode(start_mode_t mode)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (mode == DEFAULTMODE || mode == INVALID) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik char *var = getenv(SUNW_PKG_SERVERMODE);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (var != NULL)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik defmode = pkgparsemode(var);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik else
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik defmode = DEFAULTMODE;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik } else {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik defmode = mode;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikstart_mode_t
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgservergetmode(void)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (defmode == INVALID)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgserversetmode(DEFAULTMODE);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (defmode);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikvoid
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgcloseserver(PKGserver server)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server->fp != NULL)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) fclose(server->fp);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik free(server->curbuf);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server->onetime) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgcmd_t cmd;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd.cmd = PKG_EXIT;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) pkgcmd(server, &cmd, sizeof (cmd), NULL, NULL, NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) close(server->door);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server == current_server)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik current_server = NULL;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik free(server);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikint
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgcmd(PKGserver srv, void *cmd, size_t len, char **result, size_t *rlen,
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int *fd)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik door_arg_t da;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik da.data_ptr = cmd;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik da.data_size = len;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik da.desc_ptr = NULL;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik da.desc_num = 0;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik da.rbuf = result == NULL ? NULL : *result;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik da.rsize = rlen == NULL ? 0 : *rlen;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (door_call(srv->door, &da) != 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (((pkgcmd_t *)cmd)->cmd == PKG_EXIT && errno == EINTR)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (0);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (-1);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (da.desc_ptr != NULL) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int i = 0;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (fd != NULL)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik *fd = da.desc_ptr[i++].d_data.d_desc.d_descriptor;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik for (; i < da.desc_num; i++)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) close(da.desc_ptr[i].d_data.d_desc.d_descriptor);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik /* Error return */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (da.data_size == sizeof (int)) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int x = *(int *)da.data_ptr;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (x != 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (result == NULL || da.rbuf != *result)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) munmap(da.rbuf, da.rsize);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (x);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik /* Other result */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (result != NULL) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik /* Make sure that the result is at the start of the buffer. */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (da.data_ptr != NULL && da.rbuf != da.data_ptr)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) memmove(da.rbuf, da.data_ptr, da.data_size);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik *result = da.rbuf;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik *rlen = da.data_size;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik } else if (da.rbuf != NULL) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) munmap(da.rbuf, da.rsize);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (0);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik/*
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * Pkgsync:
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * If the server is running, make sure that the contents
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * file is written.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * If the server is not running, check for the log file;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * if there's a non-empty log file, we need to start the server
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * as it will incorporate the log file into the contents file.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * And then check if the door is present. If it doesn't, we don't
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * need to call it.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikboolean_t
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgsync_needed(const char *root, const char *sadmdir, boolean_t want_quit)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik struct stat pbuf;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik char pkgfile[PATH_MAX];
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik boolean_t sync_needed, running;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int fd;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik struct door_info di;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgfilename(pkgfile, root, sadmdir, PKGLOG);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik sync_needed = stat(pkgfile, &pbuf) == 0 && pbuf.st_size > 0;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (!sync_needed && !want_quit)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (B_FALSE);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgfilename(pkgfile, root, sadmdir, PKGDOOR);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik /* sync_needed == B_TRUE || want_quit == B_TRUE */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik running = B_FALSE;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik fd = open(pkgfile, O_RDWR);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (fd >= 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (door_info(fd, &di) == 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik /* It's mounted, so the server is likely there */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik running = B_TRUE;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) close(fd);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (running || sync_needed);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikint
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgsync(const char *root, const char *sadmdir, boolean_t force_quit)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik void *server;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgcmd_t cmd;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik /* No need to write contents file; don't start if not running */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (!pkgsync_needed(root, sadmdir, force_quit))
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (0);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server = pkgopenserver_i(root, sadmdir, B_FALSE, FLUSH_LOG);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik /*
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * We're assuming that it started the server and exited immediately.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * If that didn't work, there's nothing we can do.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server == NULL)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (0);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik cmd.cmd = force_quit ? PKG_EXIT : PKG_DUMP;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) pkgcmd(server, &cmd, sizeof (cmd), NULL, NULL, NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) pkgcloseserver(server);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (0);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikint
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgservercommitfile(VFP_T *a_vfp, PKGserver server)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik size_t len = vfpGetModifiedLen(a_vfp);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik ssize_t rem = len;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik size_t off;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgfilter_t *pcmd;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik char *map = a_vfp->_vfpStart;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (len < PKGADD_MAX)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pcmd = alloca(sizeof (*pcmd) + len);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik else
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pcmd = alloca(sizeof (*pcmd) + PKGADD_MAX);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik off = 0;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pcmd->cmd = PKG_ADDLINES;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik while (rem > 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik char *p = map + off;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik len = rem;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (len >= PKGADD_MAX) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik len = PKGADD_MAX - 1;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik while (p[len] != '\n' && len > 0)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik len--;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (p[len] != '\n')
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (-1);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik len++;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) memcpy(&pcmd->buf[0], p, len);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pcmd->len = len;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (pkgcmd(server, pcmd, sizeof (*pcmd) + len - 1,
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik NULL, NULL, NULL) != 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (-1);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik rem -= len;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik off += len;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pcmd->len = 0;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pcmd->cmd = PKG_PKGSYNC;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (pkgcmd(server, pcmd, sizeof (*pcmd), NULL, NULL, NULL) != 0)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (-1);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik /* Mark it unmodified. */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik vfpTruncate(a_vfp);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) vfpClearModified(a_vfp);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (0);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikint
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgopenfilter(PKGserver server, const char *filt)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int fd;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgfilter_t *pfcmd;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int clen = filt == NULL ? 0 : strlen(filt);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int len = sizeof (*pfcmd) + clen;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pfcmd = alloca(len);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server->fp != NULL) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) fclose(server->fp);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->fp = NULL;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pfcmd->cmd = PKG_FILTER;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pfcmd->len = clen;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (filt != NULL)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) strcpy(pfcmd->buf, filt);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik fd = -1;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (pkgcmd(server, pfcmd, len, NULL, NULL, &fd) != 0 || fd == -1) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik progerr(gettext(ERR_START_FILTER));
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (-1);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->fp = fdopen(fd, "r");
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server->fp == NULL) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) close(fd);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik progerr(gettext(ERR_START_FILTER));
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (-1);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (0);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikvoid
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkgclosefilter(PKGserver server)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server->fp != NULL) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) fclose(server->fp);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->fp = NULL;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik/*
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik * Report the next entry from the contents file.
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikchar *
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkggetentry(PKGserver server, int *len, int *pathlen)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int num[2];
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server->fp == NULL)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (feof(server->fp) || ferror(server->fp))
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (fread(num, sizeof (int), 2, server->fp) != 2)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (num[0] > server->buflen) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik free(server->curbuf);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->buflen = num[0];
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->curbuf = malloc(server->buflen);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server->curbuf == NULL)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (fread(server->curbuf, 1, num[0], server->fp) != num[0])
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik *len = num[0];
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik *pathlen = num[1];
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (server->curbuf);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikchar *
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dikpkggetentry_named(PKGserver server, const char *path, int *len, int *pathlen)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik{
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik int plen = strlen(path);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pkgfilter_t *pcmd = alloca(sizeof (*pcmd) + plen);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik char *result;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik unsigned int rlen;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik pcmd->cmd = PKG_FINDFILE;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik *pathlen = pcmd->len = plen;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) memcpy(pcmd->buf, path, pcmd->len + 1);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik result = server->curbuf;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik rlen = server->buflen;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (pkgcmd(server, pcmd, sizeof (*pcmd) + pcmd->len,
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik &result, &rlen, NULL) != 0) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (rlen == 0)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik /* Result too big */
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (result != server->curbuf) {
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik free(server->curbuf);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->buflen = rlen;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik server->curbuf = malloc(server->buflen);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik if (server->curbuf == NULL)
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (NULL);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) memcpy(server->curbuf, result, rlen);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik (void) munmap(result, rlen);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik }
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik *len = rlen;
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik return (server->curbuf);
62224350e5355e6834f7deb9d8a7d062a50cb7c2Casper H.S. Dik}