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 2008 Sun Microsystems, Inc. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Use is subject to license terms.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* All Rights Reserved */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdio.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <errno.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <string.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <limits.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdlib.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <unistd.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/types.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/param.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <pkgdev.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <pkgstrct.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <locale.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <libintl.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <pkglib.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <libadm.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <libinst.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandextern struct pkgdev pkgdev;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MALSIZ 500
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define EFACTOR 128ULL /* typical size of a single entry in a pkgmap file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define WRN_LIMIT "WARNING: -l limit (%llu blocks) exceeds device " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "capacity (%llu blocks)"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_MEMORY "memory allocation failure, errno=%d"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_TOOBIG "%s (%llu blocks) does not fit on a volume"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_INFOFIRST "information file <%s> must appear on first part"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_INFOSPACE "all install files must appear on first part"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_VOLBLKS "Objects selected for part %d require %llu blocks, " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "limit=%llu."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_VOLFILES "Objects selected for part %d require %llu files, " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "limit=%llu."
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_FREE "package does not fit space currently available in <%s>"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstruct data {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fsblkcnt_t blks;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct cfent *ept;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland};
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstruct class_type {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *name;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int first;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int last;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland};
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic fsblkcnt_t btotal; /* blocks stored on current part */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic fsblkcnt_t bmax; /* maximum number of blocks on any part */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic fsfilcnt_t ftotal; /* files stored on current part */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic fsfilcnt_t fmax; /* maximum number of files on any part */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic fsblkcnt_t bpkginfo; /* blocks used by pkginfo file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char **dirlist;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic short volno; /* current part */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int nparts = -1; /* total number of parts */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int nclass;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic fsblkcnt_t DIRSIZE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic struct class_type *cl;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int nodecount(char *path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int store(struct data **, unsigned int, char *, fsblkcnt_t,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fsblkcnt_t);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void addclass(char *aclass, int vol);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void allocnode(char *path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void newvolume(struct data **, unsigned int, fsblkcnt_t limit,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fsblkcnt_t);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void sortsize(struct data *f, struct data **sf, unsigned int eptnum);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsplpkgmap(struct cfent **eptlist, unsigned int eptnum, char *order[],
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ulong_t bsize, ulong_t frsize, fsblkcnt_t *plimit, fsfilcnt_t *pilimit,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fsblkcnt_t *pllimit)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct data *f, **sf;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct cfent *ept;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland register int i, j;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int new_vol_set;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland short new_vol;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int flag, errflg;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fsblkcnt_t total;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fsblkcnt_t btemp;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fsfilcnt_t ftemp;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland f = (struct data *)calloc(eptnum, sizeof (struct data));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (f == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_MEMORY), errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(99);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sf = (struct data **)calloc(eptnum, sizeof (struct data *));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sf == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_MEMORY), errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(99);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nclass = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cl = (struct class_type *)calloc(MALSIZ, sizeof (struct class_type));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cl == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_MEMORY), errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(99);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland errflg = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The next bit of code checks to see if, when creating a package
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * on a directory, there are enough free blocks and inodes before
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * continuing.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland total = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * DIRSIZE takes up 1 logical block, iff we have no frags, else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * it just takes a frag
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland DIRSIZE = ((fsblkcnt_t)frsize > 0) ?
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland howmany(frsize, DEV_BSIZE) :
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland howmany(bsize, DEV_BSIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!pkgdev.mount) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland allocnode(NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If we appear to have a valid value for free inodes
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and there's not enough for the package contents,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * then exit
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((*pilimit > 0) && (eptnum+1 > *pilimit)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_FREE), pkgdev.dirname);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < eptnum; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strchr("dxslcbp", eptlist[i]->ftype))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland total +=
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (nodecount(eptlist[i]->path) * DIRSIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland total +=
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nblk(eptlist[i]->cinfo.size, bsize, frsize);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (total > *plimit) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_FREE),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgdev.dirname);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland allocnode(eptlist[i]->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * if there is a value in pllimit (-l specified limit), use that for
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the limit from now on.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*pllimit != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkgdev.mount && *pllimit > *plimit)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(gettext(WRN_LIMIT), *pllimit, *plimit);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *plimit = *pllimit;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * calculate number of physical blocks used by each object
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < eptnum; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland f[i].ept = ept = eptlist[i];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ept->volno > nparts)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nparts = ept->volno;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland addclass(ept->pkg_class, 0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strchr("dxslcbp", ept->ftype))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * virtual object (no contents)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland f[i].blks = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * space consumers
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * (directories are space consumers as well, but they
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * get accounted for later).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland f[i].blks = nblk(ept->cinfo.size, bsize, frsize);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!bpkginfo && (strcmp(f[i].ept->path, "pkginfo") == 0))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bpkginfo = f[i].blks;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Make sure that items slated for a given 'part' do not exceed a single
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * volume.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 1; i <= nparts; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btemp = (bpkginfo + 2LL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ftemp = 2LL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i == 1) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * save room for install directory
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ftemp += 2;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btemp += nblk(eptnum * EFACTOR, bsize, frsize);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btemp += 2;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland allocnode(NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (j = 0; j < eptnum; j++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (i == 1 && f[j].ept->ftype == 'i' &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (strcmp(f[j].ept->path, "pkginfo") == 0 ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland strcmp(f[j].ept->path, "pkgmap") == 0))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (f[j].ept->volno == i ||
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (f[j].ept->ftype == 'i' && i == 1)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ftemp += nodecount(f[j].ept->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btemp += f[j].blks;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland allocnode(f[j].ept->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btemp += (ftemp * DIRSIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (btemp > *plimit) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_VOLBLKS), i, btemp, *plimit);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland errflg++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* If we have a valid inode limit, ensure this part will fit */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if ((*pilimit > 0) && (ftemp+1 > *pilimit)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_VOLFILES), i, ftemp + 1, *pilimit);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland errflg++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (errflg)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * "sf" - array sorted in decreasing file size order, based on "f".
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sortsize(f, sf, eptnum);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * initialize first volume
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland newvolume(sf, eptnum, *plimit, *pilimit);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * reserve room on first volume for pkgmap
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btotal += nblk((fsblkcnt_t)(eptnum * EFACTOR), bsize, frsize);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ftotal++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * initialize directory info
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland allocnode(NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * place installation files on first volume!
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland flag = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (j = 0; j < eptnum; ++j) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (f[j].ept->ftype != 'i')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else if (!flag++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * save room for install directory
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ftotal++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btotal += 2ULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!f[j].ept->volno) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland f[j].ept->volno = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ftotal++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btotal += f[j].blks;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (f[j].ept->volno != 1) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_INFOFIRST), f[j].ept->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland errflg++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (errflg)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (btotal > *plimit) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_INFOSPACE));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Make sure that any given file will fit on a single volume, this
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * calculation has to take into account packaging overhead, otherwise
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the function store() will go into a severe recursive plunge.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (j = 0; j < eptnum; ++j) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * directory overhead.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btemp = nodecount(f[j].ept->path) * DIRSIZE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * packaging overhead.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btemp += (bpkginfo + 2L); /* from newvolume() */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((f[j].blks + btemp) > *plimit) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland errflg++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_TOOBIG), f[j].ept->path, f[j].blks);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (errflg)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * place classes listed on command line
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (order) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; order[i]; ++i) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (store(sf, eptnum, order[i], *plimit, *pilimit))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* stay in loop until store is complete */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* void */;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (store(sf, eptnum, (char *)0, *plimit, *pilimit))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* stay in loop until store is complete */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* void */;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * place all virtual objects, e.g. links and spec devices
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < nclass; ++i) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * if no objects were associated, attempt to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * distribute in order of class list
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (cl[i].first == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cl[i].last = cl[i].first = (i ? cl[i-1].last : 1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (j = 0; j < eptnum; j++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((f[j].ept->volno == 0) &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland strcmp(f[j].ept->pkg_class, cl[i].name) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strchr("sl", f[j].ept->ftype))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland f[j].ept->volno = cl[i].last;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland f[j].ept->volno = cl[i].first;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (btotal)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland newvolume(sf, eptnum, *plimit, *pilimit);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (nparts > (volno - 1)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland new_vol = volno;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = volno; i <= nparts; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland new_vol_set = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (j = 0; j < eptnum; j++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (f[j].ept->volno == i) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland f[j].ept->volno = new_vol;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland new_vol_set = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland new_vol += new_vol_set;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nparts = new_vol - 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nparts = volno - 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *plimit = bmax;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pilimit = fmax;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * free up dynamic space used by this module
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(f);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(sf);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < nclass; ++i)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(cl[i].name);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(cl);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; dirlist[i]; i++)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(dirlist[i]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(dirlist);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (errflg ? -1 : nparts);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstore(struct data **sf, unsigned int eptnum, char *aclass, fsblkcnt_t limit,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fsfilcnt_t ilimit)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i, svnodes, choice, select;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland long ftemp;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fsblkcnt_t btemp;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland select = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland choice = (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < eptnum; ++i) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sf[i]->ept->volno || strchr("sldxcbp", sf[i]->ept->ftype))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue; /* defer storage until class is selected */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (aclass && strcmp(aclass, sf[i]->ept->pkg_class))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland select++; /* we need to place at least one object */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ftemp = nodecount(sf[i]->ept->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btemp = sf[i]->blks + (ftemp * DIRSIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (((limit == 0) || ((btotal + btemp) <= limit)) &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ((ilimit == 0) || ((ftotal + ftemp) < ilimit))) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* largest object which fits on this volume */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland choice = i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland svnodes = ftemp;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!select)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0); /* no more to objects to place */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (choice < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland newvolume(sf, eptnum, limit, ilimit);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (store(sf, eptnum, aclass, limit, ilimit));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sf[choice]->ept->volno = (char)volno;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ftotal += svnodes + 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btotal += sf[choice]->blks + (svnodes * DIRSIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland allocnode(sf[i]->ept->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland addclass(sf[choice]->ept->pkg_class, volno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (++choice); /* return non-zero if more work to do */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandallocnode(char *path)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland register int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int found;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (path == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (dirlist) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * free everything
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; dirlist[i]; i++)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(dirlist[i]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(dirlist);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland dirlist = (char **)calloc(MALSIZ, sizeof (char *));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (dirlist == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_MEMORY), errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(99);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pt = path;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*pt == '/')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * since the pathname supplied is never just a directory,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * we store only the dirname of of the path.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (pt = strchr(pt, '/')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pt = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland found = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; dirlist[i] != NULL; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(path, dirlist[i]) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland found++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!found) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* insert this path in node list */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland dirlist[i] = qstrdup(path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((++i % MALSIZ) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland dirlist = (char **)realloc(dirlist,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (i+MALSIZ) * sizeof (char *));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (dirlist == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_MEMORY), errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(99);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland dirlist[i] = (char *)NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pt++ = '/';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandnodecount(char *path)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i, found, count;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pt = path;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (*pt == '/')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * we want to count the number of path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * segments that need to be created, not
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * including the basename of the path;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * this works only since we are never
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * passed a pathname which itself is a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * directory
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland count = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (pt = strchr(pt, '/')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pt = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland found = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; dirlist[i]; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(path, dirlist[i]) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland found++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!found)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland count++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *pt++ = '/';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (count);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandnewvolume(struct data **sf, unsigned int eptnum, fsblkcnt_t limit,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fsblkcnt_t ilimit)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland register int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int newnodes;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (volno) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fprintf(stderr,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland gettext("part %2d -- %llu blocks, %llu entries\n"),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland volno, btotal, ftotal);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (btotal > bmax)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland bmax = btotal;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ftotal > fmax)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fmax = ftotal;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btotal = bpkginfo + 2ULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ftotal = 2;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btotal = 2ULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ftotal = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland volno++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * zero out directory storage
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland allocnode((char *)0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * force storage of files whose volume number has already been assigned
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < eptnum; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sf[i]->ept->volno == volno) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland newnodes = nodecount(sf[i]->ept->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ftotal += newnodes + 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland btotal += sf[i]->blks + (newnodes * DIRSIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (btotal > limit) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_VOLBLKS), volno, btotal,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland limit);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if ((ilimit == 0) && (ftotal+1 > ilimit)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_VOLFILES), volno, ftotal+1,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ilimit);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandaddclass(char *aclass, int vol)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < nclass; ++i) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(cl[i].name, aclass) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (vol <= 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!cl[i].first || (vol < cl[i].first))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cl[i].first = vol;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (vol > cl[i].last)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cl[i].last = vol;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cl[nclass].name = qstrdup(aclass);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cl[nclass].first = vol;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cl[nclass].last = vol;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((++nclass % MALSIZ) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland cl = (struct class_type *)realloc((char *)cl,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sizeof (struct class_type) * (nclass+MALSIZ));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!cl) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_MEMORY), errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(99);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsortsize(struct data *f, struct data **sf, unsigned int eptnum)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int nsf;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int j, k;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland unsigned int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nsf = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < eptnum; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (j = 0; j < nsf; ++j) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (f[i].blks > sf[j]->blks) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (k = nsf; k > j; k--) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sf[k] = sf[k-1];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sf[j] = &f[i];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nsf++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}