138494Sobrien/* 2174294Sobrien * Copyright (c) 1997-2006 Erez Zadok 338494Sobrien * Copyright (c) 1990 Jan-Simon Pendry 438494Sobrien * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 538494Sobrien * Copyright (c) 1990 The Regents of the University of California. 638494Sobrien * All rights reserved. 738494Sobrien * 838494Sobrien * This code is derived from software contributed to Berkeley by 938494Sobrien * Jan-Simon Pendry at Imperial College, London. 1038494Sobrien * 1138494Sobrien * Redistribution and use in source and binary forms, with or without 1238494Sobrien * modification, are permitted provided that the following conditions 1338494Sobrien * are met: 1438494Sobrien * 1. Redistributions of source code must retain the above copyright 1538494Sobrien * notice, this list of conditions and the following disclaimer. 1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1738494Sobrien * notice, this list of conditions and the following disclaimer in the 1838494Sobrien * documentation and/or other materials provided with the distribution. 1938494Sobrien * 3. All advertising materials mentioning features or use of this software 2042629Sobrien * must display the following acknowledgment: 2138494Sobrien * This product includes software developed by the University of 2238494Sobrien * California, Berkeley and its contributors. 2338494Sobrien * 4. Neither the name of the University nor the names of its contributors 2438494Sobrien * may be used to endorse or promote products derived from this software 2538494Sobrien * without specific prior written permission. 2638494Sobrien * 2738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2938494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3038494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3738494Sobrien * SUCH DAMAGE. 3838494Sobrien * 3938494Sobrien * 40174294Sobrien * File: am-utils/amq/pawd.c 4138494Sobrien * 4238494Sobrien */ 4338494Sobrien 4438494Sobrien/* 4538494Sobrien * pawd is similar to pwd, except that it returns more "natural" versions of 4638494Sobrien * pathnames for directories automounted with the amd automounter. If any 4738494Sobrien * arguments are given, the "more natural" form of the given pathnames are 4838494Sobrien * printed. 4938494Sobrien * 5038494Sobrien * Paul Anderson (paul@ed.lfcs) 5138494Sobrien * 5238494Sobrien */ 5338494Sobrien 5438494Sobrien#ifdef HAVE_CONFIG_H 5538494Sobrien# include <config.h> 5638494Sobrien#endif /* HAVE_CONFIG_H */ 5738494Sobrien#include <am_defs.h> 5838494Sobrien#include <amq.h> 5938494Sobrien 60174294Sobrien 6138494Sobrien/* statics */ 62174294Sobrienstatic char *localhost = "localhost"; 6338494Sobrienstatic char transform[MAXPATHLEN]; 6438494Sobrien 6538494Sobrien 6638494Sobrien#ifdef HAVE_CNODEID 6738494Sobrienstatic char * 6838494Sobriencluster_server(void) 6938494Sobrien{ 7038494Sobrien# ifdef HAVE_EXTERN_GETCCENT 7138494Sobrien struct cct_entry *cp; 7238494Sobrien# endif /* HAVE_EXTERN_GETCCENT */ 7338494Sobrien 7438494Sobrien if (cnodeid() == 0) 7538494Sobrien return localhost; 7638494Sobrien 7738494Sobrien# ifdef HAVE_EXTERN_GETCCENT 7838494Sobrien while ((cp = getccent())) 7938494Sobrien if (cp->cnode_type == 'r') 8038494Sobrien return cp->cnode_name; 8138494Sobrien# endif /* HAVE_EXTERN_GETCCENT */ 8238494Sobrien 8338494Sobrien return localhost; 8438494Sobrien} 8538494Sobrien#endif /* HAVE_CNODEID */ 8638494Sobrien 8738494Sobrien 8838494Sobrien/* DISK_HOME_HACK added by gdmr */ 8938494Sobrien#ifdef DISK_HOME_HACK 9038494Sobrienstatic char * 9138494Sobrienhack_name(char *dir) 9238494Sobrien{ 9338494Sobrien char partition[MAXPATHLEN]; 9438494Sobrien char username[MAXPATHLEN]; 9538494Sobrien char hesiod_lookup[MAXPATHLEN]; 9638494Sobrien char *to, *ch, *hes_name, *dot; 9738494Sobrien char **hes; 9838494Sobrien 9938494Sobrien#ifdef DEBUG 10038494Sobrien fprintf(stderr, "hack_name(%s)\n", dir); 10138494Sobrien#endif /* DEBUG */ 10238494Sobrien 10338494Sobrien if (dir[0] == '/' && dir[1] == 'a' && dir[2] == '/') { 10438494Sobrien /* Could be /a/server/disk/home/partition/user... */ 10538494Sobrien ch = dir + 3; 10638494Sobrien while (*ch && *ch != '/') ch++; /* Skip server */ 10738494Sobrien if (!NSTREQ(ch, "/disk/home/", 11)) 10838494Sobrien return NULL; /* Nope */ 10938494Sobrien /* Looking promising, next should be the partition name */ 11038494Sobrien ch += 11; 11138494Sobrien to = partition; 11238494Sobrien while (*ch && *ch != '/') *to++ = *ch++; 11338494Sobrien to = '\0'; 11438494Sobrien if (!(*ch)) 11538494Sobrien return NULL; /* Off the end */ 11638494Sobrien /* Now the username */ 11738494Sobrien ch++; 11838494Sobrien to = username; 11938494Sobrien while (*ch && *ch != '/') *to++ = *ch++; 12038494Sobrien to = '\0'; 12138494Sobrien#ifdef DEBUG 12238494Sobrien fprintf(stderr, "partition %s, username %s\n", partition, username); 12338494Sobrien#endif /* DEBUG */ 12438494Sobrien 125174294Sobrien xsnprintf(hesiod_lookup, sizeof(hesiod_lookup), 126174294Sobrien "%s.homes-remote", username); 12738494Sobrien hes = hes_resolve(hesiod_lookup, "amd"); 12838494Sobrien if (!hes) 12938494Sobrien return NULL; 13038494Sobrien#ifdef DEBUG 13138494Sobrien fprintf(stderr, "hesiod -> <%s>\n", *hes); 13238494Sobrien#endif /* DEBUG */ 13338494Sobrien hes_name = strstr(*hes, "/homes/remote/"); 13438494Sobrien if (!hes_name) return NULL; 13538494Sobrien hes_name += 14; 13638494Sobrien#ifdef DEBUG 13738494Sobrien fprintf(stderr, "hesiod -> <%s>\n", hes_name); 13838494Sobrien#endif /* DEBUG */ 13938494Sobrien dot = hes_name; 14038494Sobrien while (*dot && *dot != '.') dot++; 14138494Sobrien *dot = '\0'; 14238494Sobrien#ifdef DEBUG 14338494Sobrien fprintf(stderr, "hesiod -> <%s>\n", hes_name); 14438494Sobrien#endif /* DEBUG */ 14538494Sobrien 14638494Sobrien if (strcmp(partition, hes_name)) return NULL; 14738494Sobrien#ifdef DEBUG 14838494Sobrien fprintf(stderr, "A match, munging....\n"); 14938494Sobrien#endif /* DEBUG */ 150174294Sobrien xstrlcpy(transform, "/home/", sizeof(transform)); 151174294Sobrien xstrlcat(transform, username, sizeof(transform)); 152174294Sobrien if (*ch) 153174294Sobrien xstrlcat(transform, ch, sizeof(transform)); 15438494Sobrien#ifdef DEBUG 15538494Sobrien fprintf(stderr, "Munged to <%s>\n", transform); 15638494Sobrien#endif /* DEBUG */ 15738494Sobrien return transform; 15838494Sobrien } 15938494Sobrien return NULL; 16038494Sobrien} 16138494Sobrien#endif /* DISK_HOME_HACK */ 16238494Sobrien 16338494Sobrien 16438494Sobrien/* 16538494Sobrien * The routine transform_dir(path) transforms pathnames of directories 16638494Sobrien * mounted with the amd automounter to produce a more "natural" version. 16738494Sobrien * The automount table is obtained from the local amd via the rpc interface 16838494Sobrien * and reverse lookups are repeatedly performed on the directory name 16938494Sobrien * substituting the name of the automount link for the value of the link 17038494Sobrien * whenever it occurs as a prefix of the directory name. 17138494Sobrien */ 17238494Sobrienstatic char * 17338494Sobrientransform_dir(char *dir) 17438494Sobrien{ 17538494Sobrien#ifdef DISK_HOME_HACK 17638494Sobrien char *ch; 17738494Sobrien#endif /* DISK_HOME_HACK */ 17838494Sobrien char *server; 17938494Sobrien struct sockaddr_in server_addr; 18038494Sobrien int s = RPC_ANYSOCK; 18138494Sobrien CLIENT *clnt; 18238494Sobrien struct hostent *hp; 18338494Sobrien struct timeval tmo = {10, 0}; 184174294Sobrien char *dummystr; 185174294Sobrien amq_string *spp; 18638494Sobrien 18738494Sobrien#ifdef DISK_HOME_HACK 18838494Sobrien if (ch = hack_name(dir)) 18938494Sobrien return ch; 19038494Sobrien#endif /* DISK_HOME_HACK */ 19138494Sobrien 19238494Sobrien#ifdef HAVE_CNODEID 19338494Sobrien server = cluster_server(); 19438494Sobrien#else /* not HAVE_CNODEID */ 19538494Sobrien server = localhost; 19638494Sobrien#endif /* not HAVE_CNODEID */ 19738494Sobrien 198174294Sobrien if ((hp = gethostbyname(server)) == NULL) 19938494Sobrien return dir; 20038494Sobrien memset(&server_addr, 0, sizeof(server_addr)); 201174294Sobrien /* as per POSIX, sin_len need not be set (used internally by kernel) */ 20238494Sobrien server_addr.sin_family = AF_INET; 20338494Sobrien server_addr.sin_addr = *(struct in_addr *) hp->h_addr; 20438494Sobrien 20538494Sobrien clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, tmo, &s); 206174294Sobrien if (clnt == NULL) 207174294Sobrien clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0); 208174294Sobrien if (clnt == NULL) 20938494Sobrien return dir; 21038494Sobrien 211174294Sobrien xstrlcpy(transform, dir, sizeof(transform)); 212174294Sobrien dummystr = transform; 213174294Sobrien spp = amqproc_pawd_1((amq_string *) &dummystr, clnt); 214174294Sobrien if (spp && *spp && **spp) { 215174294Sobrien xstrlcpy(transform, *spp, sizeof(transform)); 216174294Sobrien XFREE(*spp); 21738494Sobrien } 218174294Sobrien clnt_destroy(clnt); 21938494Sobrien return transform; 22038494Sobrien} 22138494Sobrien 22238494Sobrien 22338494Sobrien/* getawd() is a substitute for getwd() which transforms the path */ 22438494Sobrienstatic char * 225174294Sobriengetawd(char *path, size_t l) 22638494Sobrien{ 22738494Sobrien#ifdef HAVE_GETCWD 228174294Sobrien char *wd = getcwd(path, MAXPATHLEN); 22938494Sobrien#else /* not HAVE_GETCWD */ 23038494Sobrien char *wd = getwd(path); 23138494Sobrien#endif /* not HAVE_GETCWD */ 23238494Sobrien 23338494Sobrien if (wd == NULL) { 23438494Sobrien return NULL; 23538494Sobrien } 236174294Sobrien xstrlcpy(path, transform_dir(wd), l); 23738494Sobrien return path; 23838494Sobrien} 23938494Sobrien 24038494Sobrien 24138494Sobrienint 24238494Sobrienmain(int argc, char *argv[]) 24338494Sobrien{ 24438494Sobrien char tmp_buf[MAXPATHLEN], *wd; 24538494Sobrien 24638494Sobrien if (argc == 1) { 247174294Sobrien wd = getawd(tmp_buf, sizeof(tmp_buf)); 24838494Sobrien if (wd == NULL) { 24938494Sobrien fprintf(stderr, "pawd: %s\n", tmp_buf); 25038494Sobrien exit(1); 25138494Sobrien } else { 25238494Sobrien fprintf(stdout, "%s\n", wd); 25338494Sobrien } 25438494Sobrien } else { 25538494Sobrien while (--argc) { 25638494Sobrien wd = transform_dir(*++argv); 25738494Sobrien fprintf(stdout, "%s\n", wd); 25838494Sobrien } 25938494Sobrien } 26038494Sobrien exit(0); 26138494Sobrien} 262