Fix several warnings that appear in gcc 4.3.2.
[wvstreams.git] / uniconf / unifilesystemgen.cc
blobe95a1cb875cabcab20a3e7ca85eefed598c677e7
1 #include "unifilesystemgen.h"
2 #include "wvfile.h"
3 #include "wvdiriter.h"
4 #include "wvfileutils.h"
5 #include "wvmoniker.h"
6 #include "wvlinkerhack.h"
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <unistd.h>
10 #include <fcntl.h>
12 WV_LINK(UniFileSystemGen);
15 static IUniConfGen *creator(WvStringParm s, IObject *)
17 return new UniFileSystemGen(s, 0777);
20 WvMoniker<IUniConfGen> UniFileSystemGenMoniker("fs", creator);
23 UniFileSystemGen::UniFileSystemGen(WvStringParm _dir, mode_t _mode)
24 : dir(_dir), mode(_mode)
29 static bool key_safe(const UniConfKey &key)
31 UniConfKey::Iter i(key);
32 for (i.rewind(); i.next(); )
34 if (*i == "." || *i == ".." || *i == "")
35 return false; // unsafe key segments
38 // otherwise a safe filename
39 return true;
43 WvString UniFileSystemGen::get(const UniConfKey &key)
45 WvString null;
47 if (!key_safe(key))
48 return null;
50 WvString path("%s/%s", dir, key);
52 // WARNING: this code depends on the ability to open() a directory
53 // as long as we don't read it, because we want to fstat() it after.
54 WvFile file(path, O_RDONLY);
55 if (!file.isok())
56 return null; // unreadable; pretend it doesn't exist
58 struct stat st;
59 if (fstat(file.getrfd(), &st) < 0)
60 return null; // openable but can't stat? That's odd.
62 if (S_ISREG(st.st_mode))
64 WvDynBuf buf;
65 while (file.isok())
66 file.read(buf, 4096);
67 if (file.geterr())
68 return null;
69 else
70 return buf.getstr();
72 else
73 return ""; // exists, but pretend it's an empty file
77 void UniFileSystemGen::set(const UniConfKey &key, WvStringParm value)
79 if (!key_safe(key))
80 return;
82 WvString base("%s/%s", dir, key.removelast(1));
83 WvString path("%s/%s", dir, key);
85 mkdirp(base, mode);
87 if (value.isnull())
88 rm_rf(path);
89 else
91 WvFile file(path, O_WRONLY|O_CREAT|O_TRUNC, mode & 0666);
92 file.write(value);
97 void UniFileSystemGen::setv(const UniConfPairList &pairs)
99 setv_naive(pairs);
103 class UniFileSystemGenIter : public UniConfGen::Iter
105 private:
106 UniFileSystemGen *gen;
107 WvDirIter i;
108 UniConfKey rel;
110 public:
111 UniFileSystemGenIter(UniFileSystemGen *_gen, WvStringParm path,
112 const UniConfKey &_rel)
113 : gen(_gen), i(path, false), rel(_rel)
116 ~UniFileSystemGenIter()
119 void rewind()
120 { i.rewind(); }
122 bool next()
123 { return i.next(); }
125 UniConfKey key() const
126 { return i->relname; }
128 WvString value() const
129 { return gen->get(WvString("%s/%s", rel, i->relname)); }
133 UniConfGen::Iter *UniFileSystemGen::iterator(const UniConfKey &key)
135 if (!key_safe(key))
136 return NULL;
138 return new UniFileSystemGenIter(this, WvString("%s/%s", dir, key), key);