2 * support/export/export.c
4 * Maintain list of exported file systems.
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
14 #include <sys/types.h>
15 #include <sys/param.h>
16 #include <netinet/in.h>
22 exp_hash_table exportlist[MCL_MAXTYPES] = {{NULL, {{NULL,NULL}, }}, };
23 static int export_hash(char *);
25 static void export_init(nfs_export *exp, nfs_client *clp,
26 struct exportent *nep);
27 static int export_check(nfs_export *, struct hostent *, char *);
29 export_allowed_internal(struct hostent *hp, char *path);
32 export_read(char *fname)
34 struct exportent *eep;
37 setexportent(fname, "r");
38 while ((eep = getexportent(0,1)) != NULL) {
39 exp = export_lookup(eep->e_hostname, eep->e_path, 0);
43 if (exp->m_export.e_flags != eep->e_flags) {
44 xlog(L_ERROR, "incompatible duplicated export entries:");
45 xlog(L_ERROR, "\t%s:%s (0x%x) [IGNORED]", eep->e_hostname,
46 eep->e_path, eep->e_flags);
47 xlog(L_ERROR, "\t%s:%s (0x%x)", exp->m_export.e_hostname,
48 exp->m_export.e_path, exp->m_export.e_flags);
51 xlog(L_ERROR, "duplicated export entries:");
52 xlog(L_ERROR, "\t%s:%s", eep->e_hostname, eep->e_path);
53 xlog(L_ERROR, "\t%s:%s", exp->m_export.e_hostname,
54 exp->m_export.e_path);
64 * Create an in-core export struct from an export entry.
67 export_create(struct exportent *xep, int canonical)
72 if (!(clp = client_lookup(xep->e_hostname, canonical))) {
73 /* bad export entry; complaint already logged */
76 exp = (nfs_export *) xmalloc(sizeof(*exp));
77 export_init(exp, clp, xep);
84 export_init(nfs_export *exp, nfs_client *clp, struct exportent *nep)
86 struct exportent *e = &exp->m_export;
90 e->e_hostname = xstrdup(nep->e_hostname);
102 * Duplicate exports data. The in-core export struct retains the
103 * original hostname from /etc/exports, while the in-core client struct
104 * gets the newly found FQDN.
107 export_dup(nfs_export *exp, struct hostent *hp)
112 new = (nfs_export *) xmalloc(sizeof(*new));
113 memcpy(new, exp, sizeof(*new));
114 dupexportent(&new->m_export, &exp->m_export);
115 if (exp->m_export.e_hostname)
116 new->m_export.e_hostname = xstrdup(exp->m_export.e_hostname);
117 clp = client_dup(exp->m_client, hp);
120 new->m_mayexport = exp->m_mayexport;
130 * Add export entry to hash table
133 export_add(nfs_export *exp)
135 exp_hash_table *p_tbl;
136 exp_hash_entry *p_hen;
139 int type = exp->m_client->m_type;
142 pos = export_hash(exp->m_export.e_path);
143 p_tbl = &(exportlist[type]); /* pointer to hash table */
144 p_hen = &(p_tbl->entries[pos]); /* pointer to hash table entry */
146 if (!(p_hen->p_first)) { /* hash table entry is empty */
147 p_hen->p_first = exp;
150 exp->m_next = p_tbl->p_head;
152 } else { /* hash table entry is NOT empty */
153 p_next = p_hen->p_last->m_next;
154 p_hen->p_last->m_next = exp;
155 exp->m_next = p_next;
161 export_find(struct hostent *hp, char *path)
166 for (i = 0; i < MCL_MAXTYPES; i++) {
167 for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
168 if (!export_check(exp, hp, path))
170 if (exp->m_client->m_type == MCL_FQDN)
172 return export_dup(exp, hp);
180 export_allowed_internal (struct hostent *hp, char *path)
185 for (i = 0; i < MCL_MAXTYPES; i++) {
186 for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
187 if (!exp->m_mayexport ||
188 !export_check(exp, hp, path))
198 export_allowed(struct hostent *hp, char *path)
201 char epath[MAXPATHLEN+1];
204 if (path [0] != '/') return NULL;
206 strncpy(epath, path, sizeof (epath) - 1);
207 epath[sizeof (epath) - 1] = '\0';
209 /* Try the longest matching exported pathname. */
211 exp = export_allowed_internal (hp, epath);
214 /* We have to treat the root, "/", specially. */
215 if (p == &epath[1]) break;
216 p = strrchr(epath, '/');
225 * Search hash table for export entry.
228 export_lookup(char *hname, char *path, int canonical)
232 exp_hash_entry *p_hen;
236 clp = client_lookup(hname, canonical);
240 pos = export_hash(path);
241 p_hen = &(exportlist[clp->m_type].entries[pos]);
242 for(exp = p_hen->p_first; exp && (exp != p_hen->p_last->m_next);
244 if (exp->m_client == clp && !strcmp(exp->m_export.e_path, path)) {
252 export_check(nfs_export *exp, struct hostent *hp, char *path)
254 if (strcmp(path, exp->m_export.e_path))
257 return client_check(exp->m_client, hp);
263 nfs_export *exp, *nxt;
266 for (i = 0; i < MCL_MAXTYPES; i++) {
267 for (exp = exportlist[i].p_head; exp; exp = nxt) {
269 client_release(exp->m_client);
270 if (exp->m_export.e_squids)
271 xfree(exp->m_export.e_squids);
272 if (exp->m_export.e_sqgids)
273 xfree(exp->m_export.e_sqgids);
274 if (exp->m_export.e_mountpoint)
275 free(exp->m_export.e_mountpoint);
276 if (exp->m_export.e_fslocdata)
277 xfree(exp->m_export.e_fslocdata);
278 xfree(exp->m_export.e_hostname);
281 for(j = 0; j < HASH_TABLE_SIZE; j++) {
282 exportlist[i].entries[j].p_first = NULL;
283 exportlist[i].entries[j].p_last = NULL;
285 exportlist[i].p_head = NULL;
291 * Compute and returns integer from string.
292 * Note: Its understood the smae integers can be same for
293 * different strings, but it should not matter.
301 while ( str[i] != '\0') {
312 export_hash(char *str)
314 int num = strtoint(str);
316 return num % HASH_TABLE_SIZE;