18 #include "lirc/driver.h"
19 #include "lirc/drv_admin.h"
20 #include "lirc/lirc_options.h"
27 #define MAX_PLUGINS 256
38 static void* last_plugin = NULL;
43 .device =
"/dev/null",
58 .driver_version =
"0.9.2"
67 static int ends_with_so(
const char *str)
69 char *dot = strrchr(str,
'.');
71 return (NULL == dot) ? 0 : strcmp(dot + 1, PLUGIN_FILE_EXTENSION) == 0;
76 static int line_cmp(
const void* arg1,
const void* arg2)
78 return strcmp(*(
const char**)arg1, *(
const char**)arg2);
83 static struct driver* add_hw_name(
struct driver* hw,
void* arg)
85 char_array* a = (char_array*) arg;
87 logprintf(LIRC_ERROR,
"Too many plugins(%d)",
MAX_PLUGINS);
90 a->array[a->size] = strdup(hw->
name);
99 if (drv == (
struct driver*) NULL || name == NULL )
100 return (
struct driver*)NULL;
101 if (strcasecmp(drv->
name, (
char*)name) == 0)
103 return (
struct driver*)NULL;
115 if (last_plugin != NULL)
116 dlclose(last_plugin);
117 last_plugin = dlopen(path, RTLD_NOW);
118 if (last_plugin == NULL) {
119 logprintf(LIRC_ERROR, dlerror());
122 drivers = (
struct driver**)dlsym(last_plugin,
"hardwares");
123 if (drivers == (
struct driver**)NULL ){
124 logprintf(LIRC_WARNING,
125 "No hardwares entrypoint found in %s", path);
128 for ( ; *drivers; drivers++) {
129 if( (*drivers)->name == NULL){
130 logprintf(LIRC_WARNING,
131 "No driver name in %s", path);
134 result = (*func)(*drivers, arg);
135 if (result != (
struct driver*) NULL)
144 static struct driver* for_each_plugin_in_dir(
const char* dirpath,
155 if ((dir = opendir(dirpath)) == NULL){
156 logprintf(LIRC_INFO,
"Cannot open plugindir %s", dirpath);
157 return (
struct driver*) NULL;
159 while ((ent = readdir(dir)) != NULL) {
160 if (!ends_with_so(ent->d_name))
162 snprintf(path,
sizeof(path),
163 "%s/%s", dirpath, ent->d_name);
164 result = plugin_guest(path, drv_guest, arg);
165 if (result != (
struct driver*) NULL)
177 const char* pluginpath;
185 if (pluginpath == NULL)
187 if (strchr(pluginpath,
':') == (
char*) NULL)
188 return for_each_plugin_in_dir(pluginpath,
192 tmp_path = alloca(strlen(pluginpath) + 1);
193 strncpy(tmp_path, pluginpath, strlen(pluginpath) + 1);
194 for (s = strtok(tmp_path,
":"); s != NULL; s = strtok(NULL,
":")) {
195 result = for_each_plugin_in_dir(s,
199 if (result != (
struct driver*) NULL)
208 return for_each_path(visit_plugin, func, arg);
215 for_each_path(plugin_guest, NULL, arg );
229 if (for_each_driver(add_hw_name, (
void*)&names) != NULL) {
230 fprintf(stderr,
"Too many plugins (%d)\n",
MAX_PLUGINS);
233 qsort(names.array, names.size,
sizeof(
char*), line_cmp);
234 for (i = 0; i < names.size; i += 1) {
235 fprintf(file,
"%s\n", names.array[i]);
236 free(names.array[i]);
252 memcpy(&drv, &drv_null,
sizeof(
struct driver));
255 if (strcasecmp(name,
"dev/input") == 0) {
259 found = for_each_driver(match_hw_name, (
void*)name);
260 if (found != (
struct driver*)NULL){
261 memcpy(&drv, found,
sizeof(
struct driver));
const char * ciniparser_getstring(dictionary *d, const char *key, char *def)
Get the string associated to a key.
Interface to the userspace drivers.
const struct driver drv_null
struct driver *(* plugin_guest_func)(const char *, drv_guest_func, void *)
void hw_print_drivers(FILE *file)
Prints all drivers known to the system to the file given as argument.
struct driver *(* drv_guest_func)(struct driver *, void *)
int default_drvctl(unsigned int fd, void *arg)
int hw_choose_driver(const char *name)
int default_open(const char *path)
void for_each_plugin(plugin_guest_func plugin_guest, void *arg)