<commit_before>/* directory.c
 *
 * Copyright (c) 2001 <NAME> <<EMAIL>>
 * Copyright (c) 2005 <NAME> <<EMAIL>>
 * Copyright (c) 2007 <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

#define _BSD_SOURCE

#include "config.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <utime.h>
#include <unistd.h>
#ifdef HAVE_SYS_STATVFS_H
# include <sys/statvfs.h>
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_VFS_H
# include <sys/vfs.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
# include <sys/mount.h>
#endif
#ifdef HAVE_SYS_STATFS_H
# include <sys/statfs.h>
#endif
#include <fcntl.h>

/* will happen only on Win32 */
#ifndef HAVE_LSTAT
#define lstat stat
#endif

#ifdef HAVE_LIBEXIF
#include <libexif/exif-data.h>
#endif

#include <gphoto2/gphoto2-setting.h>
#include <gphoto2/gphoto2-library.h>
#include <gphoto2/gphoto2-port.h>
#include <gphoto2/gphoto2-port-log.h>
#include <gphoto2/gphoto2-port-portability.h>

#ifdef ENABLE_NLS
#  include <libintl.h>
#  undef _
#  define _(String) dgettext (GETTEXT_PACKAGE, String)
#  ifdef gettext_noop
#    define N_(String) gettext_noop (String)
#  else
#    define N_(String) (String)
#  endif
#else
#  define textdomain(String) (String)
#  define gettext(String) (String) 
#  define dgettext(Domain,Message) (Message)
#  define dcgettext(Domain,Message,Type) (Message)
#  define bindtextdomain(Domain,Directory) (Domain)
#  define _(String) (String)
#  define N_(String) (String)
#endif

static const struct {
	const char *extension;
	const char *mime_type;
} mime_table[] = {
	{"jpeg", GP_MIME_JPEG},
	{"jpg",  GP_MIME_JPEG}, 
	{"thm",  GP_MIME_JPEG}, 
	{"tif",  GP_MIME_TIFF},
	{"ppm",  GP_MIME_PPM},
	{"pgm",  GP_MIME_PGM},
	{"avi",  GP_MIME_AVI},
	{"mov",  GP_MIME_QUICKTIME},
	{"moov", GP_MIME_QUICKTIME},
	{"qt",   GP_MIME_QUICKTIME},
	{"qtvr", GP_MIME_QUICKTIME},
	{"mp2",  GP_MIME_MPEG},
	{"mp3",  GP_MIME_MPEG},
	{"mp4",  GP_MIME_MPEG},
	{"mpg",  GP_MIME_MPEG},
	{"mpeg", GP_MIME_MPEG},
	{"mpe",  GP_MIME_MPEG},
	{"ogg",  GP_MIME_OGG},
	{"mts",  GP_MIME_AVCHD},
	{"m2ts", GP_MIME_AVCHD},
	{"pbm", "image/x-portable-bitmap"},
	{"crw",  GP_MIME_CRW},
	{"rw2",  GP_MIME_RW2},
	{"cr2",  GP_MIME_RAW},
	{"nef",  GP_MIME_RAW},
	{"mrw",  GP_MIME_RAW},
	{"dng",  GP_MIME_RAW},
	{"sr2",  GP_MIME_RAW},
	{"raf",  GP_MIME_RAW},
	{"erf",  GP_MIME_RAW},
	{"orf",  GP_MIME_RAW},
	{"arw",  GP_MIME_RAW},
	{"pef",  GP_MIME_RAW},
	{"raw",  GP_MIME_RAW},
	{"dcr",  GP_MIME_RAW},
	{"x3f",  GP_MIME_RAW},
	{"srw",  GP_MIME_RAW},
	{"gf1",  GP_MIME_RAW},
	{"srw",  GP_MIME_RAW},
	{"nrw",  GP_MIME_RAW},
	{"png",  GP_MIME_PNG},
	{"wav",  GP_MIME_WAV},
	{"3gp",  "video/3gpp"},
	{"3g2",  "video/x-3gpp2"},
	{"dif",  "video/dv"},
	{NULL, NULL}
};

/* #define DEBUG */
/* #define FOLLOW_LINKS */

#define GP_MODULE "directory"

static const char *
get_mime_type (const char *filename)
{

        char *dot;
        int x=0;

        dot = strrchr(filename, '.');
        if (dot) {
		for (x = 0; mime_table[x].extension; x++) {
#ifdef OS2
			if (!stricmp(mime_table[x].extension, dot+1))
#else
			if (!strcasecmp (mime_table[x].extension, dot+1))
#endif
				return (mime_table[x].mime_type);
                }
	}

        return (NULL);
}

