Please modify libgphoto2 instructions in the Wiki as described below.

0) Install libgphoto2 as usual

1) After installation, create the "camera" group:

groupadd camera

2) Compile the attached C program (origin: Debian):

gcc -I/usr/include/gphoto2 -o print-udev-rules -lgphoto2 print-udev-rules.c

3) Run it in order to generate and install udev rules:

packaging/linux-hotplug/print-usb-usermap | ./print-udev-rules \
        >/etc/udev/rules.d/31-libgphoto2.rules

Result: all raw USB nodes for all known cameras are owned by the "camera" group.

--
Alexander E. Patrakov
/* $Id$
 *
 * Copyright © 2002 Hans Ulrich Niedermann <[EMAIL PROTECTED]>
 * Portions Copyright © 2002 Lutz Müller <[EMAIL PROTECTED]>
 * Portions Copyright © 2002 FIXME
 * Portions Copyright © 2005 Julien BLACHE <[EMAIL PROTECTED]>
 *
 * This program 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#define GP_USB_HOTPLUG_SCRIPT "/etc/hotplug/usb/usbcam"
#define GP_CAMERA_GROUP "camera"

#define HELP_TEXT \
"print-udev-rules - print rules file for udev\n" \
"\n" \
"Syntax:\n" \
"    print-udev-rules [ --verbose ] [ --debug ] [ <scriptname> ]\n" \
"\n" \
" --verbose   also print comments with camera model names\n" \
" --debug     print all debug output\n" \
"\n" \
"print-udev-rules prints the lines for the rules file on stdout.\n" \
"All other messages are printed on stderr. In case of any error, the \n" \
"program aborts regardless of data printed on stdout and returns a non-zero\n" \
"status code.\n" \
"If no <scriptname> is given, print-udev-rules uses the script name\n" \
"\"" GP_USB_HOTPLUG_SCRIPT "\"."

#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>

#include <gphoto2-camera.h>
#include <gphoto2-port-log.h>

#ifndef TRUE
#define TRUE  (0==0)
#endif
#ifndef FALSE
#define FALSE (0!=0)
#endif

#define GP_USB_HOTPLUG_MATCH_VENDOR_ID          0x0001
#define GP_USB_HOTPLUG_MATCH_PRODUCT_ID         0x0002

#define GP_USB_HOTPLUG_MATCH_DEV_CLASS          0x0080
#define GP_USB_HOTPLUG_MATCH_DEV_SUBCLASS       0x0100
#define GP_USB_HOTPLUG_MATCH_DEV_PROTOCOL       0x0200

#ifdef __GNUC__
#define CR(result) \
	do { \
		int r = (result); \
		if (r < 0) { \
			fprintf(stderr, "print-usb-usermap: " \
				"Fatal error running `%s'.\n" \
				"Aborting.\n", #result ); \
			return (r); \
		} \
	} while (0)
#else /* !__GNUC__ */
#define CR(result) \
	do { \
		int r = (result); \
		if (r < 0) { \
			fprintf(stderr, "print-usb-usermap: " \
				"Fatal error detected, aborting.\n"); \
			return (r); \
		} \
	} while (0)
#endif /* __GNUC__ */

/* print-udev-rules
 *
 * Print out lines that can be included into an udev rules file
 * - for all cams supported by our instance of libgphoto2.
 *
 * written after list_cameras & print_usb_usermap
 */

