Ejemplo n.º 1
0
int
gp_port_library_list (GPPortInfoList *list)
{
	GPPortInfo info;
#ifdef HAVE_MDNS_BONJOUR
	DNSServiceRef		sd;
	DNSServiceErrorType	ret;
	int			fd;
	fd_set			infds;
	struct timeval		tv;
#endif

	gp_port_info_new (&info);
	gp_port_info_set_type (info, GP_PORT_PTPIP);
	gp_port_info_set_name (info, _("PTP/IP Connection"));
	gp_port_info_set_path (info, "ptpip:");
	CHECK (gp_port_info_list_append (list, info));

	/* Generic matcher so you can pass any IP address */
	gp_port_info_new (&info);
	gp_port_info_set_type (info, GP_PORT_PTPIP);
	gp_port_info_set_name (info, "");
	gp_port_info_set_path (info, "^ptpip:");
	CHECK (gp_port_info_list_append (list, info));

#ifdef HAVE_MDNS_BONJOUR
	ret = DNSServiceBrowse (
		&sd,
		0,	/* unused flags */
		0,	/* all ifaces */
		"_ptp._tcp",
		NULL,
		_ptpip_enumerate,
		list
	);
	/* We need to make it a non-blocking query */
	fd = DNSServiceRefSockFD(sd);
	if (fd != -1) {
		FD_ZERO (&infds); FD_SET (fd, &infds); 
		tv.tv_sec = 0; tv.tv_usec = 1;
		/* If we have input, we can try to process a result */
		if (1 == select (fd+1, &infds, NULL, NULL, &tv))
			DNSServiceProcessResult (sd);
	}
	DNSServiceRefDeallocate (sd);
#endif
	return GP_OK;
}
Ejemplo n.º 2
0
int
gp_port_library_list (GPPortInfoList *list)
{
    DIR *dir;
    struct dirent *dirent;
    int ret;
    GPPortInfo info;
    unsigned short vendor_id, product_id;

    dir = opendir ("/sys/class/scsi_generic");
    if (dir == NULL)
        return GP_OK;

    while ((dirent = readdir (dir))) {
        char path[4096];
        if (gp_port_usbscsi_get_usb_id (dirent->d_name,
                                        &vendor_id, &product_id) != GP_OK)
            continue; /* Not a usb device */

        gp_port_info_new (&info);
        gp_port_info_set_type (info, GP_PORT_USB_SCSI);
        snprintf (path, sizeof (path),
                  "usbscsi:/dev/%s",
                  dirent->d_name);
        gp_port_info_set_path (info, path);
        gp_port_info_set_name (info, _("USB Mass Storage raw SCSI"));
        ret = gp_port_info_list_append (list, info);
        if (ret < GP_OK) /* can only be out of memory */
            break;
    }
    closedir (dir);
    return GP_OK;
}
Ejemplo n.º 3
0
int
gp_port_library_list (GPPortInfoList *list)
{
	GPPortInfo info;

	gp_log(GP_LOG_DEBUG,__FUNCTION__,"()");

        CHECK (gp_port_info_new (&info));
        gp_port_info_set_type (info, GP_PORT_USB);
        gp_port_info_set_name (info, "");
        gp_port_info_set_path (info, "^usb:");
        gp_port_info_list_append (list, info); /* do not check, might be -1 */

	gp_port_info_new (&info);
	gp_port_info_set_type (info, GP_PORT_USB);
	gp_port_info_set_name (info, "Universal Serial Bus");
	gp_port_info_set_path (info, "usb:001,001");
	CHECK (gp_port_info_list_append (list, info));
	return GP_OK;
}
Ejemplo n.º 4
0
static void
_ptpip_resolved (
	DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
	DNSServiceErrorType errorCode,
	const char *fullname, const char *hosttarget, uint16_t port,
	uint16_t txtLen, const char *txtRecord, void *context
) {
	struct hostent*	hent;
	struct in_addr	inaddr;
	GPPortInfo	*info;
	int		i, cnt;
	struct mdnsinfo	*mdnsi = context;
	char		path[200];

	if (errorCode != kDNSServiceErr_NoError) {
		gp_log (GP_LOG_ERROR, "ptpip", "Error on 2nd level query.");
		return;
	}
	gp_log (GP_LOG_DEBUG, "ptpip", "fullname %s, hosttarget %s, port %d", fullname, hosttarget, htons(port));
	cnt = TXTRecordGetCount (txtLen, txtRecord);
	for (i=0;i<cnt;i++) {
		char	key[256];
		uint8_t	valuelen;
		const void	*value;

		valuelen = 0;
		if (kDNSServiceErr_NoError == TXTRecordGetItemAtIndex (txtLen, txtRecord, i, sizeof(key), key, &valuelen, &value))
			gp_log (GP_LOG_DEBUG, "ptpip", "%d: %s:%s", i, key, (char*)value);
	}
	hent = gethostbyname (hosttarget);
	if (!hent) {
		gp_log (GP_LOG_ERROR, "ptpip", "Could not resolve the returned host: %s", hosttarget);
		return;
	}
	memcpy(&inaddr.s_addr,hent->h_addr_list[0],hent->h_length);
	gp_port_info_new (&info);
	gp_port_info_set_type (info, GP_PORT_PTPIP);
	gp_port_info_set_name (info, mdnsi->name);
	snprintf (path, sizeof(path), "ptpip:%s:%d", inet_ntoa(inaddr), htons(port));
	gp_port_info_set_path (info, path);
	gp_port_info_list_append (mdnsi->list, info);
}
Ejemplo n.º 5
0
int
gp_port_library_list (GPPortInfoList *list)
{
	DIR *dir;
	struct dirent *dirent;
	GPPortInfo info;
	int ret;
	unsigned short vendor_id, product_id;

	dir = opendir ("/sys/block");
	if (dir == NULL)
		return GP_OK;

	while ((dirent = readdir (dir))) {
		char path[4096];
		if (dirent->d_name[0] != 's' ||
		    dirent->d_name[1] != 'd' ||
		    dirent->d_name[2] < 'a' ||
		    dirent->d_name[2] > 'z')
			continue;

		if (gp_port_usbdiskdirect_get_usb_id (dirent->d_name,
				&vendor_id, &product_id) != GP_OK)
			continue; /* Not a usb device */

		gp_port_info_new (&info);
		gp_port_info_set_type (info, GP_PORT_USB_DISK_DIRECT);
		snprintf (path, sizeof (path),
			  "usbdiskdirect:/dev/%s",
			  dirent->d_name);
		gp_port_info_set_path (info, path);
		gp_port_info_set_name (info, _("USB Mass Storage direct IO"));
		ret = gp_port_info_list_append (list, info);
		if (ret < GP_OK)
			break;
	}
	closedir (dir);
	return GP_OK;
}
Ejemplo n.º 6
0
int
gp_port_library_list (GPPortInfoList *list)
{
	GPPortInfo	info;
	int		nrofdevices = 0;
	int		d, i, i1, i2, unknownint;
	libusb_context	*ctx;
	libusb_device	**devs = NULL;
	int		nrofdevs = 0;
	struct libusb_device_descriptor	*descs;

	C_LIBUSB (libusb_init (&ctx), GP_ERROR_IO);

	/* TODO: make sure libusb_exit gets called in all error paths inside this function */

	/* generic matcher. This will catch passed XXX,YYY entries for instance. */
	C_GP (gp_port_info_new (&info));
	gp_port_info_set_type (info, GP_PORT_USB);
	gp_port_info_set_name (info, "");
	gp_port_info_set_path (info, "^usb:");
	C_GP (gp_port_info_list_append (list, info));

	nrofdevs = libusb_get_device_list (ctx, &devs);
	C_MEM (descs = calloc (nrofdevs, sizeof(descs[0])));
	for (i=0;i<nrofdevs;i++)
		LOG_ON_LIBUSB_E (libusb_get_device_descriptor(devs[i], &descs[i]));

	for (d = 0; d < nrofdevs; d++) {
		/* Devices which are definitely not cameras. */
		if (	(descs[d].bDeviceClass == LIBUSB_CLASS_HUB)		||
			(descs[d].bDeviceClass == LIBUSB_CLASS_HID)		||
			(descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER)	||
			(descs[d].bDeviceClass == LIBUSB_CLASS_COMM)	||
			(descs[d].bDeviceClass == 0xe0)	/* wireless / bluetooth */
		)
			continue;
		/* excepts HUBs, usually the interfaces have the classes, not
		 * the device */
		unknownint = 0;
		for (i = 0; i < descs[d].bNumConfigurations; i++) {
			struct libusb_config_descriptor *config;

			if (LOG_ON_LIBUSB_E (libusb_get_config_descriptor (devs[d], i, &config))) {
				unknownint++;
				continue;
			}
			for (i1 = 0; i1 < config->bNumInterfaces; i1++)
				for (i2 = 0; i2 < config->interface[i1].num_altsetting; i2++) {
					const struct libusb_interface_descriptor *intf = &config->interface[i1].altsetting[i2]; 
					if (	(intf->bInterfaceClass == LIBUSB_CLASS_HID)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_PRINTER)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_COMM)	||
						(intf->bInterfaceClass == 0xe0)	/* wireless/bluetooth*/
					)
						continue;
					unknownint++;
				}
			libusb_free_config_descriptor (config);
		}
		/* when we find only hids, printer or comm ifaces  ... skip this */
		if (!unknownint)
			continue;
		/* Note: We do not skip USB storage. Some devices can support both,
		 * and the Ricoh erronously reports it.
		 */ 
		nrofdevices++;
	}

