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:
Kees Jongenburger 2012-06-04 09:34:04 +00:00
parent ade7dc8ded
commit 51a9903002
2 changed files with 123 additions and 34 deletions

View file

@ -5,6 +5,7 @@
#include <string.h>
#include <lib.h>
#include <sys/stat.h>
#include <dirent.h>
#include <assert.h>
#include <signal.h>
#include "usb_driver.h"
@ -17,6 +18,7 @@
#define DEVMAN_TYPE_NAME "dev_type"
#define PATH_LEN 256
#define INVAL_MAJOR -1
#define MAX_CONFIG_DIRS 4
static void main_loop();
static void handle_event();
@ -42,11 +44,12 @@ static LIST_HEAD(usb_driver_inst_head, devmand_driver_instance) instances =
static int _run = 1;
struct global_args {
int deamonize;
char *path;
char *config;
char *config_dirs[MAX_CONFIG_DIRS];
int config_dir_count ;
int major_offset;
int verbose;
int check_config;
};
enum dev_type {
@ -57,14 +60,20 @@ enum dev_type {
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[] =
{
{"deamonize", no_argument, NULL, 'd'},
{"dir" , required_argument, NULL, 'd'},
{"path", required_argument, NULL, 'p'},
{"config", required_argument, NULL, 'c'},
{"verbose", required_argument, NULL, 'v'},
{"check-config", no_argument, NULL, 'x'},
{0,0,0,0} /* terminating entry */
};
@ -303,16 +312,72 @@ add_usb_match_id
*===========================================================================*/
static void parse_config()
{
yyin = fopen(args.config, "r");
int i, status, error;
struct stat stats;
char * dirname;
if (yyin < 0) {
printf("Can not open config file: %d.\n", errno);
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) {
printf("Can not open config file:"
" %d.\n", errno);
}
yyparse();
dbg("Done.");
fclose(yyin);
}
}
}
dbg("Parsing configfile... ");
yyparse();
dbg("Done.");
dbg("Parsing configuration directories done... ");
fclose(yyin);
}
/*===========================================================================*
@ -369,44 +434,60 @@ int main(int argc, char *argv[])
int opt, optindex, res;
struct devmand_usb_driver *driver;
create_pid_file();
/* 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) {
switch (opt) {
case 'd':
args.deamonize = 1;
case 'd':/* config directory */
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;
}
args.config_dirs[args.config_dir_count] = optarg;
args.config_dir_count++;
break;
case 'p':
case 'p': /* sysfs path */
args.path = optarg;
break;
case 'c':
args.config = optarg;
break;
case 'v':
case 'v': /* verbose */
args.verbose = 1;
break;
case 'h':
case '?':
case 'x': /* check config */
args.check_config = 1;
break;
case 'h': /* help */
case '?': /* help */
default:
display_usage(argv[0]);
return 0;
}
}
/* is path set? */
if (args.path == NULL) {
args.path = "/sys/";
}
/* is path set? */
if (args.config == NULL) {
args.config = "/etc/devmand/devmand.cfg";
/* is the configuration directory set? */
if (args.config_dir_count == 0) {
dbg("Using default configuration directory");
args.config_dirs[0] = "/etc/devmand";
args.config_dir_count = 1;
}
dbg("Options: deamonize: %s, path: %s",
args.deamonize?"true":"false", args.path);
/* If we only check the configuration run and exit imediately */
if (args.check_config == 1){
fprintf(stdout, "Only parsing configuration\n");
parse_config();
exit(0);
}
create_pid_file();
/* create control socket if not exists */
res = mkfifo(CONTROL_FIFO_PATH, S_IWRITE);
@ -421,7 +502,7 @@ int main(int argc, char *argv[])
run_cleanscript(driver);
}
signal(SIGINT, sig_int);
signal(SIGINT, sig_int);
main_loop();
@ -841,7 +922,8 @@ static void main_loop()
*===========================================================================*/
static void display_usage(const char *name)
{
printf("Usage: %s [-d|--deamonize] [{-p|--pathname} PATH_TO_SYS}"
" [{-c|--config} CONFIG_FILE]\n", name);
printf("Usage: %s [{-p|--pathname} PATH_TO_SYS}"
" [{-d|--config-dir} CONFIG_DIR] [-v|--verbose]"
" [[x||--check-config]\n", name);
}

View file

@ -86,7 +86,7 @@ devman_device_add_event(struct devman_device* dev)
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);
@ -119,7 +119,7 @@ devman_device_remove_event(struct devman_device* dev)
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);
@ -262,7 +262,6 @@ int do_add_device(message *msg)
}
dev = devman_dev_add_child(parent, devinf);
dev->state = DEVMAN_DEVICE_UNBOUND;
if (dev == NULL) {
res = ENODEV;
@ -270,6 +269,8 @@ int do_add_device(message *msg)
do_reply(msg, res);
return 0;
}
dev->state = DEVMAN_DEVICE_UNBOUND;
dev->owner = msg->m_source;
@ -355,10 +356,16 @@ devman_dev_add_child
char * buffer = (char *) (devinf);
char tmp_buf[128];
struct devman_device_info_entry *entries;
/* create 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) {
free(dev);
return NULL;
}