|
a/libupnpp/device/vdir.cxx |
|
b/libupnpp/device/vdir.cxx |
|
... |
|
... |
31 |
#include "libupnpp/upnpp_p.hxx"
|
31 |
#include "libupnpp/upnpp_p.hxx"
|
32 |
|
32 |
|
33 |
using namespace std;
|
33 |
using namespace std;
|
34 |
using namespace UPnPP;
|
34 |
using namespace UPnPP;
|
35 |
|
35 |
|
|
|
36 |
#if UPNP_VERSION_MAJOR > 1 || (UPNP_VERSION_MAJOR==1 && UPNP_VERSION_MINOR >= 8)
|
|
|
37 |
#define V18VDIR 1
|
|
|
38 |
#else
|
|
|
39 |
#undef V18VDIR
|
|
|
40 |
typedef struct File_Info UpnpFileInfo;
|
|
|
41 |
#endif
|
|
|
42 |
|
36 |
namespace UPnPProvider {
|
43 |
namespace UPnPProvider {
|
37 |
|
44 |
|
38 |
static VirtualDir *theDir;
|
45 |
static VirtualDir *theDir;
|
39 |
|
46 |
|
40 |
class FileEnt {
|
47 |
class FileEnt {
|
|
... |
|
... |
102 |
|
109 |
|
103 |
//LOGDEB("VirtualDir::addFile: path " << path << " name " << name << endl);
|
110 |
//LOGDEB("VirtualDir::addFile: path " << path << " name " << name << endl);
|
104 |
|
111 |
|
105 |
if (m_dirs.find(path) == m_dirs.end()) {
|
112 |
if (m_dirs.find(path) == m_dirs.end()) {
|
106 |
m_dirs[path] = DirEnt();
|
113 |
m_dirs[path] = DirEnt();
|
|
|
114 |
|
107 |
UpnpAddVirtualDir(path.c_str());
|
115 |
UpnpAddVirtualDir(path.c_str()
|
|
|
116 |
#ifdef V18VDIR
|
|
|
117 |
, 0, 0
|
|
|
118 |
#endif
|
|
|
119 |
);
|
108 |
}
|
120 |
}
|
109 |
|
121 |
|
110 |
FileEnt entry;
|
122 |
FileEnt entry;
|
111 |
entry.mtime = time(0);
|
123 |
entry.mtime = time(0);
|
112 |
entry.mimetype = mimetype;
|
124 |
entry.mimetype = mimetype;
|
|
... |
|
... |
121 |
{
|
133 |
{
|
122 |
string path(_path);
|
134 |
string path(_path);
|
123 |
pathcatslash(path);
|
135 |
pathcatslash(path);
|
124 |
if (m_dirs.find(path) == m_dirs.end()) {
|
136 |
if (m_dirs.find(path) == m_dirs.end()) {
|
125 |
m_dirs[path] = DirEnt(true);
|
137 |
m_dirs[path] = DirEnt(true);
|
126 |
UpnpAddVirtualDir(path.c_str());
|
138 |
UpnpAddVirtualDir(path.c_str()
|
|
|
139 |
#ifdef V18VDIR
|
|
|
140 |
, 0, 0
|
|
|
141 |
#endif
|
|
|
142 |
);
|
127 |
}
|
143 |
}
|
128 |
m_dirs[path].ops = fops;
|
144 |
m_dirs[path].ops = fops;
|
129 |
return true;
|
145 |
return true;
|
130 |
}
|
146 |
}
|
131 |
|
147 |
|
|
... |
|
... |
141 |
DirEnt *dir;
|
157 |
DirEnt *dir;
|
142 |
void *vhandle;
|
158 |
void *vhandle;
|
143 |
size_t offset;
|
159 |
size_t offset;
|
144 |
};
|
160 |
};
|
145 |
|
161 |
|
146 |
static int vdclose(UpnpWebFileHandle fileHnd)
|
162 |
static int vdclose(UpnpWebFileHandle fileHnd
|
|
|
163 |
#if V18VDIR
|
|
|
164 |
, const void*
|
|
|
165 |
#endif
|
|
|
166 |
)
|
147 |
{
|
167 |
{
|
148 |
Handle *h = (Handle*)fileHnd;
|
168 |
Handle *h = (Handle*)fileHnd;
|
149 |
if (h->vhandle) {
|
169 |
if (h->vhandle) {
|
150 |
h->dir->ops.close(h->vhandle);
|
170 |
h->dir->ops.close(h->vhandle);
|
151 |
}
|
171 |
}
|
152 |
delete h;
|
172 |
delete h;
|
153 |
return 0;
|
173 |
return 0;
|
154 |
}
|
174 |
}
|
155 |
|
175 |
|
156 |
static int vdgetinfo(const char *fn, struct File_Info* info)
|
176 |
static int vdgetinfo(const char *fn, UpnpFileInfo* info
|
|
|
177 |
#if V18VDIR
|
|
|
178 |
, const void*
|
|
|
179 |
#endif
|
|
|
180 |
)
|
157 |
{
|
181 |
{
|
158 |
//LOGDEB("vdgetinfo: [" << fn << "] off_t " << sizeof(off_t) <<
|
182 |
//LOGDEB("vdgetinfo: [" << fn << "] off_t " << sizeof(off_t) <<
|
159 |
// " time_t " << sizeof(time_t) << endl);
|
183 |
// " time_t " << sizeof(time_t) << endl);
|
160 |
DirEnt *dir;
|
184 |
DirEnt *dir;
|
161 |
FileEnt *entry = vdgetentry(fn, &dir);
|
185 |
FileEnt *entry = vdgetentry(fn, &dir);
|
162 |
if (dir && dir->isvd) {
|
186 |
if (dir && dir->isvd) {
|
163 |
VirtualDir::FileInfo inf;
|
187 |
VirtualDir::FileInfo inf;
|
164 |
int ret = dir->ops.getinfo(fn, &inf);
|
188 |
int ret = dir->ops.getinfo(fn, &inf);
|
165 |
if (ret >= 0) {
|
189 |
if (ret >= 0) {
|
|
|
190 |
#if V18VDIR
|
|
|
191 |
UpnpFileInfo_set_FileLength(info, inf.file_length);
|
|
|
192 |
UpnpFileInfo_set_LastModified(info, inf.last_modified);
|
|
|
193 |
UpnpFileInfo_set_IsDirectory(info, inf.is_directory);
|
|
|
194 |
UpnpFileInfo_set_IsReadable(info, inf.is_readable);
|
|
|
195 |
UpnpFileInfo_set_ContentType(info,
|
|
|
196 |
ixmlCloneDOMString(inf.mime.c_str()));
|
|
|
197 |
#else
|
166 |
info->file_length = inf.file_length;
|
198 |
info->file_length = inf.file_length;
|
167 |
info->last_modified = inf.last_modified;
|
199 |
info->last_modified = inf.last_modified;
|
168 |
info->is_directory = inf.is_directory;
|
200 |
info->is_directory = inf.is_directory;
|
169 |
info->is_readable = inf.is_readable;
|
201 |
info->is_readable = inf.is_readable;
|
170 |
info->content_type = ixmlCloneDOMString(inf.mime.c_str());
|
202 |
info->content_type = ixmlCloneDOMString(inf.mime.c_str());
|
|
|
203 |
#endif
|
171 |
}
|
204 |
}
|
172 |
return ret;
|
205 |
return ret;
|
173 |
}
|
206 |
}
|
174 |
if (entry == 0) {
|
207 |
if (entry == 0) {
|
175 |
LOGERR("vdgetinfo: no entry for " << fn << endl);
|
208 |
LOGERR("vdgetinfo: no entry for " << fn << endl);
|
176 |
return -1;
|
209 |
return -1;
|
177 |
}
|
210 |
}
|
178 |
|
211 |
|
|
|
212 |
#if V18VDIR
|
|
|
213 |
UpnpFileInfo_set_FileLength(info, entry->content.size());
|
|
|
214 |
UpnpFileInfo_set_LastModified(info, entry->mtime);
|
|
|
215 |
UpnpFileInfo_set_IsDirectory(info, 0);
|
|
|
216 |
UpnpFileInfo_set_IsReadable(info, 1);
|
|
|
217 |
UpnpFileInfo_set_ContentType(info,
|
|
|
218 |
ixmlCloneDOMString(entry->mimetype.c_str()));
|
|
|
219 |
#else
|
179 |
info->file_length = entry->content.size();
|
220 |
info->file_length = entry->content.size();
|
180 |
info->last_modified = entry->mtime;
|
221 |
info->last_modified = entry->mtime;
|
181 |
info->is_directory = 0;
|
222 |
info->is_directory = 0;
|
182 |
info->is_readable = 1;
|
223 |
info->is_readable = 1;
|
183 |
info->content_type = ixmlCloneDOMString(entry->mimetype.c_str());
|
224 |
info->content_type = ixmlCloneDOMString(entry->mimetype.c_str());
|
|
|
225 |
#endif
|
184 |
|
226 |
|
185 |
return 0;
|
227 |
return 0;
|
186 |
}
|
228 |
}
|
187 |
|
229 |
|
188 |
static UpnpWebFileHandle vdopen(const char* fn, enum UpnpOpenFileMode)
|
230 |
static UpnpWebFileHandle vdopen(const char* fn, enum UpnpOpenFileMode
|
|
|
231 |
#if V18VDIR
|
|
|
232 |
, const void*
|
|
|
233 |
#endif
|
|
|
234 |
)
|
189 |
{
|
235 |
{
|
190 |
//LOGDEB("vdopen: " << fn << endl);
|
236 |
//LOGDEB("vdopen: " << fn << endl);
|
191 |
DirEnt *dir;
|
237 |
DirEnt *dir;
|
192 |
FileEnt *entry = vdgetentry(fn, &dir);
|
238 |
FileEnt *entry = vdgetentry(fn, &dir);
|
193 |
|
239 |
|
|
... |
|
... |
205 |
return NULL;
|
251 |
return NULL;
|
206 |
}
|
252 |
}
|
207 |
return new Handle(entry);
|
253 |
return new Handle(entry);
|
208 |
}
|
254 |
}
|
209 |
|
255 |
|
210 |
static int vdread(UpnpWebFileHandle fileHnd, char* buf, size_t buflen)
|
256 |
static int vdread(UpnpWebFileHandle fileHnd, char* buf, size_t buflen
|
|
|
257 |
#if V18VDIR
|
|
|
258 |
, const void*
|
|
|
259 |
#endif
|
|
|
260 |
)
|
211 |
{
|
261 |
{
|
212 |
// LOGDEB("vdread: " << endl);
|
262 |
// LOGDEB("vdread: " << endl);
|
213 |
if (buflen == 0) {
|
263 |
if (buflen == 0) {
|
214 |
return 0;
|
264 |
return 0;
|
215 |
}
|
265 |
}
|
|
... |
|
... |
226 |
memcpy(buf, h->entry->content.c_str() + h->offset, toread);
|
276 |
memcpy(buf, h->entry->content.c_str() + h->offset, toread);
|
227 |
h->offset += toread;
|
277 |
h->offset += toread;
|
228 |
return toread;
|
278 |
return toread;
|
229 |
}
|
279 |
}
|
230 |
|
280 |
|
231 |
static int vdseek(UpnpWebFileHandle fileHnd, off_t offset, int origin)
|
281 |
static int vdseek(UpnpWebFileHandle fileHnd, off_t offset, int origin
|
|
|
282 |
#if V18VDIR
|
|
|
283 |
, const void*
|
|
|
284 |
#endif
|
|
|
285 |
)
|
232 |
{
|
286 |
{
|
233 |
// LOGDEB("vdseek: " << endl);
|
287 |
// LOGDEB("vdseek: " << endl);
|
234 |
Handle *h = (Handle *)fileHnd;
|
288 |
Handle *h = (Handle *)fileHnd;
|
235 |
if (h->vhandle) {
|
289 |
if (h->vhandle) {
|
236 |
return h->dir->ops.seek(h->vhandle, offset, origin);
|
290 |
return h->dir->ops.seek(h->vhandle, offset, origin);
|
|
... |
|
... |
245 |
return -1;
|
299 |
return -1;
|
246 |
}
|
300 |
}
|
247 |
return offset;
|
301 |
return offset;
|
248 |
}
|
302 |
}
|
249 |
|
303 |
|
250 |
static int vdwrite(UpnpWebFileHandle, char*, size_t)
|
304 |
static int vdwrite(UpnpWebFileHandle, char*, size_t
|
|
|
305 |
#if V18VDIR
|
|
|
306 |
, const void*
|
|
|
307 |
#endif
|
|
|
308 |
)
|
251 |
{
|
309 |
{
|
252 |
LOGERR("vdwrite" << endl);
|
310 |
LOGERR("vdwrite" << endl);
|
253 |
return -1;
|
311 |
return -1;
|
254 |
}
|
312 |
}
|
255 |
|
313 |
|
|
|
314 |
#if V18VDIR
|
|
|
315 |
VirtualDir *VirtualDir::getVirtualDir()
|
|
|
316 |
{
|
|
|
317 |
if (theDir == 0) {
|
|
|
318 |
theDir = new VirtualDir();
|
|
|
319 |
if (UpnpVirtualDir_set_GetInfoCallback(vdgetinfo) ||
|
|
|
320 |
UpnpVirtualDir_set_OpenCallback(vdopen) ||
|
|
|
321 |
UpnpVirtualDir_set_ReadCallback(vdread) ||
|
|
|
322 |
UpnpVirtualDir_set_WriteCallback(vdwrite) ||
|
|
|
323 |
UpnpVirtualDir_set_SeekCallback(vdseek) ||
|
|
|
324 |
UpnpVirtualDir_set_CloseCallback(vdclose)) {
|
|
|
325 |
LOGERR("SetVirtualDirCallbacks failed" << endl);
|
|
|
326 |
delete theDir;
|
|
|
327 |
theDir = 0;
|
|
|
328 |
return 0;
|
|
|
329 |
}
|
|
|
330 |
}
|
|
|
331 |
return theDir;
|
|
|
332 |
}
|
|
|
333 |
#else
|
256 |
static struct UpnpVirtualDirCallbacks myvdcalls = {
|
334 |
static struct UpnpVirtualDirCallbacks myvdcalls = {
|
257 |
vdgetinfo, vdopen, vdread, vdwrite, vdseek, vdclose
|
335 |
vdgetinfo, vdopen, vdread, vdwrite, vdseek, vdclose
|
258 |
};
|
336 |
};
|
259 |
|
337 |
|
260 |
VirtualDir *VirtualDir::getVirtualDir()
|
338 |
VirtualDir *VirtualDir::getVirtualDir()
|
|
... |
|
... |
268 |
return 0;
|
346 |
return 0;
|
269 |
}
|
347 |
}
|
270 |
}
|
348 |
}
|
271 |
return theDir;
|
349 |
return theDir;
|
272 |
}
|
350 |
}
|
|
|
351 |
#endif
|
273 |
|
352 |
|
274 |
}
|
353 |
}
|