138494Sobrien/* 2310490Scy * Copyright (c) 1997-2014 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. 19310490Scy * 3. Neither the name of the University nor the names of its contributors 2038494Sobrien * may be used to endorse or promote products derived from this software 2138494Sobrien * without specific prior written permission. 2238494Sobrien * 2338494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2438494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2538494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2638494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2738494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2838494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2938494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3038494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3138494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3238494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3338494Sobrien * SUCH DAMAGE. 3438494Sobrien * 3538494Sobrien * 36174294Sobrien * File: am-utils/amq/pawd.c 3738494Sobrien * 3838494Sobrien */ 3938494Sobrien 4038494Sobrien/* 4138494Sobrien * pawd is similar to pwd, except that it returns more "natural" versions of 4238494Sobrien * pathnames for directories automounted with the amd automounter. If any 4338494Sobrien * arguments are given, the "more natural" form of the given pathnames are 4438494Sobrien * printed. 4538494Sobrien * 4638494Sobrien * Paul Anderson (paul@ed.lfcs) 4738494Sobrien * 4838494Sobrien */ 4938494Sobrien 5038494Sobrien#ifdef HAVE_CONFIG_H 5138494Sobrien# include <config.h> 5238494Sobrien#endif /* HAVE_CONFIG_H */ 5338494Sobrien#include <am_defs.h> 5438494Sobrien#include <amq.h> 5538494Sobrien 56174294Sobrien 5738494Sobrien/* statics */ 58174294Sobrienstatic char *localhost = "localhost"; 5938494Sobrienstatic char transform[MAXPATHLEN]; 6038494Sobrien 6138494Sobrien 6238494Sobrien#ifdef HAVE_CNODEID 6338494Sobrienstatic char * 6438494Sobriencluster_server(void) 6538494Sobrien{ 6638494Sobrien# ifdef HAVE_EXTERN_GETCCENT 6738494Sobrien struct cct_entry *cp; 6838494Sobrien# endif /* HAVE_EXTERN_GETCCENT */ 6938494Sobrien 7038494Sobrien if (cnodeid() == 0) 7138494Sobrien return localhost; 7238494Sobrien 7338494Sobrien# ifdef HAVE_EXTERN_GETCCENT 7438494Sobrien while ((cp = getccent())) 7538494Sobrien if (cp->cnode_type == 'r') 7638494Sobrien return cp->cnode_name; 7738494Sobrien# endif /* HAVE_EXTERN_GETCCENT */ 7838494Sobrien 7938494Sobrien return localhost; 8038494Sobrien} 8138494Sobrien#endif /* HAVE_CNODEID */ 8238494Sobrien 8338494Sobrien 8438494Sobrien/* DISK_HOME_HACK added by gdmr */ 8538494Sobrien#ifdef DISK_HOME_HACK 8638494Sobrienstatic char * 8738494Sobrienhack_name(char *dir) 8838494Sobrien{ 8938494Sobrien char partition[MAXPATHLEN]; 9038494Sobrien char username[MAXPATHLEN]; 9138494Sobrien char hesiod_lookup[MAXPATHLEN]; 9238494Sobrien char *to, *ch, *hes_name, *dot; 9338494Sobrien char **hes; 9438494Sobrien 9538494Sobrien#ifdef DEBUG 9638494Sobrien fprintf(stderr, "hack_name(%s)\n", dir); 9738494Sobrien#endif /* DEBUG */ 9838494Sobrien 9938494Sobrien if (dir[0] == '/' && dir[1] == 'a' && dir[2] == '/') { 10038494Sobrien /* Could be /a/server/disk/home/partition/user... */ 10138494Sobrien ch = dir + 3; 10238494Sobrien while (*ch && *ch != '/') ch++; /* Skip server */ 10338494Sobrien if (!NSTREQ(ch, "/disk/home/", 11)) 10438494Sobrien return NULL; /* Nope */ 10538494Sobrien /* Looking promising, next should be the partition name */ 10638494Sobrien ch += 11; 10738494Sobrien to = partition; 10838494Sobrien while (*ch && *ch != '/') *to++ = *ch++; 10938494Sobrien to = '\0'; 11038494Sobrien if (!(*ch)) 11138494Sobrien return NULL; /* Off the end */ 11238494Sobrien /* Now the username */ 11338494Sobrien ch++; 11438494Sobrien to = username; 11538494Sobrien while (*ch && *ch != '/') *to++ = *ch++; 11638494Sobrien to = '\0'; 11738494Sobrien#ifdef DEBUG 11838494Sobrien fprintf(stderr, "partition %s, username %s\n", partition, username); 11938494Sobrien#endif /* DEBUG */ 12038494Sobrien 121174294Sobrien xsnprintf(hesiod_lookup, sizeof(hesiod_lookup), 122174294Sobrien "%s.homes-remote", username); 12338494Sobrien hes = hes_resolve(hesiod_lookup, "amd"); 12438494Sobrien if (!hes) 12538494Sobrien return NULL; 12638494Sobrien#ifdef DEBUG 12738494Sobrien fprintf(stderr, "hesiod -> <%s>\n", *hes); 12838494Sobrien#endif /* DEBUG */ 12938494Sobrien hes_name = strstr(*hes, "/homes/remote/"); 13038494Sobrien if (!hes_name) return NULL; 13138494Sobrien hes_name += 14; 13238494Sobrien#ifdef DEBUG 13338494Sobrien fprintf(stderr, "hesiod -> <%s>\n", hes_name); 13438494Sobrien#endif /* DEBUG */ 13538494Sobrien dot = hes_name; 13638494Sobrien while (*dot && *dot != '.') dot++; 13738494Sobrien *dot = '\0'; 13838494Sobrien#ifdef DEBUG 13938494Sobrien fprintf(stderr, "hesiod -> <%s>\n", hes_name); 14038494Sobrien#endif /* DEBUG */ 14138494Sobrien 14238494Sobrien if (strcmp(partition, hes_name)) return NULL; 14338494Sobrien#ifdef DEBUG 14438494Sobrien fprintf(stderr, "A match, munging....\n"); 14538494Sobrien#endif /* DEBUG */ 146174294Sobrien xstrlcpy(transform, "/home/", sizeof(transform)); 147174294Sobrien xstrlcat(transform, username, sizeof(transform)); 148174294Sobrien if (*ch) 149174294Sobrien xstrlcat(transform, ch, sizeof(transform)); 15038494Sobrien#ifdef DEBUG 15138494Sobrien fprintf(stderr, "Munged to <%s>\n", transform); 15238494Sobrien#endif /* DEBUG */ 15338494Sobrien return transform; 15438494Sobrien } 15538494Sobrien return NULL; 15638494Sobrien} 15738494Sobrien#endif /* DISK_HOME_HACK */ 15838494Sobrien 15938494Sobrien 16038494Sobrien/* 16138494Sobrien * The routine transform_dir(path) transforms pathnames of directories 16238494Sobrien * mounted with the amd automounter to produce a more "natural" version. 16338494Sobrien * The automount table is obtained from the local amd via the rpc interface 16438494Sobrien * and reverse lookups are repeatedly performed on the directory name 16538494Sobrien * substituting the name of the automount link for the value of the link 16638494Sobrien * whenever it occurs as a prefix of the directory name. 16738494Sobrien */ 16838494Sobrienstatic char * 16938494Sobrientransform_dir(char *dir) 17038494Sobrien{ 17138494Sobrien#ifdef DISK_HOME_HACK 17238494Sobrien char *ch; 17338494Sobrien#endif /* DISK_HOME_HACK */ 17438494Sobrien char *server; 17538494Sobrien struct sockaddr_in server_addr; 17638494Sobrien int s = RPC_ANYSOCK; 17738494Sobrien CLIENT *clnt; 17838494Sobrien struct hostent *hp; 17938494Sobrien struct timeval tmo = {10, 0}; 180174294Sobrien char *dummystr; 181174294Sobrien amq_string *spp; 18238494Sobrien 18338494Sobrien#ifdef DISK_HOME_HACK 18438494Sobrien if (ch = hack_name(dir)) 18538494Sobrien return ch; 18638494Sobrien#endif /* DISK_HOME_HACK */ 18738494Sobrien 18838494Sobrien#ifdef HAVE_CNODEID 18938494Sobrien server = cluster_server(); 19038494Sobrien#else /* not HAVE_CNODEID */ 19138494Sobrien server = localhost; 19238494Sobrien#endif /* not HAVE_CNODEID */ 19338494Sobrien 194174294Sobrien if ((hp = gethostbyname(server)) == NULL) 19538494Sobrien return dir; 19638494Sobrien memset(&server_addr, 0, sizeof(server_addr)); 197174294Sobrien /* as per POSIX, sin_len need not be set (used internally by kernel) */ 19838494Sobrien server_addr.sin_family = AF_INET; 19938494Sobrien server_addr.sin_addr = *(struct in_addr *) hp->h_addr; 20038494Sobrien 20138494Sobrien clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, tmo, &s); 202174294Sobrien if (clnt == NULL) 203174294Sobrien clnt = clnttcp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, &s, 0, 0); 204174294Sobrien if (clnt == NULL) 20538494Sobrien return dir; 20638494Sobrien 207174294Sobrien xstrlcpy(transform, dir, sizeof(transform)); 208174294Sobrien dummystr = transform; 209174294Sobrien spp = amqproc_pawd_1((amq_string *) &dummystr, clnt); 210174294Sobrien if (spp && *spp && **spp) { 211174294Sobrien xstrlcpy(transform, *spp, sizeof(transform)); 212174294Sobrien XFREE(*spp); 21338494Sobrien } 214174294Sobrien clnt_destroy(clnt); 21538494Sobrien return transform; 21638494Sobrien} 21738494Sobrien 21838494Sobrien 21938494Sobrien/* getawd() is a substitute for getwd() which transforms the path */ 22038494Sobrienstatic char * 221174294Sobriengetawd(char *path, size_t l) 22238494Sobrien{ 22338494Sobrien#ifdef HAVE_GETCWD 224174294Sobrien char *wd = getcwd(path, MAXPATHLEN); 22538494Sobrien#else /* not HAVE_GETCWD */ 22638494Sobrien char *wd = getwd(path); 22738494Sobrien#endif /* not HAVE_GETCWD */ 22838494Sobrien 22938494Sobrien if (wd == NULL) { 23038494Sobrien return NULL; 23138494Sobrien } 232174294Sobrien xstrlcpy(path, transform_dir(wd), l); 23338494Sobrien return path; 23438494Sobrien} 23538494Sobrien 23638494Sobrien 23738494Sobrienint 23838494Sobrienmain(int argc, char *argv[]) 23938494Sobrien{ 24038494Sobrien char tmp_buf[MAXPATHLEN], *wd; 24138494Sobrien 24238494Sobrien if (argc == 1) { 243174294Sobrien wd = getawd(tmp_buf, sizeof(tmp_buf)); 24438494Sobrien if (wd == NULL) { 24538494Sobrien fprintf(stderr, "pawd: %s\n", tmp_buf); 24638494Sobrien exit(1); 24738494Sobrien } else { 24838494Sobrien fprintf(stdout, "%s\n", wd); 24938494Sobrien } 25038494Sobrien } else { 25138494Sobrien while (--argc) { 25238494Sobrien wd = transform_dir(*++argv); 25338494Sobrien fprintf(stdout, "%s\n", wd); 25438494Sobrien } 25538494Sobrien } 25638494Sobrien exit(0); 25738494Sobrien} 258