summaryrefslogtreecommitdiff
path: root/usr/src/lib/libpkg/common/putcfile.c
diff options
context:
space:
mode:
authorMoriah Waterland <Moriah.Waterland@Sun.COM>2009-06-03 20:16:25 -0600
committerMoriah Waterland <Moriah.Waterland@Sun.COM>2009-06-03 20:16:25 -0600
commit5c51f1241dbbdf2656d0e10011981411ed0c9673 (patch)
tree0f30a2e38fe4e5d53a5a67264ba548577d82a86f /usr/src/lib/libpkg/common/putcfile.c
parent2b79d384d32b4ea1e278466cd9b0f3bb56daae22 (diff)
downloadillumos-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.c376
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);
+}