4 * Copyright (c) 1997-2009 Erez Zadok
5 * Copyright (c) 1989 Jan-Simon Pendry
6 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
7 * Copyright (c) 1989 The Regents of the University of California.
10 * This code is derived from software contributed to Berkeley by
11 * Jan-Simon Pendry at Imperial College, London.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgment:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 * File: am-utils/fsinfo/wr_atab.c
48 #endif /* HAVE_CONFIG_H */
55 * Write a sequence of automount mount map entries
58 write_amount_info(FILE *af
, automount
*ap
, u_int sk
)
65 * This can also be a top-level directory, in which
66 * case the type:=auto is not wanted...
68 * type:=auto;fs:=${map};pref:=whatever/
71 if (strlen(ap
->a_name
) > sk
) {
72 fprintf(af
, "%s type:=auto;fs:=${map};pref:=%s/\n",
73 ap
->a_name
+ sk
, ap
->a_name
+ sk
);
75 ITER(ap2
, automount
, ap
->a_mount
)
76 errors
+= write_amount_info(af
, ap2
, sk
);
77 } else if (ap
->a_hardwiredfs
) {
80 * A hardwired filesystem "hostname:path"
81 * rhost:=hostname;rfs:=path
83 char *key
= ap
->a_name
+ sk
;
84 char *hostname
= ap
->a_hardwiredfs
;
85 char *path
= strrchr(hostname
, (int) ':');
88 fprintf(stderr
, "%s: %s not an NFS filesystem\n", ap
->a_name
, ap
->a_hardwiredfs
);
98 fprintf(af
, " rhost:=%s", hostname
);
99 fprintf(af
, ";rfs:=%s", path
);
100 if (ap
->a_opts
&& !STREQ(ap
->a_opts
, "")) {
101 fprintf(af
, ";%s", ap
->a_opts
);
107 } else if (ap
->a_mounted
) {
110 * A mounted partition
111 * type:=link [ link entries ] type:=nfs [ nfs entries ]
114 dict_ent
*de
= ap
->a_mounted
;
115 int done_type_link
= 0;
116 char *key
= ap
->a_name
+ sk
;
124 * First output any Link locations that would not
125 * otherwise be correctly mounted. These refer
126 * to filesystem which are not mounted in the same
127 * place which the automounter would use.
129 ITER(dd
, dict_data
, &de
->de_q
) {
130 fsi_mount
*mp
= (fsi_mount
*) dd
->dd_data
;
132 * If the mount point and the exported volname are the
133 * same then this filesystem will be recognized by
134 * the restart code - so we don't need to put out a
135 * special rule for it.
137 if (mp
->m_dk
->d_host
->h_lochost
) {
139 compute_automount_point(amountpt
, sizeof(amountpt
),
140 mp
->m_dk
->d_host
, mp
->m_exported
->m_volname
);
141 if (!STREQ(mp
->m_dk
->d_mountpt
, amountpt
)) {
143 * ap->a_volname is the name of the aliased volume
144 * mp->m_name is the mount point of the filesystem
145 * mp->m_volname is the volume name of the filesystems
149 * Find length of key and volume names
151 int avlen
= strlen(ap
->a_volname
);
152 int mnlen
= strlen(mp
->m_volname
);
155 * Make sure a -type:=link is output once
157 if (!done_type_link
) {
159 fputs(" -type:=link", af
);
163 * Output a selector for the hostname,
164 * the device from which to mount and
165 * where to mount. This will correspond
166 * to the values output for the fstab.
168 if (mp
->m_dk
->d_host
->h_lochost
)
169 fprintf(af
, " host==%s", mp
->m_dk
->d_host
->h_lochost
);
171 fprintf(af
, " hostd==%s", mp
->m_dk
->d_host
->h_hostname
);
172 fprintf(af
, ";fs:=%s", mp
->m_name
);
175 * ... and a sublink if needed
178 char *sublink
= ap
->a_volname
+ mnlen
+ 1;
179 fprintf(af
, "/%s", sublink
);
187 * Next do the NFS locations
192 ITER(dd
, dict_data
, &de
->de_q
) {
193 fsi_mount
*mp
= (fsi_mount
*) dd
->dd_data
;
194 int namelen
= mp
->m_name_len
;
195 int exp_namelen
= mp
->m_exported
->m_name_len
;
196 int volnlen
= strlen(ap
->a_volname
);
197 int mvolnlen
= strlen(mp
->m_volname
);
202 * Output any selectors
205 fprintf(af
, "%s;", mp
->m_sel
);
208 * Print host and volname of exported filesystem
210 fprintf(af
, "rhost:=%s",
211 mp
->m_dk
->d_host
->h_lochost
?
212 mp
->m_dk
->d_host
->h_lochost
:
213 mp
->m_dk
->d_host
->h_hostname
);
214 fprintf(af
, ";rfs:=%s", mp
->m_exported
->m_volname
);
215 if (ap
->a_opts
&& !STREQ(ap
->a_opts
, "")) {
216 fprintf(af
, ";%s", ap
->a_opts
);
220 * Now determine whether a sublink is required.
222 if (exp_namelen
< namelen
|| mvolnlen
< volnlen
) {
225 if (exp_namelen
< namelen
) {
226 xstrlcat(sublink
, mp
->m_name
+ exp_namelen
+ 1, sizeof(sublink
));
227 if (mvolnlen
< volnlen
)
228 xstrlcat(sublink
, "/", sizeof(sublink
));
230 if (mvolnlen
< volnlen
)
231 xstrlcat(sublink
, ap
->a_volname
+ mvolnlen
+ 1, sizeof(sublink
));
233 fprintf(af
, ";sublink:=%s", sublink
);
237 } else if (ap
->a_symlink
) {
242 * type:=link;fs:=whatever
244 fprintf(af
, "%s type:=link;fs:=%s\n", ap
->a_name
+ sk
, ap
->a_symlink
);
252 * Write a single automount configuration file
255 write_amount( qelem
*q
, char *def
)
262 * Output all indirect maps
264 ITER(ap
, automount
, q
) {
269 * If there is no a_mount node then this is really
270 * a direct mount, so just keep a count and continue.
271 * Direct mounts are output into a special file during
272 * the second pass below.
279 p
= strrchr(ap
->a_name
, '/');
285 af
= pref_open(mount_pref
, p
, gen_hdr
, ap
->a_name
);
287 show_new(ap
->a_name
);
288 fputs("/defaults ", af
);
290 fprintf(af
, "%s;", def
);
291 fputs("type:=nfs\n", af
);
292 errors
+= write_amount_info(af
, ap
, strlen(ap
->a_name
) + 1);
293 errors
+= pref_close(af
);
298 * Output any direct map entries which were found during the
299 * previous pass over the data.
302 FILE *af
= pref_open(mount_pref
, "direct.map", info_hdr
, "direct mount");
305 show_new("direct mounts");
306 fputs("/defaults ", af
);
308 fprintf(af
, "%s;", def
);
309 fputs("type:=nfs\n", af
);
310 ITER(ap
, automount
, q
)
312 errors
+= write_amount_info(af
, ap
, 1);
313 errors
+= pref_close(af
);
321 * Write all the needed automount configuration files
330 show_area_being_processed("write automount", 5);
331 ITER(tp
, auto_tree
, q
)
332 errors
+= write_amount(tp
->t_mount
, tp
->t_defaults
);