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