/*
 * 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.
 */

/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */

#ifndef	_PKGLIB_H
#define	_PKGLIB_H


#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <limits.h>
#include <stdio.h>
#include <pkgdev.h>
#include <pkgstrct.h>
#include <openssl/bio.h>
#include <openssl/x509.h>
#include <netdb.h>
#include <boot_http.h>
#include "pkgerr.h"
#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
 */

/*
 * flags associated with virtual file protocol operations; note that these flags
 * may only occupy the low order 16 bits of the 32-bit unsigned flag.
 */

typedef unsigned long VFPFLAGS_T;

#define	VFP_NONE	0x00000000	/* no special flags */
#define	VFP_NEEDNOW	0x00000001	/* need memory now */
#define	VFP_SEQUENTIAL	0x00000002	/* sequential access */
#define	VFP_RANDOM	0x00000004	/* random access */
#define	VFP_NOMMAP	0x00000008	/* do not use mmap to access file */
#define	VFP_NOMALLOC	0x00000010	/* do not use malloc to buffer file */

/* virtual file protocol object */

typedef struct _vfp VFP_T;

/* structure behind the virtual file protocol object */

struct _vfp {
	FILE		*_vfpFile;	/* -> opened FILE */
	char		*_vfpCurr;	/* -> current byte to read/write */
	char		*_vfpHighWater;	/* -> last byte modified */
	char		*_vfpEnd;	/* -> last data byte */
	char		*_vfpPath;	/* -> path associated with FILE */
	char		*_vfpStart;	/* -> first data byte */
	void		*_vfpExtra;	/* undefined */
	size_t		_vfpSize;	/* size of mapped/allocated area */
	size_t		_vfpMapSize;	/* # mapped bytes */
	VFPFLAGS_T	_vfpFlags;	/* flags associated with vfp/data */
	int		_vfpOverflow;	/* non-zero if buffer write overflow */
	blkcnt_t	_vfpCkStBlocks;	/* checkpoint # blocks */
	dev_t		_vfpCkDev;	/* checkpoint device i.d. */
	ino_t		_vfpCkIno;	/* checkpoint inode # */
	off_t		_vfpCkSize;	/* checkpoint size */
	time_t		_vfpCkMtime;	/* checkpoint modification time */
};

/*
 * get highest modified byte (length) contained in vfp
 *
 * determine number of bytes to write - it will be the highest of:
 *  -- the current pointer into the file - this is updated whenever
 *	the location of the file is changed by a single byte
 *  -- the last "high water mark" - the last known location that
 *	was written to the file - updated only when the location
 *	of the file is directly changed - e.g. vfpSetCurrCharPtr,
 *	vfpTruncate, vfpRewind.
 * this reduces the "bookkeeping" that needs to be done to know
 * how many bytes to write out to the file - typically a file is
 * written sequentially so the current file pointer is sufficient
 * to determine how many bytes to write out.
 */

#define	vfpGetModifiedLen(VFP)						\
	(size_t)(((VFP)->_vfpHighWater > (VFP)->_vfpCurr) ?		\
		(((ptrdiff_t)(VFP)->_vfpHighWater -			\
				(ptrdiff_t)(VFP)->_vfpStart)) :		\
		(((ptrdiff_t)(VFP)->_vfpCurr -				\
				(ptrdiff_t)(VFP)->_vfpStart)))

/*
 * increment current pointer by specified delta
 * if the delta exceeds the buffer size, set pointer to buffer end
 */
#define	vfpIncCurrPtrBy(VFP, INC)					\
	{								\
		((VFP)->_vfpCurr) += (INC);				\
		if (((VFP)->_vfpCurr) > ((VFP)->_vfpEnd)) {		\
			(VFP)->_vfpCurr = (VFP)->_vfpEnd;		\
			(VFP)->_vfpOverflow = 1;			\
		}							\
		if ((VFP)->_vfpHighWater < (VFP)->_vfpCurr) {		\
			(VFP)->_vfpHighWater = (VFP)->_vfpCurr;		\
		}							\
	}

