xref: /onnv-gate/usr/src/lib/libast/common/port/mnt.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin /*
244887Schin  * Glenn Fowler
254887Schin  * AT&T Research
264887Schin  *
274887Schin  * mounted filesystem scan support
284887Schin  * where are the standards when you really need them
294887Schin  */
304887Schin 
314887Schin #include <ast.h>
324887Schin #include <mnt.h>
334887Schin #include <ls.h>
344887Schin 
354887Schin #if _lib_mntopen && _lib_mntread && _lib_mntclose
364887Schin 
374887Schin NoN(mnt)
384887Schin 
394887Schin #else
404887Schin 
414887Schin /*
424887Schin  * the original interface just had mode
434887Schin  */
444887Schin 
454887Schin #define FIXARGS(p,m,s)		do {					\
464887Schin 					if ((p)&&*(p)!='/') {		\
474887Schin 						mode = p;		\
484887Schin 						path = 0;		\
494887Schin 					}				\
504887Schin 					if (!path)			\
514887Schin 						path = s;		\
524887Schin 				} while (0)
534887Schin typedef struct
544887Schin {
554887Schin 	Mnt_t	mnt;
564887Schin 	char	buf[128];
574887Schin #if __CYGWIN__
584887Schin 	char	typ[128];
594887Schin 	char	opt[128];
604887Schin #endif
614887Schin } Header_t;
624887Schin 
634887Schin #if __CYGWIN__
644887Schin #include <ast_windows.h>
654887Schin #endif
664887Schin 
674887Schin static void
684887Schin set(register Header_t* hp, const char* fs, const char* dir, const char* type, const char* options)
694887Schin {
704887Schin 	const char*	x;
714887Schin 
724887Schin 	hp->mnt.flags = 0;
734887Schin 	if (x = (const char*)strchr(fs, ':'))
744887Schin 	{
754887Schin 		if (*++x && *x != '\\')
764887Schin 		{
774887Schin 			hp->mnt.flags |= MNT_REMOTE;
784887Schin 			if (*x == '(')
794887Schin 			{
804887Schin 				fs = x;
814887Schin 				type = "auto";
824887Schin 			}
834887Schin 		}
844887Schin 	}
854887Schin 	else if (x = (const char*)strchr(fs, '@'))
864887Schin 	{
874887Schin 		hp->mnt.flags |= MNT_REMOTE;
884887Schin 		sfsprintf(hp->buf, sizeof(hp->buf) - 1, "%s:%*.*s", x + 1, x - fs, x - fs, fs);
894887Schin 		fs = (const char*)hp->buf;
904887Schin 	}
914887Schin 	else if (strmatch(type, "[aAnN][fF][sS]*"))
924887Schin 		hp->mnt.flags |= MNT_REMOTE;
934887Schin 	if (streq(fs, "none"))
944887Schin 		fs = dir;
954887Schin 	hp->mnt.fs = (char*)fs;
964887Schin 	hp->mnt.dir = (char*)dir;
974887Schin 	hp->mnt.type = (char*)type;
984887Schin 	hp->mnt.options = (char*)options;
994887Schin #if __CYGWIN__
1004887Schin 	if (streq(type, "system") || streq(type, "user"))
1014887Schin 	{
1024887Schin 		char*	s;
1034887Schin 		int	mode;
1044887Schin 		DWORD	vser;
1054887Schin 		DWORD	flags;
1064887Schin 		DWORD	len;
1074887Schin 		char	drive[4];
1084887Schin 
1094887Schin 		mode = SetErrorMode(SEM_FAILCRITICALERRORS);
1104887Schin 		drive[0] = fs[0];
1114887Schin 		drive[1] = ':';
1124887Schin 		drive[2] = '\\';
1134887Schin 		drive[3] = 0;
1144887Schin 		if (GetVolumeInformation(drive, 0, 0, &vser, &len, &flags, hp->typ, sizeof(hp->typ) - 1))
1154887Schin 			hp->mnt.type = hp->typ;
1164887Schin 		else
1174887Schin 			flags = 0;
1184887Schin 		SetErrorMode(mode);
1194887Schin 		s = strcopy(hp->mnt.options = hp->opt, type);
1204887Schin 		s = strcopy(s, ",ignorecase");
1214887Schin 		if (options)
1224887Schin 		{
1234887Schin 			*s++ = ',';
1244887Schin 			strcpy(s, options);
1254887Schin 		}
1264887Schin 	}
1274887Schin #endif
1284887Schin }
1294887Schin 
1304887Schin #undef	MNT_REMOTE
1314887Schin 
1324887Schin #if _lib_getmntinfo && _sys_mount
1334887Schin 
1344887Schin /*
1354887Schin  * 4.4 bsd
1364887Schin  *
1374887Schin  * what a crappy interface
1384887Schin  * data returned in static buffer -- ok
1394887Schin  * big chunk of allocated memory that cannot be freed -- come on
1404887Schin  * *and* netbsd changed the interface somewhere along the line
1414887Schin  * private interface? my bad -- public interface? par for the bsd course
1424887Schin  */
1434887Schin 
1444887Schin #include <sys/param.h>		/* expect some macro redefinitions here */
1454887Schin #include <sys/mount.h>
1464887Schin 
1474887Schin #if _lib_getmntinfo_statvfs
1484887Schin #define statfs		statvfs
1494887Schin #define f_flags		f_flag
1504887Schin #endif
1514887Schin 
1524887Schin typedef struct
1534887Schin {
1544887Schin 	Header_t	hdr;
1554887Schin 	struct statfs*	next;
1564887Schin 	struct statfs*	last;
1574887Schin 	char		opt[256];
1584887Schin } Handle_t;
1594887Schin 
1604887Schin #ifdef MFSNAMELEN
1614887Schin #define TYPE(f)		((f)->f_fstypename)
1624887Schin #else
1634887Schin #ifdef INITMOUNTNAMES
1644887Schin #define TYPE(f)		((char*)type[(f)->f_type])
1654887Schin static const char*	type[] = INITMOUNTNAMES;
1664887Schin #else
1674887Schin #if _sys_fs_types
1684887Schin #define TYPE(f)		((char*)mnt_names[(f)->f_type])
1694887Schin #include <sys/fs_types.h>
1704887Schin #else
1714887Schin #define TYPE(f)		(strchr((f)->f_mntfromname,':')?"nfs":"ufs")
1724887Schin #endif
1734887Schin #endif
1744887Schin #endif
1754887Schin 
1764887Schin static struct Mnt_options_t
1774887Schin {
1784887Schin 	unsigned long	flag;
1794887Schin 	const char*	name;
1804887Schin }
1814887Schin options[] =
1824887Schin {
1834887Schin #ifdef MNT_RDONLY
1844887Schin 	MNT_RDONLY,	"rdonly",
1854887Schin #endif
1864887Schin #ifdef MNT_SYNCHRONOUS
1874887Schin 	MNT_SYNCHRONOUS,"synchronous",
1884887Schin #endif
1894887Schin #ifdef MNT_NOEXEC
1904887Schin 	MNT_NOEXEC,	"noexec",
1914887Schin #endif
1924887Schin #ifdef MNT_NOSUID
1934887Schin 	MNT_NOSUID,	"nosuid",
1944887Schin #endif
1954887Schin #ifdef MNT_NODEV
1964887Schin 	MNT_NODEV,	"nodev",
1974887Schin #endif
1984887Schin #ifdef MNT_UNION
1994887Schin 	MNT_UNION,	"union",
2004887Schin #endif
2014887Schin #ifdef MNT_ASYNC
2024887Schin 	MNT_ASYNC,	"async",
2034887Schin #endif
2044887Schin #ifdef MNT_NOCOREDUMP
2054887Schin 	MNT_NOCOREDUMP,	"nocoredump",
2064887Schin #endif
2074887Schin #ifdef MNT_NOATIME
2084887Schin 	MNT_NOATIME,	"noatime",
2094887Schin #endif
2104887Schin #ifdef MNT_SYMPERM
2114887Schin 	MNT_SYMPERM,	"symperm",
2124887Schin #endif
2134887Schin #ifdef MNT_NODEVMTIME
2144887Schin 	MNT_NODEVMTIME,	"nodevmtime",
2154887Schin #endif
2164887Schin #ifdef MNT_SOFTDEP
2174887Schin 	MNT_SOFTDEP,	"softdep",
2184887Schin #endif
2194887Schin #ifdef MNT_EXRDONLY
2204887Schin 	MNT_EXRDONLY,	"exrdonly",
2214887Schin #endif
2224887Schin #ifdef MNT_EXPORTED
2234887Schin 	MNT_EXPORTED,	"exported",
2244887Schin #endif
2254887Schin #ifdef MNT_DEFEXPORTED
2264887Schin 	MNT_DEFEXPORTED,"defexported",
2274887Schin #endif
2284887Schin #ifdef MNT_EXPORTANON
2294887Schin 	MNT_EXPORTANON,	"exportanon",
2304887Schin #endif
2314887Schin #ifdef MNT_EXKERB
2324887Schin 	MNT_EXKERB,	"exkerb",
2334887Schin #endif
2344887Schin #ifdef MNT_EXNORESPORT
2354887Schin 	MNT_EXNORESPORT,"exnoresport",
2364887Schin #endif
2374887Schin #ifdef MNT_EXPUBLIC
2384887Schin 	MNT_EXPUBLIC,	"expublic",
2394887Schin #endif
2404887Schin #ifdef MNT_LOCAL
2414887Schin 	MNT_LOCAL,	"local",
2424887Schin #endif
2434887Schin #ifdef MNT_QUOTA
2444887Schin 	MNT_QUOTA,	"quota",
2454887Schin #endif
2464887Schin #ifdef MNT_ROOTFS
2474887Schin 	MNT_ROOTFS,	"rootfs",
2484887Schin #endif
2494887Schin 	0,		"unknown",
2504887Schin };
2514887Schin 
2524887Schin void*
2534887Schin mntopen(const char* path, const char* mode)
2544887Schin {
2554887Schin 	register Handle_t*	mp;
2564887Schin 	register int		n;
2574887Schin 
2584887Schin 	FIXARGS(path, mode, 0);
2594887Schin 	if (!(mp = newof(0, Handle_t, 1, 0)))
2604887Schin 		return 0;
2614887Schin 	if ((n = getmntinfo(&mp->next, 0)) <= 0)
2624887Schin 	{
2634887Schin 		free(mp);
2644887Schin 		return 0;
2654887Schin 	}
2664887Schin 	mp->last = mp->next + n;
2674887Schin 	return (void*)mp;
2684887Schin }
2694887Schin 
2704887Schin Mnt_t*
2714887Schin mntread(void* handle)
2724887Schin {
2734887Schin 	register Handle_t*	mp = (Handle_t*)handle;
2744887Schin 	register int		i;
2754887Schin 	register int		n;
2764887Schin 	register unsigned long	flags;
2774887Schin 
2784887Schin 	if (mp->next < mp->last)
2794887Schin 	{
2804887Schin 		flags = mp->next->f_flags;
2814887Schin 		n = 0;
2824887Schin 		for (i = 0; i < elementsof(options); i++)
2834887Schin 			if (flags & options[i].flag)
2844887Schin 				n += sfsprintf(mp->opt + n, sizeof(mp->opt) - n - 1, ",%s", options[i].name);
2854887Schin 		set(&mp->hdr, mp->next->f_mntfromname, mp->next->f_mntonname, TYPE(mp->next), n ? (mp->opt + 1) : (char*)0);
2864887Schin 		mp->next++;
2874887Schin 		return &mp->hdr.mnt;
2884887Schin 	}
2894887Schin 	return 0;
2904887Schin }
2914887Schin 
2924887Schin int
2934887Schin mntclose(void* handle)
2944887Schin {
2954887Schin 	register Handle_t*	mp = (Handle_t*)handle;
2964887Schin 
2974887Schin 	if (!mp)
2984887Schin 		return -1;
2994887Schin 	free(mp);
3004887Schin 	return 0;
3014887Schin }
3024887Schin 
3034887Schin #else
3044887Schin 
3054887Schin #if _lib_mntctl && _sys_vmount
3064887Schin 
3074887Schin /*
3084887Schin  * aix
3094887Schin  */
3104887Schin 
3114887Schin #include <sys/vmount.h>
3124887Schin 
3134887Schin #define SIZE		(16 * 1024)
3144887Schin 
3154887Schin static const char*	type[] =
3164887Schin {
3174887Schin 	"aix", "aix#1", "nfs", "jfs", "aix#4", "cdrom"
3184887Schin };
3194887Schin 
3204887Schin typedef struct
3214887Schin {
3224887Schin 	Header_t	hdr;
3234887Schin 	long		count;
3244887Schin 	struct vmount*	next;
3254887Schin 	char		remote[128];
3264887Schin 	char		type[16];
3274887Schin 	struct vmount	info[1];
3284887Schin } Handle_t;
3294887Schin 
3304887Schin void*
3314887Schin mntopen(const char* path, const char* mode)
3324887Schin {
3334887Schin 	register Handle_t*	mp;
3344887Schin 
3354887Schin 	FIXARGS(path, mode, 0);
3364887Schin 	if (!(mp = newof(0, Handle_t, 1, SIZE)))
3374887Schin 		return 0;
3384887Schin 	if ((mp->count = mntctl(MCTL_QUERY, sizeof(Handle_t) + SIZE, &mp->info)) <= 0)
3394887Schin 	{
3404887Schin 		free(mp);
3414887Schin 		return 0;
3424887Schin 	}
3434887Schin 	mp->next = mp->info;
3444887Schin 	return (void*)mp;
3454887Schin }
3464887Schin 
3474887Schin Mnt_t*
3484887Schin mntread(void* handle)
3494887Schin {
3504887Schin 	register Handle_t*	mp = (Handle_t*)handle;
3514887Schin 	register char*		s;
3524887Schin 	register char*		t;
3534887Schin 	register char*		o;
3544887Schin 
3554887Schin 	if (mp->count > 0)
3564887Schin 	{
3574887Schin 		if (vmt2datasize(mp->next, VMT_HOST) && (s = vmt2dataptr(mp->next, VMT_HOST)) && !streq(s, "-"))
3584887Schin 		{
3594887Schin 			sfsprintf(mp->remote, sizeof(mp->remote) - 1, "%s:%s", s, vmt2dataptr(mp->next, VMT_OBJECT));
3604887Schin 			s = mp->remote;
3614887Schin 		}
3624887Schin 		else
3634887Schin 			s = vmt2dataptr(mp->next, VMT_OBJECT);
3644887Schin 		if (vmt2datasize(mp->next, VMT_ARGS))
3654887Schin 			o = vmt2dataptr(mp->next, VMT_ARGS);
3664887Schin 		else
3674887Schin 			o = NiL;
3684887Schin 		switch (mp->next->vmt_gfstype)
3694887Schin 		{
3704887Schin #ifdef MNT_AIX
3714887Schin 		case MNT_AIX:
3724887Schin 			t = "aix";
3734887Schin 			break;
3744887Schin #endif
3754887Schin #ifdef MNT_NFS
3764887Schin 		case MNT_NFS:
3774887Schin 			t = "nfs";
3784887Schin 			break;
3794887Schin #endif
3804887Schin #ifdef MNT_JFS
3814887Schin 		case MNT_JFS:
3824887Schin 			t = "jfs";
3834887Schin 			break;
3844887Schin #endif
3854887Schin #ifdef MNT_CDROM
3864887Schin 		case MNT_CDROM:
3874887Schin 			t = "cdrom";
3884887Schin 			break;
3894887Schin #endif
3904887Schin #ifdef MNT_SFS
3914887Schin 		case MNT_SFS:
3924887Schin 			t = "sfs";
3934887Schin 			break;
3944887Schin #endif
3954887Schin #ifdef MNT_CACHEFS
3964887Schin 		case MNT_CACHEFS:
3974887Schin 			t = "cachefs";
3984887Schin 			break;
3994887Schin #endif
4004887Schin #ifdef MNT_NFS3
4014887Schin 		case MNT_NFS3:
4024887Schin 			t = "nfs3";
4034887Schin 			break;
4044887Schin #endif
4054887Schin #ifdef MNT_AUTOFS
4064887Schin 		case MNT_AUTOFS:
4074887Schin 			t = "autofs";
4084887Schin 			break;
4094887Schin #endif
4104887Schin 		default:
4114887Schin 			sfsprintf(t = mp->type, sizeof(mp->type), "aix%+d", mp->next->vmt_gfstype);
4124887Schin 			break;
4134887Schin 		}
4144887Schin 		set(&mp->hdr, s, vmt2dataptr(mp->next, VMT_STUB), t, o);
4154887Schin 		if (--mp->count > 0)
4164887Schin 			mp->next = (struct vmount*)((char*)mp->next + mp->next->vmt_length);
4174887Schin 		return &mp->hdr.mnt;
4184887Schin 	}
4194887Schin 	return 0;
4204887Schin }
4214887Schin 
4224887Schin int
4234887Schin mntclose(void* handle)
4244887Schin {
4254887Schin 	register Handle_t*	mp = (Handle_t*)handle;
4264887Schin 
4274887Schin 	if (!mp)
4284887Schin 		return -1;
4294887Schin 	free(mp);
4304887Schin 	return 0;
4314887Schin }
4324887Schin 
4334887Schin #else
4344887Schin 
4354887Schin #if !_lib_setmntent
4364887Schin #undef	_lib_getmntent
4374887Schin #if !_SCO_COFF && !_SCO_ELF && !_UTS
4384887Schin #undef	_hdr_mnttab
4394887Schin #endif
4404887Schin #endif
4414887Schin 
4424887Schin #if _lib_getmntent && ( _hdr_mntent || _sys_mntent && !_sys_mnttab )
4434887Schin 
4444887Schin #if defined(__STDPP__directive) && defined(__STDPP__hide)
4454887Schin __STDPP__directive pragma pp:hide endmntent getmntent
4464887Schin #else
4474887Schin #define endmntent	______endmntent
4484887Schin #define getmntent	______getmntent
4494887Schin #endif
4504887Schin 
4514887Schin #include <stdio.h>
4524887Schin #if _hdr_mntent
4534887Schin #include <mntent.h>
4544887Schin #else
4554887Schin #include <sys/mntent.h>
4564887Schin #endif
4574887Schin 
4584887Schin #if defined(__STDPP__directive) && defined(__STDPP__hide)
4594887Schin __STDPP__directive pragma pp:nohide endmntent getmntent
4604887Schin #else
4614887Schin #undef	endmntent
4624887Schin #undef	getmntent
4634887Schin #endif
4644887Schin 
4654887Schin extern int		endmntent(FILE*);
4664887Schin extern struct mntent*	getmntent(FILE*);
4674887Schin 
4684887Schin #else
4694887Schin 
4704887Schin #undef	_lib_getmntent
4714887Schin 
4724887Schin #if _hdr_mnttab
4734887Schin #include <mnttab.h>
4744887Schin #else
4754887Schin #if _sys_mnttab
4764887Schin #include <sys/mnttab.h>
4774887Schin #endif
4784887Schin #endif
4794887Schin 
4804887Schin #endif
4814887Schin 
4824887Schin #ifndef MOUNTED
4834887Schin #ifdef	MNT_MNTTAB
4844887Schin #define MOUNTED		MNT_MNTTAB
4854887Schin #else
4864887Schin #if _hdr_mnttab || _sys_mnttab
4874887Schin #define MOUNTED		"/etc/mnttab"
4884887Schin #else
4894887Schin #define MOUNTED		"/etc/mtab"
4904887Schin #endif
4914887Schin #endif
4924887Schin #endif
4934887Schin 
4944887Schin #ifdef __Lynx__
4954887Schin #undef	MOUNTED
4964887Schin #define MOUNTED		"/etc/fstab"
4974887Schin #define SEP		':'
4984887Schin #endif
4994887Schin 
5004887Schin #if _lib_getmntent
5014887Schin 
5024887Schin typedef struct
5034887Schin #if _mem_mnt_opts_mntent
5044887Schin #define OPTIONS(p)	((p)->mnt_opts)
5054887Schin #else
5064887Schin #define OPTIONS(p)	NiL
5074887Schin #endif
5084887Schin 
5094887Schin {
5104887Schin 	Header_t	hdr;
5114887Schin 	FILE*		fp;
5124887Schin } Handle_t;
5134887Schin 
5144887Schin void*
5154887Schin mntopen(const char* path, const char* mode)
5164887Schin {
5174887Schin 	register Handle_t*	mp;
5184887Schin 
5194887Schin 	FIXARGS(path, mode, MOUNTED);
5204887Schin 	if (!(mp = newof(0, Handle_t, 1, 0)))
5214887Schin 		return 0;
5224887Schin 	if (!(mp->fp = setmntent(path, mode)))
5234887Schin 	{
5244887Schin 		free(mp);
5254887Schin 		return 0;
5264887Schin 	}
5274887Schin 	return (void*)mp;
5284887Schin }
5294887Schin 
5304887Schin Mnt_t*
5314887Schin mntread(void* handle)
5324887Schin {
5334887Schin 	register Handle_t*	mp = (Handle_t*)handle;
5344887Schin 	register struct mntent*	mnt;
5354887Schin 
5364887Schin 	if (mnt = getmntent(mp->fp))
5374887Schin 	{
5384887Schin 		set(&mp->hdr, mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, OPTIONS(mnt));
5394887Schin 		return &mp->hdr.mnt;
5404887Schin 	}
5414887Schin 	return 0;
5424887Schin }
5434887Schin 
5444887Schin int
5454887Schin mntclose(void* handle)
5464887Schin {
5474887Schin 	register Handle_t*	mp = (Handle_t*)handle;
5484887Schin 
5494887Schin 	if (!mp)
5504887Schin 		return -1;
5514887Schin 	endmntent(mp->fp);
5524887Schin 	free(mp);
5534887Schin 	return 0;
5544887Schin }
5554887Schin 
5564887Schin #else
5574887Schin 
5584887Schin #if _sys_mntent && _lib_w_getmntent
5594887Schin 
5604887Schin #include <sys/mntent.h>
5614887Schin 
5624887Schin #define mntent		w_mntent
5634887Schin 
5644887Schin #define mnt_dir		mnt_mountpoint
5654887Schin #define mnt_type	mnt_fstname
5664887Schin 
5674887Schin #define MNTBUFSIZE	(sizeof(struct w_mnth)+16*sizeof(struct w_mntent))
5684887Schin 
5694887Schin #if _mem_mnt_opts_w_mntent
5704887Schin #define OPTIONS(p)	((p)->mnt_opts)
5714887Schin #else
5724887Schin #define OPTIONS(p)	NiL
5734887Schin #endif
5744887Schin 
5754887Schin #else
5764887Schin 
5774887Schin #undef _lib_w_getmntent
5784887Schin 
5794887Schin #define MNTBUFSIZE	sizeof(struct mntent)
5804887Schin 
5814887Schin #if !_mem_mt_dev_mnttab || !_mem_mt_filsys_mnttab
5824887Schin #undef	_hdr_mnttab
5834887Schin #endif
5844887Schin 
5854887Schin #if _hdr_mnttab
5864887Schin 
5874887Schin #define mntent	mnttab
5884887Schin 
5894887Schin #define mnt_fsname	mt_dev
5904887Schin #define mnt_dir		mt_filsys
5914887Schin #if _mem_mt_fstyp_mnttab
5924887Schin #define mnt_type	mt_fstyp
5934887Schin #endif
5944887Schin 
5954887Schin #if _mem_mnt_opts_mnttab
5964887Schin #define OPTIONS(p)	((p)->mnt_opts)
5974887Schin #else
5984887Schin #define OPTIONS(p)	NiL
5994887Schin #endif
6004887Schin 
6014887Schin #else
6024887Schin 
6034887Schin struct mntent
6044887Schin {
6054887Schin 	char	mnt_fsname[256];
6064887Schin 	char	mnt_dir[256];
6074887Schin 	char	mnt_type[32];
6084887Schin 	char	mnt_opts[64];
6094887Schin };
6104887Schin 
6114887Schin #define OPTIONS(p)	((p)->mnt_opts)
6124887Schin 
6134887Schin #endif
6144887Schin 
6154887Schin #endif
6164887Schin 
6174887Schin typedef struct
6184887Schin {
6194887Schin 	Header_t	hdr;
6204887Schin 	Sfio_t*		fp;
6214887Schin 	struct mntent*	mnt;
6224887Schin #if _lib_w_getmntent
6234887Schin 	int		count;
6244887Schin #endif
6254887Schin 	char		buf[MNTBUFSIZE];
6264887Schin } Handle_t;
6274887Schin 
6284887Schin void*
6294887Schin mntopen(const char* path, const char* mode)
6304887Schin {
6314887Schin 	register Handle_t*	mp;
6324887Schin 
6334887Schin 	FIXARGS(path, mode, MOUNTED);
6344887Schin 	if (!(mp = newof(0, Handle_t, 1, 0)))
6354887Schin 		return 0;
6364887Schin #if _lib_w_getmntent
6374887Schin 	if ((mp->count = w_getmntent(mp->buf, sizeof(mp->buf))) > 0)
6384887Schin 		mp->mnt = (struct mntent*)(((struct w_mnth*)mp->buf) + 1);
6394887Schin 	else
6404887Schin #else
6414887Schin 	mp->mnt = (struct mntent*)mp->buf;
6424887Schin 	if (!(mp->fp = sfopen(NiL, path, mode)))
6434887Schin #endif
6444887Schin 	{
6454887Schin 		free(mp);
6464887Schin 		return 0;
6474887Schin 	}
6484887Schin 	return (void*)mp;
6494887Schin }
6504887Schin 
6514887Schin Mnt_t*
6524887Schin mntread(void* handle)
6534887Schin {
6544887Schin 	register Handle_t*	mp = (Handle_t*)handle;
6554887Schin 
6564887Schin #if _lib_w_getmntent
6574887Schin 
6584887Schin 	if (mp->count-- <= 0)
6594887Schin 	{
6604887Schin 		if ((mp->count = w_getmntent(mp->buf, sizeof(mp->buf))) <= 0)
6614887Schin 			return 0;
6624887Schin 		mp->count--;
6634887Schin 		mp->mnt = (struct mntent*)(((struct w_mnth*)mp->buf) + 1);
6644887Schin 	}
6654887Schin 	set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt));
6664887Schin 	mp->mnt++;
6674887Schin 	return &mp->hdr.mnt;
6684887Schin 
6694887Schin #else
6704887Schin 
6714887Schin #if _hdr_mnttab
6724887Schin 
6734887Schin 	while (sfread(mp->fp, &mp->buf, sizeof(mp->buf)) == sizeof(mp->buf))
6744887Schin 		if (*mp->mnt->mnt_fsname && *mp->mnt->mnt_dir)
6754887Schin 		{
6764887Schin #ifndef mnt_type
6774887Schin 			struct stat	st;
6784887Schin 
6794887Schin 			static char	typ[32];
6804887Schin 
6814887Schin 			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));
6824887Schin #else
6834887Schin 			set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt));
6844887Schin #endif
6854887Schin 			return &mp->hdr.mnt;
6864887Schin 		}
6874887Schin 	return 0;
6884887Schin 
6894887Schin #else
6904887Schin 
6914887Schin 	register int		c;
6924887Schin 	register char*		s;
6934887Schin 	register char*		m;
6944887Schin 	register char*		b;
6954887Schin 	register int		q;
6964887Schin 	register int		x;
6974887Schin 
6984887Schin  again:
6994887Schin 	q = 0;
7004887Schin 	x = 0;
7014887Schin 	b = s = mp->mnt->mnt_fsname;
7024887Schin 	m = s + sizeof(mp->mnt->mnt_fsname) - 1;
7034887Schin 	for (;;) switch (c = sfgetc(mp->fp))
7044887Schin 	{
7054887Schin 	case EOF:
7064887Schin 		return 0;
7074887Schin 	case '"':
7084887Schin 	case '\'':
7094887Schin 		if (q == c)
7104887Schin 			q = 0;
7114887Schin 		else if (!q)
7124887Schin 			q = c;
7134887Schin 		break;
7144887Schin #ifdef SEP
7154887Schin 	case SEP:
7164887Schin #else
7174887Schin 	case ' ':
7184887Schin 	case '\t':
7194887Schin #endif
7204887Schin 		if (s != b && !q) switch (++x)
7214887Schin 		{
7224887Schin 		case 1:
7234887Schin 			*s = 0;
7244887Schin 			b = s = mp->mnt->mnt_dir;
7254887Schin 			m = s + sizeof(mp->mnt->mnt_dir) - 1;
7264887Schin 			break;
7274887Schin 		case 2:
7284887Schin 			*s = 0;
7294887Schin 			b = s = mp->mnt->mnt_type;
7304887Schin 			m = s + sizeof(mp->mnt->mnt_type) - 1;
7314887Schin 			break;
7324887Schin 		case 3:
7334887Schin 			*s = 0;
7344887Schin 			b = s = mp->mnt->mnt_opts;
7354887Schin 			m = s + sizeof(mp->mnt->mnt_opts) - 1;
7364887Schin 			break;
7374887Schin 		case 4:
7384887Schin 			*s = 0;
7394887Schin 			b = s = m = 0;
7404887Schin 			break;
7414887Schin 		}
7424887Schin 		break;
7434887Schin 	case '\n':
7444887Schin 		if (x >= 3)
7454887Schin 		{
7464887Schin 			set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt));
7474887Schin 			return &mp->hdr.mnt;
7484887Schin 		}
7494887Schin 		goto again;
7504887Schin 	default:
7514887Schin 		if (s < m)
7524887Schin 			*s++ = c;
7534887Schin 		break;
7544887Schin 	}
7554887Schin 
7564887Schin #endif
7574887Schin 
7584887Schin #endif
7594887Schin 
7604887Schin }
7614887Schin 
7624887Schin int
7634887Schin mntclose(void* handle)
7644887Schin {
7654887Schin 	register Handle_t*	mp = (Handle_t*)handle;
7664887Schin 
7674887Schin 	if (!mp)
7684887Schin 		return -1;
7694887Schin 	sfclose(mp->fp);
7704887Schin 	free(mp);
7714887Schin 	return 0;
7724887Schin }
7734887Schin 
7744887Schin #endif
7754887Schin 
7764887Schin #endif
7774887Schin 
7784887Schin #endif
7794887Schin 
7804887Schin /*
7814887Schin  * currently no write
7824887Schin  */
7834887Schin 
7844887Schin int
7854887Schin mntwrite(void* handle, const Mnt_t* mnt)
7864887Schin {
7874887Schin 	NoP(handle);
7884887Schin 	NoP(mnt);
7894887Schin 	return -1;
7904887Schin }
7914887Schin 
7924887Schin #endif
793