2 * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * LATCHESAR IONKOV AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
23 #define _XOPEN_SOURCE 600
32 #include <gphoto2/gphoto2.h>
36 #define NELEM(x) (sizeof(x)/sizeof((x)[0]))
38 typedef struct File File
;
47 static u32
gpfs_read(Npfilefid
*, u64
, u32
, u8
*, Npreq
*);
48 static u32
gpfs_write(Npfilefid
*, u64
, u32
, u8
*, Npreq
*);
49 static int gpfs_wstat(Npfile
*, Npstat
*);
50 static void gpfs_destroy(Npfile
*);
51 static Npfile
* gpfs_create(Npfile
*, char *, u32
, Npuser
*, Npgroup
*);
52 static Npfile
* gpfs_first(Npfile
*);
53 static Npfile
* gpfs_next(Npfile
*, Npfile
*);
54 static int gpfs_wstat(Npfile
*, Npstat
*);
55 static int gpfs_remove(Npfile
*, Npfile
*);
56 static int gpfs_openfid(Npfilefid
*);
57 static void gpfs_closefid(Npfilefid
*);
64 static GPContext
*ctx
;
70 .destroy
= gpfs_destroy
,
71 .openfid
= gpfs_openfid
,
72 .closefid
= gpfs_closefid
,
76 .create
= gpfs_create
,
80 .remove
= gpfs_remove
,
81 .destroy
= gpfs_destroy
,
84 static File
* file_alloc(char *);
89 fprintf(stderr
, "gphotofs: -d -u user -w nthreads "
90 "-o mount-options mount-point\n");
95 main(int argc
, char **argv
)
97 int err
, c
, debuglevel
, nwthreads
;
103 user
= np_uid2user(getuid());
104 while ((c
= getopt(argc
, argv
, "du:w:o:")) != -1) {
111 user
= np_uname2user(optarg
);
115 nwthreads
= strtol(optarg
, &s
, 10);
125 fprintf(stderr
, "invalid option\n");
130 fprintf(stderr
, "invalid user\n");
134 ctx
= gp_context_new();
137 err
= gp_camera_init(cam
, ctx
);
139 fprintf(stderr
, "cannot initialize the camera: %d\n", err
);
143 root
= npfile_alloc(NULL
, strdup(""), ROOTPERM
|Dmdir
, qidpath
++,
144 &dirops
, file_alloc(""));
148 root
->atime
= time(NULL
);
149 root
->mtime
= root
->atime
;
151 root
->gid
= user
->dfltgroup
;
154 srv
= np_pipesrv_create(nwthreads
);
158 npfile_init_srv(srv
, root
);
162 srv
->debuglevel
= debuglevel
;
163 np_pipesrv_mount(srv
, argv
[optind
], user
->uname
, 0, opts
);
173 file_alloc(char *path
)
177 f
= malloc(sizeof(*f
));
178 f
->path
= strdup(path
);
187 gpfs_read(Npfilefid
*fid
, u64 offset
, u32 count
, u8
*data
, Npreq
*req
)
196 if (file
->length
< offset
+count
)
197 n
= file
->length
- offset
;
202 memmove(data
, f
->data
+ offset
, n
);
207 gpfs_write(Npfilefid
*fid
, u64 offset
, u32 count
, u8
*data
, Npreq
*req
)
209 np_werror("permission denied", EPERM
);
214 gpfs_wstat(Npfile
*file
, Npstat
*stat
)
216 np_werror("permission denied", EPERM
);
221 gpfs_destroy(Npfile
* file
)
225 fprintf(stderr
, "destroy file: %s\n", file
->name
);
227 gp_file_unref(f
->camfile
);
233 gpfs_create(Npfile
*dir
, char *name
, u32 perm
, Npuser
*uid
, Npgroup
*gid
)
235 np_werror("permission denied", EPERM
);
240 read_files(Npfile
*dir
)
249 CameraFileInfo finfo
;
253 folder = strdup("/");
257 if (strcmp(p
, "/") == 0)
261 nlen
= strlen(dir
->name
);
262 folder
= malloc(plen
+ nlen
+ 2);
263 memcpy(folder
, p
, plen
);
265 strcpy(folder
+ plen
+ 1, dir
->name
);
269 gp_camera_folder_list_files(cam
, folder
, cl
, ctx
);
270 n
= gp_list_count(cl
);
271 for(i
= 0; i
< n
; i
++) {
272 gp_list_get_name(cl
, i
, &fname
);
273 gp_camera_file_get_info(cam
, folder
, fname
, &finfo
, ctx
);
275 nf
= npfile_alloc(dir
, (char *) fname
, 0500, qidpath
++,
276 &fileops
, file_alloc(folder
));
277 nf
->mtime
= finfo
.file
.mtime
;
278 nf
->atime
= nf
->mtime
;
280 nf
->gid
= user
->dfltgroup
;
282 nf
->length
= finfo
.file
.size
;
284 dir
->dirlast
->next
= nf
;
285 nf
->prev
= dir
->dirlast
;
293 gp_camera_folder_list_folders(cam
, folder
, cl
, ctx
);
294 n
= gp_list_count(cl
);
295 for(i
= 0; i
< n
; i
++) {
296 gp_list_get_name(cl
, i
, &fname
);
298 nf
= npfile_alloc(dir
, (char *) fname
, 0500|Dmdir
, qidpath
++,
299 &dirops
, file_alloc(folder
));
301 nf
->gid
= user
->dfltgroup
;
304 dir
->dirlast
->next
= nf
;
305 nf
->prev
= dir
->dirlast
;
315 gpfs_first(Npfile
*dir
)
320 npfile_incref(dir
->dirfirst
);
321 return dir
->dirfirst
;
325 gpfs_next(Npfile
*dir
, Npfile
*prevchild
)
327 npfile_incref(prevchild
->next
);
328 return prevchild
->next
;
332 gpfs_remove(Npfile
*dir
, Npfile
*file
)
334 np_werror("permission denied", EPERM
);
339 gpfs_openfid(Npfilefid
*fid
)
350 gp_file_new(&f
->camfile
);
351 n
= gp_camera_file_get(cam
, f
->path
, file
->name
,
352 GP_FILE_TYPE_RAW
, f
->camfile
, ctx
);
354 fprintf(stderr
, "error getting file: %d\n", n
);
355 np_werror("error getting file", EIO
);
359 gp_file_get_data_and_size(f
->camfile
, &f
->data
, &len
);
368 gpfs_closefid(Npfilefid
*fid
)
377 gp_file_unref(f
->camfile
);