xref: /original-bsd/usr.sbin/amd/amd/info_union.c (revision 4092c5cc)
1646eb4dbSpendry /*
2646eb4dbSpendry  * Copyright (c) 1990 Jan-Simon Pendry
3646eb4dbSpendry  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
4*4092c5ccSbostic  * Copyright (c) 1990, 1993
5*4092c5ccSbostic  *	The Regents of the University of California.  All rights reserved.
6646eb4dbSpendry  *
7646eb4dbSpendry  * This code is derived from software contributed to Berkeley by
8646eb4dbSpendry  * Jan-Simon Pendry at Imperial College, London.
9646eb4dbSpendry  *
108a89c22cSpendry  * %sccs.include.redist.c%
11646eb4dbSpendry  *
12*4092c5ccSbostic  *	@(#)info_union.c	8.1 (Berkeley) 06/06/93
13c626267eSpendry  *
14cc0207dcSpendry  * $Id: info_union.c,v 5.2.2.1 1992/02/09 15:08:34 jsp beta $
15c626267eSpendry  *
16646eb4dbSpendry  */
17646eb4dbSpendry 
18646eb4dbSpendry /*
19646eb4dbSpendry  * Get info from the system namespace
20646eb4dbSpendry  *
21646eb4dbSpendry  * NOTE: Cannot handle reads back through the automounter.
22646eb4dbSpendry  * THIS WILL CAUSE A DEADLOCK!
23646eb4dbSpendry  */
24646eb4dbSpendry 
25646eb4dbSpendry #include "am.h"
26646eb4dbSpendry 
27646eb4dbSpendry #ifdef HAS_UNION_MAPS
28646eb4dbSpendry 
29646eb4dbSpendry #ifdef _POSIX_SOURCE
30646eb4dbSpendry #include <dirent.h>
31646eb4dbSpendry #define	DIRENT struct dirent
32646eb4dbSpendry #else
33646eb4dbSpendry #include <sys/dir.h>
34646eb4dbSpendry #define	DIRENT struct direct
35646eb4dbSpendry #endif
36646eb4dbSpendry 
37646eb4dbSpendry #define	UNION_PREFIX	"union:"
38646eb4dbSpendry #define	UNION_PREFLEN	6
39646eb4dbSpendry 
40646eb4dbSpendry /*
41646eb4dbSpendry  * No way to probe - check the map name begins with "union:"
42646eb4dbSpendry  */
43646eb4dbSpendry int union_init P((char *map, time_t *tp));
union_init(map,tp)44646eb4dbSpendry int union_init(map, tp)
45646eb4dbSpendry char *map;
46646eb4dbSpendry time_t *tp;
47646eb4dbSpendry {
48646eb4dbSpendry 	*tp = 0;
49646eb4dbSpendry 	return strncmp(map, UNION_PREFIX, UNION_PREFLEN) == 0 ? 0 : ENOENT;
50646eb4dbSpendry }
51646eb4dbSpendry 
52646eb4dbSpendry int union_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp));
union_search(m,map,key,pval,tp)53646eb4dbSpendry int union_search(m, map, key, pval, tp)
54646eb4dbSpendry mnt_map *m;
55646eb4dbSpendry char *map;
56646eb4dbSpendry char *key;
57646eb4dbSpendry char **pval;
58646eb4dbSpendry time_t *tp;
59646eb4dbSpendry {
60646eb4dbSpendry 	char *mapd = strdup(map + UNION_PREFLEN);
61646eb4dbSpendry 	char **v = strsplit(mapd, ':', '\"');
62646eb4dbSpendry 	char **p;
63646eb4dbSpendry 	for (p = v; p[1]; p++)
64646eb4dbSpendry 		;
65646eb4dbSpendry 	*pval = xmalloc(strlen(*p) + 5);
66646eb4dbSpendry 	sprintf(*pval, "fs:=%s", *p);
67646eb4dbSpendry 	free(mapd);
68646eb4dbSpendry 	free(v);
69646eb4dbSpendry 	return 0;
70646eb4dbSpendry }
71646eb4dbSpendry 
72646eb4dbSpendry int union_reload P((mnt_map *m, char *map, void (*fn)()));
union_reload(m,map,fn)73646eb4dbSpendry int union_reload(m, map, fn)
74646eb4dbSpendry mnt_map *m;
75646eb4dbSpendry char *map;
76646eb4dbSpendry void (*fn)();
77646eb4dbSpendry {
78646eb4dbSpendry 	char *mapd = strdup(map + UNION_PREFLEN);
79646eb4dbSpendry 	char **v = strsplit(mapd, ':', '\"');
80646eb4dbSpendry 	char **dir;
81646eb4dbSpendry 
82646eb4dbSpendry 	/*
83646eb4dbSpendry 	 * Add fake /defaults entry
84646eb4dbSpendry 	 */
85646eb4dbSpendry 	(*fn)(m, strdup("/defaults"), strdup("type:=link;opts:=nounmount;sublink:=${key}"));
86646eb4dbSpendry 
87646eb4dbSpendry 	for (dir = v; *dir; dir++) {
88646eb4dbSpendry 		int dlen;
89646eb4dbSpendry 		DIRENT *dp;
90646eb4dbSpendry 		DIR *dirp = opendir(*dir);
91646eb4dbSpendry 		if (!dirp) {
92646eb4dbSpendry 			plog(XLOG_USER, "Cannot read directory %s: %m", *dir);
93646eb4dbSpendry 			continue;
94646eb4dbSpendry 		}
95646eb4dbSpendry 		dlen = strlen(*dir);
96646eb4dbSpendry #ifdef DEBUG
97646eb4dbSpendry 		dlog("Reading directory %s...", *dir);
98646eb4dbSpendry #endif
99646eb4dbSpendry 		while (dp = readdir(dirp)) {
100646eb4dbSpendry 			char *val;
101646eb4dbSpendry 			if (dp->d_name[0] == '.' &&
102646eb4dbSpendry 					(dp->d_name[1] == '\0' ||
103646eb4dbSpendry 					(dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
104646eb4dbSpendry 				continue;
105646eb4dbSpendry 
106646eb4dbSpendry #ifdef DEBUG
107646eb4dbSpendry 			dlog("... gives %s", dp->d_name);
108646eb4dbSpendry #endif
109646eb4dbSpendry 			val = xmalloc(dlen + 5);
110646eb4dbSpendry 			sprintf(val, "fs:=%s", *dir);
111646eb4dbSpendry 			(*fn)(m, strdup(dp->d_name), val);
112646eb4dbSpendry 		}
113646eb4dbSpendry 		closedir(dirp);
114646eb4dbSpendry 	}
115646eb4dbSpendry 	/*
116646eb4dbSpendry 	 * Add wildcard entry
117646eb4dbSpendry 	 */
118646eb4dbSpendry 	{ char *val = xmalloc(strlen(dir[-1]) + 5);
119646eb4dbSpendry 	  sprintf(val, "fs:=%s", dir[-1]);
120646eb4dbSpendry 	  (*fn)(m, strdup("*"), val);
121646eb4dbSpendry 	}
122646eb4dbSpendry 	free(mapd);
123646eb4dbSpendry 	free(v);
124646eb4dbSpendry 	return 0;
125646eb4dbSpendry }
126646eb4dbSpendry 
127646eb4dbSpendry #endif /* HAS_UNION_MAPS */
128