int camera_id (CameraText *id)
{
        strcpy(id->text, "directory");

        return (GP_OK);
}


int camera_abilities (CameraAbilitiesList *list)
{
        CameraAbilities a;

	memset(&a, 0, sizeof(a));
        strcpy(a.model, "Directory Browse");
	a.status = GP_DRIVER_STATUS_PRODUCTION;
        a.port     = GP_PORT_DISK;
        a.speed[0] = 0;

        a.operations = GP_OPERATION_NONE;

#ifdef DEBUG
        a.file_operations = GP_FILE_OPERATION_PREVIEW |
			    GP_FILE_OPERATION_DELETE | 
			    GP_FILE_OPERATION_EXIF;
#else
	a.file_operations = GP_FILE_OPERATION_DELETE |
			    GP_FILE_OPERATION_EXIF;
#endif
        a.folder_operations = GP_FOLDER_OPERATION_MAKE_DIR |
			      GP_FOLDER_OPERATION_REMOVE_DIR |
			      GP_FOLDER_OPERATION_PUT_FILE;

        gp_abilities_list_append(list, a);

	/* Since "Directory Browse" is hardcoded in clients,
	 * better also add a new name here.
	 */
        strcpy(a.model, "Mass Storage Camera");
        gp_abilities_list_append(list, a);
        return (GP_OK);
}

static int
_get_mountpoint(GPPort *port, char **path) {
	GPPortInfo	info;
	int ret;
	char *p;

	ret = gp_port_get_info (port, &info);
	if (ret < GP_OK)
		return ret;
	ret = gp_port_info_get_path (info, path);
	if (ret < GP_OK)
		return ret;
	p = strchr (*path, ':');
	if (p) *path = p+1;
	return GP_OK;
}

static int
_get_path (GPPort *port, const char *folder, const char *file, char *path, unsigned int size) {
	if (port->type == GP_PORT_DISK) {
		int ret;
		char *xpath;

		ret = _get_mountpoint (port, &xpath);
		snprintf (path, size, "%s/%s/%s", xpath, folder, file);
	} else {
		/* old style access */
		snprintf (path, size, "%s/%s", folder, file);
	}
	return GP_OK;
}


static int
file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,<commit_msg>From: "<NAME>" <<EMAIL>><commit_after>/* directory.c
 *
 * Copyright (c) 2001 <NAME> <<EMAIL>>
 * Copyright (c) 2005 <NAME> <<EMAIL>>
 * Copyright (c) 2007 <NAME> <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

#define _BSD_SOURCE

#include "config.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <utime.h>
#include <unistd.h>
#ifdef HAVE_SYS_STATVFS_H
# include <sys/statvfs.h>
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_VFS_H
# include <sys/vfs.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
# include <sys/mount.h>
#endif
#ifdef HAVE_SYS_STATFS_H
# include <sys/statfs.h>
#endif
#include <fcntl.h>

/* will happen only on Win32 */
#ifndef HAVE_LSTAT
#define lstat stat
#endif

#ifdef HAVE_LIBEXIF
#include <libexif/exif-data.h>
#endif

#include <gphoto2/gphoto2-setting.h>
#include <gphoto2/gphoto2-library.h>
#include <gphoto2/gphoto2-port.h>
#include <gphoto2/gphoto2-port-log.h>
#include <gphoto2/gphoto2-port-portability.h>

#ifdef ENABLE_NLS
#  include <libintl.h>
#  undef _
#  define _(String) dgettext (GETTEXT_PACKAGE, String)
#  ifdef gettext_noop
#    define N_(String) gettext_noop (String)
#  else
#    define N_(String) (String)
#  endif
#else
#  define textdomain(String) (String)
#  define gettext(String) (String) 
#  define dgettext(Domain,Message) (Message)
#  define dcgettext(Domain,Message,Type) (Message)
#  define bindtextdomain(Domain,Directory) (Domain)
#  define _(String) (String)
#  define N_(String) (String)
#endif

