pawd.c revision 42629
1/* 2 * Copyright (c) 1997-1998 Erez Zadok 3 * Copyright (c) 1990 Jan-Simon Pendry 4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Jan-Simon Pendry at Imperial College, London. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgment: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * %W% (Berkeley) %G% 40 * 41 * $Id: pawd.c,v 1.2 1998/12/27 06:24:50 ezk Exp $ 42 * 43 */ 44 45/* 46 * pawd is similar to pwd, except that it returns more "natural" versions of 47 * pathnames for directories automounted with the amd automounter. If any 48 * arguments are given, the "more natural" form of the given pathnames are 49 * printed. 50 * 51 * Paul Anderson (paul@ed.lfcs) 52 * 53 */ 54 55#ifdef HAVE_CONFIG_H 56# include <config.h> 57#endif /* HAVE_CONFIG_H */ 58#include <am_defs.h> 59#include <amq.h> 60 61/* dummy variables */ 62#if 0 63char *progname; 64char hostname[MAXHOSTNAMELEN]; 65pid_t mypid; 66serv_state amd_state; 67int foreground, orig_umask; 68int debug_flags; 69#endif 70 71/* statics */ 72static char *localhost="localhost"; 73static char newdir[MAXPATHLEN]; 74static char transform[MAXPATHLEN]; 75 76static int 77find_mt(amq_mount_tree *mt, char *dir) 78{ 79 while (mt) { 80 if (STREQ(mt->mt_type, "link") || STREQ(mt->mt_type, "nfs")) { 81 int len = strlen(mt->mt_mountpoint); 82 if (NSTREQ(mt->mt_mountpoint, dir, len) && 83 ((dir[len] == '\0') || (dir[len] == '/'))) { 84 char tmp_buf[MAXPATHLEN]; 85 strcpy(tmp_buf, mt->mt_directory); 86 strcat(tmp_buf, &dir[len]); 87 strcpy(newdir, tmp_buf); 88 return 1; 89 } 90 } 91 if (find_mt(mt->mt_next,dir)) 92 return 1; 93 mt = mt->mt_child; 94 } 95 return 0; 96} 97 98 99static int 100find_mlp(amq_mount_tree_list *mlp, char *dir) 101{ 102 int i; 103 104 for (i = 0; i < mlp->amq_mount_tree_list_len; i++) { 105 if (find_mt(mlp->amq_mount_tree_list_val[i], dir)) 106 return 1; 107 } 108 return 0; 109} 110 111 112#ifdef HAVE_CNODEID 113static char * 114cluster_server(void) 115{ 116# ifdef HAVE_EXTERN_GETCCENT 117 struct cct_entry *cp; 118# endif /* HAVE_EXTERN_GETCCENT */ 119 120 if (cnodeid() == 0) 121 return localhost; 122 123# ifdef HAVE_EXTERN_GETCCENT 124 while ((cp = getccent())) 125 if (cp->cnode_type == 'r') 126 return cp->cnode_name; 127# endif /* HAVE_EXTERN_GETCCENT */ 128 129 return localhost; 130} 131#endif /* HAVE_CNODEID */ 132 133 134/* DISK_HOME_HACK added by gdmr */ 135#ifdef DISK_HOME_HACK 136static char * 137hack_name(char *dir) 138{ 139 char partition[MAXPATHLEN]; 140 char username[MAXPATHLEN]; 141 char hesiod_lookup[MAXPATHLEN]; 142 char *to, *ch, *hes_name, *dot; 143 char **hes; 144 145#ifdef DEBUG 146 fprintf(stderr, "hack_name(%s)\n", dir); 147#endif /* DEBUG */ 148 149 if (dir[0] == '/' && dir[1] == 'a' && dir[2] == '/') { 150 /* Could be /a/server/disk/home/partition/user... */ 151 ch = dir + 3; 152 while (*ch && *ch != '/') ch++; /* Skip server */ 153 if (!NSTREQ(ch, "/disk/home/", 11)) 154 return NULL; /* Nope */ 155 /* Looking promising, next should be the partition name */ 156 ch += 11; 157 to = partition; 158 while (*ch && *ch != '/') *to++ = *ch++; 159 to = '\0'; 160 if (!(*ch)) 161 return NULL; /* Off the end */ 162 /* Now the username */ 163 ch++; 164 to = username; 165 while (*ch && *ch != '/') *to++ = *ch++; 166 to = '\0'; 167#ifdef DEBUG 168 fprintf(stderr, "partition %s, username %s\n", partition, username); 169#endif /* DEBUG */ 170 171 sprintf(hesiod_lookup, "%s.homes-remote", username); 172 hes = hes_resolve(hesiod_lookup, "amd"); 173 if (!hes) 174 return NULL; 175#ifdef DEBUG 176 fprintf(stderr, "hesiod -> <%s>\n", *hes); 177#endif /* DEBUG */ 178 hes_name = strstr(*hes, "/homes/remote/"); 179 if (!hes_name) return NULL; 180 hes_name += 14; 181#ifdef DEBUG 182 fprintf(stderr, "hesiod -> <%s>\n", hes_name); 183#endif /* DEBUG */ 184 dot = hes_name; 185 while (*dot && *dot != '.') dot++; 186 *dot = '\0'; 187#ifdef DEBUG 188 fprintf(stderr, "hesiod -> <%s>\n", hes_name); 189#endif /* DEBUG */ 190 191 if (strcmp(partition, hes_name)) return NULL; 192#ifdef DEBUG 193 fprintf(stderr, "A match, munging....\n"); 194#endif /* DEBUG */ 195 strcpy(transform, "/home/"); 196 strcat(transform, username); 197 if (*ch) strcat(transform, ch); 198#ifdef DEBUG 199 fprintf(stderr, "Munged to <%s>\n", transform); 200#endif /* DEBUG */ 201 return transform; 202 } 203 return NULL; 204} 205#endif /* DISK_HOME_HACK */ 206 207 208/* 209 * The routine transform_dir(path) transforms pathnames of directories 210 * mounted with the amd automounter to produce a more "natural" version. 211 * The automount table is obtained from the local amd via the rpc interface 212 * and reverse lookups are repeatedly performed on the directory name 213 * substituting the name of the automount link for the value of the link 214 * whenever it occurs as a prefix of the directory name. 215 */ 216static char * 217transform_dir(char *dir) 218{ 219#ifdef DISK_HOME_HACK 220 char *ch; 221#endif /* DISK_HOME_HACK */ 222 char *server; 223 struct sockaddr_in server_addr; 224 int s = RPC_ANYSOCK; 225 CLIENT *clnt; 226 struct hostent *hp; 227 amq_mount_tree_list *mlp; 228 struct timeval tmo = {10, 0}; 229 230#ifdef DISK_HOME_HACK 231 if (ch = hack_name(dir)) 232 return ch; 233#endif /* DISK_HOME_HACK */ 234 235#ifdef HAVE_CNODEID 236 server = cluster_server(); 237#else /* not HAVE_CNODEID */ 238 server = localhost; 239#endif /* not HAVE_CNODEID */ 240 241 if ((hp = gethostbyname(server)) == 0) 242 return dir; 243 memset(&server_addr, 0, sizeof(server_addr)); 244 server_addr.sin_family = AF_INET; 245 server_addr.sin_addr = *(struct in_addr *) hp->h_addr; 246 247 clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, tmo, &s); 248 if (clnt == 0) 249 return dir; 250 251 strcpy(transform,dir); 252 while ( (mlp = amqproc_export_1((voidp)0, clnt)) && 253 find_mlp(mlp,transform) ) { 254 strcpy(transform,newdir); 255 } 256 return transform; 257} 258 259 260/* getawd() is a substitute for getwd() which transforms the path */ 261static char * 262getawd(char *path) 263{ 264#ifdef HAVE_GETCWD 265 char *wd = getcwd(path, MAXPATHLEN+1); 266#else /* not HAVE_GETCWD */ 267 char *wd = getwd(path); 268#endif /* not HAVE_GETCWD */ 269 270 if (wd == NULL) { 271 return NULL; 272 } 273 strcpy(path, transform_dir(wd)); 274 return path; 275} 276 277 278int 279main(int argc, char *argv[]) 280{ 281 char tmp_buf[MAXPATHLEN], *wd; 282 283 if (argc == 1) { 284 wd = getawd(tmp_buf); 285 if (wd == NULL) { 286 fprintf(stderr, "pawd: %s\n", tmp_buf); 287 exit(1); 288 } else { 289 fprintf(stdout, "%s\n", wd); 290 } 291 } else { 292 while (--argc) { 293 wd = transform_dir(*++argv); 294 fprintf(stdout, "%s\n", wd); 295 } 296 } 297 exit(0); 298} 299