1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 1997 Jeffrey S. Freedman
3 This file is part of the SANE package.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 As a special exception, the authors of SANE give permission for
21 additional uses of the libraries contained in this release of SANE.
23 The exception is that, if you link a SANE library with other files
24 to produce an executable, this does not by itself cause the
25 resulting executable to be covered by the GNU General Public
26 License. Your use of that executable is in no way restricted on
27 account of linking the SANE library code into it.
29 This exception does not, however, invalidate any other reasons why
30 the executable file might be covered by the GNU General Public
33 If you submit changes to SANE to the maintainers to be included in
34 a subsequent release, you agree by submitting the changes that
35 those changes may be distributed with this exception intact.
37 If you write modifications of your own for SANE, it is your choice
38 whether to permit this exception to apply to your modifications.
39 If you do not wish that, delete this exception notice.
41 This file provides generic configuration support. */
43 #include "sane/config.h"
50 #include <sys/param.h>
52 #include "sane/sanei.h"
53 #include "sane/sanei_config.h"
55 #define BACKEND_NAME sanei_config
56 #include "sane/sanei_debug.h"
59 # define PATH_MAX 1024
62 #if defined(HAVE_OS2_H)
64 # define PATH_SEP '\\'
65 #elif defined(HAVE_WINDOWS_H)
67 # define PATH_SEP '\\'
73 #define DEFAULT_DIRS "." DIR_SEP STRINGIFY(PATH_SANE_CONFIG_DIR)
76 #include <FindDirectory.h>
79 static char *dir_list
;
82 sanei_config_get_paths ()
85 char result
[PATH_MAX
];
95 dlist
= getenv ("SANE_CONFIG_DIR");
97 dir_list
= strdup (dlist
);
99 /* ~/config/settings/SANE takes precedence over /etc/sane.d/ */
102 if (find_directory(B_USER_SETTINGS_DIRECTORY
, 0, true, result
, PATH_MAX
) == B_OK
)
104 strcat(result
,"/SANE");
105 strcat(result
,DIR_SEP
); /* do append the default ones */
106 dir_list
= strdup (result
);
112 len
= strlen (dir_list
);
113 if ((len
> 0) && (dir_list
[len
- 1] == DIR_SEP
[0]))
115 /* append default search directories: */
116 mem
= malloc (len
+ sizeof (DEFAULT_DIRS
));
117 memcpy (mem
, dir_list
, len
);
118 memcpy ((char *) mem
+ len
, DEFAULT_DIRS
, sizeof (DEFAULT_DIRS
));
125 /* Create a copy, since we might call free on it */
126 dir_list
= strdup (DEFAULT_DIRS
);
129 DBG (5, "sanei_config_get_paths: using config directories %s\n", dir_list
);
135 sanei_config_open (const char *filename
)
137 char *next
, *dir
, result
[PATH_MAX
];
138 const char *cfg_dir_list
;
142 cfg_dir_list
= sanei_config_get_paths ();
145 DBG(2, "sanei_config_open: could not find config file `%s'\n", filename
);
149 copy
= strdup (cfg_dir_list
);
151 for (next
= copy
; (dir
= strsep (&next
, DIR_SEP
)) != 0; )
153 snprintf (result
, sizeof (result
), "%s%c%s", dir
, PATH_SEP
, filename
);
154 DBG(4, "sanei_config_open: attempting to open `%s'\n", result
);
155 fp
= fopen (result
, "r");
158 DBG(3, "sanei_config_open: using file `%s'\n", result
);
165 DBG(2, "sanei_config_open: could not find config file `%s'\n", filename
);
171 sanei_config_skip_whitespace (const char *str
)
173 while (str
&& *str
&& isspace (*str
))
179 sanei_config_get_string (const char *str
, char **string_const
)
184 str
= sanei_config_skip_whitespace (str
);
189 while (*str
&& *str
!= '"')
195 start
= 0; /* final double quote is missing */
200 while (*str
&& !isspace (*str
))
205 *string_const
= strndup (start
, len
);
212 sanei_config_read (char *str
, int n
, FILE *stream
)
218 /* read line from stream */
219 rc
= fgets( str
, n
, stream
);
223 /* remove ending whitespaces */
225 while( (0 < len
) && (isspace( str
[--len
])) )
228 /* remove starting whitespaces */
230 while( isspace( *start
))
243 sanei_configure_attach (const char *config_file
, SANEI_Config
* config
,
244 SANE_Status (*attach
) (SANEI_Config
* config
,
245 const char *devname
))
247 SANE_Char line
[PATH_MAX
];
248 SANE_Char
*token
, *string
;
250 const char *lp
, *lp2
;
252 SANE_Status status
= SANE_STATUS_GOOD
;
260 DBG (3, "sanei_configure_attach: start\n");
262 /* open configuration file */
263 fp
= sanei_config_open (config_file
);
266 DBG (2, "sanei_configure_attach: couldn't access %s\n", config_file
);
267 DBG (3, "sanei_configure_attach: exit\n");
268 return SANE_STATUS_ACCESS_DENIED
;
271 /* loop reading the configuration file, all line beginning by "option " are
272 * parsed for value to store in configuration structure, other line are
273 * used are device to try to attach
275 while (sanei_config_read (line
, PATH_MAX
, fp
) && status
== SANE_STATUS_GOOD
)
277 /* skip white spaces at beginning of line */
278 lp
= sanei_config_skip_whitespace (line
);
280 /* skip empty lines */
284 /* skip comment line */
290 /* delete newline characters at end */
291 if (line
[len
- 1] == '\n')
296 /* to ensure maximum compatibility, we accept line like:
297 * option "option_name" "option_value"
298 * "option_name" "option_value"
299 * So we parse the line 2 time to find an option */
300 /* check if it is an option */
301 lp
= sanei_config_get_string (lp
, &token
);
302 if (strncmp (token
, "option", 6) == 0)
304 /* skip the "option" token */
306 lp
= sanei_config_get_string (lp
, &token
);
309 /* search for a matching descriptor */
312 while (config
!=NULL
&& i
< config
->count
&& !found
)
314 if (strcmp (config
->descriptors
[i
]->name
, token
) == 0)
317 switch (config
->descriptors
[i
]->type
)
320 size
=config
->descriptors
[i
]->size
;
321 value
= malloc (size
);
322 wa
= (SANE_Word
*) value
;
323 count
= config
->descriptors
[i
]->size
/ sizeof (SANE_Word
);
324 for (j
= 0; j
< count
; j
++)
326 lp
= sanei_config_get_string (lp
, &string
);
330 "sanei_configure_attach: couldn't find a string to parse");
331 return SANE_STATUS_INVAL
;
333 wa
[j
] = strtol (string
, NULL
, 0);
338 size
=config
->descriptors
[i
]->size
;
339 value
= malloc (size
);
340 ba
= (SANE_Bool
*) value
;
341 count
= config
->descriptors
[i
]->size
/ sizeof (SANE_Bool
);
342 for (j
= 0; j
< count
; j
++)
344 lp
= sanei_config_get_string (lp
, &string
);
348 "sanei_configure_attach: couldn't find a string to parse");
349 return SANE_STATUS_INVAL
;
351 if ((strcmp (string
, "1") == 0)
352 || (strcmp (string
, "true") == 0))
358 if ((strcmp (string
, "0") == 0)
359 || (strcmp (string
, "false") == 0))
364 "sanei_configure_attach: couldn't find a valid boolean value");
365 return SANE_STATUS_INVAL
;
371 case SANE_TYPE_FIXED
:
372 size
=config
->descriptors
[i
]->size
;
373 value
= malloc (size
);
374 wa
= (SANE_Word
*) value
;
375 count
= config
->descriptors
[i
]->size
/ sizeof (SANE_Word
);
376 for (j
= 0; j
< count
; j
++)
378 lp
= sanei_config_get_string (lp
, &string
);
382 "sanei_configure_attach: couldn't find a string to parse");
383 return SANE_STATUS_INVAL
;
385 wa
[j
] = SANE_FIX(strtod (string
, NULL
));
389 case SANE_TYPE_STRING
:
390 sanei_config_get_string (lp
, &string
);
394 "sanei_configure_attach: couldn't find a string value to parse");
395 return SANE_STATUS_INVAL
;
398 size
=strlen(string
)+1;
399 if(size
>config
->descriptors
[i
]->size
)
401 size
=config
->descriptors
[i
]->size
-1;
407 "sanei_configure_attach: incorrect type %d for option %s, skipping option ...\n",
408 config
->descriptors
[i
]->type
,
409 config
->descriptors
[i
]->name
);
412 /* check decoded value */
413 status
= sanei_check_value (config
->descriptors
[i
], value
);
415 /* if value OK, copy it in configuration struct */
416 if (status
== SANE_STATUS_GOOD
)
418 memcpy (config
->values
[i
], value
, size
);
426 if (status
!= SANE_STATUS_GOOD
)
429 "sanei_configure_attach: failed to parse option '%s', line '%s'\n",
436 /* not detected as an option, so we call the attach function
438 if (!found
&& status
== SANE_STATUS_GOOD
)
440 /* if not an option, try to attach */
441 /* to avoid every backend to depend on scsi and usb functions
442 * we call back the backend for attach. In turn it will call
443 * sanei_usb_attach_matching_devices, sanei_config_attach_matching_devices
444 * or other. This means 2 callback functions per backend using this
446 DBG (3, "sanei_configure_attach: trying to attach with '%s'\n",
449 attach (config
, lp2
);
454 DBG (3, "sanei_configure_attach: exit\n");