5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER START
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The contents of this file are subject to the terms of the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Common Development and Distribution License (the "License").
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You may not use this file except in compliance with the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * or http://www.opensolaris.org/os/licensing.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * See the License for the specific language governing permissions
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and limitations under the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If applicable, add the following below this CDDL HEADER, with the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER END
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Use is subject to license terms.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * special.c
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This module contains code required to remove special contents from
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the contents file when a pkgrm is done on a system upgraded to use
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the new database.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdio.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdlib.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <assert.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <errno.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <unistd.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <string.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <time.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <limits.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <fnmatch.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/types.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/stat.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <pkgstrct.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include "pkglib.h"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <libintl.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* This specifies the maximum length of a contents file line read in. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define LINESZ 8192
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define SPECIAL_MALLOC "unable to maintain package contents text due to "\
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "insufficient memory."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define SPECIAL_ACCESS "unable to maintain package contents text due to "\
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "an access failure."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define SPECIAL_INPUT "unable to maintain package contents text: alternate "\
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "root path too long"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * strcompare
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function is used by qsort to sort an array of special contents
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * rule strings. This array must be sorted to facilitate efficient
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * rule processing. See qsort(3c) regarding qsort compare functions.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstrcompare(const void *pv1, const void *pv2)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char **ppc1 = (char **) pv1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char **ppc2 = (char **) pv2;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i = strcmp(*ppc1, *ppc2);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i < 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i > 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * match
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function determines whether a file name (pc) matches a rule
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * from the special contents file (pcrule). We assume that neither
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * string is ever NULL.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Return: 1 on match, 0 on no match.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Side effects: none.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandmatch(const char *pc, char *pcrule)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int n = strlen(pcrule);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int wild = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pcrule[n - 1] == '*') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland wild = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pcrule[n - 1] = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!wild) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fnmatch(pc, pcrule, FNM_PATHNAME) == 0 ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fnmatch(pc, pcrule, 0) == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int j;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland j = strncmp(pc, pcrule, n - 1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pcrule[n - 1] = '*';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (j == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * search_special_contents
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function assumes that a series of calls will be made requesting
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * whether a given path matches the special contents rules or not. We
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * assume that
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a) the special_contents array is sorted
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * b) the calls will be made with paths in a sorted order
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Given that, we can keep track of where the last search ended and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * begin the new search at that point. This reduces the cost of a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * special contents matching search to O(n) from O(n^2).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ppcSC A pointer to an array of special contents obtained via
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * get_special_contents().
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * path A path: determine whether it matches the special
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * contents rules or not.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * piX The position in the special_contents array we have already
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * arrived at through searching. This must be initialized to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * zero before initiating a series of search_special_contents
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * operations.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Example:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * int i = 0, j, max;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * char **ppSC = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * if (get_special_contents(NULL, &ppcSC, &max) != 0) exit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * for (j = 0; paths != NULL && paths[j] != NULL; j++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * if (search_special_contents(ppcSC, path[j], &i)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * do_something_with_special_path(path[j]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Return: 1 if there is a match, 0 otherwise.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Side effects: The value of *piX will be set between calls to this
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * function. To make this function thread safe, use search arrays.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Also: Nonmatching entries are eliminated, set to NULL.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsearch_special_contents(char **ppcSC, const char *pcpath, int *piX, int max)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int wild;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ppcSC == NULL || *piX == max)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (*piX < max) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int j, k;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ppcSC[*piX] == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (*piX)++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland j = strlen(ppcSC[*piX]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland k = strcmp(pcpath, ppcSC[*piX]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland wild = (ppcSC[*piX][j - 1] == '*');
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Depending on whether the path string compared with the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * rule, we take different actions. If the path is less
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * than the rule, we keep the rule. If the path equals
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the rule, we advance the rule (as long as the rule is
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * not a wild card). If the path is greater than the rule,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * we have to advance the rule list until we are less or equal
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * again. This way we only have to make one pass through the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * rules, as we make one pass through the path strings. We
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * assume that the rules and the path strings are sorted.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (k < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (wild == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (match(pcpath, ppcSC[*piX]))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (k == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int x = match(pcpath, ppcSC[*piX]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (wild == 0) (*piX)++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (x);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* One last try. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (match(pcpath, ppcSC[*piX]))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * As pcpath > ppcSC[*piX] we have passed up this
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * rule - it cannot apply. Therefore, we do not
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * need to retain it. Removing the rule will make
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * subsequent searching more efficient.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(ppcSC[*piX]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ppcSC[*piX] = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (*piX)++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * get_special_contents
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Retrieves the special contents file entries, if they exist. These
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * are sorted. We do not assume the special_contents file is in sorted
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * order.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pcroot The root of the install database. If NULL assume '/'.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pppcSC A pointer to a char **. This pointer will be set to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * point at NULL if there is no special_contents file or
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to a sorted array of strings, NULL terminated, otherwise.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * piMax The # of entries in the special contents result.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: 0 on no error, nonzero on error.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Side effects: the pppcSC pointer is set to point at a newly
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * allocated array of pointers to strings.. The caller must
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * free this buffer. The value of *piMax is set to the # of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * entries in ppcSC.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandget_special_contents(const char *pcroot, char ***pppcSC, int *piMax)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int e, i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland FILE *fp;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char line[2048];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char **ppc;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *pc = "var/sadm/install/special_contents";
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char path[PATH_MAX];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct stat s;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Initialize the return values. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *piMax = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pppcSC = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pcroot == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pcroot = "/";
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pcroot[strlen(pcroot) - 1] == '/') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (snprintf(path, PATH_MAX, "%s%s", pcroot, pc) >= PATH_MAX) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_INPUT));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (snprintf(path, PATH_MAX, "%s/%s", pcroot, pc)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland >= PATH_MAX) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_INPUT));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland errno = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland e = stat(path, &s);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (e != 0 && errno == ENOENT)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0); /* No special contents file. Do nothing. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (access(path, R_OK) != 0 || (fp = fopen(path, "r")) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Could not open special contents which exists */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_ACCESS));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; fgets(line, 2048, fp) != NULL; i++);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland rewind(fp);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ppc = (char **) calloc(i + 1, sizeof (char *))) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_MALLOC));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; fgets(line, 2048, fp) != NULL; ) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int n;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (line[0] == '#' || line[0] == ' ' || line[0] == '\n' ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland line[0] == '\t' || line[0] == '\r')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland n = strlen(line);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (line[n - 1] == '\n')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland line[n - 1] = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ppc[i++] = strdup(line);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland qsort(ppc, i, sizeof (char *), strcompare);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pppcSC = ppc;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *piMax = i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * free_special_contents
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function frees special_contents which have been allocated using
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * get_special_contents.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pppcSC A pointer to a buffer allocated using get_special_contents.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * max The number of entries allocated.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Result: None.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Side effects: Frees memory allocated using get_special_contents and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sets the pointer passed in to NULL.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandfree_special_contents(char ***pppcSC, int max)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char **ppc = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*pppcSC == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ppc = *pppcSC;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; ppc != NULL && i < max; i++)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ppc[i] == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(ppc[i]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ppc != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(ppc);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pppcSC = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * get_path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Return the first field of a string delimited by a space.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pcline A line from the contents file.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Return: NULL if an error. Otherwise a string allocated by this
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * function. The caller must free the string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Side effects: none.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandget_path(const char *pcline)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i = strcspn(pcline, " ");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *pc = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i <= 1 || (pc = (char *) calloc(i + 1, 1)) == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memcpy(pc, pcline, i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (pc);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * generate_special_contents_rules
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This procedure will generate an array of integers which will be a mask
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to apply to the ppcfextra array. If set to 1, then the content must be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * added to the contents file. Otherwise it will not be: The old contents
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file will be used for this path value, if one even exists.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ient The number of ppcfextra contents installed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ppcfent The contents installed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ppcSC The rules (special contents)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * max The number of special contents rules.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ppiIndex The array of integer values, determining whether
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * individual ppcfextra items match special contents rules.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This array will be created and set in this function and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * returned.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Return: 0 success, nonzero failure
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Side effects: allocates an array of integers that the caller must free.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandgenerate_special_contents_rules(int ient, struct cfent **ppcfent,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char **ppcSC, int max, int **ppiIndex)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i, j;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int *pi = (int *) calloc(ient, sizeof (int));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pi == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_MALLOC));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * For each entry in ppcfextra, check if it matches a rule.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If it does not, set the entry in the index to -1.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0, j = 0; i < ient && j < max; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (search_special_contents(ppcSC, ppcfent[i]->path,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland &j, max) == 1) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pi[i] = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pi[i] = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * In case we ran out of rules before contents, we will not use
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * those contents. Make sure these contents are set to 0 and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * will not be copied from the ppcfent array into the contents
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = i; i < ient; i++)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pi[i] = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *ppiIndex = pi;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pathcmp
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Compare a path to a cfent. It will match either if the path is
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * equal to the cfent path, or if the cfent is a symbolic or link
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and *that* matches.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * path a path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pent a contents entry
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns: as per strcmp
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Side effects: none.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandpathcmp(const char *pc, const struct cfent *pent)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((pent->ftype == 's' || pent->ftype == 'l') &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pent->ainfo.local) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *p, *q;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((p = strstr(pc, "=")) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = strcmp(pc, pent->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* A path without additional chars strcmp's to less */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Break the link path into two pieces. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *p = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Compare the first piece. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = strcmp(pc, pent->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If equal we must compare the second piece. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland q = p + 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = strcmp(q, pent->ainfo.local);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Restore the link path. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *p = '=';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = strcmp(pc, pent->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (i);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * -----------------------------------------------------------------------
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Externally visible function.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * special_contents_remove
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Given a set of entries to remove and an alternate root, this function
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * will do everything required to ensure that the entries are removed
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * from the contents file if they are listed in the special_contents
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file. The contents file will get changed only in the case that the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * entire operation has succeeded.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ient The number of entries.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ppcfent The entries to remove.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * pcroot The alternate install root. Could be NULL. In this
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * case, assume root is '/'
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Result: 0 on success, nonzero on failure. If an error occurs, an
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * error string will get output to standard error alerting the user.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Side effects: The contents file may change as a result of this call,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * such that lines in the in the file will be changed or removed.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If the call fails, a t.contents file may be left behind. This
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * temporary file should be removed subsequently.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandspecial_contents_remove(int ient, struct cfent **ppcfent, const char *pcroot)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int result = 0; /* Assume we will succeed. Return result. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char **ppcSC = NULL; /* The special contents rules, sorted. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i, j; /* Indexes into contents & special contents */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland FILE *fpi = NULL, /* Input of contents file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *fpo = NULL; /* Output to temp contents file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char cpath[PATH_MAX], /* Contents file path */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tcpath[PATH_MAX]; /* Temp contents file path */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland const char *pccontents = "var/sadm/install/contents";
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland const char *pctcontents = "var/sadm/install/t.contents";
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char line[LINESZ]; /* Reads in and writes out contents lines. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland time_t t; /* Used to create a timestamp comment. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int max; /* Max number of special contents entries. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int *piIndex; /* An index to ppcfents to remove from cfile */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cpath[0] = tcpath[0] = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ient == 0 || ppcfent == NULL || ppcfent[0] == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto remove_done;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((get_special_contents(pcroot, &ppcSC, &max)) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto remove_done;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Check if there are no special contents actions to take. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ppcSC == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto remove_done;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pcroot == NULL) pcroot = "/";
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pcroot[strlen(pcroot) - 1] == '/') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (snprintf(cpath, PATH_MAX, "%s%s", pcroot, pccontents)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland >= PATH_MAX ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland snprintf(tcpath, PATH_MAX, "%s%s", pcroot, pctcontents)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland >= PATH_MAX) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_INPUT));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto remove_done;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (snprintf(cpath, PATH_MAX, "%s/%s", pcroot, pccontents)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland >= PATH_MAX ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland snprintf(tcpath, PATH_MAX, "%s/%s", pcroot, pctcontents)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland >= PATH_MAX) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_INPUT));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto remove_done;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Open the temporary contents file to write, contents to read. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (access(cpath, F_OK | R_OK) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This is not a problem since no contents means nothing
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to remove due to special contents rules.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cpath[0] = '\0'; /* This signals omission of 'rename cleanup' */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto remove_done;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (access(cpath, W_OK) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* can't write contents file, something is wrong. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_ACCESS));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto remove_done;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((fpi = fopen(cpath, "r")) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Given the access test above, this should not happen. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_ACCESS));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto remove_done;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((fpo = fopen(tcpath, "w")) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* open t.contents failed */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_ACCESS));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto remove_done;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (generate_special_contents_rules(ient, ppcfent, ppcSC, max, &piIndex)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland goto remove_done;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copy contents to t.contents unless there is an entry in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the ppcfent array which corresponds to an index set to 1.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * These items are the removed package contents which matche an
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * entry in ppcSC (the special_contents rules).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Since both the contents and rules are sorted, we can
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * make a single efficient pass.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memset(line, 0, LINESZ);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0, j = 0; fgets(line, LINESZ, fpi) != NULL; ) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *pcpath = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Note: This could be done better: We should figure out
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * which are the last 2 lines and only trim those off.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This will suffice to do this and will only be done as
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * part of special_contents handling.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (line[0] == '#')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue; /* Do not copy the final 2 comment lines */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pcpath = get_path(line);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pcpath != NULL && i < ient) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int k;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (piIndex[i] == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i < ient)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland k = pathcmp(pcpath, ppcfent[i]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (k < 0 || i >= ient) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Just copy contents -> t.contents */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*EMPTY*/
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (k == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* We have a match. Do not copy the content. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(pcpath);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memset(line, 0, LINESZ);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else while (i < ient) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This is a complex case: The content
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * entry is further along alphabetically
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * than the rule. Skip over all rules which
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * apply until we come to a rule which is
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * greater than the current entry, or equal
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to it. If equal, do not copy, otherwise
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * do copy the entry.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (piIndex[i] == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if ((k = pathcmp(pcpath, ppcfent[i]))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland >= 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (k == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(pcpath);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memset(line, 0, LINESZ);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* path < rule, end special case */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Avoid copying the old content when path == rule
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This occurs when the complex case ends on a match.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (k == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fprintf(fpo, "%s", line) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Failing to write output would be catastrophic. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_ACCESS));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memset(line, 0, LINESZ);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland t = time(NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fprintf(fpo, "# Last modified by pkgremove\n");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fprintf(fpo, "# %s", ctime(&t));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandremove_done:
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free_special_contents(&ppcSC, max);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fpi != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fclose(fpi);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fpo != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fclose(fpo);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (result == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (tcpath[0] != '\0' && cpath[0] != '\0' &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland rename(tcpath, cpath) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(SPECIAL_ACCESS));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (tcpath[0] != '\0' && remove(tcpath) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Do not output a diagnostic message. This condition
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * occurs only when we are unable to clean up after
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * a failure. A temporary file will linger.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland result = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (result);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}