library name fixups
[libmvfs.git] / libmvfs / hostfs_ops.c
blob9f687586e21a7ab6c2569adf948e504040a9ad2c
1 /*
2 libmvfs - metux Virtual Filesystem Library
4 Filesystem driver: local filesystem
6 Copyright (C) 2008 Enrico Weigelt, metux IT service <weigelt@metux.de>
7 This code is published under the terms of the GNU Public License 2.0
9 ----
11 FD private data layout:
13 id fd
14 name filename
15 ptr DIR* pointer
18 #include "mvfs-internal.h"
20 // #define __DEBUG
22 #define PRIV_FD(file) (file->priv.id)
23 #define PRIV_NAME(file) (file->priv.name)
24 #define PRIV_DIRP(file) ((DIR*)(file->priv.ptr))
26 #define PRIV_SET_FD(file,fd) file->priv.id = fd;
27 #define PRIV_SET_NAME(file,name) file->priv.name = strdup(name)
28 #define PRIV_SET_DIRP(file,dirp) file->priv.ptr = dirp;
30 #include <mvfs/mvfs.h>
31 #include <mvfs/default_ops.h>
32 #include <mvfs/hostfs.h>
33 #include <mvfs/_utils.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <unistd.h>
38 #include <dirent.h>
39 #include <stdio.h>
40 #include <errno.h>
41 #include <unistd.h>
42 #include <errno.h>
43 #include <string.h>
44 #include <pwd.h>
45 #include <grp.h>
47 #define FS_MAGIC "hostfs"
49 static int mvfs_hostfs_fileops_open (MVFS_FILE* file, mode_t mode);
50 static off64_t mvfs_hostfs_fileops_seek (MVFS_FILE* file, off64_t offset, int whence);
51 static ssize_t mvfs_hostfs_fileops_read (MVFS_FILE* file, void* buf, size_t count);
52 static ssize_t mvfs_hostfs_fileops_write (MVFS_FILE* file, const void* buf, size_t count);
53 static ssize_t mvfs_hostfs_fileops_pread (MVFS_FILE* file, void* buf, size_t count, off64_t offset);
54 static ssize_t mvfs_hostfs_fileops_pwrite (MVFS_FILE* file, const void* buf, size_t count, off64_t offset);
55 static int mvfs_hostfs_fileops_setflag (MVFS_FILE* file, MVFS_FILE_FLAG flag, long value);
56 static int mvfs_hostfs_fileops_getflag (MVFS_FILE* file, MVFS_FILE_FLAG flag, long* value);
57 static MVFS_STAT* mvfs_hostfs_fileops_stat (MVFS_FILE* file);
58 static int mvfs_hostfs_fileops_close (MVFS_FILE* file);
59 static int mvfs_hostfs_fileops_eof (MVFS_FILE* file);
60 static MVFS_FILE* mvfs_hostfs_fileops_lookup (MVFS_FILE* file, const char* name);
61 static MVFS_STAT* mvfs_hostfs_fileops_scan (MVFS_FILE* file);
62 static int mvfs_hostfs_fileops_reset (MVFS_FILE* file);
64 static MVFS_FILE_OPS hostfs_fileops =
66 .seek = mvfs_hostfs_fileops_seek,
67 .read = mvfs_hostfs_fileops_read,
68 .write = mvfs_hostfs_fileops_write,
69 .pread = mvfs_hostfs_fileops_pread,
70 .pwrite = mvfs_hostfs_fileops_pwrite,
71 .close = mvfs_hostfs_fileops_close,
72 .eof = mvfs_hostfs_fileops_eof,
73 .lookup = mvfs_hostfs_fileops_lookup,
74 .reset = mvfs_hostfs_fileops_reset,
75 .scan = mvfs_hostfs_fileops_scan,
76 .stat = mvfs_hostfs_fileops_stat
79 static MVFS_FILE* mvfs_hostfs_fsops_open (MVFS_FILESYSTEM* fs, const char* name, mode_t mode);
80 static MVFS_STAT* mvfs_hostfs_fsops_stat (MVFS_FILESYSTEM* fs, const char* name);
81 static int mvfs_hostfs_fsops_unlink (MVFS_FILESYSTEM* fs, const char* name);
82 static int mvfs_hostfs_fsops_free (MVFS_FILESYSTEM* fs);
83 static int mvfs_hostfs_fsops_mkdir (MVFS_FILESYSTEM* file, const char* name, mode_t mode);
84 static int mvfs_hostfs_fsops_chmod (MVFS_FILESYSTEM* fs, const char* name, mode_t mode);
85 static MVFS_SYMLINK mvfs_hostfs_fsops_readlink (MVFS_FILESYSTEM* fs, const char* path);
87 static MVFS_FILESYSTEM_OPS hostfs_fsops =
89 .openfile = mvfs_hostfs_fsops_open,
90 .unlink = mvfs_hostfs_fsops_unlink,
91 .stat = mvfs_hostfs_fsops_stat,
92 .mkdir = mvfs_hostfs_fsops_mkdir,
93 .chmod = mvfs_hostfs_fsops_chmod,
94 .readlink = mvfs_hostfs_fsops_readlink
97 static off64_t mvfs_hostfs_fileops_seek (MVFS_FILE* file, off64_t offset, int whence)
99 off_t ret = lseek(PRIV_FD(file), offset, whence);
100 file->errcode = errno;
101 return ret;
104 static ssize_t mvfs_hostfs_fileops_read (MVFS_FILE* file, void* buf, size_t count)
106 memset(buf, 0, count);
107 ssize_t s = read(PRIV_FD(file), buf, count);
108 file->errcode = errno;
109 if (s==0)
110 file->priv.status = 1;
111 return s;
114 static ssize_t mvfs_hostfs_fileops_pread (MVFS_FILE* file, void* buf, size_t count, off64_t offset)
116 mvfs_hostfs_fileops_seek(file, offset, SEEK_SET);
117 return mvfs_hostfs_fileops_read(file, buf, count);
120 static ssize_t mvfs_hostfs_fileops_write (MVFS_FILE* file, const void* buf, size_t count)
122 ssize_t s = write(PRIV_FD(file), buf, count);
123 file->errcode = errno;
124 return s;
127 static ssize_t mvfs_hostfs_fileops_pwrite (MVFS_FILE* file, const void* buf, size_t count, off64_t offset)
129 mvfs_hostfs_fileops_seek(file,offset,SEEK_SET);
130 return mvfs_hostfs_fileops_write(file,buf,count);
133 static inline const char* __mvfs_flag2str(MVFS_FILE_FLAG f)
135 switch (f)
137 case NONBLOCK: return "NONBLOCK";
138 case READ_TIMEOUT: return "READ_TIMEOUT";
139 case WRITE_TIMEOUT: return "WRITE_TIMEOUT";
140 case READ_AHEAD: return "READ_AHEAD";
141 case WRITE_ASYNC: return "WRITE_ASYNNC";
142 default: return "UNKNOWN";
146 static int mvfs_hostfs_fileops_setflag (MVFS_FILE* fp, MVFS_FILE_FLAG flag, long value)
148 ERRMSG("%s not supported", __mvfs_flag2str(flag));
149 fp->errcode = EINVAL;
150 return -1;
153 static int mvfs_hostfs_fileops_getflag (MVFS_FILE* fp, MVFS_FILE_FLAG flag, long* value)
155 ERRMSG("%s not supported", __mvfs_flag2str(flag));
156 fp->errcode = EINVAL;
157 return -1;
160 static MVFS_STAT* mvfs_stat_from_unix(const char* name, struct stat s)
162 struct passwd* pw = getpwuid(s.st_uid);
163 struct group* gr = getgrgid(s.st_gid);
165 const char* uid="???";
166 const char* gid="???";
168 if (pw)
169 uid = pw->pw_name;
170 if (gr)
171 gid = gr->gr_name;
173 MVFS_STAT* mstat = mvfs_stat_alloc(name, uid, gid);
174 mstat->mode = s.st_mode;
175 mstat->size = s.st_size;
176 mstat->atime = s.st_atime;
177 mstat->mtime = s.st_mtime;
178 mstat->ctime = s.st_ctime;
180 return mstat;
183 static MVFS_STAT* mvfs_hostfs_fileops_stat(MVFS_FILE* fp)
185 struct stat ust;
186 int ret = fstat(PRIV_FD(fp), &ust);
188 if (ret!=0)
190 fp->fs->errcode = errno;
191 return NULL;
194 return mvfs_stat_from_unix(PRIV_NAME(fp), ust);
197 static MVFS_FILE* mvfs_hostfs_fsops_open(MVFS_FILESYSTEM* fs, const char* name, mode_t mode)
199 int fd = open(name, mode);
200 if (fd<0)
202 fs->errcode = errno;
203 ERRMSG("error opening file: %s", strerror(errno));
204 return NULL;
207 MVFS_FILE* file = mvfs_file_alloc(fs,hostfs_fileops);
208 file->priv.name = strdup(name);
209 file->priv.id = fd;
211 return file;
214 static MVFS_STAT* mvfs_hostfs_fsops_stat(MVFS_FILESYSTEM* fs, const char* name)
216 if (fs==NULL)
218 ERRMSG("fs==NULL");;
219 return NULL;
222 if (name==NULL)
224 ERRMSG("name==NULL");
225 fs->errcode = EFAULT;
226 return NULL;
229 struct stat ust;
230 int ret = lstat(name, &ust);
232 if (ret!=0)
234 fs->errcode = errno;
235 return NULL;
238 return mvfs_stat_from_unix(name, ust);
241 static int mvfs_hostfs_fsops_unlink(MVFS_FILESYSTEM* fs, const char* name)
243 int ret = unlink(name);
245 if ((ret != 0) && (errno == EISDIR))
246 ret = rmdir(name);
248 if (ret == 0)
249 return 0;
251 fs->errcode = errno;
252 return errno;
255 static int mvfs_hostfs_fsops_mkdir(MVFS_FILESYSTEM* fs, const char* fn, mode_t mode)
257 DEBUGMSG("fn=\"%s\"", fn);
258 return mkdir(fn,mode);
261 MVFS_FILESYSTEM* mvfs_hostfs_create(MVFS_HOSTFS_PARAM par)
263 DEBUGMSG("params currently ignored !");
264 MVFS_FILESYSTEM* fs = mvfs_fs_alloc(hostfs_fsops,FS_MAGIC);
265 return fs;
268 MVFS_FILESYSTEM* mvfs_hostfs_create_args(MVFS_ARGS* args)
270 const char* chroot = mvfs_args_get(args,"chroot");
271 if ((chroot) && (strlen(chroot)) && (!strcmp(chroot,"/")))
273 ERRMSG("chroot not supported yet!");
274 return NULL;
277 MVFS_FILESYSTEM* fs = mvfs_fs_alloc(hostfs_fsops, FS_MAGIC);
278 return fs;
281 static int mvfs_hostfs_fileops_close(MVFS_FILE* file)
283 int ret = close(PRIV_FD(file));
284 file->priv.id = -1;
285 return ret;
288 static int mvfs_hostfs_fileops_eof(MVFS_FILE* file)
290 return ((file->priv.status) ? 1 : 0);
293 static MVFS_FILE* mvfs_hostfs_fileops_lookup (MVFS_FILE* file, const char* name)
295 int fd = openat(PRIV_FD(file), name, O_RDONLY);
296 if (fd<0)
297 return NULL;
299 MVFS_FILE* f2 = mvfs_file_alloc(file->fs,hostfs_fileops);
300 f2->priv.name = strdup(name);
301 f2->priv.id = fd;
303 return f2;
306 static DIR* mvfs_hostfs_fileops_init_dir(MVFS_FILE* file)
308 DIR* dir = PRIV_DIRP(file);
309 if (dir != NULL)
310 return dir;
312 dup(PRIV_FD(file));
314 dir = fdopendir(1);
316 dir = fdopendir(dup(PRIV_FD(file)));
317 PRIV_SET_DIRP(file,dir);
318 return dir;
321 static MVFS_STAT* mvfs_hostfs_fileops_scan(MVFS_FILE* file)
323 DIR* dir = mvfs_hostfs_fileops_init_dir(file);
324 if (dir==NULL)
326 ERRMSG("cannot get DIR* ptr");
327 return NULL;
330 struct dirent * ent = readdir(dir);
331 if (ent == NULL)
332 return 0;
334 if ((strcmp(ent->d_name,".")==0) || (strcmp(ent->d_name,"..")==0))
335 return mvfs_hostfs_fileops_scan(file);
337 struct stat st;
338 char buffer[4096];
339 memset(buffer,0,sizeof(buffer));
340 snprintf(buffer,sizeof(buffer)-1,"%s/%s", PRIV_NAME(file),ent->d_name);
341 lstat(buffer,&st);
343 return mvfs_stat_from_unix(ent->d_name, st);
346 static int mvfs_hostfs_fileops_reset(MVFS_FILE* file)
348 DIR* dir = mvfs_hostfs_fileops_init_dir(file);
349 if (dir==NULL)
351 ERRMSG("cannot get DIR* ptr");
352 return 0;
355 rewinddir(dir);
356 return 1;
359 static int mvfs_hostfs_fsops_chmod(MVFS_FILESYSTEM* fs, const char* name, mode_t mode)
361 return chmod(name, mode);
364 static MVFS_SYMLINK mvfs_hostfs_fsops_readlink(MVFS_FILESYSTEM* fs, const char* path)
366 MVFS_SYMLINK link;
367 if (readlink(path, (char*)&link.target, sizeof(link.target)) == -1)
368 link.errcode = errno;
369 else
370 link.errcode = 0;
371 return link;