xref: /illumos-gate/usr/src/lib/libpkg/common/pkglib.h (revision f3aaec0a97c3584095582719a0149d5e94c06ea2)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29 
30 #ifndef	_PKGLIB_H
31 #define	_PKGLIB_H
32 
33 
34 #ifdef	__cplusplus
35 extern "C" {
36 #endif
37 
38 #include <sys/types.h>
39 #include <limits.h>
40 #include <stdio.h>
41 #include <pkgdev.h>
42 #include <pkgstrct.h>
43 #include <openssl/bio.h>
44 #include <openssl/x509.h>
45 #include <netdb.h>
46 #include <boot_http.h>
47 #include "pkgerr.h"
48 #include "keystore.h"
49 #include "cfext.h"
50 
51 /*
52  * The contents database file interface.
53  */
54 
55 typedef struct pkg_server *PKGserver;
56 
57 /* Some commands modify the internal database: add them here */
58 #define	PKG_WRITE_COMMAND(cmd)	((cmd) == PKG_ADDLINES)
59 
60 #define	PKG_EXIT		0x0
61 #define	PKG_FINDFILE		0x1
62 #define	PKG_DUMP		0x2
63 #define	PKG_PKGSYNC		0x3
64 #define	PKG_FILTER		0x4
65 #define	PKG_ADDLINES		0x5
66 #define	PKG_NOP			0x6
67 
68 #define	SUNW_PKG_SERVERMODE	"SUNW_PKG_SERVERMODE"
69 
70 #define	PKGSERV_MODE		"pkg-server-mode="
71 #define	PKGSERV_MODE_LEN	(sizeof (PKGSERV_MODE) - 1)
72 
73 #define	MODE_PERMANENT		"permanent"
74 #define	MODE_RUN_ONCE		"run_once"
75 #define	MODE_TIMEOUT		"timeout"
76 
77 #define	MAXLOGFILESIZE		(20 * 1024 * 1024)
78 
79 #define	PKGLOG			"pkglog"
80 #define	PKGDOOR			".door"
81 
82 typedef enum {
83 	INVALID,		/* Not initialized */
84 	NEVER,			/* Don't start, does check if it is running. */
85 	FLUSH_LOG,		/* Run it once to incorporate the log. */
86 	RUN_ONCE,		/* Run until the current client stops. */
87 	TIMEOUT,		/* Run until a timeout occurs. */
88 	PERMANENT,		/* Run until it is externally terminated. */
89 	DEFAULTMODE = TIMEOUT	/* The default mode, must come last */
90 } start_mode_t;
91 
92 typedef struct pkgcmd {
93 	int cmd;
94 	char buf[1];
95 } pkgcmd_t;
96 
97 typedef struct pkgfilter {
98 	int cmd;
99 	int len;
100 	char buf[1];
101 } pkgfilter_t;
102 
103 /*
104  * Virtual File Protocol definitions
105  */
106 
107 /*
108  * flags associated with virtual file protocol operations; note that these flags
109  * may only occupy the low order 16 bits of the 32-bit unsigned flag.
110  */
111 
112 typedef unsigned long VFPFLAGS_T;
113 
114 #define	VFP_NONE	0x00000000	/* no special flags */
115 #define	VFP_NEEDNOW	0x00000001	/* need memory now */
116 #define	VFP_SEQUENTIAL	0x00000002	/* sequential access */
117 #define	VFP_RANDOM	0x00000004	/* random access */
118 #define	VFP_NOMMAP	0x00000008	/* do not use mmap to access file */
119 #define	VFP_NOMALLOC	0x00000010	/* do not use malloc to buffer file */
120 
121 /* virtual file protocol object */
122 
123 typedef struct _vfp VFP_T;
124 
125 /* structure behind the virtual file protocol object */
126 
127 struct _vfp {
128 	FILE		*_vfpFile;	/* -> opened FILE */
129 	char		*_vfpCurr;	/* -> current byte to read/write */
130 	char		*_vfpHighWater;	/* -> last byte modified */
131 	char		*_vfpEnd;	/* -> last data byte */
132 	char		*_vfpPath;	/* -> path associated with FILE */
133 	char		*_vfpStart;	/* -> first data byte */
134 	void		*_vfpExtra;	/* undefined */
135 	size_t		_vfpSize;	/* size of mapped/allocated area */
136 	size_t		_vfpMapSize;	/* # mapped bytes */
137 	VFPFLAGS_T	_vfpFlags;	/* flags associated with vfp/data */
138 	int		_vfpOverflow;	/* non-zero if buffer write overflow */
139 	blkcnt_t	_vfpCkStBlocks;	/* checkpoint # blocks */
140 	dev_t		_vfpCkDev;	/* checkpoint device i.d. */
141 	ino_t		_vfpCkIno;	/* checkpoint inode # */
142 	off_t		_vfpCkSize;	/* checkpoint size */
143 	time_t		_vfpCkMtime;	/* checkpoint modification time */
144 };
145 
146 /*
147  * get highest modified byte (length) contained in vfp
148  *
149  * determine number of bytes to write - it will be the highest of:
150  *  -- the current pointer into the file - this is updated whenever
151  *	the location of the file is changed by a single byte
152  *  -- the last "high water mark" - the last known location that
153  *	was written to the file - updated only when the location
154  *	of the file is directly changed - e.g. vfpSetCurrCharPtr,
155  *	vfpTruncate, vfpRewind.
156  * this reduces the "bookkeeping" that needs to be done to know
157  * how many bytes to write out to the file - typically a file is
158  * written sequentially so the current file pointer is sufficient
159  * to determine how many bytes to write out.
160  */
161 
162 #define	vfpGetModifiedLen(VFP)						\
163 	(size_t)(((VFP)->_vfpHighWater > (VFP)->_vfpCurr) ?		\
164 		(((ptrdiff_t)(VFP)->_vfpHighWater -			\
165 				(ptrdiff_t)(VFP)->_vfpStart)) :		\
166 		(((ptrdiff_t)(VFP)->_vfpCurr -				\
167 				(ptrdiff_t)(VFP)->_vfpStart)))
168 
169 /*
170  * increment current pointer by specified delta
171  * if the delta exceeds the buffer size, set pointer to buffer end
172  */
173 #define	vfpIncCurrPtrBy(VFP, INC)					\
174 	{								\
175 		((VFP)->_vfpCurr) += (INC);				\
176 		if (((VFP)->_vfpCurr) > ((VFP)->_vfpEnd)) {		\
177 			(VFP)->_vfpCurr = (VFP)->_vfpEnd;		\
178 			(VFP)->_vfpOverflow = 1;			\
179 		}							\
180 		if ((VFP)->_vfpHighWater < (VFP)->_vfpCurr) {		\
181 			(VFP)->_vfpHighWater = (VFP)->_vfpCurr;		\
182 		}							\
183 	}
184 
185 /* get the path associated with the vfp */
186 #define	vfpGetPath(VFP)		((VFP)->_vfpPath)
187 
188 /* get a string from the vfp into a fixed size buffer */
189 #define	vfpGets(VFP, PTR, LEN)						\
190 	{								\
191 		char	*XXpXX = (PTR);					\
192 		size_t	XXlXX = (LEN);					\
193 		while ((*(VFP)->_vfpCurr != '\0') &&			\
194 				(*(VFP)->_vfpCurr != '\n')) {		\
195 			if (XXlXX > 1) {				\
196 				*XXpXX++ = *(VFP)->_vfpCurr;		\
197 				XXlXX--;				\
198 			}						\
199 			(VFP)->_vfpCurr++;				\
200 		}							\
201 		*XXpXX++ = '\0';					\
202 		if (*(VFP)->_vfpCurr != '\0') {				\
203 			(VFP)->_vfpCurr++;				\
204 		}							\
205 	}
206 
207 /* get number of bytes remaining to read */
208 #define	vfpGetBytesRemaining(VFP)	\
209 	(((((VFP)->_vfpHighWater) <= ((VFP)->_vfpCurr))) ? 0 : 		\
210 	((((ptrdiff_t)(VFP)->_vfpHighWater)-((ptrdiff_t)(VFP)->_vfpCurr))))
211 
212 /* get number of bytes remaining to write */
213 #define	vfpGetBytesAvailable(VFP)	\
214 	(((((VFP)->_vfpEnd) <= ((VFP)->_vfpCurr))) ? 0 : 		\
215 	((((ptrdiff_t)(VFP)->_vfpEnd)-((ptrdiff_t)(VFP)->_vfpCurr))))
216 
217 /* put current character and increment to next */
218 #define	vfpPutc(VFP, C)							\
219 	{								\
220 		(*(VFP)->_vfpCurr) = ((char)(C));			\
221 		vfpIncCurrPtrBy((VFP), 1);				\
222 	}
223 
224 /* put integer to current character and increment */
225 #define	vfpPutInteger(VFP, NUMBER)	vfpPutFormat((VFP), "%d", (NUMBER))
226 
227 /* put long to current character and increment */
228 #define	vfpPutLong(VFP, NUMBER)	vfpPutFormat((VFP), "%ld", (NUMBER))
229 
230 /* get current character and increment to next */
231 #define	vfpGetc(VFP)		(*(VFP)->_vfpCurr++)
232 
233 /* get current character - do not increment */
234 #define	vfpGetcNoInc(VFP)	(*(VFP)->_vfpCurr)
235 
236 /* get pointer to current character */
237 #define	vfpGetCurrCharPtr(VFP)	((VFP)->_vfpCurr)
238 
239 /* increment current character pointer */
240 #define	vfpIncCurrPtr(VFP)	vfpIncCurrPtrBy((VFP), 1)
241 
242 /* decrement current character pointer */
243 #define	vfpDecCurrPtr(VFP)	((VFP)->_vfpCurr--)
244 
245 /* get pointer to first data byte in buffer */
246 #define	vfpGetFirstCharPtr(VFP)	((VFP)->_vfpStart)
247 
248 /* get pointer to last data byte in buffer */
249 #define	vfpGetLastCharPtr(VFP)	((VFP)->_vfpHighWater)
250 
251 /* set pointer to current character */
252 #define	vfpSetCurrCharPtr(VFP, PTR)					\
253 	if ((VFP)->_vfpCurr > (VFP)->_vfpHighWater) {			\
254 		(VFP)->_vfpHighWater = (VFP)->_vfpCurr;			\
255 	}								\
256 	((VFP)->_vfpCurr = (PTR))
257 
258 /* set pointer to last data byte in buffer */
259 #define	vfpSetLastCharPtr(VFP, PTR)					\
260 	if ((PTR) >= (VFP)->_vfpStart) {				\
261 		(VFP)->_vfpHighWater = (PTR);				\
262 		if ((VFP)->_vfpCurr > (VFP)->_vfpHighWater) {		\
263 			(VFP)->_vfpCurr = (VFP)->_vfpHighWater;		\
264 		}							\
265 	}
266 
267 /* seek to end of file - one past last data byte in file */
268 #define	vfpSeekToEnd(VFP)	((VFP)->_vfpCurr = ((VFP)->_vfpHighWater)+1)
269 
270 /* get number of bytes between current char and specified char */
271 #define	vfpGetCurrPtrDelta(VFP, P)	\
272 	(((ptrdiff_t)(P))-((ptrdiff_t)(VFP)->_vfpCurr))
273 
274 /* put string to current character and increment */
275 #define	vfpPuts(VFP, S)							\
276 	{								\
277 		size_t	xxLen;						\
278 		size_t	xxResult;					\
279 		xxLen = vfpGetBytesAvailable((VFP));			\
280 		xxResult = strlcpy(((VFP)->_vfpCurr), (S), xxLen);	\
281 		vfpIncCurrPtrBy((VFP), xxResult);			\
282 	}
283 
284 /* put fixed number of bytes to current character and increment */
285 #define	vfpPutBytes(VFP, PTR, LEN)					\
286 	{								\
287 		size_t	xxLen;						\
288 		xxLen = vfpGetBytesAvailable((VFP));			\
289 		if (xxLen > (LEN)) {					\
290 			xxLen = (LEN);					\
291 		} else {						\
292 			(VFP)->_vfpOverflow = 1;			\
293 		}							\
294 		memcpy((VFP)->_vfpCurr, (PTR), (xxLen));		\
295 		vfpIncCurrPtrBy((VFP), (xxLen));			\
296 	}
297 
298 /* put format one arg to current character and increment */
299 #define	vfpPutFormat(VFP, FORMAT, ARG)					\
300 	{								\
301 	char	xxTeMpXX[256];						\
302 	(void) snprintf(xxTeMpXX, sizeof (xxTeMpXX), (FORMAT), (ARG));	\
303 	vfpPuts((VFP), xxTeMpXX);					\
304 	}
305 
306 struct dm_buf {
307 	char *text_buffer;	/* start of allocated buffer */
308 	int offset;		/* number of bytes into the text_buffer */
309 	int allocation;		/* size of buffer in bytes */
310 };
311 
312 /* This structure is used to hold a dynamically growing string */
313 
314 struct dstr {
315 	char *pc;
316 	int   len;
317 	int   max;
318 };
319 
320 /* setmapmode() defines */
321 #define	MAPALL		0	/* resolve all variables */
322 #define	MAPBUILD	1	/* map only build variables */
323 #define	MAPINSTALL	2	/* map only install variables */
324 #define	MAPNONE		3	/* map no variables */
325 
326 #define	NON_ABI_NAMELNGTH	33	/* 32 chars for name + 1 for NULL */
327 
328 #define	BLK_SIZE	512	/* size of logical block */
329 
330 /* max length for printed attributes */
331 #define	ATTR_MAX	80
332 
333 /*
334  * These three defines indicate that the prototype file contains a '?'
335  * meaning do not specify this data in the pkgmap entry.
336  */
337 #define	CURMODE		BADMODE		/* current mode has been specified */
338 #define	CUROWNER	BADOWNER	/* ... same for owner ... */
339 #define	CURGROUP	BADGROUP	/* ... and group. */
340 
341 #define	WILDCARD		BADMODE >> 1
342 #define	DB_UNDEFINED_ENTRY	"?"
343 
344 #define	DEFAULT_MODE		0755
345 #define	DEFAULT_MODE_FILE	0644
346 #define	DEFAULT_OWNER	"root"
347 #define	DEFAULT_GROUP	"other"
348 
349 #define	INST_RELEASE "var/sadm/system/admin/INST_RELEASE"
350 
351 #define	RANDOM			"/dev/urandom"
352 #define	BLOCK			256
353 
354 #define	TERM_WIDTH		60
355 #define	SMALL_DIVISOR		4
356 #define	MED_DIVISOR		5
357 #define	LARGE_DIVISOR		10
358 #define	MED_DWNLD		(10 * 1024 * 1024) /* 10 MB */
359 #define	LARGE_DWNLD		(5 * MED_DWNLD) /* 50 MB */
360 
361 #define	HTTP			"http://"
362 #define	HTTPS			"https://"
363 
364 #define	PKGADD			"pkgadd"
365 
366 /* Settings for network admin defaults */
367 
368 #define	NET_TIMEOUT_DEFAULT 	60
369 #define	NET_RETRIES_DEFAULT 	3
370 #define	NET_TIMEOUT_MIN		1		/* 1 second */
371 #define	NET_TIMEOUT_MAX		(5 * 60)	/* 5 minutes */
372 #define	NET_RETRIES_MIN		1
373 #define	NET_RETRIES_MAX		10
374 #define	AUTH_NOCHECK		0
375 #define	AUTH_QUIT		1
376 
377 /* package header magic tokens */
378 #define	HDR_PREFIX	"# PaCkAgE DaTaStReAm"
379 #define	HDR_SUFFIX	"# end of header"
380 
381 /* name of security files */
382 #define	PKGSEC		"/var/sadm/security"
383 #define	SIGNATURE_FILENAME	"signature"
384 
385 #define	GROUP	"/etc/group"
386 #define	PASSWD	"/etc/passwd"
387 
388 /*
389  * The next three mean that no mode, owner or group was specified or that the
390  * one specified is invalid for some reason. Sometimes this is an error in
391  * which case it is generally converted to CUR* with a warning. Other times
392  * it means "look it up" by stating the existing file system object pointred
393  * to in the prototype file.
394  */
395 #define	NOMODE		(BADMODE-1)
396 #define	NOOWNER		"@"
397 #define	NOGROUP		"@"
398 
399 /* string comparitor abbreviators */
400 
401 #define	ci_streq(a, b)		(strcasecmp((a), (b)) == 0)
402 #define	ci_strneq(a, b, c)	(strncasecmp((a), (b), (c)) == 0)
403 #define	streq(a, b)		(strcmp((a), (b)) == 0)
404 #define	strneq(a, b, c)		(strncmp((a), (b), (c)) == 0)
405 
406 extern FILE	*epopen(char *cmd, char *mode);
407 extern char	**gpkglist(char *dir, char **pkg, char **catg);
408 extern int	is_not_valid_length(char **category);
409 extern int	is_not_valid_category(char **category, char *progname);
410 extern int	is_same_CATEGORY(char **category, char *installed_category);
411 extern char **get_categories(char *catg_arg);
412 
413 extern void	pkglist_cont(char *keyword);
414 extern char	**pkgalias(char *pkg);
415 extern char	*get_prog_name(void);
416 extern char 	*set_prog_name(char *name);
417 extern int	averify(int fix, char *ftype, char *path, struct ainfo *ainfo);
418 extern int	ckparam(char *param, char *value);
419 extern int	ckvolseq(char *dir, int part, int nparts);
420 extern int	cverify(int fix, char *ftype, char *path, struct cinfo *cinfo,
421 			int allow_checksum);
422 extern unsigned long	compute_checksum(int *r_cksumerr, char *a_path);
423 extern int	fverify(int fix, char *ftype, char *path, struct ainfo *ainfo,
424 		    struct cinfo *cinfo);
425 extern char	*getErrbufAddr(void);
426 extern int	getErrbufSize(void);
427 extern char	*getErrstr(void);
428 extern void	setErrstr(char *errstr);
429 extern int	devtype(char *alias, struct pkgdev *devp);
430 extern int	ds_totread;	/* total number of parts read */
431 extern int	ds_close(int pkgendflg);
432 extern int	ds_findpkg(char *device, char *pkg);
433 extern int	ds_getinfo(char *string);
434 extern int	ds_getpkg(char *device, int n, char *dstdir);
435 extern int	ds_ginit(char *device);
436 extern boolean_t	ds_fd_open(void);
437 extern int	ds_init(char *device, char **pkg, char *norewind);
438 extern int	BIO_ds_dump_header(PKG_ERR *, BIO *);
439 extern int	BIO_ds_dump(PKG_ERR *, char *, BIO *);
440 extern int	BIO_dump_cmd(char *cmd, BIO *bio);
441 extern int	ds_next(char *, char *);
442 extern int	ds_readbuf(char *device);
443 extern int	epclose(FILE *pp);
444 extern int	esystem(char *cmd, int ifd, int ofd);
445 extern int	e_ExecCmdArray(int *r_status, char **r_results,
446 			char *a_inputFile, char *a_cmd, char **a_args);
447 extern int	e_ExecCmdList(int *r_status, char **r_results,
448 			char *a_inputFile, char *a_cmd, ...);
449 extern int	gpkgmap(struct cfent *ept, FILE *fp);
450 extern int	gpkgmapvfp(struct cfent *ept, VFP_T *fpv);
451 extern void	setmapmode(int mode_no);
452 extern int	isFdRemote(int a_fd);
453 extern int	isFstypeRemote(char *a_fstype);
454 extern int	isPathRemote(char *a_path);
455 extern int	iscpio(char *path, int *iscomp);
456 extern int	isdir(char *path);
457 extern int	isfile(char *dir, char *file);
458 extern int	fmkdir(char *a_path, int a_mode);
459 extern int	pkgexecl(char *filein, char *fileout, char *uname, char *gname,
460 			...);
461 extern int	pkgexecv(char *filein, char *fileout, char *uname, char *gname,
462 			char *arg[]);
463 extern int	pkghead(char *device);
464 extern int	pkgmount(struct pkgdev *devp, char *pkg, int part, int nparts,
465 			int getvolflg);
466 extern int	pkgtrans(char *device1, char *device2, char **pkg,
467 			int options, keystore_handle_t, char *);
468 extern int	pkgumount(struct pkgdev *devp);
469 extern int	ppkgmap(struct cfent *ept, FILE *fp);
470 extern int	putcfile(struct cfent *ept, FILE *fp);
471 extern int	putcvfpfile(struct cfent *ept, VFP_T *vfp);
472 extern int	rrmdir(char *path);
473 extern void	set_memalloc_failure_func(void (*)(int));
474 extern void	*xmalloc(size_t size);
475 extern void	*xrealloc(void *ptr, size_t size);
476 extern char	*xstrdup(char *str);
477 extern void	set_passphrase_prompt(char *);
478 extern void	set_passphrase_passarg(char *);
479 extern int	pkg_passphrase_cb(char *, int, int, void *);
480 
481 extern int	srchcfile(struct cfent *ept, char *path, PKGserver server);
482 extern struct	group *cgrgid(gid_t gid);
483 extern struct	group *cgrnam(char *nam);
484 extern struct	passwd *cpwnam(char *nam);
485 extern struct	passwd *cpwuid(uid_t uid);
486 extern struct	group *clgrgid(gid_t gid);
487 extern struct	group *clgrnam(char *nam);
488 extern struct	passwd *clpwnam(char *nam);
489 extern struct	passwd *clpwuid(uid_t uid);
490 extern void	basepath(char *path, char *basedir, char *ir);
491 extern void	canonize(char *file);
492 extern void	canonize_slashes(char *file);
493 extern void	checksum_off(void);
494 extern void	checksum_on(void);
495 extern void	cvtpath(char *path, char *copy);
496 extern void	ds_order(char *list[]);
497 extern void	ds_putinfo(char *buf, size_t);
498 extern void	ds_skiptoend(char *device);
499 extern void	ecleanup(void);
500 /*PRINTFLIKE1*/
501 extern void	logerr(char *fmt, ...);
502 extern int	mappath(int flag, char *path);
503 extern int	mapvar(int flag, char *varname);
504 /*PRINTFLIKE1*/
505 extern void	progerr(char *fmt, ...);
506 extern void	pkgerr(PKG_ERR *);
507 extern void	rpterr(void);
508 extern void	tputcfent(struct cfent *ept, FILE *fp);
509 extern void	set_nonABI_symlinks(void);
510 extern int	nonABI_symlinks(void);
511 extern void	disable_attribute_check(void);
512 extern int	get_disable_attribute_check(void);
513 
514 /* security.c */
515 extern void	sec_init(void);
516 extern char	*get_subject_display_name(X509 *);
517 extern char	*get_issuer_display_name(X509 *);
518 extern char	*get_serial_num(X509 *);
519 extern char	*get_fingerprint(X509 *, const EVP_MD *);
520 extern int	get_cert_chain(PKG_ERR *, X509 *, STACK_OF(X509) *,
521     STACK_OF(X509) *, STACK_OF(X509) **);
522 
523 /* pkgstr.c */
524 void		pkgstrConvertUllToTimeString_r(unsigned long long a_time,
525 			char *a_buf, int a_bufLen);
526 char		*pkgstrConvertPathToBasename(char *a_path);
527 char		*pkgstrConvertPathToDirname(char *a_path);
528 char		*pkgstrDup(char *a_str);
529 char		*pkgstrLocatePathBasename(char *a_path);
530 void		pkgstrScaleNumericString(char *a_buf, unsigned long long scale);
531 void		pkgstrAddToken(char **a_old, char *a_new, char a_separator);
532 boolean_t	pkgstrContainsToken(char *a_string, char *a_token,
533 			char *a_separators);
534 void		pkgstrExpandTokens(char **a_old, char *a_string,
535 			char a_separator, char *a_separators);
536 char		*pkgstrGetToken(char *r_sep, char *a_string, int a_index,
537 			char *a_separators);
538 void		pkgstrGetToken_r(char *r_sep, char *a_string, int a_index,
539 			char *a_separators, char *a_buf, int a_bufLen);
540 unsigned long	pkgstrNumTokens(char *a_string, char *a_separators);
541 char		*pkgstrPrintf(char *a_format, ...);
542 void		pkgstrPrintf_r(char *a_buf, int a_bufLen, char *a_format, ...);
543 void		pkgstrRemoveToken(char **r_string, char *a_token,
544 			char *a_separators, int a_index);
545 void		pkgstrRemoveLeadingWhitespace(char **a_str);
546 /* vfpops.c */
547 extern int	vfpCheckpointFile(VFP_T **r_destVfp, VFP_T **a_vfp,
548 			char *a_path);
549 extern int	vfpCheckpointOpen(VFP_T **a_cvfp, VFP_T **r_vfp, char *a_path,
550 			char *a_mode, VFPFLAGS_T a_flags);
551 extern int	vfpClearModified(VFP_T *a_vfp);
552 extern int	vfpClose(VFP_T **r_vfp);
553 extern int	vfpGetModified(VFP_T *a_vfp);
554 extern int	vfpOpen(VFP_T **r_vfp, char *a_path, char *a_mode,
555 			VFPFLAGS_T a_flags);
556 extern void	vfpRewind(VFP_T *a_vfp);
557 extern ssize_t	vfpSafePwrite(int a_fildes, void *a_buf,
558 			size_t a_nbyte, off_t a_offset);
559 extern ssize_t	vfpSafeWrite(int a_fildes, void *a_buf, size_t a_nbyte);
560 extern int	vfpSetFlags(VFP_T *a_vfp, VFPFLAGS_T a_flags);
561 extern int	vfpSetModified(VFP_T *a_vfp);
562 extern int	vfpSetSize(VFP_T *a_vfp, size_t a_size);
563 extern void	vfpTruncate(VFP_T *a_vfp);
564 extern int	vfpWriteToFile(VFP_T *a_vfp, char *a_path);
565 
566 /* handlelocalfs.c */
567 boolean_t	enable_local_fs(void);
568 boolean_t	restore_local_fs(void);
569 
570 /* pkgserv.c */
571 extern PKGserver	pkgopenserver(const char *, const char *, boolean_t);
572 extern void		pkgcloseserver(PKGserver);
573 extern int		pkgcmd(PKGserver, void *, size_t, char **, size_t *,
574     int *);
575 extern boolean_t	pkgsync_needed(const char *, const char *, boolean_t);
576 extern int		pkgsync(const char *, const char *, boolean_t);
577 extern int		pkgservercommitfile(VFP_T *, PKGserver);
578 extern int		pkgopenfilter(PKGserver server, const char *pkginst);
579 extern void		pkgclosefilter(PKGserver);
580 extern char 		*pkggetentry(PKGserver, int *, int *);
581 extern char 		*pkggetentry_named(PKGserver, const char *, int *,
582     int *);
583 extern void		pkgserversetmode(start_mode_t);
584 extern start_mode_t	pkgservergetmode(void);
585 extern start_mode_t	pkgparsemode(const char *);
586 extern char 		*pkgmodeargument(start_mode_t);
587 
588 #ifdef	__cplusplus
589 }
590 #endif
591 
592 #endif	/* _PKGLIB_H */
593