#if 0
	/* If we already added usb:, and have 0 or 1 devices we have nothing to do.
	 * This should be the standard use case.
	 */
	/* We never want to return just "usb:" ... also return "usb:XXX,YYY", and
	 * let upper layers filter out the usb: */
	if (nrofdevices <= 1) 
		return (GP_OK);
#endif

	/* Redo the same bus/device walk, but now add the ports with usb:x,y notation,
	 * so we can address all USB devices.
	 */
	for (d = 0; d < nrofdevs; d++) {
		char path[200];

		/* Devices which are definitely not cameras. */
		if (	(descs[d].bDeviceClass == LIBUSB_CLASS_HUB)		||
			(descs[d].bDeviceClass == LIBUSB_CLASS_HID)		||
			(descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER)	||
			(descs[d].bDeviceClass == LIBUSB_CLASS_COMM)
		)
			continue;
		/* excepts HUBs, usually the interfaces have the classes, not
		 * the device */
		unknownint = 0;
		for (i = 0; i < descs[d].bNumConfigurations; i++) {
			struct libusb_config_descriptor *config;

			if (LOG_ON_LIBUSB_E (libusb_get_config_descriptor (devs[d], i, &config))) {
				unknownint++;
				continue;
			}
			for (i1 = 0; i1 < config->bNumInterfaces; i1++)
				for (i2 = 0; i2 < config->interface[i1].num_altsetting; i2++) {
					const struct libusb_interface_descriptor *intf = &config->interface[i1].altsetting[i2]; 
					if (	(intf->bInterfaceClass == LIBUSB_CLASS_HID)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_PRINTER)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_COMM))
						continue;
					unknownint++;
				}
			libusb_free_config_descriptor (config);
		}
		/* when we find only hids, printer or comm ifaces  ... skip this */
		if (!unknownint)
			continue;
		/* Note: We do not skip USB storage. Some devices can support both,
		 * and the Ricoh erronously reports it.
		 */ 
		C_GP (gp_port_info_new (&info));
		gp_port_info_set_type (info, GP_PORT_USB);
		gp_port_info_set_name (info, "Universal Serial Bus");
		snprintf (path,sizeof(path), "usb:%03d,%03d",
			libusb_get_bus_number (devs[d]),
			libusb_get_device_address (devs[d])
		);
		gp_port_info_set_path (info, path);
		C_GP (gp_port_info_list_append (list, info));
	}
	/* This will only be added if no other device was ever added.
	 * Users doing "usb:" usage will enter the regular expression matcher case. */
	if (nrofdevices == 0) {
		C_GP (gp_port_info_new (&info));
		gp_port_info_set_type (info, GP_PORT_USB);
		gp_port_info_set_name (info, "Universal Serial Bus");
		gp_port_info_set_path (info, "usb:");
		C_GP (gp_port_info_list_append (list, info));
	}
	libusb_free_device_list (devs, 1);
	libusb_exit (ctx); /* should free all stuff above */
	free (descs);
	return (GP_OK);
}
Ejemplo n.º 7
0
int
gp_port_library_list (GPPortInfoList *list)
{
	GPPortInfo info;
# ifdef HAVE_MNTENT_H
	FILE *mnt;
	struct mntent *mntent;
	char	path[1024];
	char	*s;
	struct stat stbuf;

	mnt = setmntent ("/etc/fstab", "r");
	if (mnt) {
		while ((mntent = getmntent (mnt))) {
			/* detect floppies so we don't access them with the stat() below */
			GP_LOG_D ("found fstab fsname %s", mntent->mnt_fsname);

			if ((NULL != strstr(mntent->mnt_fsname,"fd"))	||
			    (NULL != strstr(mntent->mnt_fsname,"floppy")) ||
			    (NULL != strstr(mntent->mnt_fsname,"fuse"))	||
			    (NULL != strstr(mntent->mnt_fsname,"nfs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"cifs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"smbfs"))||
			    (NULL != strstr(mntent->mnt_fsname,"afs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"autofs"))||
                            (NULL != strstr(mntent->mnt_fsname,"cgroup"))||
                            (NULL != strstr(mntent->mnt_fsname,"systemd"))||
                            (NULL != strstr(mntent->mnt_fsname,"mqueue"))||
                            (NULL != strstr(mntent->mnt_fsname,"securityfs"))||
                            (NULL != strstr(mntent->mnt_fsname,"proc"))||
                            (NULL != strstr(mntent->mnt_fsname,"devtmpfs"))||
                            (NULL != strstr(mntent->mnt_fsname,"devpts"))||
                            (NULL != strstr(mntent->mnt_fsname,"sysfs"))||
			    (NULL != strstr(mntent->mnt_fsname,"gphotofs"))||
			/* fstype based */
			    (NULL != strstr(mntent->mnt_type,"autofs"))	||
			    (NULL != strstr(mntent->mnt_type,"nfs"))	||
			    (NULL != strstr(mntent->mnt_type,"smbfs"))||
			    (NULL != strstr(mntent->mnt_type,"proc"))||
			    (NULL != strstr(mntent->mnt_type,"sysfs"))||
			    (NULL != strstr(mntent->mnt_type,"cifs"))||
			    (NULL != strstr(mntent->mnt_type,"afs")) ||
			/* mount options */
				/* x-systemd.automount or similar */
			    (NULL != strstr(mntent->mnt_opts,"automount"))
			) {
				continue;
			}

			/* Whitelist some fuse based filesystems, e.g. to help exfat mounts */
			/* In general, if we are backed by a device, it is probably good(tm) */
			if (NULL != strstr(mntent->mnt_type,"fuse")) {
				if (!strstr(mntent->mnt_fsname,"/dev/"))
					continue;
			}

			snprintf (path, sizeof(path), "%s/DCIM", mntent->mnt_dir);
			if (-1 == stat(path, &stbuf)) {
				snprintf (path, sizeof(path), "%s/dcim", mntent->mnt_dir);
				if (-1 == stat(path, &stbuf))
					continue;
			}
			s = malloc (strlen(_("Media '%s'"))+strlen(mntent->mnt_fsname)+1);
			sprintf (s, _("Media '%s'"), mntent->mnt_fsname);
			gp_port_info_new (&info);
			gp_port_info_set_type (info, GP_PORT_DISK);
			gp_port_info_set_name (info, s);
			free (s);
			
			s = malloc (strlen("disk:")+strlen(mntent->mnt_dir)+1);
			sprintf (s, "disk:%s", mntent->mnt_dir);
			gp_port_info_set_path (info, s);
			if (gp_port_info_list_lookup_path (list, s) >= GP_OK) {
				free (s);
				continue;
			}
			free(s);
			CHECK (gp_port_info_list_append (list, info));
		}
		endmntent(mnt);
	}
	mnt = setmntent ("/etc/mtab", "r");
	if (mnt) {
		while ((mntent = getmntent (mnt))) {
			/* detect floppies so we don't access them with the stat() below */
			GP_LOG_D ("found mtab fsname %s", mntent->mnt_fsname);

			if ((NULL != strstr(mntent->mnt_fsname,"fd"))	||
			    (NULL != strstr(mntent->mnt_fsname,"floppy")) ||
			    (NULL != strstr(mntent->mnt_fsname,"fuse"))	||
			    (NULL != strstr(mntent->mnt_fsname,"nfs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"cifs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"smbfs"))||
			    (NULL != strstr(mntent->mnt_fsname,"afs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"autofs"))||
                            (NULL != strstr(mntent->mnt_fsname,"cgroup"))||
                            (NULL != strstr(mntent->mnt_fsname,"systemd"))||
                            (NULL != strstr(mntent->mnt_fsname,"mqueue"))||
                            (NULL != strstr(mntent->mnt_fsname,"securityfs"))||
                            (NULL != strstr(mntent->mnt_fsname,"proc"))||
                            (NULL != strstr(mntent->mnt_fsname,"devtmpfs"))||
                            (NULL != strstr(mntent->mnt_fsname,"devpts"))||
                            (NULL != strstr(mntent->mnt_fsname,"sysfs"))||
			    (NULL != strstr(mntent->mnt_fsname,"gphotofs"))||
			/* fstype based */
			    (NULL != strstr(mntent->mnt_type,"autofs"))	||
			    (NULL != strstr(mntent->mnt_type,"nfs"))	||
			    (NULL != strstr(mntent->mnt_type,"smbfs"))||
			    (NULL != strstr(mntent->mnt_type,"proc"))||
			    (NULL != strstr(mntent->mnt_type,"sysfs"))||
			    (NULL != strstr(mntent->mnt_type,"cifs"))||
			    (NULL != strstr(mntent->mnt_type,"afs")) ||
			/* options */
			    (NULL != strstr(mntent->mnt_opts,"automount"))
			) {
				continue;
			}
			/* Whitelist some fuse based filesystems, e.g. to help exfat mounts */
			/* In general, if we are backed by a device, it is probably good(tm) */
			if (NULL != strstr(mntent->mnt_type,"fuse")) {
				if (!strstr(mntent->mnt_fsname,"/dev/"))
					continue;
			}

			snprintf (path, sizeof(path), "%s/DCIM", mntent->mnt_dir);
			if (-1 == stat(path, &stbuf)) {
				snprintf (path, sizeof(path), "%s/dcim", mntent->mnt_dir);
				if (-1 == stat(path, &stbuf))
					continue;
			}
			/* automount should be blacklist here, but we still need
			 * to look it up first otherwise the automounted camera
			 * won't appear.
			 */
			if (NULL != strstr(mntent->mnt_fsname, "automount")) {
				continue;
			}
			gp_port_info_new (&info);
			gp_port_info_set_type (info, GP_PORT_DISK);
			s = malloc (strlen(_("Media '%s'"))+strlen(mntent->mnt_fsname)+1);
			sprintf (s, _("Media '%s'"),  mntent->mnt_fsname);
			gp_port_info_set_name (info, s);
			free (s);
			
			s = malloc (strlen("disk:")+strlen(mntent->mnt_dir)+1);
			sprintf (s, "disk:%s", mntent->mnt_dir);
			gp_port_info_set_path (info, s);
			if (gp_port_info_list_lookup_path (list, s) >= GP_OK) {
				free (s);
				continue;
			}
			free (s);
			CHECK (gp_port_info_list_append (list, info));
		}
		endmntent(mnt);
	}
# else
#  ifdef HAVE_MNTTAB
	FILE *mnt;
	struct mnttab mnttab;
	char	path[1024];
	struct stat stbuf;

	info.type = GP_PORT_DISK;

	mnt = fopen ("/etc/fstab", "r");
	if (mnt) {
		while (! getmntent (mnt, &mntent)) {
			/* detect floppies so we don't access them with the stat() below */
			if (	(NULL != strstr(mnttab.mnt_special,"fd")) ||
				(NULL != strstr(mnttab.mnt_special,"floppy"))
			)
				continue;

			snprintf (path, sizeof(path), "%s/DCIM", mnttab.mnt_mountp);
			if (-1 == stat(path, &stbuf)) {
				snprintf (path, sizeof(path), "%s/dcim", mnttab.mnt_mountp);
				if (-1 == stat(path, &stbuf))
					continue;
			}
			snprintf (info.name, sizeof(info.name), _("Media '%s'"), mntent.mnt_special),
			snprintf (info.path, sizeof(info.path), "disk:%s", mntent.mnt_mountp);
			if (gp_port_info_list_lookup_path (list, info.path) >= GP_OK)
				continue;
			CHECK (gp_port_info_list_append (list, info));
		}
		fclose(mnt);
	}
	mnt = fopen ("/etc/mtab", "r");
	if (mnt) {
		while (! getmntent (mnt, &mntent)) {
			/* detect floppies so we don't access them with the stat() below */
			if (	(NULL != strstr(mnttab.mnt_special,"fd")) ||
				(NULL != strstr(mnttab.mnt_special,"floppy"))
			)
				continue;

			snprintf (path, sizeof(path), "%s/DCIM", mnttab.mnt_mountp);
			if (-1 == stat(path, &stbuf)) {
				snprintf (path, sizeof(path), "%s/dcim", mnttab.mnt_mountp);
				if (-1 == stat(path, &stbuf))
					continue;
			}
			snprintf (info.name, sizeof(info.name), _("Media '%s'"), mntent.mnt_special),
			snprintf (info.path, sizeof(info.path), "disk:%s", mntent.mnt_mountp);
			if (gp_port_info_list_lookup_path (list, info.path) >= GP_OK)
				continue;
			CHECK (gp_port_info_list_append (list, info));
		}
		fclose(mnt);
	}
#  endif
# endif
	/* generic disk:/xxx/ matcher */
	gp_port_info_new (&info);
	gp_port_info_set_type (info, GP_PORT_DISK);
	gp_port_info_set_name (info, "");
	gp_port_info_set_path (info, "^disk:");
	gp_port_info_list_append (list, info); /* do not check return */
	return GP_OK;
}
Ejemplo n.º 8
0
int
gp_port_library_list (GPPortInfoList *list)
{
	GPPortInfo	info;
	int		nrofdevices = 0;
	int		d, i, i1, i2, unknownint;

	/* generic matcher. This will catch passed XXX,YYY entries for instance. */
	info.type = GP_PORT_USB;
	strcpy (info.name, "");
	strcpy (info.path, "^usb:");
	CHECK (gp_port_info_list_append (list, info));

	libusb_init (NULL);
	gp_nrofdevs = load_devicelist (NULL);

	for (d = 0; d < gp_nrofdevs; d++) {
		/* Devices which are definitely not cameras. */
		if (	(gp_descs[d].bDeviceClass == LIBUSB_CLASS_HUB)		||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_HID)		||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER)	||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_COMM)	||
			(gp_descs[d].bDeviceClass == 0xe0)	/* wireless / bluetooth */
		)
			continue;
		/* excepts HUBs, usually the interfaces have the classes, not
		 * the device */
		unknownint = 0;
		for (i = 0; i < gp_descs[d].bNumConfigurations; i++) {
			struct libusb_config_descriptor *config;
			int ret;

			ret = libusb_get_config_descriptor (gp_devs[d], i, &config);
			if (ret) {
				unknownint++;
				continue;
			}
			for (i1 = 0; i1 < config->bNumInterfaces; i1++)
				for (i2 = 0; i2 < config->interface[i1].num_altsetting; i2++) {
					const struct libusb_interface_descriptor *intf = &config->interface[i1].altsetting[i2]; 
					if (	(intf->bInterfaceClass == LIBUSB_CLASS_HID)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_PRINTER)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_COMM)	||
						(intf->bInterfaceClass == 0xe0)	/* wireless/bluetooth*/
					)
						continue;
					unknownint++;
				}
			libusb_free_config_descriptor (config);
		}
		/* when we find only hids, printer or comm ifaces  ... skip this */
		if (!unknownint)
			continue;
		/* Note: We do not skip USB storage. Some devices can support both,
		 * and the Ricoh erronously reports it.
		 */ 
		nrofdevices++;
	}

