1/*
2 * Copyright (c) 1997-2006 Erez Zadok
3 * Copyright (c) 1989 Jan-Simon Pendry
4 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
5 * Copyright (c) 1989 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry at Imperial College, London.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 *    must display the following acknowledgment:
21 *      This product includes software developed by the University of
22 *      California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 *    may be used to endorse or promote products derived from this software
25 *    without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 *
40 * File: am-utils/fsinfo/wr_fstab.c
41 *
42 */
43
44#ifdef HAVE_CONFIG_H
45# include <config.h>
46#endif /* HAVE_CONFIG_H */
47#include <am_defs.h>
48#include <fsi_data.h>
49#include <fsinfo.h>
50
51#define	GENERIC_OS_NAME "generic"
52
53/* forward definitions */
54static void write_aix1_dkfstab(FILE *ef, disk_fs *dp);
55static void write_aix1_dkrmount(FILE *ef, char *hn, fsmount *fp);
56static void write_aix3_dkfstab(FILE *ef, disk_fs *dp);
57static void write_aix3_dkrmount(FILE *ef, char *hn, fsmount *fp);
58static int  write_dkfstab(FILE *ef, qelem *q, void (*output) (FILE *, disk_fs *));
59static int write_dkrmount(FILE *ef, qelem *q, char *hn, void (*output) (FILE *, char *, fsmount *));
60static void write_generic_dkfstab(FILE *ef, disk_fs *dp);
61static void write_generic_dkrmount(FILE *ef, char *hn, fsmount *fp);
62static void write_ultrix_dkfstab(FILE *ef, disk_fs *dp);
63static void write_ultrix_dkrmount(FILE *ef, char *hn, fsmount *fp);
64
65/* ----------------------------------------------- */
66
67static struct os_fstab_type {
68  char *os_name;
69  void (*op_fstab) (FILE *ef, disk_fs *dp);
70  void (*op_mount) (FILE *ef, char *hn, fsmount *fp);
71} os_tabs[] = {
72
73  {
74    "aix1", write_aix1_dkfstab, write_aix1_dkrmount
75  },				/* AIX 1 */
76  {
77    "aix3", write_aix3_dkfstab, write_aix3_dkrmount
78  },				/* AIX 3 */
79  {
80    "generic", write_generic_dkfstab, write_generic_dkrmount
81  },				/* Generic */
82  {
83    "u2_0", write_ultrix_dkfstab, write_ultrix_dkrmount
84  },				/* Ultrix */
85  {
86    "u3_0", write_ultrix_dkfstab, write_ultrix_dkrmount
87  },				/* Ultrix */
88  {
89    "u4_0", write_ultrix_dkfstab, write_ultrix_dkrmount
90  },				/* Ultrix */
91  {
92    0, 0, 0
93  }
94};
95
96
97/* ---------- AIX 1 ------------------------------ */
98
99/*
100 * AIX 1 format
101 */
102static void
103write_aix1_dkfstab(FILE *ef, disk_fs *dp)
104{
105  char *hp = strdup(dp->d_host->h_hostname);
106  char *p = strchr(hp, '.');
107
108  if (p)
109    *p = '\0';
110
111  fprintf(ef, "\n%s:\n\tdev = %s\n\tvfs = %s\n\ttype = %s\n\tlog = %s\n\tvol = %s\n\topts = %s\n\tmount = true\n\tcheck = true\n\tfree = false\n",
112	  dp->d_mountpt,
113	  dp->d_dev,
114	  dp->d_fstype,
115	  dp->d_fstype,
116	  dp->d_log,
117	  dp->d_mountpt,
118	  dp->d_opts);
119  XFREE(hp);
120}
121
122
123static void
124write_aix1_dkrmount(FILE *ef, char *hn, fsmount *fp)
125{
126  char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname);
127  char *hp = strdup(h);
128  char *p = strchr(hp, '.');
129
130  if (p)
131    *p = '\0';
132  domain_strip(h, hn);
133  fprintf(ef, "\n%s:\n\tsite = %s\n\tdev = %s:%s\n\tvfs = %s\n\ttype = %s\n\tvol = %s\n\topts = %s\n\tmount = true\n\tcheck = true\n\tfree = false\n",
134	  fp->f_localname,
135	  hp,
136	  h,
137	  fp->f_volname,
138	  fp->f_fstype,
139	  fp->f_fstype,
140	  fp->f_localname,
141	  fp->f_opts);
142
143  XFREE(hp);
144  XFREE(h);
145}
146
147
148/* ---------- AIX 3 ------------------------------ */
149
150/*
151 * AIX 3 format
152 */
153static void
154write_aix3_dkfstab(FILE *ef, disk_fs *dp)
155{
156  if (STREQ(dp->d_fstype, "jfs") &&
157      NSTREQ(dp->d_dev, "/dev/", 5) &&
158      !dp->d_log)
159    error("aix 3 needs a log device for journalled filesystem (jfs) mounts");
160
161  fprintf(ef, "\n%s:\n\tdev = %s\n\tvfs = %s\n\ttype = %s\n\tlog = %s\n\tvol = %s\n\topts = %s\n\tmount = true\n\tcheck = true\n\tfree = false\n",
162	  dp->d_mountpt,
163	  dp->d_dev,
164	  dp->d_fstype,
165	  dp->d_fstype,
166	  dp->d_log,
167	  dp->d_mountpt,
168	  dp->d_opts);
169}
170
171
172static void
173write_aix3_dkrmount(FILE *ef, char *hn, fsmount *fp)
174{
175  char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname);
176
177  domain_strip(h, hn);
178  fprintf(ef, "\n%s:\n\tdev = %s:%s\n\tvfs = %s\n\ttype = %s\n\tvol = %s\n\topts = %s\n\tmount = true\n\tcheck = true\n\tfree = false\n",
179	  fp->f_localname,
180	  h,
181	  fp->f_volname,
182	  fp->f_fstype,
183	  fp->f_fstype,
184	  fp->f_localname,
185	  fp->f_opts);
186
187  XFREE(h);
188}
189
190
191/* ---------- Ultrix ----------------------------- */
192
193static void
194write_ultrix_dkfstab(FILE *ef, disk_fs *dp)
195{
196  fprintf(ef, "%s:%s:%s:%s:%d:%d\n",
197	  dp->d_dev,
198	  dp->d_mountpt,
199	  dp->d_fstype,
200	  dp->d_opts,
201	  dp->d_freq,
202	  dp->d_passno);
203}
204
205
206static void
207write_ultrix_dkrmount(FILE *ef, char *hn, fsmount *fp)
208{
209  char *h = strdup(fp->f_ref->m_dk->d_host->h_hostname);
210
211  domain_strip(h, hn);
212  fprintf(ef, "%s@%s:%s:%s:%s:0:0\n",
213	  fp->f_volname,
214	  h,
215	  fp->f_localname,
216	  fp->f_fstype,
217	  fp->f_opts);
218  XFREE(h);
219}
220
221
222/* ---------- Generic ---------------------------- */
223
224/*
225 * Generic (BSD, SunOS, HPUX) format
226 */
227static void
228write_generic_dkfstab(FILE *ef, disk_fs *dp)
229{
230  fprintf(ef, "%s %s %s %s %d %d\n",
231	  dp->d_dev,
232	  dp->d_mountpt,
233	  dp->d_fstype,
234	  dp->d_opts,
235	  dp->d_freq,
236	  dp->d_passno);
237}
238
239
240static void
241write_generic_dkrmount(FILE *ef, char *hn, fsmount *fp)
242{
243  char *h;
244
245  if (fp->f_ref) {
246    h = strdup(fp->f_ref->m_dk->d_host->h_hostname);
247  } else {
248    h = strdup(fp->f_from);
249  }
250  domain_strip(h, hn);
251  fprintf(ef, "%s:%s %s %s %s 0 0\n",
252	  h,
253	  fp->f_volname,
254	  fp->f_localname,
255	  fp->f_fstype,
256	  fp->f_opts);
257  XFREE(h);
258}
259
260
261static struct os_fstab_type *
262find_fstab_type(host *hp)
263{
264  struct os_fstab_type *op = 0;
265  char *os_name = 0;
266
267again:;
268  if (os_name == 0) {
269    if (ISSET(hp->h_mask, HF_OS))
270      os_name = hp->h_os;
271    else
272      os_name = GENERIC_OS_NAME;
273  }
274  for (op = os_tabs; op->os_name; op++)
275    if (STREQ(os_name, op->os_name))
276      return op;
277
278  os_name = GENERIC_OS_NAME;
279  goto again;
280}
281
282
283static int
284write_dkfstab(FILE *ef, qelem *q, void (*output) (FILE *, disk_fs *))
285{
286  int errors = 0;
287  disk_fs *dp;
288
289  ITER(dp, disk_fs, q)
290  if (!STREQ(dp->d_fstype, "export"))
291      (*output) (ef, dp);
292
293  return errors;
294}
295
296
297static int
298write_dkrmount(FILE *ef, qelem *q, char *hn, void (*output) (FILE *, char *, fsmount *))
299{
300  int errors = 0;
301  fsmount *fp;
302
303  ITER(fp, fsmount, q)
304    (*output) (ef, hn, fp);
305
306  return errors;
307}
308
309
310int
311write_fstab(qelem *q)
312{
313  int errors = 0;
314
315  if (fstab_pref) {
316    host *hp;
317
318    show_area_being_processed("write fstab", 4);
319    ITER(hp, host, q) {
320      if (hp->h_disk_fs || hp->h_mount) {
321	FILE *ef = pref_open(fstab_pref, hp->h_hostname, gen_hdr, hp->h_hostname);
322	if (ef) {
323	  struct os_fstab_type *op = find_fstab_type(hp);
324	  show_new(hp->h_hostname);
325	  if (hp->h_disk_fs)
326	    errors += write_dkfstab(ef, hp->h_disk_fs, op->op_fstab);
327	  else
328	    fsi_log("No local disk mounts on %s", hp->h_hostname);
329
330	  if (hp->h_mount)
331	    errors += write_dkrmount(ef, hp->h_mount, hp->h_hostname, op->op_mount);
332
333	  pref_close(ef);
334	}
335      } else {
336	error("no disk mounts on %s", hp->h_hostname);
337      }
338    }
339  }
340  return errors;
341}
342