4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
35 #include <sys/types.h>
41 * Description: Write contents file entry to specified FILE
42 * Arguments: struct cfent a_ept - data for contents file entry
43 * FILE *a_fp - FP of file to write contents file entry to
44 * Notes: This is identical to putcvfpfile() but this function takes a
45 * stdio FILE* file to write to instead of a VFP_T file. It is
46 * MUCH slower than putcvfpfile().
50 putcfile(struct cfent
*a_ept
, FILE *a_fp
)
54 if (a_ept
->ftype
== 'i') {
55 return (0); /* no ifiles stored in contents DB */
58 if (a_ept
->path
== NULL
) {
59 return (-1); /* no path name - no entry to write */
62 if (fputs(a_ept
->path
, a_fp
) == EOF
) {
66 if (a_ept
->ainfo
.local
) {
67 if (putc('=', a_fp
) == EOF
) {
70 if (fputs(a_ept
->ainfo
.local
, a_fp
) == EOF
)
75 if (fprintf(a_fp
, " %d", a_ept
->volno
) < 0) {
80 if (putc(' ', a_fp
) == EOF
) {
84 if (putc(a_ept
->ftype
, a_fp
) == EOF
) {
88 if (putc(' ', a_fp
) == EOF
) {
92 if (fputs(a_ept
->pkg_class
, a_fp
) == EOF
) {
96 if ((a_ept
->ftype
== 'c') || (a_ept
->ftype
== 'b')) {
97 if (a_ept
->ainfo
.major
== BADMAJOR
) {
98 if (putc(' ', a_fp
) == EOF
) {
102 if (putc('?', a_fp
) == EOF
) {
106 if (fprintf(a_fp
, " %ld", a_ept
->ainfo
.major
) < 0)
110 if (a_ept
->ainfo
.minor
== BADMINOR
) {
111 if (putc(' ', a_fp
) == EOF
) {
115 if (putc('?', a_fp
) == EOF
) {
119 if (fprintf(a_fp
, " %ld", a_ept
->ainfo
.minor
) < 0)
124 if ((a_ept
->ftype
== 'd') || (a_ept
->ftype
== 'x') ||
125 (a_ept
->ftype
== 'c') || (a_ept
->ftype
== 'b') ||
126 (a_ept
->ftype
== 'p') || (a_ept
->ftype
== 'f') ||
127 (a_ept
->ftype
== 'v') || (a_ept
->ftype
== 'e')) {
129 ((a_ept
->ainfo
.mode
== BADMODE
) ? " ?" : " %04o"),
130 a_ept
->ainfo
.mode
) < 0)
133 if (putc(' ', a_fp
) == EOF
) {
137 if (fputs(a_ept
->ainfo
.owner
, a_fp
) == EOF
) {
141 if (putc(' ', a_fp
) == EOF
) {
145 if (fputs(a_ept
->ainfo
.group
, a_fp
) == EOF
) {
150 if ((a_ept
->ftype
== 'f') || (a_ept
->ftype
== 'v') ||
151 (a_ept
->ftype
== 'e')) {
153 ((a_ept
->cinfo
.size
== BADCONT
) ? " ?" : " %llu"),
154 a_ept
->cinfo
.size
) < 0)
158 ((a_ept
->cinfo
.cksum
== BADCONT
) ? " ?" : " %ld"),
159 a_ept
->cinfo
.cksum
) < 0)
163 ((a_ept
->cinfo
.modtime
== BADCONT
) ? " ?" : " %ld"),
164 a_ept
->cinfo
.modtime
) < 0)
168 pinfo
= a_ept
->pinfo
;
170 if (putc(' ', a_fp
) == EOF
) {
175 if (fputc(pinfo
->status
, a_fp
) == EOF
) {
180 if (fputs(pinfo
->pkg
, a_fp
) == EOF
) {
184 if (pinfo
->editflag
) {
185 if (putc('\\', a_fp
) == EOF
) {
190 if (pinfo
->aclass
[0]) {
191 if (putc(':', a_fp
) == EOF
) {
194 if (fputs(pinfo
->aclass
, a_fp
) == EOF
) {
201 if (putc('\n', a_fp
) == EOF
) {
209 * Description: Write contents file entry to specified VFP
210 * Arguments: struct cfent a_ept - data for contents file entry
211 * VFP_T *a_vfp - VFP of file to write contents file entry to
212 * Notes: This is identical to putcfile() but this function takes a
213 * VFP_T file to write to instead of a stdio FILE file. It is
214 * MUCH faster tha putcfile().
218 putcvfpfile(struct cfent
*a_ept
, VFP_T
*a_vfp
)
222 /* contents file does not maintain any 'i' file entries */
224 if (a_ept
->ftype
== 'i') {
228 /* cannot create an entry if it has no file name */
230 if (a_ept
->path
== NULL
) {
235 * Format of contents file line could be one of:
236 * /file=./dir/file s class SUNWxxx
237 * /file=../dir/file l class SUNWxxx
238 * /dir d class mode owner group SUNWxxx SUNWyyy
239 * /devices/name c class major minor mode owner group SUNWxxx
240 * /file f class mode owner group size cksum modtime SUNWxxx
241 * /file x class mode owner group SUNWppro
242 * /file v class mode owner group size cksum modtime SUNWxxx
243 * /file e class mode owner group size cksum modtime SUNWxxx
244 * The package name could be prefixed by one of the following
245 * status indicators: +-*!%@#~
249 * Adding an entry to the specified VFP. During normal processing the
250 * contents file is copied to a temporary contents file and entries are
251 * added as appropriate. When this processing is completed, a decision
252 * is made on whether or not to overwrite the real contents file with
253 * the contents of the temporary contents file. If the temporary
254 * contents file is just a copy of the real contents file then there is
255 * no need to overwrite the real contents file with the contents of the
256 * temporary contents file. This decision is made in part on whether
257 * or not any new or modified entries have been added to the temporary
258 * contents file. Set the "data is modified" indication associated
259 * with this VFP so that the real contents file is overwritten when
260 * processing is done.
263 (void) vfpSetModified(a_vfp
);
265 /* write initial path [all entries] */
267 vfpPuts(a_vfp
, a_ept
->path
);
269 /* if link, write out '=' portion */
271 if (a_ept
->ainfo
.local
) {
273 vfpPuts(a_vfp
, a_ept
->ainfo
.local
);
276 /* if volume, write it out */
280 vfpPutInteger(a_vfp
, a_ept
->volno
);
283 /* write out <space><entry type><space>class> */
286 vfpPutc(a_vfp
, a_ept
->ftype
);
288 vfpPuts(a_vfp
, a_ept
->pkg_class
);
290 /* if char/block device, write out major/minor numbers */
292 if ((a_ept
->ftype
== 'c') || (a_ept
->ftype
== 'b')) {
293 /* major device number */
294 if (a_ept
->ainfo
.major
== BADMAJOR
) {
299 vfpPutInteger(a_vfp
, a_ept
->ainfo
.major
);
302 /* minor device number */
303 if (a_ept
->ainfo
.minor
== BADMINOR
) {
308 vfpPutInteger(a_vfp
, a_ept
->ainfo
.minor
);
312 /* if dxcbpfve, write out mode, owner, group */
314 if ((a_ept
->ftype
== 'd') || (a_ept
->ftype
== 'x') ||
315 (a_ept
->ftype
== 'c') || (a_ept
->ftype
== 'b') ||
316 (a_ept
->ftype
== 'p') || (a_ept
->ftype
== 'f') ||
317 (a_ept
->ftype
== 'v') || (a_ept
->ftype
== 'e')) {
321 ((a_ept
->ainfo
.mode
== BADMODE
) ? " ?" : " %04o"),
326 vfpPuts(a_vfp
, a_ept
->ainfo
.owner
);
330 vfpPuts(a_vfp
, a_ept
->ainfo
.group
);
332 /* if f/v/e, write out size, cksum, modtime */
334 if ((a_ept
->ftype
== 'f') || (a_ept
->ftype
== 'v') ||
335 (a_ept
->ftype
== 'e')) {
338 ((a_ept
->cinfo
.size
== BADCONT
) ? " ?" : " %llu"),
343 ((a_ept
->cinfo
.cksum
== BADCONT
) ? " ?" : " %ld"),
348 ((a_ept
->cinfo
.modtime
== BADCONT
) ? " ?" : " %ld"),
349 a_ept
->cinfo
.modtime
);
352 /* write out list of all packages referencing this entry */
354 pinfo
= a_ept
->pinfo
;
358 vfpPutc(a_vfp
, pinfo
->status
);
361 vfpPuts(a_vfp
, pinfo
->pkg
);
363 if (pinfo
->editflag
) {
364 vfpPutc(a_vfp
, '\\');
367 if (pinfo
->aclass
[0]) {
369 vfpPuts(a_vfp
, pinfo
->aclass
);
374 vfpPutc(a_vfp
, '\n');