#if 0
	/* If we already added usb:, and have 0 or 1 devices we have nothing to do.
	 * This should be the standard use case.
	 */
	/* We never want to return just "usb:" ... also return "usb:XXX,YYY", and
	 * let upper layers filter out the usb: */
	if (nrofdevices <= 1) 
		return (GP_OK);
#endif

	/* Redo the same bus/device walk, but now add the ports with usb:x,y notation,
	 * so we can address all USB devices.
	 */
	for (d = 0; d < gp_nrofdevs; d++) {
		/* Devices which are definitely not cameras. */
		if (	(gp_descs[d].bDeviceClass == LIBUSB_CLASS_HUB)		||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_HID)		||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER)	||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_COMM)
		)
			continue;
		/* excepts HUBs, usually the interfaces have the classes, not
		 * the device */
		unknownint = 0;
		for (i = 0; i < gp_descs[d].bNumConfigurations; i++) {
			struct libusb_config_descriptor *config;
			int ret;

			ret = libusb_get_config_descriptor (gp_devs[d], i, &config);
			if (ret) {
				gp_log (GP_LOG_ERROR, "libusb1", "libusb_get_config_descriptor(%d) returned %d", d, ret);
				unknownint++;
				continue;
			}
			for (i1 = 0; i1 < config->bNumInterfaces; i1++)
				for (i2 = 0; i2 < config->interface[i1].num_altsetting; i2++) {
					const struct libusb_interface_descriptor *intf = &config->interface[i1].altsetting[i2]; 
					if (	(intf->bInterfaceClass == LIBUSB_CLASS_HID)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_PRINTER)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_COMM))
						continue;
					unknownint++;
				}
			libusb_free_config_descriptor (config);
		}
		/* when we find only hids, printer or comm ifaces  ... skip this */
		if (!unknownint)
			continue;
		/* Note: We do not skip USB storage. Some devices can support both,
		 * and the Ricoh erronously reports it.
		 */ 
		info.type = GP_PORT_USB;
		strcpy (info.name, "Universal Serial Bus");
		snprintf (info.path,sizeof(info.path), "usb:%03d,%03d",
			libusb_get_bus_number (gp_devs[d]),
			libusb_get_device_address (gp_devs[d])
		);
		CHECK (gp_port_info_list_append (list, info));
	}
	/* This will only be added if no other device was ever added.
	 * Users doing "usb:" usage will enter the regular expression matcher case. */
	if (nrofdevices == 0) {
		info.type = GP_PORT_USB;
		strcpy (info.name, "Universal Serial Bus");
		strcpy (info.path, "usb:");
		CHECK (gp_port_info_list_append (list, info));
	}
	libusb_exit (NULL);
	return (GP_OK);
}
/**
 * \brief Lookup a specific path in the list
 *
 * \param list a #GPPortInfoList
 * \param path a path
 *
 * Looks for an entry in the list with the supplied path. If no exact match
 * can be found, a regex search will be performed in the hope some driver
 * claimed ports like "serial:*".
 *
 * \return The index of the entry or a gphoto2 error code
 **/
