xref: /onnv-gate/usr/src/lib/libast/common/port/mnt.c (revision 4887:feebf9260c2e)
1*4887Schin /***********************************************************************
2*4887Schin *                                                                      *
3*4887Schin *               This software is part of the ast package               *
4*4887Schin *           Copyright (c) 1985-2007 AT&T Knowledge Ventures            *
5*4887Schin *                      and is licensed under the                       *
6*4887Schin *                  Common Public License, Version 1.0                  *
7*4887Schin *                      by AT&T Knowledge Ventures                      *
8*4887Schin *                                                                      *
9*4887Schin *                A copy of the License is available at                 *
10*4887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11*4887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*4887Schin *                                                                      *
13*4887Schin *              Information and Software Systems Research               *
14*4887Schin *                            AT&T Research                             *
15*4887Schin *                           Florham Park NJ                            *
16*4887Schin *                                                                      *
17*4887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
18*4887Schin *                  David Korn <dgk@research.att.com>                   *
19*4887Schin *                   Phong Vo <kpv@research.att.com>                    *
20*4887Schin *                                                                      *
21*4887Schin ***********************************************************************/
22*4887Schin #pragma prototyped
23*4887Schin /*
24*4887Schin  * Glenn Fowler
25*4887Schin  * AT&T Research
26*4887Schin  *
27*4887Schin  * mounted filesystem scan support
28*4887Schin  * where are the standards when you really need them
29*4887Schin  */
30*4887Schin 
31*4887Schin #include <ast.h>
32*4887Schin #include <mnt.h>
33*4887Schin #include <ls.h>
34*4887Schin 
35*4887Schin #if _lib_mntopen && _lib_mntread && _lib_mntclose
36*4887Schin 
37*4887Schin NoN(mnt)
38*4887Schin 
39*4887Schin #else
40*4887Schin 
41*4887Schin /*
42*4887Schin  * the original interface just had mode
43*4887Schin  */
44*4887Schin 
45*4887Schin #define FIXARGS(p,m,s)		do {					\
46*4887Schin 					if ((p)&&*(p)!='/') {		\
47*4887Schin 						mode = p;		\
48*4887Schin 						path = 0;		\
49*4887Schin 					}				\
50*4887Schin 					if (!path)			\
51*4887Schin 						path = s;		\
52*4887Schin 				} while (0)
53*4887Schin typedef struct
54*4887Schin {
55*4887Schin 	Mnt_t	mnt;
56*4887Schin 	char	buf[128];
57*4887Schin #if __CYGWIN__
58*4887Schin 	char	typ[128];
59*4887Schin 	char	opt[128];
60*4887Schin #endif
61*4887Schin } Header_t;
62*4887Schin 
63*4887Schin #if __CYGWIN__
64*4887Schin #include <ast_windows.h>
65*4887Schin #endif
66*4887Schin 
67*4887Schin static void
68*4887Schin set(register Header_t* hp, const char* fs, const char* dir, const char* type, const char* options)
69*4887Schin {
70*4887Schin 	const char*	x;
71*4887Schin 
72*4887Schin 	hp->mnt.flags = 0;
73*4887Schin 	if (x = (const char*)strchr(fs, ':'))
74*4887Schin 	{
75*4887Schin 		if (*++x && *x != '\\')
76*4887Schin 		{
77*4887Schin 			hp->mnt.flags |= MNT_REMOTE;
78*4887Schin 			if (*x == '(')
79*4887Schin 			{
80*4887Schin 				fs = x;
81*4887Schin 				type = "auto";
82*4887Schin 			}
83*4887Schin 		}
84*4887Schin 	}
85*4887Schin 	else if (x = (const char*)strchr(fs, '@'))
86*4887Schin 	{
87*4887Schin 		hp->mnt.flags |= MNT_REMOTE;
88*4887Schin 		sfsprintf(hp->buf, sizeof(hp->buf) - 1, "%s:%*.*s", x + 1, x - fs, x - fs, fs);
89*4887Schin 		fs = (const char*)hp->buf;
90*4887Schin 	}
91*4887Schin 	else if (strmatch(type, "[aAnN][fF][sS]*"))
92*4887Schin 		hp->mnt.flags |= MNT_REMOTE;
93*4887Schin 	if (streq(fs, "none"))
94*4887Schin 		fs = dir;
95*4887Schin 	hp->mnt.fs = (char*)fs;
96*4887Schin 	hp->mnt.dir = (char*)dir;
97*4887Schin 	hp->mnt.type = (char*)type;
98*4887Schin 	hp->mnt.options = (char*)options;
99*4887Schin #if __CYGWIN__
100*4887Schin 	if (streq(type, "system") || streq(type, "user"))
101*4887Schin 	{
102*4887Schin 		char*	s;
103*4887Schin 		int	mode;
104*4887Schin 		DWORD	vser;
105*4887Schin 		DWORD	flags;
106*4887Schin 		DWORD	len;
107*4887Schin 		char	drive[4];
108*4887Schin 
109*4887Schin 		mode = SetErrorMode(SEM_FAILCRITICALERRORS);
110*4887Schin 		drive[0] = fs[0];
111*4887Schin 		drive[1] = ':';
112*4887Schin 		drive[2] = '\\';
113*4887Schin 		drive[3] = 0;
114*4887Schin 		if (GetVolumeInformation(drive, 0, 0, &vser, &len, &flags, hp->typ, sizeof(hp->typ) - 1))
115*4887Schin 			hp->mnt.type = hp->typ;
116*4887Schin 		else
117*4887Schin 			flags = 0;
118*4887Schin 		SetErrorMode(mode);
119*4887Schin 		s = strcopy(hp->mnt.options = hp->opt, type);
120*4887Schin 		s = strcopy(s, ",ignorecase");
121*4887Schin 		if (options)
122*4887Schin 		{
123*4887Schin 			*s++ = ',';
124*4887Schin 			strcpy(s, options);
125*4887Schin 		}
126*4887Schin 	}
127*4887Schin #endif
128*4887Schin }
129*4887Schin 
130*4887Schin #undef	MNT_REMOTE
131*4887Schin 
132*4887Schin #if _lib_getmntinfo && _sys_mount
133*4887Schin 
134*4887Schin /*
135*4887Schin  * 4.4 bsd
136*4887Schin  *
137*4887Schin  * what a crappy interface
138*4887Schin  * data returned in static buffer -- ok
139*4887Schin  * big chunk of allocated memory that cannot be freed -- come on
140*4887Schin  * *and* netbsd changed the interface somewhere along the line
141*4887Schin  * private interface? my bad -- public interface? par for the bsd course
142*4887Schin  */
143*4887Schin 
144*4887Schin #include <sys/param.h>		/* expect some macro redefinitions here */
145*4887Schin #include <sys/mount.h>
146*4887Schin 
147*4887Schin #if _lib_getmntinfo_statvfs
148*4887Schin #define statfs		statvfs
149*4887Schin #define f_flags		f_flag
150*4887Schin #endif
151*4887Schin 
152*4887Schin typedef struct
153*4887Schin {
154*4887Schin 	Header_t	hdr;
155*4887Schin 	struct statfs*	next;
156*4887Schin 	struct statfs*	last;
157*4887Schin 	char		opt[256];
158*4887Schin } Handle_t;
159*4887Schin 
160*4887Schin #ifdef MFSNAMELEN
161*4887Schin #define TYPE(f)		((f)->f_fstypename)
162*4887Schin #else
163*4887Schin #ifdef INITMOUNTNAMES
164*4887Schin #define TYPE(f)		((char*)type[(f)->f_type])
165*4887Schin static const char*	type[] = INITMOUNTNAMES;
166*4887Schin #else
167*4887Schin #if _sys_fs_types
168*4887Schin #define TYPE(f)		((char*)mnt_names[(f)->f_type])
169*4887Schin #include <sys/fs_types.h>
170*4887Schin #else
171*4887Schin #define TYPE(f)		(strchr((f)->f_mntfromname,':')?"nfs":"ufs")
172*4887Schin #endif
173*4887Schin #endif
174*4887Schin #endif
175*4887Schin 
176*4887Schin static struct Mnt_options_t
177*4887Schin {
178*4887Schin 	unsigned long	flag;
179*4887Schin 	const char*	name;
180*4887Schin }
181*4887Schin options[] =
182*4887Schin {
183*4887Schin #ifdef MNT_RDONLY
184*4887Schin 	MNT_RDONLY,	"rdonly",
185*4887Schin #endif
186*4887Schin #ifdef MNT_SYNCHRONOUS
187*4887Schin 	MNT_SYNCHRONOUS,"synchronous",
188*4887Schin #endif
189*4887Schin #ifdef MNT_NOEXEC
190*4887Schin 	MNT_NOEXEC,	"noexec",
191*4887Schin #endif
192*4887Schin #ifdef MNT_NOSUID
193*4887Schin 	MNT_NOSUID,	"nosuid",
194*4887Schin #endif
195*4887Schin #ifdef MNT_NODEV
196*4887Schin 	MNT_NODEV,	"nodev",
197*4887Schin #endif
198*4887Schin #ifdef MNT_UNION
199*4887Schin 	MNT_UNION,	"union",
200*4887Schin #endif
201*4887Schin #ifdef MNT_ASYNC
202*4887Schin 	MNT_ASYNC,	"async",
203*4887Schin #endif
204*4887Schin #ifdef MNT_NOCOREDUMP
205*4887Schin 	MNT_NOCOREDUMP,	"nocoredump",
206*4887Schin #endif
207*4887Schin #ifdef MNT_NOATIME
208*4887Schin 	MNT_NOATIME,	"noatime",
209*4887Schin #endif
210*4887Schin #ifdef MNT_SYMPERM
211*4887Schin 	MNT_SYMPERM,	"symperm",
212*4887Schin #endif
213*4887Schin #ifdef MNT_NODEVMTIME
214*4887Schin 	MNT_NODEVMTIME,	"nodevmtime",
215*4887Schin #endif
216*4887Schin #ifdef MNT_SOFTDEP
217*4887Schin 	MNT_SOFTDEP,	"softdep",
218*4887Schin #endif
219*4887Schin #ifdef MNT_EXRDONLY
220*4887Schin 	MNT_EXRDONLY,	"exrdonly",
221*4887Schin #endif
222*4887Schin #ifdef MNT_EXPORTED
223*4887Schin 	MNT_EXPORTED,	"exported",
224*4887Schin #endif
225*4887Schin #ifdef MNT_DEFEXPORTED
226*4887Schin 	MNT_DEFEXPORTED,"defexported",
227*4887Schin #endif
228*4887Schin #ifdef MNT_EXPORTANON
229*4887Schin 	MNT_EXPORTANON,	"exportanon",
230*4887Schin #endif
231*4887Schin #ifdef MNT_EXKERB
232*4887Schin 	MNT_EXKERB,	"exkerb",
233*4887Schin #endif
234*4887Schin #ifdef MNT_EXNORESPORT
235*4887Schin 	MNT_EXNORESPORT,"exnoresport",
236*4887Schin #endif
237*4887Schin #ifdef MNT_EXPUBLIC
238*4887Schin 	MNT_EXPUBLIC,	"expublic",
239*4887Schin #endif
240*4887Schin #ifdef MNT_LOCAL
241*4887Schin 	MNT_LOCAL,	"local",
242*4887Schin #endif
243*4887Schin #ifdef MNT_QUOTA
244*4887Schin 	MNT_QUOTA,	"quota",
245*4887Schin #endif
246*4887Schin #ifdef MNT_ROOTFS
247*4887Schin 	MNT_ROOTFS,	"rootfs",
248*4887Schin #endif
249*4887Schin 	0,		"unknown",
250*4887Schin };
251*4887Schin 
252*4887Schin void*
253*4887Schin mntopen(const char* path, const char* mode)
254*4887Schin {
255*4887Schin 	register Handle_t*	mp;
256*4887Schin 	register int		n;
257*4887Schin 
258*4887Schin 	FIXARGS(path, mode, 0);
259*4887Schin 	if (!(mp = newof(0, Handle_t, 1, 0)))
260*4887Schin 		return 0;
261*4887Schin 	if ((n = getmntinfo(&mp->next, 0)) <= 0)
262*4887Schin 	{
263*4887Schin 		free(mp);
264*4887Schin 		return 0;
265*4887Schin 	}
266*4887Schin 	mp->last = mp->next + n;
267*4887Schin 	return (void*)mp;
268*4887Schin }
269*4887Schin 
270*4887Schin Mnt_t*
271*4887Schin mntread(void* handle)
272*4887Schin {
273*4887Schin 	register Handle_t*	mp = (Handle_t*)handle;
274*4887Schin 	register int		i;
275*4887Schin 	register int		n;
276*4887Schin 	register unsigned long	flags;
277*4887Schin 
278*4887Schin 	if (mp->next < mp->last)
279*4887Schin 	{
280*4887Schin 		flags = mp->next->f_flags;
281*4887Schin 		n = 0;
282*4887Schin 		for (i = 0; i < elementsof(options); i++)
283*4887Schin 			if (flags & options[i].flag)
284*4887Schin 				n += sfsprintf(mp->opt + n, sizeof(mp->opt) - n - 1, ",%s", options[i].name);
285*4887Schin 		set(&mp->hdr, mp->next->f_mntfromname, mp->next->f_mntonname, TYPE(mp->next), n ? (mp->opt + 1) : (char*)0);
286*4887Schin 		mp->next++;
287*4887Schin 		return &mp->hdr.mnt;
288*4887Schin 	}
289*4887Schin 	return 0;
290*4887Schin }
291*4887Schin 
292*4887Schin int
293*4887Schin mntclose(void* handle)
294*4887Schin {
295*4887Schin 	register Handle_t*	mp = (Handle_t*)handle;
296*4887Schin 
297*4887Schin 	if (!mp)
298*4887Schin 		return -1;
299*4887Schin 	free(mp);
300*4887Schin 	return 0;
301*4887Schin }
302*4887Schin 
303*4887Schin #else
304*4887Schin 
305*4887Schin #if _lib_mntctl && _sys_vmount
306*4887Schin 
307*4887Schin /*
308*4887Schin  * aix
309*4887Schin  */
310*4887Schin 
311*4887Schin #include <sys/vmount.h>
312*4887Schin 
313*4887Schin #define SIZE		(16 * 1024)
314*4887Schin 
315*4887Schin static const char*	type[] =
316*4887Schin {
317*4887Schin 	"aix", "aix#1", "nfs", "jfs", "aix#4", "cdrom"
318*4887Schin };
319*4887Schin 
320*4887Schin typedef struct
321*4887Schin {
322*4887Schin 	Header_t	hdr;
323*4887Schin 	long		count;
324*4887Schin 	struct vmount*	next;
325*4887Schin 	char		remote[128];
326*4887Schin 	char		type[16];
327*4887Schin 	struct vmount	info[1];
328*4887Schin } Handle_t;
329*4887Schin 
330*4887Schin void*
331*4887Schin mntopen(const char* path, const char* mode)
332*4887Schin {
333*4887Schin 	register Handle_t*	mp;
334*4887Schin 
335*4887Schin 	FIXARGS(path, mode, 0);
336*4887Schin 	if (!(mp = newof(0, Handle_t, 1, SIZE)))
337*4887Schin 		return 0;
338*4887Schin 	if ((mp->count = mntctl(MCTL_QUERY, sizeof(Handle_t) + SIZE, &mp->info)) <= 0)
339*4887Schin 	{
340*4887Schin 		free(mp);
341*4887Schin 		return 0;
342*4887Schin 	}
343*4887Schin 	mp->next = mp->info;
344*4887Schin 	return (void*)mp;
345*4887Schin }
346*4887Schin 
347*4887Schin Mnt_t*
348*4887Schin mntread(void* handle)
349*4887Schin {
350*4887Schin 	register Handle_t*	mp = (Handle_t*)handle;
351*4887Schin 	register char*		s;
352*4887Schin 	register char*		t;
353*4887Schin 	register char*		o;
354*4887Schin 
355*4887Schin 	if (mp->count > 0)
356*4887Schin 	{
357*4887Schin 		if (vmt2datasize(mp->next, VMT_HOST) && (s = vmt2dataptr(mp->next, VMT_HOST)) && !streq(s, "-"))
358*4887Schin 		{
359*4887Schin 			sfsprintf(mp->remote, sizeof(mp->remote) - 1, "%s:%s", s, vmt2dataptr(mp->next, VMT_OBJECT));
360*4887Schin 			s = mp->remote;
361*4887Schin 		}
362*4887Schin 		else
363*4887Schin 			s = vmt2dataptr(mp->next, VMT_OBJECT);
364*4887Schin 		if (vmt2datasize(mp->next, VMT_ARGS))
365*4887Schin 			o = vmt2dataptr(mp->next, VMT_ARGS);
366*4887Schin 		else
367*4887Schin 			o = NiL;
368*4887Schin 		switch (mp->next->vmt_gfstype)
369*4887Schin 		{
370*4887Schin #ifdef MNT_AIX
371*4887Schin 		case MNT_AIX:
372*4887Schin 			t = "aix";
373*4887Schin 			break;
374*4887Schin #endif
375*4887Schin #ifdef MNT_NFS
376*4887Schin 		case MNT_NFS:
377*4887Schin 			t = "nfs";
378*4887Schin 			break;
379*4887Schin #endif
380*4887Schin #ifdef MNT_JFS
381*4887Schin 		case MNT_JFS:
382*4887Schin 			t = "jfs";
383*4887Schin 			break;
384*4887Schin #endif
385*4887Schin #ifdef MNT_CDROM
386*4887Schin 		case MNT_CDROM:
387*4887Schin 			t = "cdrom";
388*4887Schin 			break;
389*4887Schin #endif
390*4887Schin #ifdef MNT_SFS
391*4887Schin 		case MNT_SFS:
392*4887Schin 			t = "sfs";
393*4887Schin 			break;
394*4887Schin #endif
395*4887Schin #ifdef MNT_CACHEFS
396*4887Schin 		case MNT_CACHEFS:
397*4887Schin 			t = "cachefs";
398*4887Schin 			break;
399*4887Schin #endif
400*4887Schin #ifdef MNT_NFS3
401*4887Schin 		case MNT_NFS3:
402*4887Schin 			t = "nfs3";
403*4887Schin 			break;
404*4887Schin #endif
405*4887Schin #ifdef MNT_AUTOFS
406*4887Schin 		case MNT_AUTOFS:
407*4887Schin 			t = "autofs";
408*4887Schin 			break;
409*4887Schin #endif
410*4887Schin 		default:
411*4887Schin 			sfsprintf(t = mp->type, sizeof(mp->type), "aix%+d", mp->next->vmt_gfstype);
412*4887Schin 			break;
413*4887Schin 		}
414*4887Schin 		set(&mp->hdr, s, vmt2dataptr(mp->next, VMT_STUB), t, o);
415*4887Schin 		if (--mp->count > 0)
416*4887Schin 			mp->next = (struct vmount*)((char*)mp->next + mp->next->vmt_length);
417*4887Schin 		return &mp->hdr.mnt;
418*4887Schin 	}
419*4887Schin 	return 0;
420*4887Schin }
421*4887Schin 
422*4887Schin int
423*4887Schin mntclose(void* handle)
424*4887Schin {
425*4887Schin 	register Handle_t*	mp = (Handle_t*)handle;
426*4887Schin 
427*4887Schin 	if (!mp)
428*4887Schin 		return -1;
429*4887Schin 	free(mp);
430*4887Schin 	return 0;
431*4887Schin }
432*4887Schin 
433*4887Schin #else
434*4887Schin 
435*4887Schin #if !_lib_setmntent
436*4887Schin #undef	_lib_getmntent
437*4887Schin #if !_SCO_COFF && !_SCO_ELF && !_UTS
438*4887Schin #undef	_hdr_mnttab
439*4887Schin #endif
440*4887Schin #endif
441*4887Schin 
442*4887Schin #if _lib_getmntent && ( _hdr_mntent || _sys_mntent && !_sys_mnttab )
443*4887Schin 
444*4887Schin #if defined(__STDPP__directive) && defined(__STDPP__hide)
445*4887Schin __STDPP__directive pragma pp:hide endmntent getmntent
446*4887Schin #else
447*4887Schin #define endmntent	______endmntent
448*4887Schin #define getmntent	______getmntent
449*4887Schin #endif
450*4887Schin 
451*4887Schin #include <stdio.h>
452*4887Schin #if _hdr_mntent
453*4887Schin #include <mntent.h>
454*4887Schin #else
455*4887Schin #include <sys/mntent.h>
456*4887Schin #endif
457*4887Schin 
458*4887Schin #if defined(__STDPP__directive) && defined(__STDPP__hide)
459*4887Schin __STDPP__directive pragma pp:nohide endmntent getmntent
460*4887Schin #else
461*4887Schin #undef	endmntent
462*4887Schin #undef	getmntent
463*4887Schin #endif
464*4887Schin 
465*4887Schin extern int		endmntent(FILE*);
466*4887Schin extern struct mntent*	getmntent(FILE*);
467*4887Schin 
468*4887Schin #else
469*4887Schin 
470*4887Schin #undef	_lib_getmntent
471*4887Schin 
472*4887Schin #if _hdr_mnttab
473*4887Schin #include <mnttab.h>
474*4887Schin #else
475*4887Schin #if _sys_mnttab
476*4887Schin #include <sys/mnttab.h>
477*4887Schin #endif
478*4887Schin #endif
479*4887Schin 
480*4887Schin #endif
481*4887Schin 
482*4887Schin #ifndef MOUNTED
483*4887Schin #ifdef	MNT_MNTTAB
484*4887Schin #define MOUNTED		MNT_MNTTAB
485*4887Schin #else
486*4887Schin #if _hdr_mnttab || _sys_mnttab
487*4887Schin #define MOUNTED		"/etc/mnttab"
488*4887Schin #else
489*4887Schin #define MOUNTED		"/etc/mtab"
490*4887Schin #endif
491*4887Schin #endif
492*4887Schin #endif
493*4887Schin 
494*4887Schin #ifdef __Lynx__
495*4887Schin #undef	MOUNTED
496*4887Schin #define MOUNTED		"/etc/fstab"
497*4887Schin #define SEP		':'
498*4887Schin #endif
499*4887Schin 
500*4887Schin #if _lib_getmntent
501*4887Schin 
502*4887Schin typedef struct
503*4887Schin #if _mem_mnt_opts_mntent
504*4887Schin #define OPTIONS(p)	((p)->mnt_opts)
505*4887Schin #else
506*4887Schin #define OPTIONS(p)	NiL
507*4887Schin #endif
508*4887Schin 
509*4887Schin {
510*4887Schin 	Header_t	hdr;
511*4887Schin 	FILE*		fp;
512*4887Schin } Handle_t;
513*4887Schin 
514*4887Schin void*
515*4887Schin mntopen(const char* path, const char* mode)
516*4887Schin {
517*4887Schin 	register Handle_t*	mp;
518*4887Schin 
519*4887Schin 	FIXARGS(path, mode, MOUNTED);
520*4887Schin 	if (!(mp = newof(0, Handle_t, 1, 0)))
521*4887Schin 		return 0;
522*4887Schin 	if (!(mp->fp = setmntent(path, mode)))
523*4887Schin 	{
524*4887Schin 		free(mp);
525*4887Schin 		return 0;
526*4887Schin 	}
527*4887Schin 	return (void*)mp;
528*4887Schin }
529*4887Schin 
530*4887Schin Mnt_t*
531*4887Schin mntread(void* handle)
532*4887Schin {
533*4887Schin 	register Handle_t*	mp = (Handle_t*)handle;
534*4887Schin 	register struct mntent*	mnt;
535*4887Schin 
536*4887Schin 	if (mnt = getmntent(mp->fp))
537*4887Schin 	{
538*4887Schin 		set(&mp->hdr, mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, OPTIONS(mnt));
539*4887Schin 		return &mp->hdr.mnt;
540*4887Schin 	}
541*4887Schin 	return 0;
542*4887Schin }
543*4887Schin 
544*4887Schin int
545*4887Schin mntclose(void* handle)
546*4887Schin {
547*4887Schin 	register Handle_t*	mp = (Handle_t*)handle;
548*4887Schin 
549*4887Schin 	if (!mp)
550*4887Schin 		return -1;
551*4887Schin 	endmntent(mp->fp);
552*4887Schin 	free(mp);
553*4887Schin 	return 0;
554*4887Schin }
555*4887Schin 
556*4887Schin #else
557*4887Schin 
558*4887Schin #if _sys_mntent && _lib_w_getmntent
559*4887Schin 
560*4887Schin #include <sys/mntent.h>
561*4887Schin 
562*4887Schin #define mntent		w_mntent
563*4887Schin 
564*4887Schin #define mnt_dir		mnt_mountpoint
565*4887Schin #define mnt_type	mnt_fstname
566*4887Schin 
567*4887Schin #define MNTBUFSIZE	(sizeof(struct w_mnth)+16*sizeof(struct w_mntent))
568*4887Schin 
569*4887Schin #if _mem_mnt_opts_w_mntent
570*4887Schin #define OPTIONS(p)	((p)->mnt_opts)
571*4887Schin #else
572*4887Schin #define OPTIONS(p)	NiL
573*4887Schin #endif
574*4887Schin 
575*4887Schin #else
576*4887Schin 
577*4887Schin #undef _lib_w_getmntent
578*4887Schin 
579*4887Schin #define MNTBUFSIZE	sizeof(struct mntent)
580*4887Schin 
581*4887Schin #if !_mem_mt_dev_mnttab || !_mem_mt_filsys_mnttab
582*4887Schin #undef	_hdr_mnttab
583*4887Schin #endif
584*4887Schin 
585*4887Schin #if _hdr_mnttab
586*4887Schin 
587*4887Schin #define mntent	mnttab
588*4887Schin 
589*4887Schin #define mnt_fsname	mt_dev
590*4887Schin #define mnt_dir		mt_filsys
591*4887Schin #if _mem_mt_fstyp_mnttab
592*4887Schin #define mnt_type	mt_fstyp
593*4887Schin #endif
594*4887Schin 
595*4887Schin #if _mem_mnt_opts_mnttab
596*4887Schin #define OPTIONS(p)	((p)->mnt_opts)
597*4887Schin #else
598*4887Schin #define OPTIONS(p)	NiL
599*4887Schin #endif
600*4887Schin 
601*4887Schin #else
602*4887Schin 
603*4887Schin struct mntent
604*4887Schin {
605*4887Schin 	char	mnt_fsname[256];
606*4887Schin 	char	mnt_dir[256];
607*4887Schin 	char	mnt_type[32];
608*4887Schin 	char	mnt_opts[64];
609*4887Schin };
610*4887Schin 
611*4887Schin #define OPTIONS(p)	((p)->mnt_opts)
612*4887Schin 
613*4887Schin #endif
614*4887Schin 
615*4887Schin #endif
616*4887Schin 
617*4887Schin typedef struct
618*4887Schin {
619*4887Schin 	Header_t	hdr;
620*4887Schin 	Sfio_t*		fp;
621*4887Schin 	struct mntent*	mnt;
622*4887Schin #if _lib_w_getmntent
623*4887Schin 	int		count;
624*4887Schin #endif
625*4887Schin 	char		buf[MNTBUFSIZE];
626*4887Schin } Handle_t;
627*4887Schin 
628*4887Schin void*
629*4887Schin mntopen(const char* path, const char* mode)
630*4887Schin {
631*4887Schin 	register Handle_t*	mp;
632*4887Schin 
633*4887Schin 	FIXARGS(path, mode, MOUNTED);
634*4887Schin 	if (!(mp = newof(0, Handle_t, 1, 0)))
635*4887Schin 		return 0;
636*4887Schin #if _lib_w_getmntent
637*4887Schin 	if ((mp->count = w_getmntent(mp->buf, sizeof(mp->buf))) > 0)
638*4887Schin 		mp->mnt = (struct mntent*)(((struct w_mnth*)mp->buf) + 1);
639*4887Schin 	else
640*4887Schin #else
641*4887Schin 	mp->mnt = (struct mntent*)mp->buf;
642*4887Schin 	if (!(mp->fp = sfopen(NiL, path, mode)))
643*4887Schin #endif
644*4887Schin 	{
645*4887Schin 		free(mp);
646*4887Schin 		return 0;
647*4887Schin 	}
648*4887Schin 	return (void*)mp;
649*4887Schin }
650*4887Schin 
651*4887Schin Mnt_t*
652*4887Schin mntread(void* handle)
653*4887Schin {
654*4887Schin 	register Handle_t*	mp = (Handle_t*)handle;
655*4887Schin 
656*4887Schin #if _lib_w_getmntent
657*4887Schin 
658*4887Schin 	if (mp->count-- <= 0)
659*4887Schin 	{
660*4887Schin 		if ((mp->count = w_getmntent(mp->buf, sizeof(mp->buf))) <= 0)
661*4887Schin 			return 0;
662*4887Schin 		mp->count--;
663*4887Schin 		mp->mnt = (struct mntent*)(((struct w_mnth*)mp->buf) + 1);
664*4887Schin 	}
665*4887Schin 	set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt));
666*4887Schin 	mp->mnt++;
667*4887Schin 	return &mp->hdr.mnt;
668*4887Schin 
669*4887Schin #else
670*4887Schin 
671*4887Schin #if _hdr_mnttab
672*4887Schin 
673*4887Schin 	while (sfread(mp->fp, &mp->buf, sizeof(mp->buf)) == sizeof(mp->buf))
674*4887Schin 		if (*mp->mnt->mnt_fsname && *mp->mnt->mnt_dir)
675*4887Schin 		{
676*4887Schin #ifndef mnt_type
677*4887Schin 			struct stat	st;
678*4887Schin 
679*4887Schin 			static char	typ[32];
680*4887Schin 
681*4887Schin 			set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, stat(mp->mnt->mnt_dir, &st) ? FS_default : strncpy(typ, fmtfs(&st), sizeof(typ) - 1), OPTIONS(mp->mnt));
682*4887Schin #else
683*4887Schin 			set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt));
684*4887Schin #endif
685*4887Schin 			return &mp->hdr.mnt;
686*4887Schin 		}
687*4887Schin 	return 0;
688*4887Schin 
689*4887Schin #else
690*4887Schin 
691*4887Schin 	register int		c;
692*4887Schin 	register char*		s;
693*4887Schin 	register char*		m;
694*4887Schin 	register char*		b;
695*4887Schin 	register int		q;
696*4887Schin 	register int		x;
697*4887Schin 
698*4887Schin  again:
699*4887Schin 	q = 0;
700*4887Schin 	x = 0;
701*4887Schin 	b = s = mp->mnt->mnt_fsname;
702*4887Schin 	m = s + sizeof(mp->mnt->mnt_fsname) - 1;
703*4887Schin 	for (;;) switch (c = sfgetc(mp->fp))
704*4887Schin 	{
705*4887Schin 	case EOF:
706*4887Schin 		return 0;
707*4887Schin 	case '"':
708*4887Schin 	case '\'':
709*4887Schin 		if (q == c)
710*4887Schin 			q = 0;
711*4887Schin 		else if (!q)
712*4887Schin 			q = c;
713*4887Schin 		break;
714*4887Schin #ifdef SEP
715*4887Schin 	case SEP:
716*4887Schin #else
717*4887Schin 	case ' ':
718*4887Schin 	case '\t':
719*4887Schin #endif
720*4887Schin 		if (s != b && !q) switch (++x)
721*4887Schin 		{
722*4887Schin 		case 1:
723*4887Schin 			*s = 0;
724*4887Schin 			b = s = mp->mnt->mnt_dir;
725*4887Schin 			m = s + sizeof(mp->mnt->mnt_dir) - 1;
726*4887Schin 			break;
727*4887Schin 		case 2:
728*4887Schin 			*s = 0;
729*4887Schin 			b = s = mp->mnt->mnt_type;
730*4887Schin 			m = s + sizeof(mp->mnt->mnt_type) - 1;
731*4887Schin 			break;
732*4887Schin 		case 3:
733*4887Schin 			*s = 0;
734*4887Schin 			b = s = mp->mnt->mnt_opts;
735*4887Schin 			m = s + sizeof(mp->mnt->mnt_opts) - 1;
736*4887Schin 			break;
737*4887Schin 		case 4:
738*4887Schin 			*s = 0;
739*4887Schin 			b = s = m = 0;
740*4887Schin 			break;
741*4887Schin 		}
742*4887Schin 		break;
743*4887Schin 	case '\n':
744*4887Schin 		if (x >= 3)
745*4887Schin 		{
746*4887Schin 			set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt));
747*4887Schin 			return &mp->hdr.mnt;
748*4887Schin 		}
749*4887Schin 		goto again;
750*4887Schin 	default:
751*4887Schin 		if (s < m)
752*4887Schin 			*s++ = c;
753*4887Schin 		break;
754*4887Schin 	}
755*4887Schin 
756*4887Schin #endif
757*4887Schin 
758*4887Schin #endif
759*4887Schin 
760*4887Schin }
761*4887Schin 
762*4887Schin int
763*4887Schin mntclose(void* handle)
764*4887Schin {
765*4887Schin 	register Handle_t*	mp = (Handle_t*)handle;
766*4887Schin 
767*4887Schin 	if (!mp)
768*4887Schin 		return -1;
769*4887Schin 	sfclose(mp->fp);
770*4887Schin 	free(mp);
771*4887Schin 	return 0;
772*4887Schin }
773*4887Schin 
774*4887Schin #endif
775*4887Schin 
776*4887Schin #endif
777*4887Schin 
778*4887Schin #endif
779*4887Schin 
780*4887Schin /*
781*4887Schin  * currently no write
782*4887Schin  */
783*4887Schin 
784*4887Schin int
785*4887Schin mntwrite(void* handle, const Mnt_t* mnt)
786*4887Schin {
787*4887Schin 	NoP(handle);
788*4887Schin 	NoP(mnt);
789*4887Schin 	return -1;
790*4887Schin }
791*4887Schin 
792*4887Schin #endif
793