http://prdownloads.sourceforge.net/lufs/lufs-0.9.6.tar.gz?download
[lufs.git] / filesystems / cardfs / cardfs.cpp
1 /***************************************************************************
2  $RCSfile$
3                              -------------------
4     cvs         : $Id$
5     begin       : Thu Aug 15 2002
6     copyright   : (C) 2002 by Martin Preuss
7     email       : martin@libchipcard.de
8
9  ***************************************************************************
10  *                                                                         *
11  *   This library is free software; you can redistribute it and/or         *
12  *   modify it under the terms of the GNU Lesser General Public            *
13  *   License as published by the Free Software Foundation; either          *
14  *   version 2.1 of the License, or (at your option) any later version.    *
15  *                                                                         *
16  *   This library is distributed in the hope that it will be useful,       *
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
19  *   Lesser General Public License for more details.                       *
20  *                                                                         *
21  *   You should have received a copy of the GNU Lesser General Public      *
22  *   License along with this library; if not, write to the Free Software   *
23  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
24  *   MA  02111-1307  USA                                                   *
25  *                                                                         *
26  ***************************************************************************/
27
28
29 #include <unistd.h>
30 #include <dirent.h>
31 #include <fcntl.h>
32 #include <stdio.h>
33 #include <utime.h>
34
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <sys/file.h>
38
39 #include <lufs/proto.h>
40 #include <lufs/fs.h>
41
42 #include "cardfs.h"
43
44 extern "C" {
45
46 void*
47 cardfs_init(struct list_head *cfg, struct dir_cache *cache, struct credentials *cred, void **global_fs){
48     return (void*)new CardFS(cfg, cache);
49 }
50
51 void
52 cardfs_free(void *ctx){
53     CardFS *p = (CardFS*)ctx;
54
55     delete p;
56 }
57
58 int     
59 cardfs_mount(void *ctx){
60     return ((CardFS*)ctx)->do_mount();
61 }
62
63 void    
64 cardfs_umount(void *ctx){
65 //    return ((CardFS*)ctx)->do_umount();
66 }
67
68 int     
69 cardfs_readdir(void *ctx, char *dir_name, struct directory *dir){
70     return ((CardFS*)ctx)->do_readdir(dir_name, dir);
71 }
72
73 int     
74 cardfs_stat(void *ctx, char *name, struct lufs_fattr *fattr){
75     return ((CardFS*)ctx)->do_stat(name, fattr);
76 }
77
78 int     
79 cardfs_mkdir(void *ctx, char *dir, int mode){
80     return ((CardFS*)ctx)->do_mkdir(dir, mode);
81 }
82
83 int     
84 cardfs_rmdir(void *ctx, char *dir){
85     return ((CardFS*)ctx)->do_rmdir(dir);
86 }
87
88 int     
89 cardfs_create(void *ctx, char *file, int mode){
90     return ((CardFS*)ctx)->do_create(file, mode);
91 }
92
93 int     
94 cardfs_unlink(void *ctx, char *file){
95     return ((CardFS*)ctx)->do_unlink(file);
96 }
97
98 int     
99 cardfs_rename(void *ctx, char *old_name, char *new_name){
100     return ((CardFS*)ctx)->do_rename(old_name, new_name);
101 }
102
103 int     
104 cardfs_open(void *ctx, char *file, unsigned mode){
105     return ((CardFS*)ctx)->do_open(file, mode);
106 }
107
108 int     
109 cardfs_release(void *ctx, char *file){
110     return ((CardFS*)ctx)->do_release(file);
111 }
112
113 int     
114 cardfs_read(void *ctx, char *file, unsigned long offset, unsigned long count, char *buf){
115     return ((CardFS*)ctx)->do_read(file, offset, count, buf);
116 }
117
118 int     
119 cardfs_write(void *ctx, char *file, unsigned long offset, unsigned long count, char *buf){
120     return ((CardFS*)ctx)->do_write(file, offset, count, buf);
121 }
122
123 int     
124 cardfs_readlink(void *ctx, char *link, char *buf, int buflen){
125     return ((CardFS*)ctx)->do_readlink(link, buf, buflen);
126 }
127
128 int     
129 cardfs_link(void *ctx, char *target, char *link){
130     return ((CardFS*)ctx)->do_link(target, link);
131 }
132
133 int     
134 cardfs_symlink(void *ctx, char *target, char *link){
135     return ((CardFS*)ctx)->do_symlink(target, link);
136 }
137
138 int     
139 cardfs_setattr(void *ctx, char *file, struct lufs_fattr *fattr){
140     return ((CardFS*)ctx)->do_setattr(file, fattr);
141 }
142
143 } /* extern "C" */
144
145 CardFS::CardFS(struct list_head *c, struct dir_cache *cache, struct credentials *cred)
146 {
147     cfg = c;
148     this->cache = cache;
149     this->cred = cred;
150
151     _cid="LUFS:CardFS:"+CTMisc::num2string(getpid());
152 }
153
154 CardFS::~CardFS(){
155 }
156
157 int
158 CardFS::do_mount(){
159     unsigned int pos;
160     string tmp;
161
162     try {
163         tmp=options.o_host;
164         pos=tmp.find("@");
165         if (pos!=string::npos) {
166             _terminal=tmp.substr(0,pos);
167             if (pos+1<tmp.length())
168                 _host=tmp.substr(pos+1);
169         }
170         else
171             _host=tmp;
172
173         FileClient client(_cid, InetAddress(_host.c_str()),
174                           options.o_port,
175                           10,
176                           TIMEOUT1,
177                           TIMEOUT2);
178         return client.mount(_terminal,
179                             options.o_username,
180                             options.o_password);
181     }
182     catch (Status st) {
183         TRACE("Exception: "<<st.statusHistory());
184         return 0;
185     }
186 }
187
188
189 void
190 CardFS::do_umount(){
191     FileClient client(_cid, InetAddress(_host.c_str()),
192                       options.o_port,
193                       10,
194                       TIMEOUT1,
195                       TIMEOUT2);
196     // force unmounting !
197     client.unmount(true);
198 }
199
200 struct lufs_fattr CardFS::_entry2fattr(const CTDirEntry &e) {
201     struct lufs_fattr fattr;
202     int acc;
203
204     acc=0;
205     if (e.attributes() & CTDirEntry::Attr_DIR) {
206         acc|=S_IFDIR;
207         acc|=S_IXUSR;
208     }
209     else
210         acc|=S_IFREG;
211
212     if (e.attributes() & CTDirEntry::Attr_READ) {
213         acc|=S_IRUSR;
214     }
215     if (e.attributes() & CTDirEntry::Attr_WRITE) {
216         acc|=S_IWUSR;
217     }
218
219     fattr.f_mode = acc;
220     fattr.f_nlink = 1;
221     fattr.f_uid = getuid();
222     fattr.f_gid = getgid();
223     fattr.f_size = e.size();
224     fattr.f_atime = 0;
225     fattr.f_mtime = 0;
226     fattr.f_ctime = 0;
227     return fattr;
228 }
229
230 int
231 CardFS::do_readdir(char* d, struct directory *dir){
232     struct lufs_fattr fattr;
233     int i;
234     CTDirEntry entry;
235     
236     INFO("do_readdir "<<d);
237     FileClient client(_cid, InetAddress(_host.c_str()),
238                       options.o_port,
239                       10,
240                       TIMEOUT1,
241                       TIMEOUT2);
242
243     // create "." entry
244     entry=CTDirEntry(-1,
245                      ".",
246                      CTDirEntry::Attr_DIR   |
247                      CTDirEntry::Attr_READ  |
248                      CTDirEntry::Attr_WRITE);
249     fattr=_entry2fattr(entry);
250     lu_cache_add2dir(dir, (char*)entry.name().c_str(), NULL, &fattr);
251
252     // create ".." entry
253     entry=CTDirEntry(-1,
254                      "..",
255                      CTDirEntry::Attr_DIR   |
256                      CTDirEntry::Attr_READ  |
257                      CTDirEntry::Attr_WRITE);
258     fattr=_entry2fattr(entry);
259     lu_cache_add2dir(dir, (char*)entry.name().c_str(), NULL, &fattr);
260
261     i=0;
262     while(client.readDir(d,entry,i++)>=0) {
263         if (entry.attributes() & CTDirEntry::Attr_USED) {
264             fattr=_entry2fattr(entry);
265             lu_cache_add2dir(dir, (char*)entry.name().c_str(), NULL, &fattr);
266         }
267     } // while
268
269     return 0;
270 }
271
272
273 int
274 CardFS::do_stat(char *nm, struct lufs_fattr *fattr){
275     int result;
276     CTDirEntry entry;
277
278     INFO("do_stat "<<nm);
279     FileClient client(_cid, InetAddress(_host.c_str()),
280                       options.o_port,
281                       10,
282                       TIMEOUT1,
283                       TIMEOUT2);
284
285     result=client.statFile(nm,
286                            entry);
287     if (result<0)
288         return result;
289     if (entry.attributes() & CTDirEntry::Attr_USED)
290         *fattr=_entry2fattr(entry);
291     else
292         return -1;
293     return 0;
294 }
295
296 unsigned int CardFS::_mode2attribs(int mode) {
297     unsigned int att;
298
299     att=0;
300
301     if (mode & S_IRUSR)
302         att|=CTDirEntry::Attr_READ;
303     if (mode & S_IWUSR)
304         att|=CTDirEntry::Attr_WRITE;
305     if (mode & S_IFDIR)
306         att|=CTDirEntry::Attr_DIR;
307     att|=CTDirEntry::Attr_USED;
308     return att;
309 }
310
311 int CardFS::do_mkdir(char *d, int mode){
312     int result;
313
314     FileClient client(_cid, InetAddress(_host.c_str()),
315                       options.o_port,
316                       10,
317                       TIMEOUT1,
318                       TIMEOUT2);
319     result=client.mkDir(d,_mode2attribs(mode));
320
321     return result;
322 }
323
324 int
325 CardFS::do_rmdir(char *d){
326     int result;
327
328     FileClient client(_cid, InetAddress(_host.c_str()),
329                       options.o_port,
330                       10,
331                       TIMEOUT1,
332                       TIMEOUT2);
333     result=client.rmDir(d);
334     return result;
335 }
336
337 int
338 CardFS::do_create(char *fn, int mode){
339     int result;
340
341     INFO("CardFS::do_create "<<fn);
342     FileClient client(_cid, InetAddress(_host.c_str()),
343                       options.o_port,
344                       10,
345                       TIMEOUT1,
346                       TIMEOUT2);
347     result=client.createFile(fn,_mode2attribs(mode));
348     return result;
349 }
350
351
352 int
353 CardFS::do_unlink(char *fn){
354     int result;
355
356     FileClient client(_cid, InetAddress(_host.c_str()),
357                       options.o_port,
358                       10,
359                       TIMEOUT1,
360                       TIMEOUT2);
361     result=client.unlinkFile(fn);
362     return result;
363 }
364
365 int
366 CardFS::do_rename(char *old, char *nnew){
367     int result;
368
369     INFO("do_rename "<<old<<"->"<<nnew);
370
371     FileClient client(_cid, InetAddress(_host.c_str()),
372                       options.o_port,
373                       10,
374                       TIMEOUT1,
375                       TIMEOUT2);
376     result=client.renameFile(old,nnew);
377
378     return result;
379 }
380
381 int
382 CardFS::do_open(char *fn, unsigned mode){
383     struct lufs_fattr fattr;
384     INFO("do_open "<<fn);
385
386     return do_stat(fn,&fattr);
387 }
388
389
390 int
391 CardFS::do_release(char *file){
392     INFO("do_release "<<file);
393
394     return 1;
395 }
396
397 int
398 CardFS::do_read(char *fn, unsigned long offset, unsigned long count, char *buf){
399     int result;
400     string tmp;
401
402     INFO("do_read "<<fn);
403     FileClient client(_cid, InetAddress(_host.c_str()),
404                       options.o_port,
405                       10,
406                       TIMEOUT1,
407                       TIMEOUT2);
408
409     result=client.readFile(fn,
410                            offset,
411                            count,
412                            tmp);
413     if (result<0)
414         return -1;
415     memmove(buf,tmp.c_str(),tmp.length());
416     return result;
417 }
418
419 int
420 CardFS::do_write(char *fn, unsigned long offset, unsigned long count, char *buf){
421     FileClient client(_cid, InetAddress(_host.c_str()),
422                       options.o_port,
423                       10,
424                       TIMEOUT1,
425                       TIMEOUT2);
426     return client.writeFile(fn,offset,count,buf);
427 }
428
429 int
430 CardFS::do_readlink(char *link, char *buf, int buflen){
431     INFO("CardFS::do_readlink "<<link);
432     return -1;
433 }
434
435 int
436 CardFS::do_link(char *old, char *nnew){
437     INFO("CardFS::do_link "<<old<<"->"<<nnew);
438     return -1;
439 }
440
441 int CardFS::do_symlink(char *old, char *nnew){
442     INFO("CardFS::do_symlink "<<old<<"->"<<nnew);
443     return -1;
444 }
445
446 int CardFS::do_setattr(char *f, struct lufs_fattr *fattr){
447
448     INFO("CardFS::do_setattr "<<f<<"(ignored)");
449
450     return 0;
451 }
452
453