/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <stdio.h>
#include <fcntl.h>
#include <sys/sysmacros.h>
#include <string.h>
#include <strings.h>
#include <signal.h>
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <pkglocs.h>
#include <locale.h>
#include <libintl.h>
#include <pkglib.h>
#include "libinst.h"
#include "libadm.h"
"from <%s>"
"(block size=%d)"
"database."
"unavailable."
static int active_lock;
static char *pkgadm_dir;
static int pkgWunlock(void);
/* forward declarations */
int relslock(void);
/*ARGSUSED*/
static void
do_alarm(int n)
{
}
/*
* Point packaging to the appropriate contents file. This is primarily used
* to establish a dryrun contents file. If the malloc() doesn't work, this
* returns 99 (internal error), else 0.
*/
int
{
int status;
pkgadm_dir = get_PKGADM();
return (0);
}
return (99);
}
/*
* return if a temporary contents file already exists -
* assume it is from a prior package in this series.
*/
return (0);
}
/*
* no temporary contents file exists - create one.
*/
/*
* If there's a contents file there already, copy it
* over, otherwise initialize one. Make sure that the
* server, if running, flushes the contents file.
*/
/* create new contents file if one does not already exist */
int n;
if (n < 0) {
return (99);
}
(void) close(n);
} else {
/* contents file exists, save in pkgadm-dir */
if (status != 0) {
return (99);
}
}
return (0);
}
/*
* This function installs the database lock, opens the contents file for
* It returns 1 if successful, 0 otherwise.
*/
int
{
int n;
/* establish package administration contents directory location */
if (pkgadm_dir == NULL) {
return (0);
}
}
/* Lock the file for exclusive access */
if (!pkgWlock(1)) {
return (0);
}
(void) vfpClearModified(*r_tmpvfp);
return (1);
}
/* The error has been reported. */
return (0);
/* determine path to the primary contents file */
/*
* Check and see if there is enough space for the packaging commands
* to back up the contents file, if there is not, then do not allow
* execution to continue by failing the ocfile() call.
*/
/* Get the contents file size */
return (0);
}
/* Get the filesystem space */
return (0);
}
/* determine blocks used by the logfile */
log_blocks = 0;
else
/*
* Calculate the number of blocks we need to be able to operate on
* the contents file and the log file.
* When adding a package (map_blks > 0), we add the size of the
* pkgmap file times 1.5 as the pkgmap is a bit smaller then the
* lines added to the contents file. That data is written both to
* the new contents file and the log file (2 * 1.5 * map_blks).
* The new contents file is limited by the size of the current
* contents file and the increased log file.
* If we're removing a package, then the log might grow to the size
* of the full contents file but then the new contents file would
* be zero and so we only need to add the size of the contents file.
*/
/* Current log file */
/* Current contents file */
return (0);
}
/*
* open the temporary contents file without a path name - this causes
* the "vfp" to be opened on in-memory storage only, the size of which
* is set following a successful return - this causes the temporary
* contents file to be maintained in memory only - if no changes are
* made as the primary contents file is processed, the in memory data
* is discarded and not written to the disk.
*/
return (0);
}
/*
* set size of allocation for temporary contents file - this sets the
* size of the in-memory buffer associated with the open vfp.
* We only store the new and changed entries.
* We allocate memory depending on the size of the pkgmap; it's not
* completely right but <some value + * 1.5 * map_blks * DEV_BSIZE>
* seems fine (an install adds the size if the name of the package.)
*/
if (cdiff_alloc < 1000000)
cdiff_alloc += 1000000;
return (0);
}
return (1); /* All OK */
}
/*
* This is a simple open and lock of the contents file. It doesn't create a
* temporary contents file and it doesn't need to do any space checking.
* Returns 1 for OK and 0 for "didn't do it".
*/
int
{
if (pkgadm_dir == NULL) {
return (0);
}
}
/*
* Lock the database for exclusive access, but don't make a fuss if
* it fails (user may not be root and the .pkg.lock file may not
* exist yet).
*/
if (!pkgWlock(0)) {
if (!quiet)
}
return (0);
return (1);
}
/*
* Name: swapcfile
* Description: This function closes both the current and temporary contents
* files specified, and conditionally replaces the old transitory
* contents file with the newly updated temporary contents file.
* The "ocfile()" or "socfile()" functions must be called to re-
* open the real contents file for processing.
* Arguments: PKGserver - handle to the package database
* a_cfTmpVfp - (VFP_T **) - [RW, *RW]
* This is the VFP associated which contains all the
* modifications to be written back to the database.
* file that is being written to.
* pkginst - (char) - [RO, *RO]
* This is the name of the package being operated on;
* this is used to write the "last modified by xxx"
* comment at the end of the contents file.
* dbchg - (int) - [RO]
* == 0 - the temporary contents file has NOT been changed
* with respect to the real contents file; do not
* update the real contents file with the contents
* of the temporary contents file.
* != 0 - the temporary contetns file HAS been changed with
* respect to the real contents file; DO update the
* real contents file with the contents of the
* temporary contents file.
* Returns: int == RESULT_OK - successful
* == RESULT_WRN - successful with warnings
* == RESULT_ERR - failed with fatal errors - deserves an
* alarming message and a quit()
* NOTES: If dbchg != 0, the contents file is always updated. If dbchg == 0,
* the contents file is updated IF the data is modified indication
* is set on the contents file associated with a_cfTmpVfp.
*/
int
{
char *pe;
char *pl;
char *ps;
/* normalize pkginst so its never null */
dbchg = 0;
pkginst = "<unknown>";
}
/*
* If no changes were made to the database, checkpoint the temporary
* contents file - if this fails, then just close the file which causes
* the contents file to be reopened and reread if it is needed again
*/
(void) pkgWunlock(); /* Free the database lock. */
return (retval);
}
/*
* changes made to the current temporary contents file -
* remove any trailing comment lines in the temp contents file, then
* append updated modification info records to temp contents file
*/
/* skip past all trailing newlines and null bytes */
pe--;
}
/* remove trailing comments as long as there are lines in the file */
if (*pe != '\n') {
/* curr char is not newline: backup one byte */
} else if (*pl != '#') {
/* curr char is newline next char not comment break */
break;
} else {
/* curr char is newline next char is comment - remove */
*pl = '\0';
pe--;
}
}
/* create two update comment lines */
gettext("# Last modified by %s for %s package\n# %s"),
/* commit temporary contents file bytes to storage */
(void) pkgWunlock(); /* Free the database lock. */
return (RESULT_ERR);
}
}
/* This function releases the lock on the package database. */
int
relslock(void)
{
/*
* This closes the contents file and releases the lock.
*/
if (!pkgWunlock()) {
return (0);
}
return (1);
}
/*
* This function attempts to lock the package database. It returns 1 on
* success, 0 on failure. The positive logic verbose flag determines whether
* or not the function displays the error message upon failure.
*/
int
active_lock = 0;
/*
* If the lock file is not present, create it. The mode is set to
* allow any process to lock the database, that's because pkgchk may
* be run by a non-root user.
*/
if (lock_fd < 0) {
if (verbose)
return (0);
} else {
}
} else {
if (verbose)
return (0);
}
}
do {
retval = 0;
break;
retval = 0;
break;
retval = 0;
break;
}
} else {
active_lock = 1;
retval = 1;
break;
}
} while (retry_cnt--);
if (retval == 0)
{
if (retry_cnt == -1) {
}
(void) pkgWunlock(); /* close the lockfile. */
}
return (retval);
}
/*
* Release the lock on the package database. Returns 1 on success, 0 on
* failure.
*/
static int
pkgWunlock(void) {
if (active_lock) {
active_lock = 0;
return (0);
else
return (1);
} else
return (1);
}
/*
* This function verifies that the contents file is in place.
* returns 1 - if it exists
* returns 0 - if it does not exist
*/
int
iscfile(void)
{
}
/*
* This function verifies that the contents file is in place. If it is - no
* change. If it isn't - this creates it.
* Returns: == 0 : failure
* != 0 : success
*/
int
vcfile(void)
{
int lerrno;
int fd;
/*
* create full path to contents file
*/
"%s/contents", get_PKGADM());
/*
* Attempt to create the file - will only be successful
* if the file does not currently exist.
*/
if (fd >= 0) {
/*
* Contents file wasn't there, but is now.
*/
return (1); /* success */
}
/*
* Could not create the file - it may exist or there may be
* permissions issues - find out and act accordingly.
*/
/* success if error is 'file exists' */
return (1); /* success */
}
/* success if error is 'permission denied' but file exists */
/*
* Because O_CREAT and O_EXCL are specified in open(),
* if the contents file already exists, the open will
* fail with EACCES - determine if this is the case -
* if so return success.
*/
return (1); /* success */
}
/*
* access() failed - if because of permissions failure this
* means the contents file exists but it cannot be accessed
* or the path to the contents file cannot be accessed - in
* either case the contents file cannot be accessed.
*/
return (0); /* failure */
}
}
/*
* the contents file does not exist and it cannot be created.
*/
return (0); /* failure */
}