diff options
author | Moriah Waterland <Moriah.Waterland@Sun.COM> | 2009-06-03 20:16:25 -0600 |
---|---|---|
committer | Moriah Waterland <Moriah.Waterland@Sun.COM> | 2009-06-03 20:16:25 -0600 |
commit | 5c51f1241dbbdf2656d0e10011981411ed0c9673 (patch) | |
tree | 0f30a2e38fe4e5d53a5a67264ba548577d82a86f /usr/src/lib/libpkg/common/putcfile.c | |
parent | 2b79d384d32b4ea1e278466cd9b0f3bb56daae22 (diff) | |
download | illumos-joyent-5c51f1241dbbdf2656d0e10011981411ed0c9673.tar.gz |
6739234 move SVR4 packaging to ONNV gate
Diffstat (limited to 'usr/src/lib/libpkg/common/putcfile.c')
-rw-r--r-- | usr/src/lib/libpkg/common/putcfile.c | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/usr/src/lib/libpkg/common/putcfile.c b/usr/src/lib/libpkg/common/putcfile.c new file mode 100644 index 0000000000..959f2684b8 --- /dev/null +++ b/usr/src/lib/libpkg/common/putcfile.c @@ -0,0 +1,376 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + + + +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <sys/types.h> +#include "pkgstrct.h" +#include "pkglib.h" + +/* + * Name: putcfile + * Description: Write contents file entry to specified FILE + * Arguments: struct cfent a_ept - data for contents file entry + * FILE *a_fp - FP of file to write contents file entry to + * Notes: This is identical to putcvfpfile() but this function takes a + * stdio FILE* file to write to instead of a VFP_T file. It is + * MUCH slower than putcvfpfile(). + */ + +int +putcfile(struct cfent *a_ept, FILE *a_fp) +{ + struct pinfo *pinfo; + + if (a_ept->ftype == 'i') { + return (0); /* no ifiles stored in contents DB */ + } + + if (a_ept->path == NULL) { + return (-1); /* no path name - no entry to write */ + } + + if (fputs(a_ept->path, a_fp) == EOF) { + return (-1); + } + + if (a_ept->ainfo.local) { + if (putc('=', a_fp) == EOF) { + return (-1); + } + if (fputs(a_ept->ainfo.local, a_fp) == EOF) + return (-1); + } + + if (a_ept->volno) { + if (fprintf(a_fp, " %d", a_ept->volno) < 0) { + return (-1); + } + } + + if (putc(' ', a_fp) == EOF) { + return (-1); + } + + if (putc(a_ept->ftype, a_fp) == EOF) { + return (-1); + } + + if (putc(' ', a_fp) == EOF) { + return (-1); + } + + if (fputs(a_ept->pkg_class, a_fp) == EOF) { + return (-1); + } + + if ((a_ept->ftype == 'c') || (a_ept->ftype == 'b')) { + if (a_ept->ainfo.major == BADMAJOR) { + if (putc(' ', a_fp) == EOF) { + return (-1); + } + + if (putc('?', a_fp) == EOF) { + return (-1); + } + } else { + if (fprintf(a_fp, " %d", a_ept->ainfo.major) < 0) + return (-1); + } + + if (a_ept->ainfo.minor == BADMINOR) { + if (putc(' ', a_fp) == EOF) { + return (-1); + } + + if (putc('?', a_fp) == EOF) { + return (-1); + } + } else { + if (fprintf(a_fp, " %d", a_ept->ainfo.minor) < 0) + return (-1); + } + } + + if ((a_ept->ftype == 'd') || (a_ept->ftype == 'x') || + (a_ept->ftype == 'c') || (a_ept->ftype == 'b') || + (a_ept->ftype == 'p') || (a_ept->ftype == 'f') || + (a_ept->ftype == 'v') || (a_ept->ftype == 'e')) { + if (fprintf(a_fp, + ((a_ept->ainfo.mode == BADMODE) ? " ?" : " %04o"), + a_ept->ainfo.mode) < 0) + return (-1); + + if (putc(' ', a_fp) == EOF) { + return (-1); + } + + if (fputs(a_ept->ainfo.owner, a_fp) == EOF) { + return (-1); + } + + if (putc(' ', a_fp) == EOF) { + return (-1); + } + + if (fputs(a_ept->ainfo.group, a_fp) == EOF) { + return (-1); + } + } + + if ((a_ept->ftype == 'f') || (a_ept->ftype == 'v') || + (a_ept->ftype == 'e')) { + if (fprintf(a_fp, + ((a_ept->cinfo.size == BADCONT) ? " ?" : " %llu"), + a_ept->cinfo.size) < 0) + return (-1); + + if (fprintf(a_fp, + ((a_ept->cinfo.cksum == BADCONT) ? " ?" : " %ld"), + a_ept->cinfo.cksum) < 0) + return (-1); + + if (fprintf(a_fp, + ((a_ept->cinfo.modtime == BADCONT) ? " ?" : " %ld"), + a_ept->cinfo.modtime) < 0) + return (-1); + } + + pinfo = a_ept->pinfo; + while (pinfo) { + if (putc(' ', a_fp) == EOF) { + return (-1); + } + + if (pinfo->status) { + if (fputc(pinfo->status, a_fp) == EOF) { + return (-1); + } + } + + if (fputs(pinfo->pkg, a_fp) == EOF) { + return (-1); + } + + if (pinfo->editflag) { + if (putc('\\', a_fp) == EOF) { + return (-1); + } + } + + if (pinfo->aclass[0]) { + if (putc(':', a_fp) == EOF) { + return (-1); + } + if (fputs(pinfo->aclass, a_fp) == EOF) { + return (-1); + } + } + pinfo = pinfo->next; + } + + if (putc('\n', a_fp) == EOF) { + return (-1); + } + return (0); +} + +/* + * Name: putcvfpfile + * Description: Write contents file entry to specified VFP + * Arguments: struct cfent a_ept - data for contents file entry + * VFP_T *a_vfp - VFP of file to write contents file entry to + * Notes: This is identical to putcfile() but this function takes a + * VFP_T file to write to instead of a stdio FILE file. It is + * MUCH faster tha putcfile(). + */ + +int +putcvfpfile(struct cfent *a_ept, VFP_T *a_vfp) +{ + struct pinfo *pinfo; + + /* contents file does not maintain any 'i' file entries */ + + if (a_ept->ftype == 'i') { + return (0); + } + + /* cannot create an entry if it has no file name */ + + if (a_ept->path == NULL) { + return (-1); + } + + /* + * Format of contents file line could be one of: + * /file=./dir/file s class SUNWxxx + * /file=../dir/file l class SUNWxxx + * /dir d class mode owner group SUNWxxx SUNWyyy + * /devices/name c class major minor mode owner group SUNWxxx + * /file f class mode owner group size cksum modtime SUNWxxx + * /file x class mode owner group SUNWppro + * /file v class mode owner group size cksum modtime SUNWxxx + * /file e class mode owner group size cksum modtime SUNWxxx + * The package name could be prefixed by one of the following + * status indicators: +-*!%@#~ + */ + + /* + * Adding an entry to the specified VFP. During normal processing the + * contents file is copied to a temporary contents file and entries are + * added as appropriate. When this processing is completed, a decision + * is made on whether or not to overwrite the real contents file with + * the contents of the temporary contents file. If the temporary + * contents file is just a copy of the real contents file then there is + * no need to overwrite the real contents file with the contents of the + * temporary contents file. This decision is made in part on whether + * or not any new or modified entries have been added to the temporary + * contents file. Set the "data is modified" indication associated + * with this VFP so that the real contents file is overwritten when + * processing is done. + */ + + (void) vfpSetModified(a_vfp); + + /* write initial path [all entries] */ + + vfpPuts(a_vfp, a_ept->path); + + /* if link, write out '=' portion */ + + if (a_ept->ainfo.local) { + vfpPutc(a_vfp, '='); + vfpPuts(a_vfp, a_ept->ainfo.local); + } + + /* if volume, write it out */ + + if (a_ept->volno) { + vfpPutc(a_vfp, ' '); + vfpPutInteger(a_vfp, a_ept->volno); + } + + /* write out <space><entry type><space>class> */ + + vfpPutc(a_vfp, ' '); + vfpPutc(a_vfp, a_ept->ftype); + vfpPutc(a_vfp, ' '); + vfpPuts(a_vfp, a_ept->pkg_class); + + /* if char/block device, write out major/minor numbers */ + + if ((a_ept->ftype == 'c') || (a_ept->ftype == 'b')) { + /* major device number */ + if (a_ept->ainfo.major == BADMAJOR) { + vfpPutc(a_vfp, ' '); + vfpPutc(a_vfp, '?'); + } else { + vfpPutc(a_vfp, ' '); + vfpPutInteger(a_vfp, a_ept->ainfo.major); + } + + /* minor device number */ + if (a_ept->ainfo.minor == BADMINOR) { + vfpPutc(a_vfp, ' '); + vfpPutc(a_vfp, '?'); + } else { + vfpPutc(a_vfp, ' '); + vfpPutInteger(a_vfp, a_ept->ainfo.minor); + } + } + + /* if dxcbpfve, write out mode, owner, group */ + + if ((a_ept->ftype == 'd') || (a_ept->ftype == 'x') || + (a_ept->ftype == 'c') || (a_ept->ftype == 'b') || + (a_ept->ftype == 'p') || (a_ept->ftype == 'f') || + (a_ept->ftype == 'v') || (a_ept->ftype == 'e')) { + + /* mode */ + vfpPutFormat(a_vfp, + ((a_ept->ainfo.mode == BADMODE) ? " ?" : " %04o"), + a_ept->ainfo.mode); + + /* owner */ + vfpPutc(a_vfp, ' '); + vfpPuts(a_vfp, a_ept->ainfo.owner); + + /* group */ + vfpPutc(a_vfp, ' '); + vfpPuts(a_vfp, a_ept->ainfo.group); + } + /* if f/v/e, write out size, cksum, modtime */ + + if ((a_ept->ftype == 'f') || (a_ept->ftype == 'v') || + (a_ept->ftype == 'e')) { + /* size */ + vfpPutFormat(a_vfp, + ((a_ept->cinfo.size == BADCONT) ? " ?" : " %llu"), + a_ept->cinfo.size); + + /* cksum */ + vfpPutFormat(a_vfp, + ((a_ept->cinfo.cksum == BADCONT) ? " ?" : " %ld"), + a_ept->cinfo.cksum); + + /* modtime */ + vfpPutFormat(a_vfp, + ((a_ept->cinfo.modtime == BADCONT) ? " ?" : " %ld"), + a_ept->cinfo.modtime); + } + + /* write out list of all packages referencing this entry */ + + pinfo = a_ept->pinfo; + while (pinfo) { + vfpPutc(a_vfp, ' '); + if (pinfo->status) { + vfpPutc(a_vfp, pinfo->status); + } + + vfpPuts(a_vfp, pinfo->pkg); + + if (pinfo->editflag) { + vfpPutc(a_vfp, '\\'); + } + + if (pinfo->aclass[0]) { + vfpPutc(a_vfp, ':'); + vfpPuts(a_vfp, pinfo->aclass); + } + pinfo = pinfo->next; + } + + vfpPutc(a_vfp, '\n'); + return (0); +} |