138494Sobrien/*
2174294Sobrien * Copyright (c) 1997-2006 Erez Zadok
338494Sobrien * Copyright (c) 1989 Jan-Simon Pendry
438494Sobrien * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
538494Sobrien * Copyright (c) 1989 The Regents of the University of California.
638494Sobrien * All rights reserved.
738494Sobrien *
838494Sobrien * Redistribution and use in source and binary forms, with or without
938494Sobrien * modification, are permitted provided that the following conditions
1038494Sobrien * are met:
1138494Sobrien * 1. Redistributions of source code must retain the above copyright
1238494Sobrien *    notice, this list of conditions and the following disclaimer.
1338494Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1438494Sobrien *    notice, this list of conditions and the following disclaimer in the
1538494Sobrien *    documentation and/or other materials provided with the distribution.
1638494Sobrien * 3. All advertising materials mentioning features or use of this software
1742629Sobrien *    must display the following acknowledgment:
1838494Sobrien *      This product includes software developed by the University of
1938494Sobrien *      California, Berkeley and its contributors.
2038494Sobrien * 4. Neither the name of the University nor the names of its contributors
2138494Sobrien *    may be used to endorse or promote products derived from this software
2238494Sobrien *    without specific prior written permission.
2338494Sobrien *
2438494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2538494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2638494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2738494Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2838494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2938494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3038494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3138494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3238494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3338494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3438494Sobrien * SUCH DAMAGE.
3538494Sobrien *
3638494Sobrien *
37174294Sobrien * File: am-utils/fsinfo/fsi_util.c
3838494Sobrien *
3938494Sobrien */
4038494Sobrien
4138494Sobrien#ifdef HAVE_CONFIG_H
4238494Sobrien# include <config.h>
4338494Sobrien#endif /* HAVE_CONFIG_H */
4438494Sobrien#include <am_defs.h>
4538494Sobrien#include <fsi_data.h>
4638494Sobrien#include <fsinfo.h>
4738494Sobrien
4838494Sobrien/* static variables */
4938494Sobrienstatic int show_range = 10;
5038494Sobrienstatic int col = 0;
5138494Sobrienstatic int total_shown = 0;
5238494Sobrienstatic int total_mmm = 8;
5338494Sobrien
5438494Sobrien
5538494Sobrienstatic int
5638494Sobriencol_output(int len)
5738494Sobrien{
5838494Sobrien  int wrapped = 0;
5938494Sobrien
6038494Sobrien  col += len;
6138494Sobrien  if (col > 77) {
6238494Sobrien    fputc('\n', stdout);
6338494Sobrien    col = len;
6438494Sobrien    wrapped = 1;
6538494Sobrien  }
6638494Sobrien  return wrapped;
6738494Sobrien}
6838494Sobrien
6938494Sobrien
7038494Sobrienstatic void
7138494Sobrienshow_total(void)
7238494Sobrien{
7338494Sobrien  if (total_mmm != -show_range + 1) {
7438494Sobrien    char n[8];
7538494Sobrien    int len;
7638494Sobrien
7738494Sobrien    if (total_mmm < 0)
7838494Sobrien      fputc('*', stdout);
79174294Sobrien    xsnprintf(n, sizeof(n), "%d", total_shown);
8038494Sobrien    len = strlen(n);
8138494Sobrien    if (col_output(len))
8238494Sobrien      fputc(' ', stdout);
8338494Sobrien    fputs(n, stdout);
8438494Sobrien    fflush(stdout);
8538494Sobrien    total_mmm = -show_range;
8638494Sobrien  }
8738494Sobrien}
8838494Sobrien
8938494Sobrien
9038494Sobrienvoid
9138494Sobriencol_cleanup(int eoj)
9238494Sobrien{
9338494Sobrien  if (verbose < 0)
9438494Sobrien    return;
9538494Sobrien  if (eoj) {
9638494Sobrien    show_total();
9738494Sobrien    fputs(")]", stdout);
9838494Sobrien  }
9938494Sobrien  if (col) {
10038494Sobrien    fputc('\n', stdout);
10138494Sobrien    col = 0;
10238494Sobrien  }
10338494Sobrien}
10438494Sobrien
10538494Sobrien
10638494Sobrien/*
10738494Sobrien * Lots of ways of reporting errors...
10838494Sobrien */
10938494Sobrienvoid
11038494Sobrienerror(char *fmt, ...)
11138494Sobrien{
11238494Sobrien  va_list ap;
11338494Sobrien
11438494Sobrien  va_start(ap, fmt);
11538494Sobrien  col_cleanup(0);
11638494Sobrien  fprintf(stderr, "%s: Error, ", progname);
11782794Sobrien  vfprintf(stderr, fmt, ap);
11838494Sobrien  fputc('\n', stderr);
11938494Sobrien  errors++;
12038494Sobrien  va_end(ap);
12138494Sobrien}
12238494Sobrien
12338494Sobrien
12438494Sobrienvoid
12538494Sobrienlerror(ioloc *l, char *fmt, ...)
12638494Sobrien{
12738494Sobrien  va_list ap;
12838494Sobrien
12938494Sobrien  va_start(ap, fmt);
13038494Sobrien  col_cleanup(0);
13138494Sobrien  fprintf(stderr, "%s:%d: ", l->i_file, l->i_line);
13282794Sobrien  vfprintf(stderr, fmt, ap);
13338494Sobrien  fputc('\n', stderr);
13438494Sobrien  errors++;
13538494Sobrien  va_end(ap);
13638494Sobrien}
13738494Sobrien
13838494Sobrien
13938494Sobrienvoid
14038494Sobrienlwarning(ioloc *l, char *fmt, ...)
14138494Sobrien{
14238494Sobrien  va_list ap;
14338494Sobrien
14438494Sobrien  va_start(ap, fmt);
14538494Sobrien  col_cleanup(0);
14638494Sobrien  fprintf(stderr, "%s:%d: ", l->i_file, l->i_line);
14782794Sobrien  vfprintf(stderr, fmt, ap);
14838494Sobrien  fputc('\n', stderr);
14938494Sobrien  va_end(ap);
15038494Sobrien}
15138494Sobrien
15238494Sobrien
15338494Sobrienvoid
15438494Sobrienfatal(char *fmt, ...)
15538494Sobrien{
15638494Sobrien  va_list ap;
15738494Sobrien
15838494Sobrien  va_start(ap, fmt);
15938494Sobrien  col_cleanup(1);
16038494Sobrien  fprintf(stderr, "%s: Fatal, ", progname);
16182794Sobrien  vfprintf(stderr, fmt, ap);
16238494Sobrien  fputc('\n', stderr);
16338494Sobrien  va_end(ap);
16438494Sobrien  exit(1);
16538494Sobrien}
16638494Sobrien
16738494Sobrien
16838494Sobrien/*
16938494Sobrien * Debug log
17038494Sobrien */
17138494Sobrienvoid
172119679Smbrfsi_log(char *fmt, ...)
17338494Sobrien{
17438494Sobrien  va_list ap;
17538494Sobrien
17638494Sobrien  if (verbose > 0) {
17738494Sobrien    va_start(ap, fmt);
17838494Sobrien    fputc('#', stdout);
17938494Sobrien    fprintf(stdout, "%s: ", progname);
18082794Sobrien    vfprintf(stdout, fmt, ap);
18138494Sobrien    putc('\n', stdout);
18238494Sobrien    va_end(ap);
18338494Sobrien  }
18438494Sobrien}
18538494Sobrien
18638494Sobrien
18738494Sobrienvoid
18838494Sobrieninfo_hdr(FILE *ef, char *info)
18938494Sobrien{
19038494Sobrien  fprintf(ef, "# *** NOTE: This file contains %s info\n", info);
19138494Sobrien}
19238494Sobrien
19338494Sobrien
19438494Sobrienvoid
19538494Sobriengen_hdr(FILE *ef, char *hn)
19638494Sobrien{
19738494Sobrien  fprintf(ef, "# *** NOTE: Only for use on %s\n", hn);
19838494Sobrien}
19938494Sobrien
20038494Sobrien
20138494Sobrienstatic void
20238494Sobrienmake_banner(FILE *fp)
20338494Sobrien{
20438494Sobrien  time_t t = time((time_t *) 0);
20538494Sobrien  char *cp = ctime(&t);
20638494Sobrien
20738494Sobrien  fprintf(fp,
20838494Sobrien	  "\
20938494Sobrien# *** This file was automatically generated -- DO NOT EDIT HERE ***\n\
21038494Sobrien# \"%s\" run by %s@%s on %s\
21138494Sobrien#\n\
21238494Sobrien",
21338494Sobrien	  progname, username, hostname, cp);
21438494Sobrien}
21538494Sobrien
21638494Sobrien
21738494Sobrienvoid
21838494Sobrienshow_new(char *msg)
21938494Sobrien{
22038494Sobrien  if (verbose < 0)
22138494Sobrien    return;
22238494Sobrien
22338494Sobrien  total_shown++;
22438494Sobrien  if (total_mmm > show_range) {
22538494Sobrien    show_total();
22638494Sobrien  } else if (total_mmm == 0) {
22738494Sobrien    fputc('*', stdout);
22838494Sobrien    fflush(stdout);
22938494Sobrien    col += 1;
23038494Sobrien  }
23138494Sobrien  total_mmm++;
23238494Sobrien}
23338494Sobrien
23438494Sobrien
23538494Sobrienvoid
23638494Sobrienshow_area_being_processed(char *area, int n)
23738494Sobrien{
23838494Sobrien  static char *last_area = 0;
23938494Sobrien
24038494Sobrien  if (verbose < 0)
24138494Sobrien    return;
24238494Sobrien  if (last_area) {
24338494Sobrien    if (total_shown)
24438494Sobrien      show_total();
24538494Sobrien    fputs(")", stdout);
24638494Sobrien    col += 1;
24738494Sobrien  }
24838494Sobrien
24938494Sobrien  if (!last_area || !STREQ(area, last_area)) {
25038494Sobrien    if (last_area) {
25138494Sobrien      col_cleanup(0);
25238494Sobrien      total_shown = 0;
25338494Sobrien      total_mmm = show_range + 1;
25438494Sobrien    }
25538494Sobrien    (void) col_output(strlen(area) + 2);
25638494Sobrien    fprintf(stdout, "[%s", area);
25738494Sobrien    last_area = area;
25838494Sobrien  }
25938494Sobrien
26038494Sobrien  fputs(" (", stdout);
26138494Sobrien  col += 2;
26238494Sobrien  show_range = n;
26338494Sobrien  total_mmm = n + 1;
26438494Sobrien
26538494Sobrien  fflush(stdout);
26638494Sobrien}
26738494Sobrien
26838494Sobrien
26938494Sobrien/*
27038494Sobrien * Open a file with the given prefix and name
27138494Sobrien */
27238494SobrienFILE *
27338494Sobrienpref_open(char *pref, char *hn, void (*hdr) (FILE *, char *), char *arg)
27438494Sobrien{
27538494Sobrien  char p[MAXPATHLEN];
27638494Sobrien  FILE *ef;
27738494Sobrien
278174294Sobrien  xsnprintf(p, sizeof(p), "%s%s", pref, hn);
279119679Smbr  fsi_log("Writing %s info for %s to %s", pref, hn, p);
28038494Sobrien  ef = fopen(p, "w");
28138494Sobrien  if (ef) {
28238494Sobrien    (*hdr) (ef, arg);
28338494Sobrien    make_banner(ef);
28438494Sobrien  } else {
28538494Sobrien    error("can't open %s for writing", p);
28638494Sobrien  }
28738494Sobrien
28838494Sobrien  return ef;
28938494Sobrien}
29038494Sobrien
29138494Sobrien
29238494Sobrienint
29338494Sobrienpref_close(FILE *fp)
29438494Sobrien{
29538494Sobrien  return fclose(fp) == 0;
29638494Sobrien}
29738494Sobrien
29838494Sobrien
29938494Sobrien/*
30038494Sobrien * Determine where Amd would automount the host/volname pair
30138494Sobrien */
30238494Sobrienvoid
303174294Sobriencompute_automount_point(char *buf, size_t l, host *hp, char *vn)
30438494Sobrien{
305174294Sobrien  xsnprintf(buf, l, "%s/%s%s", autodir, hp->h_lochost, vn);
30638494Sobrien}
30738494Sobrien
30838494Sobrien
30938494Sobrien/*
31038494Sobrien * Data constructors..
31138494Sobrien */
31238494Sobrienautomount *
31338494Sobriennew_automount(char *name)
31438494Sobrien{
31538494Sobrien  automount *ap = CALLOC(struct automount);
31638494Sobrien
31738494Sobrien  ap->a_ioloc = current_location();
31838494Sobrien  ap->a_name = name;
31938494Sobrien  ap->a_volname = 0;
32038494Sobrien  ap->a_mount = 0;
32138494Sobrien  ap->a_opts = 0;
32238494Sobrien  show_new("automount");
32338494Sobrien  return ap;
32438494Sobrien}
32538494Sobrien
32638494Sobrien
32738494Sobrienauto_tree *
32838494Sobriennew_auto_tree(char *def, qelem *ap)
32938494Sobrien{
33038494Sobrien  auto_tree *tp = CALLOC(struct auto_tree);
33138494Sobrien
33238494Sobrien  tp->t_ioloc = current_location();
33338494Sobrien  tp->t_defaults = def;
33438494Sobrien  tp->t_mount = ap;
33538494Sobrien  show_new("auto_tree");
33638494Sobrien  return tp;
33738494Sobrien}
33838494Sobrien
33938494Sobrien
34038494Sobrienhost *
34138494Sobriennew_host(void)
34238494Sobrien{
34338494Sobrien  host *hp = CALLOC(struct host);
34438494Sobrien
34538494Sobrien  hp->h_ioloc = current_location();
34638494Sobrien  hp->h_mask = 0;
34738494Sobrien  show_new("host");
34838494Sobrien  return hp;
34938494Sobrien}
35038494Sobrien
35138494Sobrien
35238494Sobrienvoid
35338494Sobrienset_host(host *hp, int k, char *v)
35438494Sobrien{
35538494Sobrien  int m = 1 << k;
35638494Sobrien
35738494Sobrien  if (hp->h_mask & m) {
35838494Sobrien    yyerror("host field \"%s\" already set", host_strings[k]);
35938494Sobrien    return;
36038494Sobrien  }
36138494Sobrien  hp->h_mask |= m;
36238494Sobrien
36338494Sobrien  switch (k) {
36438494Sobrien
36538494Sobrien  case HF_HOST:{
36638494Sobrien      char *p = strdup(v);
36738494Sobrien      dict_ent *de = dict_locate(dict_of_hosts, v);
36838494Sobrien
36938494Sobrien      if (de)
37038494Sobrien	yyerror("duplicate host %s!", v);
37138494Sobrien      else
37238494Sobrien	dict_add(dict_of_hosts, v, (char *) hp);
37338494Sobrien      hp->h_hostname = v;
37438494Sobrien      domain_strip(p, hostname);
37538494Sobrien      if (strchr(p, '.') != 0)
37638494Sobrien	XFREE(p);
37738494Sobrien      else
37838494Sobrien	hp->h_lochost = p;
37938494Sobrien    }
38038494Sobrien    break;
38138494Sobrien
38238494Sobrien  case HF_CONFIG:{
38338494Sobrien      qelem *q;
38438494Sobrien      qelem *vq = (qelem *) v;
38538494Sobrien
38638494Sobrien      hp->h_mask &= ~m;
38738494Sobrien      if (hp->h_config)
38838494Sobrien	q = hp->h_config;
38938494Sobrien      else
39038494Sobrien	q = hp->h_config = new_que();
39138494Sobrien      ins_que(vq, q->q_back);
39238494Sobrien    }
39338494Sobrien    break;
39438494Sobrien
39538494Sobrien  case HF_ETHER:{
39638494Sobrien      qelem *q;
39738494Sobrien      qelem *vq = (qelem *) v;
39838494Sobrien
39938494Sobrien      hp->h_mask &= ~m;
40038494Sobrien      if (hp->h_ether)
40138494Sobrien	q = hp->h_ether;
40238494Sobrien      else
40338494Sobrien	q = hp->h_ether = new_que();
40438494Sobrien      ins_que(vq, q->q_back);
40538494Sobrien    }
40638494Sobrien    break;
40738494Sobrien
40838494Sobrien  case HF_ARCH:
40938494Sobrien    hp->h_arch = v;
41038494Sobrien    break;
41138494Sobrien
41238494Sobrien  case HF_OS:
41338494Sobrien    hp->h_os = v;
41438494Sobrien    break;
41538494Sobrien
41638494Sobrien  case HF_CLUSTER:
41738494Sobrien    hp->h_cluster = v;
41838494Sobrien    break;
41938494Sobrien
42038494Sobrien  default:
42138494Sobrien    abort();
42238494Sobrien    break;
42338494Sobrien  }
42438494Sobrien}
42538494Sobrien
42638494Sobrien
42738494Sobrienether_if *
42838494Sobriennew_ether_if(void)
42938494Sobrien{
43038494Sobrien  ether_if *ep = CALLOC(struct ether_if);
43138494Sobrien
43238494Sobrien  ep->e_mask = 0;
43338494Sobrien  ep->e_ioloc = current_location();
43438494Sobrien  show_new("ether_if");
43538494Sobrien  return ep;
43638494Sobrien}
43738494Sobrien
43838494Sobrien
43938494Sobrienvoid
44038494Sobrienset_ether_if(ether_if *ep, int k, char *v)
44138494Sobrien{
44238494Sobrien  int m = 1 << k;
44338494Sobrien
44438494Sobrien  if (ep->e_mask & m) {
44538494Sobrien    yyerror("netif field \"%s\" already set", ether_if_strings[k]);
44638494Sobrien    return;
44738494Sobrien  }
44838494Sobrien  ep->e_mask |= m;
44938494Sobrien
45038494Sobrien  switch (k) {
45138494Sobrien
45238494Sobrien  case EF_INADDR:{
45338494Sobrien      ep->e_inaddr.s_addr = inet_addr(v);
454174294Sobrien      if ((int) ep->e_inaddr.s_addr == (int) INADDR_NONE)
45538494Sobrien	yyerror("malformed IP dotted quad: %s", v);
45638494Sobrien      XFREE(v);
45738494Sobrien    }
45838494Sobrien    break;
45938494Sobrien
46038494Sobrien  case EF_NETMASK:{
46138494Sobrien      u_long nm = 0;
46238494Sobrien
46338494Sobrien      if ((sscanf(v, "0x%lx", &nm) == 1 || sscanf(v, "%lx", &nm) == 1) && nm != 0)
46438494Sobrien	ep->e_netmask = htonl(nm);
46538494Sobrien      else
46638494Sobrien	yyerror("malformed netmask: %s", v);
46738494Sobrien      XFREE(v);
46838494Sobrien    }
46938494Sobrien    break;
47038494Sobrien
47138494Sobrien  case EF_HWADDR:
47238494Sobrien    ep->e_hwaddr = v;
47338494Sobrien    break;
47438494Sobrien
47538494Sobrien  default:
47638494Sobrien    abort();
47738494Sobrien    break;
47838494Sobrien  }
47938494Sobrien}
48038494Sobrien
48138494Sobrien
48238494Sobrienvoid
48338494Sobrienset_disk_fs(disk_fs *dp, int k, char *v)
48438494Sobrien{
48538494Sobrien  int m = 1 << k;
48638494Sobrien
48738494Sobrien  if (dp->d_mask & m) {
48838494Sobrien    yyerror("fs field \"%s\" already set", disk_fs_strings[k]);
48938494Sobrien    return;
49038494Sobrien  }
49138494Sobrien  dp->d_mask |= m;
49238494Sobrien
49338494Sobrien  switch (k) {
49438494Sobrien
49538494Sobrien  case DF_FSTYPE:
49638494Sobrien    dp->d_fstype = v;
49738494Sobrien    break;
49838494Sobrien
49938494Sobrien  case DF_OPTS:
50038494Sobrien    dp->d_opts = v;
50138494Sobrien    break;
50238494Sobrien
50338494Sobrien  case DF_DUMPSET:
50438494Sobrien    dp->d_dumpset = v;
50538494Sobrien    break;
50638494Sobrien
50738494Sobrien  case DF_LOG:
50838494Sobrien    dp->d_log = v;
50938494Sobrien    break;
51038494Sobrien
51138494Sobrien  case DF_PASSNO:
51238494Sobrien    dp->d_passno = atoi(v);
51338494Sobrien    XFREE(v);
51438494Sobrien    break;
51538494Sobrien
51638494Sobrien  case DF_FREQ:
51738494Sobrien    dp->d_freq = atoi(v);
51838494Sobrien    XFREE(v);
51938494Sobrien    break;
52038494Sobrien
52138494Sobrien  case DF_MOUNT:
52238494Sobrien    dp->d_mount = &((fsi_mount *) v)->m_q;
52338494Sobrien    break;
52438494Sobrien
52538494Sobrien  default:
52638494Sobrien    abort();
52738494Sobrien    break;
52838494Sobrien  }
52938494Sobrien}
53038494Sobrien
53138494Sobrien
53238494Sobriendisk_fs *
53338494Sobriennew_disk_fs(void)
53438494Sobrien{
53538494Sobrien  disk_fs *dp = CALLOC(struct disk_fs);
53638494Sobrien
53738494Sobrien  dp->d_ioloc = current_location();
53838494Sobrien  show_new("disk_fs");
53938494Sobrien  return dp;
54038494Sobrien}
54138494Sobrien
54238494Sobrien
54338494Sobrienvoid
54438494Sobrienset_mount(fsi_mount *mp, int k, char *v)
54538494Sobrien{
54638494Sobrien  int m = 1 << k;
54738494Sobrien
54838494Sobrien  if (mp->m_mask & m) {
54938494Sobrien    yyerror("mount tree field \"%s\" already set", mount_strings[k]);
55038494Sobrien    return;
55138494Sobrien  }
55238494Sobrien  mp->m_mask |= m;
55338494Sobrien
55438494Sobrien  switch (k) {
55538494Sobrien
55638494Sobrien  case DM_VOLNAME:
55738494Sobrien    dict_add(dict_of_volnames, v, (char *) mp);
55838494Sobrien    mp->m_volname = v;
55938494Sobrien    break;
56038494Sobrien
56138494Sobrien  case DM_EXPORTFS:
56238494Sobrien    mp->m_exportfs = v;
56338494Sobrien    break;
56438494Sobrien
56538494Sobrien  case DM_SEL:
56638494Sobrien    mp->m_sel = v;
56738494Sobrien    break;
56838494Sobrien
56938494Sobrien  default:
57038494Sobrien    abort();
57138494Sobrien    break;
57238494Sobrien  }
57338494Sobrien}
57438494Sobrien
57538494Sobrien
57638494Sobrienfsi_mount *
57738494Sobriennew_mount(void)
57838494Sobrien{
57938494Sobrien  fsi_mount *fp = CALLOC(struct fsi_mount);
58038494Sobrien
58138494Sobrien  fp->m_ioloc = current_location();
58238494Sobrien  show_new("mount");
58338494Sobrien  return fp;
58438494Sobrien}
58538494Sobrien
58638494Sobrien
58738494Sobrienvoid
58838494Sobrienset_fsmount(fsmount *fp, int k, char *v)
58938494Sobrien{
59038494Sobrien  int m = 1 << k;
59138494Sobrien
59238494Sobrien  if (fp->f_mask & m) {
59338494Sobrien    yyerror("mount field \"%s\" already set", fsmount_strings[k]);
59438494Sobrien    return;
59538494Sobrien  }
59638494Sobrien  fp->f_mask |= m;
59738494Sobrien
59838494Sobrien  switch (k) {
59938494Sobrien
60038494Sobrien  case FM_LOCALNAME:
60138494Sobrien    fp->f_localname = v;
60238494Sobrien    break;
60338494Sobrien
60438494Sobrien  case FM_VOLNAME:
60538494Sobrien    fp->f_volname = v;
60638494Sobrien    break;
60738494Sobrien
60838494Sobrien  case FM_FSTYPE:
60938494Sobrien    fp->f_fstype = v;
61038494Sobrien    break;
61138494Sobrien
61238494Sobrien  case FM_OPTS:
61338494Sobrien    fp->f_opts = v;
61438494Sobrien    break;
61538494Sobrien
61638494Sobrien  case FM_FROM:
61738494Sobrien    fp->f_from = v;
61838494Sobrien    break;
61938494Sobrien
62038494Sobrien  case FM_DIRECT:
62138494Sobrien    break;
62238494Sobrien
62338494Sobrien  default:
62438494Sobrien    abort();
62538494Sobrien    break;
62638494Sobrien  }
62738494Sobrien}
62838494Sobrien
62938494Sobrien
63038494Sobrienfsmount *
63138494Sobriennew_fsmount(void)
63238494Sobrien{
63338494Sobrien  fsmount *fp = CALLOC(struct fsmount);
63438494Sobrien
63538494Sobrien  fp->f_ioloc = current_location();
63638494Sobrien  show_new("fsmount");
63738494Sobrien  return fp;
63838494Sobrien}
63938494Sobrien
64038494Sobrien
64138494Sobrienvoid
64238494Sobrieninit_que(qelem *q)
64338494Sobrien{
64438494Sobrien  q->q_forw = q->q_back = q;
64538494Sobrien}
64638494Sobrien
64738494Sobrien
64838494Sobrienqelem *
64938494Sobriennew_que(void)
65038494Sobrien{
65138494Sobrien  qelem *q = CALLOC(qelem);
65238494Sobrien
65338494Sobrien  init_que(q);
65438494Sobrien  return q;
65538494Sobrien}
65638494Sobrien
65738494Sobrien
65838494Sobrienvoid
65938494Sobrienins_que(qelem *elem, qelem *pred)
66038494Sobrien{
66138494Sobrien  qelem *p;
66238494Sobrien
66338494Sobrien  p = pred->q_forw;
66438494Sobrien  elem->q_back = pred;
66538494Sobrien  elem->q_forw = p;
66638494Sobrien  pred->q_forw = elem;
66738494Sobrien  p->q_back = elem;
66838494Sobrien}
66938494Sobrien
67038494Sobrien
67138494Sobrienvoid
67238494Sobrienrem_que(qelem *elem)
67338494Sobrien{
67438494Sobrien  qelem *p, *p2;
67538494Sobrien
67638494Sobrien  p = elem->q_forw;
67738494Sobrien  p2 = elem->q_back;
67838494Sobrien
67938494Sobrien  p2->q_forw = p;
68038494Sobrien  p->q_back = p2;
68138494Sobrien}
682