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