1*9781SMoriah.Waterland@Sun.COM /*
2*9781SMoriah.Waterland@Sun.COM * CDDL HEADER START
3*9781SMoriah.Waterland@Sun.COM *
4*9781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the
5*9781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License").
6*9781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License.
7*9781SMoriah.Waterland@Sun.COM *
8*9781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*9781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions
11*9781SMoriah.Waterland@Sun.COM * and limitations under the License.
12*9781SMoriah.Waterland@Sun.COM *
13*9781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*9781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*9781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*9781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*9781SMoriah.Waterland@Sun.COM *
19*9781SMoriah.Waterland@Sun.COM * CDDL HEADER END
20*9781SMoriah.Waterland@Sun.COM */
21*9781SMoriah.Waterland@Sun.COM
22*9781SMoriah.Waterland@Sun.COM /*
23*9781SMoriah.Waterland@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24*9781SMoriah.Waterland@Sun.COM * Use is subject to license terms.
25*9781SMoriah.Waterland@Sun.COM */
26*9781SMoriah.Waterland@Sun.COM
27*9781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*9781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
29*9781SMoriah.Waterland@Sun.COM
30*9781SMoriah.Waterland@Sun.COM
31*9781SMoriah.Waterland@Sun.COM
32*9781SMoriah.Waterland@Sun.COM #include <stdio.h>
33*9781SMoriah.Waterland@Sun.COM #include <limits.h>
34*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
35*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
36*9781SMoriah.Waterland@Sun.COM #include <string.h>
37*9781SMoriah.Waterland@Sun.COM #include <ctype.h>
38*9781SMoriah.Waterland@Sun.COM #include <fcntl.h>
39*9781SMoriah.Waterland@Sun.COM #include <sys/types.h>
40*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
41*9781SMoriah.Waterland@Sun.COM #include <errno.h>
42*9781SMoriah.Waterland@Sun.COM #include "pkgstrct.h"
43*9781SMoriah.Waterland@Sun.COM #include "pkglib.h"
44*9781SMoriah.Waterland@Sun.COM #include "pkglibmsgs.h"
45*9781SMoriah.Waterland@Sun.COM #include "pkglocale.h"
46*9781SMoriah.Waterland@Sun.COM
47*9781SMoriah.Waterland@Sun.COM #define ERR_CANT_READ_LCLPATH "unable to read local pathname"
48*9781SMoriah.Waterland@Sun.COM #define ERR_BAD_VOLUME_NUMBER "bad volume number"
49*9781SMoriah.Waterland@Sun.COM #define ERR_CANNOT_READ_PATHNAME_FIELD "unable to read pathname field"
50*9781SMoriah.Waterland@Sun.COM #define ERR_CANNOT_READ_CONTENT_INFO "unable to read content info"
51*9781SMoriah.Waterland@Sun.COM #define ERR_EXTRA_TOKENS_PRESENT "extra tokens on input line"
52*9781SMoriah.Waterland@Sun.COM #define ERR_CANNOT_READ_CLASS_TOKEN "unable to read class token"
53*9781SMoriah.Waterland@Sun.COM #define ERR_BAD_LINK_SPEC "missing or invalid link specification"
54*9781SMoriah.Waterland@Sun.COM #define ERR_UNKNOWN_FTYPE "unknown ftype"
55*9781SMoriah.Waterland@Sun.COM #define ERR_NO_LINKSOURCE "no link source specified"
56*9781SMoriah.Waterland@Sun.COM #define ERR_CANNOT_READ_MM_DEVNUMS "unable to read major/minor "\
57*9781SMoriah.Waterland@Sun.COM "device numbers"
58*9781SMoriah.Waterland@Sun.COM static int eatwhite(FILE *fp);
59*9781SMoriah.Waterland@Sun.COM static int getend(FILE *fp);
60*9781SMoriah.Waterland@Sun.COM static int getstr(FILE *fp, char *sep, int n, char *str);
61*9781SMoriah.Waterland@Sun.COM static int getnum(FILE *fp, int base, long *d, long bad);
62*9781SMoriah.Waterland@Sun.COM static int getlnum(FILE *fp, int base, fsblkcnt_t *d, long bad);
63*9781SMoriah.Waterland@Sun.COM static int getvalmode(FILE *fp, mode_t *d, long bad, int map);
64*9781SMoriah.Waterland@Sun.COM
65*9781SMoriah.Waterland@Sun.COM static int getendvfp(char **cp);
66*9781SMoriah.Waterland@Sun.COM static void findendvfp(char **cp);
67*9781SMoriah.Waterland@Sun.COM static int getstrvfp(char **cp, char *sep, int n, char *str);
68*9781SMoriah.Waterland@Sun.COM static int getvalmodevfp(char **cp, mode_t *d, long bad, int map);
69*9781SMoriah.Waterland@Sun.COM int getnumvfp(char **cp, int base, long *d, long bad);
70*9781SMoriah.Waterland@Sun.COM int getlnumvfp(char **cp, int base, fsblkcnt_t *d, long bad);
71*9781SMoriah.Waterland@Sun.COM
72*9781SMoriah.Waterland@Sun.COM static char mypath[PATH_MAX];
73*9781SMoriah.Waterland@Sun.COM static char mylocal[PATH_MAX];
74*9781SMoriah.Waterland@Sun.COM static int mapmode = MAPNONE;
75*9781SMoriah.Waterland@Sun.COM static char *maptype = "";
76*9781SMoriah.Waterland@Sun.COM static mode_t d_mode = BADMODE;
77*9781SMoriah.Waterland@Sun.COM static char *d_owner = BADOWNER;
78*9781SMoriah.Waterland@Sun.COM static char *d_group = BADGROUP;
79*9781SMoriah.Waterland@Sun.COM
80*9781SMoriah.Waterland@Sun.COM /*
81*9781SMoriah.Waterland@Sun.COM * These determine how gpkgmap() deals with mode, owner and group defaults.
82*9781SMoriah.Waterland@Sun.COM * It is assumed that the owner and group arguments represent static fields
83*9781SMoriah.Waterland@Sun.COM * which will persist until attrdefault() is called.
84*9781SMoriah.Waterland@Sun.COM */
85*9781SMoriah.Waterland@Sun.COM void
attrpreset(int mode,char * owner,char * group)86*9781SMoriah.Waterland@Sun.COM attrpreset(int mode, char *owner, char *group)
87*9781SMoriah.Waterland@Sun.COM {
88*9781SMoriah.Waterland@Sun.COM d_mode = mode;
89*9781SMoriah.Waterland@Sun.COM d_owner = owner;
90*9781SMoriah.Waterland@Sun.COM d_group = group;
91*9781SMoriah.Waterland@Sun.COM }
92*9781SMoriah.Waterland@Sun.COM
93*9781SMoriah.Waterland@Sun.COM void
attrdefault()94*9781SMoriah.Waterland@Sun.COM attrdefault()
95*9781SMoriah.Waterland@Sun.COM {
96*9781SMoriah.Waterland@Sun.COM d_mode = NOMODE;
97*9781SMoriah.Waterland@Sun.COM d_owner = NOOWNER;
98*9781SMoriah.Waterland@Sun.COM d_group = NOGROUP;
99*9781SMoriah.Waterland@Sun.COM }
100*9781SMoriah.Waterland@Sun.COM
101*9781SMoriah.Waterland@Sun.COM /*
102*9781SMoriah.Waterland@Sun.COM * This determines how gpkgmap() deals with environment variables in the
103*9781SMoriah.Waterland@Sun.COM * mode, owner and group. Path is evaluated at a higher level based upon
104*9781SMoriah.Waterland@Sun.COM * other circumstances.
105*9781SMoriah.Waterland@Sun.COM */
106*9781SMoriah.Waterland@Sun.COM void
setmapmode(int mode)107*9781SMoriah.Waterland@Sun.COM setmapmode(int mode)
108*9781SMoriah.Waterland@Sun.COM {
109*9781SMoriah.Waterland@Sun.COM if (mode >= 0 || mode <= 3) {
110*9781SMoriah.Waterland@Sun.COM mapmode = mode;
111*9781SMoriah.Waterland@Sun.COM if (mode == MAPBUILD)
112*9781SMoriah.Waterland@Sun.COM maptype = " build";
113*9781SMoriah.Waterland@Sun.COM else if (mode == MAPINSTALL)
114*9781SMoriah.Waterland@Sun.COM maptype = " install";
115*9781SMoriah.Waterland@Sun.COM else
116*9781SMoriah.Waterland@Sun.COM maptype = "";
117*9781SMoriah.Waterland@Sun.COM }
118*9781SMoriah.Waterland@Sun.COM }
119*9781SMoriah.Waterland@Sun.COM
120*9781SMoriah.Waterland@Sun.COM /* This is the external query interface for mapmode. */
121*9781SMoriah.Waterland@Sun.COM int
getmapmode(void)122*9781SMoriah.Waterland@Sun.COM getmapmode(void)
123*9781SMoriah.Waterland@Sun.COM {
124*9781SMoriah.Waterland@Sun.COM return (mapmode);
125*9781SMoriah.Waterland@Sun.COM }
126*9781SMoriah.Waterland@Sun.COM
127*9781SMoriah.Waterland@Sun.COM /*
128*9781SMoriah.Waterland@Sun.COM * Unpack the pkgmap or the contents file or whatever file is in that format.
129*9781SMoriah.Waterland@Sun.COM * Based upon mapmode, environment parameters will be resolved for mode,
130*9781SMoriah.Waterland@Sun.COM * owner and group.
131*9781SMoriah.Waterland@Sun.COM */
132*9781SMoriah.Waterland@Sun.COM
133*9781SMoriah.Waterland@Sun.COM int
gpkgmap(struct cfent * ept,FILE * fp)134*9781SMoriah.Waterland@Sun.COM gpkgmap(struct cfent *ept, FILE *fp)
135*9781SMoriah.Waterland@Sun.COM {
136*9781SMoriah.Waterland@Sun.COM int c;
137*9781SMoriah.Waterland@Sun.COM boolean_t first_char = B_TRUE;
138*9781SMoriah.Waterland@Sun.COM
139*9781SMoriah.Waterland@Sun.COM setErrstr(NULL);
140*9781SMoriah.Waterland@Sun.COM ept->volno = 0;
141*9781SMoriah.Waterland@Sun.COM ept->ftype = BADFTYPE;
142*9781SMoriah.Waterland@Sun.COM (void) strcpy(ept->pkg_class, BADCLASS);
143*9781SMoriah.Waterland@Sun.COM ept->pkg_class_idx = -1;
144*9781SMoriah.Waterland@Sun.COM ept->path = NULL;
145*9781SMoriah.Waterland@Sun.COM ept->ainfo.local = NULL;
146*9781SMoriah.Waterland@Sun.COM /* default attributes were supplied, so don't reset */
147*9781SMoriah.Waterland@Sun.COM ept->ainfo.mode = d_mode;
148*9781SMoriah.Waterland@Sun.COM (void) strcpy(ept->ainfo.owner, d_owner);
149*9781SMoriah.Waterland@Sun.COM (void) strcpy(ept->ainfo.group, d_group);
150*9781SMoriah.Waterland@Sun.COM #ifdef SUNOS41
151*9781SMoriah.Waterland@Sun.COM ept->ainfo.xmajor = BADMAJOR;
152*9781SMoriah.Waterland@Sun.COM ept->ainfo.xminor = BADMINOR;
153*9781SMoriah.Waterland@Sun.COM #else
154*9781SMoriah.Waterland@Sun.COM ept->ainfo.major = BADMAJOR;
155*9781SMoriah.Waterland@Sun.COM ept->ainfo.minor = BADMINOR;
156*9781SMoriah.Waterland@Sun.COM #endif
157*9781SMoriah.Waterland@Sun.COM ept->cinfo.cksum = ept->cinfo.modtime = ept->cinfo.size = (-1L);
158*9781SMoriah.Waterland@Sun.COM
159*9781SMoriah.Waterland@Sun.COM ept->npkgs = 0;
160*9781SMoriah.Waterland@Sun.COM
161*9781SMoriah.Waterland@Sun.COM if (!fp)
162*9781SMoriah.Waterland@Sun.COM return (-1);
163*9781SMoriah.Waterland@Sun.COM readline:
164*9781SMoriah.Waterland@Sun.COM c = eatwhite(fp);
165*9781SMoriah.Waterland@Sun.COM
166*9781SMoriah.Waterland@Sun.COM /*
167*9781SMoriah.Waterland@Sun.COM * If the first character is not a digit, we assume that the
168*9781SMoriah.Waterland@Sun.COM * volume number is 1.
169*9781SMoriah.Waterland@Sun.COM */
170*9781SMoriah.Waterland@Sun.COM if (first_char && !isdigit(c)) {
171*9781SMoriah.Waterland@Sun.COM ept->volno = 1;
172*9781SMoriah.Waterland@Sun.COM }
173*9781SMoriah.Waterland@Sun.COM first_char = B_FALSE;
174*9781SMoriah.Waterland@Sun.COM
175*9781SMoriah.Waterland@Sun.COM switch (c) {
176*9781SMoriah.Waterland@Sun.COM case EOF:
177*9781SMoriah.Waterland@Sun.COM return (0);
178*9781SMoriah.Waterland@Sun.COM
179*9781SMoriah.Waterland@Sun.COM case '0':
180*9781SMoriah.Waterland@Sun.COM case '1':
181*9781SMoriah.Waterland@Sun.COM case '2':
182*9781SMoriah.Waterland@Sun.COM case '3':
183*9781SMoriah.Waterland@Sun.COM case '4':
184*9781SMoriah.Waterland@Sun.COM case '5':
185*9781SMoriah.Waterland@Sun.COM case '6':
186*9781SMoriah.Waterland@Sun.COM case '7':
187*9781SMoriah.Waterland@Sun.COM case '8':
188*9781SMoriah.Waterland@Sun.COM case '9':
189*9781SMoriah.Waterland@Sun.COM if (ept->volno) {
190*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_BAD_VOLUME_NUMBER));
191*9781SMoriah.Waterland@Sun.COM goto error;
192*9781SMoriah.Waterland@Sun.COM }
193*9781SMoriah.Waterland@Sun.COM do {
194*9781SMoriah.Waterland@Sun.COM ept->volno = (ept->volno*10)+c-'0';
195*9781SMoriah.Waterland@Sun.COM c = getc(fp);
196*9781SMoriah.Waterland@Sun.COM } while (isdigit(c));
197*9781SMoriah.Waterland@Sun.COM if (ept->volno == 0)
198*9781SMoriah.Waterland@Sun.COM ept->volno = 1;
199*9781SMoriah.Waterland@Sun.COM
200*9781SMoriah.Waterland@Sun.COM goto readline;
201*9781SMoriah.Waterland@Sun.COM
202*9781SMoriah.Waterland@Sun.COM case ':':
203*9781SMoriah.Waterland@Sun.COM case '#':
204*9781SMoriah.Waterland@Sun.COM (void) getend(fp);
205*9781SMoriah.Waterland@Sun.COM /*FALLTHRU*/
206*9781SMoriah.Waterland@Sun.COM case '\n':
207*9781SMoriah.Waterland@Sun.COM /*
208*9781SMoriah.Waterland@Sun.COM * Since we are going to scan the next line,
209*9781SMoriah.Waterland@Sun.COM * we need to reset volume number and first_char.
210*9781SMoriah.Waterland@Sun.COM */
211*9781SMoriah.Waterland@Sun.COM ept->volno = 0;
212*9781SMoriah.Waterland@Sun.COM first_char = B_TRUE;
213*9781SMoriah.Waterland@Sun.COM goto readline;
214*9781SMoriah.Waterland@Sun.COM
215*9781SMoriah.Waterland@Sun.COM case 'i':
216*9781SMoriah.Waterland@Sun.COM ept->ftype = (char)c;
217*9781SMoriah.Waterland@Sun.COM c = eatwhite(fp);
218*9781SMoriah.Waterland@Sun.COM /*FALLTHRU*/
219*9781SMoriah.Waterland@Sun.COM case '.':
220*9781SMoriah.Waterland@Sun.COM case '/':
221*9781SMoriah.Waterland@Sun.COM (void) ungetc(c, fp);
222*9781SMoriah.Waterland@Sun.COM
223*9781SMoriah.Waterland@Sun.COM if (getstr(fp, "=", PATH_MAX, mypath)) {
224*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
225*9781SMoriah.Waterland@Sun.COM goto error;
226*9781SMoriah.Waterland@Sun.COM }
227*9781SMoriah.Waterland@Sun.COM ept->path = mypath;
228*9781SMoriah.Waterland@Sun.COM c = getc(fp);
229*9781SMoriah.Waterland@Sun.COM if (c == '=') {
230*9781SMoriah.Waterland@Sun.COM if (getstr(fp, NULL, PATH_MAX, mylocal)) {
231*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANT_READ_LCLPATH));
232*9781SMoriah.Waterland@Sun.COM goto error;
233*9781SMoriah.Waterland@Sun.COM }
234*9781SMoriah.Waterland@Sun.COM ept->ainfo.local = mylocal;
235*9781SMoriah.Waterland@Sun.COM } else
236*9781SMoriah.Waterland@Sun.COM (void) ungetc(c, fp);
237*9781SMoriah.Waterland@Sun.COM
238*9781SMoriah.Waterland@Sun.COM if (ept->ftype == 'i') {
239*9781SMoriah.Waterland@Sun.COM /* content info might exist */
240*9781SMoriah.Waterland@Sun.COM if (!getlnum(fp, 10, (fsblkcnt_t *)&ept->cinfo.size,
241*9781SMoriah.Waterland@Sun.COM BADCONT) &&
242*9781SMoriah.Waterland@Sun.COM (getnum(fp, 10, (long *)&ept->cinfo.cksum,
243*9781SMoriah.Waterland@Sun.COM BADCONT) ||
244*9781SMoriah.Waterland@Sun.COM getnum(fp, 10, (long *)&ept->cinfo.modtime,
245*9781SMoriah.Waterland@Sun.COM BADCONT))) {
246*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
247*9781SMoriah.Waterland@Sun.COM goto error;
248*9781SMoriah.Waterland@Sun.COM }
249*9781SMoriah.Waterland@Sun.COM }
250*9781SMoriah.Waterland@Sun.COM if (getend(fp)) {
251*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
252*9781SMoriah.Waterland@Sun.COM return (-1);
253*9781SMoriah.Waterland@Sun.COM }
254*9781SMoriah.Waterland@Sun.COM return (1);
255*9781SMoriah.Waterland@Sun.COM
256*9781SMoriah.Waterland@Sun.COM case '?':
257*9781SMoriah.Waterland@Sun.COM case 'f':
258*9781SMoriah.Waterland@Sun.COM case 'v':
259*9781SMoriah.Waterland@Sun.COM case 'e':
260*9781SMoriah.Waterland@Sun.COM case 'l':
261*9781SMoriah.Waterland@Sun.COM case 's':
262*9781SMoriah.Waterland@Sun.COM case 'p':
263*9781SMoriah.Waterland@Sun.COM case 'c':
264*9781SMoriah.Waterland@Sun.COM case 'b':
265*9781SMoriah.Waterland@Sun.COM case 'd':
266*9781SMoriah.Waterland@Sun.COM case 'x':
267*9781SMoriah.Waterland@Sun.COM ept->ftype = (char)c;
268*9781SMoriah.Waterland@Sun.COM if (getstr(fp, NULL, CLSSIZ, ept->pkg_class)) {
269*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_CLASS_TOKEN));
270*9781SMoriah.Waterland@Sun.COM goto error;
271*9781SMoriah.Waterland@Sun.COM }
272*9781SMoriah.Waterland@Sun.COM if (getstr(fp, "=", PATH_MAX, mypath)) {
273*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
274*9781SMoriah.Waterland@Sun.COM goto error;
275*9781SMoriah.Waterland@Sun.COM }
276*9781SMoriah.Waterland@Sun.COM ept->path = mypath;
277*9781SMoriah.Waterland@Sun.COM
278*9781SMoriah.Waterland@Sun.COM c = getc(fp);
279*9781SMoriah.Waterland@Sun.COM if (c == '=') {
280*9781SMoriah.Waterland@Sun.COM /* local path */
281*9781SMoriah.Waterland@Sun.COM if (getstr(fp, NULL, PATH_MAX, mylocal)) {
282*9781SMoriah.Waterland@Sun.COM if (ept->ftype == 's' || ept->ftype == 'l') {
283*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_READLINK));
284*9781SMoriah.Waterland@Sun.COM } else {
285*9781SMoriah.Waterland@Sun.COM setErrstr(
286*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_CANT_READ_LCLPATH));
287*9781SMoriah.Waterland@Sun.COM }
288*9781SMoriah.Waterland@Sun.COM goto error;
289*9781SMoriah.Waterland@Sun.COM }
290*9781SMoriah.Waterland@Sun.COM ept->ainfo.local = mylocal;
291*9781SMoriah.Waterland@Sun.COM } else if (strchr("sl", ept->ftype)) {
292*9781SMoriah.Waterland@Sun.COM if ((c != EOF) && (c != '\n'))
293*9781SMoriah.Waterland@Sun.COM (void) getend(fp);
294*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_BAD_LINK_SPEC));
295*9781SMoriah.Waterland@Sun.COM return (-1);
296*9781SMoriah.Waterland@Sun.COM } else
297*9781SMoriah.Waterland@Sun.COM (void) ungetc(c, fp);
298*9781SMoriah.Waterland@Sun.COM break;
299*9781SMoriah.Waterland@Sun.COM
300*9781SMoriah.Waterland@Sun.COM default:
301*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_UNKNOWN_FTYPE));
302*9781SMoriah.Waterland@Sun.COM error:
303*9781SMoriah.Waterland@Sun.COM (void) getend(fp);
304*9781SMoriah.Waterland@Sun.COM return (-1);
305*9781SMoriah.Waterland@Sun.COM }
306*9781SMoriah.Waterland@Sun.COM
307*9781SMoriah.Waterland@Sun.COM if (strchr("sl", ept->ftype) && (ept->ainfo.local == NULL)) {
308*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_NO_LINKSOURCE));
309*9781SMoriah.Waterland@Sun.COM goto error;
310*9781SMoriah.Waterland@Sun.COM }
311*9781SMoriah.Waterland@Sun.COM
312*9781SMoriah.Waterland@Sun.COM if (strchr("cb", ept->ftype)) {
313*9781SMoriah.Waterland@Sun.COM #ifdef SUNOS41
314*9781SMoriah.Waterland@Sun.COM ept->ainfo.xmajor = BADMAJOR;
315*9781SMoriah.Waterland@Sun.COM ept->ainfo.xminor = BADMINOR;
316*9781SMoriah.Waterland@Sun.COM if (getnum(fp, 10, (long *)&ept->ainfo.xmajor, BADMAJOR) ||
317*9781SMoriah.Waterland@Sun.COM getnum(fp, 10, (long *)&ept->ainfo.xminor, BADMINOR))
318*9781SMoriah.Waterland@Sun.COM #else
319*9781SMoriah.Waterland@Sun.COM ept->ainfo.major = BADMAJOR;
320*9781SMoriah.Waterland@Sun.COM ept->ainfo.minor = BADMINOR;
321*9781SMoriah.Waterland@Sun.COM if (getnum(fp, 10, (long *)&ept->ainfo.major, BADMAJOR) ||
322*9781SMoriah.Waterland@Sun.COM getnum(fp, 10, (long *)&ept->ainfo.minor, BADMINOR))
323*9781SMoriah.Waterland@Sun.COM #endif
324*9781SMoriah.Waterland@Sun.COM {
325*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_MM_DEVNUMS));
326*9781SMoriah.Waterland@Sun.COM goto error;
327*9781SMoriah.Waterland@Sun.COM }
328*9781SMoriah.Waterland@Sun.COM }
329*9781SMoriah.Waterland@Sun.COM
330*9781SMoriah.Waterland@Sun.COM /*
331*9781SMoriah.Waterland@Sun.COM * Links and information files don't have attributes associated with
332*9781SMoriah.Waterland@Sun.COM * them. The following either resolves potential variables or passes
333*9781SMoriah.Waterland@Sun.COM * them through. Mode is tested for validity to some degree. BAD???
334*9781SMoriah.Waterland@Sun.COM * is returned to indicate that no meaningful mode was provided. A
335*9781SMoriah.Waterland@Sun.COM * higher authority will decide if that's OK or not. CUR??? means that
336*9781SMoriah.Waterland@Sun.COM * the prototype file specifically requires a wildcard ('?') for
337*9781SMoriah.Waterland@Sun.COM * that entry. We issue an error if attributes were entered wrong.
338*9781SMoriah.Waterland@Sun.COM * We just return BAD??? if there was no entry at all.
339*9781SMoriah.Waterland@Sun.COM */
340*9781SMoriah.Waterland@Sun.COM if (strchr("cbdxpfve", ept->ftype)) {
341*9781SMoriah.Waterland@Sun.COM int retval;
342*9781SMoriah.Waterland@Sun.COM
343*9781SMoriah.Waterland@Sun.COM if ((retval = getvalmode(fp, &(ept->ainfo.mode), CURMODE,
344*9781SMoriah.Waterland@Sun.COM (mapmode != MAPNONE))) == 1)
345*9781SMoriah.Waterland@Sun.COM goto end; /* nothing else on the line */
346*9781SMoriah.Waterland@Sun.COM else if (retval == 2)
347*9781SMoriah.Waterland@Sun.COM goto error; /* mode is too no good */
348*9781SMoriah.Waterland@Sun.COM
349*9781SMoriah.Waterland@Sun.COM /* owner & group should be here */
350*9781SMoriah.Waterland@Sun.COM if ((retval = getstr(fp, NULL, ATRSIZ,
351*9781SMoriah.Waterland@Sun.COM ept->ainfo.owner)) == 1)
352*9781SMoriah.Waterland@Sun.COM goto end; /* no owner or group - warning */
353*9781SMoriah.Waterland@Sun.COM if (retval == -1) {
354*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_OWNTOOLONG));
355*9781SMoriah.Waterland@Sun.COM goto error;
356*9781SMoriah.Waterland@Sun.COM }
357*9781SMoriah.Waterland@Sun.COM
358*9781SMoriah.Waterland@Sun.COM if ((retval = getstr(fp, NULL, ATRSIZ,
359*9781SMoriah.Waterland@Sun.COM ept->ainfo.group)) == 1)
360*9781SMoriah.Waterland@Sun.COM goto end; /* no group - warning */
361*9781SMoriah.Waterland@Sun.COM if (retval == -1) {
362*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_GRPTOOLONG));
363*9781SMoriah.Waterland@Sun.COM goto error;
364*9781SMoriah.Waterland@Sun.COM }
365*9781SMoriah.Waterland@Sun.COM
366*9781SMoriah.Waterland@Sun.COM /* Resolve the parameters if required. */
367*9781SMoriah.Waterland@Sun.COM if (mapmode != MAPNONE) {
368*9781SMoriah.Waterland@Sun.COM if (mapvar(mapmode, ept->ainfo.owner)) {
369*9781SMoriah.Waterland@Sun.COM (void) snprintf(getErrbufAddr(),
370*9781SMoriah.Waterland@Sun.COM getErrbufSize(),
371*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_NOVAR),
372*9781SMoriah.Waterland@Sun.COM maptype, ept->ainfo.owner);
373*9781SMoriah.Waterland@Sun.COM setErrstr(getErrbufAddr());
374*9781SMoriah.Waterland@Sun.COM goto error;
375*9781SMoriah.Waterland@Sun.COM }
376*9781SMoriah.Waterland@Sun.COM if (mapvar(mapmode, ept->ainfo.group)) {
377*9781SMoriah.Waterland@Sun.COM (void) snprintf(getErrbufAddr(),
378*9781SMoriah.Waterland@Sun.COM getErrbufSize(), pkg_gt(ERR_NOVAR),
379*9781SMoriah.Waterland@Sun.COM maptype, ept->ainfo.group);
380*9781SMoriah.Waterland@Sun.COM setErrstr(getErrbufAddr());
381*9781SMoriah.Waterland@Sun.COM goto error;
382*9781SMoriah.Waterland@Sun.COM }
383*9781SMoriah.Waterland@Sun.COM }
384*9781SMoriah.Waterland@Sun.COM }
385*9781SMoriah.Waterland@Sun.COM
386*9781SMoriah.Waterland@Sun.COM if (strchr("ifve", ept->ftype)) {
387*9781SMoriah.Waterland@Sun.COM /* look for content description */
388*9781SMoriah.Waterland@Sun.COM if (!getlnum(fp, 10, (fsblkcnt_t *)&ept->cinfo.size, BADCONT) &&
389*9781SMoriah.Waterland@Sun.COM (getnum(fp, 10, (long *)&ept->cinfo.cksum, BADCONT) ||
390*9781SMoriah.Waterland@Sun.COM getnum(fp, 10, (long *)&ept->cinfo.modtime, BADCONT))) {
391*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
392*9781SMoriah.Waterland@Sun.COM goto error;
393*9781SMoriah.Waterland@Sun.COM }
394*9781SMoriah.Waterland@Sun.COM }
395*9781SMoriah.Waterland@Sun.COM
396*9781SMoriah.Waterland@Sun.COM if (ept->ftype == 'i')
397*9781SMoriah.Waterland@Sun.COM goto end;
398*9781SMoriah.Waterland@Sun.COM
399*9781SMoriah.Waterland@Sun.COM end:
400*9781SMoriah.Waterland@Sun.COM if (getend(fp) && ept->pinfo) {
401*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
402*9781SMoriah.Waterland@Sun.COM return (-1);
403*9781SMoriah.Waterland@Sun.COM }
404*9781SMoriah.Waterland@Sun.COM
405*9781SMoriah.Waterland@Sun.COM done:
406*9781SMoriah.Waterland@Sun.COM return (1);
407*9781SMoriah.Waterland@Sun.COM }
408*9781SMoriah.Waterland@Sun.COM
409*9781SMoriah.Waterland@Sun.COM /*
410*9781SMoriah.Waterland@Sun.COM * Get and validate the mode attribute. This returns an error if
411*9781SMoriah.Waterland@Sun.COM * 1. the mode string is too long
412*9781SMoriah.Waterland@Sun.COM * 2. the mode string includes alpha characters
413*9781SMoriah.Waterland@Sun.COM * 3. the mode string is not octal
414*9781SMoriah.Waterland@Sun.COM * 4. mode string is an install parameter
415*9781SMoriah.Waterland@Sun.COM * 5. mode is an unresolved build parameter and MAPBUILD is
416*9781SMoriah.Waterland@Sun.COM * in effect.
417*9781SMoriah.Waterland@Sun.COM * If the mode is a build parameter, it is
418*9781SMoriah.Waterland@Sun.COM * 1. returned as is if MAPNONE is in effect
419*9781SMoriah.Waterland@Sun.COM * 2. evaluated if MAPBUILD is in effect
420*9781SMoriah.Waterland@Sun.COM *
421*9781SMoriah.Waterland@Sun.COM * NOTE : We use "mapmode!=MAPBUILD" to gather that it is install
422*9781SMoriah.Waterland@Sun.COM * time. At install time we just fix a mode with bad bits set by
423*9781SMoriah.Waterland@Sun.COM * setting it to CURMODE. This should be an error in a few releases
424*9781SMoriah.Waterland@Sun.COM * (2.8 maybe) but faulty modes are so common in existing packages
425*9781SMoriah.Waterland@Sun.COM * that this is a reasonable exception. -- JST 1994-11-9
426*9781SMoriah.Waterland@Sun.COM *
427*9781SMoriah.Waterland@Sun.COM * RETURNS
428*9781SMoriah.Waterland@Sun.COM * 0 if mode is being returned as a valid value
429*9781SMoriah.Waterland@Sun.COM * 1 if no attributes are present on the line
430*9781SMoriah.Waterland@Sun.COM * 2 if there was a fundamental error
431*9781SMoriah.Waterland@Sun.COM */
432*9781SMoriah.Waterland@Sun.COM static int
getvalmode(FILE * fp,mode_t * d,long bad,int map)433*9781SMoriah.Waterland@Sun.COM getvalmode(FILE *fp, mode_t *d, long bad, int map)
434*9781SMoriah.Waterland@Sun.COM {
435*9781SMoriah.Waterland@Sun.COM char tempmode[20];
436*9781SMoriah.Waterland@Sun.COM mode_t tempmode_t;
437*9781SMoriah.Waterland@Sun.COM int retval;
438*9781SMoriah.Waterland@Sun.COM
439*9781SMoriah.Waterland@Sun.COM if ((retval = getstr(fp, NULL, ATRSIZ, tempmode)) == 1)
440*9781SMoriah.Waterland@Sun.COM return (1);
441*9781SMoriah.Waterland@Sun.COM else if (retval == -1) {
442*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_MODELONG));
443*9781SMoriah.Waterland@Sun.COM return (2);
444*9781SMoriah.Waterland@Sun.COM } else {
445*9781SMoriah.Waterland@Sun.COM /*
446*9781SMoriah.Waterland@Sun.COM * If it isn't a '?' (meaning go with whatever mode is
447*9781SMoriah.Waterland@Sun.COM * there), validate the mode and convert it to a mode_t. The
448*9781SMoriah.Waterland@Sun.COM * "bad" variable here is a misnomer. It doesn't necessarily
449*9781SMoriah.Waterland@Sun.COM * mean bad.
450*9781SMoriah.Waterland@Sun.COM */
451*9781SMoriah.Waterland@Sun.COM if (tempmode[0] == '?') {
452*9781SMoriah.Waterland@Sun.COM *d = WILDCARD;
453*9781SMoriah.Waterland@Sun.COM } else {
454*9781SMoriah.Waterland@Sun.COM /*
455*9781SMoriah.Waterland@Sun.COM * Mode may not be an install parameter or a
456*9781SMoriah.Waterland@Sun.COM * non-build parameter.
457*9781SMoriah.Waterland@Sun.COM */
458*9781SMoriah.Waterland@Sun.COM if (tempmode[0] == '$' &&
459*9781SMoriah.Waterland@Sun.COM (isupper(tempmode[1]) || !islower(tempmode[1]))) {
460*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_IMODE));
461*9781SMoriah.Waterland@Sun.COM return (2);
462*9781SMoriah.Waterland@Sun.COM }
463*9781SMoriah.Waterland@Sun.COM
464*9781SMoriah.Waterland@Sun.COM if ((map) && (mapvar(mapmode, tempmode))) {
465*9781SMoriah.Waterland@Sun.COM (void) snprintf(getErrbufAddr(),
466*9781SMoriah.Waterland@Sun.COM getErrbufSize(),
467*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_NOVAR),
468*9781SMoriah.Waterland@Sun.COM maptype, tempmode);
469*9781SMoriah.Waterland@Sun.COM setErrstr(getErrbufAddr());
470*9781SMoriah.Waterland@Sun.COM return (2);
471*9781SMoriah.Waterland@Sun.COM }
472*9781SMoriah.Waterland@Sun.COM
473*9781SMoriah.Waterland@Sun.COM
474*9781SMoriah.Waterland@Sun.COM if (tempmode[0] == '$') {
475*9781SMoriah.Waterland@Sun.COM *d = BADMODE; /* may be a problem */
476*9781SMoriah.Waterland@Sun.COM } else {
477*9781SMoriah.Waterland@Sun.COM /*
478*9781SMoriah.Waterland@Sun.COM * At this point it's supposed to be
479*9781SMoriah.Waterland@Sun.COM * something we can convert to a number.
480*9781SMoriah.Waterland@Sun.COM */
481*9781SMoriah.Waterland@Sun.COM int n = 0;
482*9781SMoriah.Waterland@Sun.COM
483*9781SMoriah.Waterland@Sun.COM /*
484*9781SMoriah.Waterland@Sun.COM * We reject it if it contains nonnumbers or
485*9781SMoriah.Waterland@Sun.COM * it's not octal.
486*9781SMoriah.Waterland@Sun.COM */
487*9781SMoriah.Waterland@Sun.COM while (tempmode[n] && !isspace(tempmode[n])) {
488*9781SMoriah.Waterland@Sun.COM if (!isdigit(tempmode[n])) {
489*9781SMoriah.Waterland@Sun.COM setErrstr(
490*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_MODEALPHA));
491*9781SMoriah.Waterland@Sun.COM return (2);
492*9781SMoriah.Waterland@Sun.COM }
493*9781SMoriah.Waterland@Sun.COM
494*9781SMoriah.Waterland@Sun.COM if (strchr("89abcdefABCDEF",
495*9781SMoriah.Waterland@Sun.COM tempmode[n])) {
496*9781SMoriah.Waterland@Sun.COM setErrstr(
497*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_BASEINVAL));
498*9781SMoriah.Waterland@Sun.COM return (2);
499*9781SMoriah.Waterland@Sun.COM }
500*9781SMoriah.Waterland@Sun.COM n++;
501*9781SMoriah.Waterland@Sun.COM }
502*9781SMoriah.Waterland@Sun.COM
503*9781SMoriah.Waterland@Sun.COM tempmode_t = strtol(tempmode, NULL, 8);
504*9781SMoriah.Waterland@Sun.COM
505*9781SMoriah.Waterland@Sun.COM /*
506*9781SMoriah.Waterland@Sun.COM * We reject it if it contains inappropriate
507*9781SMoriah.Waterland@Sun.COM * bits.
508*9781SMoriah.Waterland@Sun.COM */
509*9781SMoriah.Waterland@Sun.COM if (tempmode_t & ~(S_IAMB |
510*9781SMoriah.Waterland@Sun.COM S_ISUID | S_ISGID | S_ISVTX)) {
511*9781SMoriah.Waterland@Sun.COM if (mapmode != MAPBUILD) {
512*9781SMoriah.Waterland@Sun.COM tempmode_t = bad;
513*9781SMoriah.Waterland@Sun.COM } else {
514*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_MODEBITS));
515*9781SMoriah.Waterland@Sun.COM return (2);
516*9781SMoriah.Waterland@Sun.COM }
517*9781SMoriah.Waterland@Sun.COM }
518*9781SMoriah.Waterland@Sun.COM *d = tempmode_t;
519*9781SMoriah.Waterland@Sun.COM }
520*9781SMoriah.Waterland@Sun.COM }
521*9781SMoriah.Waterland@Sun.COM return (0);
522*9781SMoriah.Waterland@Sun.COM }
523*9781SMoriah.Waterland@Sun.COM }
524*9781SMoriah.Waterland@Sun.COM
525*9781SMoriah.Waterland@Sun.COM static int
getnum(FILE * fp,int base,long * d,long bad)526*9781SMoriah.Waterland@Sun.COM getnum(FILE *fp, int base, long *d, long bad)
527*9781SMoriah.Waterland@Sun.COM {
528*9781SMoriah.Waterland@Sun.COM int c, b;
529*9781SMoriah.Waterland@Sun.COM
530*9781SMoriah.Waterland@Sun.COM /* leading white space ignored */
531*9781SMoriah.Waterland@Sun.COM c = eatwhite(fp);
532*9781SMoriah.Waterland@Sun.COM if (c == '?') {
533*9781SMoriah.Waterland@Sun.COM *d = bad;
534*9781SMoriah.Waterland@Sun.COM return (0);
535*9781SMoriah.Waterland@Sun.COM }
536*9781SMoriah.Waterland@Sun.COM
537*9781SMoriah.Waterland@Sun.COM if ((c == EOF) || (c == '\n') || !isdigit(c)) {
538*9781SMoriah.Waterland@Sun.COM (void) ungetc(c, fp);
539*9781SMoriah.Waterland@Sun.COM return (1);
540*9781SMoriah.Waterland@Sun.COM }
541*9781SMoriah.Waterland@Sun.COM
542*9781SMoriah.Waterland@Sun.COM *d = 0;
543*9781SMoriah.Waterland@Sun.COM while (isdigit(c)) {
544*9781SMoriah.Waterland@Sun.COM b = (c & 017);
545*9781SMoriah.Waterland@Sun.COM if (b >= base)
546*9781SMoriah.Waterland@Sun.COM return (2);
547*9781SMoriah.Waterland@Sun.COM *d = (*d * base) + b;
548*9781SMoriah.Waterland@Sun.COM c = getc(fp);
549*9781SMoriah.Waterland@Sun.COM }
550*9781SMoriah.Waterland@Sun.COM (void) ungetc(c, fp);
551*9781SMoriah.Waterland@Sun.COM return (0);
552*9781SMoriah.Waterland@Sun.COM }
553*9781SMoriah.Waterland@Sun.COM
554*9781SMoriah.Waterland@Sun.COM static int
getlnum(FILE * fp,int base,fsblkcnt_t * d,long bad)555*9781SMoriah.Waterland@Sun.COM getlnum(FILE *fp, int base, fsblkcnt_t *d, long bad)
556*9781SMoriah.Waterland@Sun.COM {
557*9781SMoriah.Waterland@Sun.COM int c, b;
558*9781SMoriah.Waterland@Sun.COM
559*9781SMoriah.Waterland@Sun.COM /* leading white space ignored */
560*9781SMoriah.Waterland@Sun.COM c = eatwhite(fp);
561*9781SMoriah.Waterland@Sun.COM if (c == '?') {
562*9781SMoriah.Waterland@Sun.COM *d = bad;
563*9781SMoriah.Waterland@Sun.COM return (0);
564*9781SMoriah.Waterland@Sun.COM }
565*9781SMoriah.Waterland@Sun.COM
566*9781SMoriah.Waterland@Sun.COM if ((c == EOF) || (c == '\n') || !isdigit(c)) {
567*9781SMoriah.Waterland@Sun.COM (void) ungetc(c, fp);
568*9781SMoriah.Waterland@Sun.COM return (1);
569*9781SMoriah.Waterland@Sun.COM }
570*9781SMoriah.Waterland@Sun.COM
571*9781SMoriah.Waterland@Sun.COM *d = 0;
572*9781SMoriah.Waterland@Sun.COM while (isdigit(c)) {
573*9781SMoriah.Waterland@Sun.COM b = (c & 017);
574*9781SMoriah.Waterland@Sun.COM if (b >= base)
575*9781SMoriah.Waterland@Sun.COM return (2);
576*9781SMoriah.Waterland@Sun.COM *d = (*d * base) + b;
577*9781SMoriah.Waterland@Sun.COM c = getc(fp);
578*9781SMoriah.Waterland@Sun.COM }
579*9781SMoriah.Waterland@Sun.COM (void) ungetc(c, fp);
580*9781SMoriah.Waterland@Sun.COM return (0);
581*9781SMoriah.Waterland@Sun.COM }
582*9781SMoriah.Waterland@Sun.COM
583*9781SMoriah.Waterland@Sun.COM /*
584*9781SMoriah.Waterland@Sun.COM * Get a string from the file. Returns
585*9781SMoriah.Waterland@Sun.COM * 0 if all OK
586*9781SMoriah.Waterland@Sun.COM * 1 if nothing there
587*9781SMoriah.Waterland@Sun.COM * -1 if string is too long
588*9781SMoriah.Waterland@Sun.COM */
589*9781SMoriah.Waterland@Sun.COM static int
getstr(FILE * fp,char * sep,int n,char * str)590*9781SMoriah.Waterland@Sun.COM getstr(FILE *fp, char *sep, int n, char *str)
591*9781SMoriah.Waterland@Sun.COM {
592*9781SMoriah.Waterland@Sun.COM int c;
593*9781SMoriah.Waterland@Sun.COM
594*9781SMoriah.Waterland@Sun.COM /* leading white space ignored */
595*9781SMoriah.Waterland@Sun.COM c = eatwhite(fp);
596*9781SMoriah.Waterland@Sun.COM if ((c == EOF) || (c == '\n')) {
597*9781SMoriah.Waterland@Sun.COM (void) ungetc(c, fp);
598*9781SMoriah.Waterland@Sun.COM return (1); /* nothing there */
599*9781SMoriah.Waterland@Sun.COM }
600*9781SMoriah.Waterland@Sun.COM
601*9781SMoriah.Waterland@Sun.COM /* fill up string until space, tab, or separator */
602*9781SMoriah.Waterland@Sun.COM while (!strchr(" \t", c) && (!sep || !strchr(sep, c))) {
603*9781SMoriah.Waterland@Sun.COM if (n-- < 1) {
604*9781SMoriah.Waterland@Sun.COM *str = '\0';
605*9781SMoriah.Waterland@Sun.COM return (-1); /* too long */
606*9781SMoriah.Waterland@Sun.COM }
607*9781SMoriah.Waterland@Sun.COM *str++ = (char)c;
608*9781SMoriah.Waterland@Sun.COM c = getc(fp);
609*9781SMoriah.Waterland@Sun.COM if ((c == EOF) || (c == '\n'))
610*9781SMoriah.Waterland@Sun.COM break; /* no more on this line */
611*9781SMoriah.Waterland@Sun.COM }
612*9781SMoriah.Waterland@Sun.COM *str = '\0';
613*9781SMoriah.Waterland@Sun.COM (void) ungetc(c, fp);
614*9781SMoriah.Waterland@Sun.COM
615*9781SMoriah.Waterland@Sun.COM return (0);
616*9781SMoriah.Waterland@Sun.COM }
617*9781SMoriah.Waterland@Sun.COM
618*9781SMoriah.Waterland@Sun.COM static int
getend(FILE * fp)619*9781SMoriah.Waterland@Sun.COM getend(FILE *fp)
620*9781SMoriah.Waterland@Sun.COM {
621*9781SMoriah.Waterland@Sun.COM int c;
622*9781SMoriah.Waterland@Sun.COM int n;
623*9781SMoriah.Waterland@Sun.COM
624*9781SMoriah.Waterland@Sun.COM n = 0;
625*9781SMoriah.Waterland@Sun.COM do {
626*9781SMoriah.Waterland@Sun.COM if ((c = getc(fp)) == EOF)
627*9781SMoriah.Waterland@Sun.COM return (n);
628*9781SMoriah.Waterland@Sun.COM if (!isspace(c))
629*9781SMoriah.Waterland@Sun.COM n++;
630*9781SMoriah.Waterland@Sun.COM } while (c != '\n');
631*9781SMoriah.Waterland@Sun.COM return (n);
632*9781SMoriah.Waterland@Sun.COM }
633*9781SMoriah.Waterland@Sun.COM
634*9781SMoriah.Waterland@Sun.COM static int
eatwhite(FILE * fp)635*9781SMoriah.Waterland@Sun.COM eatwhite(FILE *fp)
636*9781SMoriah.Waterland@Sun.COM {
637*9781SMoriah.Waterland@Sun.COM int c;
638*9781SMoriah.Waterland@Sun.COM
639*9781SMoriah.Waterland@Sun.COM /* this test works around a side effect of getc() */
640*9781SMoriah.Waterland@Sun.COM if (feof(fp))
641*9781SMoriah.Waterland@Sun.COM return (EOF);
642*9781SMoriah.Waterland@Sun.COM do
643*9781SMoriah.Waterland@Sun.COM c = getc(fp);
644*9781SMoriah.Waterland@Sun.COM while ((c == ' ') || (c == '\t'));
645*9781SMoriah.Waterland@Sun.COM return (c);
646*9781SMoriah.Waterland@Sun.COM }
647*9781SMoriah.Waterland@Sun.COM
648*9781SMoriah.Waterland@Sun.COM int
gpkgmapvfp(struct cfent * ept,VFP_T * vfp)649*9781SMoriah.Waterland@Sun.COM gpkgmapvfp(struct cfent *ept, VFP_T *vfp)
650*9781SMoriah.Waterland@Sun.COM {
651*9781SMoriah.Waterland@Sun.COM int c;
652*9781SMoriah.Waterland@Sun.COM boolean_t first_char = B_TRUE;
653*9781SMoriah.Waterland@Sun.COM (void) strlcpy(ept->pkg_class, BADCLASS, sizeof (ept->pkg_class));
654*9781SMoriah.Waterland@Sun.COM (void) strlcpy(ept->ainfo.owner, d_owner, sizeof (ept->ainfo.owner));
655*9781SMoriah.Waterland@Sun.COM (void) strlcpy(ept->ainfo.group, d_group, sizeof (ept->ainfo.group));
656*9781SMoriah.Waterland@Sun.COM
657*9781SMoriah.Waterland@Sun.COM setErrstr(NULL);
658*9781SMoriah.Waterland@Sun.COM ept->volno = 0;
659*9781SMoriah.Waterland@Sun.COM ept->ftype = BADFTYPE;
660*9781SMoriah.Waterland@Sun.COM ept->pkg_class_idx = -1;
661*9781SMoriah.Waterland@Sun.COM ept->path = NULL;
662*9781SMoriah.Waterland@Sun.COM ept->ainfo.local = NULL;
663*9781SMoriah.Waterland@Sun.COM ept->ainfo.mode = d_mode;
664*9781SMoriah.Waterland@Sun.COM ept->ainfo.major = BADMAJOR;
665*9781SMoriah.Waterland@Sun.COM ept->ainfo.minor = BADMINOR;
666*9781SMoriah.Waterland@Sun.COM ept->cinfo.cksum = (-1L);
667*9781SMoriah.Waterland@Sun.COM ept->cinfo.modtime = (-1L);
668*9781SMoriah.Waterland@Sun.COM ept->cinfo.size = (-1L);
669*9781SMoriah.Waterland@Sun.COM
670*9781SMoriah.Waterland@Sun.COM ept->npkgs = 0;
671*9781SMoriah.Waterland@Sun.COM
672*9781SMoriah.Waterland@Sun.COM /* return error if no vfp specified */
673*9781SMoriah.Waterland@Sun.COM
674*9781SMoriah.Waterland@Sun.COM if (vfp == (VFP_T *)NULL) {
675*9781SMoriah.Waterland@Sun.COM return (-1);
676*9781SMoriah.Waterland@Sun.COM }
677*9781SMoriah.Waterland@Sun.COM
678*9781SMoriah.Waterland@Sun.COM readline:
679*9781SMoriah.Waterland@Sun.COM while (((c = vfpGetcNoInc(vfp)) != '\0') && (isspace(vfpGetc(vfp))))
680*9781SMoriah.Waterland@Sun.COM ;
681*9781SMoriah.Waterland@Sun.COM
682*9781SMoriah.Waterland@Sun.COM /*
683*9781SMoriah.Waterland@Sun.COM * If the first character is not a digit, we assume that the
684*9781SMoriah.Waterland@Sun.COM * volume number is 1.
685*9781SMoriah.Waterland@Sun.COM */
686*9781SMoriah.Waterland@Sun.COM if (first_char && !isdigit(c)) {
687*9781SMoriah.Waterland@Sun.COM ept->volno = 1;
688*9781SMoriah.Waterland@Sun.COM }
689*9781SMoriah.Waterland@Sun.COM first_char = B_FALSE;
690*9781SMoriah.Waterland@Sun.COM
691*9781SMoriah.Waterland@Sun.COM /*
692*9781SMoriah.Waterland@Sun.COM * In case of hsfs the zero-padding of partial pages
693*9781SMoriah.Waterland@Sun.COM * returned by mmap is not done properly. A separate bug has been filed
694*9781SMoriah.Waterland@Sun.COM * on this.
695*9781SMoriah.Waterland@Sun.COM */
696*9781SMoriah.Waterland@Sun.COM
697*9781SMoriah.Waterland@Sun.COM if (vfp->_vfpCurr && (vfp->_vfpCurr > vfp->_vfpEnd)) {
698*9781SMoriah.Waterland@Sun.COM return (0);
699*9781SMoriah.Waterland@Sun.COM }
700*9781SMoriah.Waterland@Sun.COM
701*9781SMoriah.Waterland@Sun.COM switch (c) {
702*9781SMoriah.Waterland@Sun.COM case '\0':
703*9781SMoriah.Waterland@Sun.COM return (0);
704*9781SMoriah.Waterland@Sun.COM
705*9781SMoriah.Waterland@Sun.COM case '0':
706*9781SMoriah.Waterland@Sun.COM case '1':
707*9781SMoriah.Waterland@Sun.COM case '2':
708*9781SMoriah.Waterland@Sun.COM case '3':
709*9781SMoriah.Waterland@Sun.COM case '4':
710*9781SMoriah.Waterland@Sun.COM case '5':
711*9781SMoriah.Waterland@Sun.COM case '6':
712*9781SMoriah.Waterland@Sun.COM case '7':
713*9781SMoriah.Waterland@Sun.COM case '8':
714*9781SMoriah.Waterland@Sun.COM case '9':
715*9781SMoriah.Waterland@Sun.COM if (ept->volno) {
716*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_BAD_VOLUME_NUMBER));
717*9781SMoriah.Waterland@Sun.COM goto error;
718*9781SMoriah.Waterland@Sun.COM }
719*9781SMoriah.Waterland@Sun.COM do {
720*9781SMoriah.Waterland@Sun.COM ept->volno = (ept->volno*10)+c-'0';
721*9781SMoriah.Waterland@Sun.COM c = vfpGetc(vfp);
722*9781SMoriah.Waterland@Sun.COM } while (isdigit(c));
723*9781SMoriah.Waterland@Sun.COM if (ept->volno == 0) {
724*9781SMoriah.Waterland@Sun.COM ept->volno = 1;
725*9781SMoriah.Waterland@Sun.COM }
726*9781SMoriah.Waterland@Sun.COM
727*9781SMoriah.Waterland@Sun.COM goto readline;
728*9781SMoriah.Waterland@Sun.COM
729*9781SMoriah.Waterland@Sun.COM case ':':
730*9781SMoriah.Waterland@Sun.COM case '#':
731*9781SMoriah.Waterland@Sun.COM (void) findendvfp(&vfpGetCurrCharPtr(vfp));
732*9781SMoriah.Waterland@Sun.COM /*FALLTHRU*/
733*9781SMoriah.Waterland@Sun.COM case '\n':
734*9781SMoriah.Waterland@Sun.COM /*
735*9781SMoriah.Waterland@Sun.COM * Since we are going to scan the next line,
736*9781SMoriah.Waterland@Sun.COM * we need to reset volume number and first_char.
737*9781SMoriah.Waterland@Sun.COM */
738*9781SMoriah.Waterland@Sun.COM ept->volno = 0;
739*9781SMoriah.Waterland@Sun.COM first_char = B_TRUE;
740*9781SMoriah.Waterland@Sun.COM goto readline;
741*9781SMoriah.Waterland@Sun.COM
742*9781SMoriah.Waterland@Sun.COM case 'i':
743*9781SMoriah.Waterland@Sun.COM ept->ftype = (char)c;
744*9781SMoriah.Waterland@Sun.COM while (((c = vfpGetcNoInc(vfp)) != '\0') &&
745*9781SMoriah.Waterland@Sun.COM (isspace(vfpGetc(vfp))))
746*9781SMoriah.Waterland@Sun.COM ;
747*9781SMoriah.Waterland@Sun.COM /*FALLTHRU*/
748*9781SMoriah.Waterland@Sun.COM case '.':
749*9781SMoriah.Waterland@Sun.COM case '/':
750*9781SMoriah.Waterland@Sun.COM vfpDecCurrPtr(vfp);
751*9781SMoriah.Waterland@Sun.COM
752*9781SMoriah.Waterland@Sun.COM if (getstrvfp(&vfpGetCurrCharPtr(vfp), "=", PATH_MAX, mypath)) {
753*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
754*9781SMoriah.Waterland@Sun.COM goto error;
755*9781SMoriah.Waterland@Sun.COM }
756*9781SMoriah.Waterland@Sun.COM ept->path = mypath;
757*9781SMoriah.Waterland@Sun.COM c = vfpGetc(vfp);
758*9781SMoriah.Waterland@Sun.COM if (c == '=') {
759*9781SMoriah.Waterland@Sun.COM if (getstrvfp(&vfpGetCurrCharPtr(vfp), NULL, PATH_MAX,
760*9781SMoriah.Waterland@Sun.COM mylocal)) {
761*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANT_READ_LCLPATH));
762*9781SMoriah.Waterland@Sun.COM goto error;
763*9781SMoriah.Waterland@Sun.COM }
764*9781SMoriah.Waterland@Sun.COM ept->ainfo.local = mylocal;
765*9781SMoriah.Waterland@Sun.COM } else {
766*9781SMoriah.Waterland@Sun.COM vfpDecCurrPtr(vfp);
767*9781SMoriah.Waterland@Sun.COM }
768*9781SMoriah.Waterland@Sun.COM
769*9781SMoriah.Waterland@Sun.COM if (ept->ftype == 'i') {
770*9781SMoriah.Waterland@Sun.COM /* content info might exist */
771*9781SMoriah.Waterland@Sun.COM if (!getlnumvfp(&vfpGetCurrCharPtr(vfp), 10,
772*9781SMoriah.Waterland@Sun.COM (fsblkcnt_t *)&ept->cinfo.size, BADCONT) &&
773*9781SMoriah.Waterland@Sun.COM (getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
774*9781SMoriah.Waterland@Sun.COM (long *)&ept->cinfo.cksum, BADCONT) ||
775*9781SMoriah.Waterland@Sun.COM getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
776*9781SMoriah.Waterland@Sun.COM (long *)&ept->cinfo.modtime, BADCONT))) {
777*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
778*9781SMoriah.Waterland@Sun.COM goto error;
779*9781SMoriah.Waterland@Sun.COM }
780*9781SMoriah.Waterland@Sun.COM }
781*9781SMoriah.Waterland@Sun.COM
782*9781SMoriah.Waterland@Sun.COM if (getendvfp(&vfpGetCurrCharPtr(vfp))) {
783*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
784*9781SMoriah.Waterland@Sun.COM return (-1);
785*9781SMoriah.Waterland@Sun.COM }
786*9781SMoriah.Waterland@Sun.COM return (1);
787*9781SMoriah.Waterland@Sun.COM
788*9781SMoriah.Waterland@Sun.COM case '?':
789*9781SMoriah.Waterland@Sun.COM case 'f':
790*9781SMoriah.Waterland@Sun.COM case 'v':
791*9781SMoriah.Waterland@Sun.COM case 'e':
792*9781SMoriah.Waterland@Sun.COM case 'l':
793*9781SMoriah.Waterland@Sun.COM case 's':
794*9781SMoriah.Waterland@Sun.COM case 'p':
795*9781SMoriah.Waterland@Sun.COM case 'c':
796*9781SMoriah.Waterland@Sun.COM case 'b':
797*9781SMoriah.Waterland@Sun.COM case 'd':
798*9781SMoriah.Waterland@Sun.COM case 'x':
799*9781SMoriah.Waterland@Sun.COM ept->ftype = (char)c;
800*9781SMoriah.Waterland@Sun.COM if (getstrvfp(&vfpGetCurrCharPtr(vfp), NULL,
801*9781SMoriah.Waterland@Sun.COM CLSSIZ, ept->pkg_class)) {
802*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_CLASS_TOKEN));
803*9781SMoriah.Waterland@Sun.COM goto error;
804*9781SMoriah.Waterland@Sun.COM }
805*9781SMoriah.Waterland@Sun.COM if (getstrvfp(&vfpGetCurrCharPtr(vfp), "=", PATH_MAX, mypath)) {
806*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
807*9781SMoriah.Waterland@Sun.COM goto error;
808*9781SMoriah.Waterland@Sun.COM }
809*9781SMoriah.Waterland@Sun.COM ept->path = mypath;
810*9781SMoriah.Waterland@Sun.COM
811*9781SMoriah.Waterland@Sun.COM c = vfpGetc(vfp);
812*9781SMoriah.Waterland@Sun.COM if (c == '=') {
813*9781SMoriah.Waterland@Sun.COM /* local path */
814*9781SMoriah.Waterland@Sun.COM if (getstrvfp(&vfpGetCurrCharPtr(vfp), NULL,
815*9781SMoriah.Waterland@Sun.COM PATH_MAX, mylocal)) {
816*9781SMoriah.Waterland@Sun.COM if (ept->ftype == 's' || ept->ftype == 'l') {
817*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_READLINK));
818*9781SMoriah.Waterland@Sun.COM } else {
819*9781SMoriah.Waterland@Sun.COM setErrstr(
820*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_CANT_READ_LCLPATH));
821*9781SMoriah.Waterland@Sun.COM }
822*9781SMoriah.Waterland@Sun.COM goto error;
823*9781SMoriah.Waterland@Sun.COM }
824*9781SMoriah.Waterland@Sun.COM ept->ainfo.local = mylocal;
825*9781SMoriah.Waterland@Sun.COM } else if ((ept->ftype == 's') || (ept->ftype == 'l')) {
826*9781SMoriah.Waterland@Sun.COM if ((c != '\0') && (c != '\n'))
827*9781SMoriah.Waterland@Sun.COM (void) findendvfp(&vfpGetCurrCharPtr(vfp));
828*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_BAD_LINK_SPEC));
829*9781SMoriah.Waterland@Sun.COM return (-1);
830*9781SMoriah.Waterland@Sun.COM } else {
831*9781SMoriah.Waterland@Sun.COM vfpDecCurrPtr(vfp);
832*9781SMoriah.Waterland@Sun.COM }
833*9781SMoriah.Waterland@Sun.COM break;
834*9781SMoriah.Waterland@Sun.COM
835*9781SMoriah.Waterland@Sun.COM default:
836*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_UNKNOWN_FTYPE));
837*9781SMoriah.Waterland@Sun.COM error:
838*9781SMoriah.Waterland@Sun.COM (void) findendvfp(&vfpGetCurrCharPtr(vfp));
839*9781SMoriah.Waterland@Sun.COM return (-1);
840*9781SMoriah.Waterland@Sun.COM }
841*9781SMoriah.Waterland@Sun.COM
842*9781SMoriah.Waterland@Sun.COM if (((ept->ftype == 's') || (ept->ftype == 'l')) &&
843*9781SMoriah.Waterland@Sun.COM (ept->ainfo.local == NULL)) {
844*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_NO_LINKSOURCE));
845*9781SMoriah.Waterland@Sun.COM goto error;
846*9781SMoriah.Waterland@Sun.COM }
847*9781SMoriah.Waterland@Sun.COM
848*9781SMoriah.Waterland@Sun.COM if (((ept->ftype == 'c') || (ept->ftype == 'b'))) {
849*9781SMoriah.Waterland@Sun.COM ept->ainfo.major = BADMAJOR;
850*9781SMoriah.Waterland@Sun.COM ept->ainfo.minor = BADMINOR;
851*9781SMoriah.Waterland@Sun.COM
852*9781SMoriah.Waterland@Sun.COM if (getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
853*9781SMoriah.Waterland@Sun.COM (long *)&ept->ainfo.major, BADMAJOR) ||
854*9781SMoriah.Waterland@Sun.COM getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
855*9781SMoriah.Waterland@Sun.COM (long *)&ept->ainfo.minor, BADMINOR)) {
856*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_MM_DEVNUMS));
857*9781SMoriah.Waterland@Sun.COM goto error;
858*9781SMoriah.Waterland@Sun.COM }
859*9781SMoriah.Waterland@Sun.COM }
860*9781SMoriah.Waterland@Sun.COM
861*9781SMoriah.Waterland@Sun.COM /*
862*9781SMoriah.Waterland@Sun.COM * Links and information files don't have attributes associated with
863*9781SMoriah.Waterland@Sun.COM * them. The following either resolves potential variables or passes
864*9781SMoriah.Waterland@Sun.COM * them through. Mode is tested for validity to some degree. BAD???
865*9781SMoriah.Waterland@Sun.COM * is returned to indicate that no meaningful mode was provided. A
866*9781SMoriah.Waterland@Sun.COM * higher authority will decide if that's OK or not. CUR??? means that
867*9781SMoriah.Waterland@Sun.COM * the prototype file specifically requires a wildcard ('?') for
868*9781SMoriah.Waterland@Sun.COM * that entry. We issue an error if attributes were entered wrong.
869*9781SMoriah.Waterland@Sun.COM * We just return BAD??? if there was no entry at all.
870*9781SMoriah.Waterland@Sun.COM */
871*9781SMoriah.Waterland@Sun.COM if ((ept->ftype == 'd') || (ept->ftype == 'x') || (ept->ftype == 'c') ||
872*9781SMoriah.Waterland@Sun.COM (ept->ftype == 'b') || (ept->ftype == 'p') ||
873*9781SMoriah.Waterland@Sun.COM (ept->ftype == 'f') || (ept->ftype == 'v') ||
874*9781SMoriah.Waterland@Sun.COM (ept->ftype == 'e')) {
875*9781SMoriah.Waterland@Sun.COM int retval;
876*9781SMoriah.Waterland@Sun.COM
877*9781SMoriah.Waterland@Sun.COM retval = getvalmodevfp(&vfpGetCurrCharPtr(vfp),
878*9781SMoriah.Waterland@Sun.COM &(ept->ainfo.mode),
879*9781SMoriah.Waterland@Sun.COM CURMODE, (mapmode != MAPNONE));
880*9781SMoriah.Waterland@Sun.COM
881*9781SMoriah.Waterland@Sun.COM if (retval == 1) {
882*9781SMoriah.Waterland@Sun.COM goto end; /* nothing else on the line */
883*9781SMoriah.Waterland@Sun.COM } else if (retval == 2) {
884*9781SMoriah.Waterland@Sun.COM goto error; /* mode is too no good */
885*9781SMoriah.Waterland@Sun.COM }
886*9781SMoriah.Waterland@Sun.COM
887*9781SMoriah.Waterland@Sun.COM /* owner & group should be here */
888*9781SMoriah.Waterland@Sun.COM if ((retval = getstrvfp(&vfpGetCurrCharPtr(vfp), NULL, ATRSIZ,
889*9781SMoriah.Waterland@Sun.COM ept->ainfo.owner)) == 1)
890*9781SMoriah.Waterland@Sun.COM goto end; /* no owner or group - warning */
891*9781SMoriah.Waterland@Sun.COM if (retval == -1) {
892*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_OWNTOOLONG));
893*9781SMoriah.Waterland@Sun.COM goto error;
894*9781SMoriah.Waterland@Sun.COM }
895*9781SMoriah.Waterland@Sun.COM
896*9781SMoriah.Waterland@Sun.COM if ((retval = getstrvfp(&vfpGetCurrCharPtr(vfp), NULL, ATRSIZ,
897*9781SMoriah.Waterland@Sun.COM ept->ainfo.group)) == 1)
898*9781SMoriah.Waterland@Sun.COM goto end; /* no group - warning */
899*9781SMoriah.Waterland@Sun.COM if (retval == -1) {
900*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_GRPTOOLONG));
901*9781SMoriah.Waterland@Sun.COM goto error;
902*9781SMoriah.Waterland@Sun.COM }
903*9781SMoriah.Waterland@Sun.COM
904*9781SMoriah.Waterland@Sun.COM /* Resolve the parameters if required. */
905*9781SMoriah.Waterland@Sun.COM if (mapmode != MAPNONE) {
906*9781SMoriah.Waterland@Sun.COM if (mapvar(mapmode, ept->ainfo.owner)) {
907*9781SMoriah.Waterland@Sun.COM (void) snprintf(getErrbufAddr(),
908*9781SMoriah.Waterland@Sun.COM getErrbufSize(), pkg_gt(ERR_NOVAR),
909*9781SMoriah.Waterland@Sun.COM maptype, ept->ainfo.owner);
910*9781SMoriah.Waterland@Sun.COM setErrstr(getErrbufAddr());
911*9781SMoriah.Waterland@Sun.COM goto error;
912*9781SMoriah.Waterland@Sun.COM }
913*9781SMoriah.Waterland@Sun.COM if (mapvar(mapmode, ept->ainfo.group)) {
914*9781SMoriah.Waterland@Sun.COM (void) snprintf(getErrbufAddr(),
915*9781SMoriah.Waterland@Sun.COM getErrbufSize(), pkg_gt(ERR_NOVAR),
916*9781SMoriah.Waterland@Sun.COM maptype, ept->ainfo.group);
917*9781SMoriah.Waterland@Sun.COM setErrstr(getErrbufAddr());
918*9781SMoriah.Waterland@Sun.COM goto error;
919*9781SMoriah.Waterland@Sun.COM }
920*9781SMoriah.Waterland@Sun.COM }
921*9781SMoriah.Waterland@Sun.COM }
922*9781SMoriah.Waterland@Sun.COM
923*9781SMoriah.Waterland@Sun.COM if ((ept->ftype == 'i') || (ept->ftype == 'f') ||
924*9781SMoriah.Waterland@Sun.COM (ept->ftype == 'v') || (ept->ftype == 'e')) {
925*9781SMoriah.Waterland@Sun.COM /* look for content description */
926*9781SMoriah.Waterland@Sun.COM if (!getlnumvfp(&vfpGetCurrCharPtr(vfp), 10,
927*9781SMoriah.Waterland@Sun.COM (fsblkcnt_t *)&ept->cinfo.size, BADCONT) &&
928*9781SMoriah.Waterland@Sun.COM (getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
929*9781SMoriah.Waterland@Sun.COM (long *)&ept->cinfo.cksum, BADCONT) ||
930*9781SMoriah.Waterland@Sun.COM getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
931*9781SMoriah.Waterland@Sun.COM (long *)&ept->cinfo.modtime, BADCONT))) {
932*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
933*9781SMoriah.Waterland@Sun.COM goto error;
934*9781SMoriah.Waterland@Sun.COM }
935*9781SMoriah.Waterland@Sun.COM }
936*9781SMoriah.Waterland@Sun.COM
937*9781SMoriah.Waterland@Sun.COM if (ept->ftype == 'i')
938*9781SMoriah.Waterland@Sun.COM goto end;
939*9781SMoriah.Waterland@Sun.COM
940*9781SMoriah.Waterland@Sun.COM end:
941*9781SMoriah.Waterland@Sun.COM if (getendvfp(&vfpGetCurrCharPtr(vfp)) && ept->pinfo) {
942*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
943*9781SMoriah.Waterland@Sun.COM return (-1);
944*9781SMoriah.Waterland@Sun.COM }
945*9781SMoriah.Waterland@Sun.COM
946*9781SMoriah.Waterland@Sun.COM done:
947*9781SMoriah.Waterland@Sun.COM return (1);
948*9781SMoriah.Waterland@Sun.COM }
949*9781SMoriah.Waterland@Sun.COM
950*9781SMoriah.Waterland@Sun.COM /*
951*9781SMoriah.Waterland@Sun.COM * Get and validate the mode attribute. This returns an error if
952*9781SMoriah.Waterland@Sun.COM * 1. the mode string is too long
953*9781SMoriah.Waterland@Sun.COM * 2. the mode string includes alpha characters
954*9781SMoriah.Waterland@Sun.COM * 3. the mode string is not octal
955*9781SMoriah.Waterland@Sun.COM * 4. mode string is an install parameter
956*9781SMoriah.Waterland@Sun.COM * 5. mode is an unresolved build parameter and MAPBUILD is
957*9781SMoriah.Waterland@Sun.COM * in effect.
958*9781SMoriah.Waterland@Sun.COM * If the mode is a build parameter, it is
959*9781SMoriah.Waterland@Sun.COM * 1. returned as is if MAPNONE is in effect
960*9781SMoriah.Waterland@Sun.COM * 2. evaluated if MAPBUILD is in effect
961*9781SMoriah.Waterland@Sun.COM *
962*9781SMoriah.Waterland@Sun.COM * NOTE : We use "mapmode!=MAPBUILD" to gather that it is install
963*9781SMoriah.Waterland@Sun.COM * time. At install time we just fix a mode with bad bits set by
964*9781SMoriah.Waterland@Sun.COM * setting it to CURMODE. This should be an error in a few releases
965*9781SMoriah.Waterland@Sun.COM * (2.8 maybe) but faulty modes are so common in existing packages
966*9781SMoriah.Waterland@Sun.COM * that this is a reasonable exception. -- JST 1994-11-9
967*9781SMoriah.Waterland@Sun.COM *
968*9781SMoriah.Waterland@Sun.COM * RETURNS
969*9781SMoriah.Waterland@Sun.COM * 0 if mode is being returned as a valid value
970*9781SMoriah.Waterland@Sun.COM * 1 if no attributes are present on the line
971*9781SMoriah.Waterland@Sun.COM * 2 if there was a fundamental error
972*9781SMoriah.Waterland@Sun.COM */
973*9781SMoriah.Waterland@Sun.COM static int
getvalmodevfp(char ** cp,mode_t * d,long bad,int map)974*9781SMoriah.Waterland@Sun.COM getvalmodevfp(char **cp, mode_t *d, long bad, int map)
975*9781SMoriah.Waterland@Sun.COM {
976*9781SMoriah.Waterland@Sun.COM char tempmode[ATRSIZ+1];
977*9781SMoriah.Waterland@Sun.COM mode_t tempmode_t;
978*9781SMoriah.Waterland@Sun.COM int retval;
979*9781SMoriah.Waterland@Sun.COM int n;
980*9781SMoriah.Waterland@Sun.COM
981*9781SMoriah.Waterland@Sun.COM if ((retval = getstrvfp(cp, NULL, sizeof (tempmode), tempmode)) == 1) {
982*9781SMoriah.Waterland@Sun.COM return (1);
983*9781SMoriah.Waterland@Sun.COM } else if (retval == -1) {
984*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_MODELONG));
985*9781SMoriah.Waterland@Sun.COM return (2);
986*9781SMoriah.Waterland@Sun.COM }
987*9781SMoriah.Waterland@Sun.COM
988*9781SMoriah.Waterland@Sun.COM /*
989*9781SMoriah.Waterland@Sun.COM * If it isn't a '?' (meaning go with whatever mode is
990*9781SMoriah.Waterland@Sun.COM * there), validate the mode and convert it to a mode_t. The
991*9781SMoriah.Waterland@Sun.COM * "bad" variable here is a misnomer. It doesn't necessarily
992*9781SMoriah.Waterland@Sun.COM * mean bad.
993*9781SMoriah.Waterland@Sun.COM */
994*9781SMoriah.Waterland@Sun.COM if (tempmode[0] == '?') {
995*9781SMoriah.Waterland@Sun.COM *d = WILDCARD;
996*9781SMoriah.Waterland@Sun.COM return (0);
997*9781SMoriah.Waterland@Sun.COM }
998*9781SMoriah.Waterland@Sun.COM
999*9781SMoriah.Waterland@Sun.COM /*
1000*9781SMoriah.Waterland@Sun.COM * Mode may not be an install parameter or a
1001*9781SMoriah.Waterland@Sun.COM * non-build parameter.
1002*9781SMoriah.Waterland@Sun.COM */
1003*9781SMoriah.Waterland@Sun.COM
1004*9781SMoriah.Waterland@Sun.COM if (tempmode[0] == '$' &&
1005*9781SMoriah.Waterland@Sun.COM (isupper(tempmode[1]) || !islower(tempmode[1]))) {
1006*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_IMODE));
1007*9781SMoriah.Waterland@Sun.COM return (2);
1008*9781SMoriah.Waterland@Sun.COM }
1009*9781SMoriah.Waterland@Sun.COM
1010*9781SMoriah.Waterland@Sun.COM if ((map) && (mapvar(mapmode, tempmode))) {
1011*9781SMoriah.Waterland@Sun.COM (void) snprintf(getErrbufAddr(), getErrbufSize(),
1012*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_NOVAR), maptype, tempmode);
1013*9781SMoriah.Waterland@Sun.COM setErrstr(getErrbufAddr());
1014*9781SMoriah.Waterland@Sun.COM return (2);
1015*9781SMoriah.Waterland@Sun.COM }
1016*9781SMoriah.Waterland@Sun.COM
1017*9781SMoriah.Waterland@Sun.COM if (tempmode[0] == '$') {
1018*9781SMoriah.Waterland@Sun.COM *d = BADMODE; /* may be a problem */
1019*9781SMoriah.Waterland@Sun.COM return (0);
1020*9781SMoriah.Waterland@Sun.COM }
1021*9781SMoriah.Waterland@Sun.COM
1022*9781SMoriah.Waterland@Sun.COM /* it's supposed to be something we can convert to a number */
1023*9781SMoriah.Waterland@Sun.COM
1024*9781SMoriah.Waterland@Sun.COM n = 0;
1025*9781SMoriah.Waterland@Sun.COM
1026*9781SMoriah.Waterland@Sun.COM /* reject it if it contains nonnumbers or it's not octal */
1027*9781SMoriah.Waterland@Sun.COM
1028*9781SMoriah.Waterland@Sun.COM while (tempmode[n] && !isspace(tempmode[n])) {
1029*9781SMoriah.Waterland@Sun.COM if (!isdigit(tempmode[n])) {
1030*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_MODEALPHA));
1031*9781SMoriah.Waterland@Sun.COM return (2);
1032*9781SMoriah.Waterland@Sun.COM }
1033*9781SMoriah.Waterland@Sun.COM
1034*9781SMoriah.Waterland@Sun.COM if (strchr("89abcdefABCDEF", tempmode[n])) {
1035*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_BASEINVAL));
1036*9781SMoriah.Waterland@Sun.COM return (2);
1037*9781SMoriah.Waterland@Sun.COM }
1038*9781SMoriah.Waterland@Sun.COM n++;
1039*9781SMoriah.Waterland@Sun.COM }
1040*9781SMoriah.Waterland@Sun.COM
1041*9781SMoriah.Waterland@Sun.COM tempmode_t = strtol(tempmode, NULL, 8);
1042*9781SMoriah.Waterland@Sun.COM
1043*9781SMoriah.Waterland@Sun.COM /*
1044*9781SMoriah.Waterland@Sun.COM * We reject it if it contains inappropriate
1045*9781SMoriah.Waterland@Sun.COM * bits.
1046*9781SMoriah.Waterland@Sun.COM */
1047*9781SMoriah.Waterland@Sun.COM if (tempmode_t & (~(S_IAMB | S_ISUID | S_ISGID | S_ISVTX))) {
1048*9781SMoriah.Waterland@Sun.COM if (mapmode == MAPBUILD) {
1049*9781SMoriah.Waterland@Sun.COM setErrstr(pkg_gt(ERR_MODEBITS));
1050*9781SMoriah.Waterland@Sun.COM return (2);
1051*9781SMoriah.Waterland@Sun.COM }
1052*9781SMoriah.Waterland@Sun.COM tempmode_t = bad;
1053*9781SMoriah.Waterland@Sun.COM }
1054*9781SMoriah.Waterland@Sun.COM
1055*9781SMoriah.Waterland@Sun.COM *d = tempmode_t;
1056*9781SMoriah.Waterland@Sun.COM
1057*9781SMoriah.Waterland@Sun.COM return (0);
1058*9781SMoriah.Waterland@Sun.COM }
1059*9781SMoriah.Waterland@Sun.COM
1060*9781SMoriah.Waterland@Sun.COM int
getnumvfp(char ** cp,int base,long * d,long bad)1061*9781SMoriah.Waterland@Sun.COM getnumvfp(char **cp, int base, long *d, long bad)
1062*9781SMoriah.Waterland@Sun.COM {
1063*9781SMoriah.Waterland@Sun.COM int c;
1064*9781SMoriah.Waterland@Sun.COM char *p = *cp;
1065*9781SMoriah.Waterland@Sun.COM
1066*9781SMoriah.Waterland@Sun.COM if (*p == '\0') {
1067*9781SMoriah.Waterland@Sun.COM return (0);
1068*9781SMoriah.Waterland@Sun.COM }
1069*9781SMoriah.Waterland@Sun.COM
1070*9781SMoriah.Waterland@Sun.COM /* leading white space ignored */
1071*9781SMoriah.Waterland@Sun.COM while (((c = *p) != '\0') && (isspace(*p++)))
1072*9781SMoriah.Waterland@Sun.COM ;
1073*9781SMoriah.Waterland@Sun.COM if (c == '?') {
1074*9781SMoriah.Waterland@Sun.COM *d = bad;
1075*9781SMoriah.Waterland@Sun.COM *cp = p;
1076*9781SMoriah.Waterland@Sun.COM return (0);
1077*9781SMoriah.Waterland@Sun.COM }
1078*9781SMoriah.Waterland@Sun.COM
1079*9781SMoriah.Waterland@Sun.COM if ((c == '\0') || (c == '\n') || !isdigit(c)) {
1080*9781SMoriah.Waterland@Sun.COM p--;
1081*9781SMoriah.Waterland@Sun.COM *cp = p;
1082*9781SMoriah.Waterland@Sun.COM return (1);
1083*9781SMoriah.Waterland@Sun.COM }
1084*9781SMoriah.Waterland@Sun.COM
1085*9781SMoriah.Waterland@Sun.COM *d = 0;
1086*9781SMoriah.Waterland@Sun.COM while (isdigit(c)) {
1087*9781SMoriah.Waterland@Sun.COM *d = (*d * base) + (c & 017);
1088*9781SMoriah.Waterland@Sun.COM c = *p++;
1089*9781SMoriah.Waterland@Sun.COM }
1090*9781SMoriah.Waterland@Sun.COM p--;
1091*9781SMoriah.Waterland@Sun.COM *cp = p;
1092*9781SMoriah.Waterland@Sun.COM return (0);
1093*9781SMoriah.Waterland@Sun.COM }
1094*9781SMoriah.Waterland@Sun.COM
1095*9781SMoriah.Waterland@Sun.COM int
getlnumvfp(char ** cp,int base,fsblkcnt_t * d,long bad)1096*9781SMoriah.Waterland@Sun.COM getlnumvfp(char **cp, int base, fsblkcnt_t *d, long bad)
1097*9781SMoriah.Waterland@Sun.COM {
1098*9781SMoriah.Waterland@Sun.COM int c;
1099*9781SMoriah.Waterland@Sun.COM char *p = *cp;
1100*9781SMoriah.Waterland@Sun.COM
1101*9781SMoriah.Waterland@Sun.COM if (*p == '\0') {
1102*9781SMoriah.Waterland@Sun.COM return (0);
1103*9781SMoriah.Waterland@Sun.COM }
1104*9781SMoriah.Waterland@Sun.COM
1105*9781SMoriah.Waterland@Sun.COM /* leading white space ignored */
1106*9781SMoriah.Waterland@Sun.COM while (((c = *p) != '\0') && (isspace(*p++)))
1107*9781SMoriah.Waterland@Sun.COM ;
1108*9781SMoriah.Waterland@Sun.COM if (c == '?') {
1109*9781SMoriah.Waterland@Sun.COM *d = bad;
1110*9781SMoriah.Waterland@Sun.COM *cp = p;
1111*9781SMoriah.Waterland@Sun.COM return (0);
1112*9781SMoriah.Waterland@Sun.COM }
1113*9781SMoriah.Waterland@Sun.COM
1114*9781SMoriah.Waterland@Sun.COM if ((c == '\0') || (c == '\n') || !isdigit(c)) {
1115*9781SMoriah.Waterland@Sun.COM p--;
1116*9781SMoriah.Waterland@Sun.COM *cp = p;
1117*9781SMoriah.Waterland@Sun.COM return (1);
1118*9781SMoriah.Waterland@Sun.COM }
1119*9781SMoriah.Waterland@Sun.COM
1120*9781SMoriah.Waterland@Sun.COM *d = 0;
1121*9781SMoriah.Waterland@Sun.COM while (isdigit(c)) {
1122*9781SMoriah.Waterland@Sun.COM *d = (*d * base) + (c & 017);
1123*9781SMoriah.Waterland@Sun.COM c = *p++;
1124*9781SMoriah.Waterland@Sun.COM }
1125*9781SMoriah.Waterland@Sun.COM p--;
1126*9781SMoriah.Waterland@Sun.COM *cp = p;
1127*9781SMoriah.Waterland@Sun.COM return (0);
1128*9781SMoriah.Waterland@Sun.COM }
1129*9781SMoriah.Waterland@Sun.COM
1130*9781SMoriah.Waterland@Sun.COM static int
getstrvfp(char ** cp,char * sep,int n,char * str)1131*9781SMoriah.Waterland@Sun.COM getstrvfp(char **cp, char *sep, int n, char *str)
1132*9781SMoriah.Waterland@Sun.COM {
1133*9781SMoriah.Waterland@Sun.COM char delims[256];
1134*9781SMoriah.Waterland@Sun.COM int c;
1135*9781SMoriah.Waterland@Sun.COM char *p = *cp;
1136*9781SMoriah.Waterland@Sun.COM char *p1;
1137*9781SMoriah.Waterland@Sun.COM size_t len;
1138*9781SMoriah.Waterland@Sun.COM
1139*9781SMoriah.Waterland@Sun.COM if (*p == '\0') {
1140*9781SMoriah.Waterland@Sun.COM return (1);
1141*9781SMoriah.Waterland@Sun.COM }
1142*9781SMoriah.Waterland@Sun.COM
1143*9781SMoriah.Waterland@Sun.COM /* leading white space ignored */
1144*9781SMoriah.Waterland@Sun.COM
1145*9781SMoriah.Waterland@Sun.COM while (((c = *p) != '\0') && (isspace(*p++)))
1146*9781SMoriah.Waterland@Sun.COM ;
1147*9781SMoriah.Waterland@Sun.COM if ((c == '\0') || (c == '\n')) {
1148*9781SMoriah.Waterland@Sun.COM p--;
1149*9781SMoriah.Waterland@Sun.COM *cp = p;
1150*9781SMoriah.Waterland@Sun.COM return (1); /* nothing there */
1151*9781SMoriah.Waterland@Sun.COM }
1152*9781SMoriah.Waterland@Sun.COM
1153*9781SMoriah.Waterland@Sun.COM p--;
1154*9781SMoriah.Waterland@Sun.COM
1155*9781SMoriah.Waterland@Sun.COM /* generate complete list of delimiters to scan for */
1156*9781SMoriah.Waterland@Sun.COM
1157*9781SMoriah.Waterland@Sun.COM (void) strlcpy(delims, " \t\n", sizeof (delims));
1158*9781SMoriah.Waterland@Sun.COM if ((sep != (char *)NULL) && (*sep != '\0')) {
1159*9781SMoriah.Waterland@Sun.COM (void) strlcat(delims, sep, sizeof (delims));
1160*9781SMoriah.Waterland@Sun.COM }
1161*9781SMoriah.Waterland@Sun.COM
1162*9781SMoriah.Waterland@Sun.COM /* compute length based on delimiter found or not */
1163*9781SMoriah.Waterland@Sun.COM
1164*9781SMoriah.Waterland@Sun.COM p1 = strpbrk(p, delims);
1165*9781SMoriah.Waterland@Sun.COM if (p1 == (char *)NULL) {
1166*9781SMoriah.Waterland@Sun.COM len = strlen(p);
1167*9781SMoriah.Waterland@Sun.COM } else {
1168*9781SMoriah.Waterland@Sun.COM len = (ptrdiff_t)p1 - (ptrdiff_t)p;
1169*9781SMoriah.Waterland@Sun.COM }
1170*9781SMoriah.Waterland@Sun.COM
1171*9781SMoriah.Waterland@Sun.COM /* if string will fit in result buffer copy string and return success */
1172*9781SMoriah.Waterland@Sun.COM
1173*9781SMoriah.Waterland@Sun.COM if (len < n) {
1174*9781SMoriah.Waterland@Sun.COM (void) memcpy(str, p, len);
1175*9781SMoriah.Waterland@Sun.COM str[len] = '\0';
1176*9781SMoriah.Waterland@Sun.COM p += len;
1177*9781SMoriah.Waterland@Sun.COM *cp = p;
1178*9781SMoriah.Waterland@Sun.COM return (0);
1179*9781SMoriah.Waterland@Sun.COM }
1180*9781SMoriah.Waterland@Sun.COM
1181*9781SMoriah.Waterland@Sun.COM /* result buffer too small; copy partial string, return error */
1182*9781SMoriah.Waterland@Sun.COM (void) memcpy(str, p, n-1);
1183*9781SMoriah.Waterland@Sun.COM str[n-1] = '\0';
1184*9781SMoriah.Waterland@Sun.COM p += n;
1185*9781SMoriah.Waterland@Sun.COM *cp = p;
1186*9781SMoriah.Waterland@Sun.COM return (-1);
1187*9781SMoriah.Waterland@Sun.COM }
1188*9781SMoriah.Waterland@Sun.COM
1189*9781SMoriah.Waterland@Sun.COM /*
1190*9781SMoriah.Waterland@Sun.COM * Name: getendvfp
1191*9781SMoriah.Waterland@Sun.COM * Description: Locate the end of the current line given a pointer into a buffer
1192*9781SMoriah.Waterland@Sun.COM * containing characters that is null terminated.
1193*9781SMoriah.Waterland@Sun.COM * Arguments: char **cp - pointer to pointer to null-terminated string buffer
1194*9781SMoriah.Waterland@Sun.COM * Returns: int == 0 -- no non-space characters preceeded the newline
1195*9781SMoriah.Waterland@Sun.COM * != 0 -- one or more non-space characters preceeded newline
1196*9781SMoriah.Waterland@Sun.COM * Effects: cp is updated to point to the first character PAST the first new
1197*9781SMoriah.Waterland@Sun.COM * line character found. If no newline character is found, cp is
1198*9781SMoriah.Waterland@Sun.COM * updated to point to the '\0' at the end of the buffer.
1199*9781SMoriah.Waterland@Sun.COM */
1200*9781SMoriah.Waterland@Sun.COM
1201*9781SMoriah.Waterland@Sun.COM static int
getendvfp(char ** cp)1202*9781SMoriah.Waterland@Sun.COM getendvfp(char **cp)
1203*9781SMoriah.Waterland@Sun.COM {
1204*9781SMoriah.Waterland@Sun.COM int n;
1205*9781SMoriah.Waterland@Sun.COM char *p = *cp;
1206*9781SMoriah.Waterland@Sun.COM
1207*9781SMoriah.Waterland@Sun.COM n = 0;
1208*9781SMoriah.Waterland@Sun.COM
1209*9781SMoriah.Waterland@Sun.COM /* if at end of buffer return no more characters left */
1210*9781SMoriah.Waterland@Sun.COM
1211*9781SMoriah.Waterland@Sun.COM if (*p == '\0') {
1212*9781SMoriah.Waterland@Sun.COM return (0);
1213*9781SMoriah.Waterland@Sun.COM }
1214*9781SMoriah.Waterland@Sun.COM
1215*9781SMoriah.Waterland@Sun.COM /* find the first null or end of line character */
1216*9781SMoriah.Waterland@Sun.COM
1217*9781SMoriah.Waterland@Sun.COM while ((*p != '\0') && (*p != '\n')) {
1218*9781SMoriah.Waterland@Sun.COM if (n == 0) {
1219*9781SMoriah.Waterland@Sun.COM if (!isspace(*p)) {
1220*9781SMoriah.Waterland@Sun.COM n++;
1221*9781SMoriah.Waterland@Sun.COM }
1222*9781SMoriah.Waterland@Sun.COM }
1223*9781SMoriah.Waterland@Sun.COM p++;
1224*9781SMoriah.Waterland@Sun.COM }
1225*9781SMoriah.Waterland@Sun.COM
1226*9781SMoriah.Waterland@Sun.COM /* if at newline, increment pointer to first character past newline */
1227*9781SMoriah.Waterland@Sun.COM
1228*9781SMoriah.Waterland@Sun.COM if (*p == '\n') {
1229*9781SMoriah.Waterland@Sun.COM p++;
1230*9781SMoriah.Waterland@Sun.COM }
1231*9781SMoriah.Waterland@Sun.COM
1232*9781SMoriah.Waterland@Sun.COM /* set return pointer to null or first character past newline */
1233*9781SMoriah.Waterland@Sun.COM
1234*9781SMoriah.Waterland@Sun.COM *cp = p;
1235*9781SMoriah.Waterland@Sun.COM
1236*9781SMoriah.Waterland@Sun.COM /* return space/nospace indicator */
1237*9781SMoriah.Waterland@Sun.COM
1238*9781SMoriah.Waterland@Sun.COM return (n);
1239*9781SMoriah.Waterland@Sun.COM }
1240*9781SMoriah.Waterland@Sun.COM
1241*9781SMoriah.Waterland@Sun.COM /*
1242*9781SMoriah.Waterland@Sun.COM * Name: findendvfp
1243*9781SMoriah.Waterland@Sun.COM * Description: Locate the end of the current line given a pointer into a buffer
1244*9781SMoriah.Waterland@Sun.COM * containing characters that is null terminated.
1245*9781SMoriah.Waterland@Sun.COM * Arguments: char **cp - pointer to pointer to null-terminated string buffer
1246*9781SMoriah.Waterland@Sun.COM * Returns: none
1247*9781SMoriah.Waterland@Sun.COM * Effects: cp is updated to point to the first character PAST the first new
1248*9781SMoriah.Waterland@Sun.COM * line character found. If no newline character is found, cp is
1249*9781SMoriah.Waterland@Sun.COM * updated to point to the '\0' at the end of the buffer.
1250*9781SMoriah.Waterland@Sun.COM */
1251*9781SMoriah.Waterland@Sun.COM
1252*9781SMoriah.Waterland@Sun.COM static void
findendvfp(char ** cp)1253*9781SMoriah.Waterland@Sun.COM findendvfp(char **cp)
1254*9781SMoriah.Waterland@Sun.COM {
1255*9781SMoriah.Waterland@Sun.COM char *p1;
1256*9781SMoriah.Waterland@Sun.COM char *p = *cp;
1257*9781SMoriah.Waterland@Sun.COM
1258*9781SMoriah.Waterland@Sun.COM /* if at end of buffer return no more characters left */
1259*9781SMoriah.Waterland@Sun.COM
1260*9781SMoriah.Waterland@Sun.COM if (*p == '\0') {
1261*9781SMoriah.Waterland@Sun.COM return;
1262*9781SMoriah.Waterland@Sun.COM }
1263*9781SMoriah.Waterland@Sun.COM
1264*9781SMoriah.Waterland@Sun.COM /* find the end of the line */
1265*9781SMoriah.Waterland@Sun.COM
1266*9781SMoriah.Waterland@Sun.COM p1 = strchr(p, '\n');
1267*9781SMoriah.Waterland@Sun.COM if (p1 != (char *)NULL) {
1268*9781SMoriah.Waterland@Sun.COM *cp = ++p1;
1269*9781SMoriah.Waterland@Sun.COM return;
1270*9781SMoriah.Waterland@Sun.COM }
1271*9781SMoriah.Waterland@Sun.COM
1272*9781SMoriah.Waterland@Sun.COM /* no newline found - point to null terminator */
1273*9781SMoriah.Waterland@Sun.COM
1274*9781SMoriah.Waterland@Sun.COM *cp = strchr(p, '\0');
1275*9781SMoriah.Waterland@Sun.COM }
1276