Add support in devmand for using config dirs.
Add support in devmand for using configuration directories to allow 3rd party packages to add configuration items.
This commit is contained in:
parent
ade7dc8ded
commit
51a9903002
|
@ -5,6 +5,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "usb_driver.h"
|
#include "usb_driver.h"
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
#define DEVMAN_TYPE_NAME "dev_type"
|
#define DEVMAN_TYPE_NAME "dev_type"
|
||||||
#define PATH_LEN 256
|
#define PATH_LEN 256
|
||||||
#define INVAL_MAJOR -1
|
#define INVAL_MAJOR -1
|
||||||
|
#define MAX_CONFIG_DIRS 4
|
||||||
|
|
||||||
static void main_loop();
|
static void main_loop();
|
||||||
static void handle_event();
|
static void handle_event();
|
||||||
|
@ -42,11 +44,12 @@ static LIST_HEAD(usb_driver_inst_head, devmand_driver_instance) instances =
|
||||||
|
|
||||||
static int _run = 1;
|
static int _run = 1;
|
||||||
struct global_args {
|
struct global_args {
|
||||||
int deamonize;
|
|
||||||
char *path;
|
char *path;
|
||||||
char *config;
|
char *config_dirs[MAX_CONFIG_DIRS];
|
||||||
|
int config_dir_count ;
|
||||||
int major_offset;
|
int major_offset;
|
||||||
int verbose;
|
int verbose;
|
||||||
|
int check_config;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dev_type {
|
enum dev_type {
|
||||||
|
@ -57,14 +60,20 @@ enum dev_type {
|
||||||
|
|
||||||
extern FILE *yyin;
|
extern FILE *yyin;
|
||||||
|
|
||||||
static struct global_args args = {0,NULL,NULL,25, 0};
|
static struct global_args args = {
|
||||||
|
.path = NULL,
|
||||||
|
.config_dirs = {NULL,NULL,NULL,NULL},
|
||||||
|
.config_dir_count = 0,
|
||||||
|
.major_offset = 25,
|
||||||
|
.verbose = 0,
|
||||||
|
.check_config = 0};
|
||||||
|
|
||||||
static struct option options[] =
|
static struct option options[] =
|
||||||
{
|
{
|
||||||
{"deamonize", no_argument, NULL, 'd'},
|
{"dir" , required_argument, NULL, 'd'},
|
||||||
{"path", required_argument, NULL, 'p'},
|
{"path", required_argument, NULL, 'p'},
|
||||||
{"config", required_argument, NULL, 'c'},
|
|
||||||
{"verbose", required_argument, NULL, 'v'},
|
{"verbose", required_argument, NULL, 'v'},
|
||||||
|
{"check-config", no_argument, NULL, 'x'},
|
||||||
{0,0,0,0} /* terminating entry */
|
{0,0,0,0} /* terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -303,16 +312,72 @@ add_usb_match_id
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static void parse_config()
|
static void parse_config()
|
||||||
{
|
{
|
||||||
yyin = fopen(args.config, "r");
|
int i, status, error;
|
||||||
|
struct stat stats;
|
||||||
|
char * dirname;
|
||||||
|
|
||||||
|
DIR * dir;
|
||||||
|
struct dirent entry;
|
||||||
|
struct dirent *result;
|
||||||
|
char config_file[PATH_MAX];
|
||||||
|
|
||||||
|
dbg("Parsing configuration directories... ");
|
||||||
|
/* Next parse the configuration directories */
|
||||||
|
for(i=0; i < args.config_dir_count; i++){
|
||||||
|
dirname = args.config_dirs[i];
|
||||||
|
dbg("Parsing config dir %s ", dirname);
|
||||||
|
status = stat(dirname,&stats);
|
||||||
|
if (status == -1){
|
||||||
|
error = errno;
|
||||||
|
fprintf(stderr,"Failed to read directory '%s':%s"
|
||||||
|
" (skipping) \n", dirname,strerror(error));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!S_ISDIR(stats.st_mode)){
|
||||||
|
fprintf(stderr,"Parse configuration skipping %s"
|
||||||
|
" (not a directory) \n",dirname);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dir = opendir(dirname);
|
||||||
|
if (dir == NULL){
|
||||||
|
error = errno;
|
||||||
|
fprintf(stderr,"Parse configuration failed to read"
|
||||||
|
" dir '%s' (skipping) :%s\n",dirname,
|
||||||
|
strerror(error));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
while( (status = readdir_r(dir,&entry,&result)) == 0 ){
|
||||||
|
if (result == NULL){ /* last entry */
|
||||||
|
closedir(dir);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* concatenate dir and file name to open it */
|
||||||
|
snprintf(config_file,PATH_MAX, "%s/%s",
|
||||||
|
dirname,entry.d_name);
|
||||||
|
status = stat(config_file, &stats);
|
||||||
|
if (status == -1){
|
||||||
|
error = errno;
|
||||||
|
fprintf(stderr,"Parse configuration Failed to stat"
|
||||||
|
" file '%s': %s (skipping)\n",
|
||||||
|
config_file,strerror(error));
|
||||||
|
}
|
||||||
|
if (S_ISREG(stats.st_mode)){
|
||||||
|
dbg("Parsing file %s",config_file);
|
||||||
|
yyin = fopen(config_file, "r");
|
||||||
|
|
||||||
if (yyin < 0) {
|
if (yyin < 0) {
|
||||||
printf("Can not open config file: %d.\n", errno);
|
printf("Can not open config file:"
|
||||||
|
" %d.\n", errno);
|
||||||
}
|
}
|
||||||
dbg("Parsing configfile... ");
|
|
||||||
yyparse();
|
yyparse();
|
||||||
dbg("Done.");
|
dbg("Done.");
|
||||||
|
|
||||||
fclose(yyin);
|
fclose(yyin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbg("Parsing configuration directories done... ");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
@ -369,44 +434,60 @@ int main(int argc, char *argv[])
|
||||||
int opt, optindex, res;
|
int opt, optindex, res;
|
||||||
struct devmand_usb_driver *driver;
|
struct devmand_usb_driver *driver;
|
||||||
|
|
||||||
create_pid_file();
|
|
||||||
|
|
||||||
/* get command line arguments */
|
/* get command line arguments */
|
||||||
while ((opt = getopt_long(argc, argv, "vdc:p:h?", options, &optindex))
|
while ((opt = getopt_long(argc, argv, "d:p:vxh?", options, &optindex))
|
||||||
!= -1) {
|
!= -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'd':
|
case 'd':/* config directory */
|
||||||
args.deamonize = 1;
|
if (args.config_dir_count >= MAX_CONFIG_DIRS){
|
||||||
|
fprintf(stderr,"Parse arguments: Maximum"
|
||||||
|
" of %i configuration directories"
|
||||||
|
" reached skipping directory '%s'\n"
|
||||||
|
, MAX_CONFIG_DIRS, optarg);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
}
|
||||||
|
args.config_dirs[args.config_dir_count] = optarg;
|
||||||
|
args.config_dir_count++;
|
||||||
|
break;
|
||||||
|
case 'p': /* sysfs path */
|
||||||
args.path = optarg;
|
args.path = optarg;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'v': /* verbose */
|
||||||
args.config = optarg;
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
args.verbose = 1;
|
args.verbose = 1;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'x': /* check config */
|
||||||
case '?':
|
args.check_config = 1;
|
||||||
|
break;
|
||||||
|
case 'h': /* help */
|
||||||
|
case '?': /* help */
|
||||||
default:
|
default:
|
||||||
display_usage(argv[0]);
|
display_usage(argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* is path set? */
|
/* is path set? */
|
||||||
if (args.path == NULL) {
|
if (args.path == NULL) {
|
||||||
args.path = "/sys/";
|
args.path = "/sys/";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is path set? */
|
/* is the configuration directory set? */
|
||||||
if (args.config == NULL) {
|
if (args.config_dir_count == 0) {
|
||||||
args.config = "/etc/devmand/devmand.cfg";
|
dbg("Using default configuration directory");
|
||||||
|
args.config_dirs[0] = "/etc/devmand";
|
||||||
|
args.config_dir_count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg("Options: deamonize: %s, path: %s",
|
/* If we only check the configuration run and exit imediately */
|
||||||
args.deamonize?"true":"false", args.path);
|
if (args.check_config == 1){
|
||||||
|
fprintf(stdout, "Only parsing configuration\n");
|
||||||
|
parse_config();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
create_pid_file();
|
||||||
|
|
||||||
/* create control socket if not exists */
|
/* create control socket if not exists */
|
||||||
res = mkfifo(CONTROL_FIFO_PATH, S_IWRITE);
|
res = mkfifo(CONTROL_FIFO_PATH, S_IWRITE);
|
||||||
|
@ -841,7 +922,8 @@ static void main_loop()
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
static void display_usage(const char *name)
|
static void display_usage(const char *name)
|
||||||
{
|
{
|
||||||
printf("Usage: %s [-d|--deamonize] [{-p|--pathname} PATH_TO_SYS}"
|
printf("Usage: %s [{-p|--pathname} PATH_TO_SYS}"
|
||||||
" [{-c|--config} CONFIG_FILE]\n", name);
|
" [{-d|--config-dir} CONFIG_DIR] [-v|--verbose]"
|
||||||
|
" [[x||--check-config]\n", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ devman_device_add_event(struct devman_device* dev)
|
||||||
|
|
||||||
memset(event, 0, sizeof(*event));
|
memset(event, 0, sizeof(*event));
|
||||||
|
|
||||||
strcat(event->data, ADD_STRING);
|
strncpy(event->data, ADD_STRING, DEVMAN_STRING_LEN - 1);
|
||||||
|
|
||||||
res = devman_generate_path(event->data, DEVMAN_STRING_LEN - 11 , dev);
|
res = devman_generate_path(event->data, DEVMAN_STRING_LEN - 11 , dev);
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ devman_device_remove_event(struct devman_device* dev)
|
||||||
|
|
||||||
memset(event, 0, sizeof(*event));
|
memset(event, 0, sizeof(*event));
|
||||||
|
|
||||||
strcat(event->data, REMOVE_STRING);
|
strncpy(event->data, REMOVE_STRING, DEVMAN_STRING_LEN - 1);
|
||||||
|
|
||||||
res = devman_generate_path(event->data, DEVMAN_STRING_LEN-11, dev);
|
res = devman_generate_path(event->data, DEVMAN_STRING_LEN-11, dev);
|
||||||
|
|
||||||
|
@ -262,7 +262,6 @@ int do_add_device(message *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = devman_dev_add_child(parent, devinf);
|
dev = devman_dev_add_child(parent, devinf);
|
||||||
dev->state = DEVMAN_DEVICE_UNBOUND;
|
|
||||||
|
|
||||||
if (dev == NULL) {
|
if (dev == NULL) {
|
||||||
res = ENODEV;
|
res = ENODEV;
|
||||||
|
@ -271,6 +270,8 @@ int do_add_device(message *msg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev->state = DEVMAN_DEVICE_UNBOUND;
|
||||||
|
|
||||||
dev->owner = msg->m_source;
|
dev->owner = msg->m_source;
|
||||||
|
|
||||||
msg->DEVMAN_DEVICE_ID = dev->dev_id;
|
msg->DEVMAN_DEVICE_ID = dev->dev_id;
|
||||||
|
@ -355,10 +356,16 @@ devman_dev_add_child
|
||||||
char * buffer = (char *) (devinf);
|
char * buffer = (char *) (devinf);
|
||||||
char tmp_buf[128];
|
char tmp_buf[128];
|
||||||
struct devman_device_info_entry *entries;
|
struct devman_device_info_entry *entries;
|
||||||
|
|
||||||
/* create device */
|
/* create device */
|
||||||
struct devman_device * dev = malloc(sizeof(struct devman_device));
|
struct devman_device * dev = malloc(sizeof(struct devman_device));
|
||||||
|
if (dev == NULL) {
|
||||||
|
panic("devman_dev_add_child: out of memory\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (parent == NULL) {
|
if (parent == NULL) {
|
||||||
|
free(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue