1 /*
2 tstbackend -- backend test utility
3
4 Uses the SANE library.
5 Copyright (C) 2002 Frank Zago (sane at zago dot net)
6 Copyright (C) 2013 Stéphane Voltz <stef.dev@free.fr> : sane_get_devices test
7
8 This file is part of the SANE package.
9
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2 of the
13 License, or (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24 #define BUILD 19 /* 2013-03-29 */
25
26 #include "../include/sane/config.h"
27
28 #include <assert.h>
29 #include <getopt.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <stdarg.h>
35 #include <time.h>
36
37 #include <sys/types.h>
38 #include <sys/stat.h>
39
40 #include "../include/sane/sane.h"
41 #include "../include/sane/sanei.h"
42 #include "../include/sane/saneopts.h"
43
44 static struct option basic_options[] = {
45 {"device-name", required_argument, NULL, 'd'},
46 {"level", required_argument, NULL, 'l'},
47 {"scan", no_argument, NULL, 's'},
48 {"recursion", required_argument, NULL, 'r'},
49 {"get-devices", required_argument, NULL, 'g'},
50 {"help", no_argument, NULL, 'h'}
51 };
52
53 static void
54 test_options (SANE_Device * device, int can_do_recursive);
55
56 enum message_level {
57 MSG, /* info message */
58 INF, /* non-urgent warning */
59 WRN, /* warning */
60 ERR, /* error, test can continue */
61 FATAL, /* error, test can't/mustn't continue */
62 BUG /* bug in tstbackend */
63 };
64
65 int message_number_wrn = 0;
66 int message_number_err = 0;
67 #ifdef HAVE_LONG_LONG
68 long long checks_done = 0;
69 #else
70 /* It may overflow, but it's no big deal. */
71 long int checks_done = 0;
72 #endif
73
74 int test_level;
75 int verbose_level;
76
77 /* Maybe add that to sane.h */
78 #define SANE_OPTION_IS_GETTABLE(cap) (((cap) & (SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE)) == SANE_CAP_SOFT_DETECT)
79
80 /*--------------------------------------------------------------------------*/
81
82 /* Display the message error statistics. */
display_stats(void)83 static void display_stats(void)
84 {
85 #ifdef HAVE_LONG_LONG
86 printf("warnings: %d error: %d checks: %lld\n",
87 message_number_wrn, message_number_err, checks_done);
88 #else
89 printf("warnings: %d error: %d checks: %ld\n",
90 message_number_wrn, message_number_err, checks_done);
91 #endif
92 }
93
94 /*
95 * If the condition is false, display a message with some headers
96 * depending on the level.
97 *
98 * Returns the condition.
99 *
100 */
101 #ifdef __GNUC__
102 static int check(enum message_level, int condition, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
103 #endif
check(enum message_level level,int condition,const char * format,...)104 static int check(enum message_level level, int condition, const char *format, ...)
105 {
106 char str[1000];
107 va_list args;
108
109 if (level != MSG && level != INF) checks_done ++;
110
111 if (condition != 0)
112 return condition;
113
114 va_start(args, format);
115 vsprintf(str, format, args);
116 va_end(args);
117
118 switch(level) {
119 case MSG:
120 printf(" %s\n", str);
121 break;
122 case INF: /* info */
123 printf("info : %s\n", str);
124 break;
125 case WRN: /* warning */
126 printf("warning : %s\n", str);
127 message_number_wrn ++;
128 break;
129 case ERR: /* error */
130 printf("ERROR : %s\n", str);
131 message_number_err ++;
132 break;
133 case FATAL: /* fatal error */
134 printf("FATAL ERROR : %s\n", str);
135 message_number_err ++;
136 break;
137 case BUG: /* bug in tstbackend */
138 printf("tstbackend BUG : %s\n", str);
139 break;
140 }
141
142 if (level == FATAL || level == BUG) {
143 /* Fatal error. Generate a core dump. */
144 display_stats();
145 abort();
146 }
147
148 fflush(stdout);
149
150 return(0);
151 }
152
153 /*--------------------------------------------------------------------------*/
154
155 #define GUARDS_SIZE 4 /* 4 bytes */
156 #define GUARD1 ((SANE_Word)0x5abf8ea5)
157 #define GUARD2 ((SANE_Word)0xa58ebf5a)
158
159 /* Allocate the requested memory plus enough room to store some guard bytes. */
guards_malloc(size_t size)160 static void *guards_malloc(size_t size)
161 {
162 unsigned char *ptr;
163
164 size += 2*GUARDS_SIZE;
165 ptr = malloc(size);
166
167 assert(ptr);
168
169 ptr += GUARDS_SIZE;
170
171 return(ptr);
172 }
173
174 /* Free some memory allocated by guards_malloc. */
guards_free(void * ptr)175 static void guards_free(void *ptr)
176 {
177 unsigned char *p = ptr;
178
179 p -= GUARDS_SIZE;
180 free(p);
181 }
182
183 /* Set the guards */
guards_set(void * ptr,size_t size)184 static void guards_set(void *ptr, size_t size)
185 {
186 SANE_Word *p;
187
188 p = (SANE_Word *)(((unsigned char *)ptr) - GUARDS_SIZE);
189 *p = GUARD1;
190
191 p = (SANE_Word *)(((unsigned char *)ptr) + size);
192 *p = GUARD2;
193 }
194
195 /* Check that the guards have not been tampered with. */
guards_check(void * ptr,size_t size)196 static void guards_check(void *ptr, size_t size)
197 {
198 SANE_Word *p;
199
200 p = (SANE_Word *)(((unsigned char *)ptr) - GUARDS_SIZE);
201 check(FATAL, (*p == GUARD1),
202 "guard before the block has been tampered");
203
204 p = (SANE_Word *)(((unsigned char *)ptr) + size);
205 check(FATAL, (*p == GUARD2),
206 "guard after the block has been tampered");
207 }
208
209 /*--------------------------------------------------------------------------*/
210
211 static void
test_parameters(SANE_Device * device,SANE_Parameters * params)212 test_parameters (SANE_Device * device, SANE_Parameters *params)
213 {
214 SANE_Status status;
215 SANE_Parameters p;
216
217 status = sane_get_parameters (device, &p);
218 check(FATAL, (status == SANE_STATUS_GOOD),
219 "cannot get the parameters (error %s)", sane_strstatus(status));
220
221 check(FATAL, ((p.format == SANE_FRAME_GRAY) ||
222 (p.format == SANE_FRAME_RGB) ||
223 (p.format == SANE_FRAME_RED) ||
224 (p.format == SANE_FRAME_GREEN) ||
225 (p.format == SANE_FRAME_BLUE)),
226 "parameter format is not a known SANE_FRAME_* (%d)", p.format);
227
228 check(FATAL, ((p.last_frame == SANE_FALSE) ||
229 (p.last_frame == SANE_TRUE)),
230 "parameter last_frame is neither SANE_FALSE or SANE_TRUE (%d)", p.last_frame);
231
232 check(FATAL, ((p.depth == 1) ||
233 (p.depth == 8) ||
234 (p.depth == 16)),
235 "parameter depth is neither 1, 8 or 16 (%d)", p.depth);
236
237 if (params) {
238 *params = p;
239 }
240 }
241
242 /* Try to set every option in a word list. */
243 static void
test_options_word_list(SANE_Device * device,int option_num,const SANE_Option_Descriptor * opt,int can_do_recursive)244 test_options_word_list (SANE_Device * device, int option_num,
245 const SANE_Option_Descriptor *opt,
246 int can_do_recursive)
247 {
248 SANE_Status status;
249 int i;
250 SANE_Int val_int;
251 SANE_Int info;
252
253 check(FATAL, (opt->type == SANE_TYPE_INT ||
254 opt->type == SANE_TYPE_FIXED),
255 "type must be SANE_TYPE_INT or SANE_TYPE_FIXED (%d)", opt->type);
256
257 if (!SANE_OPTION_IS_SETTABLE(opt->cap)) return;
258
259 for (i=1; i<opt->constraint.word_list[0]; i++) {
260
261 info = 0x1010; /* garbage */
262
263 val_int = opt->constraint.word_list[i];
264 status = sane_control_option (device, option_num,
265 SANE_ACTION_SET_VALUE, &val_int, &info);
266
267 check(FATAL, (status == SANE_STATUS_GOOD),
268 "cannot set a settable option (status=%s)", sane_strstatus(status));
269
270 check(WRN, ((info & ~(SANE_INFO_RELOAD_OPTIONS |
271 SANE_INFO_RELOAD_PARAMS)) == 0),
272 "sane_control_option set an invalid info (%d)", info);
273
274 if ((info & SANE_INFO_RELOAD_OPTIONS) && can_do_recursive) {
275 test_options(device, can_do_recursive-1);
276 }
277 if (info & SANE_INFO_RELOAD_PARAMS) {
278 test_parameters(device, NULL);
279 }
280
281 /* The option might have become inactive or unsettable. Skip it. */
282 if (!SANE_OPTION_IS_ACTIVE(opt->cap) ||
283 !SANE_OPTION_IS_SETTABLE(opt->cap))
284 return;
285
286 }
287 }
288
289 /* Try to set every option in a string list. */
290 static void
test_options_string_list(SANE_Device * device,int option_num,const SANE_Option_Descriptor * opt,int can_do_recursive)291 test_options_string_list (SANE_Device * device, int option_num,
292 const SANE_Option_Descriptor *opt,
293 int can_do_recursive)
294 {
295 SANE_Int info;
296 SANE_Status status;
297 SANE_String val_string;
298 int i;
299
300 check(FATAL, (opt->type == SANE_TYPE_STRING),
301 "type must be SANE_TYPE_STRING (%d)", opt->type);
302
303 if (!SANE_OPTION_IS_SETTABLE(opt->cap)) return;
304
305 for (i=0; opt->constraint.string_list[i] != NULL; i++) {
306
307 val_string = strdup(opt->constraint.string_list[i]);
308 assert(val_string);
309
310 check(WRN, (strlen(val_string) < (size_t)opt->size),
311 "string [%s] is longer than the max size (%d)",
312 val_string, opt->size);
313
314 info = 0xE1000; /* garbage */
315 status = sane_control_option (device, option_num,
316 SANE_ACTION_SET_VALUE, val_string, &info);
317
318 check(FATAL, (status == SANE_STATUS_GOOD),
319 "cannot set a settable option (status=%s)", sane_strstatus(status));
320
321 check(WRN, ((info & ~(SANE_INFO_RELOAD_OPTIONS |
322 SANE_INFO_RELOAD_PARAMS)) == 0),
323 "sane_control_option set an invalid info (%d)", info);
324
325 free(val_string);
326
327 if ((info & SANE_INFO_RELOAD_OPTIONS) && can_do_recursive) {
328 test_options(device, can_do_recursive-1);
329 }
330 if (info & SANE_INFO_RELOAD_PARAMS) {
331 test_parameters(device, NULL);
332 }
333
334 /* The option might have become inactive or unsettable. Skip it. */
335 if (!SANE_OPTION_IS_ACTIVE(opt->cap) ||
336 !SANE_OPTION_IS_SETTABLE(opt->cap))
337 return;
338 }
339 }
340
341 /* Test the consistency of the options. */
342 static void
test_options(SANE_Device * device,int can_do_recursive)343 test_options (SANE_Device * device, int can_do_recursive)
344 {
345 SANE_Word info;
346 SANE_Int num_dev_options;
347 SANE_Status status;
348 const SANE_Option_Descriptor *opt;
349 int option_num;
350 void *optval; /* value for the option */
351 size_t optsize; /* size of the optval buffer */
352
353 /*
354 * Test option 0
355 */
356 opt = sane_get_option_descriptor (device, 0);
357 check(FATAL, (opt != NULL),
358 "cannot get option descriptor for option 0 (it must exist)");
359 check(INF, (opt->cap == SANE_CAP_SOFT_DETECT),
360 "invalid capabilities for option 0 (%d)", opt->cap);
361 check(ERR, (opt->type == SANE_TYPE_INT),
362 "option 0 type must be SANE_TYPE_INT");
363
364 /* Get the number of options. */
365 status = sane_control_option (device, 0, SANE_ACTION_GET_VALUE, &num_dev_options, 0);
366 check(FATAL, (status == SANE_STATUS_GOOD),
367 "cannot get option 0 value");
368
369 /* Try to change the number of options. */
370 status = sane_control_option (device, 0, SANE_ACTION_SET_VALUE,
371 &num_dev_options, &info);
372 check(WRN, (status != SANE_STATUS_GOOD),
373 "the option 0 value can be set");
374
375 /*
376 * Test all options
377 */
378 option_num = 0;
379 for (option_num = 0; option_num < num_dev_options; option_num++) {
380
381 /* Get the option descriptor */
382 opt = sane_get_option_descriptor (device, option_num);
383 check(FATAL, (opt != NULL),
384 "cannot get option descriptor for option %d", option_num);
385 check(WRN, ((opt->cap & ~(SANE_CAP_SOFT_SELECT |
386 SANE_CAP_HARD_SELECT |
387 SANE_CAP_SOFT_DETECT |
388 SANE_CAP_EMULATED |
389 SANE_CAP_AUTOMATIC |
390 SANE_CAP_INACTIVE |
391 SANE_CAP_ADVANCED)) == 0),
392 "invalid capabilities for option [%d, %s] (%x)", option_num, opt->name, opt->cap);
393 check(WRN, (opt->title != NULL),
394 "option [%d, %s] must have a title", option_num, opt->name);
395 check(WRN, (opt->desc != NULL),
396 "option [%d, %s] must have a description", option_num, opt->name);
397
398 if (!SANE_OPTION_IS_ACTIVE (opt->cap)) {
399 /* Option not active. Skip the remaining tests. */
400 continue;
401 }
402
403 if(verbose_level) {
404 printf("checking option ""%s""\n",opt->title);
405 }
406
407 if (opt->type == SANE_TYPE_GROUP) {
408 check(INF, (opt->name == NULL || *opt->name == 0),
409 "option [%d, %s] has a name", option_num, opt->name);
410 check(ERR, (!SANE_OPTION_IS_SETTABLE (opt->cap)),
411 "option [%d, %s], group option is settable", option_num, opt->name);
412 } else {
413 if (option_num == 0) {
414 check(ERR, (opt->name != NULL && *opt->name ==0),
415 "option 0 must have an empty name (ie. \"\")");
416 } else {
417 check(ERR, (opt->name != NULL && *opt->name !=0),
418 "option %d must have a name", option_num);
419 }
420 }
421
422 /* The option name must contain only "a".."z",
423 "0".."9" and "-" and must start with "a".."z". */
424 if (opt->name && opt->name[0]) {
425 const char *p = opt->name;
426
427 check(ERR, (*p >= 'a' && *p <= 'z'),
428 "name for option [%d, %s] must start with in letter in [a..z]",
429 option_num, opt->name);
430
431 p++;
432
433 while(*p) {
434 check(ERR, ((*p >= 'a' && *p <= 'z') ||
435 (*p == '-') ||
436 (*p >= '0' && *p <= '9')),
437 "name for option [%d, %s] must only have the letters [-a..z0..9]",
438 option_num, opt->name);
439 p++;
440 }
441 }
442
443 optval = NULL;
444 optsize = 0;
445
446 switch(opt->type) {
447 case SANE_TYPE_BOOL:
448 check(WRN, (opt->size == sizeof(SANE_Word)),
449 "size of option %s is incorrect", opt->name);
450 optval = guards_malloc(opt->size);
451 optsize = opt->size;
452 check(WRN, (opt->constraint_type == SANE_CONSTRAINT_NONE),
453 "invalid constraint type for option [%d, %s] (%d)", option_num, opt->name, opt->constraint_type);
454 break;
455
456 case SANE_TYPE_INT:
457 case SANE_TYPE_FIXED:
458 check(WRN, (opt->size > 0 && (opt->size % sizeof(SANE_Word) == 0)),
459 "invalid size for option %s", opt->name);
460 optval = guards_malloc(opt->size);
461 optsize = opt->size;
462 check(WRN, (opt->constraint_type == SANE_CONSTRAINT_NONE ||
463 opt->constraint_type == SANE_CONSTRAINT_RANGE ||
464 opt->constraint_type == SANE_CONSTRAINT_WORD_LIST),
465 "invalid constraint type for option [%d, %s] (%d)", option_num, opt->name, opt->constraint_type);
466 break;
467
468 case SANE_TYPE_STRING:
469 check(WRN, (opt->size >= 1),
470 "size of option [%d, %s] must be at least 1 for the NUL terminator", option_num, opt->name);
471 check(INF, (opt->unit == SANE_UNIT_NONE),
472 "unit of option [%d, %s] is not SANE_UNIT_NONE", option_num, opt->name);
473 check(WRN, (opt->constraint_type == SANE_CONSTRAINT_STRING_LIST ||
474 opt->constraint_type == SANE_CONSTRAINT_NONE),
475 "invalid constraint type for option [%d, %s] (%d)", option_num, opt->name, opt->constraint_type);
476 optval = guards_malloc(opt->size);
477 optsize = opt->size;
478 break;
479
480 case SANE_TYPE_BUTTON:
481 case SANE_TYPE_GROUP:
482 check(INF, (opt->unit == SANE_UNIT_NONE),
483 "option [%d, %s], unit is not SANE_UNIT_NONE", option_num, opt->name);
484 check(INF, (opt->size == 0),
485 "option [%d, %s], size is not 0", option_num, opt->name);
486 check(WRN, (opt->constraint_type == SANE_CONSTRAINT_NONE),
487 "invalid constraint type for option [%d, %s] (%d)", option_num, opt->name, opt->constraint_type);
488 break;
489
490 default:
491 check(ERR, 0,
492 "invalid type %d for option %s",
493 opt->type, opt->name);
494 break;
495 }
496
497 if (optval) {
498 /* This is an option with a value */
499
500 /* get with NULL info.
501 *
502 * The SANE standard is not explicit on that subject. I
503 * consider that an inactive option shouldn't be read by a
504 * frontend because its value is meaningless. I think
505 * that, in that case, SANE_STATUS_INVAL is an appropriate
506 * return.
507 */
508 guards_set(optval, optsize);
509 status = sane_control_option (device, option_num,
510 SANE_ACTION_GET_VALUE, optval, NULL);
511 guards_check(optval, optsize);
512
513 if (SANE_OPTION_IS_GETTABLE (opt->cap)) {
514 check(ERR, (status == SANE_STATUS_GOOD),
515 "cannot get option [%d, %s] value, although it is active (%s)", option_num, opt->name, sane_strstatus(status));
516 } else {
517 check(ERR, (status == SANE_STATUS_INVAL),
518 "was able to get option [%d, %s] value, although it is not active", option_num, opt->name);
519 }
520
521 /* set with NULL info */
522 guards_set(optval, optsize);
523 status = sane_control_option (device, option_num,
524 SANE_ACTION_SET_VALUE, optval, NULL);
525 guards_check(optval, optsize);
526 if (SANE_OPTION_IS_SETTABLE (opt->cap) && SANE_OPTION_IS_ACTIVE (opt->cap)) {
527 check(ERR, (status == SANE_STATUS_GOOD),
528 "cannot set option [%d, %s] value, although it is active and settable (%s)", option_num, opt->name, sane_strstatus(status));
529 } else {
530 check(ERR, (status == SANE_STATUS_INVAL),
531 "was able to set option [%d, %s] value, although it is not active or settable", option_num, opt->name);
532 }
533
534 /* Get with invalid info. Since if is a get, info should be either
535 * ignored or set to 0. */
536 info = 0xdeadbeef;
537 guards_set(optval, optsize);
538 status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE,
539 optval, &info);
540 guards_check(optval, optsize);
541 if (SANE_OPTION_IS_GETTABLE (opt->cap)) {
542 check(ERR, (status == SANE_STATUS_GOOD),
543 "cannot get option [%d, %s] value, although it is active (%s)", option_num, opt->name, sane_strstatus(status));
544 } else {
545 check(ERR, (status == SANE_STATUS_INVAL),
546 "was able to get option [%d, %s] value, although it is not active", option_num, opt->name);
547 }
548 check(ERR, ((info == (SANE_Int)0xdeadbeef) || (info == 0)),
549 "when getting option [%d, %s], info was set to %x", option_num, opt->name, info);
550
551 /* Set with invalid info. Info should be reset by the backend. */
552 info = 0x10000;
553 guards_set(optval, optsize);
554 status = sane_control_option (device, option_num,
555 SANE_ACTION_SET_VALUE, optval, &info);
556 guards_check(optval, optsize);
557 if (SANE_OPTION_IS_SETTABLE (opt->cap) && SANE_OPTION_IS_ACTIVE (opt->cap)) {
558 check(ERR, (status == SANE_STATUS_GOOD),
559 "cannot set option [%d, %s] value, although it is active and settable (%s)", option_num, opt->name, sane_strstatus(status));
560
561 check(ERR, ((info & ~(SANE_INFO_INEXACT |
562 SANE_INFO_RELOAD_OPTIONS |
563 SANE_INFO_RELOAD_PARAMS)) == 0),
564 "sane_control_option set some wrong bit in info (%d)", info);
565
566 if (info & SANE_INFO_RELOAD_PARAMS) {
567 test_parameters(device, NULL);
568 }
569 } else {
570 check(ERR, (status == SANE_STATUS_INVAL),
571 "was able to set option [%d, %s] value, although it is not active or settable", option_num, opt->name);
572 }
573
574 /* Ask the backend to set the option automatically. */
575 guards_set(optval, optsize);
576 status = sane_control_option (device, option_num,
577 SANE_ACTION_SET_AUTO, optval, &info);
578 guards_check(optval, optsize);
579 if (SANE_OPTION_IS_SETTABLE (opt->cap) &&
580 SANE_OPTION_IS_ACTIVE (opt->cap) &&
581 (opt->cap & SANE_CAP_AUTOMATIC)) {
582 check(ERR, (status == SANE_STATUS_GOOD),
583 "cannot set the option [%d, %s] automatically.", option_num, opt->name);
584 } else {
585 check(ERR, (status != SANE_STATUS_GOOD),
586 "was able to automatically set option [%d, %s], although it is not active or settable or automatically settable", option_num, opt->name);
587 }
588 if (info & SANE_INFO_RELOAD_PARAMS) {
589 test_parameters(device, NULL);
590 }
591 }
592
593 if (optval) {
594 guards_free(optval);
595 optval = NULL;
596 }
597
598 /* Some capabilities checks. */
599 check(ERR, ((opt->cap & (SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_SELECT)) !=
600 (SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_SELECT)),
601 "option [%d, %s], SANE_CAP_HARD_SELECT and SANE_CAP_SOFT_SELECT are mutually exclusive", option_num, opt->name);
602 if (opt->cap & SANE_CAP_SOFT_SELECT) {
603 check(ERR, ((opt->cap & SANE_CAP_SOFT_DETECT) != 0),
604 "option [%d, %s], SANE_CAP_SOFT_DETECT must be set if SANE_CAP_SOFT_SELECT is set", option_num, opt->name);
605 }
606 if ((opt->cap & (SANE_CAP_SOFT_SELECT |
607 SANE_CAP_HARD_SELECT |
608 SANE_CAP_SOFT_DETECT)) == SANE_CAP_SOFT_DETECT) {
609 check(ERR, (!SANE_OPTION_IS_SETTABLE (opt->cap)),
610 "option [%d, %s], must not be settable", option_num, opt->name);
611 }
612
613 if (!SANE_OPTION_IS_SETTABLE (opt->cap)) {
614 /* Unsettable option. Ignore the rest of the test. */
615 continue;
616 }
617
618 /* Check that will sane_control_option copy the string
619 * parameter and not just store a pointer to it. */
620 if (opt->type == SANE_TYPE_STRING) {
621 SANE_String val_string2;
622 char *optstr;
623
624 optstr = guards_malloc(opt->size);
625 val_string2 = guards_malloc(opt->size);
626
627 /* Poison the current value. */
628 strncpy(optstr, "-pOiSoN-", opt->size-1);
629 optstr[opt->size-1] = 0;
630
631 /* Get the value */
632 guards_set(optstr, opt->size);
633 status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE,
634 optstr, NULL);
635 guards_check(optstr, opt->size);
636 check(FATAL, (status == SANE_STATUS_GOOD),
637 "cannot get option [%d, %s] value", option_num, opt->name);
638 check(FATAL, (strcmp(optstr, "-pOiSoN-") != 0),
639 "sane_control_option did not set a value");
640
641 /* Set the value */
642 guards_set(optstr, opt->size);
643 status = sane_control_option (device, option_num,
644 SANE_ACTION_SET_VALUE, optstr, NULL);
645 guards_check(optstr, opt->size);
646 check(ERR, (status == SANE_STATUS_GOOD),
647 "cannot set option [%d, %s] value", option_num, opt->name);
648
649 /* Poison the returned value. */
650 strncpy(optstr, "-pOiSoN-", opt->size-1);
651 optstr[opt->size-1] = 0;
652
653 /* Read again the value and compare. */
654 guards_set(val_string2, opt->size);
655 status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE,
656 val_string2, NULL);
657 guards_check(val_string2, opt->size);
658 check(ERR, (status == SANE_STATUS_GOOD),
659 "cannot get option [%d, %s] value", option_num, opt->name);
660
661 check(FATAL, (strcmp(optstr, val_string2) != 0),
662 "sane_control_option did not copy the string parameter for option [%d, %s]", option_num, opt->name);
663
664 guards_free(optstr);
665 guards_free(val_string2);
666 }
667
668 /* Try both boolean options. */
669 if (opt->type == SANE_TYPE_BOOL) {
670 SANE_Bool org_v;
671 SANE_Bool v;
672
673 status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE,
674 &org_v, &info);
675 check(ERR, (status == SANE_STATUS_GOOD),
676 "cannot get boolean option [%d, %s] value (%s)", option_num, opt->name, sane_strstatus(status));
677 /* Invert the condition. */
678 switch(org_v) {
679 case SANE_FALSE:
680 v = SANE_TRUE;
681 break;
682 case SANE_TRUE:
683 v = SANE_FALSE;
684 break;
685 default:
686 check(ERR, 0,
687 "invalid boolean value %d for option [%d, %s]",
688 org_v, option_num, opt->name);
689 }
690
691 /* Set the opposite of the current value. */
692 status = sane_control_option (device, option_num,
693 SANE_ACTION_SET_VALUE, &v, &info);
694 check(ERR, (status == SANE_STATUS_GOOD),
695 "cannot set boolean option [%d, %s] value (%s)", option_num, opt->name, sane_strstatus(status));
696 check(ERR, (v != org_v),
697 "boolean values should be different");
698
699 if (info & SANE_INFO_RELOAD_PARAMS) {
700 test_parameters(device, NULL);
701 }
702
703 /* Set the initial value. */
704 v = org_v;
705 status = sane_control_option (device, option_num,
706 SANE_ACTION_SET_VALUE, &v, &info);
707 check(ERR, (status == SANE_STATUS_GOOD),
708 "cannot set boolean option [%d, %s] value (%s)", option_num, opt->name, sane_strstatus(status));
709 check(ERR, (v == org_v),
710 "boolean values should be the same");
711
712 if (info & SANE_INFO_RELOAD_PARAMS) {
713 test_parameters(device, NULL);
714 }
715 }
716
717 /* Try to set an invalid option. */
718 switch(opt->type) {
719 case SANE_TYPE_BOOL: {
720 SANE_Word v; /* should be SANE_Bool instead */
721
722 v = -1; /* invalid value. must be SANE_FALSE or SANE_TRUE */
723 status = sane_control_option (device, option_num,
724 SANE_ACTION_SET_VALUE, &v, NULL);
725 check(ERR, (status != SANE_STATUS_GOOD),
726 "was able to set an invalid value for boolean option [%d, %s]", option_num, opt->name);
727
728 v = 2; /* invalid value. must be SANE_FALSE or SANE_TRUE */
729 status = sane_control_option (device, option_num,
730 SANE_ACTION_SET_VALUE, &v, NULL);
731 check(ERR, (status != SANE_STATUS_GOOD),
732 "was able to set an invalid value for boolean option [%d, %s]", option_num, opt->name);
733 }
734 break;
735
736 case SANE_TYPE_FIXED:
737 case SANE_TYPE_INT: {
738 SANE_Int *v;
739 unsigned int i;
740
741 v = guards_malloc(opt->size);
742
743 /* I can only think of a test for
744 * SANE_CONSTRAINT_RANGE. This tests the behaviour of
745 * sanei_constrain_value(). */
746 if (opt->constraint_type == SANE_CONSTRAINT_RANGE) {
747 for(i=0; i<opt->size / sizeof(SANE_Int); i++)
748 v[i] = opt->constraint.range->min - 1; /* invalid range */
749
750 guards_set(v, opt->size);
751 status = sane_control_option (device, option_num,
752 SANE_ACTION_SET_VALUE, v, &info);
753 guards_check(v, opt->size);
754 check(ERR, (status == SANE_STATUS_GOOD && (info & SANE_INFO_INEXACT) ),
755 "incorrect return when setting an invalid range value for option [%d, %s] (status %s, info %x)", option_num, opt->name, sane_strstatus(status), info);
756
757 /* Set the corrected value. */
758 guards_set(v, opt->size);
759 status = sane_control_option (device, option_num,
760 SANE_ACTION_SET_VALUE, v, &info);
761 guards_check(v, opt->size);
762 check(ERR, (status == SANE_STATUS_GOOD && !(info & SANE_INFO_INEXACT) ),
763 "incorrect return when setting an invalid range value for option [%d, %s] (status %s, info %x)", option_num, opt->name, sane_strstatus(status), info);
764
765
766 for(i=0; i<opt->size / sizeof(SANE_Int); i++)
767 v[i] = opt->constraint.range->max + 1; /* invalid range */
768
769 guards_set(v, opt->size);
770 status = sane_control_option (device, option_num,
771 SANE_ACTION_SET_VALUE, v, &info);
772 guards_check(v, opt->size);
773 check(ERR, (status == SANE_STATUS_GOOD && (info & SANE_INFO_INEXACT) ),
774 "incorrect return when setting an invalid range value for option [%d, %s] (status %s, info %x)", option_num, opt->name, sane_strstatus(status), info);
775
776 /* Set the corrected value. */
777 guards_set(v, opt->size);
778 status = sane_control_option (device, option_num,
779 SANE_ACTION_SET_VALUE, v, &info);
780 guards_check(v, opt->size);
781 check(ERR, (status == SANE_STATUS_GOOD && !(info & SANE_INFO_INEXACT) ),
782 "incorrect return when setting a valid range value for option [%d, %s] (status %s, info %x)", option_num, opt->name, sane_strstatus(status), info);
783 }
784
785 guards_free(v);
786 }
787 break;
788
789 default:
790 break;
791 }
792
793 /* TODO: button */
794
795 /*
796 * Here starts all the recursive stuff. After the test, it is
797 * possible that the value is not settable nor active
798 * anymore.
799 */
800
801 /* Try to set every option in a list */
802 switch(opt->constraint_type) {
803 case SANE_CONSTRAINT_WORD_LIST:
804 check(FATAL, (opt->constraint.word_list != NULL),
805 "no constraint list for option [%d, %s]", option_num, opt->name);
806 test_options_word_list (device, option_num, opt, can_do_recursive);
807 break;
808
809 case SANE_CONSTRAINT_STRING_LIST:
810 check(FATAL, (opt->constraint.string_list != NULL),
811 "no constraint list for option [%d, %s]", option_num, opt->name);
812 test_options_string_list (device, option_num, opt, can_do_recursive);
813 break;
814
815 case SANE_CONSTRAINT_RANGE:
816 check(FATAL, (opt->constraint.range != NULL),
817 "no constraint range for option [%d, %s]", option_num, opt->name);
818 check(FATAL, (opt->constraint.range->max >= opt->constraint.range->min),
819 "incorrect range for option [%d, %s] (min=%d > max=%d)",
820 option_num, opt->name, opt->constraint.range->min, opt->constraint.range->max);
821 /* Recurse. */
822 if (can_do_recursive) {
823 test_options(device, can_do_recursive-1);
824 }
825 break;
826
827 case SANE_CONSTRAINT_NONE:
828 check(INF, (opt->constraint.range == NULL),
829 "option [%d, %s] has some constraint value set", option_num, opt->name);
830
831 /* Recurse. */
832 if (can_do_recursive) {
833 test_options(device, can_do_recursive-1);
834 }
835 break;
836 }
837
838 /* End of the test for that option. */
839 }
840
841 /* test random non-existing options. */
842 opt = sane_get_option_descriptor (device, -1);
843 check(ERR, (opt == NULL),
844 "was able to get option descriptor for option -1");
845
846 opt = sane_get_option_descriptor (device, num_dev_options+1);
847 check(ERR, (opt == NULL),
848 "was able to get option descriptor for option %d", num_dev_options+1);
849
850 opt = sane_get_option_descriptor (device, num_dev_options+2);
851 check(ERR, (opt == NULL),
852 "was able to get option descriptor for option %d", num_dev_options+2);
853
854 opt = sane_get_option_descriptor (device, num_dev_options+50);
855 check(ERR, (opt == NULL),
856 "was able to get option descriptor for option %d", num_dev_options+50);
857 }
858
859 /* Get an option descriptor by the name of the option. */
get_optdesc_by_name(SANE_Handle device,const char * name,int * option_num)860 static const SANE_Option_Descriptor *get_optdesc_by_name(SANE_Handle device, const char *name, int *option_num)
861 {
862 const SANE_Option_Descriptor *opt;
863 SANE_Int num_dev_options;
864 SANE_Status status;
865
866 /* Get the number of options. */
867 status = sane_control_option (device, 0, SANE_ACTION_GET_VALUE, &num_dev_options, 0);
868 check(FATAL, (status == SANE_STATUS_GOOD),
869 "cannot get option 0 value (%s)", sane_strstatus(status));
870
871 for (*option_num = 0; *option_num < num_dev_options; (*option_num)++) {
872
873 /* Get the option descriptor */
874 opt = sane_get_option_descriptor (device, *option_num);
875 check(FATAL, (opt != NULL),
876 "cannot get option descriptor for option %d", *option_num);
877
878 if (opt->name && strcmp(opt->name, name) == 0) {
879 return(opt);
880 }
881 }
882 return(NULL);
883 }
884
885 /* Set the first value for an option. That equates to the minimum for a
886 * range or the first element in a list. */
set_min_value(SANE_Handle device,int option_num,const SANE_Option_Descriptor * opt)887 static void set_min_value(SANE_Handle device, int option_num,
888 const SANE_Option_Descriptor *opt)
889 {
890 SANE_Status status;
891 SANE_String val_string;
892 SANE_Int val_int;
893 int rc;
894
895 check(BUG, (SANE_OPTION_IS_SETTABLE(opt->cap)),
896 "option is not settable");
897
898 switch(opt->constraint_type) {
899 case SANE_CONSTRAINT_WORD_LIST:
900 rc = check(ERR, (opt->constraint.word_list[0] > 0),
901 "no value in the list for option %s", opt->name);
902 if (!rc) return;
903 val_int = opt->constraint.word_list[1];
904 status = sane_control_option (device, option_num,
905 SANE_ACTION_SET_VALUE, &val_int, NULL);
906 check(ERR, (status == SANE_STATUS_GOOD),
907 "cannot set option %s to %d (%s)", opt->name, val_int, sane_strstatus(status));
908 break;
909
910 case SANE_CONSTRAINT_STRING_LIST:
911 rc = check(ERR, (opt->constraint.string_list[0] != NULL),
912 "no value in the list for option %s", opt->name);
913 if (!rc) return;
914 val_string = strdup(opt->constraint.string_list[0]);
915 assert(val_string);
916 status = sane_control_option (device, option_num,
917 SANE_ACTION_SET_VALUE, val_string, NULL);
918 check(ERR, (status == SANE_STATUS_GOOD),
919 "cannot set option %s to [%s] (%s)", opt->name, val_string, sane_strstatus(status));
920 free(val_string);
921 break;
922
923 case SANE_CONSTRAINT_RANGE:
924 val_int = opt->constraint.range->min;
925 status = sane_control_option (device, option_num,
926 SANE_ACTION_SET_VALUE, &val_int, NULL);
927 check(ERR, (status == SANE_STATUS_GOOD),
928 "cannot set option %s to %d (%s)", opt->name, val_int, sane_strstatus(status));
929 break;
930
931 default:
932 abort();
933 }
934 }
935
936 /* Set the last value for an option. That equates to the maximum for a
937 * range or the last element in a list. */
set_max_value(SANE_Handle device,int option_num,const SANE_Option_Descriptor * opt)938 static void set_max_value(SANE_Handle device, int option_num,
939 const SANE_Option_Descriptor *opt)
940 {
941 SANE_Status status;
942 SANE_String val_string;
943 SANE_Int val_int;
944 int i;
945 int rc;
946
947 check(BUG, (SANE_OPTION_IS_SETTABLE(opt->cap)),
948 "option is not settable");
949
950 switch(opt->constraint_type) {
951 case SANE_CONSTRAINT_WORD_LIST:
952 rc = check(ERR, (opt->constraint.word_list[0] > 0),
953 "no value in the list for option %s", opt->name);
954 if (!rc) return;
955 val_int = opt->constraint.word_list[opt->constraint.word_list[0]];
956 status = sane_control_option (device, option_num,
957 SANE_ACTION_SET_VALUE, &val_int, NULL);
958 check(ERR, (status == SANE_STATUS_GOOD),
959 "cannot set option %s to %d (%s)", opt->name, val_int, sane_strstatus(status));
960 break;
961
962 case SANE_CONSTRAINT_STRING_LIST:
963 rc = check(ERR, (opt->constraint.string_list[0] != NULL),
964 "no value in the list for option %s", opt->name);
965 if (!rc) return;
966 for (i=1; opt->constraint.string_list[i] != NULL; i++);
967 val_string = strdup(opt->constraint.string_list[i-1]);
968 assert(val_string);
969 status = sane_control_option (device, option_num,
970 SANE_ACTION_SET_VALUE, val_string, NULL);
971 check(ERR, (status == SANE_STATUS_GOOD),
972 "cannot set option %s to [%s] (%s)", opt->name, val_string, sane_strstatus(status));
973 free(val_string);
974 break;
975
976 case SANE_CONSTRAINT_RANGE:
977 val_int = opt->constraint.range->max;
978 status = sane_control_option (device, option_num,
979 SANE_ACTION_SET_VALUE, &val_int, NULL);
980 check(ERR, (status == SANE_STATUS_GOOD),
981 "cannot set option %s to %d (%s)", opt->name, val_int, sane_strstatus(status));
982 break;
983
984 default:
985 abort();
986 }
987 }
988
989 /* Set a random value for an option amongst the possible values. */
set_random_value(SANE_Handle device,int option_num,const SANE_Option_Descriptor * opt)990 static void set_random_value(SANE_Handle device, int option_num,
991 const SANE_Option_Descriptor *opt)
992 {
993 SANE_Status status;
994 SANE_String val_string;
995 SANE_Int val_int;
996 int i;
997 int rc;
998
999 check(BUG, (SANE_OPTION_IS_SETTABLE(opt->cap)),
1000 "option is not settable");
1001
1002 switch(opt->constraint_type) {
1003 case SANE_CONSTRAINT_WORD_LIST:
1004 rc = check(ERR, (opt->constraint.word_list[0] > 0),
1005 "no value in the list for option %s", opt->name);
1006 if (!rc) return;
1007 i=1+(rand() % opt->constraint.word_list[0]);
1008 val_int = opt->constraint.word_list[i];
1009 status = sane_control_option (device, option_num,
1010 SANE_ACTION_SET_VALUE, &val_int, NULL);
1011 check(ERR, (status == SANE_STATUS_GOOD),
1012 "cannot set option %s to %d (%s)", opt->name, val_int, sane_strstatus(status));
1013 break;
1014
1015 case SANE_CONSTRAINT_STRING_LIST:
1016 rc = check(ERR, (opt->constraint.string_list[0] != NULL),
1017 "no value in the list for option %s", opt->name);
1018 if (!rc) return;
1019 for (i=0; opt->constraint.string_list[i] != NULL; i++);
1020 i = rand() % i;
1021 val_string = strdup(opt->constraint.string_list[0]);
1022 assert(val_string);
1023 status = sane_control_option (device, option_num,
1024 SANE_ACTION_SET_VALUE, val_string, NULL);
1025 check(ERR, (status == SANE_STATUS_GOOD),
1026 "cannot set option %s to [%s] (%s)", opt->name, val_string, sane_strstatus(status));
1027 free(val_string);
1028 break;
1029
1030 case SANE_CONSTRAINT_RANGE:
1031 i = opt->constraint.range->max - opt->constraint.range->min;
1032 i = rand() % i;
1033 val_int = opt->constraint.range->min + i;
1034 status = sane_control_option (device, option_num,
1035 SANE_ACTION_SET_VALUE, &val_int, NULL);
1036 check(ERR, (status == SANE_STATUS_GOOD),
1037 "cannot set option %s to %d (%s)", opt->name, val_int, sane_strstatus(status));
1038 break;
1039
1040 default:
1041 abort();
1042 }
1043 }
1044
1045 /*--------------------------------------------------------------------------*/
1046
1047 /* Returns a string with the value of an option. */
get_option_value(SANE_Handle device,const char * option_name)1048 static char *get_option_value(SANE_Handle device, const char *option_name)
1049 {
1050 const SANE_Option_Descriptor *opt;
1051 void *optval; /* value for the option */
1052 int optnum;
1053 static char str[100];
1054 SANE_Status status;
1055
1056 opt = get_optdesc_by_name(device, option_name, &optnum);
1057 if (opt) {
1058
1059 optval = guards_malloc(opt->size);
1060 status = sane_control_option (device, optnum,
1061 SANE_ACTION_GET_VALUE, optval, NULL);
1062
1063 if (status == SANE_STATUS_GOOD) {
1064 switch(opt->type) {
1065
1066 case SANE_TYPE_BOOL:
1067 if (*(SANE_Word*) optval == SANE_FALSE) {
1068 strcpy(str, "FALSE");
1069 } else {
1070 strcpy(str, "TRUE");
1071 }
1072 break;
1073
1074 case SANE_TYPE_INT:
1075 sprintf(str, "%d", *(SANE_Word*) optval);
1076 break;
1077
1078 case SANE_TYPE_FIXED: {
1079 int i;
1080 i = SANE_UNFIX(*(SANE_Word*) optval);
1081 sprintf(str, "%d", i);
1082 }
1083 break;
1084
1085 case SANE_TYPE_STRING:
1086 strcpy(str, optval);
1087 break;
1088
1089 default:
1090 str[0] = 0;
1091 }
1092 } else {
1093 /* Shouldn't happen. */
1094 strcpy(str, "backend default");
1095 }
1096
1097 guards_free(optval);
1098
1099 } else {
1100 /* The option does not exists. */
1101 strcpy(str, "backend default");
1102 }
1103
1104 return(str);
1105 }
1106
1107 /* Display the parameters that used for a scan. */
display_scan_parameters(SANE_Handle device)1108 static char *display_scan_parameters(SANE_Handle device)
1109 {
1110 static char str[150];
1111 char *p = str;
1112
1113 *p = 0;
1114
1115 p += sprintf(p, "scan mode=[%s] ", get_option_value(device, SANE_NAME_SCAN_MODE));
1116 p += sprintf(p, "resolution=[%s] ", get_option_value(device, SANE_NAME_SCAN_RESOLUTION));
1117
1118 p += sprintf(p, "tl_x=[%s] ", get_option_value(device, SANE_NAME_SCAN_TL_X));
1119 p += sprintf(p, "tl_y=[%s] ", get_option_value(device, SANE_NAME_SCAN_TL_Y));
1120 p += sprintf(p, "br_x=[%s] ", get_option_value(device, SANE_NAME_SCAN_BR_X));
1121 p += sprintf(p, "br_y=[%s] ", get_option_value(device, SANE_NAME_SCAN_BR_Y));
1122
1123 return(str);
1124 }
1125
1126 /* Do a scan to test the correctness of the backend. */
test_scan(SANE_Handle device)1127 static void test_scan(SANE_Handle device)
1128 {
1129 const SANE_Option_Descriptor *opt;
1130 SANE_Status status;
1131 int option_num;
1132 SANE_Int val_int;
1133 unsigned char *image = NULL;
1134 SANE_Parameters params;
1135 size_t to_read;
1136 SANE_Int len=0;
1137 int ask_len;
1138 int rc;
1139 int fd;
1140
1141 /* Set the largest scan possible.
1142 *
1143 * For that test, the corner
1144 * position must exists and be SANE_CONSTRAINT_RANGE (this is not
1145 * a SANE requirement though).
1146 */
1147 opt = get_optdesc_by_name(device, SANE_NAME_SCAN_TL_X, &option_num);
1148 if (opt) set_min_value(device, option_num, opt);
1149
1150 opt = get_optdesc_by_name(device, SANE_NAME_SCAN_TL_Y, &option_num);
1151 if (opt) set_min_value(device, option_num, opt);
1152
1153 opt = get_optdesc_by_name(device, SANE_NAME_SCAN_BR_X, &option_num);
1154 if (opt) set_max_value(device, option_num, opt);
1155
1156 opt = get_optdesc_by_name(device, SANE_NAME_SCAN_BR_Y, &option_num);
1157 if (opt) set_max_value(device, option_num, opt);
1158
1159 #define IMAGE_SIZE (512 * 1024)
1160 image = guards_malloc(IMAGE_SIZE);
1161
1162 /* Try a read outside of a scan. */
1163 status = sane_read (device, image, len, &len);
1164 check(ERR, (status != SANE_STATUS_GOOD),
1165 "it is possible to sane_read outside of a scan");
1166
1167 /* Try to set the I/O mode outside of a scan. */
1168 status = sane_set_io_mode (device, SANE_FALSE);
1169 check(ERR, (status == SANE_STATUS_INVAL),
1170 "it is possible to sane_set_io_mode outside of a scan");
1171 status = sane_set_io_mode (device, SANE_TRUE);
1172 check(ERR, (status == SANE_STATUS_INVAL ||
1173 status == SANE_STATUS_UNSUPPORTED),
1174 "it is possible to sane_set_io_mode outside of a scan");
1175
1176 /* Test sane_get_select_fd outside of a scan. */
1177 status = sane_get_select_fd(device, &fd);
1178 check(ERR, (status == SANE_STATUS_INVAL ||
1179 status == SANE_STATUS_UNSUPPORTED),
1180 "sane_get_select_fd outside of a scan returned an invalid status (%s)",
1181 sane_strstatus (status));
1182
1183 if (test_level > 2) {
1184 /* Do a scan, reading byte per byte */
1185 check(MSG, 0, "TEST: scan byte per byte - %s", display_scan_parameters(device));
1186
1187 test_parameters(device, ¶ms);
1188 status = sane_start (device);
1189 rc = check(ERR, (status == SANE_STATUS_GOOD),
1190 "cannot start the scan (%s)", sane_strstatus (status));
1191 if (!rc) goto the_end;
1192
1193 /* sane_set_io_mode with SANE_FALSE is always supported. */
1194 status = sane_set_io_mode (device, SANE_FALSE);
1195 check(ERR, (status == SANE_STATUS_GOOD),
1196 "sane_set_io_mode with SANE_FALSE must return SANE_STATUS_GOOD");
1197
1198 /* test sane_set_io_mode with SANE_TRUE. */
1199 status = sane_set_io_mode (device, SANE_TRUE);
1200 check(ERR, (status == SANE_STATUS_GOOD ||
1201 status == SANE_STATUS_UNSUPPORTED),
1202 "sane_set_io_mode with SANE_TRUE returned an invalid status (%s)",
1203 sane_strstatus (status));
1204
1205 /* Put the backend back into blocking mode. */
1206 status = sane_set_io_mode (device, SANE_FALSE);
1207 check(ERR, (status == SANE_STATUS_GOOD),
1208 "sane_set_io_mode with SANE_FALSE must return SANE_STATUS_GOOD");
1209
1210 /* Test sane_get_select_fd */
1211 fd = 0x76575; /* won't exists */
1212 status = sane_get_select_fd(device, &fd);
1213 check(ERR, (status == SANE_STATUS_GOOD ||
1214 status == SANE_STATUS_UNSUPPORTED),
1215 "sane_get_select_fd returned an invalid status (%s)",
1216 sane_strstatus (status));
1217 if (status == SANE_STATUS_GOOD) {
1218 check(ERR, (fd != 0x76575),
1219 "sane_get_select_fd didn't set the fd although it should have");
1220 check(ERR, (fd >= 0),
1221 "sane_get_select_fd returned an invalid fd");
1222 }
1223
1224 /* Check that it is not possible to set an option. It is probably
1225 * a requirement stated indirectly in the section 4.4 on code
1226 * flow.
1227 */
1228 status = sane_control_option (device, option_num,
1229 SANE_ACTION_SET_VALUE,
1230 &val_int , NULL);
1231 check(WRN, (status != SANE_STATUS_GOOD),
1232 "it is possible to set a value during a scan");
1233
1234 test_parameters(device, ¶ms);
1235
1236 if (params.bytes_per_line != 0 && params.lines != 0) {
1237
1238 to_read = params.bytes_per_line * params.lines;
1239 while(SANE_TRUE) {
1240 len = 76457645; /* garbage */
1241 guards_set(image, 1);
1242 status = sane_read (device, image, 1, &len);
1243 guards_check(image, 1);
1244
1245 if (status == SANE_STATUS_EOF) {
1246 /* End of scan */
1247 check(ERR, (len == 0),
1248 "the length returned is not 0");
1249 break;
1250 }
1251
1252 rc = check(ERR, (status == SANE_STATUS_GOOD),
1253 "scan stopped - status is %s", sane_strstatus (status));
1254 if (!rc) {
1255 check(ERR, (len == 0),
1256 "the length returned is not 0");
1257 break;
1258 }
1259
1260 /* The scanner can only return 1. If it returns 0, we may
1261 * loop forever. */
1262 rc = check(ERR, (len == 1),
1263 "backend returned 0 bytes - skipping test");
1264 if (!rc) {
1265 break;
1266 }
1267
1268 to_read -= len;
1269 }
1270
1271 if (params.lines != -1) {
1272 check(ERR, (to_read == 0),
1273 "scan ended, but data was truncated");
1274 }
1275 }
1276
1277 sane_cancel(device);
1278 }
1279
1280 /* Try a read outside a scan. */
1281 ask_len = 1;
1282 guards_set(image, ask_len);
1283 status = sane_read (device, image, ask_len, &len);
1284 guards_check(image, ask_len);
1285 check(ERR, (status != SANE_STATUS_GOOD),
1286 "it is possible to sane_read outside a scan");
1287
1288
1289 /*
1290 * Do a partial scan
1291 */
1292 check(MSG, 0, "TEST: partial scan - %s", display_scan_parameters(device));
1293
1294 status = sane_start (device);
1295 rc = check(ERR, (status == SANE_STATUS_GOOD),
1296 "cannot start the scan (%s)", sane_strstatus (status));
1297 if (!rc) goto the_end;
1298
1299 test_parameters(device, ¶ms);
1300
1301 if (params.bytes_per_line != 0 && params.lines != 0) {
1302
1303 len = 10;
1304
1305 guards_set(image, 1);
1306 status = sane_read (device, image, 1, &len);
1307 guards_check(image, 1);
1308
1309 check(ERR, (len == 1),
1310 "sane_read() didn't return 1 byte as requested");
1311 }
1312
1313 sane_cancel(device);
1314
1315
1316 /*
1317 * Do a scan, reading random length.
1318 */
1319 check(MSG, 0, "TEST: scan random length - %s", display_scan_parameters(device));
1320
1321 test_parameters(device, ¶ms);
1322
1323 /* Try a read outside a scan. */
1324 ask_len = 20;
1325 guards_set(image, ask_len);
1326 status = sane_read (device, image, ask_len, &len);
1327 guards_check(image, ask_len);
1328 check(ERR, (status != SANE_STATUS_GOOD),
1329 "it is possible to sane_read outside a scan");
1330
1331 status = sane_start (device);
1332 rc = check(ERR, (status == SANE_STATUS_GOOD),
1333 "cannot start the scan (%s)", sane_strstatus (status));
1334 if (!rc) goto the_end;
1335
1336 /* Check that it is not possible to set an option. */
1337 status = sane_control_option (device, option_num,
1338 SANE_ACTION_SET_VALUE,
1339 &val_int , NULL);
1340 check(WRN, (status != SANE_STATUS_GOOD),
1341 "it is possible to set a value during a scan");
1342
1343 test_parameters(device, ¶ms);
1344
1345 if (params.bytes_per_line != 0 && params.lines != 0) {
1346
1347 to_read = params.bytes_per_line * params.lines;
1348 srandom(time(NULL));
1349
1350 while (SANE_TRUE) {
1351
1352 ask_len = rand() & 0x7ffff; /* 0 to 512K-1 */
1353 if (ask_len == 0) len = 1;
1354 len = ask_len + 4978; /* garbage */
1355
1356 guards_set(image, ask_len);
1357 status = sane_read (device, image, ask_len, &len);
1358 guards_check(image, ask_len);
1359
1360 if (status == SANE_STATUS_EOF) {
1361 /* End of scan */
1362 check(ERR, (len == 0),
1363 "the length returned is not 0");
1364 break;
1365 }
1366
1367 rc = check(ERR, (status == SANE_STATUS_GOOD),
1368 "scan stopped - status is %s", sane_strstatus (status));
1369 if (!rc) {
1370 check(ERR, (len == 0),
1371 "the length returned is not 0");
1372 break;
1373 }
1374
1375 /* The scanner cannot return 0. If it returns 0, we may
1376 * loop forever. */
1377 rc = check(ERR, (len > 0),
1378 "backend didn't return any data - skipping test");
1379 if (!rc) {
1380 break;
1381 }
1382 rc = check(ERR, (len <= ask_len),
1383 "backend returned too much data (%d / %d) - skipping test",
1384 len, ask_len);
1385 if (!rc) {
1386 break;
1387 }
1388
1389 to_read -= len;
1390 }
1391
1392 if (params.lines != -1) {
1393 check(ERR, (to_read == 0),
1394 "scan ended, but data was truncated");
1395 }
1396 }
1397
1398 sane_cancel(device);
1399
1400 /* Try a read outside a scan. */
1401 ask_len = 30;
1402 guards_set(image, ask_len);
1403 status = sane_read (device, image, ask_len, &len);
1404 guards_check(image, ask_len);
1405 check(ERR, (status != SANE_STATUS_GOOD),
1406 "it is possible to sane_read outside a scan");
1407
1408 /*
1409 * Do a scan with a fixed size and a big buffer
1410 */
1411 check(MSG, 0, "TEST: scan with a big max_len - %s", display_scan_parameters(device));
1412
1413 test_parameters(device, ¶ms);
1414
1415 status = sane_start (device);
1416 rc = check(ERR, (status == SANE_STATUS_GOOD),
1417 "cannot start the scan (%s)", sane_strstatus (status));
1418 if (!rc) goto the_end;
1419
1420 test_parameters(device, ¶ms);
1421
1422 if (params.bytes_per_line != 0 && params.lines != 0) {
1423
1424 to_read = params.bytes_per_line * params.lines;
1425 while(SANE_TRUE) {
1426 ask_len = IMAGE_SIZE;
1427 len = rand(); /* garbage */
1428
1429 guards_set(image, ask_len);
1430 status = sane_read (device, image, ask_len, &len);
1431 guards_check(image, ask_len);
1432
1433 if (status == SANE_STATUS_EOF) {
1434 /* End of scan */
1435 check(ERR, (len == 0),
1436 "the length returned is not 0");
1437 break;
1438 }
1439
1440 rc = check(ERR, (status == SANE_STATUS_GOOD),
1441 "scan stopped - status is %s", sane_strstatus (status));
1442 if (!rc) {
1443 check(ERR, (len == 0),
1444 "the length returned is not 0");
1445 break;
1446 }
1447
1448 /* If the scanner return 0, we may loop forever. */
1449 rc = check(ERR, (len > 0),
1450 "backend didn't return any data - skipping test");
1451 if (!rc) {
1452 break;
1453 }
1454
1455 rc = check(ERR, (len <= ask_len),
1456 "backend returned too much data (%d / %d) - skipping test",
1457 len, ask_len);
1458 if (!rc) {
1459 break;
1460 }
1461
1462 to_read -= len;
1463 }
1464
1465 if (params.lines != -1) {
1466 check(ERR, (to_read == 0),
1467 "scan ended, but data was truncated");
1468 }
1469 }
1470
1471 sane_cancel(device);
1472
1473 the_end:
1474 if (image) guards_free(image);
1475 }
1476
1477 /* Do several scans at different scan mode and resolution. */
test_scans(SANE_Device * device)1478 static void test_scans(SANE_Device * device)
1479 {
1480 const SANE_Option_Descriptor *scan_mode_opt;
1481 const SANE_Option_Descriptor *resolution_mode_opt;
1482 SANE_Status status;
1483 int scan_mode_optnum;
1484 int resolution_mode_optnum;
1485 SANE_String val_string;
1486 int i;
1487 int rc;
1488
1489 /* For that test, the requirements are:
1490 * SANE_NAME_SCAN_MODE exists and is a SANE_CONSTRAINT_STRING_LIST
1491 * SANE_NAME_SCAN_RESOLUTION exists and is either a SANE_CONSTRAINT_WORD_LIST or a SANE_CONSTRAINT_RANGE.
1492 *
1493 * These are not a SANE requirement, though.
1494 */
1495
1496 scan_mode_opt = get_optdesc_by_name(device, SANE_NAME_SCAN_MODE, &scan_mode_optnum);
1497 if (scan_mode_opt) {
1498
1499 rc = check(INF, (scan_mode_opt->type == SANE_TYPE_STRING),
1500 "option [%s] is not a SANE_TYPE_STRING - skipping test", SANE_NAME_SCAN_MODE);
1501 if (!rc) return;
1502 rc = check(INF, (scan_mode_opt->constraint_type == SANE_CONSTRAINT_STRING_LIST),
1503 "constraint for option [%s] is not SANE_CONSTRAINT_STRING_LIST - skipping test", SANE_NAME_SCAN_MODE);
1504 if (!rc) return;
1505 rc = check(INF, (SANE_OPTION_IS_SETTABLE(scan_mode_opt->cap)),
1506 "option [%s] is not settable - skipping test", SANE_NAME_SCAN_MODE);
1507 if (!rc) return;
1508 }
1509
1510 resolution_mode_opt = get_optdesc_by_name(device, SANE_NAME_SCAN_RESOLUTION, &resolution_mode_optnum);
1511 if (resolution_mode_opt) {
1512 rc = check(INF, (SANE_OPTION_IS_SETTABLE(resolution_mode_opt->cap)),
1513 "option [%s] is not settable - skipping test", SANE_NAME_SCAN_RESOLUTION);
1514 if (!rc) return;
1515 }
1516
1517 if (scan_mode_opt) {
1518 /* Do several scans, with several resolution. */
1519 for (i=0; scan_mode_opt->constraint.string_list[i] != NULL; i++) {
1520
1521 val_string = strdup(scan_mode_opt->constraint.string_list[i]);
1522 assert(val_string);
1523
1524 status = sane_control_option (device, scan_mode_optnum,
1525 SANE_ACTION_SET_VALUE, val_string, NULL);
1526 check(FATAL, (status == SANE_STATUS_GOOD),
1527 "cannot set a settable option (status=%s)", sane_strstatus(status));
1528
1529 free(val_string);
1530
1531 if (resolution_mode_opt) {
1532 set_min_value(device, resolution_mode_optnum,
1533 resolution_mode_opt);
1534 test_scan(device);
1535
1536 set_max_value(device, resolution_mode_optnum,
1537 resolution_mode_opt);
1538 test_scan(device);
1539
1540 set_random_value(device, resolution_mode_optnum,
1541 resolution_mode_opt);
1542 test_scan(device);
1543 } else {
1544 test_scan(device);
1545 }
1546 }
1547 } else {
1548 if (resolution_mode_opt) {
1549 set_min_value(device, resolution_mode_optnum,
1550 resolution_mode_opt);
1551 test_scan(device);
1552
1553 set_max_value(device, resolution_mode_optnum,
1554 resolution_mode_opt);
1555 test_scan(device);
1556
1557 set_random_value(device, resolution_mode_optnum,
1558 resolution_mode_opt);
1559 test_scan(device);
1560 } else {
1561 test_scan(device);
1562 }
1563 }
1564 }
1565
1566 /** test sane_get_devices
1567 * test sane_get_device function, if time is greter than 0,
1568 * loop to let tester plug/unplug device to check for correct
1569 * hotplug detection
1570 * @param device_list device list to fill
1571 * @param time time to loop
1572 * @return 0 on success
1573 */
test_get_devices(const SANE_Device *** device_list,int time)1574 static int test_get_devices(const SANE_Device ***device_list, int time)
1575 {
1576 int loop=0;
1577 int i;
1578 const SANE_Device *dev;
1579 SANE_Status status;
1580
1581 status = sane_get_devices (device_list, SANE_TRUE);
1582 check(FATAL, (status == SANE_STATUS_GOOD),
1583 "sane_get_devices() failed (%s)", sane_strstatus (status));
1584
1585 /* Verify that the SANE doc (or tstbackend) is up to date */
1586 for (i=0; (*device_list)[i] != NULL; i++) {
1587
1588 dev = (*device_list)[i];
1589
1590 check(FATAL, (dev->name != NULL), "device name is NULL");
1591 check(FATAL, (dev->vendor != NULL), "device vendor is NULL");
1592 check(FATAL, (dev->type != NULL), "device type is NULL");
1593 check(FATAL, (dev->model != NULL), "device model is NULL");
1594
1595 check(INF, ((strcmp(dev->type, "flatbed scanner") == 0) ||
1596 (strcmp(dev->type, "frame grabber") == 0) ||
1597 (strcmp(dev->type, "handheld scanner") == 0) ||
1598 (strcmp(dev->type, "still camera") == 0) ||
1599 (strcmp(dev->type, "video camera") == 0) ||
1600 (strcmp(dev->type, "virtual device") == 0) ||
1601 (strcmp(dev->type, "film scanner") == 0) ||
1602 (strcmp(dev->type, "multi-function peripheral") == 0) ||
1603 (strcmp(dev->type, "sheetfed scanner") == 0)),
1604 "unknown device type [%s]. Update SANE doc section \"Type Strings\"", dev->type);
1605
1606 check(INF, (
1607 (strcmp(dev->vendor, "AGFA") == 0) ||
1608 (strcmp(dev->vendor, "Abaton") == 0) ||
1609 (strcmp(dev->vendor, "Acer") == 0) ||
1610 (strcmp(dev->vendor, "Apple") == 0) ||
1611 (strcmp(dev->vendor, "Artec") == 0) ||
1612 (strcmp(dev->vendor, "Avision") == 0) ||
1613 (strcmp(dev->vendor, "CANON") == 0) ||
1614 (strcmp(dev->vendor, "Connectix") == 0) ||
1615 (strcmp(dev->vendor, "Epson") == 0) ||
1616 (strcmp(dev->vendor, "Fujitsu") == 0) ||
1617 (strcmp(dev->vendor, "Gphoto2") == 0) ||
1618 (strcmp(dev->vendor, "Hewlett-Packard") == 0) ||
1619 (strcmp(dev->vendor, "IBM") == 0) ||
1620 (strcmp(dev->vendor, "Kodak") == 0) ||
1621 (strcmp(dev->vendor, "Lexmark") == 0) ||
1622 (strcmp(dev->vendor, "Logitech") == 0) ||
1623 (strcmp(dev->vendor, "Microtek") == 0) ||
1624 (strcmp(dev->vendor, "Minolta") == 0) ||
1625 (strcmp(dev->vendor, "Mitsubishi") == 0) ||
1626 (strcmp(dev->vendor, "Mustek") == 0) ||
1627 (strcmp(dev->vendor, "NEC") == 0) ||
1628 (strcmp(dev->vendor, "Nikon") == 0) ||
1629 (strcmp(dev->vendor, "Noname") == 0) ||
1630 (strcmp(dev->vendor, "Plustek") == 0) ||
1631 (strcmp(dev->vendor, "Polaroid") == 0) ||
1632 (strcmp(dev->vendor, "Relisys") == 0) ||
1633 (strcmp(dev->vendor, "Ricoh") == 0) ||
1634 (strcmp(dev->vendor, "Sharp") == 0) ||
1635 (strcmp(dev->vendor, "Siemens") == 0) ||
1636 (strcmp(dev->vendor, "Tamarack") == 0) ||
1637 (strcmp(dev->vendor, "UMAX") == 0)),
1638 "unknown device vendor [%s]. Update SANE doc section \"Vendor Strings\"", dev->vendor);
1639 }
1640
1641 /* loop on detecting device to let time to plug/unplug scanners */
1642 while(loop<time) {
1643 /* print and free detected device list */
1644 check(MSG, 0, "DETECTED DEVICES:");
1645 for (i=0; (*device_list)[i] != NULL; i++) {
1646 dev = (*device_list)[i];
1647 check(MSG, 0, "\t%s:%s %s:%s", dev->vendor, dev->name, dev->type, dev->model);
1648 }
1649 if(i==0) {
1650 check(MSG, 0, "\tnone...");
1651 }
1652 sleep(1);
1653 (*device_list) = NULL;
1654 status = sane_get_devices (device_list, SANE_TRUE);
1655 check(FATAL, (status == SANE_STATUS_GOOD),
1656 "sane_get_devices() failed (%s)", sane_strstatus (status));
1657 loop++;
1658 }
1659 return 0;
1660 }
1661
1662 /** test test_default
1663 * test by scanning using default values
1664 * @param device device to use for the scan
1665 */
test_default(SANE_Device * device)1666 static void test_default(SANE_Device * device)
1667 {
1668 test_scan(device);
1669 }
1670
usage(const char * execname)1671 static void usage(const char *execname)
1672 {
1673 printf("Usage: %s [-d backend_name] [-l test_level] [-s] [-r recursion_level] [-g time (s)]\n", execname);
1674 printf("\t-v\tverbose level\n");
1675 printf("\t-d\tbackend name\n");
1676 printf("\t-l\tlevel of testing (0=some, 1=0+options, 2=1+scans, 3=longest tests)\n");
1677 printf("\t-s\tdo a scan during open/close tests\n");
1678 printf("\t-r\trecursion level for option testing (the higher, the longer)\n");
1679 printf("\t-g\ttime to loop on sane_get_devices function to test scannet hotplug detection (time is in seconds).\n");
1680 }
1681
1682 int
main(int argc,char ** argv)1683 main (int argc, char **argv)
1684 {
1685 char *devname = NULL;
1686 SANE_Status status;
1687 SANE_Int version_code;
1688 SANE_Handle device;
1689 int ch;
1690 int index;
1691 int i;
1692 const SANE_Device **device_list;
1693 int rc;
1694 int recursion_level;
1695 int time;
1696 int default_scan;
1697
1698 printf("tstbackend, Copyright (C) 2002 Frank Zago\n");
1699 printf("tstbackend comes with ABSOLUTELY NO WARRANTY\n");
1700 printf("This is free software, and you are welcome to redistribute it\n");
1701 printf("under certain conditions. See COPYING file for details\n\n");
1702 printf("This is tstbackend build %d\n\n", BUILD);
1703
1704 /* Read the command line options. */
1705 opterr = 0;
1706 recursion_level = 5; /* 5 levels or recursion should be enough */
1707 test_level = 0; /* basic tests only */
1708 time = 0; /* no get devices loop */
1709 default_scan = 0;
1710
1711 while ((ch = getopt_long (argc, argv, "-v:d:l:r:g:h:s", basic_options,
1712 &index)) != EOF) {
1713 switch(ch) {
1714 case 'v':
1715 verbose_level = atoi(optarg);
1716 break;
1717
1718 case 'd':
1719 devname = strdup(optarg);
1720 break;
1721
1722 case 'l':
1723 test_level = atoi(optarg);
1724 if (test_level < 0 || test_level > 4) {
1725 fprintf(stderr, "invalid test_level\n");
1726 return(1);
1727 }
1728 break;
1729
1730 case 's':
1731 default_scan = 1;
1732 break;
1733
1734 case 'r':
1735 recursion_level = atoi(optarg);
1736 break;
1737
1738 case 'g':
1739 time = atoi(optarg);
1740 break;
1741
1742 case 'h':
1743 usage(argv[0]);
1744 return(0);
1745
1746 case '?':
1747 fprintf(stderr, "invalid option\n");
1748 return(1);
1749
1750 default:
1751 fprintf(stderr, "bug in tstbackend\n");
1752 return(1);
1753 }
1754 }
1755
1756 /* First test */
1757 check(MSG, 0, "TEST: init/exit");
1758 for (i=0; i<10; i++) {
1759 /* Test 1. init/exit with a version code */
1760 status = sane_init(&version_code, NULL);
1761 check(FATAL, (status == SANE_STATUS_GOOD),
1762 "sane_init failed with %s", sane_strstatus (status));
1763 check(FATAL, (SANE_VERSION_MAJOR(version_code) == 1),
1764 "invalid SANE version linked");
1765 sane_exit();
1766
1767 /* Test 2. init/exit without a version code */
1768 status = sane_init(NULL, NULL);
1769 check(FATAL, (status == SANE_STATUS_GOOD),
1770 "sane_init failed with %s", sane_strstatus (status));
1771 sane_exit();
1772
1773 /* Test 3. Init/get_devices/open invalid/exit */
1774 status = sane_init(NULL, NULL);
1775 check(FATAL, (status == SANE_STATUS_GOOD),
1776 "sane_init failed with %s", sane_strstatus (status));
1777
1778 status = sane_get_devices (&device_list, SANE_TRUE);
1779 check(FATAL, (status == SANE_STATUS_GOOD),
1780 "sane_get_devices() failed (%s)", sane_strstatus (status));
1781
1782 status = sane_open ("opihndvses75bvt6fg", &device);
1783 check(WRN, (status == SANE_STATUS_INVAL),
1784 "sane_open() failed (%s)", sane_strstatus (status));
1785
1786 if (status == SANE_STATUS_GOOD)
1787 sane_close(device);
1788
1789 sane_exit();
1790
1791 /* Test 4. Init/get_devices/open default/exit */
1792 status = sane_init(NULL, NULL);
1793 check(FATAL, (status == SANE_STATUS_GOOD),
1794 "sane_init failed with %s", sane_strstatus (status));
1795
1796 status = sane_get_devices (&device_list, SANE_TRUE);
1797 check(FATAL, (status == SANE_STATUS_GOOD),
1798 "sane_get_devices() failed (%s)", sane_strstatus (status));
1799
1800 status = sane_open ("", &device);
1801 if (status == SANE_STATUS_GOOD)
1802 sane_close(device);
1803
1804 sane_exit();
1805 }
1806
1807 status = sane_init (&version_code, NULL);
1808 check(FATAL, (status == SANE_STATUS_GOOD),
1809 "sane_init failed with %s", sane_strstatus (status));
1810
1811 /* Check the device list */
1812 rc = test_get_devices(&device_list, time);
1813 if (rc) goto the_exit;
1814
1815 if (!devname) {
1816 /* If no device name was specified explicitly, we look at the
1817 environment variable SANE_DEFAULT_DEVICE. If this variable
1818 is not set, we open the first device we find (if any): */
1819 devname = getenv ("SANE_DEFAULT_DEVICE");
1820 if (devname) devname = strdup(devname);
1821 }
1822
1823 if (!devname) {
1824 if (device_list[0]) {
1825 devname = strdup(device_list[0]->name);
1826 }
1827 }
1828
1829 rc = check(ERR, (devname != NULL),
1830 "no SANE devices found");
1831 if (!rc) goto the_exit;
1832
1833 check(MSG, 0, "using device %s", devname);
1834
1835 /* Test open close */
1836 check(MSG, 0, "TEST: open/close");
1837 for (i=0; i<10; i++) {
1838 status = sane_open (devname, &device);
1839 rc = check(ERR, (status == SANE_STATUS_GOOD),
1840 "sane_open failed with %s for device %s", sane_strstatus (status), devname);
1841 if (!rc) goto the_exit;
1842
1843 if (default_scan) {
1844 test_default (device);
1845 }
1846 sane_close (device);
1847 }
1848
1849 if (test_level < 1) {
1850 sane_exit();
1851 goto the_exit;
1852 }
1853
1854
1855 /* Test options */
1856 check(MSG, 0, "TEST: options consistency");
1857 status = sane_open (devname, &device);
1858 check(FATAL, (status == SANE_STATUS_GOOD),
1859 "sane_open failed with %s for device %s", sane_strstatus (status), devname);
1860
1861 test_parameters(device, NULL);
1862 test_options(device, recursion_level);
1863 sane_close (device);
1864 sane_exit();
1865
1866 if (test_level < 2) {
1867 goto the_exit;
1868 }
1869
1870
1871 /* Test scans */
1872 check(MSG, 0, "TEST: scan test");
1873 status = sane_init (&version_code, NULL);
1874 check(FATAL, (status == SANE_STATUS_GOOD),
1875 "sane_init failed with %s", sane_strstatus (status));
1876 status = sane_open (devname, &device);
1877 check(FATAL, (status == SANE_STATUS_GOOD),
1878 "sane_open failed with %s for device %s", sane_strstatus (status), devname);
1879 test_scans(device);
1880 sane_close (device);
1881 sane_exit();
1882
1883 the_exit:
1884 if (devname) free(devname);
1885 display_stats();
1886 return(0);
1887 }
1888