/* get the path associated with the vfp */
#define	vfpGetPath(VFP)		((VFP)->_vfpPath)

/* get a string from the vfp into a fixed size buffer */
#define	vfpGets(VFP, PTR, LEN)						\
	{								\
		char	*XXpXX = (PTR);					\
		size_t	XXlXX = (LEN);					\
		while ((*(VFP)->_vfpCurr != '\0') &&			\
				(*(VFP)->_vfpCurr != '\n')) {		\
			if (XXlXX > 1) {				\
				*XXpXX++ = *(VFP)->_vfpCurr;		\
				XXlXX--;				\
			}						\
			(VFP)->_vfpCurr++;				\
		}							\
		*XXpXX++ = '\0';					\
		if (*(VFP)->_vfpCurr != '\0') {				\
			(VFP)->_vfpCurr++;				\
		}							\
	}

/* get number of bytes remaining to read */
#define	vfpGetBytesRemaining(VFP)	\
	(((((VFP)->_vfpHighWater) <= ((VFP)->_vfpCurr))) ? 0 : 		\
	((((ptrdiff_t)(VFP)->_vfpHighWater)-((ptrdiff_t)(VFP)->_vfpCurr))))

/* get number of bytes remaining to write */
#define	vfpGetBytesAvailable(VFP)	\
	(((((VFP)->_vfpEnd) <= ((VFP)->_vfpCurr))) ? 0 : 		\
	((((ptrdiff_t)(VFP)->_vfpEnd)-((ptrdiff_t)(VFP)->_vfpCurr))))

/* put current character and increment to next */
#define	vfpPutc(VFP, C)							\
	{								\
		(*(VFP)->_vfpCurr) = ((char)(C));			\
		vfpIncCurrPtrBy((VFP), 1);				\
	}

/* put integer to current character and increment */
#define	vfpPutInteger(VFP, NUMBER)	vfpPutFormat((VFP), "%d", (NUMBER))

/* put long to current character and increment */
#define	vfpPutLong(VFP, NUMBER)	vfpPutFormat((VFP), "%ld", (NUMBER))

/* get current character and increment to next */
#define	vfpGetc(VFP)		(*(VFP)->_vfpCurr++)

/* get current character - do not increment */
#define	vfpGetcNoInc(VFP)	(*(VFP)->_vfpCurr)

/* get pointer to current character */
#define	vfpGetCurrCharPtr(VFP)	((VFP)->_vfpCurr)

/* increment current character pointer */
#define	vfpIncCurrPtr(VFP)	vfpIncCurrPtrBy((VFP), 1)

/* decrement current character pointer */
#define	vfpDecCurrPtr(VFP)	((VFP)->_vfpCurr--)

/* get pointer to first data byte in buffer */
#define	vfpGetFirstCharPtr(VFP)	((VFP)->_vfpStart)

/* get pointer to last data byte in buffer */
#define	vfpGetLastCharPtr(VFP)	((VFP)->_vfpHighWater)

/* set pointer to current character */
#define	vfpSetCurrCharPtr(VFP, PTR)					\
	if ((VFP)->_vfpCurr > (VFP)->_vfpHighWater) {			\
		(VFP)->_vfpHighWater = (VFP)->_vfpCurr;			\
	}								\
	((VFP)->_vfpCurr = (PTR))

/* set pointer to last data byte in buffer */
#define	vfpSetLastCharPtr(VFP, PTR)					\
	if ((PTR) >= (VFP)->_vfpStart) {				\
		(VFP)->_vfpHighWater = (PTR);				\
		if ((VFP)->_vfpCurr > (VFP)->_vfpHighWater) {		\
			(VFP)->_vfpCurr = (VFP)->_vfpHighWater;		\
		}							\
	}

/* seek to end of file - one past last data byte in file */
#define	vfpSeekToEnd(VFP)	((VFP)->_vfpCurr = ((VFP)->_vfpHighWater)+1)

/* get number of bytes between current char and specified char */
#define	vfpGetCurrPtrDelta(VFP, P)	\
	(((ptrdiff_t)(P))-((ptrdiff_t)(VFP)->_vfpCurr))

