1*5c51f124SMoriah Waterland /*
2*5c51f124SMoriah Waterland * CDDL HEADER START
3*5c51f124SMoriah Waterland *
4*5c51f124SMoriah Waterland * The contents of this file are subject to the terms of the
5*5c51f124SMoriah Waterland * Common Development and Distribution License (the "License").
6*5c51f124SMoriah Waterland * You may not use this file except in compliance with the License.
7*5c51f124SMoriah Waterland *
8*5c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing.
10*5c51f124SMoriah Waterland * See the License for the specific language governing permissions
11*5c51f124SMoriah Waterland * and limitations under the License.
12*5c51f124SMoriah Waterland *
13*5c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
14*5c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the
16*5c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
17*5c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
18*5c51f124SMoriah Waterland *
19*5c51f124SMoriah Waterland * CDDL HEADER END
20*5c51f124SMoriah Waterland */
21*5c51f124SMoriah Waterland
22*5c51f124SMoriah Waterland /*
23*5c51f124SMoriah Waterland * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24*5c51f124SMoriah Waterland * Use is subject to license terms.
25*5c51f124SMoriah Waterland */
26*5c51f124SMoriah Waterland
27*5c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*5c51f124SMoriah Waterland /* All Rights Reserved */
29*5c51f124SMoriah Waterland
30*5c51f124SMoriah Waterland
31*5c51f124SMoriah Waterland #include <stdio.h>
32*5c51f124SMoriah Waterland #include <ctype.h>
33*5c51f124SMoriah Waterland #include <string.h>
34*5c51f124SMoriah Waterland #include <stdlib.h>
35*5c51f124SMoriah Waterland #include <unistd.h>
36*5c51f124SMoriah Waterland #include <sys/types.h>
37*5c51f124SMoriah Waterland #include <sys/param.h>
38*5c51f124SMoriah Waterland #include <sys/stat.h>
39*5c51f124SMoriah Waterland #include <sys/statvfs.h>
40*5c51f124SMoriah Waterland #include <limits.h>
41*5c51f124SMoriah Waterland #include <locale.h>
42*5c51f124SMoriah Waterland #include <libintl.h>
43*5c51f124SMoriah Waterland #include <pkgstrct.h>
44*5c51f124SMoriah Waterland #include "install.h"
45*5c51f124SMoriah Waterland #include <pkglib.h>
46*5c51f124SMoriah Waterland #include "libadm.h"
47*5c51f124SMoriah Waterland #include "libinst.h"
48*5c51f124SMoriah Waterland #include "pkginstall.h"
49*5c51f124SMoriah Waterland
50*5c51f124SMoriah Waterland extern struct cfextra **extlist;
51*5c51f124SMoriah Waterland extern char pkgloc[];
52*5c51f124SMoriah Waterland extern char instdir[];
53*5c51f124SMoriah Waterland
54*5c51f124SMoriah Waterland #define LSIZE 256
55*5c51f124SMoriah Waterland #define LIM_BFREE 150LL
56*5c51f124SMoriah Waterland #define LIM_FFREE 25LL
57*5c51f124SMoriah Waterland
58*5c51f124SMoriah Waterland #define WRN_STATVFS "WARNING: unable to stat filesystem mounted on <%s>"
59*5c51f124SMoriah Waterland
60*5c51f124SMoriah Waterland #define WRN_NOBLKS "The %s filesystem has %llu free blocks. The current " \
61*5c51f124SMoriah Waterland "installation requires %llu blocks, which includes a " \
62*5c51f124SMoriah Waterland "required %llu block buffer for open " \
63*5c51f124SMoriah Waterland "deleted files. %llu more blocks are needed."
64*5c51f124SMoriah Waterland
65*5c51f124SMoriah Waterland #define WRN_NOFILES "The %s filesystem has %llu free file nodes. The " \
66*5c51f124SMoriah Waterland "current installation requires %llu file nodes, " \
67*5c51f124SMoriah Waterland "which includes a required %llu file node buffer " \
68*5c51f124SMoriah Waterland "for temporary files. %llu more file nodes " \
69*5c51f124SMoriah Waterland "are needed."
70*5c51f124SMoriah Waterland
71*5c51f124SMoriah Waterland #define TYPE_BLCK 0
72*5c51f124SMoriah Waterland #define TYPE_NODE 1
73*5c51f124SMoriah Waterland static void warn(int type, char *name, fsblkcnt_t need, fsblkcnt_t avail,
74*5c51f124SMoriah Waterland fsblkcnt_t limit);
75*5c51f124SMoriah Waterland static int fsys_stat(int n);
76*5c51f124SMoriah Waterland static int readmap(int *error);
77*5c51f124SMoriah Waterland static int readspace(char *spacefile, int *error);
78*5c51f124SMoriah Waterland
79*5c51f124SMoriah Waterland int
dockspace(char * spacefile)80*5c51f124SMoriah Waterland dockspace(char *spacefile)
81*5c51f124SMoriah Waterland {
82*5c51f124SMoriah Waterland struct fstable *fs_tab;
83*5c51f124SMoriah Waterland int i, error;
84*5c51f124SMoriah Waterland
85*5c51f124SMoriah Waterland error = 0;
86*5c51f124SMoriah Waterland
87*5c51f124SMoriah Waterland /*
88*5c51f124SMoriah Waterland * Also, vanilla SVr4 code used the output from popen()
89*5c51f124SMoriah Waterland * on the "/etc/mount" command. However, we need to get more
90*5c51f124SMoriah Waterland * information about mounted filesystems, so we use the C
91*5c51f124SMoriah Waterland * interfaces to the mount table, which also happens to be
92*5c51f124SMoriah Waterland * much faster than running another process. Since several
93*5c51f124SMoriah Waterland * of the pkg commands need access to the mount table, this
94*5c51f124SMoriah Waterland * code is now in libinst. However, mount table info is needed
95*5c51f124SMoriah Waterland * at the time the base directory is determined, so the call
96*5c51f124SMoriah Waterland * to get the mount table information is in main.c
97*5c51f124SMoriah Waterland */
98*5c51f124SMoriah Waterland
99*5c51f124SMoriah Waterland if (readmap(&error) || readspace(spacefile, &error))
100*5c51f124SMoriah Waterland return (-1);
101*5c51f124SMoriah Waterland
102*5c51f124SMoriah Waterland for (i = 0; fs_tab = get_fs_entry(i); ++i) {
103*5c51f124SMoriah Waterland if ((!fs_tab->fused) && (!fs_tab->bused))
104*5c51f124SMoriah Waterland continue; /* not used by us */
105*5c51f124SMoriah Waterland
106*5c51f124SMoriah Waterland if (fs_tab->bfree < (LIM_BFREE + fs_tab->bused)) {
107*5c51f124SMoriah Waterland warn(TYPE_BLCK, fs_tab->name, fs_tab->bused,
108*5c51f124SMoriah Waterland fs_tab->bfree, LIM_BFREE);
109*5c51f124SMoriah Waterland error++;
110*5c51f124SMoriah Waterland }
111*5c51f124SMoriah Waterland
112*5c51f124SMoriah Waterland /* bug id 1091292 */
113*5c51f124SMoriah Waterland if ((long)fs_tab->ffree == -1L)
114*5c51f124SMoriah Waterland continue;
115*5c51f124SMoriah Waterland if (fs_tab->ffree < (LIM_FFREE + fs_tab->fused)) {
116*5c51f124SMoriah Waterland warn(TYPE_NODE, fs_tab->name, fs_tab->fused,
117*5c51f124SMoriah Waterland fs_tab->ffree, LIM_FFREE);
118*5c51f124SMoriah Waterland error++;
119*5c51f124SMoriah Waterland }
120*5c51f124SMoriah Waterland }
121*5c51f124SMoriah Waterland return (error);
122*5c51f124SMoriah Waterland }
123*5c51f124SMoriah Waterland
124*5c51f124SMoriah Waterland static void
warn(int type,char * name,fsblkcnt_t need,fsblkcnt_t avail,fsblkcnt_t limit)125*5c51f124SMoriah Waterland warn(int type, char *name, fsblkcnt_t need, fsblkcnt_t avail, fsblkcnt_t limit)
126*5c51f124SMoriah Waterland {
127*5c51f124SMoriah Waterland logerr(gettext("WARNING:"));
128*5c51f124SMoriah Waterland if (type == TYPE_BLCK) {
129*5c51f124SMoriah Waterland logerr(gettext(WRN_NOBLKS), name, avail, (need + limit), limit,
130*5c51f124SMoriah Waterland (need + limit - avail));
131*5c51f124SMoriah Waterland } else {
132*5c51f124SMoriah Waterland logerr(gettext(WRN_NOFILES), name, avail, (need + limit), limit,
133*5c51f124SMoriah Waterland (need + limit - avail));
134*5c51f124SMoriah Waterland }
135*5c51f124SMoriah Waterland }
136*5c51f124SMoriah Waterland
137*5c51f124SMoriah Waterland static int
fsys_stat(int n)138*5c51f124SMoriah Waterland fsys_stat(int n)
139*5c51f124SMoriah Waterland {
140*5c51f124SMoriah Waterland struct statvfs64 svfsb;
141*5c51f124SMoriah Waterland struct fstable *fs_tab;
142*5c51f124SMoriah Waterland
143*5c51f124SMoriah Waterland if (n == BADFSYS)
144*5c51f124SMoriah Waterland return (1);
145*5c51f124SMoriah Waterland
146*5c51f124SMoriah Waterland fs_tab = get_fs_entry(n);
147*5c51f124SMoriah Waterland
148*5c51f124SMoriah Waterland /*
149*5c51f124SMoriah Waterland * At this point, we know we need information
150*5c51f124SMoriah Waterland * about a particular filesystem, so we can do the
151*5c51f124SMoriah Waterland * statvfs() now. For performance reasons, we only want to
152*5c51f124SMoriah Waterland * stat the filesystem once, at the first time we need to,
153*5c51f124SMoriah Waterland * and so we can key on whether or not we have the
154*5c51f124SMoriah Waterland * block size for that filesystem.
155*5c51f124SMoriah Waterland */
156*5c51f124SMoriah Waterland if (fs_tab->bsize != 0)
157*5c51f124SMoriah Waterland return (0);
158*5c51f124SMoriah Waterland
159*5c51f124SMoriah Waterland if (statvfs64(fs_tab->name, &svfsb)) {
160*5c51f124SMoriah Waterland logerr(gettext(WRN_STATVFS), fs_tab->name);
161*5c51f124SMoriah Waterland return (1);
162*5c51f124SMoriah Waterland }
163*5c51f124SMoriah Waterland
164*5c51f124SMoriah Waterland /*
165*5c51f124SMoriah Waterland * statvfs returns number of fragment size blocks
166*5c51f124SMoriah Waterland * so will change this to number of 512 byte blocks
167*5c51f124SMoriah Waterland */
168*5c51f124SMoriah Waterland fs_tab->bsize = svfsb.f_bsize;
169*5c51f124SMoriah Waterland fs_tab->frsize = svfsb.f_frsize;
170*5c51f124SMoriah Waterland fs_tab->bfree = ((svfsb.f_frsize > 0) ?
171*5c51f124SMoriah Waterland howmany(svfsb.f_frsize, DEV_BSIZE) :
172*5c51f124SMoriah Waterland howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bavail;
173*5c51f124SMoriah Waterland fs_tab->ffree = (svfsb.f_favail > 0) ? svfsb.f_favail : svfsb.f_ffree;
174*5c51f124SMoriah Waterland return (0);
175*5c51f124SMoriah Waterland }
176*5c51f124SMoriah Waterland
177*5c51f124SMoriah Waterland /*
178*5c51f124SMoriah Waterland * This function reads all of the package objects, maps them to their target
179*5c51f124SMoriah Waterland * filesystems and adds up the amount of space used on each. Wherever you see
180*5c51f124SMoriah Waterland * "fsys_value", that's the apparent filesystem which could be a temporary
181*5c51f124SMoriah Waterland * loopback mount for the purpose of constructing the client filesystem. It
182*5c51f124SMoriah Waterland * isn't necessarily the real target filesystem. Where you see "fsys_base"
183*5c51f124SMoriah Waterland * that's the real filesystem to which fsys_value may just refer. If this is
184*5c51f124SMoriah Waterland * installing to a standalone or a server, fsys_value will almost always be
185*5c51f124SMoriah Waterland * the same as fsys_base.
186*5c51f124SMoriah Waterland */
187*5c51f124SMoriah Waterland static int
readmap(int * error)188*5c51f124SMoriah Waterland readmap(int *error)
189*5c51f124SMoriah Waterland {
190*5c51f124SMoriah Waterland struct fstable *fs_tab;
191*5c51f124SMoriah Waterland struct cfextra *ext;
192*5c51f124SMoriah Waterland struct cfent *ept;
193*5c51f124SMoriah Waterland struct stat statbuf;
194*5c51f124SMoriah Waterland char tpath[PATH_MAX];
195*5c51f124SMoriah Waterland fsblkcnt_t blk;
196*5c51f124SMoriah Waterland int i, n;
197*5c51f124SMoriah Waterland
198*5c51f124SMoriah Waterland /*
199*5c51f124SMoriah Waterland * Handle the installation files (ftype i) that are in the
200*5c51f124SMoriah Waterland * pkgmap/eptlist.
201*5c51f124SMoriah Waterland */
202*5c51f124SMoriah Waterland for (i = 0; (ext = extlist[i]) != NULL; i++) {
203*5c51f124SMoriah Waterland ept = &(ext->cf_ent);
204*5c51f124SMoriah Waterland
205*5c51f124SMoriah Waterland if (ept->ftype != 'i')
206*5c51f124SMoriah Waterland continue;
207*5c51f124SMoriah Waterland
208*5c51f124SMoriah Waterland /*
209*5c51f124SMoriah Waterland * These paths are treated differently from the others
210*5c51f124SMoriah Waterland * since their full pathnames are not included in the
211*5c51f124SMoriah Waterland * pkgmap.
212*5c51f124SMoriah Waterland */
213*5c51f124SMoriah Waterland if (strcmp(ept->path, "pkginfo") == 0)
214*5c51f124SMoriah Waterland (void) sprintf(tpath, "%s/%s", pkgloc, ept->path);
215*5c51f124SMoriah Waterland else
216*5c51f124SMoriah Waterland (void) sprintf(tpath, "%s/install/%s", pkgloc,
217*5c51f124SMoriah Waterland ept->path);
218*5c51f124SMoriah Waterland
219*5c51f124SMoriah Waterland /* If we haven't done an fsys() series, do one */
220*5c51f124SMoriah Waterland if (ext->fsys_value == BADFSYS)
221*5c51f124SMoriah Waterland ext->fsys_value = fsys(tpath);
222*5c51f124SMoriah Waterland
223*5c51f124SMoriah Waterland /*
224*5c51f124SMoriah Waterland * Now check if this is a base or apparent filesystem. If
225*5c51f124SMoriah Waterland * it's just apparent, get the resolved filesystem entry,
226*5c51f124SMoriah Waterland * otherwise, base and value are the same.
227*5c51f124SMoriah Waterland */
228*5c51f124SMoriah Waterland if (use_srvr_map_n(ext->fsys_value))
229*5c51f124SMoriah Waterland ext->fsys_base = resolved_fsys(tpath);
230*5c51f124SMoriah Waterland else
231*5c51f124SMoriah Waterland ext->fsys_base = ext->fsys_value;
232*5c51f124SMoriah Waterland
233*5c51f124SMoriah Waterland if (fsys_stat(ext->fsys_base)) {
234*5c51f124SMoriah Waterland (*error)++;
235*5c51f124SMoriah Waterland continue;
236*5c51f124SMoriah Waterland }
237*5c51f124SMoriah Waterland
238*5c51f124SMoriah Waterland /*
239*5c51f124SMoriah Waterland * Don't accumulate space requirements on read-only
240*5c51f124SMoriah Waterland * remote filesystems.
241*5c51f124SMoriah Waterland */
242*5c51f124SMoriah Waterland if (is_remote_fs_n(ext->fsys_value) &&
243*5c51f124SMoriah Waterland !is_fs_writeable_n(ext->fsys_value))
244*5c51f124SMoriah Waterland continue;
245*5c51f124SMoriah Waterland
246*5c51f124SMoriah Waterland fs_tab = get_fs_entry(ext->fsys_base);
247*5c51f124SMoriah Waterland
248*5c51f124SMoriah Waterland fs_tab->fused++;
249*5c51f124SMoriah Waterland if (ept->cinfo.size != BADCONT)
250*5c51f124SMoriah Waterland blk = nblk(ept->cinfo.size,
251*5c51f124SMoriah Waterland fs_tab->bsize,
252*5c51f124SMoriah Waterland fs_tab->frsize);
253*5c51f124SMoriah Waterland else
254*5c51f124SMoriah Waterland blk = 0;
255*5c51f124SMoriah Waterland fs_tab->bused += blk;
256*5c51f124SMoriah Waterland }
257*5c51f124SMoriah Waterland
258*5c51f124SMoriah Waterland /*
259*5c51f124SMoriah Waterland * Handle the other files in the eptlist.
260*5c51f124SMoriah Waterland */
261*5c51f124SMoriah Waterland for (i = 0; (ext = extlist[i]) != NULL; i++) {
262*5c51f124SMoriah Waterland ept = &(extlist[i]->cf_ent);
263*5c51f124SMoriah Waterland
264*5c51f124SMoriah Waterland if (ept->ftype == 'i')
265*5c51f124SMoriah Waterland continue;
266*5c51f124SMoriah Waterland
267*5c51f124SMoriah Waterland /*
268*5c51f124SMoriah Waterland * Don't recalculate package objects that are already in the
269*5c51f124SMoriah Waterland * table.
270*5c51f124SMoriah Waterland */
271*5c51f124SMoriah Waterland if (ext->mstat.preloaded)
272*5c51f124SMoriah Waterland continue;
273*5c51f124SMoriah Waterland
274*5c51f124SMoriah Waterland /*
275*5c51f124SMoriah Waterland * Don't accumulate space requirements on read-only
276*5c51f124SMoriah Waterland * remote filesystems.
277*5c51f124SMoriah Waterland */
278*5c51f124SMoriah Waterland if (is_remote_fs(ept->path, &(ext->fsys_value)) &&
279*5c51f124SMoriah Waterland !is_fs_writeable(ept->path, &(ext->fsys_value)))
280*5c51f124SMoriah Waterland continue;
281*5c51f124SMoriah Waterland
282*5c51f124SMoriah Waterland /*
283*5c51f124SMoriah Waterland * Now check if this is a base or apparent filesystem. If
284*5c51f124SMoriah Waterland * it's just apparent, get the resolved filesystem entry,
285*5c51f124SMoriah Waterland * otherwise, base and value are the same.
286*5c51f124SMoriah Waterland */
287*5c51f124SMoriah Waterland if (use_srvr_map_n(ext->fsys_value))
288*5c51f124SMoriah Waterland ext->fsys_base = resolved_fsys(tpath);
289*5c51f124SMoriah Waterland else
290*5c51f124SMoriah Waterland ext->fsys_base = ext->fsys_value;
291*5c51f124SMoriah Waterland
292*5c51f124SMoriah Waterland /* At this point we know we have a good fsys_base. */
293*5c51f124SMoriah Waterland if (fsys_stat(ext->fsys_base)) {
294*5c51f124SMoriah Waterland (*error)++;
295*5c51f124SMoriah Waterland continue;
296*5c51f124SMoriah Waterland }
297*5c51f124SMoriah Waterland
298*5c51f124SMoriah Waterland /*
299*5c51f124SMoriah Waterland * We have to stat this path based upon it's real location.
300*5c51f124SMoriah Waterland * If this is a server-remap, ept->path isn't the real
301*5c51f124SMoriah Waterland * location.
302*5c51f124SMoriah Waterland */
303*5c51f124SMoriah Waterland if (use_srvr_map_n(ext->fsys_value))
304*5c51f124SMoriah Waterland strcpy(tpath, server_map(ept->path, ext->fsys_value));
305*5c51f124SMoriah Waterland else
306*5c51f124SMoriah Waterland strcpy(tpath, ept->path);
307*5c51f124SMoriah Waterland
308*5c51f124SMoriah Waterland fs_tab = get_fs_entry(ext->fsys_base);
309*5c51f124SMoriah Waterland if (stat(tpath, &statbuf)) {
310*5c51f124SMoriah Waterland /* path cannot be accessed */
311*5c51f124SMoriah Waterland fs_tab->fused++;
312*5c51f124SMoriah Waterland if (strchr("dxs", ept->ftype))
313*5c51f124SMoriah Waterland blk =
314*5c51f124SMoriah Waterland nblk(fs_tab->bsize,
315*5c51f124SMoriah Waterland fs_tab->bsize,
316*5c51f124SMoriah Waterland fs_tab->frsize);
317*5c51f124SMoriah Waterland else if (ept->cinfo.size != BADCONT)
318*5c51f124SMoriah Waterland blk = nblk(ept->cinfo.size,
319*5c51f124SMoriah Waterland fs_tab->bsize,
320*5c51f124SMoriah Waterland fs_tab->frsize);
321*5c51f124SMoriah Waterland else
322*5c51f124SMoriah Waterland blk = 0;
323*5c51f124SMoriah Waterland } else {
324*5c51f124SMoriah Waterland /* path already exists */
325*5c51f124SMoriah Waterland if (strchr("dxs", ept->ftype))
326*5c51f124SMoriah Waterland blk = 0;
327*5c51f124SMoriah Waterland else if (ept->cinfo.size != BADCONT) {
328*5c51f124SMoriah Waterland fsblkcnt_t new_size, old_size;
329*5c51f124SMoriah Waterland new_size = nblk(ept->cinfo.size,
330*5c51f124SMoriah Waterland fs_tab->bsize,
331*5c51f124SMoriah Waterland fs_tab->frsize);
332*5c51f124SMoriah Waterland old_size = nblk(statbuf.st_size,
333*5c51f124SMoriah Waterland fs_tab->bsize,
334*5c51f124SMoriah Waterland fs_tab->frsize);
335*5c51f124SMoriah Waterland /*
336*5c51f124SMoriah Waterland * negative blocks show room freed, but since
337*5c51f124SMoriah Waterland * order of installation is uncertain show
338*5c51f124SMoriah Waterland * 0 blocks usage
339*5c51f124SMoriah Waterland */
340*5c51f124SMoriah Waterland if (new_size < old_size)
341*5c51f124SMoriah Waterland blk = 0;
342*5c51f124SMoriah Waterland else
343*5c51f124SMoriah Waterland blk = new_size - old_size;
344*5c51f124SMoriah Waterland } else
345*5c51f124SMoriah Waterland blk = 0;
346*5c51f124SMoriah Waterland }
347*5c51f124SMoriah Waterland fs_tab->bused += blk;
348*5c51f124SMoriah Waterland }
349*5c51f124SMoriah Waterland return (0);
350*5c51f124SMoriah Waterland }
351*5c51f124SMoriah Waterland
352*5c51f124SMoriah Waterland static int
readspace(char * spacefile,int * error)353*5c51f124SMoriah Waterland readspace(char *spacefile, int *error)
354*5c51f124SMoriah Waterland {
355*5c51f124SMoriah Waterland FILE *fp;
356*5c51f124SMoriah Waterland char line[LSIZE];
357*5c51f124SMoriah Waterland long blocks, nodes;
358*5c51f124SMoriah Waterland int n;
359*5c51f124SMoriah Waterland
360*5c51f124SMoriah Waterland if (spacefile == NULL)
361*5c51f124SMoriah Waterland return (0);
362*5c51f124SMoriah Waterland
363*5c51f124SMoriah Waterland if ((fp = fopen(spacefile, "r")) == NULL) {
364*5c51f124SMoriah Waterland progerr(gettext("unable to open spacefile %s"), spacefile);
365*5c51f124SMoriah Waterland return (-1);
366*5c51f124SMoriah Waterland }
367*5c51f124SMoriah Waterland
368*5c51f124SMoriah Waterland while (fgets(line, LSIZE, fp)) {
369*5c51f124SMoriah Waterland struct fstable *fs_tab;
370*5c51f124SMoriah Waterland char *pt, path[PATH_MAX];
371*5c51f124SMoriah Waterland
372*5c51f124SMoriah Waterland blocks = nodes = 0;
373*5c51f124SMoriah Waterland for (pt = line; isspace(*pt); /* void */)
374*5c51f124SMoriah Waterland pt++;
375*5c51f124SMoriah Waterland if (*pt == '#' || *pt == '\0')
376*5c51f124SMoriah Waterland continue;
377*5c51f124SMoriah Waterland
378*5c51f124SMoriah Waterland (void) sscanf(line, "%s %ld %ld", path, &blocks, &nodes);
379*5c51f124SMoriah Waterland mappath(2, path);
380*5c51f124SMoriah Waterland basepath(path, get_basedir(), get_inst_root());
381*5c51f124SMoriah Waterland canonize(path);
382*5c51f124SMoriah Waterland
383*5c51f124SMoriah Waterland n = resolved_fsys(path);
384*5c51f124SMoriah Waterland if (fsys_stat(n)) {
385*5c51f124SMoriah Waterland (*error)++;
386*5c51f124SMoriah Waterland continue;
387*5c51f124SMoriah Waterland }
388*5c51f124SMoriah Waterland
389*5c51f124SMoriah Waterland /*
390*5c51f124SMoriah Waterland * Don't accumulate space requirements on read-only
391*5c51f124SMoriah Waterland * remote filesystems. NOTE: For some reason, this
392*5c51f124SMoriah Waterland * used to check for !remote && read only. If this
393*5c51f124SMoriah Waterland * blows up later, then maybe that was correct -- JST
394*5c51f124SMoriah Waterland */
395*5c51f124SMoriah Waterland if (is_remote_fs_n(n) && !is_fs_writeable_n(n))
396*5c51f124SMoriah Waterland continue;
397*5c51f124SMoriah Waterland
398*5c51f124SMoriah Waterland fs_tab = get_fs_entry(n);
399*5c51f124SMoriah Waterland
400*5c51f124SMoriah Waterland fs_tab->bused += blocks;
401*5c51f124SMoriah Waterland fs_tab->fused += nodes;
402*5c51f124SMoriah Waterland }
403*5c51f124SMoriah Waterland (void) fclose(fp);
404*5c51f124SMoriah Waterland return (0);
405*5c51f124SMoriah Waterland }
406