wr_atab.c revision 174294
138494Sobrien/* 2174294Sobrien * Copyright (c) 1997-2006 Erez Zadok 338494Sobrien * Copyright (c) 1989 Jan-Simon Pendry 438494Sobrien * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 538494Sobrien * Copyright (c) 1989 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/fsinfo/wr_atab.c 4138494Sobrien * 4238494Sobrien */ 4338494Sobrien 4438494Sobrien#ifdef HAVE_CONFIG_H 4538494Sobrien# include <config.h> 4638494Sobrien#endif /* HAVE_CONFIG_H */ 4738494Sobrien#include <am_defs.h> 4838494Sobrien#include <fsi_data.h> 4938494Sobrien#include <fsinfo.h> 5038494Sobrien 5138494Sobrien 5238494Sobrien/* 5338494Sobrien * Write a sequence of automount mount map entries 5438494Sobrien */ 5538494Sobrienstatic int 56174294Sobrienwrite_amount_info(FILE *af, automount *ap, u_int sk) 5738494Sobrien{ 5838494Sobrien int errors = 0; 5938494Sobrien 6038494Sobrien if (ap->a_mount) { 6138494Sobrien /* 6238494Sobrien * A pseudo-directory. 6338494Sobrien * This can also be a top-level directory, in which 6438494Sobrien * case the type:=auto is not wanted... 6538494Sobrien * 6638494Sobrien * type:=auto;fs:=${map};pref:=whatever/ 6738494Sobrien */ 6838494Sobrien automount *ap2; 6938494Sobrien if (strlen(ap->a_name) > sk) { 7038494Sobrien fprintf(af, "%s type:=auto;fs:=${map};pref:=%s/\n", 7138494Sobrien ap->a_name + sk, ap->a_name + sk); 7238494Sobrien } 7338494Sobrien ITER(ap2, automount, ap->a_mount) 7438494Sobrien errors += write_amount_info(af, ap2, sk); 7538494Sobrien } else if (ap->a_hardwiredfs) { 7638494Sobrien 7738494Sobrien /* 7838494Sobrien * A hardwired filesystem "hostname:path" 7938494Sobrien * rhost:=hostname;rfs:=path 8038494Sobrien */ 8138494Sobrien char *key = ap->a_name + sk; 8238494Sobrien char *hostname = ap->a_hardwiredfs; 8338494Sobrien char *path = strrchr(hostname, (int) ':'); 8438494Sobrien 8538494Sobrien if (path == NULL) { 8638494Sobrien fprintf(stderr, "%s: %s not an NFS filesystem\n", ap->a_name, ap->a_hardwiredfs); 8738494Sobrien errors++; 8838494Sobrien } else { 8938494Sobrien *path = '\0'; 9038494Sobrien path++; 9138494Sobrien 9238494Sobrien /* 9338494Sobrien * Output the map key 9438494Sobrien */ 9538494Sobrien fputs(key, af); 9638494Sobrien fprintf(af, " rhost:=%s", hostname); 9738494Sobrien fprintf(af, ";rfs:=%s", path); 9838494Sobrien if (ap->a_opts && !STREQ(ap->a_opts, "")) { 9938494Sobrien fprintf(af, ";%s", ap->a_opts); 10038494Sobrien } 10138494Sobrien fputc('\n', af); 10238494Sobrien path--; 10338494Sobrien *path = ':'; 10438494Sobrien } 10538494Sobrien } else if (ap->a_mounted) { 10638494Sobrien 10738494Sobrien /* 10838494Sobrien * A mounted partition 10938494Sobrien * type:=link [ link entries ] type:=nfs [ nfs entries ] 11038494Sobrien */ 11138494Sobrien dict_data *dd; 11238494Sobrien dict_ent *de = ap->a_mounted; 11338494Sobrien int done_type_link = 0; 11438494Sobrien char *key = ap->a_name + sk; 11538494Sobrien 11638494Sobrien /* 11738494Sobrien * Output the map key 11838494Sobrien */ 11938494Sobrien fputs(key, af); 12038494Sobrien 12138494Sobrien /* 12238494Sobrien * First output any Link locations that would not 12338494Sobrien * otherwise be correctly mounted. These refer 12438494Sobrien * to filesystem which are not mounted in the same 12538494Sobrien * place which the automounter would use. 12638494Sobrien */ 12738494Sobrien ITER(dd, dict_data, &de->de_q) { 12838494Sobrien fsi_mount *mp = (fsi_mount *) dd->dd_data; 12938494Sobrien /* 13038494Sobrien * If the mount point and the exported volname are the 13142629Sobrien * same then this filesystem will be recognized by 13238494Sobrien * the restart code - so we don't need to put out a 13338494Sobrien * special rule for it. 13438494Sobrien */ 13538494Sobrien if (mp->m_dk->d_host->h_lochost) { 13638494Sobrien char amountpt[1024]; 137174294Sobrien compute_automount_point(amountpt, sizeof(amountpt), 138174294Sobrien mp->m_dk->d_host, mp->m_exported->m_volname); 13938494Sobrien if (!STREQ(mp->m_dk->d_mountpt, amountpt)) { 14038494Sobrien /* 14138494Sobrien * ap->a_volname is the name of the aliased volume 14238494Sobrien * mp->m_name is the mount point of the filesystem 14338494Sobrien * mp->m_volname is the volume name of the filesystems 14438494Sobrien */ 14538494Sobrien 14638494Sobrien /* 14738494Sobrien * Find length of key and volume names 14838494Sobrien */ 14938494Sobrien int avlen = strlen(ap->a_volname); 15038494Sobrien int mnlen = strlen(mp->m_volname); 15138494Sobrien 15238494Sobrien /* 15338494Sobrien * Make sure a -type:=link is output once 15438494Sobrien */ 15538494Sobrien if (!done_type_link) { 15638494Sobrien done_type_link = 1; 15738494Sobrien fputs(" -type:=link", af); 15838494Sobrien } 15938494Sobrien 16038494Sobrien /* 16138494Sobrien * Output a selector for the hostname, 16238494Sobrien * the device from which to mount and 16338494Sobrien * where to mount. This will correspond 16438494Sobrien * to the values output for the fstab. 16538494Sobrien */ 16638494Sobrien if (mp->m_dk->d_host->h_lochost) 16738494Sobrien fprintf(af, " host==%s", mp->m_dk->d_host->h_lochost); 16838494Sobrien else 16938494Sobrien fprintf(af, " hostd==%s", mp->m_dk->d_host->h_hostname); 17038494Sobrien fprintf(af, ";fs:=%s", mp->m_name); 17138494Sobrien 17238494Sobrien /* 17338494Sobrien * ... and a sublink if needed 17438494Sobrien */ 17538494Sobrien if (mnlen < avlen) { 17638494Sobrien char *sublink = ap->a_volname + mnlen + 1; 17738494Sobrien fprintf(af, "/%s", sublink); 17838494Sobrien } 17938494Sobrien fputs(" ||", af); 18038494Sobrien } 18138494Sobrien } 18238494Sobrien } 18338494Sobrien 18438494Sobrien /* 18538494Sobrien * Next do the NFS locations 18638494Sobrien */ 18738494Sobrien if (done_type_link) 18838494Sobrien fputs(" -", af); 18938494Sobrien 19038494Sobrien ITER(dd, dict_data, &de->de_q) { 19138494Sobrien fsi_mount *mp = (fsi_mount *) dd->dd_data; 19238494Sobrien int namelen = mp->m_name_len; 19338494Sobrien int exp_namelen = mp->m_exported->m_name_len; 19438494Sobrien int volnlen = strlen(ap->a_volname); 19538494Sobrien int mvolnlen = strlen(mp->m_volname); 19638494Sobrien 19738494Sobrien fputc(' ', af); 19838494Sobrien 19938494Sobrien /* 20038494Sobrien * Output any selectors 20138494Sobrien */ 20238494Sobrien if (mp->m_sel) 20338494Sobrien fprintf(af, "%s;", mp->m_sel); 20438494Sobrien 20538494Sobrien /* 20638494Sobrien * Print host and volname of exported filesystem 20738494Sobrien */ 20838494Sobrien fprintf(af, "rhost:=%s", 20938494Sobrien mp->m_dk->d_host->h_lochost ? 21038494Sobrien mp->m_dk->d_host->h_lochost : 21138494Sobrien mp->m_dk->d_host->h_hostname); 21238494Sobrien fprintf(af, ";rfs:=%s", mp->m_exported->m_volname); 21338494Sobrien if (ap->a_opts && !STREQ(ap->a_opts, "")) { 21438494Sobrien fprintf(af, ";%s", ap->a_opts); 21538494Sobrien } 21638494Sobrien 21738494Sobrien /* 21838494Sobrien * Now determine whether a sublink is required. 21938494Sobrien */ 22038494Sobrien if (exp_namelen < namelen || mvolnlen < volnlen) { 22138494Sobrien char sublink[1024]; 22238494Sobrien sublink[0] = '\0'; 22338494Sobrien if (exp_namelen < namelen) { 224174294Sobrien xstrlcat(sublink, mp->m_name + exp_namelen + 1, sizeof(sublink)); 22538494Sobrien if (mvolnlen < volnlen) 226174294Sobrien xstrlcat(sublink, "/", sizeof(sublink)); 22738494Sobrien } 22838494Sobrien if (mvolnlen < volnlen) 229174294Sobrien xstrlcat(sublink, ap->a_volname + mvolnlen + 1, sizeof(sublink)); 23038494Sobrien 23138494Sobrien fprintf(af, ";sublink:=%s", sublink); 23238494Sobrien } 23338494Sobrien } 23438494Sobrien fputc('\n', af); 23538494Sobrien } else if (ap->a_symlink) { 23638494Sobrien 23738494Sobrien /* 23838494Sobrien * A specific link. 23938494Sobrien * 24038494Sobrien * type:=link;fs:=whatever 24138494Sobrien */ 24238494Sobrien fprintf(af, "%s type:=link;fs:=%s\n", ap->a_name + sk, ap->a_symlink); 24338494Sobrien } 24438494Sobrien 24538494Sobrien return errors; 24638494Sobrien} 24738494Sobrien 24838494Sobrien 24938494Sobrien/* 25038494Sobrien * Write a single automount configuration file 25138494Sobrien */ 25238494Sobrienstatic int 25338494Sobrienwrite_amount( qelem *q, char *def) 25438494Sobrien{ 25538494Sobrien automount *ap; 25638494Sobrien int errors = 0; 25738494Sobrien int direct = 0; 25838494Sobrien 25938494Sobrien /* 26038494Sobrien * Output all indirect maps 26138494Sobrien */ 26238494Sobrien ITER(ap, automount, q) { 26338494Sobrien FILE *af; 26438494Sobrien char *p; 26538494Sobrien 26638494Sobrien /* 26738494Sobrien * If there is no a_mount node then this is really 26838494Sobrien * a direct mount, so just keep a count and continue. 26938494Sobrien * Direct mounts are output into a special file during 27038494Sobrien * the second pass below. 27138494Sobrien */ 27238494Sobrien if (!ap->a_mount) { 27338494Sobrien direct++; 27438494Sobrien continue; 27538494Sobrien } 27638494Sobrien 27738494Sobrien p = strrchr(ap->a_name, '/'); 27838494Sobrien if (!p) 27938494Sobrien p = ap->a_name; 28038494Sobrien else 28138494Sobrien p++; 28238494Sobrien 28338494Sobrien af = pref_open(mount_pref, p, gen_hdr, ap->a_name); 28438494Sobrien if (af) { 28538494Sobrien show_new(ap->a_name); 28638494Sobrien fputs("/defaults ", af); 28738494Sobrien if (*def) 28838494Sobrien fprintf(af, "%s;", def); 28938494Sobrien fputs("type:=nfs\n", af); 29038494Sobrien errors += write_amount_info(af, ap, strlen(ap->a_name) + 1); 29138494Sobrien errors += pref_close(af); 29238494Sobrien } 29338494Sobrien } 29438494Sobrien 29538494Sobrien /* 29638494Sobrien * Output any direct map entries which were found during the 29738494Sobrien * previous pass over the data. 29838494Sobrien */ 29938494Sobrien if (direct) { 30038494Sobrien FILE *af = pref_open(mount_pref, "direct.map", info_hdr, "direct mount"); 30138494Sobrien 30238494Sobrien if (af) { 30338494Sobrien show_new("direct mounts"); 30438494Sobrien fputs("/defaults ", af); 30538494Sobrien if (*def) 30638494Sobrien fprintf(af, "%s;", def); 30738494Sobrien fputs("type:=nfs\n", af); 30838494Sobrien ITER(ap, automount, q) 30938494Sobrien if (!ap->a_mount) 31038494Sobrien errors += write_amount_info(af, ap, 1); 31138494Sobrien errors += pref_close(af); 31238494Sobrien } 31338494Sobrien } 31438494Sobrien return errors; 31538494Sobrien} 31638494Sobrien 31738494Sobrien 31838494Sobrien/* 31938494Sobrien * Write all the needed automount configuration files 32038494Sobrien */ 32138494Sobrienint 32238494Sobrienwrite_atab(qelem *q) 32338494Sobrien{ 32438494Sobrien int errors = 0; 32538494Sobrien 32638494Sobrien if (mount_pref) { 32738494Sobrien auto_tree *tp; 32838494Sobrien show_area_being_processed("write automount", 5); 32938494Sobrien ITER(tp, auto_tree, q) 33038494Sobrien errors += write_amount(tp->t_mount, tp->t_defaults); 33138494Sobrien } 33238494Sobrien 33338494Sobrien return errors; 33438494Sobrien} 335