xref: /csrg-svn/usr.sbin/amd/fsinfo/wr_atab.c (revision 47487)
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