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