/* put string to current character and increment */
#define	vfpPuts(VFP, S)							\
	{								\
		size_t	xxLen;						\
		size_t	xxResult;					\
		xxLen = vfpGetBytesAvailable((VFP));			\
		xxResult = strlcpy(((VFP)->_vfpCurr), (S), xxLen);	\
		vfpIncCurrPtrBy((VFP), xxResult);			\
	}

/* put fixed number of bytes to current character and increment */
#define	vfpPutBytes(VFP, PTR, LEN)					\
	{								\
		size_t	xxLen;						\
		xxLen = vfpGetBytesAvailable((VFP));			\
		if (xxLen > (LEN)) {					\
			xxLen = (LEN);					\
		} else {						\
			(VFP)->_vfpOverflow = 1;			\
		}							\
		memcpy((VFP)->_vfpCurr, (PTR), (xxLen));		\
		vfpIncCurrPtrBy((VFP), (xxLen));			\
	}

/* put format one arg to current character and increment */
#define	vfpPutFormat(VFP, FORMAT, ARG)					\
	{								\
	char	xxTeMpXX[256];						\
	(void) snprintf(xxTeMpXX, sizeof (xxTeMpXX), (FORMAT), (ARG));	\
	vfpPuts((VFP), xxTeMpXX);					\
	}

struct dm_buf {
	char *text_buffer;	/* start of allocated buffer */
	int offset;		/* number of bytes into the text_buffer */
	int allocation;		/* size of buffer in bytes */
};

/* This structure is used to hold a dynamically growing string */

struct dstr {
	char *pc;
	int   len;
	int   max;
};

/* setmapmode() defines */
#define	MAPALL		0	/* resolve all variables */
#define	MAPBUILD	1	/* map only build variables */
#define	MAPINSTALL	2	/* map only install variables */
#define	MAPNONE		3	/* map no variables */

#define	NON_ABI_NAMELNGTH	33	/* 32 chars for name + 1 for NULL */

#define	BLK_SIZE	512	/* size of logical block */

/* max length for printed attributes */
#define	ATTR_MAX	80

/*
 * These three defines indicate that the prototype file contains a '?'
 * meaning do not specify this data in the pkgmap entry.
 */
#define	CURMODE		BADMODE		/* current mode has been specified */
#define	CUROWNER	BADOWNER	/* ... same for owner ... */
#define	CURGROUP	BADGROUP	/* ... and group. */

#define	WILDCARD		BADMODE >> 1
#define	DB_UNDEFINED_ENTRY	"?"

#define	DEFAULT_MODE		0755
#define	DEFAULT_MODE_FILE	0644
#define	DEFAULT_OWNER	"root"
#define	DEFAULT_GROUP	"other"

#define	INST_RELEASE "var/sadm/system/admin/INST_RELEASE"

#define	RANDOM			"/dev/urandom"
#define	BLOCK			256

#define	TERM_WIDTH		60
#define	SMALL_DIVISOR		4
#define	MED_DIVISOR		5
#define	LARGE_DIVISOR		10
#define	MED_DWNLD		(10 * 1024 * 1024) /* 10 MB */
#define	LARGE_DWNLD		(5 * MED_DWNLD) /* 50 MB */

#define	HTTP			"http://"
#define	HTTPS			"https://"

#define	PKGADD			"pkgadd"

/* Settings for network admin defaults */

#define	NET_TIMEOUT_DEFAULT 	60
#define	NET_RETRIES_DEFAULT 	3
#define	NET_TIMEOUT_MIN		1		/* 1 second */
#define	NET_TIMEOUT_MAX		(5 * 60)	/* 5 minutes */
#define	NET_RETRIES_MIN		1
#define	NET_RETRIES_MAX		10
#define	AUTH_NOCHECK		0
#define	AUTH_QUIT		1

/* package header magic tokens */
#define	HDR_PREFIX	"# PaCkAgE DaTaStReAm"
#define	HDR_SUFFIX	"# end of header"

/* name of security files */
#define	PKGSEC		"/var/sadm/security"
#define	SIGNATURE_FILENAME	"signature"

