Example #1
0
int
swapcfile(PKGserver server, VFP_T **a_cfTmpVfp, char *pkginst, int dbchg)
{
	char	*pe;
	char	*pl;
	char	*ps;
	char	line[256];
	char	timeb[BUFSIZ];
	int	retval = RESULT_OK;
	struct tm	*timep;
	time_t	clock;

	/* normalize pkginst so its never null */

	if (pkginst == (char *)NULL) {
		dbchg = 0;
		pkginst = "<unknown>";
	}

	/*
	 * If no changes were made to the database, checkpoint the temporary
	 * contents file - if this fails, then just close the file which causes
	 * the contents file to be reopened and reread if it is needed again
	 */

	if ((dbchg == 0) && (vfpGetModified(*a_cfTmpVfp) == 0)) {
		(void) pkgWunlock();	/* Free the database lock. */
		return (retval);
	}

	/*
	 * changes made to the current temporary contents file -
	 * remove any trailing comment lines in the temp contents file, then
	 * append updated modification info records to temp contents file
	 */

	pe = vfpGetCurrCharPtr(*a_cfTmpVfp);	/* last char in contents file */
	ps = vfpGetFirstCharPtr(*a_cfTmpVfp);	/* 1st char in contents file */
	pl = pe;	/* last match is last char in contents file */

	/* skip past all trailing newlines and null bytes */

	while ((pe > ps) && ((*pe == '\n') || (*pe == '\0'))) {
		pe--;
	}

	/* remove trailing comments as long as there are lines in the file */

	while (pe > ps) {
		if (*pe != '\n') {
			/* curr char is not newline: backup one byte */
			pl = pe--;
		} else if (*pl != '#') {
			/* curr char is newline next char not comment break */
			break;
		} else {
			/* curr char is newline next char is comment - remove */
			*pl = '\0';
			vfpSetLastCharPtr(*a_cfTmpVfp, pl);
			pe--;
		}
	}

	/* create two update comment lines */

	(void) time(&clock);
	timep = localtime(&clock);

	(void) strftime(timeb, sizeof (timeb), "%c\n", timep);
	(void) snprintf(line, sizeof (line),
	    gettext("# Last modified by %s for %s package\n# %s"),
	    get_prog_name(), pkginst, timeb);
	vfpPuts(*a_cfTmpVfp, line);

	/* commit temporary contents file bytes to storage */

	if (pkgservercommitfile(*a_cfTmpVfp, server) != 0) {
		int	lerrno = errno;

		logerr(gettext(ERR_COMMIT));
		vfpClose(a_cfTmpVfp);
		pkgcloseserver(server);
		(void) pkgWunlock();	/* Free the database lock. */
		return (RESULT_ERR);
	}

	return (relslock() == 0 ? RESULT_ERR : retval);
}
Example #2
0
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) ? " ?" : " %ld"),
			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);
}