From 62224350e5355e6834f7deb9d8a7d062a50cb7c2 Mon Sep 17 00:00:00 2001 From: "Casper H.S. Dik" Date: Mon, 15 Jun 2009 22:21:13 +0200 Subject: PSARC 2009/173 Fasttrack for turbo-charging SVr4 packaging 6820054 Turbocharged SVr4 package commands [PSARC 2009/173] --- usr/src/lib/libpkg/common/mapfile-vers | 14 + usr/src/lib/libpkg/common/pkglib.h | 74 ++- usr/src/lib/libpkg/common/pkgserv.c | 603 +++++++++++++++++++++ usr/src/lib/libpkg/common/srchcfile.c | 953 ++++----------------------------- 4 files changed, 794 insertions(+), 850 deletions(-) create mode 100644 usr/src/lib/libpkg/common/pkgserv.c (limited to 'usr/src/lib/libpkg/common') diff --git a/usr/src/lib/libpkg/common/mapfile-vers b/usr/src/lib/libpkg/common/mapfile-vers index 7cb5ad56f3..f1fd2a8001 100644 --- a/usr/src/lib/libpkg/common/mapfile-vers +++ b/usr/src/lib/libpkg/common/mapfile-vers @@ -132,6 +132,9 @@ SUNWprivate { path_valid; pkg_passphrase_cb; pkgalias; + pkgclosefilter; + pkgcloseserver; + pkgcmd; pkgerr; pkgerr_add; pkgerr_clear; @@ -142,9 +145,18 @@ SUNWprivate { pkgerr_num; pkgexecl; pkgexecv; + pkggetentry; + pkggetentry_named; pkghead; pkglist_cont; + pkgmodeargument; pkgmount; + pkgopenfilter; + pkgopenserver; + pkgparsemode; + pkgservercommitfile; + pkgservergetmode; + pkgserversetmode; pkgstrAddToken; pkgstrContainsToken; pkgstrConvertPathToBasename; @@ -160,6 +172,8 @@ SUNWprivate { pkgstrRemoveLeadingWhitespace; pkgstrRemoveToken; pkgstrScaleNumericString; + pkgsync; + pkgsync_needed; pkgtrans; pkgumount; ppkgmap; diff --git a/usr/src/lib/libpkg/common/pkglib.h b/usr/src/lib/libpkg/common/pkglib.h index 418cf632f7..04b17730ca 100644 --- a/usr/src/lib/libpkg/common/pkglib.h +++ b/usr/src/lib/libpkg/common/pkglib.h @@ -48,6 +48,58 @@ extern "C" { #include "keystore.h" #include "cfext.h" +/* + * The contents database file interface. + */ + +typedef struct pkg_server *PKGserver; + +/* Some commands modify the internal database: add them here */ +#define PKG_WRITE_COMMAND(cmd) ((cmd) == PKG_ADDLINES) + +#define PKG_EXIT 0x0 +#define PKG_FINDFILE 0x1 +#define PKG_DUMP 0x2 +#define PKG_PKGSYNC 0x3 +#define PKG_FILTER 0x4 +#define PKG_ADDLINES 0x5 +#define PKG_NOP 0x6 + +#define SUNW_PKG_SERVERMODE "SUNW_PKG_SERVERMODE" + +#define PKGSERV_MODE "pkg-server-mode=" +#define PKGSERV_MODE_LEN (sizeof (PKGSERV_MODE) - 1) + +#define MODE_PERMANENT "permanent" +#define MODE_RUN_ONCE "run_once" +#define MODE_TIMEOUT "timeout" + +#define MAXLOGFILESIZE (20 * 1024 * 1024) + +#define PKGLOG "pkglog" +#define PKGDOOR ".door" + +typedef enum { + INVALID, /* Not initialized */ + NEVER, /* Don't start, does check if it is running. */ + FLUSH_LOG, /* Run it once to incorporate the log. */ + RUN_ONCE, /* Run until the current client stops. */ + TIMEOUT, /* Run until a timeout occurs. */ + PERMANENT, /* Run until it is externally terminated. */ + DEFAULTMODE = TIMEOUT /* The default mode, must come last */ +} start_mode_t; + +typedef struct pkgcmd { + int cmd; + char buf[1]; +} pkgcmd_t; + +typedef struct pkgfilter { + int cmd; + int len; + char buf[1]; +} pkgfilter_t; + /* * Virtual File Protocol definitions */ @@ -428,8 +480,7 @@ extern void set_passphrase_prompt(char *); extern void set_passphrase_passarg(char *); extern int pkg_passphrase_cb(char *, int, int, void *); -extern int srchcfile(struct cfent *ept, char *path, VFP_T *vfp, - VFP_T *vfpout); +extern int srchcfile(struct cfent *ept, char *path, PKGserver server); extern struct group *cgrgid(gid_t gid); extern struct group *cgrnam(char *nam); extern struct passwd *cpwnam(char *nam); @@ -518,6 +569,25 @@ extern int vfpWriteToFile(VFP_T *a_vfp, char *a_path); boolean_t enable_local_fs(void); boolean_t restore_local_fs(void); +/* pkgserv.c */ +extern PKGserver pkgopenserver(const char *, const char *, boolean_t); +extern void pkgcloseserver(PKGserver); +extern int pkgcmd(PKGserver, void *, size_t, char **, size_t *, + int *); +extern boolean_t pkgsync_needed(const char *, const char *, boolean_t); +extern int pkgsync(const char *, const char *, boolean_t); +extern int pkgservercommitfile(VFP_T *, PKGserver); +extern int pkgopenfilter(PKGserver server, const char *pkginst); +extern void pkgclosefilter(PKGserver); +extern char *pkggetentry(PKGserver, int *, int *); +extern char *pkggetentry_named(PKGserver, const char *, int *, + int *); +extern void pkgserversetmode(start_mode_t); +extern start_mode_t pkgservergetmode(void); +extern start_mode_t pkgparsemode(const char *); +extern char *pkgmodeargument(start_mode_t); + + #else /* __STDC__ */ extern FILE *epopen(); diff --git a/usr/src/lib/libpkg/common/pkgserv.c b/usr/src/lib/libpkg/common/pkgserv.c new file mode 100644 index 0000000000..729f3c02a8 --- /dev/null +++ b/usr/src/lib/libpkg/common/pkgserv.c @@ -0,0 +1,603 @@ +/* + * 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 + * or http://www.opensolaris.org/os/licensing. + * 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. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PKGADD_MAX (512 * 1024) + +#define SADM_DIR "/var/sadm/install" + +#define PKGSERV_PATH "/usr/sadm/install/bin/pkgserv" + +#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" + +struct pkg_server { + FILE *fp; + char *curbuf; + int buflen; + int door; + boolean_t onetime; +}; + +static PKGserver current_server; + +static start_mode_t defmode = INVALID; +static boolean_t registered = B_FALSE; +static pid_t master_pid = -1; + +static void +pkgfilename(char path[PATH_MAX], const char *root, const char *sadmdir, + const char *file) +{ + if (snprintf(path, PATH_MAX, "%s%s/%s", root == NULL ? "" : root, + sadmdir == NULL ? SADM_DIR : sadmdir, file) >= PATH_MAX) { + progerr(gettext(ERR_PATH_TOO_BIG)); + exit(99); + } +} + +static void +pkgexit_close(void) +{ + if (current_server != NULL) + pkgcloseserver(current_server); +} + +static PKGserver +pkgopenserver_i(const char *root, const char *sadmdir, boolean_t readonly, + start_mode_t mode) +{ + PKGserver server; + struct door_info di; + pid_t pid; + int stat; + int first = B_TRUE; + char *cmd[16]; + int args; + char pkgdoor[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; + + (void) strcpy(pkgdoor, "/tmp/pkgdoor.XXXXXX"); + if ((fd = mkstemp(pkgdoor)) < 0) { + progerr(gettext(ERR_OPEN_DOOR)); + return (NULL); + } + (void) close(fd); + } else { + pkgfilename(pkgdoor, root, sadmdir, PKGDOOR); + } + + server = malloc(sizeof (*server)); + + if (server == NULL) + goto return_null; + + server->fp = NULL; + server->onetime = readonly; + +openserver: + server->door = open(pkgdoor, O_RDWR); + + if (server->door >= 0) { + if (door_info(server->door, &di) == 0 && di.di_target >= 0) { + pkgcmd_t n; + n.cmd = PKG_NOP; + server->buflen = 1024; + server->curbuf = malloc(1024); + if (server->curbuf == NULL || + pkgcmd(server, &n, sizeof (n), NULL, NULL, NULL)) { + pkgcloseserver(server); + return (NULL); + } + return (current_server = server); + } + + (void) close(server->door); + } + + if (!first || mode == NEVER) + goto return_null; + + first = B_FALSE; + + args = 0; + cmd[args++] = strrchr(PKGSERV_PATH, '/') + 1; + if (root != NULL && strcmp(root, "/") != 0) { + cmd[args++] = "-R"; + cmd[args++] = (char *)root; + } + if (sadmdir != NULL && strcmp(sadmdir, SADM_DIR) != 0) { + cmd[args++] = "-d"; + cmd[args++] = (char *)sadmdir; + } + if (readonly) { + cmd[args++] = "-r"; + cmd[args++] = pkgdoor; + } + prog = get_prog_name(); + if (prog != NULL) { + cmd[args++] = "-N"; + cmd[args++] = prog; + } + + switch (mode) { + case FLUSH_LOG: + cmd[args++] = "-e"; + break; + case RUN_ONCE: + cmd[args++] = "-o"; + break; + case PERMANENT: + cmd[args++] = "-p"; + break; + default: + break; + } + + if (master_pid != -1) { + cmd[args++] = "-P"; + (void) snprintf(pidbuf, sizeof (pidbuf), "%d", master_pid); + cmd[args++] = pidbuf; + } + cmd[args++] = NULL; + assert(args <= sizeof (cmd)/sizeof (char *)); + + if (posix_spawn(&pid, PKGSERV_PATH, NULL, NULL, cmd, environ) == 0) { + server->onetime |= mode == RUN_ONCE; + while (wait4(pid, &stat, 0, NULL) != -1) { + if (WIFEXITED(stat)) { + int s = WEXITSTATUS(stat); + if (s == 0 || s == 1) + if (mode == FLUSH_LOG) + goto return_null; + else + goto openserver; + if (s == 2) + goto return_null; + break; + } else if (WIFSIGNALED(stat)) { + break; + } + } + } + + progerr(gettext(ERR_START_SERVER), strerror(errno)); + +return_null: + if (readonly) + (void) unlink(pkgdoor); + free(server); + return (NULL); +} + +PKGserver +pkgopenserver(const char *root, const char *sadmdir, boolean_t ro) +{ + return (pkgopenserver_i(root, sadmdir, ro, pkgservergetmode())); +} + +start_mode_t +pkgparsemode(const char *mode) +{ + if (strcasecmp(mode, MODE_PERMANENT) == 0) { + return (PERMANENT); + } else if (strncasecmp(mode, MODE_TIMEOUT, + sizeof (MODE_TIMEOUT) - 1) == 0) { + const char *pidstr = mode + sizeof (MODE_TIMEOUT) - 1; + if (pidstr[0] != '\0') { + master_pid = atoi(pidstr); + if (master_pid <= 1 || kill(master_pid, 0) != 0) + master_pid = -1; + } + + return (TIMEOUT); + } else if (strcasecmp(mode, MODE_RUN_ONCE) == 0) { + return (RUN_ONCE); + } else { + progerr(gettext("invalid pkgserver mode: %s"), mode); + exit(99); + /*NOTREACHED*/ + } +} + +char * +pkgmodeargument(start_mode_t mode) +{ + static char timebuf[sizeof (PKGSERV_MODE) + sizeof (MODE_TIMEOUT) + 10]; + + switch (mode) { + case PERMANENT: + return (PKGSERV_MODE MODE_PERMANENT); + case TIMEOUT: + (void) snprintf(timebuf, sizeof (timebuf), + PKGSERV_MODE MODE_TIMEOUT "%d", + (master_pid > 1 && kill(master_pid, 0) == 0) ? master_pid : + getpid()); + return (timebuf); + case RUN_ONCE: + return (PKGSERV_MODE MODE_RUN_ONCE); + } + progerr(gettext("Bad pkgserv mode: %d"), (int)mode); + exit(99); +} + +void +pkgserversetmode(start_mode_t mode) +{ + if (mode == DEFAULTMODE || mode == INVALID) { + char *var = getenv(SUNW_PKG_SERVERMODE); + + if (var != NULL) + defmode = pkgparsemode(var); + else + defmode = DEFAULTMODE; + } else { + defmode = mode; + } +} + +start_mode_t +pkgservergetmode(void) +{ + if (defmode == INVALID) + pkgserversetmode(DEFAULTMODE); + return (defmode); +} + +void +pkgcloseserver(PKGserver server) +{ + + if (server->fp != NULL) + (void) fclose(server->fp); + free(server->curbuf); + if (server->onetime) { + pkgcmd_t cmd; + cmd.cmd = PKG_EXIT; + (void) pkgcmd(server, &cmd, sizeof (cmd), NULL, NULL, NULL); + } + (void) close(server->door); + if (server == current_server) + current_server = NULL; + free(server); +} + +int +pkgcmd(PKGserver srv, void *cmd, size_t len, char **result, size_t *rlen, + int *fd) +{ + door_arg_t da; + + da.data_ptr = cmd; + da.data_size = len; + da.desc_ptr = NULL; + da.desc_num = 0; + da.rbuf = result == NULL ? NULL : *result; + da.rsize = rlen == NULL ? 0 : *rlen; + + if (door_call(srv->door, &da) != 0) { + if (((pkgcmd_t *)cmd)->cmd == PKG_EXIT && errno == EINTR) + return (0); + return (-1); + } + + if (da.desc_ptr != NULL) { + int i = 0; + if (fd != NULL) + *fd = da.desc_ptr[i++].d_data.d_desc.d_descriptor; + for (; i < da.desc_num; i++) + (void) close(da.desc_ptr[i].d_data.d_desc.d_descriptor); + } + /* Error return */ + if (da.data_size == sizeof (int)) { + int x = *(int *)da.data_ptr; + if (x != 0) { + if (result == NULL || da.rbuf != *result) + (void) munmap(da.rbuf, da.rsize); + return (x); + } + } + + /* Other result */ + if (result != NULL) { + /* Make sure that the result is at the start of the buffer. */ + if (da.data_ptr != NULL && da.rbuf != da.data_ptr) + (void) memmove(da.rbuf, da.data_ptr, da.data_size); + *result = da.rbuf; + *rlen = da.data_size; + } else if (da.rbuf != NULL) { + (void) munmap(da.rbuf, da.rsize); + } + 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. + */ + +boolean_t +pkgsync_needed(const char *root, const char *sadmdir, boolean_t want_quit) +{ + struct stat pbuf; + char pkgfile[PATH_MAX]; + boolean_t sync_needed, running; + int fd; + struct door_info di; + + pkgfilename(pkgfile, root, sadmdir, PKGLOG); + + sync_needed = stat(pkgfile, &pbuf) == 0 && pbuf.st_size > 0; + + if (!sync_needed && !want_quit) + return (B_FALSE); + + pkgfilename(pkgfile, root, sadmdir, PKGDOOR); + + /* sync_needed == B_TRUE || want_quit == B_TRUE */ + running = B_FALSE; + + fd = open(pkgfile, O_RDWR); + + if (fd >= 0) { + if (door_info(fd, &di) == 0) { + /* It's mounted, so the server is likely there */ + running = B_TRUE; + } + (void) close(fd); + } + return (running || sync_needed); +} + +int +pkgsync(const char *root, const char *sadmdir, boolean_t force_quit) +{ + void *server; + pkgcmd_t cmd; + + /* No need to write contents file; don't start if not running */ + if (!pkgsync_needed(root, sadmdir, force_quit)) + return (0); + + server = pkgopenserver_i(root, sadmdir, B_FALSE, FLUSH_LOG); + /* + * We're assuming that it started the server and exited immediately. + * If that didn't work, there's nothing we can do. + */ + if (server == NULL) + return (0); + + cmd.cmd = force_quit ? PKG_EXIT : PKG_DUMP; + + (void) pkgcmd(server, &cmd, sizeof (cmd), NULL, NULL, NULL); + (void) pkgcloseserver(server); + return (0); +} + +int +pkgservercommitfile(VFP_T *a_vfp, PKGserver server) +{ + size_t len = vfpGetModifiedLen(a_vfp); + ssize_t rem = len; + size_t off; + pkgfilter_t *pcmd; + char *map = a_vfp->_vfpStart; + + if (len < PKGADD_MAX) + pcmd = alloca(sizeof (*pcmd) + len); + else + pcmd = alloca(sizeof (*pcmd) + PKGADD_MAX); + + + off = 0; + pcmd->cmd = PKG_ADDLINES; + while (rem > 0) { + char *p = map + off; + len = rem; + + if (len >= PKGADD_MAX) { + len = PKGADD_MAX - 1; + while (p[len] != '\n' && len > 0) + len--; + if (p[len] != '\n') + return (-1); + len++; + } + (void) memcpy(&pcmd->buf[0], p, len); + pcmd->len = len; + + if (pkgcmd(server, pcmd, sizeof (*pcmd) + len - 1, + NULL, NULL, NULL) != 0) { + return (-1); + } + rem -= len; + off += len; + } + pcmd->len = 0; + pcmd->cmd = PKG_PKGSYNC; + if (pkgcmd(server, pcmd, sizeof (*pcmd), NULL, NULL, NULL) != 0) + return (-1); + + /* Mark it unmodified. */ + vfpTruncate(a_vfp); + (void) vfpClearModified(a_vfp); + + return (0); +} + +int +pkgopenfilter(PKGserver server, const char *filt) +{ + int fd; + pkgfilter_t *pfcmd; + int clen = filt == NULL ? 0 : strlen(filt); + int len = sizeof (*pfcmd) + clen; + + pfcmd = alloca(len); + + if (server->fp != NULL) { + (void) fclose(server->fp); + server->fp = NULL; + } + + pfcmd->cmd = PKG_FILTER; + pfcmd->len = clen; + if (filt != NULL) + (void) strcpy(pfcmd->buf, filt); + + fd = -1; + + if (pkgcmd(server, pfcmd, len, NULL, NULL, &fd) != 0 || fd == -1) { + progerr(gettext(ERR_START_FILTER)); + return (-1); + } + (void) fcntl(fd, F_SETFD, FD_CLOEXEC); + + server->fp = fdopen(fd, "r"); + if (server->fp == NULL) { + (void) close(fd); + progerr(gettext(ERR_START_FILTER)); + return (-1); + } + return (0); +} + +void +pkgclosefilter(PKGserver server) +{ + if (server->fp != NULL) { + (void) fclose(server->fp); + server->fp = NULL; + } +} + +/* + * Report the next entry from the contents file. + */ +char * +pkggetentry(PKGserver server, int *len, int *pathlen) +{ + int num[2]; + + if (server->fp == NULL) + return (NULL); + + if (feof(server->fp) || ferror(server->fp)) + return (NULL); + + if (fread(num, sizeof (int), 2, server->fp) != 2) + return (NULL); + + if (num[0] > server->buflen) { + free(server->curbuf); + server->buflen = num[0]; + server->curbuf = malloc(server->buflen); + if (server->curbuf == NULL) + return (NULL); + } + if (fread(server->curbuf, 1, num[0], server->fp) != num[0]) + return (NULL); + + *len = num[0]; + *pathlen = num[1]; + + return (server->curbuf); +} + +char * +pkggetentry_named(PKGserver server, const char *path, int *len, int *pathlen) +{ + int plen = strlen(path); + pkgfilter_t *pcmd = alloca(sizeof (*pcmd) + plen); + char *result; + unsigned int rlen; + + pcmd->cmd = PKG_FINDFILE; + *pathlen = pcmd->len = plen; + (void) memcpy(pcmd->buf, path, pcmd->len + 1); + + result = server->curbuf; + rlen = server->buflen; + + if (pkgcmd(server, pcmd, sizeof (*pcmd) + pcmd->len, + &result, &rlen, NULL) != 0) { + return (NULL); + } + if (rlen == 0) + return (NULL); + + /* Result too big */ + if (result != server->curbuf) { + free(server->curbuf); + server->buflen = rlen; + server->curbuf = malloc(server->buflen); + if (server->curbuf == NULL) + return (NULL); + (void) memcpy(server->curbuf, result, rlen); + (void) munmap(result, rlen); + } + *len = rlen; + + return (server->curbuf); +} diff --git a/usr/src/lib/libpkg/common/srchcfile.c b/usr/src/lib/libpkg/common/srchcfile.c index dd24a855cd..bacfc5c622 100644 --- a/usr/src/lib/libpkg/common/srchcfile.c +++ b/usr/src/lib/libpkg/common/srchcfile.c @@ -27,8 +27,6 @@ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ - - #include #include #include @@ -46,7 +44,6 @@ * Forward declarations */ -static void findend(char **cp); static int getend(char **cp); static int getstr(char **cp, int n, char *str, int separator[]); @@ -66,30 +63,9 @@ static int decisionTableInit = 0; * These arrays must be indexable by an unsigned char. */ -static int ISPKGPATHSEP[UCHAR_MAX+1]; static int ISWORDSEP[UCHAR_MAX+1]; static int ISPKGNAMESEP[UCHAR_MAX+1]; -/* - * Name: WRITEDATA - * Description: write out data to VFP_T given start and end pointers - * Arguments: VFP - (VFP_T *) - [RO, *RW] - * Contents file VFP to narrow search on - * FIRSTPOS - (char *) - [RO, *RO] - * Pointer to first byte to write out - * LASTPOS - (char *) - [RO, *RO] - * Pointer to last byte to write out - */ - -#define WRITEDATA(VFP, FIRSTPOS, LASTPOS) \ - { \ - ssize_t XXlenXX; \ - /* compute number of bytes skipped */ \ - XXlenXX = (ptrdiff_t)(LASTPOS) - (ptrdiff_t)(FIRSTPOS); \ - /* write the bytes out */ \ - vfpPutBytes((VFP), (FIRSTPOS), XXlenXX); \ - } - /* * Name: COPYPATH * Description: copy path limiting size to destination capacity @@ -111,214 +87,6 @@ static int ISPKGNAMESEP[UCHAR_MAX+1]; (DEST)[(LEN)] = '\0'; \ } -/* - * Name: narrowSearch - * Description: narrow the search location for a specified path - * The contents and package map files are always sorted by path. - * This function is given a target path to search for given the - * current location in a contents file. It is assured that the - * target path has not been searched for yet in the contents file - * so the current location in the contents file is guaranteed to - * be less than the location of the target path (if present). - * Given this employ a binary search to speed up the search for - * the path nearest to a specified target path. - * Arguments: a_vfp - (VFP_T *) - [RO, *RW] - * Contents file VFP to narrow search on - * a_path - (char *) - [RO, *RO] - * Pointer to path to search for - * a_pathLen - (size_t) - [RO] - * Length of string (a_path) - * Returns: char * - pointer to first byte of entry in contents file that - * is guaranteed to be the closest match to the specified - * a_path without being "greater than" the path. - * == (char *)NULL if no entry found - */ - -static char * -narrowSearch(VFP_T *a_vfp, char *a_path, size_t a_pathLen) -{ - char *phigh; - char *plow; - char *pmid; - int n; - size_t plen; - - /* if no path to compare, start at beginning */ - - if ((a_path == (char *)NULL) || (*a_path == '\0')) { - return ((char *)NULL); - } - - /* if the contents file is empty, resort to sequential search */ - - if (vfpGetBytesRemaining(a_vfp) <= 1) { - return ((char *)NULL); - } - - /* - * test against first path - if the path specified is less than the - * first path in the contents file, then the path can be inserted - * before the first entry in the contents file. - */ - - /* locate start of first line */ - - plow = vfpGetCurrCharPtr(a_vfp); - pmid = plow; - - /* if first path not absolute, resort to sequential search */ - - if (*pmid != '/') { - return ((char *)NULL); - } - - /* find end of path */ - - while (ISPKGPATHSEP[(int)*pmid] == 0) { - pmid++; - } - - /* determine length of path */ - - plen = (ptrdiff_t)pmid - (ptrdiff_t)plow; - - /* compare target path with current path */ - - n = strncmp(a_path, plow, plen); - if (n == 0) { - /* if lengths same exact match return position found */ - if (a_pathLen == plen) { - return (plow); - } - /* not exact match - a_path > pm */ - n = a_pathLen; - } - - /* return if target is less than or equal to first entry */ - - if (n <= 0) { - return (plow); - } - - /* - * test against last path - if the path specified is greater than the - * last path in the contents file, then the path can be appended after - * the last entry in the contents file. - */ - - /* locate start of last line */ - - plow = vfpGetCurrCharPtr(a_vfp); - pmid = vfpGetLastCharPtr(a_vfp); - - while ((pmid > plow) && (!((pmid[0] == '/') && (pmid[-1] == '\n')))) { - pmid--; - } - - /* if absolute path, do comparison */ - - if ((pmid > plow) && (*pmid == '/')) { - plow = pmid; - - /* find end of path */ - - while (ISPKGPATHSEP[(int)*pmid] == 0) { - pmid++; - } - - /* determine length of path */ - - plen = (ptrdiff_t)pmid - (ptrdiff_t)plow; - - /* compare target path with current path */ - - n = strncmp(a_path, plow, plen); - if (n == 0) { - /* if lengths same exact match return position found */ - if (a_pathLen == plen) { - return (plow); - } - /* not exact match - a_path > pm */ - n = a_pathLen; - } - - /* return if target is greater than or equal to entry */ - - if (n >= 0) { - return (plow); - } - } - /* - * firstPath < targetpath < lastPath: - * binary search looking for closest "less than" match - */ - - plow = vfpGetCurrCharPtr(a_vfp); - phigh = vfpGetLastCharPtr(a_vfp); - - for (;;) { - char *pm; - - /* determine number of bytes left in search area */ - - plen = (ptrdiff_t)phigh - (ptrdiff_t)plow; - - /* calculate mid point between current low and high points */ - - pmid = plow + (plen >> 1); - - /* backup and find first "\n/" -or- start of buffer */ - - while ((pmid > plow) && - (!((pmid[0] == '/') && (pmid[-1] == '\n')))) { - pmid--; - } - - /* return lowest line found if current line not past that */ - - if (pmid <= plow) { - return (plow); - } - - /* remember start of this line */ - - pm = pmid; - - /* find end of path */ - - while (ISPKGPATHSEP[(int)*pmid] == 0) { - pmid++; - } - - /* determine length of path */ - - plen = (ptrdiff_t)pmid - (ptrdiff_t)pm; - - /* compare target path with current path */ - - n = strncmp(a_path, pm, plen); - - if (n == 0) { - /* if lengths same exact match return position found */ - if (a_pathLen == plen) { - return (pm); - } - /* not exact match - a_path > pm */ - n = a_pathLen; - } - - - /* not exact match - determine which watermark to split */ - - if (n > 0) { /* a_path > pm */ - plow = pm; - } else { /* a_path < pm */ - phigh = pm; - } - } - /*NOTREACHED*/ -} - /* * Name: srchcfile * Description: search contents file looking for closest match to entry, @@ -329,34 +97,20 @@ narrowSearch(VFP_T *a_vfp, char *a_path, size_t a_pathLen) * - path to search for in contents file * - If path is "*", then the next entry is returned; * the next entry always matches this path - * - If the path is (char *)NULL or "", then all remaining - * entries are processed and copied out to the - * file specified by cfTmpVFp - * cfVfp - (VFP_T *) - [RO, *RW] - * - VFP_T open on contents file to search - * cfTmpVfp - (VFP_T *) - [RO, *RW] - * - VFP_T open on temporary contents file to populate + * PKGserver + * - our door to the database server. + * * Returns: int * < 0 - error occurred * - Use getErrstr to retrieve character-string describing * the reason for failure * == 0 - no match found * - specified path not in the contents file - * - all contents of cfVfp copied to cfTmpVfp - * - current character of cfVfp is at end of file * == 1 - exact match found * - specified path found in contents file - * - contents of cfVfp up to entry found copied to cfTmpVfp - * - current character of cfVfp is first character of - * entry found * - this value is always returned if path is "*" and the - * next entry is returned - -1 is returned when no more + * next entry is returned - 0 is returned when no more * entries are left to process - * == 2 - entry found which is GREATER than path specified - * - specified path would fit BEFORE entry found - * - contents of cfVfp up to entry found copied to cfTmpVfp - * - current character of cfVfp is first character of - * entry found * Side Effects: * - The ept structure supplied is filled in with a description of * the item that caused the search to terminate, except in the @@ -368,23 +122,19 @@ narrowSearch(VFP_T *a_vfp, char *a_path, size_t a_pathLen) */ int -srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) +srchcfile(struct cfent *ept, char *path, PKGserver server) { - char *cpath_start = (char *)NULL; - char *firstPos = vfpGetCurrCharPtr(cfVfp); - char *lastPos = NULL; - char *pos; + char *cpath_start = NULL; char classname[CLSSIZ+1]; char pkgname[PKGSIZ+1]; int anypath = 0; int c; - int dataSkipped = 0; - int n; - int rdpath; - size_t cpath_len = 0; - size_t pathLength; + int cpath_len = 0; struct pinfo *lastpinfo; struct pinfo *pinfo; + char *p; + char *curbuf; + int linelen; /* includes NUL */ /* * this code does not use nested subroutines because execution time @@ -394,7 +144,6 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) /* initialize local variables */ setErrstr(NULL); /* no error message currently cached */ - pathLength = (path == (char *)NULL ? 0 : strlen(path)); lpath[0] = '\0'; lpath[sizeof (lpath)-1] = '\0'; @@ -430,17 +179,6 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) * scan stops on first byte found that is set to '1' below */ - /* - * Separators for path names, normal space and = - * for linked filenames - */ - bzero(ISPKGPATHSEP, sizeof (ISPKGPATHSEP)); - ISPKGPATHSEP['='] = 1; /* = */ - ISPKGPATHSEP[' '] = 1; /* space */ - ISPKGPATHSEP['\t'] = 1; /* horizontal-tab */ - ISPKGPATHSEP['\n'] = 1; /* new-line */ - ISPKGPATHSEP['\0'] = 1; /* NULL character */ - /* * Separators for normal words */ @@ -465,16 +203,10 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) decisionTableInit = 1; } - /* if no bytes in contents file, return 0 */ - - if (vfpGetBytesRemaining(cfVfp) <= 1) { - return (0); - } - /* if the path to scan for is empty, act like no path was specified */ - if ((path != (char *)NULL) && (*path == '\0')) { - path = (char *)NULL; + if ((path != NULL) && (*path == '\0')) { + path = NULL; } /* @@ -482,7 +214,7 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) * we encounter as a match, otherwise we return an error */ - if ((path != (char *)NULL) && (path[0] != '/')) { + if ((path != NULL) && (path[0] != '/')) { if (strcmp(path, "*") != 0) { setErrstr(pkg_gt(ERR_ILLEGAL_SEARCH_PATH)); return (-1); @@ -492,497 +224,100 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) /* attempt to narrow down the search for the specified path */ - if (anypath == 0) { - char *np; - - np = narrowSearch(cfVfp, path, pathLength); - if (np != (char *)NULL) { - dataSkipped = 1; - lastPos = np; - vfpSetCurrCharPtr(cfVfp, np); - } - } + if (anypath == 0 && path == NULL) + return (0); - /* - * If the path to search for in the source contents file is NULL, then - * this is a request to scan to the end of the source contents file. If - * there is a temporary contents file to copy entries to, all that needs - * to be done is to copy the data remaining from the current location in - * the source contents file to the end of the temporary contents file. - * if there is no temporary contents file to copy to, then all that - * needs to be done is to seek to the end of the source contents file. - */ + /* determine first character of the next entry */ + if (anypath == 0) + curbuf = pkggetentry_named(server, path, &linelen, &cpath_len); + else + curbuf = pkggetentry(server, &linelen, &cpath_len); - if ((anypath == 0) && (path == (char *)NULL)) { - if (cfTmpVfp != (VFP_T *)NULL) { - if (vfpGetBytesRemaining(cfVfp) > 0) { - WRITEDATA(cfTmpVfp, firstPos, - vfpGetLastCharPtr(cfVfp)+1); - } - *vfpGetLastCharPtr(cfTmpVfp) = '\0'; - } - vfpSeekToEnd(cfVfp); + if (curbuf == NULL) return (0); - } /* - * ********************************************************************* - * main loop processing entries from the contents file looking for - * the specified path - * ********************************************************************* + * current entry DOES start with absolute path + * set ept->path to point to lpath + * set cpath_start/cpath_len to point to the file name */ - for (;;) { - char *p; - - /* not reading old style entry */ - - rdpath = 0; - - /* determine first character of the next entry */ - - if (vfpGetBytesRemaining(cfVfp) <= 0) { - /* no bytes in contents file current char is NULL */ - - c = '\0'; - } else { - /* grab path from first entry */ - - c = vfpGetcNoInc(cfVfp); - } - - /* save current position in file */ - - pos = vfpGetCurrCharPtr(cfVfp); - - /* - * ============================================================= - * at the first character of the next entry in the contents file - * if not absolute path check for exceptions and old style entry - * --> if end of contents file write out skipped data and return - * --> if comment character skip to end of line and restart loop - * --> else process "old style entry: ftype class path" - * ============================================================= - */ - - if (c != '/') { - /* if NULL character then end of contents file found */ - - if (c == '\0') { - /* write out skipped data before returning */ - if (dataSkipped && - (cfTmpVfp != (VFP_T *)NULL)) { - WRITEDATA(cfTmpVfp, firstPos, lastPos); - *vfpGetLastCharPtr(cfTmpVfp) = '\0'; - } - - return (0); /* no more entries */ - } - - /* ignore lines that begin with #, : or a "space" */ - - if ((isspace(c) != 0) || (c == '#') || (c == ':')) { - /* line is a comment */ - findend(&vfpGetCurrCharPtr(cfVfp)); - continue; - } - - /* - * old style entry - format is: - * ftype class path - * set ept->ftype to the type - * set ept->class to the class - * set ept->path to point to lpath - * set cpath_start/cpath_len to point to the file name - * set rdpath to '1' to indicate old style entry parsed - */ - - while (isspace((c = vfpGetc(cfVfp)))) - ; - - switch (c) { - case '?': case 'f': case 'v': case 'e': case 'l': - case 's': case 'p': case 'c': case 'b': case 'd': - case 'x': - /* save ftype */ - ept->ftype = (char)c; - - /* save class */ - if (getstr(&vfpGetCurrCharPtr(cfVfp), CLSSIZ, - ept->pkg_class, ISWORDSEP)) { - setErrstr(ERR_CANNOT_READ_CLASS_TOKEN); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - } - - /* - * locate file name up to "=", set cpath_start - * and cpath_len to point to the file name - */ - cpath_start = vfpGetCurrCharPtr(cfVfp); - p = vfpGetCurrCharPtr(cfVfp); - - /* - * skip past all bytes until first '= \t\n\0': - */ - while (ISPKGPATHSEP[(int)*p] == 0) { - p++; - } - - cpath_len = vfpGetCurrPtrDelta(cfVfp, p); - - /* - * if the path is zero bytes, line is corrupted - */ - - if (cpath_len < 1) { - setErrstr(ERR_CANNOT_READ_PATHNAME_FLD); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - } - - vfpIncCurrPtrBy(cfVfp, cpath_len); - - /* set path to point to local path cache */ - ept->path = lpath; - - /* set flag indicating path already parsed */ - rdpath = 1; - break; - - case '\0': - /* end of line before new-line seen */ - vfpDecCurrPtr(cfVfp); - setErrstr(ERR_INCOMPLETE_ENTRY); - return (-1); - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - /* volume number seen */ - setErrstr(ERR_VOLUMENO_UNEXPECTED); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - - case 'i': - /* type i files are not cataloged */ - setErrstr(ERR_FTYPE_I_UNEXPECTED); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - - default: - /* unknown ftype */ - setErrstr(ERR_UNKNOWN_FTYPE); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - } - } else { - /* - * current entry DOES start with absolute path - * set ept->path to point to lpath - * set cpath_start/cpath_len to point to the file name - */ - /* copy first token into path element of passed structure */ - - cpath_start = vfpGetCurrCharPtr(cfVfp); - - p = cpath_start; - - /* - * skip past all bytes until first from '= \t\n\0': - */ - - while (ISPKGPATHSEP[(int)*p] == 0) { - p++; - } - - cpath_len = vfpGetCurrPtrDelta(cfVfp, p); - - vfpIncCurrPtrBy(cfVfp, cpath_len); - - if (vfpGetcNoInc(cfVfp) == '\0') { - setErrstr(ERR_INCOMPLETE_ENTRY); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - } - - ept->path = lpath; - } - - /* - * ============================================================= - * if absolute path then the path is collected and we are at the - * first byte following the absolute path name; - * if not an absolute path then an old style entry, ept has been - * filled with the type and class and path name. - * determine if we have read the pathname which identifies - * the entry we are searching for - * ============================================================= - */ - - if (anypath != 0) { - n = 0; /* next entry is "equal to" */ - } else if (path == (char *)NULL) { - n = 1; /* next entry is "greater than" */ - } else { - n = strncmp(path, cpath_start, cpath_len); - if ((n == 0) && (cpath_len != pathLength)) { - n = cpath_len; - } - } + /* copy first token into path element of passed structure */ - /* get first character following the end of the path */ + cpath_start = curbuf; - c = vfpGetc(cfVfp); + p = cpath_start + cpath_len; - /* - * if an exact match, always parse out the local path - */ + ept->path = lpath; - if (n == 0) { - /* - * we want to return information about this path in - * the structure provided, so parse any local path - * and jump to code which parses rest of the input line - */ - if (c == '=') { - /* parse local path specification */ - if (getstr(&vfpGetCurrCharPtr(cfVfp), PATH_MAX, - mylocal, ISWORDSEP)) { - - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - - setErrstr(ERR_CANNOT_READ_LL_PATH); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - } - ept->ainfo.local = mylocal; - } - } - - /* - * if an exact match and processing a new style entry, read the - * remaining information from the new style entry - if this is - * an old style entry (rdpath != 0) then the existing info has - * already been processed as it exists before the pathname and - * not after like a new style entry - */ - - if (n == 0 && rdpath == 0) { - while (isspace((c = vfpGetc(cfVfp)))) - ; - - switch (c) { - case '?': case 'f': case 'v': case 'e': case 'l': - case 's': case 'p': case 'c': case 'b': case 'd': - case 'x': - /* save ftype */ - ept->ftype = (char)c; - - /* save class */ - if (getstr(&vfpGetCurrCharPtr(cfVfp), CLSSIZ, - ept->pkg_class, ISWORDSEP)) { - - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - - setErrstr(ERR_CANNOT_READ_CLASS_TOKEN); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - } - break; /* we already read the pathname */ - - case '\0': - /* end of line before new-line seen */ - vfpDecCurrPtr(cfVfp); - - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - - setErrstr(ERR_INCOMPLETE_ENTRY); - return (-1); - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - - setErrstr(ERR_VOLUMENO_UNEXPECTED); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - - case 'i': - - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - - setErrstr(ERR_FTYPE_I_UNEXPECTED); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - - default: - /* unknown ftype */ + /* copy path found to 'lpath' */ + COPYPATH(lpath, cpath_start, cpath_len); - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); + /* get first character following the end of the path */ - setErrstr(ERR_UNKNOWN_FTYPE); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - } - } + c = *p++; - /* - * if an exact match all processing is completed; break out of - * the main processing loop and finish processing this entry - * prior to returning to the caller. - */ - - if (n == 0) { - break; + /* + * we want to return information about this path in + * the structure provided, so parse any local path + * and jump to code which parses rest of the input line + */ + if (c == '=') { + /* parse local path specification */ + if (getstr(&p, PATH_MAX, mylocal, ISWORDSEP)) { + setErrstr(ERR_CANNOT_READ_LL_PATH); + return (-1); } + ept->ainfo.local = mylocal; + } - /* - * this entry is not an exact match for the path being searched - * for - if this entry is GREATER THAN the path being searched - * for then finish processing and return GREATER THAN result - * to the caller so the entry for the path being searched for - * can be added to the contents file. - */ - - if (n < 0) { - /* - * the entry we want would fit BEFORE the one we just - * read, so we need to unread what we've read by - * seeking back to the start of this entry - */ - - vfpSetCurrCharPtr(cfVfp, pos); + /* + * if an exact match and processing a new style entry, read the + * remaining information from the new style entry. + */ - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); + while (isspace((c = *p++))) + ; - /* write out any skipped data before returning */ - if (dataSkipped && (cfTmpVfp != (VFP_T *)NULL)) { - WRITEDATA(cfTmpVfp, firstPos, lastPos); - } + switch (c) { + case '?': case 'f': case 'v': case 'e': case 'l': + case 's': case 'p': case 'c': case 'b': case 'd': + case 'x': + /* save ftype */ + ept->ftype = (char)c; - return (2); /* path would insert here */ + /* save class */ + if (getstr(&p, CLSSIZ, ept->pkg_class, ISWORDSEP)) { + setErrstr(ERR_CANNOT_READ_CLASS_TOKEN); + return (-1); } + break; /* we already read the pathname */ - /* - * This entry is "LESS THAN" the specified path to search for - * need to process the next entry from the contents file. First, - * if writing to new contents file, update new contents file if - * processing old style entry; otherwise, update skipped data - * information to remember current last byte of skipped data. - */ - - if (cfTmpVfp != (VFP_T *)NULL) { - char *px; - ssize_t len; - - if (rdpath != 0) { - /* modify record: write out any skipped data */ - if (dataSkipped) { - WRITEDATA(cfTmpVfp, firstPos, lastPos); - } - - /* - * copy what we've read and the rest of this - * line onto the specified output stream - */ - vfpPutBytes(cfTmpVfp, cpath_start, cpath_len); - vfpPutc(cfTmpVfp, c); - vfpPutc(cfTmpVfp, ept->ftype); - vfpPutc(cfTmpVfp, ' '); - vfpPuts(cfTmpVfp, ept->pkg_class); - - px = strchr(vfpGetCurrCharPtr(cfVfp), '\n'); - - if (px == (char *)NULL) { - len = vfpGetBytesRemaining(cfVfp); - vfpPutBytes(cfTmpVfp, - vfpGetCurrCharPtr(cfVfp), len); - vfpPutc(cfTmpVfp, '\n'); - vfpSeekToEnd(cfVfp); - } else { - len = vfpGetCurrPtrDelta(cfVfp, px); - vfpPutBytes(cfTmpVfp, - vfpGetCurrCharPtr(cfVfp), len); - vfpIncCurrPtrBy(cfVfp, len); - } - - /* reset skiped bytes if any data skipped */ - if (dataSkipped) { - dataSkipped = 0; - lastPos = (char *)NULL; - firstPos = vfpGetCurrCharPtr(cfVfp); - } - } else { - /* skip data */ - dataSkipped = 1; - - px = strchr(vfpGetCurrCharPtr(cfVfp), '\n'); - - if (px == (char *)NULL) { - vfpSeekToEnd(cfVfp); - } else { - len = vfpGetCurrPtrDelta(cfVfp, px)+1; - vfpIncCurrPtrBy(cfVfp, len); - } - lastPos = vfpGetCurrCharPtr(cfVfp); - } - } else { - /* - * since this isn't the entry we want, just read the - * stream until we find the end of this entry and - * then start this search loop again - */ - char *px; - - px = strchr(vfpGetCurrCharPtr(cfVfp), '\n'); - - if (px == (char *)NULL) { - vfpSeekToEnd(cfVfp); + case '\0': + /* end of line before new-line seen */ + setErrstr(ERR_INCOMPLETE_ENTRY); + return (-1); - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + setErrstr(ERR_VOLUMENO_UNEXPECTED); + return (-1); - setErrstr(pkg_gt(ERR_MISSING_NEWLINE)); - findend(&vfpGetCurrCharPtr(cfVfp)); - return (-1); - } else { - ssize_t len; + case 'i': + setErrstr(ERR_FTYPE_I_UNEXPECTED); + return (-1); - len = vfpGetCurrPtrDelta(cfVfp, px)+1; - vfpIncCurrPtrBy(cfVfp, len); - } - } + default: + /* unknown ftype */ + setErrstr(ERR_UNKNOWN_FTYPE); + return (-1); } - /* - * ********************************************************************* - * end of main loop processing entries from contents file - * the loop is broken out of when an exact match for the - * path being searched for has been found and the type is one of: - * - ?fvelspcbdx - * at this point parsing is at the first character past the full path - * name on an exact match for the path being looked for - parse the - * remainder of the entries information into the ept structure. - * ********************************************************************* - */ - /* link/symbolic link must have link destination */ if (((ept->ftype == 's') || (ept->ftype == 'l')) && - (ept->ainfo.local == NULL)) { - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - + (ept->ainfo.local == NULL)) { setErrstr(ERR_NO_LINK_SOURCE_SPECIFIED); - findend(&vfpGetCurrCharPtr(cfVfp)); return (-1); } @@ -991,15 +326,9 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) if (((ept->ftype == 'c') || (ept->ftype == 'b'))) { ept->ainfo.major = BADMAJOR; ept->ainfo.minor = BADMINOR; - if (getnumvfp(&vfpGetCurrCharPtr(cfVfp), 10, - (long *)&ept->ainfo.major, BADMAJOR) || - getnumvfp(&vfpGetCurrCharPtr(cfVfp), 10, - (long *)&ept->ainfo.minor, BADMINOR)) { - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - + if (getnumvfp(&p, 10, (long *)&ept->ainfo.major, BADMAJOR) || + getnumvfp(&p, 10, (long *)&ept->ainfo.minor, BADMINOR)) { setErrstr(pkg_gt(ERR_CANNOT_READ_MM_NUMS)); - findend(&vfpGetCurrCharPtr(cfVfp)); return (-1); } } @@ -1007,21 +336,16 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) /* most types have mode, owner, group identification components */ if ((ept->ftype == 'd') || (ept->ftype == 'x') || (ept->ftype == 'c') || - (ept->ftype == 'b') || (ept->ftype == 'p') || - (ept->ftype == 'f') || (ept->ftype == 'v') || - (ept->ftype == 'e')) { + (ept->ftype == 'b') || (ept->ftype == 'p') || + (ept->ftype == 'f') || (ept->ftype == 'v') || + (ept->ftype == 'e')) { /* mode, owner, group should be here */ - if (getnumvfp(&vfpGetCurrCharPtr(cfVfp), 8, - (long *)&ept->ainfo.mode, BADMODE) || - getstr(&vfpGetCurrCharPtr(cfVfp), sizeof (ept->ainfo.owner), - ept->ainfo.owner, ISWORDSEP) || - getstr(&vfpGetCurrCharPtr(cfVfp), sizeof (ept->ainfo.group), - ept->ainfo.group, ISWORDSEP)) { - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - + if (getnumvfp(&p, 8, (long *)&ept->ainfo.mode, BADMODE) || + getstr(&p, sizeof (ept->ainfo.owner), ept->ainfo.owner, + ISWORDSEP) || + getstr(&p, sizeof (ept->ainfo.group), ept->ainfo.group, + ISWORDSEP)) { setErrstr(ERR_CANNOT_READ_MOG); - findend(&vfpGetCurrCharPtr(cfVfp)); return (-1); } } @@ -1029,19 +353,13 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) /* i/f/v/e have size, checksum, modification time components */ if ((ept->ftype == 'i') || (ept->ftype == 'f') || - (ept->ftype == 'v') || (ept->ftype == 'e')) { + (ept->ftype == 'v') || (ept->ftype == 'e')) { /* look for content description */ - if (getlnumvfp(&vfpGetCurrCharPtr(cfVfp), 10, - (fsblkcnt_t *)&ept->cinfo.size, BADCONT) || - getnumvfp(&vfpGetCurrCharPtr(cfVfp), 10, - (long *)&ept->cinfo.cksum, BADCONT) || - getnumvfp(&vfpGetCurrCharPtr(cfVfp), 10, - (long *)&ept->cinfo.modtime, BADCONT)) { - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - + if (getlnumvfp(&p, 10, (fsblkcnt_t *)&ept->cinfo.size, + BADCONT) || + getnumvfp(&p, 10, (long *)&ept->cinfo.cksum, BADCONT) || + getnumvfp(&p, 10, (long *)&ept->cinfo.modtime, BADCONT)) { setErrstr(ERR_CANNOT_READ_CONTENT_INFO); - findend(&vfpGetCurrCharPtr(cfVfp)); return (-1); } } @@ -1049,22 +367,6 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) /* i files processing is completed - return 'exact match found' */ if (ept->ftype == 'i') { - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - - if (getend(&vfpGetCurrCharPtr(cfVfp))) { - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - - setErrstr(ERR_EXTRA_TOKENS); - return (-1); - } - - /* write out any skipped data before returning */ - if (dataSkipped && (cfTmpVfp != (VFP_T *)NULL)) { - WRITEDATA(cfTmpVfp, firstPos, lastPos); - } - return (1); } @@ -1073,16 +375,11 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) */ lastpinfo = (struct pinfo *)NULL; - while ((c = getstr(&vfpGetCurrCharPtr(cfVfp), sizeof (pkgname), - pkgname, ISPKGNAMESEP)) <= 0) { + while ((c = getstr(&p, sizeof (pkgname), pkgname, ISPKGNAMESEP)) <= 0) { /* if c < 0 the string was too long to fix in the buffer */ if (c < 0) { - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - setErrstr(ERR_PACKAGE_NAME_TOO_LONG); - findend(&vfpGetCurrCharPtr(cfVfp)); return (-1); } @@ -1090,11 +387,7 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) pinfo = (struct pinfo *)calloc(1, sizeof (struct pinfo)); if (!pinfo) { - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - setErrstr(ERR_NO_MEMORY); - findend(&vfpGetCurrCharPtr(cfVfp)); return (-1); } if (!lastpinfo) { @@ -1105,31 +398,31 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) lastpinfo = pinfo; if ((pkgname[0] == '-') || (pkgname[0] == '+') || - (pkgname[0] == '*') || (pkgname[0] == '~') || - (pkgname[0] == '!') || (pkgname[0] == '%')) { + (pkgname[0] == '*') || (pkgname[0] == '~') || + (pkgname[0] == '!') || (pkgname[0] == '%')) { pinfo->status = pkgname[0]; (void) strlcpy(pinfo->pkg, pkgname+1, - sizeof (pinfo->pkg)); + sizeof (pinfo->pkg)); } else { (void) strlcpy(pinfo->pkg, pkgname, - sizeof (pinfo->pkg)); + sizeof (pinfo->pkg)); } /* pkg/[:[ftype][:class] */ - c = (vfpGetc(cfVfp)); + c = *p++; if (c == '\\') { /* get alternate ftype */ pinfo->editflag++; - c = (vfpGetc(cfVfp)); + c = *p++; } if (c == ':') { /* get special classname */ - (void) getstr(&vfpGetCurrCharPtr(cfVfp), - sizeof (classname), classname, ISWORDSEP); + (void) getstr(&p, sizeof (classname), classname, + ISWORDSEP); (void) strlcpy(pinfo->aclass, classname, - sizeof (pinfo->aclass)); - c = (vfpGetc(cfVfp)); + sizeof (pinfo->aclass)); + c = *p++; } ept->npkgs++; @@ -1142,11 +435,7 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) /* if package not separated by a space return an error */ if (!isspace(c)) { - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - setErrstr(ERR_BAD_ENTRY_END); - findend(&vfpGetCurrCharPtr(cfVfp)); return (-1); } } @@ -1155,18 +444,10 @@ srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) * parsing of the entry is complete */ - /* copy path found to 'lpath' */ - COPYPATH(lpath, cpath_start, cpath_len); - - /* write out any skipped data before returning */ - if (dataSkipped && (cfTmpVfp != (VFP_T *)NULL)) { - WRITEDATA(cfTmpVfp, firstPos, lastPos); - } - /* if not at the end of the entry, make it so */ if ((c != '\n') && (c != '\0')) { - if (getend(&vfpGetCurrCharPtr(cfVfp)) && ept->pinfo) { + if (getend(&p) && ept->pinfo) { setErrstr(ERR_EXTRA_TOKENS); return (-1); } @@ -1202,7 +483,7 @@ getstr(char **cp, int n, char *str, int separator[]) /* compute length based on delimiter found or not */ p1 = p; - while (separator[(int)*p1] == 0) { + while (separator[(int)(*(unsigned char *)p1)] == 0) { p1++; } @@ -1252,27 +533,3 @@ getend(char **cp) *cp = ++p; return (n); } - -static void -findend(char **cp) -{ - char *p1; - char *p = *cp; - - /* if at end of buffer return no more characters left */ - - if (*p == '\0') { - return; - } - - /* find the end of the line */ - - p1 = strchr(p, '\n'); - - if (p1 != (char *)NULL) { - *cp = ++p1; - return; - } - - *cp = strchr(p, '\0'); -} -- cgit v1.2.3