#define	GROUP	"/etc/group"
#define	PASSWD	"/etc/passwd"

/*
 * The next three mean that no mode, owner or group was specified or that the
 * one specified is invalid for some reason. Sometimes this is an error in
 * which case it is generally converted to CUR* with a warning. Other times
 * it means "look it up" by stating the existing file system object pointred
 * to in the prototype file.
 */
#define	NOMODE		(BADMODE-1)
#define	NOOWNER		"@"
#define	NOGROUP		"@"

/* string comparitor abbreviators */

#define	ci_streq(a, b)		(strcasecmp((a), (b)) == 0)
#define	ci_strneq(a, b, c)	(strncasecmp((a), (b), (c)) == 0)
#define	streq(a, b)		(strcmp((a), (b)) == 0)
#define	strneq(a, b, c)		(strncmp((a), (b), (c)) == 0)

#ifdef	__STDC__

extern FILE	*epopen(char *cmd, char *mode);
extern char	**gpkglist(char *dir, char **pkg, char **catg);
extern int	is_not_valid_length(char **category);
extern int	is_not_valid_category(char **category, char *progname);
extern int	is_same_CATEGORY(char **category, char *installed_category);
extern char **get_categories(char *catg_arg);

extern void	pkglist_cont(char *keyword);
extern char	**pkgalias(char *pkg);
extern char	*get_prog_name(void);
extern char 	*set_prog_name(char *name);
extern int	averify(int fix, char *ftype, char *path, struct ainfo *ainfo);
extern int	ckparam(char *param, char *value);
extern int	ckvolseq(char *dir, int part, int nparts);
extern int	cverify(int fix, char *ftype, char *path, struct cinfo *cinfo,
			int allow_checksum);
extern unsigned long	compute_checksum(int *r_cksumerr, char *a_path);
extern int	fverify(int fix, char *ftype, char *path, struct ainfo *ainfo,
		    struct cinfo *cinfo);
extern char	*getErrbufAddr(void);
extern int	getErrbufSize(void);
extern char	*getErrstr(void);
extern void	setErrstr(char *errstr);
extern int	devtype(char *alias, struct pkgdev *devp);
extern int	ds_totread;	/* total number of parts read */
extern int	ds_close(int pkgendflg);
extern int	ds_findpkg(char *device, char *pkg);
extern int	ds_getinfo(char *string);
extern int	ds_getpkg(char *device, int n, char *dstdir);
extern int	ds_ginit(char *device);
extern boolean_t	ds_fd_open(void);
extern int	ds_init(char *device, char **pkg, char *norewind);
extern int	BIO_ds_dump_header(PKG_ERR *, BIO *);
extern int	BIO_ds_dump(PKG_ERR *, char *, BIO *);
extern int	BIO_dump_cmd(char *cmd, BIO *bio);
extern int	ds_next(char *, char *);
extern int	ds_readbuf(char *device);
extern int	epclose(FILE *pp);
extern int	esystem(char *cmd, int ifd, int ofd);
extern int	e_ExecCmdArray(int *r_status, char **r_results,
			char *a_inputFile, char *a_cmd, char **a_args);
extern int	e_ExecCmdList(int *r_status, char **r_results,
			char *a_inputFile, char *a_cmd, ...);
extern int	gpkgmap(struct cfent *ept, FILE *fp);
extern int	gpkgmapvfp(struct cfent *ept, VFP_T *fpv);
extern void	setmapmode(int mode_no);
extern int	isFdRemote(int a_fd);
extern int	isFstypeRemote(char *a_fstype);
extern int	isPathRemote(char *a_path);
extern int	iscpio(char *path, int *iscomp);
extern int	isdir(char *path);
extern int	isfile(char *dir, char *file);
extern int	fmkdir(char *a_path, int a_mode);
extern int	pkgexecl(char *filein, char *fileout, char *uname, char *gname,
			...);
extern int	pkgexecv(char *filein, char *fileout, char *uname, char *gname,
			char *arg[]);
extern int	pkghead(char *device);
extern int	pkgmount(struct pkgdev *devp, char *pkg, int part, int nparts,
			int getvolflg);