int
gp_port_info_list_lookup_path (GPPortInfoList *list, const char *path)
{
	int i, result, generic;
	regex_t pattern;
#ifdef HAVE_GNU_REGEX
	const char *rv;
#else
	regmatch_t match;
#endif

	CHECK_NULL (list && path);

	gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list", ngettext(
		"Looking for path '%s' (%i entry available)...",
		"Looking for path '%s' (%i entries available)...",
		list->count
	), path, list->count);

	/* Exact match? */
	for (generic = i = 0; i < list->count; i++)
		if (!strlen (list->info[i].name))
			generic++;
		else if (!strcmp (list->info[i].path, path))
			return (i - generic);

	/* Regex match? */
	gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list",
		_("Starting regex search for '%s'..."), path);
	for (i = 0; i < list->count; i++) {
		GPPortInfo newinfo;

		if (strlen (list->info[i].name))
			continue;

		gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list",
			_("Trying '%s'..."), list->info[i].path);

		/* Compile the pattern */
#ifdef HAVE_GNU_REGEX
		memset (&pattern, 0, sizeof (pattern));
		rv = re_compile_pattern (list->info[i].path,
					 strlen (list->info[i].path), &pattern);
		if (rv) {
			gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list",
				"%s", rv);
			continue;
		}
#else
		result = regcomp (&pattern, list->info[i].path, REG_ICASE);
		if (result) {
			char buf[1024];
			if (regerror (result, &pattern, buf, sizeof (buf)))
				gp_log (GP_LOG_ERROR, "gphoto2-port-info-list",
					"%s", buf);
			else
				gp_log (GP_LOG_ERROR, "gphoto2-port-info-list",
					_("regcomp failed"));
			return (GP_ERROR_UNKNOWN_PORT);
		}
