1 /* 2 * Copyright (c) 1990 Jan-Simon Pendry 3 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 4 * Copyright (c) 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Jan-Simon Pendry at Imperial College, London. 9 * 10 * %sccs.include.redist.c% 11 * 12 * @(#)info_union.c 8.1 (Berkeley) 06/06/93 13 * 14 * $Id: info_union.c,v 5.2.2.1 1992/02/09 15:08:34 jsp beta $ 15 * 16 */ 17 18 /* 19 * Get info from the system namespace 20 * 21 * NOTE: Cannot handle reads back through the automounter. 22 * THIS WILL CAUSE A DEADLOCK! 23 */ 24 25 #include "am.h" 26 27 #ifdef HAS_UNION_MAPS 28 29 #ifdef _POSIX_SOURCE 30 #include <dirent.h> 31 #define DIRENT struct dirent 32 #else 33 #include <sys/dir.h> 34 #define DIRENT struct direct 35 #endif 36 37 #define UNION_PREFIX "union:" 38 #define UNION_PREFLEN 6 39 40 /* 41 * No way to probe - check the map name begins with "union:" 42 */ 43 int union_init P((char *map, time_t *tp)); 44 int union_init(map, tp) 45 char *map; 46 time_t *tp; 47 { 48 *tp = 0; 49 return strncmp(map, UNION_PREFIX, UNION_PREFLEN) == 0 ? 0 : ENOENT; 50 } 51 52 int union_search P((mnt_map *m, char *map, char *key, char **pval, time_t *tp)); 53 int union_search(m, map, key, pval, tp) 54 mnt_map *m; 55 char *map; 56 char *key; 57 char **pval; 58 time_t *tp; 59 { 60 char *mapd = strdup(map + UNION_PREFLEN); 61 char **v = strsplit(mapd, ':', '\"'); 62 char **p; 63 for (p = v; p[1]; p++) 64 ; 65 *pval = xmalloc(strlen(*p) + 5); 66 sprintf(*pval, "fs:=%s", *p); 67 free(mapd); 68 free(v); 69 return 0; 70 } 71 72 int union_reload P((mnt_map *m, char *map, void (*fn)())); 73 int union_reload(m, map, fn) 74 mnt_map *m; 75 char *map; 76 void (*fn)(); 77 { 78 char *mapd = strdup(map + UNION_PREFLEN); 79 char **v = strsplit(mapd, ':', '\"'); 80 char **dir; 81 82 /* 83 * Add fake /defaults entry 84 */ 85 (*fn)(m, strdup("/defaults"), strdup("type:=link;opts:=nounmount;sublink:=${key}")); 86 87 for (dir = v; *dir; dir++) { 88 int dlen; 89 DIRENT *dp; 90 DIR *dirp = opendir(*dir); 91 if (!dirp) { 92 plog(XLOG_USER, "Cannot read directory %s: %m", *dir); 93 continue; 94 } 95 dlen = strlen(*dir); 96 #ifdef DEBUG 97 dlog("Reading directory %s...", *dir); 98 #endif 99 while (dp = readdir(dirp)) { 100 char *val; 101 if (dp->d_name[0] == '.' && 102 (dp->d_name[1] == '\0' || 103 (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) 104 continue; 105 106 #ifdef DEBUG 107 dlog("... gives %s", dp->d_name); 108 #endif 109 val = xmalloc(dlen + 5); 110 sprintf(val, "fs:=%s", *dir); 111 (*fn)(m, strdup(dp->d_name), val); 112 } 113 closedir(dirp); 114 } 115 /* 116 * Add wildcard entry 117 */ 118 { char *val = xmalloc(strlen(dir[-1]) + 5); 119 sprintf(val, "fs:=%s", dir[-1]); 120 (*fn)(m, strdup("*"), val); 121 } 122 free(mapd); 123 free(v); 124 return 0; 125 } 126 127 #endif /* HAS_UNION_MAPS */ 128