static int print_udev_rules (const char *hotplug_script, const int add_comments)
{
	int x, n;
	CameraAbilitiesList *al;
        CameraAbilities a;

	CR (gp_abilities_list_new (&al));
	CR (gp_abilities_list_load (al, NULL)); /* use NULL context */
	CR (n = gp_abilities_list_count (al));

	printf ("# udev rules file for libgphoto2\n#\n");
	printf ("ACTION!=\"add\", GOTO=\"libgphoto2_rules_end\"\n\n");

        for (x = 0; x < n; x++) {
		int flags = 0;
		int class = 0, subclass = 0, proto = 0;
		int usb_vendor = 0, usb_product = 0;

		CR (gp_abilities_list_get_abilities (al, x, &a));

		if (!(a.port & GP_PORT_USB))
		    continue;

		if (a.usb_vendor) { /* usb product id may be 0! */
			class = 0;
			subclass = 0;
			proto = 0;
			flags = GP_USB_HOTPLUG_MATCH_VENDOR_ID | GP_USB_HOTPLUG_MATCH_PRODUCT_ID;
			usb_vendor = a.usb_vendor;
			usb_product = a.usb_product;
		} else if (a.usb_class) {
			class = a.usb_class;
			subclass = a.usb_subclass;
			proto = a.usb_protocol;
			flags = GP_USB_HOTPLUG_MATCH_DEV_CLASS;
			if (subclass != -1)
			    flags |= GP_USB_HOTPLUG_MATCH_DEV_SUBCLASS;
			else
			    subclass = 0;
			if (proto != -1)
			    flags |= GP_USB_HOTPLUG_MATCH_DEV_PROTOCOL;
			else
			    proto = 0;
			usb_vendor = 0;
			usb_product = 0;
		} else {
			flags = 0;
		}

		if (flags != 0) {
			printf ("# %s\n", 
				a.model);

			if (flags & GP_USB_HOTPLUG_MATCH_DEV_CLASS) {
				printf("SYSFS{bDeviceClass}==\"%02x\", ", class);
				if (flags & GP_USB_HOTPLUG_MATCH_DEV_SUBCLASS) {
					printf("SYSFS{bDeviceSubClass}==\"%02x\", ", subclass);
				}
				if (flags & GP_USB_HOTPLUG_MATCH_DEV_PROTOCOL) {
					printf("SYSFS{bDeviceProtocol}==\"%02x\", ", proto);
				}
			} else {
				printf ("SYSFS{idVendor}==\"%04x\", SYSFS{idProduct}==\"%04x\", ",
					a.usb_vendor, a.usb_product);
			}
			printf("MODE=\"0660\", GROUP=\"%s\"\n", GP_CAMERA_GROUP);
		} else {
			fputs ("Error: Neither vendor/product nor class/subclass matched\n", stderr);
			return 2;
		}
        }
	printf ("\nLABEL=\"libgphoto2_rules_end\"\n");

	CR (gp_abilities_list_free (al));

        return (0);
}

/* time zero for debug log time stamps */
struct timeval glob_tv_zero = { 0, 0 };

static void
debug_func (GPLogLevel level, const char *domain, const char *format,
	    va_list args, void *data)
{
	struct timeval tv;
	gettimeofday (&tv,NULL);
	fprintf (stderr, "%li.%06li %s(%i): ", 
		 tv.tv_sec - glob_tv_zero.tv_sec, 
		 (1000000 + tv.tv_usec - glob_tv_zero.tv_usec) % 1000000,
		 domain, level);
	vfprintf (stderr, format, args);
	fprintf (stderr, "\n");
}

int main(int argc, char *argv[])
{
	char *hotplug_script = NULL; /* script name to use */
	int add_comments = FALSE;    /* whether to add cam model as a comment */
	int debug_mode = FALSE;      /* whether we should output debug messages */

	int i;

	/* check command line arguments */
	for (i=1; i<argc; i++) {
		if (0 == strcmp(argv[i], "--verbose")) {
			if (add_comments) {
				fprintf(stderr, "Error: duplicate parameter: option \"%s\"\n", argv[i]);
				return 1;
			}
			add_comments = TRUE;
		} else if (0 == strcmp(argv[i], "--debug")) {
			if (debug_mode) {
				fprintf(stderr, "Error: duplicate parameter: option \"%s\"\n", argv[i]);
				return 1;
			}
			debug_mode = TRUE;
			/* now is time zero for debug log time stamps */
			gettimeofday (&glob_tv_zero, NULL);
			gp_log_add_func (GP_LOG_ALL, debug_func, NULL);
		} else if (0 == strcmp(argv[i], "--help")) {
			puts(HELP_TEXT);
			return 0;
		} else {
			if (hotplug_script != NULL) {
				fprintf(stderr, "Error: duplicate script parameter: \"%s\"\n", argv[i]);
				return 1;
			}
			/* assume script name */
			hotplug_script = argv[i];
		}
	}

	if (NULL == hotplug_script) {
		hotplug_script = GP_USB_HOTPLUG_SCRIPT;
	}

	return print_udev_rules(hotplug_script, add_comments);
}

/*
 * Local Variables:
 * c-file-style:"linux"
 * indent-tabs-mode:t
 * End:
 */
-- 
http://linuxfromscratch.org/mailman/listinfo/blfs-dev
FAQ: http://www.linuxfromscratch.org/blfs/faq.html
Unsubscribe: See the above information page

Reply via email to