static const struct {
	const char *extension;
	const char *mime_type;
} mime_table[] = {
	{"jpeg", GP_MIME_JPEG},
	{"jpg",  GP_MIME_JPEG}, 
	{"thm",  GP_MIME_JPEG}, 
	{"tif",  GP_MIME_TIFF},
	{"ppm",  GP_MIME_PPM},
	{"pgm",  GP_MIME_PGM},
	{"avi",  GP_MIME_AVI},
	{"mov",  GP_MIME_QUICKTIME},
	{"moov", GP_MIME_QUICKTIME},
	{"qt",   GP_MIME_QUICKTIME},
	{"qtvr", GP_MIME_QUICKTIME},
	{"mp2",  GP_MIME_MPEG},
	{"mp3",  GP_MIME_MPEG},
	{"mp4",  GP_MIME_MPEG},
	{"mpg",  GP_MIME_MPEG},
	{"mpeg", GP_MIME_MPEG},
	{"mpe",  GP_MIME_MPEG},
	{"ogg",  GP_MIME_OGG},
	{"mts",  GP_MIME_AVCHD},
	{"m2ts", GP_MIME_AVCHD},
	{"pbm", "image/x-portable-bitmap"},
	{"crw",  GP_MIME_CRW},
	{"rw2",  GP_MIME_RW2},
	{"cr2",  GP_MIME_RAW},
	{"nef",  GP_MIME_RAW},
	{"mrw",  GP_MIME_RAW},
	{"dng",  GP_MIME_RAW},
	{"sr2",  GP_MIME_RAW},
	{"raf",  GP_MIME_RAW},
	{"erf",  GP_MIME_RAW},
	{"orf",  GP_MIME_RAW},
	{"arw",  GP_MIME_RAW},
	{"pef",  GP_MIME_RAW},
	{"raw",  GP_MIME_RAW},
	{"dcr",  GP_MIME_RAW},
	{"x3f",  GP_MIME_RAW},
	{"srw",  GP_MIME_RAW},
	{"gf1",  GP_MIME_RAW},
	{"srw",  GP_MIME_RAW},
	{"nrw",  GP_MIME_RAW},
	{"png",  GP_MIME_PNG},
	{"wav",  GP_MIME_WAV},
	{"3gp",  "video/3gpp"},
	{"3g2",  "video/x-3gpp2"},
	{"dif",  "video/dv"},
	{NULL, NULL}
};

/* #define DEBUG */
/* #define FOLLOW_LINKS */

#define GP_MODULE "directory"

static const char *
get_mime_type (const char *filename)
{

        char *dot;
        int x=0;

        dot = strrchr(filename, '.');
        if (dot) {
		for (x = 0; mime_table[x].extension; x++) {
#ifdef OS2
			if (!stricmp(mime_table[x].extension, dot+1))
#else
			if (!strcasecmp (mime_table[x].extension, dot+1))
#endif
				return (mime_table[x].mime_type);
                }
	}

        return (NULL);
}

int camera_id (CameraText *id)
{
        strcpy(id->text, "directory");

        return (GP_OK);
}


int camera_abilities (CameraAbilitiesList *list)
{
        CameraAbilities a;

	memset(&a, 0, sizeof(a));
        strcpy(a.model, "Directory Browse");
	a.status = GP_DRIVER_STATUS_PRODUCTION;
        a.port     = GP_PORT_DISK;
        a.speed[0] = 0;

        a.operations = GP_OPERATION_NONE;

#ifdef DEBUG
        a.file_operations = GP_FILE_OPERATION_PREVIEW |
			    GP_FILE_OPERATION_DELETE | 
			    GP_FILE_OPERATION_EXIF;
#else
	a.file_operations = GP_FILE_OPERATION_DELETE |
			    GP_FILE_OPERATION_EXIF;
#endif
        a.folder_operations = GP_FOLDER_OPERATION_MAKE_DIR |
			      GP_FOLDER_OPERATION_REMOVE_DIR |
			      GP_FOLDER_OPERATION_PUT_FILE;

        gp_abilities_list_append(list, a);

	/* Since "Directory Browse" is hardcoded in clients,
	 * better also add a new name here.
	 */
        strcpy(a.model, "Mass Storage Camera");
        gp_abilities_list_append(list, a);
        return (GP_OK);
}

static int
_get_mountpoint(GPPort *port, char **path) {
	GPPortInfo	info;
	int ret;
	char *p;

	ret = gp_port_get_info (port, &info);
	if (ret < GP_OK)
		return ret;
	ret = gp_port_info_get_path (info, path);
	if (ret < GP_OK)
		return ret;
	p = strchr (*path, ':');
	if (p) *path = p+1;
	return GP_OK;
}

static int
_get_path (GPPort *port, const char *folder, const char *file, char *path, unsigned int size) {
	if (port->type == GP_PORT_DISK) {
		int ret;
		char *xpath;

		ret = _get_mountpoint (port, &xpath);
		if (ret < GP_OK)
			return ret;
		snprintf (path, size, "%s/%s/%s", xpath, folder, file);
	} else {
		/* old style access */
		snprintf (path, size, "%s/%s", folder, file);
	}
	return GP_OK;
}


static int
file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
{'fraction_non_alphanumeric': 0.14764578833693304, 'fraction_numerical': 0.010539956803455723, 'mean_word_length': 3.959725792630677, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 68, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3840444', 'n_tokens_mistral': 4853, 'n_tokens_neox': 4623, 'n_words': 1114}