/* * 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 (c) 2017 Peter Tribble. */ /* * 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 #include #include #include #include #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 PKGADD "pkgadd" /* package header magic tokens */ #define HDR_PREFIX "# PaCkAgE DaTaStReAm" #define HDR_SUFFIX "# end of header" #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) 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 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); 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 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, size_t); 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 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); /* 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); /* path_valid.c */ extern boolean_t path_valid(char *); /* 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); #ifdef __cplusplus } #endif #endif /* _PKGLIB_H */