WvStreams
unifstreegen.cc
1 #include "uniconfgen.h"
2 #include "unimountgen.h"
3 #include "wvmoniker.h"
4 #include "wvlinkerhack.h"
5 #include "wvlog.h"
6 
7 #include "unifiltergen.h"
8 
10 {
11  WvString dir;
12  UniMountGen *mount;
13  IUniConfGen *treegen;
14  WvLog log;
15 
16 public:
18  : UniFilterGen(mount = new UniMountGen), dir(_dir),
19  log(WvString("AutoMount '%s'", dir), WvLog::Info)
20  {
21  log("Starting.\n");
22  mount->mount("/", WvString("readonly:fs:%s", dir), true);
23  treegen = mount->whichmount("/", NULL);
24  }
25 
26  virtual ~UniAutoMountGen()
27  {
28  log("Stopping.\n");
29  }
30 
31  virtual bool keymap(const UniConfKey &key, UniConfKey &mapped_key)
32  {
33  automount(key);
34  return UniFilterGen::keymap(key, mapped_key);
35  }
36 
37  void automount(const UniConfKey &key)
38  {
39  IUniConfGen *parent = mount->whichmount(key, NULL);
40  if (parent && parent != treegen && parent->haschildren("/"))
41  return; // don't bother; already mounted a parent
42 
43  log("Automount for '%s'\n", key);
44 
45  for (int count = key.numsegments(); count >= 0; count--)
46  {
47  UniConfKey k(key.first(count));
48  if (mount->ismountpoint(k))
49  {
50  log("Key '%s' already mounted.\n", k);
51  return; // already mounted
52  }
53 
54  WvString filename("%s/%s", dir, k);
55  log("Filename is '%s'\n", filename);
56  mount->mount(k, WvString("ini:%s", filename), true);
57  log("Key '%s' newly mounted.\n", k);
58  return; // newly mounted
59  }
60 
61  // just plain not found
62  log("Key '%s' not found.\n", key);
63  }
64 
65  virtual Iter *recursiveiterator(const UniConfKey &key)
66  {
67  // don't try to optimize this like UniMountGen does, because we're
68  // going to mount things *as* we iterate through them, not sooner.
69  // Use the default UniConfGen implementation, which just recursively
70  // calls iterator().
72  }
73 };
74 
75 
76 WV_LINK(UniFsTreeGen);
77 
78 
79 static IUniConfGen *creator(WvStringParm s, IObject *)
80 {
81  return new UniAutoMountGen(s);
82 }
83 
84 WvMoniker<IUniConfGen> UniFsTreeGenMoniker("fstree", creator);
85 
86