extern int	pkgtrans(char *device1, char *device2, char **pkg,
			int options, keystore_handle_t, char *);
extern int	pkgumount(struct pkgdev *devp);
extern int	ppkgmap(struct cfent *ept, FILE *fp);
extern int	putcfile(struct cfent *ept, FILE *fp);
extern int	putcvfpfile(struct cfent *ept, VFP_T *vfp);
extern int	rrmdir(char *path);
extern void	set_memalloc_failure_func(void (*)(int));
extern void	*xmalloc(size_t size);
extern void	*xrealloc(void *ptr, size_t size);
extern char	*xstrdup(char *str);
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, PKGserver server);
extern struct	group *cgrgid(gid_t gid);
extern struct	group *cgrnam(char *nam);
extern struct	passwd *cpwnam(char *nam);
extern struct	passwd *cpwuid(uid_t uid);
extern struct	group *clgrgid(gid_t gid);
extern struct	group *clgrnam(char *nam);
extern struct	passwd *clpwnam(char *nam);
extern struct	passwd *clpwuid(uid_t uid);
extern void	basepath(char *path, char *basedir, char *ir);
extern void	canonize(char *file);
extern void	canonize_slashes(char *file);
extern void	checksum_off(void);
extern void	checksum_on(void);
extern void	cvtpath(char *path, char *copy);
extern void	ds_order(char *list[]);
extern void	ds_putinfo(char *buf);
extern void	ds_skiptoend(char *device);
extern void	ecleanup(void);
/*PRINTFLIKE1*/
extern void	logerr(char *fmt, ...);
extern int	mappath(int flag, char *path);
extern int	mapvar(int flag, char *varname);
/*PRINTFLIKE1*/
extern void	progerr(char *fmt, ...);
extern void	pkgerr(PKG_ERR *);
extern void	rpterr(void);
extern void	tputcfent(struct cfent *ept, FILE *fp);
extern void	set_nonABI_symlinks(void);
extern int	nonABI_symlinks(void);
extern void	disable_attribute_check(void);
extern int	get_disable_attribute_check(void);

/* security.c */
extern void	sec_init(void);
extern char	*get_subject_display_name(X509 *);
extern char	*get_issuer_display_name(X509 *);
extern char	*get_serial_num(X509 *);
extern char	*get_fingerprint(X509 *, const EVP_MD *);
extern int	get_cert_chain(PKG_ERR *, X509 *, STACK_OF(X509) *,
    STACK_OF(X509) *, STACK_OF(X509) **);

/* pkgstr.c */
void		pkgstrConvertUllToTimeString_r(unsigned long long a_time,
			char *a_buf, int a_bufLen);
char		*pkgstrConvertPathToBasename(char *a_path);
char		*pkgstrConvertPathToDirname(char *a_path);
char		*pkgstrDup(char *a_str);
char		*pkgstrLocatePathBasename(char *a_path);
void		pkgstrScaleNumericString(char *a_buf, unsigned long long scale);
void		pkgstrAddToken(char **a_old, char *a_new, char a_separator);
boolean_t	pkgstrContainsToken(char *a_string, char *a_token,
			char *a_separators);
void		pkgstrExpandTokens(char **a_old, char *a_string,
			char a_separator, char *a_separators);
char		*pkgstrGetToken(char *r_sep, char *a_string, int a_index,
			char *a_separators);
void		pkgstrGetToken_r(char *r_sep, char *a_string, int a_index,
			char *a_separators, char *a_buf, int a_bufLen);
unsigned long	pkgstrNumTokens(char *a_string, char *a_separators);
char		*pkgstrPrintf(char *a_format, ...);
void		pkgstrPrintf_r(char *a_buf, int a_bufLen, char *a_format, ...);
void		pkgstrRemoveToken(char **r_string, char *a_token,
			char *a_separators, int a_index);
void		pkgstrRemoveLeadingWhitespace(char **a_str);
/* vfpops.c */
extern int	vfpCheckpointFile(VFP_T **r_destVfp, VFP_T **a_vfp,
			char *a_path);
