main.c revision 9b2055ccc67e94a8568754108452d32facb6c23e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <pkginfo.h>
#include <pkgstrct.h>
#include <pkglocs.h>
#include <locale.h>
#include <libintl.h>
#include <instzones_api.h>
#include <pkglib.h>
#include <install.h>
#include <libadm.h>
#include <libinst.h>
#include "installf.h"
#define BASEDIR "/BASEDIR/"
#define MSG_MANMOUNT "Assuming mounts were provided."
#define ERR_PKGNAME_TOO_LONG \
"The package name specified on the command line\n" \
"exceeds the maximum package name length: a package name may contain a\n" \
"maximum of <%d> characters; however, the package name specified on\n" \
"the command line contains <%d> characters, which exceeds the maximum\n" \
"package name length by <%d> characters. Please specify a package name\n" \
"that contains no more than <%d> characters."
#define ERR_DB_GET "unable to retrieve entries from the database."
#define ERR_DB_PUT "unable to update the package database."
#define ERR_ROOT_SET "Could not set install root from the environment."
#define ERR_ROOT_CMD "Command line install root contends with environment."
#define ERR_CLASSLONG "classname argument too long"
#define ERR_CLASSCHAR "bad character in classname"
#define ERR_INVAL "package instance <%s> is invalid"
#define ERR_NOTINST "package instance <%s> is not installed"
#define ERR_MERG "unable to merge contents file"
#define ERR_SORT "unable to sort contents file"
#define ERR_I_FAIL "installf did not complete successfully"
#define ERR_R_FAIL "removef did not complete successfully"
#define ERR_NOTROOT "You must be \"root\" for %s to execute properly."
#define ERR_USAGE0 "usage:\n" \
"\t%s [[-M|-A] -R host_path] [-V ...] pkginst path " \
"[path ...]\n" \
"\t%s [[-M|-A] -R host_path] [-V ...] pkginst path\n"
#define ERR_USAGE1 "usage:\n" \
"\t%s [[-M] -R host_path] [-V ...] [-c class] <pkginst> " \
"<path>\n" \
"\t%s [[-M] -R host_path] [-V ...] [-c class] <pkginst> " \
"<path> <specs>\n" \
"\t where <specs> may be defined as:\n" \
"\t\tf <mode> <owner> <group>\n" \
"\t\tv <mode> <owner> <group>\n" \
"\t\te <mode> <owner> <group>\n" \
"\t\td <mode> <owner> <group>\n" \
"\t\tx <mode> <owner> <group>\n" \
"\t\tp <mode> <owner> <group>\n" \
"\t\tc <major> <minor> <mode> <owner> <group>\n" \
"\t\tb <major> <minor> <mode> <owner> <group>\n" \
"\t\ts <path>=<srcpath>\n" \
"\t\tl <path>=<srcpath>\n" \
"\t%s [[-M] -R host_path] [-V ...] [-c class] -f pkginst\n"
#define CMD_SORT "sort +0 -1"
#define LINK 1
extern char dbst; /* libinst/pkgdbmerg.c */
char *pkginst;
char *uniTmp;
char *abi_sym_ptr;
char *ulim;
char *script;
int eptnum;
int nosetuid;
int nocnflct;
int warnflag = 0;
/* libadm/pkgparam.c */
extern void set_PKGADM(char *newpath);
extern void set_PKGLOC(char *newpath);
extern void set_limit(void);
int
{
char *tp;
char *prog;
char *pt;
char *vfstab_file = NULL;
char *temp_cl_basedir;
int c;
int dbchg;
int err;
int fflag = 0;
int map_client = 1;
int n;
int pkgrmremote = 0; /* don't remove remote files */
/* hookup signals */
/* initialize locale mechanism */
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#define TEXT_DOMAIN "SYS_TEST"
#endif /* !defined(TEXT_DOMAIN) */
(void) textdomain(TEXT_DOMAIN);
/* determine program name */
/* tell instzones interface how to access package output functions */
/* only allow root to run this program */
if (getuid() != 0) {
exit(1);
}
set_limit();
clr_ulimit();
}
/* bug id 4244631, not ABI compliant */
/* bugId 4012147 */
map_client = 0;
exit(1);
}
switch (c) {
case 'f':
fflag++;
break;
case 'c':
/* validate that classname is acceptable */
exit(1);
}
exit(1);
}
}
break;
/*
* Don't map the client filesystem onto the server's. Assume
* the mounts have been made for us.
*/
case 'M':
map_client = 0;
break;
/*
* Allow admin to establish the client filesystem using a
* vfstab-like file of stable format.
*/
case 'V':
map_client = 1;
break;
case 'A':
pkgrmremote++;
break;
case 'R': /* added for newroot option */
if (!set_inst_root(optarg)) {
exit(1);
}
break;
default:
usage();
/*NOTREACHED*/
/*
* Although usage() calls a noreturn function,
* needed to add return (1); so that main() would
* pass compilation checks. The statement below
* should never be executed.
*/
return (1);
}
}
usage();
/*NOTREACHED*/
}
/*
* Get the mount table info and store internally.
*/
exit(1);
/*
* This function defines the standard /var/... directories used later
* to construct the paths to the various databases.
*/
(void) set_PKGpaths(get_inst_root());
/*
* If this is being installed on a client whose /var filesystem is
* mounted in some odd way, remap the administrative paths to the
* real filesystem. This could be avoided by simply mounting up the
* client now; but we aren't yet to the point in the process where
* modification of the filesystem is permitted.
*/
if (is_an_inst_root()) {
int fsys_value;
if (use_srvr_map_n(fsys_value))
if (use_srvr_map_n(fsys_value))
}
/*
* get the package name and verify length is not too long
*/
usage();
/*NOTREACHED*/
}
if (n > PKGSIZ) {
PKGSIZ);
usage();
/*NOTREACHED*/
}
/*
* The following is used to setup the environment. Note that the
* variable 'BASEDIR' is only meaningful for this utility if there
* is an install root, recorded in PKG_INSTALL_ROOT. Otherwise, this
* utility can create a file or directory anywhere unfettered by
* the basedir associated with the package instance.
*/
if (INSTALF)
mkbasedir(0, get_basedir());
if (fflag) {
/* installf and removef must only have pkginst */
usage();
/*NOTREACHED*/
}
} else {
/*
* installf and removef must have at minimum
* pkginst & pathname specified on command line
*/
usage();
/*NOTREACHED*/
}
}
if (REMOVEF) {
if (classname) {
usage();
}
}
exit(1);
}
exit(1);
}
#ifdef ALLOW_EXCEPTION_PKG_LIST
/*
* *********************************************************************
* this feature is removed starting with Solaris 10 - there is no built
* in list of packages that should be run "the old way"
* *********************************************************************
*/
/* Until 2.9, set it from the execption list */
#endif
/*
* This maps the client filesystems into the server's space.
*/
if (map_client && !mount_client())
/* open the package database (contents) file */
quit(1);
}
if (fflag) {
} else {
if (INSTALF) {
quit(1);
} else {
}
if (dbchg < 0) {
quit(99);
}
}
if (dbchg) {
== RESULT_WRN) {
warnflag++;
} else if (n == RESULT_ERR) {
quit(99);
}
}
relslock();
for (n = 0; extlist[n]; n++) {
/* Skip duplicated paths */
continue;
}
/*
* Only output paths that can be deleted.
* so need to skip if the object is owned
* by a remote server and removal is not
* being forced.
*/
continue;
c = 0;
if (is_a_cl_basedir() && !is_an_inst_root()) {
/*
* A path in contents db might have
* other prefix than BASEDIR of the
* package
*/
strlen(temp_cl_basedir)) == 0) {
c = strlen(temp_cl_basedir);
sizeof (outbuf), "%s/%s\n",
get_basedir(),
} else {
sizeof (outbuf),
}
} else if (is_an_inst_root()) {
"%s/%s\n", get_inst_root(),
} else {
}
}
}
for (n = 0; extlist[n]; n++) {
}
}
}
/* LINTED: no return */
}
void
quit(int n)
{
char *prog = get_prog_name();
if (REMOVEF) {
} else {
}
}
exit(n);
}
void
usage(void)
{
char *prog = get_prog_name();
if (REMOVEF) {
} else {
}
exit(1);
}