WvStreams
unifilesystemgen.cc
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>
11
12WV_LINK(UniFileSystemGen);
13
14
15static IUniConfGen *creator(WvStringParm s, IObject *)
16{
17 return new UniFileSystemGen(s, 0777);
18}
19
20WvMoniker<IUniConfGen> UniFileSystemGenMoniker("fs", creator);
21
22
23UniFileSystemGen::UniFileSystemGen(WvStringParm _dir, mode_t _mode)
24 : dir(_dir), mode(_mode)
25{
26}
27
28
29static bool key_safe(const UniConfKey &key)
30{
31 UniConfKey::Iter i(key);
32 for (i.rewind(); i.next(); )
33 {
34 if (*i == "." || *i == ".." || *i == "")
35 return false; // unsafe key segments
36 }
37
38 // otherwise a safe filename
39 return true;
40}
41
42
44{
45 WvString null;
46
47 if (!key_safe(key))
48 return null;
49
50 WvString path("%s/%s", dir, key);
51
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
57
58 struct stat st;
59 if (fstat(file.getrfd(), &st) < 0)
60 return null; // openable but can't stat? That's odd.
61
62 if (S_ISREG(st.st_mode))
63 {
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();
71 }
72 else
73 return ""; // exists, but pretend it's an empty file
74}
75
76
78{
79 if (!key_safe(key))
80 return;
81
82 WvString base("%s/%s", dir, key.removelast(1));
83 WvString path("%s/%s", dir, key);
84
85 mkdirp(base, mode);
86
87 if (value.isnull())
88 rm_rf(path);
89 else
90 {
91 WvFile file(path, O_WRONLY|O_CREAT|O_TRUNC, mode & 0666);
92 file.write(value);
93 }
94}
95
96
97void UniFileSystemGen::setv(const UniConfPairList &pairs)
98{
99 setv_naive(pairs);
100}
101
102
104{
105private:
106 UniFileSystemGen *gen;
107 WvDirIter i;
108 UniConfKey rel;
109
110public:
112 const UniConfKey &_rel)
113 : gen(_gen), i(path, false), rel(_rel)
114 { }
115
117 { }
118
119 void rewind()
120 { i.rewind(); }
121
122 bool next()
123 { return i.next(); }
124
126 { return i->relname; }
127
129 { return gen->get(WvString("%s/%s", rel, i->relname)); }
130};
131
132
134{
135 if (!key_safe(key))
136 return NULL;
137
138 return new UniFileSystemGenIter(this, WvString("%s/%s", dir, key), key);
139}
The basic interface which is included by all other XPLC interfaces and objects.
An abstract data container that backs a UniConf tree.
An abstract iterator over keys and values in a generator.
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
UniConfKey removelast(int n=1) const
Returns the path formed by removing the last n segments of this path.
WvString value() const
Returns the value of the current key.
UniConfKey key() const
Returns the current key.
void rewind()
Rewinds the iterator.
bool next()
Seeks to the next element in the sequence.
Creates a UniConf tree that mirrors some point in the Linux filesystem, with restrictions.
virtual Iter * iterator(const UniConfKey &key)
Returns an iterator over the children of the specified key.
virtual void setv(const UniConfPairList &pairs)
Stores multiple key-value pairs into the registry.
virtual void set(const UniConfKey &key, WvStringParm value)
Stores a string value for a key into the registry.
virtual WvString get(const UniConfKey &key)
Fetches a string value for a key from the registry.
virtual int geterr() const
If isok() is false, return the system error number corresponding to the error, -1 for a special error...
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
bool isnull() const
returns true if this string is null
int getrfd() const
Returns the Unix file descriptor for reading from this stream.
virtual bool isok() const
return true if the stream is actually usable right now
WvFile implements a stream connected to a file or Unix device.
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
virtual size_t write(const void *buf, size_t count)
Write data to the stream.
Definition wvstream.cc:532
virtual size_t read(void *buf, size_t count)
read a data block on the stream.
Definition wvstream.cc:490
WvString is an implementation of a simple and efficient printable-string class.