#endif

		/* Try to match */
#ifdef HAVE_GNU_REGEX
		result = re_match (&pattern, path, strlen (path), 0, NULL);
		regfree (&pattern);
		if (result < 0) {
			gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list",
				_("re_match failed (%i)"), result);
			continue;
		}
#else
		result = regexec (&pattern, path, 1, &match, 0);
		regfree (&pattern);
		if (result) {
			gp_log (GP_LOG_DEBUG, "gphoto2-port-info-list",
				_("regexec failed"));
			continue;
		}
#endif
		memcpy (&newinfo, &list->info[i], sizeof(newinfo));
		strncpy (newinfo.path, path, sizeof (newinfo.path));
		strncpy (newinfo.name, _("Generic Port"), sizeof (newinfo.name));
		CR (result = gp_port_info_list_append (list, newinfo));
		return result;
	}

	return (GP_ERROR_UNKNOWN_PORT);
}
Ejemplo n.º 10
0
Archivo: unix.c Proyecto: rajbot/gphoto
int
gp_port_library_list (GPPortInfoList *list)
{
	GPPortInfo info;
	char path[1024], prefix[1024];
	int x;
	struct stat s;
#ifdef OS2
	int r, fh, option;
#endif

	/* Copy in the serial port prefix */
	strcpy (prefix, GP_PORT_SERIAL_PREFIX);

	/* On Linux systems, check for devfs */
#ifdef __linux
	if (!stat ("/dev/tts", &s))
		strcpy (prefix, "/dev/tts/%i");
#endif

	for (x=GP_PORT_SERIAL_RANGE_LOW; x<=GP_PORT_SERIAL_RANGE_HIGH; x++) {
		char *xname;

		sprintf (path, prefix, x);

		/* OS/2 seems to need an additional check */
#ifdef OS2
		r = DosOpen (path, &fh, &option, 0, 0, 1,
			     OPEN_FLAGS_FAIL_ON_ERROR |
			     OPEN_SHARE_DENYREADWRITE, 0);
		DosClose(fh);
		if (r)
			continue;
#endif
		/* Very first of all, if the device node is not there,
		 * there is no need to try locking. */
		if ((stat (path, &s) == -1) && ((errno == ENOENT) || (errno == ENODEV)))
			continue;

		gp_port_info_new (&info);
		gp_port_info_set_type (info, GP_PORT_SERIAL);
		xname = malloc (strlen("serial:")+strlen(path)+1);
		strcpy (xname, "serial:");
		strcat (xname, path);
		gp_port_info_set_path (info, xname);
		free (xname);
		xname = malloc (100);
		snprintf (xname, 100, _("Serial Port %i"), x);
		gp_port_info_set_name (info, xname);
		free (xname);
		CHECK (gp_port_info_list_append (list, info));
	}

	/*
	 * Generic support. Append it to the list without checking for
	 * return values, because this entry will not be counted.
	 */
	gp_port_info_new (&info);
	gp_port_info_set_type (info, GP_PORT_SERIAL);
	gp_port_info_set_path (info, "^serial:");
	gp_port_info_set_name (info, "");
	return gp_port_info_list_append (list, info);
}
Ejemplo n.º 11
0
int
gp_port_library_list (GPPortInfoList *list)
{
	GPPortInfo info;
	struct usb_bus *bus;
	struct usb_device *dev;
	int nrofdevices = 0, i, i1, i2, unknownint;

	/* default port first */
	info.type = GP_PORT_USB;
	/* generic matcher. This will catch passed XXX,YYY entries for instance. */
	memset (info.name, 0, sizeof(info.name));
	strcpy (info.path, "^usb:");
	CHECK (gp_port_info_list_append (list, info));

	usb_init ();
	usb_find_busses ();
	usb_find_devices ();

	strcpy (info.name, "Universal Serial Bus");

	bus = usb_get_busses();

	/* Look and enumerate all USB ports. */
	while (bus) {
		for (dev = bus->devices; dev; dev = dev->next) {
			/* Devices which are definitely not cameras. */
			if (	(dev->descriptor.bDeviceClass == USB_CLASS_HUB)		||
				(dev->descriptor.bDeviceClass == USB_CLASS_HID)		||
				(dev->descriptor.bDeviceClass == USB_CLASS_PRINTER)	||
				(dev->descriptor.bDeviceClass == USB_CLASS_COMM)
			)
				continue;
			/* excepts HUBs, usually the interfaces have the classes, not
			 * the device */
			unknownint = 0;
			for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
				if (!dev->config) {
					unknownint++;
					continue;
				}
				for (i1 = 0; i1 < dev->config[i].bNumInterfaces; i1++)
					for (i2 = 0; i2 < dev->config[i].interface[i1].num_altsetting; i2++) {
						struct usb_interface_descriptor *intf = &dev->config[i].interface[i1].altsetting[i2]; 
						if (	(intf->bInterfaceClass == USB_CLASS_HID)	||
							(intf->bInterfaceClass == USB_CLASS_PRINTER)	||
							(intf->bInterfaceClass == USB_CLASS_COMM))
							continue;
						unknownint++;
					}
			}
			/* when we find only hids, printer or comm ifaces  ... skip this */
			if (!unknownint)
				continue;
			/* Note: We do not skip USB storage. Some devices can support both,
			 * and the Ricoh erronously reports it.
			 */ 
			nrofdevices++;
		}
		bus = bus->next;
	}

