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