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 2006 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 #include <stdio.h>
32*9781SMoriah.Waterland@Sun.COM #include <limits.h>
33*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
34*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
35*9781SMoriah.Waterland@Sun.COM #include <errno.h>
36*9781SMoriah.Waterland@Sun.COM #include <string.h>
37*9781SMoriah.Waterland@Sun.COM #include <sys/types.h>
38*9781SMoriah.Waterland@Sun.COM #include <pkgstrct.h>
39*9781SMoriah.Waterland@Sun.COM #include <locale.h>
40*9781SMoriah.Waterland@Sun.COM #include <libintl.h>
41*9781SMoriah.Waterland@Sun.COM #include <pkglib.h>
42*9781SMoriah.Waterland@Sun.COM #include <install.h>
43*9781SMoriah.Waterland@Sun.COM #include <libinst.h>
44*9781SMoriah.Waterland@Sun.COM
45*9781SMoriah.Waterland@Sun.COM #define ERR_MEMORY "memory allocation failure"
46*9781SMoriah.Waterland@Sun.COM #define ERR_DUPPATH "duplicate pathname <%s>"
47*9781SMoriah.Waterland@Sun.COM
48*9781SMoriah.Waterland@Sun.COM /* libpkg/gpkgmap */
49*9781SMoriah.Waterland@Sun.COM extern int getmapmode(void);
50*9781SMoriah.Waterland@Sun.COM
51*9781SMoriah.Waterland@Sun.COM #define EPTMALLOC 512
52*9781SMoriah.Waterland@Sun.COM
53*9781SMoriah.Waterland@Sun.COM static struct cfent **eptlist;
54*9781SMoriah.Waterland@Sun.COM
55*9781SMoriah.Waterland@Sun.COM static int eptnum;
56*9781SMoriah.Waterland@Sun.COM static int errflg;
57*9781SMoriah.Waterland@Sun.COM static int nparts;
58*9781SMoriah.Waterland@Sun.COM static int space = -1;
59*9781SMoriah.Waterland@Sun.COM
60*9781SMoriah.Waterland@Sun.COM static void procinit(void);
61*9781SMoriah.Waterland@Sun.COM static int procassign(struct cfent *ept, char **server_local,
62*9781SMoriah.Waterland@Sun.COM char **client_local, char **server_path,
63*9781SMoriah.Waterland@Sun.COM char **client_path, char **map_path, int mapflag,
64*9781SMoriah.Waterland@Sun.COM int nc);
65*9781SMoriah.Waterland@Sun.COM
66*9781SMoriah.Waterland@Sun.COM static int ckdup(struct cfent *ept1, struct cfent *ept2);
67*9781SMoriah.Waterland@Sun.COM static int sortentry(int index);
68*9781SMoriah.Waterland@Sun.COM
69*9781SMoriah.Waterland@Sun.COM static void
procinit(void)70*9781SMoriah.Waterland@Sun.COM procinit(void)
71*9781SMoriah.Waterland@Sun.COM {
72*9781SMoriah.Waterland@Sun.COM errflg = nparts = eptnum = 0;
73*9781SMoriah.Waterland@Sun.COM
74*9781SMoriah.Waterland@Sun.COM if (space != -1) {
75*9781SMoriah.Waterland@Sun.COM ar_free(space);
76*9781SMoriah.Waterland@Sun.COM space = -1;
77*9781SMoriah.Waterland@Sun.COM }
78*9781SMoriah.Waterland@Sun.COM
79*9781SMoriah.Waterland@Sun.COM /*
80*9781SMoriah.Waterland@Sun.COM * initialize dynamic memory used to store
81*9781SMoriah.Waterland@Sun.COM * path information which is read in
82*9781SMoriah.Waterland@Sun.COM */
83*9781SMoriah.Waterland@Sun.COM (void) pathdup((char *)0);
84*9781SMoriah.Waterland@Sun.COM }
85*9781SMoriah.Waterland@Sun.COM
86*9781SMoriah.Waterland@Sun.COM /*
87*9781SMoriah.Waterland@Sun.COM * This function assigns appropriate values based upon the pkgmap entry
88*9781SMoriah.Waterland@Sun.COM * in the cfent structure.
89*9781SMoriah.Waterland@Sun.COM */
90*9781SMoriah.Waterland@Sun.COM static int
procassign(struct cfent * ept,char ** server_local,char ** client_local,char ** server_path,char ** client_path,char ** map_path,int mapflag,int nc)91*9781SMoriah.Waterland@Sun.COM procassign(struct cfent *ept, char **server_local, char **client_local,
92*9781SMoriah.Waterland@Sun.COM char **server_path, char **client_path, char **map_path, int mapflag,
93*9781SMoriah.Waterland@Sun.COM int nc)
94*9781SMoriah.Waterland@Sun.COM {
95*9781SMoriah.Waterland@Sun.COM int path_duped = 0;
96*9781SMoriah.Waterland@Sun.COM int local_duped = 0;
97*9781SMoriah.Waterland@Sun.COM char source[PATH_MAX+1];
98*9781SMoriah.Waterland@Sun.COM
99*9781SMoriah.Waterland@Sun.COM if (nc >= 0 && ept->ftype != 'i')
100*9781SMoriah.Waterland@Sun.COM if ((ept->pkg_class_idx = cl_idx(ept->pkg_class)) == -1)
101*9781SMoriah.Waterland@Sun.COM return (1);
102*9781SMoriah.Waterland@Sun.COM
103*9781SMoriah.Waterland@Sun.COM if (ept->volno > nparts)
104*9781SMoriah.Waterland@Sun.COM nparts++;
105*9781SMoriah.Waterland@Sun.COM
106*9781SMoriah.Waterland@Sun.COM /*
107*9781SMoriah.Waterland@Sun.COM * Generate local (delivered source) paths for files
108*9781SMoriah.Waterland@Sun.COM * which need them so that the install routine will know
109*9781SMoriah.Waterland@Sun.COM * where to get the file from the package. Note that we
110*9781SMoriah.Waterland@Sun.COM * do not resolve path environment variables here since
111*9781SMoriah.Waterland@Sun.COM * they won't be resolved in the reloc directory.
112*9781SMoriah.Waterland@Sun.COM */
113*9781SMoriah.Waterland@Sun.COM if ((mapflag > 1) && strchr("fve", ept->ftype)) {
114*9781SMoriah.Waterland@Sun.COM if (ept->ainfo.local == NULL) {
115*9781SMoriah.Waterland@Sun.COM source[0] = '~';
116*9781SMoriah.Waterland@Sun.COM (void) strcpy(&source[1], ept->path);
117*9781SMoriah.Waterland@Sun.COM ept->ainfo.local = pathdup(source);
118*9781SMoriah.Waterland@Sun.COM *server_local = ept->ainfo.local;
119*9781SMoriah.Waterland@Sun.COM *client_local = ept->ainfo.local;
120*9781SMoriah.Waterland@Sun.COM
121*9781SMoriah.Waterland@Sun.COM local_duped = 1;
122*9781SMoriah.Waterland@Sun.COM }
123*9781SMoriah.Waterland@Sun.COM }
124*9781SMoriah.Waterland@Sun.COM
125*9781SMoriah.Waterland@Sun.COM /*
126*9781SMoriah.Waterland@Sun.COM * Evaluate the destination path based upon available
127*9781SMoriah.Waterland@Sun.COM * environment, then produce a client-relative and
128*9781SMoriah.Waterland@Sun.COM * server-relative canonized path.
129*9781SMoriah.Waterland@Sun.COM */
130*9781SMoriah.Waterland@Sun.COM if (mapflag && (ept->ftype != 'i')) {
131*9781SMoriah.Waterland@Sun.COM mappath(getmapmode(), ept->path); /* evaluate variables */
132*9781SMoriah.Waterland@Sun.COM canonize(ept->path); /* Fix path as necessary. */
133*9781SMoriah.Waterland@Sun.COM
134*9781SMoriah.Waterland@Sun.COM (void) eval_path(server_path,
135*9781SMoriah.Waterland@Sun.COM client_path,
136*9781SMoriah.Waterland@Sun.COM map_path,
137*9781SMoriah.Waterland@Sun.COM ept->path);
138*9781SMoriah.Waterland@Sun.COM path_duped = 1; /* eval_path dup's it */
139*9781SMoriah.Waterland@Sun.COM ept->path = *server_path; /* default */
140*9781SMoriah.Waterland@Sun.COM }
141*9781SMoriah.Waterland@Sun.COM
142*9781SMoriah.Waterland@Sun.COM /*
143*9781SMoriah.Waterland@Sun.COM * Deal with source for hard and soft links.
144*9781SMoriah.Waterland@Sun.COM */
145*9781SMoriah.Waterland@Sun.COM if (strchr("sl", ept->ftype)) {
146*9781SMoriah.Waterland@Sun.COM if (mapflag) {
147*9781SMoriah.Waterland@Sun.COM mappath(getmapmode(), ept->ainfo.local);
148*9781SMoriah.Waterland@Sun.COM if (!RELATIVE(ept->ainfo.local)) {
149*9781SMoriah.Waterland@Sun.COM canonize(ept->ainfo.local);
150*9781SMoriah.Waterland@Sun.COM
151*9781SMoriah.Waterland@Sun.COM /* check for hard link */
152*9781SMoriah.Waterland@Sun.COM if (ept->ftype == 'l') {
153*9781SMoriah.Waterland@Sun.COM (void) eval_path(
154*9781SMoriah.Waterland@Sun.COM server_local,
155*9781SMoriah.Waterland@Sun.COM client_local,
156*9781SMoriah.Waterland@Sun.COM NULL,
157*9781SMoriah.Waterland@Sun.COM ept->ainfo.local);
158*9781SMoriah.Waterland@Sun.COM local_duped = 1;
159*9781SMoriah.Waterland@Sun.COM
160*9781SMoriah.Waterland@Sun.COM /* Default to server. */
161*9781SMoriah.Waterland@Sun.COM ept->ainfo.local = *server_local;
162*9781SMoriah.Waterland@Sun.COM }
163*9781SMoriah.Waterland@Sun.COM }
164*9781SMoriah.Waterland@Sun.COM }
165*9781SMoriah.Waterland@Sun.COM }
166*9781SMoriah.Waterland@Sun.COM
167*9781SMoriah.Waterland@Sun.COM /*
168*9781SMoriah.Waterland@Sun.COM * For the paths (both source and target) that were too mundane to
169*9781SMoriah.Waterland@Sun.COM * have been copied into dup space yet, do that.
170*9781SMoriah.Waterland@Sun.COM */
171*9781SMoriah.Waterland@Sun.COM if (!path_duped) {
172*9781SMoriah.Waterland@Sun.COM *server_path = pathdup(ept->path);
173*9781SMoriah.Waterland@Sun.COM *client_path = *server_path;
174*9781SMoriah.Waterland@Sun.COM ept->path = *server_path;
175*9781SMoriah.Waterland@Sun.COM
176*9781SMoriah.Waterland@Sun.COM path_duped = 1;
177*9781SMoriah.Waterland@Sun.COM }
178*9781SMoriah.Waterland@Sun.COM if (ept->ainfo.local != NULL)
179*9781SMoriah.Waterland@Sun.COM if (!local_duped) {
180*9781SMoriah.Waterland@Sun.COM *server_local = pathdup(ept->ainfo.local);
181*9781SMoriah.Waterland@Sun.COM ept->ainfo.local = *server_local;
182*9781SMoriah.Waterland@Sun.COM *client_local = ept->ainfo.local;
183*9781SMoriah.Waterland@Sun.COM
184*9781SMoriah.Waterland@Sun.COM local_duped = 1;
185*9781SMoriah.Waterland@Sun.COM }
186*9781SMoriah.Waterland@Sun.COM
187*9781SMoriah.Waterland@Sun.COM return (0);
188*9781SMoriah.Waterland@Sun.COM }
189*9781SMoriah.Waterland@Sun.COM
190*9781SMoriah.Waterland@Sun.COM /*
191*9781SMoriah.Waterland@Sun.COM * This function reads the prototype file and returns a pointer to a list of
192*9781SMoriah.Waterland@Sun.COM * struct cfent representing the contents of that file.
193*9781SMoriah.Waterland@Sun.COM */
194*9781SMoriah.Waterland@Sun.COM /*ARGSUSED*/
195*9781SMoriah.Waterland@Sun.COM struct cfent **
procmap(VFP_T * vfp,int mapflag,char * ir)196*9781SMoriah.Waterland@Sun.COM procmap(VFP_T *vfp, int mapflag, char *ir)
197*9781SMoriah.Waterland@Sun.COM {
198*9781SMoriah.Waterland@Sun.COM struct cfent *ept = (struct cfent *)NULL;
199*9781SMoriah.Waterland@Sun.COM struct cfent map_entry;
200*9781SMoriah.Waterland@Sun.COM struct cfent **ept_ptr;
201*9781SMoriah.Waterland@Sun.COM int i;
202*9781SMoriah.Waterland@Sun.COM int n;
203*9781SMoriah.Waterland@Sun.COM int nc;
204*9781SMoriah.Waterland@Sun.COM static char *server_local, *client_local;
205*9781SMoriah.Waterland@Sun.COM static char *server_path, *client_path, *map_path;
206*9781SMoriah.Waterland@Sun.COM
207*9781SMoriah.Waterland@Sun.COM procinit();
208*9781SMoriah.Waterland@Sun.COM
209*9781SMoriah.Waterland@Sun.COM space = ar_create(EPTMALLOC, (unsigned)sizeof (struct cfent),
210*9781SMoriah.Waterland@Sun.COM "prototype object");
211*9781SMoriah.Waterland@Sun.COM if (space == -1) {
212*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_MEMORY));
213*9781SMoriah.Waterland@Sun.COM return (NULL);
214*9781SMoriah.Waterland@Sun.COM }
215*9781SMoriah.Waterland@Sun.COM
216*9781SMoriah.Waterland@Sun.COM nc = cl_getn();
217*9781SMoriah.Waterland@Sun.COM for (;;) {
218*9781SMoriah.Waterland@Sun.COM /* Clear the buffer. */
219*9781SMoriah.Waterland@Sun.COM (void) memset(&map_entry, '\000', sizeof (struct cfent));
220*9781SMoriah.Waterland@Sun.COM
221*9781SMoriah.Waterland@Sun.COM n = gpkgmapvfp(&map_entry, vfp);
222*9781SMoriah.Waterland@Sun.COM
223*9781SMoriah.Waterland@Sun.COM if (n == 0)
224*9781SMoriah.Waterland@Sun.COM break; /* no more entries in pkgmap */
225*9781SMoriah.Waterland@Sun.COM else if (n < 0) {
226*9781SMoriah.Waterland@Sun.COM char *errstr = getErrstr();
227*9781SMoriah.Waterland@Sun.COM progerr(gettext("bad entry read in pkgmap"));
228*9781SMoriah.Waterland@Sun.COM logerr(gettext("pathname=%s"),
229*9781SMoriah.Waterland@Sun.COM (ept && ept->path && *ept->path) ?
230*9781SMoriah.Waterland@Sun.COM ept->path : "Unknown");
231*9781SMoriah.Waterland@Sun.COM logerr(gettext("problem=%s"),
232*9781SMoriah.Waterland@Sun.COM (errstr && *errstr) ? errstr : "Unknown");
233*9781SMoriah.Waterland@Sun.COM return (NULL);
234*9781SMoriah.Waterland@Sun.COM }
235*9781SMoriah.Waterland@Sun.COM
236*9781SMoriah.Waterland@Sun.COM /*
237*9781SMoriah.Waterland@Sun.COM * A valid entry was found in the map, so allocate an
238*9781SMoriah.Waterland@Sun.COM * official record.
239*9781SMoriah.Waterland@Sun.COM */
240*9781SMoriah.Waterland@Sun.COM ept_ptr = (struct cfent **)ar_next_avail(space);
241*9781SMoriah.Waterland@Sun.COM if (ept_ptr == NULL || *ept_ptr == NULL) {
242*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_MEMORY));
243*9781SMoriah.Waterland@Sun.COM return (NULL);
244*9781SMoriah.Waterland@Sun.COM }
245*9781SMoriah.Waterland@Sun.COM
246*9781SMoriah.Waterland@Sun.COM ept = *ept_ptr;
247*9781SMoriah.Waterland@Sun.COM
248*9781SMoriah.Waterland@Sun.COM /* Transfer what we just read in. */
249*9781SMoriah.Waterland@Sun.COM (void) memcpy(ept, &map_entry, sizeof (struct cfent));
250*9781SMoriah.Waterland@Sun.COM
251*9781SMoriah.Waterland@Sun.COM if (procassign(ept, &server_local, &client_local,
252*9781SMoriah.Waterland@Sun.COM &server_path, &client_path, &map_path,
253*9781SMoriah.Waterland@Sun.COM mapflag, nc)) {
254*9781SMoriah.Waterland@Sun.COM /* It didn't take. */
255*9781SMoriah.Waterland@Sun.COM (void) ar_delete(space, eptnum);
256*9781SMoriah.Waterland@Sun.COM continue;
257*9781SMoriah.Waterland@Sun.COM }
258*9781SMoriah.Waterland@Sun.COM
259*9781SMoriah.Waterland@Sun.COM eptnum++;
260*9781SMoriah.Waterland@Sun.COM }
261*9781SMoriah.Waterland@Sun.COM
262*9781SMoriah.Waterland@Sun.COM /* setup a pointer array to point to malloc'd entries space */
263*9781SMoriah.Waterland@Sun.COM eptlist = (struct cfent **)ar_get_head(space);
264*9781SMoriah.Waterland@Sun.COM if (eptlist == NULL) {
265*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_MEMORY));
266*9781SMoriah.Waterland@Sun.COM return (NULL);
267*9781SMoriah.Waterland@Sun.COM }
268*9781SMoriah.Waterland@Sun.COM
269*9781SMoriah.Waterland@Sun.COM (void) sortentry(-1);
270*9781SMoriah.Waterland@Sun.COM for (i = 0; i < eptnum; /* void */) {
271*9781SMoriah.Waterland@Sun.COM if (!sortentry(i))
272*9781SMoriah.Waterland@Sun.COM i++;
273*9781SMoriah.Waterland@Sun.COM }
274*9781SMoriah.Waterland@Sun.COM return (errflg ? NULL : eptlist);
275*9781SMoriah.Waterland@Sun.COM }
276*9781SMoriah.Waterland@Sun.COM
277*9781SMoriah.Waterland@Sun.COM /*
278*9781SMoriah.Waterland@Sun.COM * This function sorts the final list of cfent entries. If index = -1, the
279*9781SMoriah.Waterland@Sun.COM * function is initialized. index = 0 doesn't get us anywhere because this
280*9781SMoriah.Waterland@Sun.COM * sorts against index-1. Positive natural index values are compared and
281*9781SMoriah.Waterland@Sun.COM * sorted into the array appropriately. Yes, it does seem we should use a
282*9781SMoriah.Waterland@Sun.COM * quicksort on the whole array or something. The apparent reason for taking
283*9781SMoriah.Waterland@Sun.COM * this approach is that there are enough special considerations to be
284*9781SMoriah.Waterland@Sun.COM * applied to each package object that inserting them one-by-one doesn't cost
285*9781SMoriah.Waterland@Sun.COM * that much.
286*9781SMoriah.Waterland@Sun.COM */
287*9781SMoriah.Waterland@Sun.COM static int
sortentry(int index)288*9781SMoriah.Waterland@Sun.COM sortentry(int index)
289*9781SMoriah.Waterland@Sun.COM {
290*9781SMoriah.Waterland@Sun.COM struct cfent *ept, *ept_i;
291*9781SMoriah.Waterland@Sun.COM static int last = 0;
292*9781SMoriah.Waterland@Sun.COM int i, n, j;
293*9781SMoriah.Waterland@Sun.COM int upper, lower;
294*9781SMoriah.Waterland@Sun.COM
295*9781SMoriah.Waterland@Sun.COM if (index == 0)
296*9781SMoriah.Waterland@Sun.COM return (0);
297*9781SMoriah.Waterland@Sun.COM else if (index < 0) {
298*9781SMoriah.Waterland@Sun.COM last = 0;
299*9781SMoriah.Waterland@Sun.COM return (0);
300*9781SMoriah.Waterland@Sun.COM }
301*9781SMoriah.Waterland@Sun.COM
302*9781SMoriah.Waterland@Sun.COM /*
303*9781SMoriah.Waterland@Sun.COM * Based on the index, this is the package object we're going to
304*9781SMoriah.Waterland@Sun.COM * review. It may stay where it is or it may be repositioned in the
305*9781SMoriah.Waterland@Sun.COM * array.
306*9781SMoriah.Waterland@Sun.COM */
307*9781SMoriah.Waterland@Sun.COM ept = eptlist[index];
308*9781SMoriah.Waterland@Sun.COM
309*9781SMoriah.Waterland@Sun.COM /* quick comparison optimization for pre-sorted arrays */
310*9781SMoriah.Waterland@Sun.COM if (strcmp(ept->path, eptlist[index-1]->path) > 0) {
311*9781SMoriah.Waterland@Sun.COM /* do nothing */
312*9781SMoriah.Waterland@Sun.COM last = index-1;
313*9781SMoriah.Waterland@Sun.COM return (0);
314*9781SMoriah.Waterland@Sun.COM }
315*9781SMoriah.Waterland@Sun.COM
316*9781SMoriah.Waterland@Sun.COM lower = 0; /* lower bound of the unsorted elements */
317*9781SMoriah.Waterland@Sun.COM upper = index; /* upper bound */
318*9781SMoriah.Waterland@Sun.COM i = last;
319*9781SMoriah.Waterland@Sun.COM do {
320*9781SMoriah.Waterland@Sun.COM /*
321*9781SMoriah.Waterland@Sun.COM * NOTE: This does a binary sort on path. There are lots of
322*9781SMoriah.Waterland@Sun.COM * other worthy items in the array, but path is the key into
323*9781SMoriah.Waterland@Sun.COM * the package database.
324*9781SMoriah.Waterland@Sun.COM */
325*9781SMoriah.Waterland@Sun.COM ept_i = eptlist[i];
326*9781SMoriah.Waterland@Sun.COM
327*9781SMoriah.Waterland@Sun.COM n = strcmp(ept->path, ept_i->path);
328*9781SMoriah.Waterland@Sun.COM if (n == 0) {
329*9781SMoriah.Waterland@Sun.COM if (!ckdup(ept, ept_i)) {
330*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_DUPPATH),
331*9781SMoriah.Waterland@Sun.COM ept->path);
332*9781SMoriah.Waterland@Sun.COM errflg++;
333*9781SMoriah.Waterland@Sun.COM }
334*9781SMoriah.Waterland@Sun.COM /* remove the entry at index */
335*9781SMoriah.Waterland@Sun.COM (void) ar_delete(space, index);
336*9781SMoriah.Waterland@Sun.COM
337*9781SMoriah.Waterland@Sun.COM eptnum--;
338*9781SMoriah.Waterland@Sun.COM return (1); /* Use this index again. */
339*9781SMoriah.Waterland@Sun.COM } else if (n < 0) {
340*9781SMoriah.Waterland@Sun.COM /*
341*9781SMoriah.Waterland@Sun.COM * The path of interest is smaller than the path
342*9781SMoriah.Waterland@Sun.COM * under test. Move down array using the method of
343*9781SMoriah.Waterland@Sun.COM * division
344*9781SMoriah.Waterland@Sun.COM */
345*9781SMoriah.Waterland@Sun.COM upper = i;
346*9781SMoriah.Waterland@Sun.COM i = lower + (upper-lower)/2;
347*9781SMoriah.Waterland@Sun.COM } else {
348*9781SMoriah.Waterland@Sun.COM /* Move up array */
349*9781SMoriah.Waterland@Sun.COM lower = i+1;
350*9781SMoriah.Waterland@Sun.COM i = upper - (upper-lower)/2 - 1;
351*9781SMoriah.Waterland@Sun.COM }
352*9781SMoriah.Waterland@Sun.COM } while (upper != lower);
353*9781SMoriah.Waterland@Sun.COM last = i = upper;
354*9781SMoriah.Waterland@Sun.COM
355*9781SMoriah.Waterland@Sun.COM /* expand to insert at i */
356*9781SMoriah.Waterland@Sun.COM for (j = index; j > i; j--)
357*9781SMoriah.Waterland@Sun.COM eptlist[j] = eptlist[j-1];
358*9781SMoriah.Waterland@Sun.COM
359*9781SMoriah.Waterland@Sun.COM eptlist[i] = ept;
360*9781SMoriah.Waterland@Sun.COM
361*9781SMoriah.Waterland@Sun.COM return (0);
362*9781SMoriah.Waterland@Sun.COM }
363*9781SMoriah.Waterland@Sun.COM
364*9781SMoriah.Waterland@Sun.COM /*
365*9781SMoriah.Waterland@Sun.COM * Check duplicate entries in the package object list. If it's a directory,
366*9781SMoriah.Waterland@Sun.COM * this just merges them, if not, it returns a 0 to force further processing.
367*9781SMoriah.Waterland@Sun.COM */
368*9781SMoriah.Waterland@Sun.COM static int
ckdup(struct cfent * ept1,struct cfent * ept2)369*9781SMoriah.Waterland@Sun.COM ckdup(struct cfent *ept1, struct cfent *ept2)
370*9781SMoriah.Waterland@Sun.COM {
371*9781SMoriah.Waterland@Sun.COM /* ept2 will be modified to contain "merged" entries */
372*9781SMoriah.Waterland@Sun.COM
373*9781SMoriah.Waterland@Sun.COM if (!strchr("?dx", ept1->ftype))
374*9781SMoriah.Waterland@Sun.COM return (0);
375*9781SMoriah.Waterland@Sun.COM
376*9781SMoriah.Waterland@Sun.COM if (!strchr("?dx", ept2->ftype))
377*9781SMoriah.Waterland@Sun.COM return (0);
378*9781SMoriah.Waterland@Sun.COM
379*9781SMoriah.Waterland@Sun.COM if (ept2->ainfo.mode == BADMODE)
380*9781SMoriah.Waterland@Sun.COM ept2->ainfo.mode = ept1->ainfo.mode;
381*9781SMoriah.Waterland@Sun.COM if ((ept1->ainfo.mode != ept2->ainfo.mode) &&
382*9781SMoriah.Waterland@Sun.COM (ept1->ainfo.mode != BADMODE))
383*9781SMoriah.Waterland@Sun.COM return (0);
384*9781SMoriah.Waterland@Sun.COM
385*9781SMoriah.Waterland@Sun.COM if (strcmp(ept2->ainfo.owner, "?") == 0)
386*9781SMoriah.Waterland@Sun.COM (void) strcpy(ept2->ainfo.owner, ept1->ainfo.owner);
387*9781SMoriah.Waterland@Sun.COM if (strcmp(ept1->ainfo.owner, ept2->ainfo.owner) &&
388*9781SMoriah.Waterland@Sun.COM strcmp(ept1->ainfo.owner, "?"))
389*9781SMoriah.Waterland@Sun.COM return (0);
390*9781SMoriah.Waterland@Sun.COM
391*9781SMoriah.Waterland@Sun.COM if (strcmp(ept2->ainfo.group, "?") == 0)
392*9781SMoriah.Waterland@Sun.COM (void) strcpy(ept2->ainfo.group, ept1->ainfo.group);
393*9781SMoriah.Waterland@Sun.COM if (strcmp(ept1->ainfo.group, ept2->ainfo.group) &&
394*9781SMoriah.Waterland@Sun.COM strcmp(ept1->ainfo.group, "?"))
395*9781SMoriah.Waterland@Sun.COM return (0);
396*9781SMoriah.Waterland@Sun.COM
397*9781SMoriah.Waterland@Sun.COM if (ept1->pinfo) {
398*9781SMoriah.Waterland@Sun.COM ept2->npkgs = ept1->npkgs;
399*9781SMoriah.Waterland@Sun.COM ept2->pinfo = ept1->pinfo;
400*9781SMoriah.Waterland@Sun.COM }
401*9781SMoriah.Waterland@Sun.COM
402*9781SMoriah.Waterland@Sun.COM return (1);
403*9781SMoriah.Waterland@Sun.COM }
404