#if 0
	/* Do not filter out usb:XXX,YYY, we want it for consistency... */
	/* If we already added usb:, and have 0 or 1 devices we have nothing to do.
	 * This should be the standard use case.
	 */
	if (nrofdevices <= 1) 
		return (GP_OK);
#endif

	/* Redo the same bus/device walk, but now add the ports with usb:x,y notation,
	 * so we can address all USB devices.
	 */
	bus = usb_get_busses();
	while (bus) {
		for (dev = bus->devices; dev; dev = dev->next) {
			char *s;
			/* Devices which are definitely not cameras. */
			if (	(dev->descriptor.bDeviceClass == USB_CLASS_HUB)		||
				(dev->descriptor.bDeviceClass == USB_CLASS_HID)		||
				(dev->descriptor.bDeviceClass == USB_CLASS_PRINTER)	||
				(dev->descriptor.bDeviceClass == USB_CLASS_COMM)
			)
				continue;
			/* excepts HUBs, usually the interfaces have the classes, not
			 * the device */
			unknownint = 0;
			for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
				if (!dev->config) {
					unknownint++;
					continue;
				}
				for (i1 = 0; i1 < dev->config[i].bNumInterfaces; i1++)
					for (i2 = 0; i2 < dev->config[i].interface[i1].num_altsetting; i2++) {
						struct usb_interface_descriptor *intf = &dev->config[i].interface[i1].altsetting[i2]; 
						if (	(intf->bInterfaceClass == USB_CLASS_HID)	||
							(intf->bInterfaceClass == USB_CLASS_PRINTER)	||
							(intf->bInterfaceClass == USB_CLASS_COMM))
							continue;
						unknownint++;
					}
			}
			/* when we find only hids, printer or comm ifaces  ... skip this */
			if (!unknownint)
				continue;
			/* Note: We do not skip USB storage. Some devices can support both,
			 * and the Ricoh erronously reports it.
			 */ 
			sprintf (info.path, "usb:%s,%s", bus->dirname, dev->filename);
			/* On MacOS X we might get usb:006,002-04a9-3139-00-00. */
			s = strchr(info.path, '-');if (s) *s='\0';
			CHECK (gp_port_info_list_append (list, info));
		}
		bus = bus->next;
	}
	/* This will only be added if no other device was ever added.
	 * Users doing "usb:" usage will enter the regular expression matcher case. */
	if (nrofdevices == 0) {
		strcpy (info.name, "Universal Serial Bus");
		strcpy (info.path, "usb:");
		CHECK (gp_port_info_list_append (list, info));
	}
	return (GP_OK);
}