147487Spendry /* 247487Spendry * Copyright (c) 1989 Jan-Simon Pendry 347487Spendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 447487Spendry * Copyright (c) 1989 The Regents of the University of California. 547487Spendry * All rights reserved. 647487Spendry * 747487Spendry * This code is derived from software contributed to Berkeley by 847487Spendry * Jan-Simon Pendry at Imperial College, London. 947487Spendry * 1047530Spendry * %sccs.include.redist.c% 1147487Spendry * 12*52455Spendry * @(#)wr_atab.c 5.4 (Berkeley) 02/09/92 1349686Spendry * 14*52455Spendry * $Id: wr_atab.c,v 5.2.2.1 1992/02/09 15:09:44 jsp beta $ 1549686Spendry * 1647487Spendry */ 1747487Spendry 1847487Spendry #include "../fsinfo/fsinfo.h" 1947487Spendry 2047487Spendry /* 2147487Spendry * Write a sequence of automount mount map entries 2247487Spendry */ 2347487Spendry static int write_amount_info(af, ap, sk) 2447487Spendry FILE *af; 2547487Spendry automount *ap; 2647487Spendry int sk; 2747487Spendry { 2847487Spendry int errors = 0; 2947487Spendry if (ap->a_mount) { 3047487Spendry /* 3147487Spendry * A pseudo-directory. 3247487Spendry * This can also be a top-level directory, in which 3347487Spendry * case the type:=auto is not wanted... 3447487Spendry * 3547487Spendry * type:=auto;fs:=${map};pref:=whatever/ 3647487Spendry */ 3747487Spendry automount *ap2; 3847487Spendry if (strlen(ap->a_name) > sk) { 3947487Spendry fprintf(af, "%s type:=auto;fs:=${map};pref:=%s/\n", 4047487Spendry ap->a_name + sk, ap->a_name + sk); 4147487Spendry } 4247487Spendry ITER(ap2, automount, ap->a_mount) 4347487Spendry errors += write_amount_info(af, ap2, sk); 4447487Spendry } else if (ap->a_mounted) { 4547487Spendry /* 4647487Spendry * A mounted partition 4747487Spendry * type:=link [ link entries ] type:=nfs [ nfs entries ] 4847487Spendry */ 4947487Spendry dict_data *dd; 5047487Spendry dict_ent *de = ap->a_mounted; 5147487Spendry int done_type_link = 0; 5247487Spendry char *key = ap->a_name + sk; 5347487Spendry 5447487Spendry /* 5547487Spendry * Output the map key 5647487Spendry */ 5747487Spendry fputs(key, af); 5847487Spendry 5947487Spendry /* 6047487Spendry * First output any Link locations that would not 6147487Spendry * otherwise be correctly mounted. These refer 6247487Spendry * to filesystem which are not mounted in the same 6347487Spendry * place which the automounter would use. 6447487Spendry */ 6547487Spendry ITER(dd, dict_data, &de->de_q) { 6647487Spendry mount *mp = (mount *) dd->dd_data; 6747487Spendry /* 6847487Spendry * If the mount point and the exported volname are the 6947487Spendry * same then this filesystem will be recognised by 7047487Spendry * the restart code - so we don't need to put out a 7147487Spendry * special rule for it. 7247487Spendry */ 7347487Spendry if (mp->m_dk->d_host->h_lochost) { 7447487Spendry char amountpt[1024]; 7547487Spendry compute_automount_point(amountpt, mp->m_dk->d_host, mp->m_exported->m_volname); 7647487Spendry if (strcmp(mp->m_dk->d_mountpt, amountpt) != 0) { 7747487Spendry /* 7847487Spendry * ap->a_volname is the name of the aliased volume 7947487Spendry * mp->m_name is the mount point of the filesystem 8047487Spendry * mp->m_volname is the volume name of the filesystems 8147487Spendry */ 8247487Spendry 8347487Spendry /* 8447487Spendry * Find length of key and volume names 8547487Spendry */ 8647487Spendry int avlen = strlen(ap->a_volname); 8747487Spendry int mnlen = strlen(mp->m_volname); 8847487Spendry /* 8947487Spendry * Make sure a -type:=link is output once 9047487Spendry */ 9147487Spendry if (!done_type_link) { 9247487Spendry done_type_link = 1; 9347487Spendry fputs(" -type:=link", af); 9447487Spendry } 9547487Spendry /* 9647487Spendry * Output a selector for the hostname, 9747487Spendry * the device from which to mount and 9847487Spendry * where to mount. This will correspond 9947487Spendry * to the values output for the fstab. 10047487Spendry */ 10147487Spendry if (mp->m_dk->d_host->h_lochost) 10247487Spendry fprintf(af, " host==%s", mp->m_dk->d_host->h_lochost); 10347487Spendry else 10447487Spendry fprintf(af, " hostd==%s", mp->m_dk->d_host->h_hostname); 10547487Spendry fprintf(af, ";fs:=%s", mp->m_name); 10647487Spendry /* 10747487Spendry * ... and a sublink if needed 10847487Spendry */ 10947487Spendry if (mnlen < avlen) { 11047487Spendry char *sublink = ap->a_volname + mnlen + 1; 11147487Spendry fprintf(af, "/%s", sublink); 11247487Spendry } 11347487Spendry fputs(" ||", af); 11447487Spendry } 11547487Spendry } 11647487Spendry } 11747487Spendry 11847487Spendry /* 11947487Spendry * Next do the NFS locations 12047487Spendry */ 12147487Spendry 12247487Spendry if (done_type_link) 12347487Spendry fputs(" -", af); 12447487Spendry 12547487Spendry ITER(dd, dict_data, &de->de_q) { 12647487Spendry mount *mp = (mount *) dd->dd_data; 12747487Spendry int namelen = mp->m_name_len; 12847487Spendry int exp_namelen = mp->m_exported->m_name_len; 12947487Spendry int volnlen = strlen(ap->a_volname); 13047487Spendry int mvolnlen = strlen(mp->m_volname); 13147487Spendry fputc(' ', af); 13247487Spendry #ifdef notdef 13347487Spendry fprintf(af, "\\\n /* avolname = %s, mname = %s,\n * mvolname = %s, mexp_name = %s,\n * mexp_volname = %s\n */\\\n", 13447487Spendry ap->a_volname, mp->m_name, mp->m_volname, mp->m_exported->m_name, mp->m_exported->m_volname); 13547487Spendry #endif 13647487Spendry /* 13747487Spendry * Output any selectors 13847487Spendry */ 13947487Spendry if (mp->m_sel) 14047487Spendry fprintf(af, "%s;", mp->m_sel); 14147487Spendry /* 14247487Spendry * Print host and volname of exported filesystem 14347487Spendry */ 14447487Spendry fprintf(af, "rhost:=%s", 14547487Spendry mp->m_dk->d_host->h_lochost ? 14647487Spendry mp->m_dk->d_host->h_lochost : 14747487Spendry mp->m_dk->d_host->h_hostname); 14847487Spendry fprintf(af, ";rfs:=%s", mp->m_exported->m_volname); 14947487Spendry /* 15047487Spendry * Now determine whether a sublink is required. 15147487Spendry */ 15247487Spendry if (exp_namelen < namelen || mvolnlen < volnlen) { 15347487Spendry char sublink[1024]; 15447487Spendry sublink[0] = '\0'; 15547487Spendry if (exp_namelen < namelen) { 15647487Spendry strcat(sublink, mp->m_name + exp_namelen + 1); 15747487Spendry if (mvolnlen < volnlen) 15847487Spendry strcat(sublink, "/"); 15947487Spendry } 16047487Spendry if (mvolnlen < volnlen) 16147487Spendry strcat(sublink, ap->a_volname + mvolnlen + 1); 16247487Spendry 16347487Spendry fprintf(af, ";sublink:=%s", sublink); 16447487Spendry } 16547487Spendry } 16647487Spendry fputc('\n', af); 16747487Spendry } else if (ap->a_symlink) { 16847487Spendry /* 16947487Spendry * A specific link. 17047487Spendry * 17147487Spendry * type:=link;fs:=whatever 17247487Spendry */ 17347487Spendry fprintf(af, "%s type:=link;fs:=%s\n", ap->a_name + sk, ap->a_symlink); 17447487Spendry } 17547487Spendry return errors; 17647487Spendry } 17747487Spendry 17847487Spendry /* 17947487Spendry * Write a single automount configuration file 18047487Spendry */ 18147487Spendry static int write_amount(q, def) 18247487Spendry qelem *q; 18347487Spendry char *def; 18447487Spendry { 18547487Spendry automount *ap; 18647487Spendry int errors = 0; 18747487Spendry int direct = 0; 18847487Spendry 18947487Spendry /* 19047487Spendry * Output all indirect maps 19147487Spendry */ 19247487Spendry ITER(ap, automount, q) { 19347487Spendry FILE *af; 19447487Spendry char *p; 19547487Spendry /* 19647487Spendry * If there is no a_mount node then this is really 19747487Spendry * a direct mount, so just keep a count and continue. 19847487Spendry * Direct mounts are output into a special file during 19947487Spendry * the second pass below. 20047487Spendry */ 20147487Spendry if (!ap->a_mount) { 20247487Spendry direct++; 20347487Spendry continue; 20447487Spendry } 20547487Spendry p = strrchr(ap->a_name, '/'); 20647487Spendry if (!p) p = ap->a_name; 20747487Spendry else p++; 20847487Spendry af = pref_open(mount_pref, p, gen_hdr, ap->a_name); 20947487Spendry if (af) { 21047487Spendry show_new(ap->a_name); 21147487Spendry fputs("/defaults ", af); 21247487Spendry if (*def) 21347487Spendry fprintf(af, "%s;", def); 21447487Spendry fputs("type:=nfs\n", af); 21547487Spendry errors += write_amount_info(af, ap, strlen(ap->a_name) + 1); 21647487Spendry errors += pref_close(af); 21747487Spendry } 21847487Spendry } 21947487Spendry 22047487Spendry /* 22147487Spendry * Output any direct map entries which were found during the 22247487Spendry * previous pass over the data. 22347487Spendry */ 22447487Spendry if (direct) { 22547487Spendry FILE *af = pref_open(mount_pref, "direct.map", info_hdr, "direct mount"); 22647487Spendry if (af) { 22747487Spendry show_new("direct mounts"); 22847487Spendry fputs("/defaults ", af); 22947487Spendry if (*def) 23047487Spendry fprintf(af, "%s;", def); 23147487Spendry fputs("type:=nfs\n", af); 23247487Spendry ITER(ap, automount, q) 23347487Spendry if (!ap->a_mount) 23447487Spendry errors += write_amount_info(af, ap, 1); 23547487Spendry errors += pref_close(af); 23647487Spendry } 23747487Spendry } 23847487Spendry 23947487Spendry return errors; 24047487Spendry } 24147487Spendry 24247487Spendry /* 24347487Spendry * Write all the needed automount configuration files 24447487Spendry */ 24547487Spendry write_atab(q) 24647487Spendry qelem *q; 24747487Spendry { 24847487Spendry int errors = 0; 24947487Spendry 25047487Spendry if (mount_pref) { 25147487Spendry auto_tree *tp; 25247487Spendry show_area_being_processed("write automount", ""); 25347487Spendry ITER(tp, auto_tree, q) 25447487Spendry errors += write_amount(tp->t_mount, tp->t_defaults); 25547487Spendry } 25647487Spendry 25747487Spendry return errors; 25847487Spendry } 259