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