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 * @(#)sfs_ops.c 8.1 (Berkeley) 06/06/93 13 * 14 * $Id: sfs_ops.c,v 5.2.2.1 1992/02/09 15:09:04 jsp beta $ 15 * 16 */ 17 18 #include "am.h" 19 20 #if defined(HAS_SFS) || defined(HAS_SFSX) 21 #define NEED_SFS_MATCH 22 #define NEED_SFS_UMOUNT 23 #endif 24 25 /* 26 * Symbol-link file system 27 */ 28 29 #ifdef HAS_SFSX 30 #include <sys/stat.h> 31 #endif 32 33 #ifdef NEED_SFS_MATCH 34 /* 35 * SFS needs a link. 36 */ 37 static char *sfs_match(fo) 38 am_opts *fo; 39 { 40 if (!fo->opt_fs) { 41 plog(XLOG_USER, "link: no fs specified"); 42 return 0; 43 } 44 45 /* 46 * Bug report (14/12/89) from Jay Plett <jay@princeton.edu> 47 * If an automount point has the same name as an existing 48 * link type mount Amd hits a race condition and either hangs 49 * or causes a symlink loop. 50 * 51 * If fs begins with a '/' change the opt_fs & opt_sublink 52 * fields so that the fs option doesn't end up pointing at 53 * an existing symlink. 54 * 55 * If sublink is nil then set sublink to fs 56 * else set sublink to fs / sublink 57 * 58 * Finally set fs to ".". 59 */ 60 if (*fo->opt_fs == '/') { 61 char *fullpath; 62 char *link = fo->opt_sublink; 63 if (link) { 64 if (*link == '/') 65 fullpath = strdup(link); 66 else 67 fullpath = str3cat((char *)0, fo->opt_fs, "/", link); 68 } else { 69 fullpath = strdup(fo->opt_fs); 70 } 71 72 if (fo->opt_sublink) 73 free(fo->opt_sublink); 74 fo->opt_sublink = fullpath; 75 fo->opt_fs = str3cat(fo->opt_fs, ".", fullpath, ""); 76 } 77 78 return strdup(fo->opt_fs); 79 } 80 #endif 81 82 #ifdef HAS_SFSX 83 /*ARGUSED*/ 84 static int sfsx_mount P((am_node *mp)); 85 static int sfsx_mount(mp) 86 am_node *mp; 87 { 88 /* 89 * Check for existence of target. 90 */ 91 struct stat stb; 92 char *ln; 93 94 if (mp->am_link) 95 ln = mp->am_link; 96 else /* should never occur */ 97 ln = mp->am_mnt->mf_mount; 98 99 /* 100 * Use lstat, not stat, since we don't 101 * want to know if the ultimate target of 102 * a symlink chain exists, just the first. 103 */ 104 if (lstat(ln, &stb) < 0) 105 return errno; 106 107 return 0; 108 } 109 #endif 110 111 #ifdef HAS_SFS 112 /*ARGUSED*/ 113 static int sfs_fmount(mf) 114 mntfs *mf; 115 { 116 /* 117 * Wow - this is hard to implement! 118 */ 119 120 return 0; 121 } 122 #endif 123 124 #ifdef NEED_SFS_UMOUNT 125 /*ARGUSED*/ 126 static int sfs_fumount(mf) 127 mntfs *mf; 128 { 129 return 0; 130 } 131 #endif 132 133 /* 134 * Ops structures 135 */ 136 #ifdef HAS_SFS 137 am_ops sfs_ops = { 138 "link", 139 sfs_match, 140 0, /* sfs_init */ 141 auto_fmount, 142 sfs_fmount, 143 auto_fumount, 144 sfs_fumount, 145 efs_lookuppn, 146 efs_readdir, 147 0, /* sfs_readlink */ 148 0, /* sfs_mounted */ 149 0, /* sfs_umounted */ 150 find_afs_srvr, 151 #ifdef FLUSH_KERNEL_NAME_CACHE 152 FS_UBACKGROUND 153 #else /* FLUSH_KERNEL_NAME_CACHE */ 154 0 155 #endif /* FLUSH_KERNEL_NAME_CACHE */ 156 }; 157 158 #endif /* HAS_SFS */ 159 160 #ifdef HAS_SFSX 161 struct am_ops sfsx_ops = { 162 "linkx", 163 sfs_match, 164 0, /* sfsx_init */ 165 sfsx_mount, 166 0, 167 auto_fumount, 168 sfs_fumount, 169 efs_lookuppn, 170 efs_readdir, 171 0, /* sfsx_readlink */ 172 0, /* sfsx_mounted */ 173 0, /* sfsx_umounted */ 174 find_afs_srvr, 175 #ifdef FLUSH_KERNEL_NAME_CACHE 176 FS_BACKGROUND 177 #else /* FLUSH_KERNEL_NAME_CACHE */ 178 FS_MBACKGROUND 179 #endif /* FLUSH_KERNEL_NAME_CACHE */ 180 }; 181 182 #endif /* HAS_SFSX */ 183