You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
246 lines
7.0 KiB
246 lines
7.0 KiB
Date: Sat, 10 Jan 2009 21:14:50 +0100 (CET)
|
|
From: Stefan Richter <stefanr@s5r6.in-berlin.de>
|
|
Subject: Re: [PATCH libraw1394] Work without permission to access local node's
|
|
/dev/fw*
|
|
To: Dan Dennedy <dan@dennedy.org>
|
|
Cc: linux1394-devel@lists.sourceforge.net,
|
|
dcm@acm.org
|
|
|
|
On 10 Jan, Stefan Richter wrote:
|
|
> --- a/src/fw.c
|
|
> +++ b/src/fw.c
|
|
> @@ -125,17 +125,19 @@ scan_devices(fw_handle_t handle)
|
|
> char filename[32];
|
|
> struct fw_cdev_get_info get_info;
|
|
> struct fw_cdev_event_bus_reset reset;
|
|
> - int fd, err, i, fname_str_sz;
|
|
> + int fd, err, i, j, fname_str_sz;
|
|
> struct port *ports;
|
|
>
|
|
> ports = handle->ports;
|
|
> memset(ports, 0, sizeof handle->ports);
|
|
> + for (i = 0; i < MAX_PORTS; i++)
|
|
> + ports[i].card = -1;
|
|
> +
|
|
|
|
The memset is not necessary.
|
|
|
|
|
|
From: Stefan Richter <stefanr@s5r6.in-berlin.de>
|
|
Subject: [PATCH] Work without permission to access local node's /dev/fw*
|
|
|
|
Fix for juju backend:
|
|
|
|
libraw1394 required write permission to the character device file of
|
|
the local node(s) in order to enumerate cards and for a number of
|
|
other operations. This forced users to either run applications like
|
|
dvgrab and kino with elevated privileges, or to configure write
|
|
permission for all /dev/fw* or at least for local nodes' /dev/fw*.
|
|
|
|
We now use the first accessible file which was found for each card
|
|
for as many tasks as possible, instead of the local node's file.
|
|
|
|
This allows distributors or admins to implement stricter access
|
|
rights (default off, e.g. only on for AV/C and IIDC devices)
|
|
without sacrificing functionality of said class of applications.
|
|
Access to the local node is now only required by low-level tools
|
|
like gscanbus.
|
|
|
|
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
|
|
---
|
|
src/fw-iso.c | 4 ++--
|
|
src/fw.c | 50 +++++++++++++++++++++++++++++++++-----------------
|
|
src/fw.h | 6 +++---
|
|
3 files changed, 38 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/src/fw-iso.c b/src/fw-iso.c
|
|
index 6a84662..a87259b 100644
|
|
--- a/src/fw-iso.c
|
|
+++ b/src/fw-iso.c
|
|
@@ -407,7 +407,7 @@ iso_init(fw_handle_t handle, int type,
|
|
if (handle->iso.packets == NULL)
|
|
return -1;
|
|
|
|
- handle->iso.fd = open(handle->local_filename, O_RDWR);
|
|
+ handle->iso.fd = open(handle->iso.filename, O_RDWR);
|
|
if (handle->iso.fd < 0) {
|
|
free(handle->iso.packets);
|
|
handle->iso.packets = NULL;
|
|
@@ -557,7 +557,7 @@ int fw_read_cycle_timer(fw_handle_t handle,
|
|
int err;
|
|
struct fw_cdev_get_cycle_timer ctr = { 0 };
|
|
|
|
- err = ioctl(handle->local_fd, FW_CDEV_IOC_GET_CYCLE_TIMER, &ctr);
|
|
+ err = ioctl(handle->ioctl_fd, FW_CDEV_IOC_GET_CYCLE_TIMER, &ctr);
|
|
if (!err) {
|
|
*cycle_timer = ctr.cycle_timer;
|
|
*local_time = ctr.local_time;
|
|
diff --git a/src/fw.c b/src/fw.c
|
|
index e211b60..3f5d806 100644
|
|
--- a/src/fw.c
|
|
+++ b/src/fw.c
|
|
@@ -125,17 +125,18 @@ scan_devices(fw_handle_t handle)
|
|
char filename[32];
|
|
struct fw_cdev_get_info get_info;
|
|
struct fw_cdev_event_bus_reset reset;
|
|
- int fd, err, i, fname_str_sz;
|
|
+ int fd, err, i, j, fname_str_sz;
|
|
struct port *ports;
|
|
|
|
ports = handle->ports;
|
|
- memset(ports, 0, sizeof handle->ports);
|
|
+ for (i = 0; i < MAX_PORTS; i++)
|
|
+ ports[i].card = -1;
|
|
+
|
|
dir = opendir(FW_DEVICE_DIR);
|
|
if (dir == NULL)
|
|
return -1;
|
|
|
|
- i = 0;
|
|
- while (1) {
|
|
+ for (i = 0; i < MAX_PORTS; ) {
|
|
de = readdir(dir);
|
|
if (de == NULL)
|
|
break;
|
|
@@ -161,7 +162,10 @@ scan_devices(fw_handle_t handle)
|
|
if (err < 0)
|
|
continue;
|
|
|
|
- if (i < MAX_PORTS && reset.node_id == reset.local_node_id) {
|
|
+ for (j = 0; j < i; j++)
|
|
+ if (ports[j].card == get_info.card)
|
|
+ break;
|
|
+ if (j == i) {
|
|
fname_str_sz = sizeof(ports[i].device_file) - 1;
|
|
strncpy(ports[i].device_file, filename, fname_str_sz);
|
|
ports[i].device_file[fname_str_sz] = '\0';
|
|
@@ -626,20 +630,27 @@ int fw_set_port(fw_handle_t handle, int port)
|
|
return -1;
|
|
}
|
|
|
|
- handle->generation = reset.generation;
|
|
- if (reset.node_id == reset.local_node_id) {
|
|
+ if (handle->iso.filename == NULL) {
|
|
memcpy(&handle->reset, &reset, sizeof handle->reset);
|
|
- handle->local_fd = fd;
|
|
- fname_str_sz = sizeof(handle->local_filename) -1;
|
|
- strncpy(handle->local_filename, filename, fname_str_sz);
|
|
- handle->local_filename[fname_str_sz] = '\0';
|
|
+ handle->iso.filename = handle->devices[i].filename;
|
|
+ handle->ioctl_fd = fd;
|
|
}
|
|
|
|
+ if (reset.node_id == reset.local_node_id)
|
|
+ handle->local_device = &handle->devices[i];
|
|
+
|
|
+ handle->generation = reset.generation;
|
|
+
|
|
i++;
|
|
}
|
|
|
|
closedir(dir);
|
|
|
|
+ if (i == 0) {
|
|
+ errno = ENODEV;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -656,7 +667,7 @@ int fw_reset_bus_new(fw_handle_t handle, int type)
|
|
break;
|
|
}
|
|
|
|
- return ioctl(handle->local_fd,
|
|
+ return ioctl(handle->ioctl_fd,
|
|
FW_CDEV_IOC_INITIATE_BUS_RESET, &initiate);
|
|
}
|
|
|
|
@@ -817,7 +828,7 @@ fw_arm_register(fw_handle_t handle, nodeaddr_t start,
|
|
request.length = length;
|
|
request.closure = ptr_to_u64(&allocation->closure);
|
|
|
|
- retval = ioctl(handle->local_fd, FW_CDEV_IOC_ALLOCATE, &request);
|
|
+ retval = ioctl(handle->ioctl_fd, FW_CDEV_IOC_ALLOCATE, &request);
|
|
if (retval < 0) {
|
|
free(allocation);
|
|
return -1;
|
|
@@ -863,7 +874,7 @@ fw_arm_unregister(fw_handle_t handle, nodeaddr_t start)
|
|
request.handle = allocation->handle;
|
|
free(allocation);
|
|
|
|
- return ioctl(handle->local_fd, FW_CDEV_IOC_DEALLOCATE, &request);
|
|
+ return ioctl(handle->ioctl_fd, FW_CDEV_IOC_DEALLOCATE, &request);
|
|
}
|
|
|
|
int
|
|
@@ -1251,7 +1262,7 @@ fw_start_fcp_listen(fw_handle_t handle)
|
|
request.offset = CSR_REGISTER_BASE + CSR_FCP_COMMAND;
|
|
request.length = CSR_FCP_END - CSR_FCP_COMMAND;
|
|
request.closure = ptr_to_u64(closure);
|
|
- if (ioctl(handle->local_fd, FW_CDEV_IOC_ALLOCATE, &request) < 0)
|
|
+ if (ioctl(handle->ioctl_fd, FW_CDEV_IOC_ALLOCATE, &request) < 0)
|
|
return -1;
|
|
|
|
handle->fcp_allocation_handle = request.handle;
|
|
@@ -1266,7 +1277,7 @@ fw_stop_fcp_listen(fw_handle_t handle)
|
|
|
|
request.handle = handle->fcp_allocation_handle;
|
|
|
|
- return ioctl(handle->local_fd, FW_CDEV_IOC_DEALLOCATE, &request);
|
|
+ return ioctl(handle->ioctl_fd, FW_CDEV_IOC_DEALLOCATE, &request);
|
|
}
|
|
|
|
int
|
|
@@ -1284,13 +1295,18 @@ fw_get_config_rom(fw_handle_t handle, quadlet_t *buffer,
|
|
struct fw_cdev_get_info get_info;
|
|
int err;
|
|
|
|
+ if (handle->local_device == NULL) {
|
|
+ errno = EPERM;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
memset(&get_info, 0, sizeof(get_info));
|
|
get_info.version = FW_CDEV_VERSION;
|
|
get_info.rom = ptr_to_u64(buffer);
|
|
get_info.rom_length = buffersize;
|
|
get_info.bus_reset = 0;
|
|
|
|
- err = ioctl(handle->local_fd, FW_CDEV_IOC_GET_INFO, &get_info);
|
|
+ err = ioctl(handle->local_device->fd, FW_CDEV_IOC_GET_INFO, &get_info);
|
|
if (err)
|
|
return err;
|
|
|
|
diff --git a/src/fw.h b/src/fw.h
|
|
index 56b59d9..a5e3772 100644
|
|
--- a/src/fw.h
|
|
+++ b/src/fw.h
|
|
@@ -101,6 +101,7 @@ struct fw_handle {
|
|
__u32 fcp_allocation_handle;
|
|
struct allocation *allocations;
|
|
|
|
+ int ioctl_fd;
|
|
int epoll_fd;
|
|
int inotify_fd;
|
|
int inotify_watch;
|
|
@@ -110,13 +111,12 @@ struct fw_handle {
|
|
struct epoll_closure inotify_closure;
|
|
|
|
struct device devices[MAX_DEVICES];
|
|
+ struct device *local_device;
|
|
int nodes[MAX_DEVICES];
|
|
- int local_fd;
|
|
- char local_filename[FILENAME_SIZE];
|
|
-
|
|
struct fw_cdev_event_bus_reset reset;
|
|
|
|
struct {
|
|
+ char *filename;
|
|
struct epoll_closure closure;
|
|
int fd;
|
|
int type;
|
|
--
|
|
1.6.0.6
|