WvStreams
Main Page
Modules
Classes
Files
File List
File Members
uniconf
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
12
WV_LINK(
UniFileSystemGen
);
13
14
15
static
IUniConfGen
*creator(
WvStringParm
s,
IObject
*)
16
{
17
return
new
UniFileSystemGen
(s, 0777);
18
}
19
20
WvMoniker<IUniConfGen>
UniFileSystemGenMoniker(
"fs"
, creator);
21
22
23
UniFileSystemGen::UniFileSystemGen(
WvStringParm
_dir, mode_t _mode)
24
: dir(_dir), mode(_mode)
25
{
26
}
27
28
29
static
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
43
WvString
UniFileSystemGen::get
(
const
UniConfKey
&key)
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
77
void
UniFileSystemGen::set
(
const
UniConfKey
&key,
WvStringParm
value)
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
97
void
UniFileSystemGen::setv
(
const
UniConfPairList &pairs)
98
{
99
setv_naive(pairs);
100
}
101
102
103
class
UniFileSystemGenIter
:
public
UniConfGen::Iter
104
{
105
private
:
106
UniFileSystemGen
*gen;
107
WvDirIter
i;
108
UniConfKey
rel;
109
110
public
:
111
UniFileSystemGenIter
(
UniFileSystemGen
*_gen,
WvStringParm
path,
112
const
UniConfKey
&_rel)
113
: gen(_gen), i(path,
false
), rel(_rel)
114
{ }
115
116
~
UniFileSystemGenIter
()
117
{ }
118
119
void
rewind
()
120
{ i.rewind(); }
121
122
bool
next
()
123
{
return
i.next(); }
124
125
UniConfKey
key
()
const
126
{
return
i->relname; }
127
128
WvString
value
()
const
129
{
return
gen->
get
(
WvString
(
"%s/%s"
, rel, i->relname)); }
130
};
131
132
133
UniConfGen::Iter
*
UniFileSystemGen::iterator
(
const
UniConfKey
&key)
134
{
135
if
(!key_safe(key))
136
return
NULL;
137
138
return
new
UniFileSystemGenIter
(
this
,
WvString
(
"%s/%s"
, dir, key), key);
139
}
Generated on Thu Jul 12 2012 23:23:55 for WvStreams by
1.8.1.1