1*47487Spendry /* 2*47487Spendry * $Id: wr_atab.c,v 5.2.1.2 90/12/21 16:46:49 jsp Alpha $ 3*47487Spendry * 4*47487Spendry * Copyright (c) 1989 Jan-Simon Pendry 5*47487Spendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 6*47487Spendry * Copyright (c) 1989 The Regents of the University of California. 7*47487Spendry * All rights reserved. 8*47487Spendry * 9*47487Spendry * This code is derived from software contributed to Berkeley by 10*47487Spendry * Jan-Simon Pendry at Imperial College, London. 11*47487Spendry * 12*47487Spendry * Redistribution and use in source and binary forms are permitted provided 13*47487Spendry * that: (1) source distributions retain this entire copyright notice and 14*47487Spendry * comment, and (2) distributions including binaries display the following 15*47487Spendry * acknowledgement: ``This product includes software developed by the 16*47487Spendry * University of California, Berkeley and its contributors'' in the 17*47487Spendry * documentation or other materials provided with the distribution and in 18*47487Spendry * all advertising materials mentioning features or use of this software. 19*47487Spendry * Neither the name of the University nor the names of its contributors may 20*47487Spendry * be used to endorse or promote products derived from this software without 21*47487Spendry * specific prior written permission. 22*47487Spendry * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 23*47487Spendry * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 24*47487Spendry * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 25*47487Spendry * 26*47487Spendry * @(#)wr_atab.c 5.1 (Berkeley) 03/17/91 27*47487Spendry */ 28*47487Spendry 29*47487Spendry #include "../fsinfo/fsinfo.h" 30*47487Spendry 31*47487Spendry /* 32*47487Spendry * Write a sequence of automount mount map entries 33*47487Spendry */ 34*47487Spendry static int write_amount_info(af, ap, sk) 35*47487Spendry FILE *af; 36*47487Spendry automount *ap; 37*47487Spendry int sk; 38*47487Spendry { 39*47487Spendry int errors = 0; 40*47487Spendry if (ap->a_mount) { 41*47487Spendry /* 42*47487Spendry * A pseudo-directory. 43*47487Spendry * This can also be a top-level directory, in which 44*47487Spendry * case the type:=auto is not wanted... 45*47487Spendry * 46*47487Spendry * type:=auto;fs:=${map};pref:=whatever/ 47*47487Spendry */ 48*47487Spendry automount *ap2; 49*47487Spendry if (strlen(ap->a_name) > sk) { 50*47487Spendry fprintf(af, "%s type:=auto;fs:=${map};pref:=%s/\n", 51*47487Spendry ap->a_name + sk, ap->a_name + sk); 52*47487Spendry } 53*47487Spendry ITER(ap2, automount, ap->a_mount) 54*47487Spendry errors += write_amount_info(af, ap2, sk); 55*47487Spendry } else if (ap->a_mounted) { 56*47487Spendry /* 57*47487Spendry * A mounted partition 58*47487Spendry * type:=link [ link entries ] type:=nfs [ nfs entries ] 59*47487Spendry */ 60*47487Spendry dict_data *dd; 61*47487Spendry dict_ent *de = ap->a_mounted; 62*47487Spendry int done_type_link = 0; 63*47487Spendry char *key = ap->a_name + sk; 64*47487Spendry 65*47487Spendry /* 66*47487Spendry * Output the map key 67*47487Spendry */ 68*47487Spendry fputs(key, af); 69*47487Spendry 70*47487Spendry /* 71*47487Spendry * First output any Link locations that would not 72*47487Spendry * otherwise be correctly mounted. These refer 73*47487Spendry * to filesystem which are not mounted in the same 74*47487Spendry * place which the automounter would use. 75*47487Spendry */ 76*47487Spendry ITER(dd, dict_data, &de->de_q) { 77*47487Spendry mount *mp = (mount *) dd->dd_data; 78*47487Spendry /* 79*47487Spendry * If the mount point and the exported volname are the 80*47487Spendry * same then this filesystem will be recognised by 81*47487Spendry * the restart code - so we don't need to put out a 82*47487Spendry * special rule for it. 83*47487Spendry */ 84*47487Spendry if (mp->m_dk->d_host->h_lochost) { 85*47487Spendry char amountpt[1024]; 86*47487Spendry compute_automount_point(amountpt, mp->m_dk->d_host, mp->m_exported->m_volname); 87*47487Spendry if (strcmp(mp->m_dk->d_mountpt, amountpt) != 0) { 88*47487Spendry /* 89*47487Spendry * ap->a_volname is the name of the aliased volume 90*47487Spendry * mp->m_name is the mount point of the filesystem 91*47487Spendry * mp->m_volname is the volume name of the filesystems 92*47487Spendry */ 93*47487Spendry 94*47487Spendry /* 95*47487Spendry * Find length of key and volume names 96*47487Spendry */ 97*47487Spendry int avlen = strlen(ap->a_volname); 98*47487Spendry int mnlen = strlen(mp->m_volname); 99*47487Spendry /* 100*47487Spendry * Make sure a -type:=link is output once 101*47487Spendry */ 102*47487Spendry if (!done_type_link) { 103*47487Spendry done_type_link = 1; 104*47487Spendry fputs(" -type:=link", af); 105*47487Spendry } 106*47487Spendry /* 107*47487Spendry * Output a selector for the hostname, 108*47487Spendry * the device from which to mount and 109*47487Spendry * where to mount. This will correspond 110*47487Spendry * to the values output for the fstab. 111*47487Spendry */ 112*47487Spendry if (mp->m_dk->d_host->h_lochost) 113*47487Spendry fprintf(af, " host==%s", mp->m_dk->d_host->h_lochost); 114*47487Spendry else 115*47487Spendry fprintf(af, " hostd==%s", mp->m_dk->d_host->h_hostname); 116*47487Spendry fprintf(af, ";fs:=%s", mp->m_name); 117*47487Spendry /* 118*47487Spendry * ... and a sublink if needed 119*47487Spendry */ 120*47487Spendry if (mnlen < avlen) { 121*47487Spendry char *sublink = ap->a_volname + mnlen + 1; 122*47487Spendry fprintf(af, "/%s", sublink); 123*47487Spendry } 124*47487Spendry fputs(" ||", af); 125*47487Spendry } 126*47487Spendry } 127*47487Spendry } 128*47487Spendry 129*47487Spendry /* 130*47487Spendry * Next do the NFS locations 131*47487Spendry */ 132*47487Spendry 133*47487Spendry if (done_type_link) 134*47487Spendry fputs(" -", af); 135*47487Spendry 136*47487Spendry ITER(dd, dict_data, &de->de_q) { 137*47487Spendry mount *mp = (mount *) dd->dd_data; 138*47487Spendry int namelen = mp->m_name_len; 139*47487Spendry int exp_namelen = mp->m_exported->m_name_len; 140*47487Spendry int volnlen = strlen(ap->a_volname); 141*47487Spendry int mvolnlen = strlen(mp->m_volname); 142*47487Spendry fputc(' ', af); 143*47487Spendry #ifdef notdef 144*47487Spendry fprintf(af, "\\\n /* avolname = %s, mname = %s,\n * mvolname = %s, mexp_name = %s,\n * mexp_volname = %s\n */\\\n", 145*47487Spendry ap->a_volname, mp->m_name, mp->m_volname, mp->m_exported->m_name, mp->m_exported->m_volname); 146*47487Spendry #endif 147*47487Spendry /* 148*47487Spendry * Output any selectors 149*47487Spendry */ 150*47487Spendry if (mp->m_sel) 151*47487Spendry fprintf(af, "%s;", mp->m_sel); 152*47487Spendry /* 153*47487Spendry * Print host and volname of exported filesystem 154*47487Spendry */ 155*47487Spendry fprintf(af, "rhost:=%s", 156*47487Spendry mp->m_dk->d_host->h_lochost ? 157*47487Spendry mp->m_dk->d_host->h_lochost : 158*47487Spendry mp->m_dk->d_host->h_hostname); 159*47487Spendry fprintf(af, ";rfs:=%s", mp->m_exported->m_volname); 160*47487Spendry /* 161*47487Spendry * Now determine whether a sublink is required. 162*47487Spendry */ 163*47487Spendry if (exp_namelen < namelen || mvolnlen < volnlen) { 164*47487Spendry char sublink[1024]; 165*47487Spendry sublink[0] = '\0'; 166*47487Spendry if (exp_namelen < namelen) { 167*47487Spendry strcat(sublink, mp->m_name + exp_namelen + 1); 168*47487Spendry if (mvolnlen < volnlen) 169*47487Spendry strcat(sublink, "/"); 170*47487Spendry } 171*47487Spendry if (mvolnlen < volnlen) 172*47487Spendry strcat(sublink, ap->a_volname + mvolnlen + 1); 173*47487Spendry 174*47487Spendry fprintf(af, ";sublink:=%s", sublink); 175*47487Spendry } 176*47487Spendry } 177*47487Spendry fputc('\n', af); 178*47487Spendry } else if (ap->a_symlink) { 179*47487Spendry /* 180*47487Spendry * A specific link. 181*47487Spendry * 182*47487Spendry * type:=link;fs:=whatever 183*47487Spendry */ 184*47487Spendry fprintf(af, "%s type:=link;fs:=%s\n", ap->a_name + sk, ap->a_symlink); 185*47487Spendry } 186*47487Spendry return errors; 187*47487Spendry } 188*47487Spendry 189*47487Spendry /* 190*47487Spendry * Write a single automount configuration file 191*47487Spendry */ 192*47487Spendry static int write_amount(q, def) 193*47487Spendry qelem *q; 194*47487Spendry char *def; 195*47487Spendry { 196*47487Spendry automount *ap; 197*47487Spendry int errors = 0; 198*47487Spendry int direct = 0; 199*47487Spendry 200*47487Spendry /* 201*47487Spendry * Output all indirect maps 202*47487Spendry */ 203*47487Spendry ITER(ap, automount, q) { 204*47487Spendry FILE *af; 205*47487Spendry char *p; 206*47487Spendry /* 207*47487Spendry * If there is no a_mount node then this is really 208*47487Spendry * a direct mount, so just keep a count and continue. 209*47487Spendry * Direct mounts are output into a special file during 210*47487Spendry * the second pass below. 211*47487Spendry */ 212*47487Spendry if (!ap->a_mount) { 213*47487Spendry direct++; 214*47487Spendry continue; 215*47487Spendry } 216*47487Spendry p = strrchr(ap->a_name, '/'); 217*47487Spendry if (!p) p = ap->a_name; 218*47487Spendry else p++; 219*47487Spendry af = pref_open(mount_pref, p, gen_hdr, ap->a_name); 220*47487Spendry if (af) { 221*47487Spendry show_new(ap->a_name); 222*47487Spendry fputs("/defaults ", af); 223*47487Spendry if (*def) 224*47487Spendry fprintf(af, "%s;", def); 225*47487Spendry fputs("type:=nfs\n", af); 226*47487Spendry errors += write_amount_info(af, ap, strlen(ap->a_name) + 1); 227*47487Spendry errors += pref_close(af); 228*47487Spendry } 229*47487Spendry } 230*47487Spendry 231*47487Spendry /* 232*47487Spendry * Output any direct map entries which were found during the 233*47487Spendry * previous pass over the data. 234*47487Spendry */ 235*47487Spendry if (direct) { 236*47487Spendry FILE *af = pref_open(mount_pref, "direct.map", info_hdr, "direct mount"); 237*47487Spendry if (af) { 238*47487Spendry show_new("direct mounts"); 239*47487Spendry fputs("/defaults ", af); 240*47487Spendry if (*def) 241*47487Spendry fprintf(af, "%s;", def); 242*47487Spendry fputs("type:=nfs\n", af); 243*47487Spendry ITER(ap, automount, q) 244*47487Spendry if (!ap->a_mount) 245*47487Spendry errors += write_amount_info(af, ap, 1); 246*47487Spendry errors += pref_close(af); 247*47487Spendry } 248*47487Spendry } 249*47487Spendry 250*47487Spendry return errors; 251*47487Spendry } 252*47487Spendry 253*47487Spendry /* 254*47487Spendry * Write all the needed automount configuration files 255*47487Spendry */ 256*47487Spendry write_atab(q) 257*47487Spendry qelem *q; 258*47487Spendry { 259*47487Spendry int errors = 0; 260*47487Spendry 261*47487Spendry if (mount_pref) { 262*47487Spendry auto_tree *tp; 263*47487Spendry show_area_being_processed("write automount", ""); 264*47487Spendry ITER(tp, auto_tree, q) 265*47487Spendry errors += write_amount(tp->t_mount, tp->t_defaults); 266*47487Spendry } 267*47487Spendry 268*47487Spendry return errors; 269*47487Spendry } 270