OpenSolaris_b135/lib/libpkg/common/putcfile.c

Compare this file to the similar file:
Show the results in this format:

/*
 * 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);
}