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 
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 
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 
97 void UniFileSystemGen::setv(const UniConfPairList &pairs)
98 {
99  setv_naive(pairs);
100 }
101 
102 
104 {
105 private:
106  UniFileSystemGen *gen;
107  WvDirIter i;
108  UniConfKey rel;
109 
110 public:
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 
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 
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.
Definition: IObject.h:65
An abstract data container that backs a UniConf tree.
Definition: uniconfgen.h:40
An abstract iterator over keys and values in a generator.
Definition: uniconfgen.h:324
An iterator over the segments of a key.
Definition: uniconfkey.h:464
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
Definition: uniconfkey.h:39
UniConfKey removelast(int n=1) const
Returns the path formed by removing the last n segments of this path.
Definition: uniconfkey.h:346
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.
WvString getstr()
Returns the entire buffer as a null-terminated WvString.
Definition: wvbuffer.cc:17
virtual int geterr() const
If isok() is false, return the system error number corresponding to the error, -1 for a special error...
Definition: wverror.h:48
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
Definition: wvstring.h:94
bool isnull() const
returns true if this string is null
Definition: wvstring.h:290
int getrfd() const
Returns the Unix file descriptor for reading from this stream.
Definition: wvfdstream.h:63
virtual bool isok() const
return true if the stream is actually usable right now
Definition: wvfdstream.cc:134
WvFile implements a stream connected to a file or Unix device.
Definition: wvfile.h:29
A type-safe version of WvMonikerBase that lets you provide create functions for object types other th...
Definition: wvmoniker.h:62
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.
Definition: wvstring.h:330