diff options
Diffstat (limited to 'backend/dll.c')
-rw-r--r-- | backend/dll.c | 125 |
1 files changed, 98 insertions, 27 deletions
diff --git a/backend/dll.c b/backend/dll.c index 5eaa046..73ffde4 100644 --- a/backend/dll.c +++ b/backend/dll.c @@ -42,7 +42,7 @@ allows managing an arbitrary number of SANE backends by using dynamic linking to load backends on demand. */ -/* Please increase version number with every change +/* Please increase version number with every change (don't forget to update dll.desc) */ #define DLL_VERSION "1.0.13" @@ -89,6 +89,20 @@ posix_dlsym (void *handle, const char *func) } # pragma GCC diagnostic pop + /* Similar to the above, GCC also warns about conversion between + pointers to functions. The ISO C standard says that invoking a + converted pointer to a function whose type is not compatible with + the pointed-to type, the behavior is undefined. Although GCC is + correct to warn about this, the dll backend has been using these + conversions without issues for a very long time already. + + Rather than push/pop around every use, which would get very ugly + real fast, ignore this particular warning for the remainder of + the file. + */ +# pragma GCC diagnostic ignored "-Wpragmas" /* backward compatibility */ +# pragma GCC diagnostic ignored "-Wcast-function-type" + /* Older versions of dlopen() don't define RTLD_NOW and RTLD_LAZY. They all seem to use a mode of 1 to indicate RTLD_NOW and some do not support RTLD_LAZY at all. Hence, unless defined, we define @@ -139,6 +153,8 @@ posix_dlsym (void *handle, const char *func) #define DLL_CONFIG_FILE "dll.conf" #define DLL_ALIASES_FILE "dll.aliases" +#include "../include/sane/sanei_usb.h" + enum SANE_Ops { OP_INIT = 0, @@ -353,7 +369,7 @@ load (struct backend *be) image_id id = -1; int i, w; directory_which which[3] = { B_USER_ADDONS_DIRECTORY, B_COMMON_ADDONS_DIRECTORY, B_BEOS_ADDONS_DIRECTORY }; - + /* look for config files in SANE/conf */ for (w = 0; (w < 3) && (id < 0) && (find_directory(which[w],0,true,path,PATH_MAX) == 0); w++) { @@ -373,7 +389,7 @@ load (struct backend *be) continue; /* try next path */ } be->handle=(void *)id; - + for (i = 0; i < NUM_OPS; ++i) { void *(*op) (); @@ -492,7 +508,7 @@ load (struct backend *be) break; DBG (4, "load: couldn't open `%s' (%s)\n", libname, strerror (errno)); -#ifdef ALT_POSTFIX +#ifdef ALT_POSTFIX /* Some platforms have two ways of storing their libraries, try both postfixes */ snprintf (libname, sizeof (libname), "%s/" PREFIX "%s" ALT_POSTFIX, @@ -797,7 +813,8 @@ read_dlld (void) DIR *dlld; struct dirent *dllconf; struct stat st; - char conffile[PATH_MAX], dlldir[PATH_MAX]; + char dlldir[PATH_MAX]; + char conffile[PATH_MAX + strlen("/") + NAME_MAX]; size_t len, plen; const char *dir_list; char *copy, *next, *dir; @@ -849,7 +866,7 @@ read_dlld (void) || (dllconf->d_name[len-1] == '#')) continue; - snprintf (conffile, PATH_MAX, "%s/%s", dlldir, dllconf->d_name); + snprintf (conffile, sizeof(conffile), "%s/%s", dlldir, dllconf->d_name); DBG (5, "sane_init/read_dlld: considering %s\n", conffile); @@ -882,7 +899,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) char path[1024]; directory_which which[3] = { B_USER_ADDONS_DIRECTORY, B_COMMON_ADDONS_DIRECTORY, B_BEOS_ADDONS_DIRECTORY }; int i; -#endif +#endif DBG_INIT (); @@ -934,7 +951,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) } fclose (fp); -#else +#else /* no ugly config files, just get scanners from their ~/config/add-ons/SANE */ /* look for drivers */ for (i = 0; i < 3; i++) @@ -943,13 +960,13 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) continue; strcat(path,"/SANE/"); dir=opendir(path); - if(!dir) continue; + if(!dir) continue; while((dirent=readdir(dir))) { if((strcmp(dirent->d_name,".")==0) || (strcmp(dirent->d_name,"..")==0)) continue; if((strcmp(dirent->d_name,"dll")==0)) continue; - add_backend(dirent->d_name,0); + add_backend(dirent->d_name,0); } closedir(dir); } @@ -1155,7 +1172,8 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) SANE_Status sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle) { - const char *be_name, *dev_name; + char *be_name; + const char *dev_name; struct meta_scanner *s; SANE_Handle handle; struct backend *be; @@ -1176,29 +1194,78 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle) } dev_name = strchr (full_name, ':'); + + int is_fakeusb = 0, is_fakeusbdev = 0, is_fakeusbout = 0; + if (dev_name) { -#ifdef strndupa - be_name = strndupa (full_name, dev_name - full_name); -#else - char *tmp; + is_fakeusb = strncmp(full_name, "fakeusb", dev_name - full_name) == 0 && + dev_name - full_name == 7; + is_fakeusbdev = strncmp(full_name, "fakeusbdev", dev_name - full_name) == 0 && + dev_name - full_name == 10; + is_fakeusbout = strncmp(full_name, "fakeusbout", dev_name - full_name) == 0 && + dev_name - full_name == 10; + } - tmp = alloca (dev_name - full_name + 1); - memcpy (tmp, full_name, dev_name - full_name); - tmp[dev_name - full_name] = '\0'; - be_name = tmp; -#endif - ++dev_name; /* skip colon */ + if (is_fakeusb || is_fakeusbdev) + { + ++dev_name; // skip colon + status = sanei_usb_testing_enable_replay(dev_name, is_fakeusbdev); + if (status != SANE_STATUS_GOOD) + return status; + + be_name = sanei_usb_testing_get_backend(); + if (be_name == NULL) + { + DBG (0, "%s: unknown backend for testing\n", __func__); + return SANE_STATUS_ACCESS_DENIED; + } } else { - /* if no colon interpret full_name as the backend name; an empty - backend device name will cause us to open the first device of - that backend. */ - be_name = full_name; - dev_name = ""; + char* fakeusbout_path = NULL; + if (is_fakeusbout) + { + ++dev_name; // skip colon + + const char* path_end = strchr(dev_name, ':'); + if (path_end == NULL) + { + DBG (0, "%s: the device name does not contain path\n", __func__); + return SANE_STATUS_INVAL; + } + fakeusbout_path = strndup(dev_name, path_end - dev_name); + + full_name = path_end + 1; // skip colon + dev_name = strchr(full_name, ':'); + } + + if (dev_name) + { + be_name = strndup(full_name, dev_name - full_name); + ++dev_name; /* skip colon */ + } + else + { + /* if no colon interpret full_name as the backend name; an empty + backend device name will cause us to open the first device of + that backend. */ + be_name = strdup(full_name); + dev_name = ""; + } + + if (is_fakeusbout) + { + status = sanei_usb_testing_enable_record(fakeusbout_path, be_name); + free(fakeusbout_path); + if (status != SANE_STATUS_GOOD) + return status; + } } + if (!be_name) + return SANE_STATUS_NO_MEM; + if (!be_name[0]) be = first_backend; else @@ -1210,8 +1277,12 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle) { status = add_backend (be_name, &be); if (status != SANE_STATUS_GOOD) - return status; + { + free(be_name); + return status; + } } + free(be_name); if (!be->inited) { |