extern int	vfpCheckpointOpen(VFP_T **a_cvfp, VFP_T **r_vfp, char *a_path,
			char *a_mode, VFPFLAGS_T a_flags);
extern int	vfpClearModified(VFP_T *a_vfp);
extern int	vfpClose(VFP_T **r_vfp);
extern int	vfpGetModified(VFP_T *a_vfp);
extern int	vfpOpen(VFP_T **r_vfp, char *a_path, char *a_mode,
			VFPFLAGS_T a_flags);
extern void	vfpRewind(VFP_T *a_vfp);
extern ssize_t	vfpSafePwrite(int a_fildes, void *a_buf,
			size_t a_nbyte, off_t a_offset);
extern ssize_t	vfpSafeWrite(int a_fildes, void *a_buf, size_t a_nbyte);
extern int	vfpSetFlags(VFP_T *a_vfp, VFPFLAGS_T a_flags);
extern int	vfpSetModified(VFP_T *a_vfp);
extern int	vfpSetSize(VFP_T *a_vfp, size_t a_size);
extern void	vfpTruncate(VFP_T *a_vfp);
extern int	vfpWriteToFile(VFP_T *a_vfp, char *a_path);

/* handlelocalfs.c */
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();
extern void	pkglist_cont();
extern char	**gpkglist();
extern char	**pkgalias();
extern char	*get_prog_name();
extern char 	*set_prog_name();
extern int	averify();
extern int	ckparam();
extern int	ckvolseq();
extern int	cverify();
extern unsigned long	compute_checksum();
extern int	fverify();
extern char	*getErrbufAddr();
extern int	getErrbufSize();
extern char	*getErrstr();
extern void	setErrstr();
extern int	devtype();
extern int	ds_close();
extern int	ds_findpkg();
extern int	ds_getinfo();
extern int	ds_getpkg();
extern int	ds_ginit();
extern boolean_t	ds_fd_open();
extern int	ds_init();
extern int	ds_next();
extern int	ds_readbuf();
extern int	epclose();
extern int	esystem();
extern int	e_ExecCmdArray();
extern int	e_ExecCmdList();
extern int	gpkgmap();
extern int	isFdRemote();
extern int	isFstypeRemote();
extern int	isPathRemote();
extern int	iscpio();
extern int	isdir();
extern int	isfile();
extern int	pkgexecl();
extern int	pkgexecv();
extern int	pkghead();
extern int	pkgmount();
extern int	pkgtrans();
extern int	pkgumount();
extern int	ppkgmap();
extern int	putcfile();
extern int	putcvfpfile();
extern int	rrmdir();
extern int	srchcfile();
extern struct	group *cgrgid();
extern struct	group *cgrnam();
extern struct	passwd *cpwnam();
extern struct	passwd *cpwuid();
extern void	basepath();
extern void	canonize();
extern void	canonize_slashes();
extern void	checksum_off();
extern void	checksum_on();
extern void	cvtpath();
extern void	ds_order();
extern void	ds_putinfo();
extern void	ds_skiptoend();
extern void	ecleanup();
extern void	logerr();
extern int	mappath();
extern int	mapvar();
extern void	progerr();
extern void	rpterr();
extern void	tputcfent();
extern void	set_nonABI_symlinks();
extern int	nonABI_symlinks();
extern void	disable_attribute_check();
extern int	get_disable_attribute_check();
/* vfpops.c */
extern int	vfpCheckpointFile();
extern int	vfpCheckpointOpen();
extern int	vfpClearModified();
extern int	vfpClose();
extern int	vfpGetModified();
extern int	vfpOpen();
extern void	vfpRewind();
extern int	vfpSetFlags();
extern int	vfpSetModified();
extern int	vfpSetSize();
extern void	vfpTruncate();
extern int	vfpWriteToFile();

/* handlelocalfs.c */
boolean_t	enable_local_fs();
boolean_t	restore_local_fs();

/* gpkgmap.c */
int		getmapmode(void);

#endif	/* __STDC__ */

#ifdef	__cplusplus
}
#endif

#endif	/* _PKGLIB_H */