"Fossies" - the Fresh Open Source Software Archive 
Member "libgphoto2-2.5.27/camlibs/directory/directory.c" (26 Oct 2020, 20442 Bytes) of package /linux/privat/libgphoto2-2.5.27.tar.bz2:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "directory.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.5.26_vs_2.5.27.
1 /* directory.c
2 *
3 * Copyright (c) 2001 Lutz Mueller <lutz@users.sf.net>
4 * Copyright (c) 2005 Marcus Meissner <marcus@jet.franken.de>
5 * Copyright (c) 2007 Hubert Figuiere <hub@figuiere.net>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
21 */
22
23 #define _DEFAULT_SOURCE
24
25 #include "config.h"
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <utime.h>
33 #ifdef HAVE_SYS_STATVFS_H
34 # include <sys/statvfs.h>
35 #endif
36 #ifdef HAVE_SYS_PARAM_H
37 # include <sys/param.h>
38 #endif
39 #ifdef HAVE_SYS_VFS_H
40 # include <sys/vfs.h>
41 #endif
42 #ifdef HAVE_SYS_MOUNT_H
43 # include <sys/mount.h>
44 #endif
45 #include <fcntl.h>
46
47 /* will happen only on Win32 */
48 #ifndef HAVE_LSTAT
49 #define lstat stat
50 #endif
51
52 #ifdef HAVE_LIBEXIF
53 #include <libexif/exif-data.h>
54 #endif
55
56 #include <gphoto2/gphoto2-setting.h>
57 #include <gphoto2/gphoto2-library.h>
58 #include <gphoto2/gphoto2-port.h>
59 #include <gphoto2/gphoto2-port-log.h>
60 #include <gphoto2/gphoto2-port-portability.h>
61
62 #ifdef ENABLE_NLS
63 # include <libintl.h>
64 # undef _
65 # define _(String) dgettext (GETTEXT_PACKAGE, String)
66 # ifdef gettext_noop
67 # define N_(String) gettext_noop (String)
68 # else
69 # define N_(String) (String)
70 # endif
71 #else
72 # define textdomain(String) (String)
73 # define gettext(String) (String)
74 # define dgettext(Domain,Message) (Message)
75 # define dcgettext(Domain,Message,Type) (Message)
76 # define bindtextdomain(Domain,Directory) (Domain)
77 # define _(String) (String)
78 # define N_(String) (String)
79 #endif
80
81 static const struct {
82 const char *extension;
83 const char *mime_type;
84 } mime_table[] = {
85 {"jpeg", GP_MIME_JPEG},
86 {"jpg", GP_MIME_JPEG},
87 {"thm", GP_MIME_JPEG},
88 {"tif", GP_MIME_TIFF},
89 {"ppm", GP_MIME_PPM},
90 {"pgm", GP_MIME_PGM},
91 {"avi", GP_MIME_AVI},
92 {"mov", GP_MIME_QUICKTIME},
93 {"moov", GP_MIME_QUICKTIME},
94 {"qt", GP_MIME_QUICKTIME},
95 {"qtvr", GP_MIME_QUICKTIME},
96 {"mp2", GP_MIME_MPEG},
97 {"mp3", GP_MIME_MPEG},
98 {"mp4", GP_MIME_MPEG},
99 {"mpg", GP_MIME_MPEG},
100 {"mpeg", GP_MIME_MPEG},
101 {"mpe", GP_MIME_MPEG},
102 {"ogg", GP_MIME_OGG},
103 {"mts", GP_MIME_AVCHD},
104 {"m2ts", GP_MIME_AVCHD},
105 {"pbm", "image/x-portable-bitmap"},
106 {"crw", GP_MIME_CRW},
107 {"rw2", GP_MIME_RW2},
108 {"cr2", GP_MIME_RAW},
109 {"cr3", GP_MIME_RAW},
110 {"nef", GP_MIME_RAW},
111 {"mrw", GP_MIME_RAW},
112 {"dng", GP_MIME_RAW},
113 {"sr2", GP_MIME_RAW},
114 {"raf", GP_MIME_RAW},
115 {"erf", GP_MIME_RAW},
116 {"orf", GP_MIME_RAW},
117 {"arw", GP_MIME_RAW},
118 {"pef", GP_MIME_RAW},
119 {"raw", GP_MIME_RAW},
120 {"dcr", GP_MIME_RAW},
121 {"x3f", GP_MIME_RAW},
122 {"srw", GP_MIME_RAW},
123 {"gf1", GP_MIME_RAW},
124 {"srw", GP_MIME_RAW},
125 {"nrw", GP_MIME_RAW},
126 {"png", GP_MIME_PNG},
127 {"wav", GP_MIME_WAV},
128 {"3gp", "video/3gpp"},
129 {"3g2", "video/x-3gpp2"},
130 {"dif", "video/dv"},
131 {NULL, NULL}
132 };
133
134 /* #define DEBUG */
135 /* #define FOLLOW_LINKS */
136
137 #define GP_MODULE "directory"
138
139 static const char *
140 get_mime_type (const char *filename)
141 {
142
143 char *dot;
144 int x=0;
145
146 dot = strrchr(filename, '.');
147 if (dot) {
148 for (x = 0; mime_table[x].extension; x++) {
149 #ifdef OS2
150 if (!stricmp(mime_table[x].extension, dot+1))
151 #else
152 if (!strcasecmp (mime_table[x].extension, dot+1))
153 #endif
154 return (mime_table[x].mime_type);
155 }
156 }
157
158 return (NULL);
159 }
160
161 int camera_id (CameraText *id)
162 {
163 strcpy(id->text, "directory");
164
165 return (GP_OK);
166 }
167
168
169 int camera_abilities (CameraAbilitiesList *list)
170 {
171 CameraAbilities a;
172
173 memset(&a, 0, sizeof(a));
174 strcpy(a.model, "Directory Browse");
175 a.status = GP_DRIVER_STATUS_PRODUCTION;
176 a.port = GP_PORT_DISK;
177 a.speed[0] = 0;
178
179 a.operations = GP_OPERATION_NONE;
180
181 #ifdef DEBUG
182 a.file_operations = GP_FILE_OPERATION_PREVIEW |
183 GP_FILE_OPERATION_DELETE |
184 GP_FILE_OPERATION_EXIF;
185 #else
186 a.file_operations = GP_FILE_OPERATION_DELETE |
187 GP_FILE_OPERATION_EXIF;
188 #endif
189 a.folder_operations = GP_FOLDER_OPERATION_MAKE_DIR |
190 GP_FOLDER_OPERATION_REMOVE_DIR |
191 GP_FOLDER_OPERATION_PUT_FILE;
192
193 gp_abilities_list_append(list, a);
194
195 /* Since "Directory Browse" is hardcoded in clients,
196 * better also add a new name here.
197 */
198 strcpy(a.model, "Mass Storage Camera");
199 gp_abilities_list_append(list, a);
200 return (GP_OK);
201 }
202
203 static int
204 _get_mountpoint(GPPort *port, char **path) {
205 GPPortInfo info;
206 int ret;
207 char *p;
208
209 ret = gp_port_get_info (port, &info);
210 if (ret < GP_OK)
211 return ret;
212 ret = gp_port_info_get_path (info, path);
213 if (ret < GP_OK)
214 return ret;
215 p = strchr (*path, ':');
216 if (p) *path = p+1;
217 return GP_OK;
218 }
219
220 static int
221 _get_path (GPPort *port, const char *folder, const char *file, char *path, unsigned int size) {
222 if (port->type == GP_PORT_DISK) {
223 int ret;
224 char *xpath;
225
226 ret = _get_mountpoint (port, &xpath);
227 if (ret < GP_OK)
228 return ret;
229 snprintf (path, size, "%s/%s/%s", xpath, folder, file);
230 } else {
231 /* old style access */
232 snprintf (path, size, "%s/%s", folder, file);
233 }
234 return GP_OK;
235 }
236
237
238 static int
239 file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
240 void *data, GPContext *context)
241 {
242 gp_system_dir dir;
243 gp_system_dirent de;
244 char buf[1024], f[1024];
245 unsigned int id, n;
246 int ret;
247 Camera *camera = (Camera*)data;
248
249 if (camera->port->type == GP_PORT_DISK) {
250 char *path;
251
252 ret = _get_mountpoint (camera->port, &path);
253 if (ret < GP_OK)
254 return ret;
255 snprintf (f, sizeof(f), "%s/%s/", path, folder);
256 /* UNIX / is empty, or we recurse through the whole fs */
257 if ( (!strcmp(path, "") || !strcmp(path, "/")) &&
258 !strcmp(folder,"/")
259 )
260 return GP_OK;
261 } else {
262 /* old style access */
263 if (folder[strlen(folder)-1] != '/') {
264 snprintf (f, sizeof(f), "%s%c", folder, '/');
265 } else {
266 strncpy (f, folder, sizeof(f));
267 }
268 }
269 dir = gp_system_opendir ((char*) f);
270 if (!dir)
271 return (GP_ERROR);
272
273 /* Make sure we have 1 delimiter */
274
275 /* Count the files */
276 n = 0;
277 while (gp_system_readdir (dir))
278 n++;
279
280 gp_system_closedir (dir);
281 dir = gp_system_opendir (f);
282 if (!dir)
283 return (GP_ERROR);
284 id = gp_context_progress_start (context, n, _("Listing files in "
285 "'%s'..."), f);
286 n = 0;
287 while ((de = gp_system_readdir(dir))) {
288 const char * filename = NULL;
289 /* Give some feedback */
290 gp_context_progress_update (context, id, n + 1);
291 gp_context_idle (context);
292 if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) {
293 gp_system_closedir (dir);
294 return (GP_ERROR_CANCEL);
295 }
296
297 filename = gp_system_filename(de);
298 if (*filename != '.') {
299 snprintf (buf, sizeof(buf), "%s%s", f, filename);
300 if (gp_system_is_file (buf) && (get_mime_type (buf))) {
301 gp_list_append (list, filename, NULL);
302 }
303 }
304 n++;
305 }
306 gp_system_closedir (dir);
307 gp_context_progress_stop (context, id);
308
309 return (GP_OK);
310 }
311
312 static int
313 folder_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
314 void *data, GPContext *context)
315 {
316 gp_system_dir dir;
317 gp_system_dirent de;
318 char buf[1024], f[1024];
319 unsigned int id, n;
320 struct stat st;
321 Camera *camera = (Camera*)data;
322
323 if (camera->port->type == GP_PORT_DISK) {
324 char *path;
325 int ret;
326
327 ret = _get_mountpoint (camera->port, &path);
328 if (ret < GP_OK)
329 return ret;
330
331 snprintf (f, sizeof(f), "%s/%s/", path, folder);
332 /* UNIX / is empty, or we recurse through the whole fs */
333 if ( (!strcmp(path, "") || !strcmp(path, "/")) &&
334 !strcmp(folder,"/")
335 )
336 return GP_OK;
337 } else {
338 /* old style access */
339 /* Make sure we have 1 delimiter */
340 if (folder[strlen(folder)-1] != '/') {
341 snprintf (f, sizeof(f), "%s%c", folder, '/');
342 } else {
343 strncpy (f, folder, sizeof(f));
344 }
345 }
346 dir = gp_system_opendir ((char*) f);
347 if (!dir)
348 return GP_ERROR;
349 /* Count the files */
350 n = 0;
351 while (gp_system_readdir (dir))
352 n++;
353 gp_system_closedir (dir);
354
355 dir = gp_system_opendir (f);
356 if (!dir)
357 return GP_ERROR;
358 id = gp_context_progress_start (context, n, _("Listing folders in "
359 "'%s'..."), folder);
360 n = 0;
361 while ((de = gp_system_readdir (dir))) {
362 const char * filename = NULL;
363
364 /* Give some feedback */
365 gp_context_progress_update (context, id, n + 1);
366 gp_context_idle (context);
367 if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) {
368 gp_system_closedir (dir);
369 return GP_ERROR_CANCEL;
370 }
371 filename = gp_system_filename (de);
372 if (*filename != '.') {
373 snprintf (buf, sizeof(buf), "%s%s", f, filename);
374
375 /* lstat ... do not follow symlinks */
376 if (lstat (buf, &st) != 0) {
377 int saved_errno = errno;
378 gp_context_error (context, _("Could not get information "
379 "about '%s' (%s)."),
380 buf, strerror(saved_errno));
381 gp_system_closedir (dir);
382 return GP_ERROR;
383 }
384 if (S_ISDIR (st.st_mode)) {
385 gp_list_append(list, filename, NULL);
386 }
387 }
388 n++;
389 }
390 gp_system_closedir (dir);
391 gp_context_progress_stop (context, id);
392 return (GP_OK);
393 }
394
395 static int
396 get_info_func (CameraFilesystem *fs, const char *folder, const char *file,
397 CameraFileInfo *info, void *data, GPContext *context)
398 {
399 char path[1024];
400 const char *mime_type;
401 struct stat st;
402 Camera *camera = (Camera*)data;
403 int result;
404
405 result = _get_path (camera->port, folder, file, path, sizeof(path));
406 if (result < GP_OK)
407 return result;
408
409 if (lstat (path, &st) != 0) {
410 int saved_errno = errno;
411 gp_context_error (context, _("Could not get information "
412 "about '%s' in '%s' (%s)."),
413 file, folder, strerror(saved_errno));
414 return (GP_ERROR);
415 }
416
417 info->preview.fields = GP_FILE_INFO_NONE;
418 info->file.fields = GP_FILE_INFO_SIZE |
419 GP_FILE_INFO_TYPE | GP_FILE_INFO_PERMISSIONS |
420 GP_FILE_INFO_MTIME;
421
422 info->file.mtime = st.st_mtime;
423 info->file.permissions = GP_FILE_PERM_NONE;
424 if (st.st_mode & S_IRUSR)
425 info->file.permissions |= GP_FILE_PERM_READ;
426 if (st.st_mode & S_IWUSR)
427 info->file.permissions |= GP_FILE_PERM_DELETE;
428 info->file.size = st.st_size;
429 mime_type = get_mime_type (file);
430 if (!mime_type)
431 mime_type = GP_MIME_UNKNOWN;
432 strcpy (info->file.type, mime_type);
433 return (GP_OK);
434 }
435
436 static int
437 set_info_func (CameraFilesystem *fs, const char *folder, const char *file,
438 CameraFileInfo info, void *data, GPContext *context)
439 {
440 int retval;
441 char path[1024];
442 Camera *camera = (Camera*)data;
443
444 retval = _get_path (camera->port, folder, file, path, sizeof(path));
445 if (retval < GP_OK)
446 return retval;
447
448 /* We don't support updating permissions (yet) */
449 if (info.file.fields & GP_FILE_INFO_PERMISSIONS)
450 return (GP_ERROR_NOT_SUPPORTED);
451
452 if (info.file.fields & GP_FILE_INFO_MTIME) {
453 struct utimbuf utimbuf;
454
455 utimbuf.actime = info.file.mtime;
456 utimbuf.modtime = info.file.mtime;
457 if (utime (path, &utimbuf) != 0) {
458 int saved_errno = errno;
459 gp_context_error (context, _("Could not change "
460 "time of file '%s' in '%s' (%s)."),
461 file, folder, strerror(saved_errno));
462 return (GP_ERROR);
463 }
464 }
465
466 #if 0 /* implement this using new api -Marcus */
467 if (info.file.fields & GP_FILE_INFO_NAME) {
468 if (!strcasecmp (info.file.name, file))
469 return (GP_OK);
470
471 /* We really have to rename the poor file... */
472 if (strlen (folder) == 1) {
473 snprintf (path_old, sizeof (path_old), "/%s",
474 file);
475 snprintf (path_new, sizeof (path_new), "/%s",
476 info.file.name);
477 } else {
478 snprintf (path_old, sizeof (path_old), "%s/%s",
479 folder, file);
480 snprintf (path_new, sizeof (path_new), "%s/%s",
481 folder, info.file.name);
482 }
483 retval = rename (path_old, path_new);
484 if (retval != 0) {
485 switch (errno) {
486 case EISDIR:
487 return (GP_ERROR_DIRECTORY_EXISTS);
488 case EEXIST:
489 return (GP_ERROR_FILE_EXISTS);
490 case EINVAL:
491 return (GP_ERROR_BAD_PARAMETERS);
492 case EIO:
493 return (GP_ERROR_IO);
494 case ENOMEM:
495 return (GP_ERROR_NO_MEMORY);
496 case ENOENT:
497 return (GP_ERROR_FILE_NOT_FOUND);
498 default:
499 return (GP_ERROR);
500 }
501 }
502 }
503 #endif
504
505 return (GP_OK);
506 }
507
508 static int
509 get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
510 CameraFileType type, CameraFile *file, void *user_data,
511 GPContext *context)
512 {
513 char path[1024];
514 int result = GP_OK;
515 struct stat stbuf;
516 int fd, id;
517 off_t curread, toread;
518 unsigned char *buf;
519 #ifdef HAVE_LIBEXIF
520 ExifData *data;
521 unsigned int buf_len;
522 #endif /* HAVE_LIBEXIF */
523 Camera *camera = (Camera*)user_data;
524
525 result = _get_path (camera->port, folder, filename, path, sizeof(path));
526 if (result < GP_OK)
527 return result;
528
529 if (-1 == lstat(path,&stbuf))
530 return GP_ERROR_IO_READ;
531
532 gp_file_set_mtime (file, stbuf.st_mtime);
533
534 switch (type) {
535 case GP_FILE_TYPE_NORMAL:
536 #ifdef DEBUG
537 case GP_FILE_TYPE_PREVIEW:
538 #endif
539 fd = open (path,O_RDONLY);
540 if (fd == -1)
541 return GP_ERROR_IO_READ;
542 break;
543 #ifdef HAVE_LIBEXIF
544 case GP_FILE_TYPE_EXIF:
545 data = exif_data_new_from_file (path);
546 if (!data) {
547 gp_context_error (context, _("Could not open '%s'."),
548 path);
549 return (GP_ERROR);
550 }
551 exif_data_save_data (data, &buf, &buf_len);
552 exif_data_unref (data);
553 gp_file_set_data_and_size (file, (char *)buf, buf_len);
554 return (GP_OK);
555 #endif /* HAVE_LIBEXIF */
556 default:
557 return (GP_ERROR_NOT_SUPPORTED);
558 }
559 #define BLOCKSIZE 65536
560 /* do it in 64kb blocks */
561 buf = malloc(BLOCKSIZE);
562 if (!buf) {
563 close (fd);
564 return GP_ERROR_NO_MEMORY;
565 }
566 if (-1 == fstat(fd,&stbuf)) {
567 free (buf);
568 close (fd);
569 return GP_ERROR_IO_READ;
570 }
571
572 curread = 0;
573 id = gp_context_progress_start (context, (1.0*stbuf.st_size/BLOCKSIZE), _("Getting file..."));
574 GP_DEBUG ("Progress id: %i", id);
575 result = GP_OK;
576 while (curread < stbuf.st_size) {
577 int ret;
578
579 toread = stbuf.st_size-curread;
580 if (toread>BLOCKSIZE) toread = BLOCKSIZE;
581 ret = read(fd,buf,toread);
582 if (ret == -1) {
583 result = GP_ERROR_IO_READ;
584 break;
585 }
586 curread += ret;
587 gp_file_append (file, (char *)buf, ret);
588 gp_context_progress_update (context, id, (1.0*curread/BLOCKSIZE));
589 gp_context_idle (context);
590 if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) {
591 result = GP_ERROR_CANCEL;
592 break;
593 }
594 #if 0
595 /* We could take 2 seconds to download this image. everytime. */
596 /* But actually this driver is used in production by some frontends,
597 * so do not delay at all
598 */
599 usleep(2000000/(stbuf.st_size/BLOCKSIZE));
600 #endif
601 }
602 gp_context_progress_stop (context, id);
603 free (buf);
604 close (fd);
605 return (GP_OK);
606 }
607
608 static int
609 camera_manual (Camera *camera, CameraText *manual, GPContext *context)
610 {
611 strcpy (manual->text, _("The Directory Browse \"camera\" lets "
612 "you index photos on your hard drive."));
613
614 return (GP_OK);
615 }
616
617 static int
618 camera_about (Camera *camera, CameraText *about, GPContext *context)
619 {
620 strcpy (about->text, _("Directory Browse Mode - written "
621 "by Scott Fritzinger <scottf@unr.edu>."));
622
623 return (GP_OK);
624 }
625
626 static int
627 make_dir_func (CameraFilesystem *fs, const char *folder, const char *name,
628 void *data, GPContext *context)
629 {
630 char path[2048];
631 Camera *camera = (Camera*)data;
632 int result;
633
634 result = _get_path (camera->port, folder, name, path, sizeof(path));
635 if (result < GP_OK)
636 return result;
637 return gp_system_mkdir (path);
638 }
639
640 static int
641 remove_dir_func (CameraFilesystem *fs, const char *folder, const char *name,
642 void *data, GPContext *context)
643 {
644 char path[2048];
645 Camera *camera = (Camera*)data;
646 int result;
647
648 result = _get_path (camera->port, folder, name, path, sizeof(path));
649 if (result < GP_OK)
650 return result;
651 return gp_system_rmdir (path);
652 }
653
654 static int
655 delete_file_func (CameraFilesystem *fs, const char *folder,
656 const char *file, void *data, GPContext *context)
657 {
658 char path[2048];
659 int result;
660 Camera *camera = (Camera*)data;
661
662 result = _get_path (camera->port, folder, file, path, sizeof(path));
663 if (result < GP_OK)
664 return result;
665 result = unlink (path);
666 if (result) {
667 int saved_errno = errno;
668 gp_context_error (context, _("Could not delete file '%s' "
669 "in folder '%s' (error code %i: %s)."),
670 file, folder, result, strerror(saved_errno));
671 return (GP_ERROR);
672 }
673
674 return (GP_OK);
675 }
676
677 static int
678 put_file_func (CameraFilesystem *fs, const char *folder, const char *name,
679 CameraFileType type, CameraFile *file, void *data, GPContext *context)
680 {
681 char path[2048];
682 int result;
683 #ifdef DEBUG
684 unsigned int i, id;
685 #endif
686 Camera *camera = (Camera*)data;
687
688 result = _get_path (camera->port, folder, name, path, sizeof(path));
689 if (result < GP_OK)
690 return result;
691
692 result = gp_file_save (file, path);
693 if (result < 0)
694 return (result);
695
696 #ifdef DEBUG
697 id = gp_context_progress_start (context, 500., "Uploading file...");
698 for (i = 0; i < 500; i++) {
699 gp_context_progress_update (context, id, i + 1);
700 gp_context_idle (context);
701 if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
702 return (result);
703 usleep (10);
704 }
705 gp_context_progress_stop (context, id);
706 #endif
707
708 return (GP_OK);
709 }
710
711 #ifdef DEBUG
712 static int
713 camera_capture_preview (Camera *camera, CameraFile *file, GPContext *context)
714 {
715 int r;
716
717 r = gp_file_open (file, "/usr/share/pixmaps/gnome-logo-large.png");
718 if (r < 0)
719 return (r);
720
721 return (GP_OK);
722 }
723
724 static int
725 camera_capture (Camera *camera, CameraCaptureType type, CameraFilePath *path,
726 GPContext *context)
727 {
728 if (path) {
729 strcpy (path->folder, "/usr/share/pixmaps");
730 strcpy (path->name, "gnome-logo-large.png");
731 }
732
733 return (GP_OK);
734 }
735 #endif
736
737 static int
738 storage_info_func (CameraFilesystem *fs,
739 CameraStorageInformation **sinfos,
740 int *nrofsinfos,
741 void *data, GPContext *context
742 ) {
743 Camera *camera = data;
744 CameraStorageInformation *sfs;
745
746 #if defined(HAVE_STATVFS)
747 struct statvfs stfs;
748 char *xpath;
749 int ret;
750
751 ret = _get_mountpoint (camera->port, &xpath);
752 if (ret < GP_OK)
753 return ret;
754 if (-1 == statvfs (xpath, &stfs))
755 return GP_ERROR_NOT_SUPPORTED;
756
757 sfs = malloc (sizeof (CameraStorageInformation));
758 if (!sfs)
759 return GP_ERROR_NO_MEMORY;
760 *sinfos = sfs;
761 *nrofsinfos = 1;
762
763 sfs->fields = GP_STORAGEINFO_BASE |
764 GP_STORAGEINFO_DESCRIPTION |
765 GP_STORAGEINFO_STORAGETYPE |
766 GP_STORAGEINFO_FILESYSTEMTYPE |
767 GP_STORAGEINFO_ACCESS |
768 GP_STORAGEINFO_MAXCAPACITY |
769 GP_STORAGEINFO_FREESPACEKBYTES;
770 ;
771 strcpy (sfs->basedir, "/");
772 strcpy (sfs->description, "Directory Driver");
773 sfs->type = GP_STORAGEINFO_ST_REMOVABLE_RAM;
774 sfs->fstype = GP_STORAGEINFO_FST_GENERICHIERARCHICAL;
775 sfs->access = GP_STORAGEINFO_AC_READWRITE;
776 if (stfs.f_bsize >= 1024) {
777 sfs->capacitykbytes = stfs.f_blocks*(stfs.f_bsize/1024);
778 sfs->freekbytes = stfs.f_bavail*(stfs.f_bsize/1024);
779 } else {
780 sfs->capacitykbytes = stfs.f_blocks/(1024/stfs.f_bsize);
781 sfs->freekbytes = stfs.f_bavail/(1024/stfs.f_bsize);
782 }
783 return GP_OK;
784 #endif
785
786 return GP_ERROR_NOT_SUPPORTED;
787 }
788
789 static CameraFilesystemFuncs fsfuncs = {
790 .file_list_func = file_list_func,
791 .folder_list_func = folder_list_func,
792 .set_info_func = set_info_func,
793 .get_info_func = get_info_func,
794 .get_file_func = get_file_func,
795 .put_file_func = put_file_func,
796 .del_file_func = delete_file_func,
797 .make_dir_func = make_dir_func,
798 .remove_dir_func = remove_dir_func,
799 .storage_info_func = storage_info_func,
800 };
801
802 int
803 camera_init (Camera *camera, GPContext *context)
804 {
805 /* First, set up all the function pointers */
806 camera->functions->manual = camera_manual;
807 camera->functions->about = camera_about;
808 return gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera);
809 }