libgphoto2 photo camera library (libgphoto2) Internals  2.5.23
gphoto2-port-info-list.c
Go to the documentation of this file.
1 
23 #define _GNU_SOURCE
24 
25 #include "config.h"
26 
28 
29 #include <stdlib.h>
30 #include <string.h>
31 #include <stdio.h>
32 #ifdef HAVE_REGEX
33 #include <regex.h>
34 #elif defined(_MSC_VER)
35 #pragma message("We need regex.h, but it has not been detected.")
36 #else
37 #warning We need regex.h, but it has not been detected.
38 #endif
39 
40 #include <ltdl.h>
41 
45 
46 #include "gphoto2-port-info.h"
47 
48 #ifdef ENABLE_NLS
49 # include <libintl.h>
50 # undef _
51 # define _(String) dgettext (GETTEXT_PACKAGE, String)
52 # ifdef gettext_noop
53 # define N_(String) gettext_noop (String)
54 # else
55 # define N_(String) (String)
56 # endif
57 #else
58 # define textdomain(String) (String)
59 # define gettext(String) (String)
60 # define dgettext(Domain,Message) (Message)
61 # define dcgettext(Domain,Message,Type) (Message)
62 # define bindtextdomain(Domain,Directory) (Domain)
63 # define bind_textdomain_codeset(Domain,codeset) (codeset)
64 # define ngettext(String1,String2,Count) ((Count==1)?String1:String2)
65 # define _(String) (String)
66 # define N_(String) (String)
67 #endif
68 
76  unsigned int count;
77  unsigned int iolib_count;
78 };
79 
80 #define CR(x) {int r=(x);if (r<0) return (r);}
81 
82 
95 const char*
96 gp_port_message_codeset (const char *codeset) {
97  return bind_textdomain_codeset (GETTEXT_PACKAGE, codeset);
98 }
99 
110 int
112 {
113  C_PARAMS (list);
114 
115  /*
116  * We put this in here because everybody needs to call this function
117  * before accessing ports...
118  */
119  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
120 
121  C_MEM (*list = calloc (1, sizeof (GPPortInfoList)));
122 
123  return (GP_OK);
124 }
125 
134 int
136 {
137  C_PARAMS (list);
138 
139  if (list->info) {
140  unsigned int i;
141 
142  for (i=0;i<list->count;i++) {
143  free (list->info[i]->name);
144  list->info[i]->name = NULL;
145  free (list->info[i]->path);
146  list->info[i]->path = NULL;
147  free (list->info[i]->library_filename);
148  list->info[i]->library_filename = NULL;
149  free (list->info[i]);
150  }
151  free (list->info);
152  list->info = NULL;
153  }
154  list->count = 0;
155 
156  free (list);
157 
158  return (GP_OK);
159 }
160 
176 int
178 {
179  int generic, i;
180 
181  C_PARAMS (list);
182 
183  C_MEM (list->info = realloc (list->info, sizeof (GPPortInfo) * (list->count + 1)));
184  list->count++;
185  list->info[list->count - 1] = info;
186 
187  /* Ignore generic entries */
188  for (generic = i = 0; i < list->count; i++)
189  if (!strlen (list->info[i]->name))
190  generic++;
191  return (list->count - 1 - generic);
192 }
193 
194 
195 static int
196 foreach_func (const char *filename, lt_ptr data)
197 {
198  GPPortInfoList *list = data;
199  lt_dlhandle lh;
200  GPPortLibraryType lib_type;
201  GPPortLibraryList lib_list;
202  GPPortType type;
203  unsigned int j, old_size = list->count;
204  int result;
205 
206  GP_LOG_D ("Called for filename '%s'.", filename );
207 
208  lh = lt_dlopenext (filename);
209  if (!lh) {
210  GP_LOG_D ("Could not load '%s': '%s'.", filename, lt_dlerror ());
211  return (0);
212  }
213 
214  lib_type = lt_dlsym (lh, "gp_port_library_type");
215  lib_list = lt_dlsym (lh, "gp_port_library_list");
216  if (!lib_type || !lib_list) {
217  GP_LOG_D ("Could not find some functions in '%s': '%s'.",
218  filename, lt_dlerror ());
219  lt_dlclose (lh);
220  return (0);
221  }
222 
223  type = lib_type ();
224  for (j = 0; j < list->count; j++)
225  if (list->info[j]->type == type)
226  break;
227  if (j != list->count) {
228  GP_LOG_D ("'%s' already loaded", filename);
229  lt_dlclose (lh);
230  return (0);
231  }
232 
233  result = lib_list (list);
234 #if !defined(VALGRIND)
235  lt_dlclose (lh);
236 #endif
237  if (result < 0) {
238  GP_LOG_E ("Error during assembling of port list: '%s' (%d).",
240  }
241 
242  if (old_size != list->count) {
243  /*
244  * It doesn't matter if lib_list returned a failure code,
245  * at least some entries were added
246  */
247  list->iolib_count++;
248 
249  for (j = old_size; j < list->count; j++){
250  GP_LOG_D ("Loaded '%s' ('%s') from '%s'.",
251  list->info[j]->name, list->info[j]->path,
252  filename);
253  list->info[j]->library_filename = strdup (filename);
254  }
255  }
256 
257  return (0);
258 }
259 
260 
273 int
275 {
276  const char *iolibs_env = getenv(IOLIBDIR_ENV);
277  const char *iolibs = (iolibs_env != NULL)?iolibs_env:IOLIBS;
278  int result;
279 
280  C_PARAMS (list);
281 
282  GP_LOG_D ("Using ltdl to load io-drivers from '%s'...", iolibs);
283  lt_dlinit ();
284  lt_dladdsearchdir (iolibs);
285  result = lt_dlforeachfile (iolibs, foreach_func, list);
286  lt_dlexit ();
287  if (result < 0)
288  return (result);
289  if (list->iolib_count == 0) {
290  GP_LOG_E ("No iolibs found in '%s'", iolibs);
291  return GP_ERROR_LIBRARY;
292  }
293  return (GP_OK);
294 }
295 
304 int
306 {
307  unsigned int count, i;
308 
309  C_PARAMS (list);
310 
311  GP_LOG_D ("Counting entries (%i available)...", list->count);
312 
313  /* Ignore generic entries */
314  count = list->count;
315  for (i = 0; i < list->count; i++)
316  if (!strlen (list->info[i]->name))
317  count--;
318 
319  GP_LOG_D ("%i regular entries available.", count);
320  return count;
321 }
322 
335 int
337 {
338  unsigned int i;
339  int result, generic;
340 #ifdef HAVE_REGEX
341  regex_t pattern;
342 #ifdef HAVE_GNU_REGEX
343  const char *rv;
344 #else
345  regmatch_t match;
346 #endif
347 #endif
348 
349  C_PARAMS (list && path);
350 
351  GP_LOG_D ("Looking for path '%s' (%i entries available)...", path, list->count);
352 
353  /* Exact match? */
354  for (generic = i = 0; i < list->count; i++)
355  if (!strlen (list->info[i]->name))
356  generic++;
357  else if (!strcmp (list->info[i]->path, path))
358  return (i - generic);
359 
360 #ifdef HAVE_REGEX
361  /* Regex match? */
362  GP_LOG_D ("Starting regex search for '%s'...", path);
363  for (i = 0; i < list->count; i++) {
364  GPPortInfo newinfo;
365 
366  if (strlen (list->info[i]->name))
367  continue;
368 
369  GP_LOG_D ("Trying '%s'...", list->info[i]->path);
370 
371  /* Compile the pattern */
372 #ifdef HAVE_GNU_REGEX
373  memset (&pattern, 0, sizeof (pattern));
374  rv = re_compile_pattern (list->info[i]->path,
375  strlen (list->info[i]->path), &pattern);
376  if (rv) {
377  GP_LOG_D ("%s", rv);
378  continue;
379  }
380 #else
381  result = regcomp (&pattern, list->info[i]->path, REG_ICASE);
382  if (result) {
383  char buf[1024];
384  if (regerror (result, &pattern, buf, sizeof (buf)))
385  GP_LOG_E ("%s", buf);
386  else
387  GP_LOG_E ("regcomp failed");
388  return (GP_ERROR_UNKNOWN_PORT);
389  }
390 #endif
391 
392  /* Try to match */
393 #ifdef HAVE_GNU_REGEX
394  result = re_match (&pattern, path, strlen (path), 0, NULL);
395  regfree (&pattern);
396  if (result < 0) {
397  GP_LOG_D ("re_match failed (%i)", result);
398  continue;
399  }
400 #else
401  result = regexec (&pattern, path, 1, &match, 0);
402  regfree (&pattern);
403  if (result) {
404  GP_LOG_D ("regexec failed");
405  continue;
406  }
407 #endif
408  gp_port_info_new (&newinfo);
409  gp_port_info_set_type (newinfo, list->info[i]->type);
410  newinfo->library_filename = strdup(list->info[i]->library_filename);
411  gp_port_info_set_name (newinfo, _("Generic Port"));
412  gp_port_info_set_path (newinfo, path);
413  CR (result = gp_port_info_list_append (list, newinfo));
414  return result;
415  }
416 #endif /* HAVE_REGEX */
417 
418  return (GP_ERROR_UNKNOWN_PORT);
419 }
420 
430 int
432 {
433  unsigned int i, generic;
434 
435  C_PARAMS (list && name);
436 
437  GP_LOG_D ("Looking up entry '%s'...", name);
438 
439  /* Ignore generic entries */
440  for (generic = i = 0; i < list->count; i++)
441  if (!strlen (list->info[i]->name))
442  generic++;
443  else if (!strcmp (list->info[i]->name, name))
444  return (i - generic);
445 
446  return (GP_ERROR_UNKNOWN_PORT);
447 }
448 
459 int
461 {
462  int i;
463 
464  C_PARAMS (list && info);
465 
466  GP_LOG_D ("Getting info of entry %i (%i available)...", n, list->count);
467 
468  C_PARAMS (n >= 0 && n < list->count);
469 
470  /* Ignore generic entries */
471  for (i = 0; i <= n; i++)
472  if (!strlen (list->info[i]->name)) {
473  n++;
474  C_PARAMS (n < list->count);
475  }
476 
477  *info = list->info[n];
478  return GP_OK;
479 }
480 
481 
491 int
492 gp_port_info_get_name (GPPortInfo info, char **name) {
493  *name = info->name;
494  return GP_OK;
495 }
496 
507 int
508 gp_port_info_set_name (GPPortInfo info, const char *name) {
509  C_MEM (info->name = strdup (name));
510  return GP_OK;
511 }
512 
522 int
523 gp_port_info_get_path (GPPortInfo info, char **path) {
524  *path = info->path;
525  return GP_OK;
526 }
527 
538 int
539 gp_port_info_set_path (GPPortInfo info, const char *path) {
540  C_MEM (info->path = strdup (path));
541  return GP_OK;
542 }
543 
553 int
555  *type = info->type;
556  return GP_OK;
557 }
558 
569 int
571  info->type = type;
572  return GP_OK;
573 }
574 
584 int
586  C_MEM (*info = calloc (1, sizeof(struct _GPPortInfo)));
587  return GP_OK;
588 }
_GPPortInfo::name
char * name
The name of this port (usb:)
Definition: gphoto2-port-info.h:34
_GPPortInfo
Definition: gphoto2-port-info.h:32
gp_port_info_list_lookup_name
int gp_port_info_list_lookup_name(GPPortInfoList *list, const char *name)
Look up a name in the list.
Definition: gphoto2-port-info-list.c:431
gp_port_info_set_type
int gp_port_info_set_type(GPPortInfo info, GPPortType type)
Set type of a specific port entry.
Definition: gphoto2-port-info-list.c:570
_GPPortInfoList
Definition: gphoto2-port-info-list.c:74
_GPPortInfo::type
GPPortType type
The type of this port.
Definition: gphoto2-port-info.h:33
GP_ERROR_UNKNOWN_PORT
#define GP_ERROR_UNKNOWN_PORT
Unknown libgphoto2 port passed.
Definition: gphoto2-port-result.h:50
gp_port_info_list_append
int gp_port_info_list_append(GPPortInfoList *list, GPPortInfo info)
Append a portinfo to the port information list.
Definition: gphoto2-port-info-list.c:177
gp_port_info_list_new
int gp_port_info_list_new(GPPortInfoList **list)
Create a new GPPortInfoList.
Definition: gphoto2-port-info-list.c:111
gp_port_info_get_type
int gp_port_info_get_type(GPPortInfo info, GPPortType *type)
Get type of a specific port entry.
Definition: gphoto2-port-info-list.c:554
gp_port_info_list_free
int gp_port_info_list_free(GPPortInfoList *list)
Free a GPPortInfo list.
Definition: gphoto2-port-info-list.c:135
gp_port_info_get_path
int gp_port_info_get_path(GPPortInfo info, char **path)
Get path of a specific port entry.
Definition: gphoto2-port-info-list.c:523
gphoto2-port-result.h
result
int result
Definition: gphoto2-result.c:44
_GPPortInfo::path
char * path
The path of this port (usb:001,023)
Definition: gphoto2-port-info.h:35
GPPortLibraryList
int(* GPPortLibraryList)(GPPortInfoList *list)
Definition: gphoto2-port-library.h:89
bindtextdomain
#define bindtextdomain(Domain, Directory)
Definition: gphoto2-port-info-list.c:62
gp_port_info_list_count
int gp_port_info_list_count(GPPortInfoList *list)
Number of ports in the list.
Definition: gphoto2-port-info-list.c:305
GP_OK
#define GP_OK
Everything is OK.
Definition: gphoto2-port-result.h:30
_GPPortInfoList::count
unsigned int count
Definition: gphoto2-port-info-list.c:76
gp_port_info_list_lookup_path
int gp_port_info_list_lookup_path(GPPortInfoList *list, const char *path)
Lookup a specific path in the list.
Definition: gphoto2-port-info-list.c:336
gp_port_message_codeset
const char * gp_port_message_codeset(const char *codeset)
Specify codeset for translations.
Definition: gphoto2-port-info-list.c:96
gp_port_info_set_name
int gp_port_info_set_name(GPPortInfo info, const char *name)
Set name of a specific port entry.
Definition: gphoto2-port-info-list.c:508
_
#define _(String)
Definition: gphoto2-port-info-list.c:65
_GPPortInfoList::info
GPPortInfo * info
Definition: gphoto2-port-info-list.c:75
gphoto2-port-info.h
gp_port_info_new
int gp_port_info_new(GPPortInfo *info)
Create a new portinfo.
Definition: gphoto2-port-info-list.c:585
gp_port_info_list_load
int gp_port_info_list_load(GPPortInfoList *list)
Load system ports.
Definition: gphoto2-port-info-list.c:274
gphoto2-port-library.h
_GPPortInfoList::iolib_count
unsigned int iolib_count
Definition: gphoto2-port-info-list.c:77
foreach_func
static int foreach_func(const char *filename, lt_ptr data)
Definition: gphoto2-port-info-list.c:196
gphoto2-port-info-list.h
GPPortLibraryType
GPPortType(* GPPortLibraryType)(void)
Definition: gphoto2-port-library.h:88
gp_port_info_set_path
int gp_port_info_set_path(GPPortInfo info, const char *path)
Set path of a specific port entry.
Definition: gphoto2-port-info-list.c:539
gp_port_info_get_name
int gp_port_info_get_name(GPPortInfo info, char **name)
Get name of a specific port entry.
Definition: gphoto2-port-info-list.c:492
gphoto2-port-log.h
bind_textdomain_codeset
#define bind_textdomain_codeset(Domain, codeset)
Definition: gphoto2-port-info-list.c:63
_GPPortInfo::library_filename
char * library_filename
Internal pathname of the port driver. Do not use outside of the port library.
Definition: gphoto2-port-info.h:38
CR
#define CR(x)
Definition: gphoto2-port-info-list.c:80
GP_ERROR_LIBRARY
#define GP_ERROR_LIBRARY
Error in the camera driver.
Definition: gphoto2-port-result.h:46
gp_port_info_list_get_info
int gp_port_info_list_get_info(GPPortInfoList *list, int n, GPPortInfo *info)
Get port information of specific entry.
Definition: gphoto2-port-info-list.c:460
gp_port_result_as_string
const char * gp_port_result_as_string(int result)
Definition: gphoto2-port-result.c:54
GPPortType
GPPortType
The gphoto port type.
Definition: gphoto2-port-info-list.h:34