1 /* AirScan (a.k.a. eSCL) backend for SANE
2  *
3  * Copyright (C) 2019 and up by Alexander Pevzner (pzz@apevzner.com)
4  * See LICENSE for license terms and conditions
5  */
6 
7 #ifndef airscan_h
8 #define airscan_h
9 
10 #include <avahi-common/address.h>
11 #include <avahi-common/strlst.h>
12 #include <avahi-common/watch.h>
13 
14 #include <sane/sane.h>
15 #include <sane/saneopts.h>
16 
17 #include <ctype.h>
18 #include <math.h>
19 #include <pthread.h>
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <time.h>
25 
26 #include <netinet/in.h>
27 #include <sys/param.h>
28 #include <sys/socket.h>
29 #include <sys/types.h>
30 
31 #ifdef  __cplusplus
32 extern "C" {
33 #endif
34 
35 /******************** Static configuration ********************/
36 /* Configuration path in environment
37  */
38 #define CONFIG_PATH_ENV                 "SANE_CONFIG_DIR"
39 
40 /* Standard SANE configuration directory
41  */
42 #ifndef CONFIG_SANE_CONFIG_DIR
43 #    define CONFIG_SANE_CONFIG_DIR      "/etc/sane.d/"
44 #endif
45 
46 /* Sane-airscan configuration file and subdirectory names
47  */
48 #define CONFIG_AIRSCAN_CONF             "airscan.conf"
49 #define CONFIG_AIRSCAN_D                "airscan.d"
50 
51 /* Environment variables
52  */
53 #define CONFIG_ENV_AIRSCAN_DEBUG        "SANE_DEBUG_AIRSCAN"
54 
55 /* Default resolution, DPI
56  */
57 #define CONFIG_DEFAULT_RESOLUTION       300
58 
59 /* Minimal interval between subsequent sane_start()
60  * attempts, if previous sane_start was failed
61  */
62 #define CONFIG_START_RETRY_INTERVAL     2500
63 
64 /* Default directory for AF_UNIX sockets
65  */
66 #define CONFIG_DEFAULT_SOCKET_DIR       "/var/run"
67 
68 /******************** Forward declarations ********************/
69 /* log_ctx represents logging context
70  */
71 typedef struct log_ctx log_ctx;
72 
73 /* Type http_uri represents HTTP URI
74  */
75 typedef struct http_uri http_uri;
76 
77 /******************** Utility macros ********************/
78 /* Obtain pointer to outer structure from pointer to
79  * its known member
80  */
81 #define OUTER_STRUCT(member_p,struct_t,field)                            \
82     ((struct_t*)((char*)(member_p) - ((ptrdiff_t) &(((struct_t*) 0)->field))))
83 
84 /******************** Circular Linked Lists ********************/
85 /* ll_node represents a linked data node.
86  * Data nodes are embedded into the corresponding data structures:
87  *   struct data {
88  *       ll_node chain; // Linked list chain
89  *       ...
90  *   };
91  *
92  * Use OUTER_STRUCT() macro to obtain pointer to containing
93  * structure from the pointer to the list node
94  */
95 typedef struct ll_node ll_node;
96 struct ll_node {
97     ll_node *ll_prev, *ll_next;
98 };
99 
100 /* ll_head represents a linked list head node
101  * ll_head must be initialized before use with ll_init() function
102  */
103 typedef struct {
104     ll_node node;
105 } ll_head;
106 
107 /* Initialize list head
108  */
109 static inline void
ll_init(ll_head * head)110 ll_init (ll_head *head)
111 {
112     head->node.ll_next = head->node.ll_prev = &head->node;
113 }
114 
115 /* Check if list is empty
116  */
117 static inline bool
ll_empty(const ll_head * head)118 ll_empty (const ll_head *head)
119 {
120     return head->node.ll_next == &head->node;
121 }
122 
123 /* Push node to the end of the list, represented
124  * by its head node
125  */
126 static inline void
ll_push_end(ll_head * head,ll_node * node)127 ll_push_end (ll_head *head, ll_node *node)
128 {
129     node->ll_prev = head->node.ll_prev;
130     node->ll_next = &head->node;
131     head->node.ll_prev->ll_next = node;
132     head->node.ll_prev = node;
133 }
134 
135 /* Push node to the beginning of the list, represented
136  * by its head node
137  */
138 static inline void
ll_push_beg(ll_head * head,ll_node * node)139 ll_push_beg (ll_head *head, ll_node *node)
140 {
141     node->ll_next = head->node.ll_next;
142     node->ll_prev = &head->node;
143     head->node.ll_next->ll_prev = node;
144     head->node.ll_next = node;
145 }
146 
147 /* Delete node from the list
148  */
149 static inline void
ll_del(ll_node * node)150 ll_del (ll_node *node)
151 {
152     ll_node *p = node->ll_prev, *n = node->ll_next;
153 
154     p->ll_next = n;
155     n->ll_prev = p;
156 
157     /* Make double-delete safe */
158     node->ll_next = node->ll_prev = node;
159 }
160 
161 /* Pop node from the beginning of the list.
162  * Returns NULL if list is empty
163  */
164 static inline ll_node*
ll_pop_beg(ll_head * head)165 ll_pop_beg (ll_head *head)
166 {
167     ll_node *node, *next;
168 
169     node = head->node.ll_next;
170     if (node == &head->node) {
171         return NULL; /* List is empty if it is looped to itself */
172     }
173 
174     next = node->ll_next;
175     next->ll_prev = &head->node;
176     head->node.ll_next = next;
177 
178     /* Make double-delete safe */
179     node->ll_next = node->ll_prev = node;
180 
181     return node;
182 }
183 
184 /* Pop node from the end of the list.
185  * Returns NULL if list is empty
186  */
187 static inline ll_node*
ll_pop_end(ll_head * head)188 ll_pop_end (ll_head *head)
189 {
190     ll_node *node, *prev;
191 
192     node = head->node.ll_prev;
193     if (node == &head->node) {
194         return NULL; /* List is empty if it is looped to itself */
195     }
196 
197     prev = node->ll_prev;
198     prev->ll_next = &head->node;
199     head->node.ll_prev = prev;
200 
201     /* Make double-delete safe */
202     node->ll_next = node->ll_prev = node;
203 
204     return node;
205 }
206 
207 /* Get next (from the beginning to the end) node of
208  * the list. Returns NULL, if end of list is reached
209  */
210 static inline ll_node*
ll_next(const ll_head * head,const ll_node * node)211 ll_next (const ll_head *head, const ll_node *node)
212 {
213     ll_node *next = node->ll_next;
214     return next == &head->node ? NULL : next;
215 }
216 
217 /* Get previous (from the beginning to the end) node of
218  * the list. Returns NULL, if end of list is reached
219  */
220 static inline ll_node*
ll_prev(const ll_head * head,const ll_node * node)221 ll_prev (const ll_head *head, const ll_node *node)
222 {
223     ll_node *prev = node->ll_prev;
224     return prev == &head->node ? NULL : prev;
225 }
226 
227 /* Get first node of the list.
228  * Returns NULL if list is empty
229  */
230 static inline ll_node*
ll_first(const ll_head * head)231 ll_first (const ll_head *head)
232 {
233     return ll_next(head, &head->node);
234 }
235 
236 /* Get last node of the list.
237  * Returns NULL if list is empty
238  */
239 static inline ll_node*
ll_last(const ll_head * head)240 ll_last (const ll_head *head)
241 {
242     return ll_prev(head, &head->node);
243 }
244 
245 /* Concatenate lists:
246  *   list1 += list2
247  *   list2 = empty
248  */
249 static inline void
ll_cat(ll_head * list1,ll_head * list2)250 ll_cat (ll_head *list1, ll_head *list2)
251 {
252     if (ll_empty(list2)) {
253         return;
254     }
255 
256     list2->node.ll_prev->ll_next = &list1->node;
257     list2->node.ll_next->ll_prev = list1->node.ll_prev;
258     list1->node.ll_prev->ll_next = list2->node.ll_next;
259     list1->node.ll_prev = list2->node.ll_prev;
260 
261     ll_init(list2);
262 }
263 
264 /* Helper macro for list iteration.
265  * Usage:
266  *   for (LL_FOR_EACH(node, list)) {
267  *     // do something with the node
268  *   }
269  */
270 #define LL_FOR_EACH(node,list)                          \
271     node = ll_first(list); node != NULL; node = ll_next(list, node)
272 
273 /******************** Memory allocation ********************/
274 /* Allocate `len' elements of type T
275  */
276 #define mem_new(T,len)  ((T*) __mem_alloc(len, 0, sizeof(T), true))
277 
278 /* Resize memory. The returned memory block has length of `len' and
279  * capacity at least of `len' + `extra'
280  *
281  * If p is NULL, new memory block will be allocated. Otherwise,
282  * existent memory block will be resized, new pointer is returned,
283  * while old becomes invalid (similar to how realloc() works).
284  *
285  * This function never returns NULL, it panics in a case of
286  * memory allocation error.
287  */
288 #define mem_resize(p,len,extra)         \
289         ((__typeof__(p)) __mem_resize(p,len,extra,sizeof(*p),true))
290 
291 /* Try to resize memory. It works like mem_resize() but may
292  * return NULL if memory allocation failed.
293  */
294 #define mem_try_resize(p,len,extra) __mem_resize(p,len,extra,sizeof(*p),false)
295 
296 /* Truncate the memory block length, preserving its capacity
297  */
298 void
299 mem_trunc (void *p);
300 
301 /* Shrink the memory block length, preserving its capacity
302  */
303 #define mem_shrink(p,len)       __mem_shrink(p,len, sizeof(*p))
304 
305 /* Free memory block, obtained from mem_new() or mem_resize()
306  * `p' can be NULL
307  */
308 void
309 mem_free (void *p);
310 
311 /* Get memory block length/capacity, in bytes
312  * For NULL pointer return 0
313  */
314 size_t mem_len_bytes (const void *p);
315 size_t mem_cap_bytes (const void *p);
316 
317 /* Get memory block length/capacity, in elements
318  * For NULL pointer return 0
319  */
320 #define mem_len(v)  (mem_len_bytes(v) / sizeof(*v))
321 #define mem_cap(v)  (mem_cap_bytes(v) / sizeof(*v))
322 
323 /* Helper functions for memory allocation, don't use directly
324  */
325 void* __attribute__ ((__warn_unused_result__))
326 __mem_alloc (size_t len, size_t extra, size_t elsize, bool must);
327 
328 void* __attribute__ ((__warn_unused_result__))
329 __mem_resize (void *p, size_t len, size_t cap, size_t elsize, bool must);
330 
331 void
332 __mem_shrink (void *p, size_t len, size_t elsize);
333 
334 /******************** Strings ********************/
335 /* Create new string
336  */
337 static inline char*
str_new(void)338 str_new (void) {
339     char *s = mem_resize((char*) NULL, 0, 1);
340     *s = '\0';
341     return s;
342 }
343 
344 /* Create new string as a copy of existent string
345  */
346 static inline char*
str_dup(const char * s1)347 str_dup (const char *s1)
348 {
349     size_t len = strlen(s1);
350     char   *s = mem_resize((char*) NULL, len, 1);
351     memcpy(s, s1, len + 1);
352     return s;
353 }
354 
355 /* Get string length in bytes, not including terminating '\0'
356  */
357 static inline size_t
str_len(const char * s)358 str_len (const char *s)
359 {
360     return mem_len(s);
361 }
362 
363 /* Create new string as a lowercase copy of existent string
364  */
365 char*
366 str_dup_tolower (const char *s1);
367 
368 /* Create new string and print to it
369  */
370 char*
371 str_printf (const char *format, ...);
372 
373 /* Create new string and print to it, va_list version
374  */
375 char*
376 str_vprintf (const char *format, va_list ap);
377 
378 /* Truncate the string
379  */
380 static inline void
str_trunc(char * s)381 str_trunc (char *s)
382 {
383     mem_trunc(s);
384     *s = '\0';
385 }
386 
387 /* Resize the string
388  *
389  * s1 must be previously created by some of str_XXX functions,
390  * s1 will be consumed and the new pointer will be returned
391  */
392 static inline char*
str_resize(char * s,size_t len)393 str_resize (char *s, size_t len)
394 {
395     s = mem_resize(s, len, 1);
396     s[len] = '\0';
397     return s;
398 }
399 
400 /* Append memory to string:
401  *     s1 += s2[:l2]
402  *
403  * s1 must be previously created by some of str_XXX functions,
404  * s1 will be consumed and the new pointer will be returned
405  */
406 static inline char*
str_append_mem(char * s1,const char * s2,size_t l2)407 str_append_mem (char *s1, const char *s2, size_t l2)
408 {
409     size_t l1 = str_len(s1);
410 
411     s1 = mem_resize(s1, l1 + l2, 1);
412     memcpy(s1 + l1, s2, l2);
413     s1[l1+l2] = '\0';
414 
415     return s1;
416 }
417 
418 /* Append string to string:
419  *     s1 += s2
420  *
421  * s1 must be previously created by some of str_XXX functions,
422  * s1 will be consumed and the new pointer will be returned
423  */
424 static inline char*
str_append(char * s1,const char * s2)425 str_append (char *s1, const char *s2)
426 {
427     return str_append_mem(s1, s2, strlen(s2));
428 }
429 
430 /* Append character to string:
431  *     s1 += c
432  *
433  * `s' must be previously created by some of str_XXX functions,
434  * `s' will be consumed and the new pointer will be returned
435  */
436 static inline char*
str_append_c(char * s,char c)437 str_append_c (char *s, char c)
438 {
439     return str_append_mem(s, &c, 1);
440 }
441 
442 /* Append formatted string to string
443  *
444  * `s' must be previously created by some of str_XXX functions,
445  * `s' will be consumed and the new pointer will be returned
446  */
447 char*
448 str_append_printf (char *s, const char *format, ...);
449 
450 /* Append formatted string to string -- va_list version
451  */
452 char*
453 str_append_vprintf (char *s, const char *format, va_list ap);
454 
455 /* Assign value to string
456  *
457  * `s1' must be previously created by some of str_XXX functions,
458  * `s1' will be consumed and the new pointer will be returned
459  */
460 static inline char*
str_assign(char * s1,const char * s2)461 str_assign (char *s1, const char *s2)
462 {
463     mem_trunc(s1);
464     return str_append(s1, s2);
465 }
466 
467 /* Concatenate several strings. Last pointer must be NULL.
468  * The returned pointer must be eventually freed by mem_free
469  */
470 char*
471 str_concat (const char *s, ...);
472 
473 /* Make sure that string is terminated with the `c' character:
474  * if string is not empty and the last character is not `c`,
475  * append `c' to the string
476  *
477  * `s' must be previously created by some of str_XXX functions,
478  * `s' will be consumed and the new pointer will be returned
479  */
480 static inline char*
str_terminate(char * s,char c)481 str_terminate (char *s, char c)
482 {
483     if (s[0] != '\0' && s[str_len(s) - 1] != c) {
484         s = str_append_c(s, c);
485     }
486 
487     return s;
488 }
489 
490 /* Check if string has a specified prefix
491  */
492 bool
493 str_has_prefix (const char *s, const char *prefix);
494 
495 /* Check if string has a specified suffix
496  */
497 bool
498 str_has_suffix (const char *s, const char *suffix);
499 
500 /* Remove leading and trailing white space.
501  * This function modifies string in place, and returns pointer
502  * to original string, for convenience
503  */
504 char*
505 str_trim (char *s);
506 
507 /******************** NULL-terminated pointer arrays  ********************/
508 /* Create NULL-terminated array of pointers of type *T
509  */
510 #define ptr_array_new(T)                mem_resize((T*) NULL, 0, 1)
511 
512 /* Append pointer to the NULL-terminated array of pointers.
513  * Returns new, potentially reallocated array
514  */
515 #define ptr_array_append(a,p)           \
516         ((__typeof__(a)) __ptr_array_append((void**)a, p))
517 
518 /* Truncate NULL-terminated array of pointers
519  */
520 #define ptr_array_trunc(a)              \
521     do {                                \
522         mem_trunc(a);                   \
523         a[0] = NULL;                    \
524     } while(0)
525 
526 /* Find pointer within array of pointers.
527  * Return non-negative index if pointer was found, -1 otherwise
528  */
529 #define ptr_array_find(a,p)             __ptr_array_find((void**) a, p)
530 
531 /* Delete element at given index.
532  * Returns value of deleted pointer or NULL, if index is out of range
533  */
534 #define ptr_array_del(a,i)              \
535         ((__typeof__(*a)) __ptr_array_del((void**) a, i))
536 
537 /* Helper function for ptr_array_append, don't use directly
538  */
539 static inline void**
__ptr_array_append(void ** a,void * p)540 __ptr_array_append (void **a, void *p)
541 {
542     size_t len = mem_len(a) + 1;
543     a = mem_resize(a, len, 1);
544     a[len - 1] = p;
545     a[len] = NULL;
546     return a;
547 }
548 
549 /* Helper function for ptr_array_find, don't use directly
550  */
551 static inline int
__ptr_array_find(void ** a,void * p)552 __ptr_array_find (void **a, void *p)
553 {
554     size_t len = mem_len(a), i;
555 
556     for (i = 0; i < len; i ++) {
557         if (a[i] == p) {
558             return (int) i;
559         }
560     }
561 
562     return -1;
563 }
564 
565 /* Helper function for ptr_array_del, don't use directly
566  */
567 static inline void*
__ptr_array_del(void ** a,int i)568 __ptr_array_del (void **a, int i)
569 {
570     size_t len = mem_len(a);
571     void   *p;
572 
573     if (i < 0 || i >= (int) len) {
574         return NULL;
575     }
576 
577     len --;
578     p = a[i];
579     memmove(&a[i], &a[i + 1], sizeof(void*) * (len - i));
580     mem_shrink(a, len);
581     a[len] = NULL;
582 
583     return p;
584 }
585 
586 /******************** Safe ctype macros ********************/
587 #define safe_isspace(c)         isspace((unsigned char) c)
588 #define safe_isxdigit(c)        isxdigit((unsigned char) c)
589 #define safe_toupper(c)         toupper((unsigned char) c)
590 #define safe_tolower(c)         tolower((unsigned char) c)
591 
592 /******************** OS Facilities ********************/
593 /* The following macros, if defined, indicate that OS
594  * has a particular features:
595  *
596  *   OS_HAVE_EVENTFD      - Linux-like eventfd (2)
597  *   OS_HAVE_RTNETLINK    - Linux-like rtnetlink (7)
598  *   OS_HAVE_AF_ROUTE     - BSD-like AF_ROUTE
599  *   OS_HAVE_LINUX_PROCFS - Linux-style procfs
600  *   OS_HAVE_IP_MREQN     - OS defines struct ip_mreqn
601  *   OS_HAVE_ENDIAN_H     - #include <endian.h> works
602  *   OS_HAVE_SYS_ENDIAN_H - #include <sys/endian.h> works
603  */
604 #ifdef  __linux__
605 #   define OS_HAVE_EVENTFD              1
606 #   define OS_HAVE_RTNETLINK            1
607 #   define OS_HAVE_LINUX_PROCFS         1
608 #   define OS_HAVE_IP_MREQN             1
609 #   define OS_HAVE_ENDIAN_H             1
610 #endif
611 
612 #ifdef BSD
613 #   define OS_HAVE_AF_ROUTE             1
614 #   ifdef __FreeBSD__
615 #       define OS_HAVE_SYS_ENDIAN_H     1
616 #   else
617 #       define OS_HAVE_ENDIAN_H         1
618 #   endif
619 #endif
620 
621 /* Get user's home directory. There is no need to
622  * free the returned string
623  *
624  * May return NULL in a case of error
625  */
626 const char *
627 os_homedir (void);
628 
629 /* Get base name of the calling program.
630  * There is no need to free the returned string
631  *
632  * May return NULL in a case of error
633  */
634 const char*
635 os_progname (void);
636 
637 /* Make directory with parents
638  */
639 int
640 os_mkdir (const char *path, mode_t mode);
641 
642 /******************** Error handling ********************/
643 /* Type error represents an error. Its value either NULL,
644  * which indicates "no error" condition, or some opaque
645  * non-null pointer, which can be converted to string
646  * with textual description of the error, using the ESTRING()
647  * function
648  *
649  * Caller should not attempt to free the memory, referred
650  * by error or string, obtained from an error using the
651  * ESTRING() function
652  */
653 typedef struct error_s *error;
654 
655 /* Standard errors
656  */
657 extern error ERROR_ENOMEM;
658 
659 /* Construct error from a string
660  */
661 static inline error
ERROR(const char * s)662 ERROR (const char *s)
663 {
664     return (error) s;
665 }
666 
667 /* Obtain textual representation of the error
668  */
669 static inline const char*
ESTRING(error err)670 ESTRING (error err)
671 {
672     return (const char*) err;
673 }
674 
675 /******************** Various identifiers ********************/
676 /* ID_PROTO represents protocol identifier
677  */
678 typedef enum {
679     ID_PROTO_UNKNOWN = -1,
680     ID_PROTO_ESCL,
681     ID_PROTO_WSD,
682 
683     NUM_ID_PROTO
684 } ID_PROTO;
685 
686 /* id_proto_name returns protocol name
687  * For unknown ID returns NULL
688  */
689 const char*
690 id_proto_name (ID_PROTO proto);
691 
692 /* id_proto_by_name returns protocol identifier by name
693  * For unknown name returns ID_PROTO_UNKNOWN
694  */
695 ID_PROTO
696 id_proto_by_name (const char* name);
697 
698 /* ID_SOURCE represents scanning source
699  */
700 typedef enum {
701     ID_SOURCE_UNKNOWN = -1,
702     ID_SOURCE_PLATEN,
703     ID_SOURCE_ADF_SIMPLEX,
704     ID_SOURCE_ADF_DUPLEX,
705 
706     NUM_ID_SOURCE
707 } ID_SOURCE;
708 
709 /* id_source_sane_name returns SANE name for the source
710  * For unknown ID returns NULL
711  */
712 const char*
713 id_source_sane_name (ID_SOURCE id);
714 
715 /* id_source_by_sane_name returns ID_SOURCE by its SANE name
716  * For unknown name returns ID_SOURCE_UNKNOWN
717  */
718 ID_SOURCE
719 id_source_by_sane_name (const char *name);
720 
721 /* ID_COLORMODE represents color mode
722  */
723 typedef enum {
724     ID_COLORMODE_UNKNOWN = -1,
725     ID_COLORMODE_COLOR,
726     ID_COLORMODE_GRAYSCALE,
727     ID_COLORMODE_BW1,
728 
729     NUM_ID_COLORMODE
730 } ID_COLORMODE;
731 
732 /* id_colormode_sane_name returns SANE name for the color mode
733  * For unknown ID returns NULL
734  */
735 const char*
736 id_colormode_sane_name (ID_COLORMODE id);
737 
738 /* id_colormode_by_sane_name returns ID_COLORMODE by its SANE name
739  * For unknown name returns ID_COLORMODE_UNKNOWN
740  */
741 ID_COLORMODE
742 id_colormode_by_sane_name (const char *name);
743 
744 /* ID_FORMAT represents image format
745  */
746 typedef enum {
747     ID_FORMAT_UNKNOWN = -1,
748     ID_FORMAT_JPEG,
749     ID_FORMAT_TIFF,
750     ID_FORMAT_PNG,
751     ID_FORMAT_PDF,
752     ID_FORMAT_BMP,
753 
754     NUM_ID_FORMAT
755 } ID_FORMAT;
756 
757 /* id_format_mime_name returns MIME name for the image format
758  */
759 const char*
760 id_format_mime_name (ID_FORMAT id);
761 
762 /* id_format_by_mime_name returns ID_FORMAT by its MIME name
763  * For unknown name returns ID_FORMAT_UNKNOWN
764  */
765 ID_FORMAT
766 id_format_by_mime_name (const char *name);
767 
768 /* if_format_short_name returns short name for ID_FORMAT
769  */
770 const char*
771 id_format_short_name (ID_FORMAT id);
772 
773 /******************** Device ID ********************/
774 /* Allocate unique device ID
775  */
776 unsigned int
777 devid_alloc (void);
778 
779 /* Free device ID
780  */
781 void
782 devid_free (unsigned int id);
783 
784 /* Initialize device ID allocator
785  */
786 void
787 devid_init (void);
788 
789 /******************** Random bytes ********************/
790 /* Get N random bytes
791  */
792 void
793 rand_bytes (void *buf, size_t n);
794 
795 /* Initialize random bytes generator
796  */
797 SANE_Status
798 rand_init (void);
799 
800 /* Cleanup random bytes generator
801  */
802 void
803 rand_cleanup (void);
804 
805 /******************** UUID utilities ********************/
806 /* Type uuid represents a random UUID string.
807  *
808  * It is wrapped into struct, so it can be returned
809  * by value, without need to mess with memory allocation
810  */
811 typedef struct {
812     char text[sizeof("urn:uuid:ede05377-460e-4b4a-a5c0-423f9e02e8fa")];
813 } uuid;
814 
815 /* Check if uuid is valid
816  */
817 static inline bool
uuid_valid(uuid u)818 uuid_valid (uuid u)
819 {
820     return u.text[0] != '\0';
821 }
822 
823 /* Generate random UUID. Generated UUID has a following form:
824  *    urn:uuid:ede05377-460e-4b4a-a5c0-423f9e02e8fa
825  */
826 uuid
827 uuid_rand (void);
828 
829 /* Parse UUID. This function ignores all "decorations", like
830  * urn:uuid: prefix and so on, and takes only hexadecimal digits
831  * into considerations
832  *
833  * Check the returned uuid with uuid_valid() for possible parse errors
834  */
835 uuid
836 uuid_parse (const char *in);
837 
838 /* Generate uuid by cryptographically cacheing input string
839  */
840 uuid
841 uuid_hash (const char *s);
842 
843 /* Compare two uuids
844  */
845 static inline bool
uuid_equal(uuid u1,uuid u2)846 uuid_equal (uuid u1, uuid u2)
847 {
848     return !strcmp(u1.text, u2.text);
849 }
850 
851 /******************** Generic .INI file parser ********************/
852 /* Types of .INI file records
853  */
854 typedef enum {
855     INIFILE_SECTION,                    /* The [section name] string */
856     INIFILE_VARIABLE,                   /* The variable = value string */
857     INIFILE_COMMAND,                    /* command param1 param2 ... */
858     INIFILE_SYNTAX                      /* The syntax error */
859 } INIFILE_RECORD;
860 
861 /* .INI file record
862  */
863 typedef struct {
864     INIFILE_RECORD      type;           /* Record type */
865     const char          *section;       /* Section name */
866     const char          *variable;      /* Variable name */
867     const char          *value;         /* Variable value */
868     const char          **tokv;         /* Value split to tokens */
869     unsigned int        tokc;           /* Count of strings in tokv */
870     const char          *file;          /* File name */
871     unsigned int        line;           /* File line */
872 } inifile_record;
873 
874 /* .INI file (opaque)
875  */
876 typedef struct {
877     const char          *file;                  /* File name */
878     unsigned int        line;                   /* File handle */
879     FILE                *fp;                    /* File pointer */
880 
881     bool                tk_open;                /* Token is currently open */
882     char                *tk_buffer;             /* Parser buffer, tokenized */
883     unsigned int        *tk_offsets;            /* Tokens offsets */
884     unsigned int        tk_count;               /* Tokens count */
885 
886     char                *buffer;                /* Parser buffer */
887     char                *section;               /* Section name string */
888     char                *variable;              /* Variable name string */
889     char                *value;                 /* Value string */
890     inifile_record      record;                 /* Record buffer */
891 } inifile;
892 
893 /* Open the .INI file
894  */
895 inifile*
896 inifile_open (const char *name);
897 
898 /* Close the .INI file
899  */
900 void
901 inifile_close (inifile *file);
902 
903 /* Read next record
904  */
905 const inifile_record*
906 inifile_read (inifile *file);
907 
908 /* Match name of section of variable
909  *   - match is case-insensitive
910  *   - difference in amount of free space is ignored
911  *   - leading and trailing space is ignored
912  */
913 bool
914 inifile_match_name (const char *n1, const char *n2);
915 
916 /******************** Utility functions for IP addresses ********************/
917 /* Address string, wrapped into structure so can
918  * be passed by value
919  */
920 typedef struct {
921     /* Holds sun_path from sockaddr_un plus a null byte. */
922     char       text[109];
923 } ip_straddr;
924 
925 /* Format ip_straddr from IP address (struct in_addr or struct in6_addr)
926  * af must be AF_INET or AF_INET6
927  */
928 ip_straddr
929 ip_straddr_from_ip (int af, const void *addr);
930 
931 /* Format ip_straddr from struct sockaddr.
932  * AF_INET, AF_INET6, and AF_UNIX are supported
933  *
934  * If `withzone' is true, zone suffix will be appended, when appropriate
935  */
936 ip_straddr
937 ip_straddr_from_sockaddr(const struct sockaddr *addr, bool withzone);
938 
939 /* Format ip_straddr from struct sockaddr.
940  * AF_INET, AF_INET6, and AF_UNIX are supported
941  *
942  * Port will not be appended, if it matches provided default port
943  * If `withzone' is true, zone suffix will be appended, when appropriate
944  */
945 ip_straddr
946 ip_straddr_from_sockaddr_dport (const struct sockaddr *addr,
947         int dport, bool withzone);
948 
949 /* Check if address is link-local
950  * af must be AF_INET or AF_INET6
951  */
952 bool
953 ip_is_linklocal (int af, const void *addr);
954 
955 /* Check if sockaddr is link-local
956  */
957 bool
958 ip_sockaddr_is_linklocal (const struct sockaddr *addr);
959 
960 /* Check if address is loopback
961  * af must be AF_INET or AF_INET6
962  */
963 bool
964 ip_is_loopback (int af, const void *addr);
965 
966 /* ip_addr represents IPv4 or IPv6 address
967  */
968 typedef struct {
969     int                 af;      /* AF_INET or AF_INET6 */
970     int                 ifindex; /* For IPv6 link-local addresses */
971     union {
972         struct in_addr  v4;      /* IPv4 address */
973         struct in6_addr v6;      /* IPv4 address */
974     } ip;
975 } ip_addr;
976 
977 /* Make ip_addr
978  */
979 static inline ip_addr
ip_addr_make(int ifindex,int af,const void * addr)980 ip_addr_make (int ifindex, int af, const void *addr)
981 {
982     ip_addr ip_addr;
983 
984     memset(&ip_addr, 0, sizeof(ip_addr));
985     ip_addr.af = af;
986 
987     switch (ip_addr.af) {
988     case AF_INET:
989         memcpy(&ip_addr.ip.v4, addr, 4);
990         break;
991 
992     case AF_INET6:
993         memcpy(&ip_addr.ip, addr, 16);
994         if (ip_is_linklocal(AF_INET6, &ip_addr.ip.v6)) {
995             ip_addr.ifindex = ifindex;
996         }
997         break;
998     }
999 
1000     return ip_addr;
1001 }
1002 
1003 /* Extract ip_addr from sockaddr
1004  */
1005 static inline ip_addr
ip_addr_from_sockaddr(const struct sockaddr * sockaddr)1006 ip_addr_from_sockaddr (const struct sockaddr *sockaddr)
1007 {
1008     ip_addr addr;
1009 
1010     memset(&addr, 0, sizeof(addr));
1011     addr.af = sockaddr->sa_family;
1012 
1013     switch (addr.af) {
1014     case AF_INET:
1015         addr.ip.v4 = ((struct sockaddr_in*) sockaddr)->sin_addr;
1016         break;
1017 
1018     case AF_INET6:
1019         addr.ip.v6 = ((struct sockaddr_in6*) sockaddr)->sin6_addr;
1020         if (ip_is_linklocal(AF_INET6, &addr.ip.v6)) {
1021             addr.ifindex = ((struct sockaddr_in6*) sockaddr)->sin6_scope_id;
1022         }
1023         break;
1024     }
1025 
1026     return addr;
1027 }
1028 
1029 /* Format ip_addr into ip_straddr
1030  */
1031 ip_straddr
1032 ip_addr_to_straddr (ip_addr addr, bool withzone);
1033 
1034 /* Check if two addresses are equal
1035  */
1036 static inline bool
ip_addr_equal(ip_addr a1,ip_addr a2)1037 ip_addr_equal (ip_addr a1, ip_addr a2)
1038 {
1039     if (a1.af != a2.af) {
1040         return false;
1041     }
1042 
1043     switch (a1.af) {
1044     case AF_INET:
1045         return a1.ip.v4.s_addr == a2.ip.v4.s_addr;
1046     case AF_INET6:
1047         return a1.ifindex == a2.ifindex &&
1048                !memcmp(a1.ip.v6.s6_addr, a2.ip.v6.s6_addr, 16);
1049     }
1050 
1051     return false;
1052 }
1053 
1054 /* ip_network represents IPv4 or IPv6 network (i.e., address with mask)
1055  */
1056 typedef struct {
1057     ip_addr addr; /* Network address */
1058     int     mask; /* Network mask */
1059 } ip_network;
1060 
1061 /* Format ip_network into ip_straddr
1062  */
1063 ip_straddr
1064 ip_network_to_straddr (ip_network net);
1065 
1066 /* Check if ip_network contains ip_addr
1067  */
1068 bool
1069 ip_network_contains (ip_network net, ip_addr addr);
1070 
1071 /* ip_addr_set represents a set of IP addresses
1072  */
1073 typedef struct ip_addrset ip_addrset;
1074 
1075 /* Create new ip_addrset
1076  */
1077 ip_addrset*
1078 ip_addrset_new (void);
1079 
1080 /* Free ip_addrset
1081  */
1082 void
1083 ip_addrset_free (ip_addrset *addrset);
1084 
1085 /* Check if address is in set
1086  */
1087 bool
1088 ip_addrset_lookup (const ip_addrset *addrset, ip_addr addr);
1089 
1090 /* Add address to the set. Returns true, if address was
1091  * actually added, false if it was already in the set
1092  */
1093 bool
1094 ip_addrset_add (ip_addrset *addrset, ip_addr addr);
1095 
1096 /* Add address to the set without checking for duplicates
1097  */
1098 void
1099 ip_addrset_add_unsafe (ip_addrset *addrset, ip_addr addr);
1100 
1101 /* Del address from the set.
1102  */
1103 void
1104 ip_addrset_del (ip_addrset *addrset, ip_addr addr);
1105 
1106 /* Delete all addresses from the set
1107  */
1108 void
1109 ip_addrset_purge (ip_addrset *addrset);
1110 
1111 /* Merge two sets:
1112  *   addrset += addrset2
1113  */
1114 void
1115 ip_addrset_merge (ip_addrset *addrset, const ip_addrset *addrset2);
1116 
1117 /* Get access to array of addresses in the set
1118  */
1119 const ip_addr*
1120 ip_addrset_addresses (const ip_addrset *addrset, size_t *count);
1121 
1122 /* Check if two address sets are intersecting
1123  */
1124 bool
1125 ip_addrset_is_intersect (const ip_addrset *set, const ip_addrset *set2);
1126 
1127 /* Check if some of addresses in the address set is on the
1128  * given network
1129  */
1130 bool
1131 ip_addrset_on_network (const ip_addrset *set, ip_network net);
1132 
1133 /* Create user-friendly string out of set of addresses, containing
1134  * in the ip_addrset:
1135  *   * addresses are sorted, IP4 addresses goes first
1136  *   * link-local addresses are skipped, if there are non-link-local ones
1137  */
1138 char*
1139 ip_addrset_friendly_str (const ip_addrset *set, char *s);
1140 
1141 /******************** Network interfaces addresses ********************/
1142 /* Network interface name, wrapped into structure, so
1143  * it can be passed by value
1144  */
1145 typedef struct {
1146     char text[32];
1147 } netif_name;
1148 
1149 /* Network interface address
1150  */
1151 typedef struct netif_addr netif_addr;
1152 struct netif_addr {
1153     netif_addr *next;         /* Next address in the list */
1154     int        ifindex;       /* Interface index */
1155     netif_name ifname;        /* Interface name, for logging */
1156     bool       ipv6;          /* This is an IPv6 address */
1157     void       *data;         /* Placeholder for user data */
1158     char       straddr[64];   /* Address string */
1159     union {
1160         struct in_addr  v4;   /* IPv4 address */
1161         struct in6_addr v6;   /* IPv6 address */
1162     } ip;
1163 };
1164 
1165 /* NETIF_DISTANCE represents a distance to the target address
1166  */
1167 typedef enum {
1168     NETIF_DISTANCE_LOOPBACK, /* Target address is host's local address */
1169     NETIF_DISTANCE_DIRECT,   /* Target is on a local network */
1170     NETIF_DISTANCE_ROUTED    /* Target is behind a router */
1171 } NETIF_DISTANCE;
1172 
1173 /* Get distance to the target address
1174  */
1175 NETIF_DISTANCE
1176 netif_distance_get (const struct sockaddr *addr);
1177 
1178 /* Check that interface has non-link-local address
1179  * of particular address family
1180  */
1181 bool
1182 netif_has_non_link_local_addr (int af, int ifindex);
1183 
1184 /* Compare addresses by distance. Returns:
1185  *   <0, if addr1 is closer that addr2
1186  *   >0, if addr2 is farther that addr2
1187  *   0 if distance is equal
1188  */
1189 static inline int
netif_distance_cmp(const struct sockaddr * addr1,const struct sockaddr * addr2)1190 netif_distance_cmp (const struct sockaddr *addr1, const struct sockaddr *addr2)
1191 {
1192     int d1 = (int) netif_distance_get(addr1);
1193     int d2 = (int) netif_distance_get(addr2);
1194 
1195     return d1 - d2;
1196 }
1197 
1198 /* Get list of network interfaces addresses
1199  * The returned list is sorted
1200  */
1201 netif_addr*
1202 netif_addr_list_get (void);
1203 
1204 /* Free list of network interfaces addresses
1205  */
1206 void
1207 netif_addr_list_free (netif_addr *list);
1208 
1209 /* netif_diff represents a difference between two
1210  * lists of network interface addresses
1211  */
1212 typedef struct {
1213     netif_addr *added, *removed; /* What was added/removed */
1214     netif_addr *preserved;
1215 } netif_diff;
1216 
1217 /* Compute a difference between two lists of addresses.
1218  *
1219  * It works by tossing nodes between 3 output lists:
1220  *   * if node is present in list2 only, it is moved
1221  *     to netif_diff.added
1222  *   * if node is present in list1 only, it is moved
1223  *     to netif_diff.removed
1224  *   * if node is present in both lists, node from
1225  *     list1 is moved to preserved, and node from
1226  *     list2 is released
1227  *
1228  * It assumes, both lists are sorted, as returned
1229  * by netif_addr_get(). Returned lists are also sorted
1230  */
1231 netif_diff
1232 netif_diff_compute (netif_addr *list1, netif_addr *list2);
1233 
1234 /* Merge two lists of addresses
1235  *
1236  * Input lists are consumed and new list is created.
1237  *
1238  * Input lists are assumed to be sorted, and output
1239  * list will be sorted as well
1240  */
1241 netif_addr*
1242 netif_addr_list_merge (netif_addr *list1, netif_addr *list2);
1243 
1244 /* Network interfaces addresses change notifier
1245  */
1246 typedef struct netif_notifier netif_notifier;
1247 
1248 /* Create netif_notifier
1249  */
1250 netif_notifier*
1251 netif_notifier_create (void (*callback) (void*), void *data);
1252 
1253 /* Destroy netif_notifier
1254  */
1255 void
1256 netif_notifier_free (netif_notifier *notifier);
1257 
1258 /* Initialize network interfaces monitoring
1259  */
1260 SANE_Status
1261 netif_init (void);
1262 
1263 /* Cleanup network interfaces monitoring
1264  */
1265 void
1266 netif_cleanup (void);
1267 
1268 /******************** Configuration file loader ********************/
1269 /* Device URI for manually disabled device
1270  */
1271 #define CONF_DEVICE_DISABLE     "disable"
1272 
1273 /* Device configuration, for manually added devices
1274  */
1275 typedef struct conf_device conf_device;
1276 struct conf_device {
1277     unsigned int devid; /* Device ident */
1278     const char   *name; /* Device name */
1279     ID_PROTO     proto; /* Protocol to use */
1280     http_uri     *uri;  /* Device URI, parsed; NULL if device disabled */
1281     conf_device  *next; /* Next device in the list */
1282 };
1283 
1284 /* WSDD_MODE represents WS-Discovery mode
1285  */
1286 typedef enum {
1287     WSDD_FAST,  /* Use hints from DNS-SD to speed up WSDD */
1288     WSDD_FULL,  /* Full discovery, slow and fair */
1289     WSDD_OFF    /* Disable WSDD */
1290 } WSDD_MODE;
1291 
1292 /* Device blacklist entry
1293  */
1294 typedef struct conf_blacklist conf_blacklist;
1295 struct conf_blacklist {
1296     const char     *model;   /* If not NULL, match by model */
1297     const char     *name;    /* If not NULL, match by network name */
1298     ip_network     net;      /* if net.addr.af != AF_UNSPEC, match by net */
1299     conf_blacklist *next;    /* Next entry in the list */
1300 };
1301 
1302 /* Backend configuration
1303  */
1304 typedef struct {
1305     bool           dbg_enabled;      /* Debugging enabled */
1306     const char     *dbg_trace;       /* Trace directory */
1307     conf_device    *devices;         /* Manually configured devices */
1308     bool           discovery;        /* Scanners discovery enabled */
1309     bool           model_is_netname; /* Use network name instead of model */
1310     bool           proto_auto;       /* Auto protocol selection */
1311     WSDD_MODE      wsdd_mode;        /* WS-Discovery mode */
1312     const char     *socket_dir;      /* Directory for AF_UNIX sockets */
1313     conf_blacklist *blacklist;       /* Devices blacklisted for discovery */
1314 } conf_data;
1315 
1316 #define CONF_INIT {                     \
1317         .dbg_enabled = false,           \
1318         .dbg_trace = NULL,              \
1319         .devices = NULL,                \
1320         .discovery = true,              \
1321         .model_is_netname = true,       \
1322         .proto_auto = true,             \
1323         .wsdd_mode = WSDD_FAST,         \
1324         .socket_dir = NULL              \
1325     }
1326 
1327 extern conf_data conf;
1328 
1329 /* Load configuration. It updates content of a global conf variable
1330  */
1331 void
1332 conf_load (void);
1333 
1334 /* Free resources, allocated by conf_load, and reset configuration
1335  * data into initial state
1336  */
1337 void
1338 conf_unload (void);
1339 
1340 /******************** Pollable events ********************/
1341 /* The pollable event
1342  *
1343  * Pollable events allow to wait until some event happens
1344  * and can be used in combination with select()/poll()
1345  * system calls
1346  */
1347 typedef struct pollable pollable;
1348 
1349 /* Create new pollable event
1350  */
1351 pollable*
1352 pollable_new (void);
1353 
1354 /* Free pollable event
1355  */
1356 void
1357 pollable_free (pollable *p);
1358 
1359 /* Get file descriptor for poll()/select().
1360  *
1361  * When pollable event becomes "ready", this file descriptor
1362  * becomes readable from the select/poll point of view
1363  */
1364 int
1365 pollable_get_fd (pollable *p);
1366 
1367 /* Make pollable event "ready"
1368  */
1369 void
1370 pollable_signal (pollable *p);
1371 
1372 /* Make pollable event "not ready"
1373  */
1374 void
1375 pollable_reset (pollable *p);
1376 
1377 /* Wait until pollable event is ready
1378  */
1379 void
1380 pollable_wait (pollable *p);
1381 
1382 /******************** Time stamps ********************/
1383 /* timestamp represents a monotonic time, in milliseconds
1384  */
1385 typedef int64_t timestamp;
1386 
1387 /* timestamp_now() returns a current time as timestamp
1388  */
1389 static inline timestamp
timestamp_now(void)1390 timestamp_now (void)
1391 {
1392     struct timespec t;
1393 
1394     clock_gettime(CLOCK_MONOTONIC, &t);
1395     return (timestamp) t.tv_sec * 1000 + (timestamp) t.tv_nsec / 1000000;
1396 }
1397 
1398 /******************** Event loop ********************/
1399 /* Initialize event loop
1400  */
1401 SANE_Status
1402 eloop_init (void);
1403 
1404 /* Cleanup event loop
1405  */
1406 void
1407 eloop_cleanup (void);
1408 
1409 /* Add start/stop callback. This callback is called
1410  * on a event loop thread context, once when event
1411  * loop is started, and second time when it is stopped
1412  *
1413  * Start callbacks are called in the same order as
1414  * they were added. Stop callbacks are called in a
1415  * reverse order
1416  */
1417 void
1418 eloop_add_start_stop_callback (void (*callback) (bool start));
1419 
1420 /* Start event loop thread.
1421  */
1422 void
1423 eloop_thread_start (void);
1424 
1425 /* Stop event loop thread and wait until its termination
1426  */
1427 void
1428 eloop_thread_stop (void);
1429 
1430 /* Acquire event loop mutex
1431  */
1432 void
1433 eloop_mutex_lock (void);
1434 
1435 /* Release event loop mutex
1436  */
1437 void
1438 eloop_mutex_unlock (void);
1439 
1440 /* Wait on conditional variable under the event loop mutex
1441  */
1442 void
1443 eloop_cond_wait (pthread_cond_t *cond);
1444 
1445 /* Get AvahiPoll that runs in event loop thread
1446  */
1447 const AvahiPoll*
1448 eloop_poll_get (void);
1449 
1450 /* Call function on a context of event loop thread
1451  * The returned value can be supplied as a `callid'
1452  * parameter for the eloop_call_cancel() function
1453  */
1454 uint64_t
1455 eloop_call (void (*func)(void*), void *data);
1456 
1457 /* Cancel pending eloop_call
1458  *
1459  * This is safe to cancel already finished call (at this
1460  * case nothing will happen)
1461  */
1462 void
1463 eloop_call_cancel (uint64_t callid);
1464 
1465 /* Event notifier. Calls user-defined function on a context
1466  * of event loop thread, when event is triggered. This is
1467  * safe to trigger the event from a context of any thread
1468  * or even from a signal handler
1469  */
1470 typedef struct eloop_event eloop_event;
1471 
1472 /* Create new event notifier. May return NULL
1473  */
1474 eloop_event*
1475 eloop_event_new (void (*callback)(void *), void *data);
1476 
1477 /* Destroy event notifier
1478  */
1479 void
1480 eloop_event_free (eloop_event *event);
1481 
1482 /* Trigger an event
1483  */
1484 void
1485 eloop_event_trigger (eloop_event *event);
1486 
1487 /* Timer. Calls user-defined function after a specified
1488  * interval
1489  */
1490 typedef struct eloop_timer eloop_timer;
1491 
1492 /* Create new timer. Timeout is in milliseconds
1493  */
1494 eloop_timer*
1495 eloop_timer_new (int timeout, void (*callback)(void *), void *data);
1496 
1497 /* Cancel a timer
1498  *
1499  * Caller SHOULD NOT cancel expired timer (timer with called
1500  * callback) -- this is done automatically
1501  */
1502 void
1503 eloop_timer_cancel (eloop_timer *timer);
1504 
1505 /* eloop_fdpoll notifies user when file becomes
1506  * readable, writable or both, depending on its
1507  * event mask
1508  */
1509 typedef struct eloop_fdpoll eloop_fdpoll;
1510 
1511 /* Mask of file events user interested in
1512  */
1513 typedef enum {
1514     ELOOP_FDPOLL_READ  = (1 << 0),
1515     ELOOP_FDPOLL_WRITE = (1 << 1),
1516     ELOOP_FDPOLL_BOTH  = ELOOP_FDPOLL_READ | ELOOP_FDPOLL_WRITE
1517 } ELOOP_FDPOLL_MASK;
1518 
1519 /* Convert ELOOP_FDPOLL_MASK to string. Used for logging.
1520  */
1521 const char*
1522 eloop_fdpoll_mask_str (ELOOP_FDPOLL_MASK mask);
1523 
1524 /* Create eloop_fdpoll
1525  *
1526  * Callback will be called, when file will be ready for read/write/both,
1527  * depending on mask
1528  *
1529  * Initial mask value is 0, and it can be changed, using
1530  * eloop_fdpoll_set_mask() function
1531  */
1532 eloop_fdpoll*
1533 eloop_fdpoll_new (int fd,
1534         void (*callback) (int, void*, ELOOP_FDPOLL_MASK), void *data);
1535 
1536 /* Destroy eloop_fdpoll
1537  */
1538 void
1539 eloop_fdpoll_free (eloop_fdpoll *fdpoll);
1540 
1541 /* Set eloop_fdpoll event mask. It returns a previous value of event mask
1542  */
1543 ELOOP_FDPOLL_MASK
1544 eloop_fdpoll_set_mask (eloop_fdpoll *fdpoll, ELOOP_FDPOLL_MASK mask);
1545 
1546 /* Format error string, as printf() does and save result
1547  * in the memory, owned by the event loop
1548  *
1549  * Caller should not free returned string. This is safe
1550  * to use the returned string as an argument to the
1551  * subsequent eloop_eprintf() call.
1552  *
1553  * The returned string remains valid until next call
1554  * to eloop_eprintf(), which makes it usable to
1555  * report errors up by the stack. However, it should
1556  * not be assumed, that the string will remain valid
1557  * on a next eloop roll, so don't save this string
1558  * anywhere, if you need to do so, create a copy!
1559  */
1560 error
1561 eloop_eprintf(const char *fmt, ...);
1562 
1563 /******************** HTTP Client ********************/
1564 /* Create new URI, by parsing URI string
1565  */
1566 http_uri*
1567 http_uri_new (const char *str, bool strip_fragment);
1568 
1569 /* Clone an URI
1570  */
1571 http_uri*
1572 http_uri_clone (const http_uri *old);
1573 
1574 /* Create URI, relative to base URI. If `path_only' is
1575  * true, scheme, host and port are taken from the
1576  * base URI
1577  */
1578 http_uri*
1579 http_uri_new_relative (const http_uri *base, const char *path,
1580         bool strip_fragment, bool path_only);
1581 
1582 /* Free the URI
1583  */
1584 void
1585 http_uri_free (http_uri *uri);
1586 
1587 /* Get URI string
1588  */
1589 const char*
1590 http_uri_str (http_uri *uri);
1591 
1592 /* Get URI's host address. If Host address is not literal, returns NULL
1593  */
1594 const struct sockaddr*
1595 http_uri_addr (http_uri *uri);
1596 
1597 /* Get URI's address family. May return AF_UNSPEC,
1598  * if host address is not literal
1599  */
1600 static inline int
http_uri_af(http_uri * uri)1601 http_uri_af (http_uri *uri)
1602 {
1603     const struct sockaddr *addr = http_uri_addr(uri);
1604     return addr ? addr->sa_family : AF_UNSPEC;
1605 }
1606 
1607 /* Get URI path
1608  */
1609 const char*
1610 http_uri_get_path (const http_uri *uri);
1611 
1612 /* Set URI path
1613  */
1614 void
1615 http_uri_set_path (http_uri *uri, const char *path);
1616 
1617 /* Get URI host. It returns only host name, port number is
1618  * not included.
1619  *
1620  * IPv6 literal addresses are returned in square brackets
1621  * (i.e., [fe80::217:c8ff:fe7b:6a91%4])
1622  *
1623  * Note, the subsequent modifications of URI, such as http_uri_fix_host(),
1624  * http_uri_fix_ipv6_zone() etc, may make the returned string invalid,
1625  * so if you need to keep it for a long time, better make a copy
1626  */
1627 const char*
1628 http_uri_get_host (const http_uri *uri);
1629 
1630 /* Fix URI host: if `match` is NULL or uri's host matches `match`,
1631  * replace uri's host and port with values taken from the base_uri
1632  */
1633 void
1634 http_uri_fix_host (http_uri *uri, const http_uri *base_uri, const char *match);
1635 
1636 /* Fix IPv6 address zone suffix
1637  */
1638 void
1639 http_uri_fix_ipv6_zone (http_uri *uri, int ifindex);
1640 
1641 /* Strip zone suffix from literal IPv6 host address
1642  *
1643  * If address is not IPv6 or doesn't have zone suffix, it is
1644  * not changed
1645  */
1646 void
1647 http_uri_strip_zone_suffux (http_uri *uri);
1648 
1649 /* Make sure URI's path ends with the slash character
1650  */
1651 void
1652 http_uri_fix_end_slash (http_uri *uri);
1653 
1654 /* Check if 2 URIs are equal
1655  */
1656 bool
1657 http_uri_equal (const http_uri *uri1, const http_uri *uri2);
1658 
1659 /* HTTP data
1660  */
1661 typedef struct {
1662     const char *content_type; /* Normalized: low-case with stripped directives */
1663     const void *bytes;        /* Data bytes */
1664     size_t     size;          /* Data size */
1665 } http_data;
1666 
1667 /* Ref http_data
1668  */
1669 http_data*
1670 http_data_ref (http_data *data);
1671 
1672 /* Unref http_data
1673  */
1674 void
1675 http_data_unref (http_data *data);
1676 
1677 /* http_data_queue represents a queue of http_data items
1678  */
1679 typedef struct http_data_queue http_data_queue;
1680 
1681 /* Create new http_data_queue
1682  */
1683 http_data_queue*
1684 http_data_queue_new (void);
1685 
1686 /* Destroy http_data_queue
1687  */
1688 void
1689 http_data_queue_free (http_data_queue *queue);
1690 
1691 /* Push item into the http_data_queue.
1692  */
1693 void
1694 http_data_queue_push (http_data_queue *queue, http_data *data);
1695 
1696 /* Pull an item from the http_data_queue. Returns NULL if queue is empty
1697  */
1698 http_data*
1699 http_data_queue_pull (http_data_queue *queue);
1700 
1701 /* Get queue length
1702  */
1703 int
1704 http_data_queue_len (const http_data_queue *queue);
1705 
1706 /* Check if queue is empty
1707  */
1708 static inline bool
http_data_queue_empty(const http_data_queue * queue)1709 http_data_queue_empty (const http_data_queue *queue)
1710 {
1711     return http_data_queue_len(queue) == 0;
1712 }
1713 
1714 /* Purge the queue
1715  */
1716 void
1717 http_data_queue_purge (http_data_queue *queue);
1718 
1719 /* Type http_client represents HTTP client instance
1720  */
1721 typedef struct http_client http_client;
1722 
1723 /* Create new http_client
1724  */
1725 http_client*
1726 http_client_new (log_ctx *log, void *ptr);
1727 
1728 /* Destroy http_client
1729  */
1730 void
1731 http_client_free (http_client *client);
1732 
1733 /* Set on-error callback. If this callback is not NULL,
1734  * in a case of transport error it will be called instead
1735  * of the http_query callback
1736  */
1737 void
1738 http_client_onerror (http_client *client,
1739         void (*callback)(void *ptr, error err));
1740 
1741 /* Cancel all pending queries, if any
1742  */
1743 void
1744 http_client_cancel (http_client *client);
1745 
1746 /* Set timeout of all pending queries, if any. Timeout is in milliseconds
1747  */
1748 void
1749 http_client_timeout (http_client *client, int timeout);
1750 
1751 /* Cancel all pending queries with matching address family and uintptr
1752  */
1753 void
1754 http_client_cancel_af_uintptr (http_client *client, int af, uintptr_t uintptr);
1755 
1756 /* Check if client has pending queries
1757  */
1758 bool
1759 http_client_has_pending (const http_client *client);
1760 
1761 /* Type http_query represents HTTP query (both request and response)
1762  */
1763 typedef struct http_query http_query;
1764 
1765 /* Create new http_query
1766  *
1767  * Newly created http_query takes ownership on uri and body (if not NULL).
1768  * The method and content_type assumed to be constant strings.
1769  */
1770 http_query*
1771 http_query_new (http_client *client, http_uri *uri, const char *method,
1772         char *body, const char *content_type);
1773 
1774 /* Create new http_query
1775  *
1776  * Newly created http_query takes ownership on uri and body (if not NULL).
1777  * The method and content_type assumed to be constant strings.
1778  */
1779 http_query*
1780 http_query_new_len (http_client *client, http_uri *uri, const char *method,
1781         void *body, size_t body_len, const char *content_type);
1782 
1783 /* Create new http_query, relative to base URI
1784  *
1785  * Newly created http_query takes ownership on body (if not NULL).
1786  * The method and content_type assumed to be constant strings.
1787  */
1788 http_query*
1789 http_query_new_relative(http_client *client,
1790         const http_uri *base_uri, const char *path,
1791         const char *method, char *body, const char *content_type);
1792 
1793 /* Set query timeout, in milliseconds. Negative timeout means 'infinite'
1794  *
1795  * This function may be called multiple times (each subsequent call overrides
1796  * a previous one)
1797  */
1798 void
1799 http_query_timeout (http_query *q, int timeout);
1800 
1801 /* Set forcing port to be added to the Host header for this query.
1802  *
1803  * This function may be called multiple times (each subsequent call overrides
1804  * a previous one).
1805  */
1806 void
1807 http_query_force_port(http_query *q, bool force_port);
1808 
1809 /* For this particular query override on-error callback, previously
1810  * set by http_client_onerror()
1811  *
1812  * If canllback is NULL, the completion callback, specified on a
1813  * http_query_submit() call, will be used even in a case of
1814  * transport error.
1815  */
1816 void
1817 http_query_onerror (http_query *q, void (*onerror)(void *ptr, error err));
1818 
1819 /* Set on-redirect callback. It is called in a case of HTTP
1820  * redirect and may modify the supplied URI
1821  */
1822 void
1823 http_query_onredir (http_query *q,
1824         void (*onredir)(void *ptr, http_uri *uri, const http_uri *orig_uri));
1825 
1826 /* Set callback that will be called, when response headers reception
1827  * is completed
1828  */
1829 void
1830 http_query_onrxhdr (http_query *q, void (*onrxhdr)(void *ptr, http_query *q));
1831 
1832 /* Submit the query.
1833  *
1834  * When query is finished, callback will be called. After return from
1835  * callback, memory, owned by http_query will be invalidated
1836  */
1837 void
1838 http_query_submit (http_query *q, void (*callback)(void *ptr, http_query *q));
1839 
1840 /* Get http_query timestamp. Timestamp is set when query is
1841  * submitted. And this function should not be called before
1842  * http_query_submit()
1843  */
1844 timestamp
1845 http_query_timestamp (const http_query *q);
1846 
1847 /* Set uintptr_t parameter, associated with query.
1848  * Completion callback may later use http_query_get_uintptr()
1849  * to fetch this value
1850  */
1851 void
1852 http_query_set_uintptr (http_query *q, uintptr_t u);
1853 
1854 /* Get uintptr_t parameter, previously set by http_query_set_uintptr()
1855  */
1856 uintptr_t
1857 http_query_get_uintptr (http_query *q);
1858 
1859 /* Get query error, if any
1860  *
1861  * Both transport errors and erroneous HTTP response codes
1862  * considered as errors here
1863  */
1864 error
1865 http_query_error (const http_query *q);
1866 
1867 /* Get query transport error, if any
1868  *
1869  * Only transport errors considered errors here
1870  */
1871 error
1872 http_query_transport_error (const http_query *q);
1873 
1874 /* Get HTTP status code. Code not available, if query finished
1875  * with error
1876  */
1877 int
1878 http_query_status (const http_query *q);
1879 
1880 /* Get HTTP status string
1881  */
1882 const char*
1883 http_query_status_string (const http_query *q);
1884 
1885 /* Get query URI
1886  *
1887  * It works as http_query_orig_uri() before query is submitted
1888  * or after it is completed, and as http_query_real_uri() in
1889  * between
1890  *
1891  * This function is deprecated, use http_query_orig_uri()
1892  * or http_query_real_uri() instead
1893  */
1894 http_uri*
1895 http_query_uri (const http_query *q);
1896 
1897 /* Get original URI (the same as used when http_query was created)
1898  */
1899 http_uri*
1900 http_query_orig_uri (const http_query *q);
1901 
1902 /* Get real URI, that can differ from the requested URI
1903  * in a case of HTTP redirection
1904  */
1905 http_uri*
1906 http_query_real_uri (const http_query *q);
1907 
1908 /* Get query method
1909  */
1910 const char*
1911 http_query_method (const http_query *q);
1912 
1913 /* Set request header
1914  */
1915 void
1916 http_query_set_request_header (http_query *q, const char *name,
1917         const char *value);
1918 
1919 /* Get request header
1920  */
1921 const char*
1922 http_query_get_request_header (const http_query *q, const char *name);
1923 
1924 /* Get response header
1925  */
1926 const char*
1927 http_query_get_response_header (const http_query *q, const char *name);
1928 
1929 /* Get request data
1930  *
1931  * You need to http_data_ref(), if you want data to remain valid
1932  * after query end of life
1933  */
1934 http_data*
1935 http_query_get_request_data (const http_query *q);
1936 
1937 /* Get request data
1938  *
1939  * You need to http_data_ref(), if you want data to remain valid
1940  * after query end of life
1941  */
1942 http_data*
1943 http_query_get_response_data (const http_query *q);
1944 
1945 /* Get count of parts of multipart response
1946  */
1947 int
1948 http_query_get_mp_response_count (const http_query *q);
1949 
1950 /* Get data of Nth part of multipart response
1951  *
1952  * You need to http_data_ref(), if you want data to remain valid
1953  * after query end of life
1954  */
1955 http_data*
1956 http_query_get_mp_response_data (const http_query *q, int n);
1957 
1958 /* Call callback for each request header
1959  */
1960 void
1961 http_query_foreach_request_header (const http_query *q,
1962         void (*callback)(const char *name, const char *value, void *ptr),
1963         void *ptr);
1964 
1965 /* Call callback for each response header
1966  */
1967 void
1968 http_query_foreach_response_header (const http_query *q,
1969         void (*callback)(const char *name, const char *value, void *ptr),
1970         void *ptr);
1971 
1972 /* Decode response part of the query.
1973  * This function is intended for testing purposes, not for regular use
1974  */
1975 error
1976 http_query_test_decode_response (http_query *q, const void *data, size_t size);
1977 
1978 /* HTTP schemes
1979  */
1980 typedef enum {
1981     HTTP_SCHEME_UNSET = -1,
1982     HTTP_SCHEME_HTTP,
1983     HTTP_SCHEME_HTTPS,
1984     HTTP_SCHEME_UNIX
1985 } HTTP_SCHEME;
1986 
1987 /* Some HTTP status codes
1988  */
1989 #ifndef NO_HTTP_STATUS
1990 enum {
1991     HTTP_STATUS_OK                  = 200,
1992     HTTP_STATUS_CREATED             = 201,
1993     HTTP_STATUS_NOT_FOUND           = 404,
1994     HTTP_STATUS_SERVICE_UNAVAILABLE = 503
1995 };
1996 #endif
1997 
1998 /* Initialize HTTP client
1999  */
2000 SANE_Status
2001 http_init (void);
2002 
2003 /* Initialize HTTP client
2004  */
2005 void
2006 http_cleanup (void);
2007 
2008 /******************** Protocol trace ********************/
2009 /* Type trace represents an opaque handle of trace
2010  * file
2011  */
2012 typedef struct trace trace;
2013 
2014 /* Initialize protocol trace. Called at backend initialization
2015  */
2016 SANE_Status
2017 trace_init (void);
2018 
2019 /* Cleanup protocol trace. Called at backend unload
2020  */
2021 void
2022 trace_cleanup (void);
2023 
2024 /* Open protocol trace
2025  */
2026 trace*
2027 trace_open (const char *device_name);
2028 
2029 /* Ref the trace
2030  */
2031 trace*
2032 trace_ref (trace *t);
2033 
2034 /* Unref the trace. When trace is not longer in use, it will be closed
2035  */
2036 void
2037 trace_unref (trace *t);
2038 
2039 /* This hook is called on every http_query completion
2040  */
2041 void
2042 trace_http_query_hook (trace *t, http_query *q);
2043 
2044 /* Printf to the trace log
2045  */
2046 void
2047 trace_printf (trace *t, const char *fmt, ...);
2048 
2049 /* Note an error in trace log
2050  */
2051 void
2052 trace_error (trace *t, error err);
2053 
2054 /* Dump message body
2055  */
2056 void
2057 trace_dump_body (trace *t, http_data *data);
2058 
2059 /******************** SANE_Word/SANE_String arrays ********************/
2060 /* Create array of SANE_Word
2061  */
2062 static inline SANE_Word*
sane_word_array_new(void)2063 sane_word_array_new (void)
2064 {
2065     return mem_new(SANE_Word,1);
2066 }
2067 
2068 /* Free array of SANE_Word
2069  */
2070 static inline void
sane_word_array_free(SANE_Word * a)2071 sane_word_array_free (SANE_Word *a)
2072 {
2073     mem_free(a);
2074 }
2075 
2076 /* Reset array of SANE_Word
2077  */
2078 static inline void
sane_word_array_reset(SANE_Word ** a)2079 sane_word_array_reset (SANE_Word **a)
2080 {
2081     (*a)[0] = 0;
2082 }
2083 
2084 /* Get length of the SANE_Word array
2085  */
2086 static inline size_t
sane_word_array_len(const SANE_Word * a)2087 sane_word_array_len (const SANE_Word *a)
2088 {
2089     return (size_t) a[0];
2090 }
2091 
2092 /* Append word to array. Returns new array (old becomes invalid)
2093  */
2094 static inline SANE_Word*
sane_word_array_append(SANE_Word * a,SANE_Word w)2095 sane_word_array_append (SANE_Word *a, SANE_Word w)
2096 {
2097     size_t len = sane_word_array_len(a) + 1;
2098     a = mem_resize(a, len + 1, 0);
2099     a[0] = len;
2100     a[len] = w;
2101     return a;
2102 }
2103 
2104 /* Drop array elements that outside of specified boundary
2105  */
2106 void
2107 sane_word_array_bound (SANE_Word *a, SANE_Word min, SANE_Word max);
2108 
2109 /* Sort array of SANE_Word in increasing order
2110  */
2111 void
2112 sane_word_array_sort (SANE_Word *a);
2113 
2114 /* Intersect two sorted arrays.
2115  */
2116 SANE_Word*
2117 sane_word_array_intersect_sorted ( const SANE_Word *a1, const SANE_Word *a2);
2118 
2119 /* Create array of SANE_String
2120  */
2121 static inline SANE_String*
sane_string_array_new(void)2122 sane_string_array_new (void)
2123 {
2124     return ptr_array_new(SANE_String);
2125 }
2126 
2127 /* Free array of SANE_String
2128  */
2129 static inline void
sane_string_array_free(SANE_String * a)2130 sane_string_array_free (SANE_String *a)
2131 {
2132     mem_free(a);
2133 }
2134 
2135 /* Reset array of SANE_String
2136  */
2137 static inline void
sane_string_array_reset(SANE_String * a)2138 sane_string_array_reset (SANE_String *a)
2139 {
2140     ptr_array_trunc(a);
2141 }
2142 
2143 /* Get length of the SANE_String array
2144  */
2145 static inline size_t
sane_string_array_len(const SANE_String * a)2146 sane_string_array_len (const SANE_String *a)
2147 {
2148     return mem_len(a);
2149 }
2150 
2151 /* Append string to array Returns new array (old becomes invalid)
2152  */
2153 static inline SANE_String*
sane_string_array_append(SANE_String * a,SANE_String s)2154 sane_string_array_append(SANE_String *a, SANE_String s)
2155 {
2156     return ptr_array_append(a, s);
2157 }
2158 
2159 /* Compute max string length in array of strings
2160  */
2161 size_t
2162 sane_string_array_max_strlen(const SANE_String *a);
2163 
2164 /* Create array of SANE_Device
2165  */
2166 static inline const SANE_Device**
sane_device_array_new(void)2167 sane_device_array_new (void)
2168 {
2169     return ptr_array_new(const SANE_Device*);
2170 }
2171 
2172 /* Free array of SANE_Device
2173  */
2174 static inline void
sane_device_array_free(const SANE_Device ** a)2175 sane_device_array_free (const SANE_Device **a)
2176 {
2177     mem_free(a);
2178 }
2179 
2180 /* Get length of the SANE_Device array
2181  */
2182 static inline size_t
sane_device_array_len(const SANE_Device * const * a)2183 sane_device_array_len (const SANE_Device * const *a)
2184 {
2185     return mem_len(a);
2186 }
2187 
2188 /* Append device to array. Returns new array (old becomes invalid)
2189  */
2190 static inline const SANE_Device**
sane_device_array_append(const SANE_Device ** a,SANE_Device * d)2191 sane_device_array_append(const SANE_Device **a, SANE_Device *d)
2192 {
2193     return ptr_array_append(a, d);
2194 }
2195 
2196 /******************** XML utilities ********************/
2197 /* xml_ns defines XML namespace.
2198  *
2199  * For XML writer namespaces are simply added to the root
2200  * node attributes
2201  *
2202  * XML reader performs prefix substitutions
2203  *
2204  * If namespace substitution is enabled, for each note, if its
2205  * namespace matches the pattern, will be reported with name prefix
2206  * defined by substitution rule, regardless of prefix actually used
2207  * in the document
2208  *
2209  * Example:
2210  *   <namespace:nodes xmlns:namespace="http://www.example.com/namespace">
2211  *     <namespace:node1/>
2212  *     <namespace:node2/>
2213  *     <namespace:node3/>
2214  *   </namespace:nodes>
2215  *
2216  *   rule: {"ns", "http://www.example.com/namespace"}
2217  *
2218  * With this rule set, all nodes will be reported as if they
2219  * had the "ns" prefix, though actually their prefix in document
2220  * is different
2221  *
2222  * XML reader interprets namespace uri as a glob-style pattern,
2223  * as used by fnmatch (3) function with flags = 0
2224  */
2225 typedef struct {
2226     const char *prefix; /* Short prefix */
2227     const char *uri;    /* The namespace uri (glob pattern for reader) */
2228 } xml_ns;
2229 
2230 /* xml_attr represents an XML attribute.
2231  *
2232  * Attributes are supported by XML writer. Array of attributes
2233  * is terminated by the {NULL, NULL} attribute
2234  */
2235 typedef struct {
2236     const char *name;   /* Attribute name */
2237     const char *value;  /* Attribute value */
2238 } xml_attr;
2239 
2240 /* XML reader
2241  */
2242 typedef struct xml_rd xml_rd;
2243 
2244 /* Parse XML text and initialize reader to iterate
2245  * starting from the root node
2246  *
2247  * The 'ns' argument, if not NULL, points to array of substitution
2248  * rules. Last element must have NULL prefix and url
2249  *
2250  * Array of rules considered to be statically allocated
2251  * (at least, it can remain valid during reader life time)
2252  *
2253  * On success, saves newly constructed reader into
2254  * the xml parameter.
2255  */
2256 error
2257 xml_rd_begin (xml_rd **xml, const char *xml_text, size_t xml_len,
2258         const xml_ns *ns);
2259 
2260 /* Finish reading, free allocated resources
2261  */
2262 void
2263 xml_rd_finish (xml_rd **xml);
2264 
2265 /* Get current node depth in the tree. Root depth is 0
2266  */
2267 unsigned int
2268 xml_rd_depth (xml_rd *xml);
2269 
2270 /* Check for end-of-document condition
2271  */
2272 bool
2273 xml_rd_end (xml_rd *xml);
2274 
2275 /* Shift to the next node
2276  */
2277 void
2278 xml_rd_next (xml_rd *xml);
2279 
2280 /* Shift to the next node, visiting the nested nodes on the way
2281  *
2282  * If depth > 0, it will not return from nested nodes
2283  * upper the specified depth
2284  */
2285 void
2286 xml_rd_deep_next (xml_rd *xml, unsigned int depth);
2287 
2288 /* Enter the current node - iterate its children
2289  */
2290 void
2291 xml_rd_enter (xml_rd *xml);
2292 
2293 /* Leave the current node - return to its parent
2294  */
2295 void
2296 xml_rd_leave (xml_rd *xml);
2297 
2298 /* Get name of the current node.
2299  *
2300  * The returned string remains valid, until reader is cleaned up
2301  * or current node is changed (by set/next/enter/leave operations).
2302  * You don't need to free this string explicitly
2303  */
2304 const char*
2305 xml_rd_node_name (xml_rd *xml);
2306 
2307 /* Get full path to the current node, '/'-separated
2308  */
2309 const char*
2310 xml_rd_node_path (xml_rd *xml);
2311 
2312 /* Match name of the current node against the pattern
2313  */
2314 bool
2315 xml_rd_node_name_match (xml_rd *xml, const char *pattern);
2316 
2317 /* Get value of the current node as text
2318  *
2319  * The returned string remains valid, until reader is cleaned up
2320  * or current node is changed (by set/next/enter/leave operations).
2321  * You don't need to free this string explicitly
2322  */
2323 const char*
2324 xml_rd_node_value (xml_rd *xml);
2325 
2326 /* Get value of the current node as unsigned integer
2327  */
2328 error
2329 xml_rd_node_value_uint (xml_rd *xml, SANE_Word *val);
2330 
2331 /* XML writer
2332  */
2333 typedef struct xml_wr xml_wr;
2334 
2335 /* Begin writing XML document. Root node will be created automatically
2336  *
2337  * The ns parameter must be terminated by {NULL, NULL} structure
2338  */
2339 xml_wr*
2340 xml_wr_begin (const char *root, const xml_ns *ns);
2341 
2342 /* Finish writing, generate document string.
2343  * Caller must g_free() this string after use
2344  */
2345 char*
2346 xml_wr_finish (xml_wr *xml);
2347 
2348 /* Like xml_wr_finish, but returns compact representation
2349  * of XML (without indentation and new lines)
2350  */
2351 char*
2352 xml_wr_finish_compact (xml_wr *xml);
2353 
2354 /* Add node with textual value
2355  */
2356 void
2357 xml_wr_add_text (xml_wr *xml, const char *name, const char *value);
2358 
2359 /* Add text node with attributes
2360  */
2361 void
2362 xml_wr_add_text_attr (xml_wr *xml, const char *name, const char *value,
2363         const xml_attr *attrs);
2364 
2365 /* Add node with unsigned integer value
2366  */
2367 void
2368 xml_wr_add_uint (xml_wr *xml, const char *name, unsigned int value);
2369 
2370 /* Add node with unsigned integer value and attributes
2371  */
2372 void
2373 xml_wr_add_uint_attr (xml_wr *xml, const char *name, unsigned int value,
2374         const xml_attr *attrs);
2375 
2376 /* Add node with boolean value
2377  */
2378 void
2379 xml_wr_add_bool (xml_wr *xml, const char *name, bool value);
2380 
2381 /* Add node with boolean value and attributes
2382  */
2383 void
2384 xml_wr_add_bool_attr (xml_wr *xml, const char *name, bool value,
2385         const xml_attr *attrs);
2386 
2387 /* Create node with children and enter newly added node
2388  */
2389 void
2390 xml_wr_enter (xml_wr *xml, const char *name);
2391 
2392 /* xml_wr_enter with attributes
2393  */
2394 void
2395 xml_wr_enter_attr (xml_wr *xml, const char *name, const xml_attr *attrs);
2396 
2397 /* Leave the current node
2398  */
2399 void
2400 xml_wr_leave (xml_wr *xml);
2401 
2402 /* Format XML to file. It either succeeds, writes a formatted XML
2403  * and returns true, or fails, writes nothing to file and returns false
2404  */
2405 bool
2406 xml_format (FILE *fp, const char *xml_text, size_t xml_len);
2407 
2408 /******************** Sane Options********************/
2409 /* Options numbers, for internal use
2410  */
2411 enum {
2412     OPT_NUM_OPTIONS,            /* Total number of options */
2413 
2414     /* Standard options group */
2415     OPT_GROUP_STANDARD,
2416     OPT_SCAN_RESOLUTION,
2417     OPT_SCAN_COLORMODE,         /* I.e. color/grayscale etc */
2418     OPT_SCAN_SOURCE,            /* Platem/ADF/ADF Duplex */
2419 
2420     /* Geometry options group */
2421     OPT_GROUP_GEOMETRY,
2422     OPT_SCAN_TL_X,
2423     OPT_SCAN_TL_Y,
2424     OPT_SCAN_BR_X,
2425     OPT_SCAN_BR_Y,
2426 
2427     /* Image enhancement group */
2428     OPT_GROUP_ENHANCEMENT,
2429     OPT_BRIGHTNESS,
2430     OPT_CONTRAST,
2431     OPT_SHADOW,
2432     OPT_HIGHLIGHT,
2433     OPT_GAMMA,
2434     OPT_NEGATIVE,
2435 
2436     /* Total count of options, computed by compiler */
2437     NUM_OPTIONS
2438 };
2439 
2440 /* String constants for certain SANE options values
2441  * (missed from sane/sameopt.h)
2442  */
2443 #define OPTVAL_SOURCE_PLATEN      "Flatbed"
2444 #define OPTVAL_SOURCE_ADF_SIMPLEX "ADF"
2445 #define OPTVAL_SOURCE_ADF_DUPLEX  "ADF Duplex"
2446 
2447 /* Check if option belongs to image enhancement group
2448  */
2449 static inline bool
opt_is_enhancement(int opt)2450 opt_is_enhancement (int opt)
2451 {
2452     return OPT_BRIGHTNESS <= opt && opt <= OPT_NEGATIVE;
2453 }
2454 
2455 /******************** Device Capabilities ********************/
2456 /* Source flags
2457  */
2458 enum {
2459     /* Supported Intents */
2460     DEVCAPS_SOURCE_INTENT_DOCUMENT      = (1 << 3),
2461     DEVCAPS_SOURCE_INTENT_TXT_AND_GRAPH = (1 << 4),
2462     DEVCAPS_SOURCE_INTENT_PHOTO         = (1 << 5),
2463     DEVCAPS_SOURCE_INTENT_PREVIEW       = (1 << 6),
2464 
2465     DEVCAPS_SOURCE_INTENT_ALL =
2466         DEVCAPS_SOURCE_INTENT_DOCUMENT |
2467         DEVCAPS_SOURCE_INTENT_TXT_AND_GRAPH |
2468         DEVCAPS_SOURCE_INTENT_PHOTO |
2469         DEVCAPS_SOURCE_INTENT_PREVIEW,
2470 
2471     /* How resolutions are defined */
2472     DEVCAPS_SOURCE_RES_DISCRETE = (1 << 7), /* Discrete resolutions */
2473     DEVCAPS_SOURCE_RES_RANGE    = (1 << 8), /* Range of resolutions */
2474 
2475     DEVCAPS_SOURCE_RES_ALL =
2476         DEVCAPS_SOURCE_RES_DISCRETE |
2477         DEVCAPS_SOURCE_RES_RANGE,
2478 
2479     /* Miscellaneous flags */
2480     DEVCAPS_SOURCE_HAS_SIZE = (1 << 12), /* max_width, max_height and
2481                                             derivatives are valid */
2482 
2483     /* Protocol dialects */
2484     DEVCAPS_SOURCE_PWG_DOCFMT      = (1 << 13), /* pwg:DocumentFormat */
2485     DEVCAPS_SOURCE_SCAN_DOCFMT_EXT = (1 << 14), /* scan:DocumentFormatExt */
2486 };
2487 
2488 /* Supported image formats
2489  */
2490 #define DEVCAPS_FORMATS_SUPPORTED       \
2491     ((1 << ID_FORMAT_JPEG) |            \
2492      (1 << ID_FORMAT_PNG)  |            \
2493      (1 << ID_FORMAT_BMP))
2494 
2495 /* Supported color modes
2496  *
2497  * Note, currently the only image format we support is JPEG
2498  * With JPEG, ID_COLORMODE_BW1 cannot be supported
2499  */
2500 #define DEVCAPS_COLORMODES_SUPPORTED    \
2501     ((1 << ID_COLORMODE_COLOR) |        \
2502      (1 << ID_COLORMODE_GRAYSCALE))
2503 
2504 /* Source Capabilities (each device may contain multiple sources)
2505  */
2506 typedef struct {
2507     unsigned int flags;                  /* Source flags */
2508     unsigned int colormodes;             /* Set of 1 << ID_COLORMODE */
2509     unsigned int formats;                /* Set of 1 << ID_FORMAT */
2510     SANE_Word    min_wid_px, max_wid_px; /* Min/max width, in pixels */
2511     SANE_Word    min_hei_px, max_hei_px; /* Min/max height, in pixels */
2512     SANE_Word    *resolutions;           /* Discrete resolutions, in DPI */
2513     SANE_Range   res_range;              /* Resolutions range, in DPI */
2514     SANE_Range   win_x_range_mm;         /* Window x range, in mm */
2515     SANE_Range   win_y_range_mm;         /* Window y range, in mm */
2516 } devcaps_source;
2517 
2518 /* Allocate devcaps_source
2519  */
2520 devcaps_source*
2521 devcaps_source_new (void);
2522 
2523 /* Free devcaps_source
2524  */
2525 void
2526 devcaps_source_free (devcaps_source *src);
2527 
2528 /* Clone a source
2529  */
2530 devcaps_source*
2531 devcaps_source_clone (const devcaps_source *src);
2532 
2533 /* Merge two sources, resulting the source that contains
2534  * only capabilities, supported by two input sources
2535  *
2536  * Returns NULL, if sources cannot be merged
2537  */
2538 devcaps_source*
2539 devcaps_source_merge (const devcaps_source *s1, const devcaps_source *s2);
2540 
2541 /* Device Capabilities
2542  */
2543 typedef struct {
2544     /* Fundamental values */
2545     const char     *protocol;            /* Protocol name */
2546     SANE_Word      units;                /* Size units, pixels per inch */
2547 
2548     /* Image compression */
2549     bool           compression_ok;       /* Compression params are supported */
2550     SANE_Range     compression_range;    /* Compression range */
2551     SANE_Word      compression_norm;     /* Normal compression */
2552 
2553     /* Sources */
2554     devcaps_source *src[NUM_ID_SOURCE];  /* Missed sources are NULL */
2555 } devcaps;
2556 
2557 /* Initialize Device Capabilities
2558  */
2559 void
2560 devcaps_init (devcaps *caps);
2561 
2562 /* Cleanup Device Capabilities
2563  */
2564 void
2565 devcaps_cleanup (devcaps *caps);
2566 
2567 /* Reset Device Capabilities into initial state
2568  */
2569 void
2570 devcaps_reset (devcaps *caps);
2571 
2572 /* Dump device capabilities, for debugging
2573  */
2574 void
2575 devcaps_dump (log_ctx *log, devcaps *caps);
2576 
2577 /******************** Device options ********************/
2578 /* Scan options
2579  */
2580 typedef struct {
2581     devcaps                caps;              /* Device capabilities */
2582     SANE_Option_Descriptor desc[NUM_OPTIONS]; /* Option descriptors */
2583     ID_SOURCE              src;               /* Current source */
2584     ID_COLORMODE           colormode_emul;    /* Current "emulated" color mode*/
2585     ID_COLORMODE           colormode_real;    /* Current real color mode*/
2586     SANE_Word              resolution;        /* Current resolution */
2587     SANE_Fixed             tl_x, tl_y;        /* Top-left x/y */
2588     SANE_Fixed             br_x, br_y;        /* Bottom-right x/y */
2589     SANE_Parameters        params;            /* Scan parameters */
2590     SANE_String            *sane_sources;     /* Sources, in SANE format */
2591     SANE_String            *sane_colormodes;  /* Color modes in SANE format */
2592     SANE_Fixed             brightness;        /* -100.0 ... +100.0 */
2593     SANE_Fixed             contrast;          /* -100.0 ... +100.0 */
2594     SANE_Fixed             shadow;            /* 0.0 ... +100.0 */
2595     SANE_Fixed             highlight;         /* 0.0 ... +100.0 */
2596     SANE_Fixed             gamma;             /* Small positive value */
2597     bool                   negative;          /* Flip black and white */
2598 } devopt;
2599 
2600 /* Initialize device options
2601  */
2602 void
2603 devopt_init (devopt *opt);
2604 
2605 /* Cleanup device options
2606  */
2607 void
2608 devopt_cleanup (devopt *opt);
2609 
2610 /* Set default option values. Before call to this function,
2611  * devopt.caps needs to be properly filled.
2612  */
2613 void
2614 devopt_set_defaults (devopt *opt);
2615 
2616 /* Set device option
2617  */
2618 SANE_Status
2619 devopt_set_option (devopt *opt, SANE_Int option, void *value, SANE_Word *info);
2620 
2621 /* Get device option
2622  */
2623 SANE_Status
2624 devopt_get_option (devopt *opt, SANE_Int option, void *value);
2625 
2626 /******************** ZeroConf (device discovery) ********************/
2627 /* Common logging context for device discovery
2628  */
2629 extern log_ctx *zeroconf_log;
2630 
2631 /* zeroconf_device represents a single device
2632  */
2633 typedef struct zeroconf_device zeroconf_device;
2634 
2635 /* zeroconf_endpoint represents a device endpoint
2636  */
2637 typedef struct zeroconf_endpoint zeroconf_endpoint;
2638 struct zeroconf_endpoint {
2639     ID_PROTO          proto;     /* The protocol */
2640     http_uri          *uri;      /* I.e, "http://192.168.1.1:8080/eSCL/" */
2641     zeroconf_endpoint *next;     /* Next endpoint in the list */
2642 };
2643 
2644 /* ZEROCONF_METHOD represents a method how device was discovered
2645  * The same device may be discovered using multiple methods
2646  */
2647 typedef enum {
2648     /* The following findings serve as indirect signs of
2649      * scanner presence in the network
2650      */
2651     ZEROCONF_MDNS_HINT,   /* Hint finding from MDNS world */
2652 
2653     /* The following findings are expected to bring actual
2654      * scanner endpoints
2655      */
2656     ZEROCONF_USCAN_TCP,   /* _uscan._tcp */
2657     ZEROCONF_USCANS_TCP,  /* _uscans._tcp */
2658     ZEROCONF_WSD,         /* WS-Discovery */
2659 
2660     NUM_ZEROCONF_METHOD
2661 } ZEROCONF_METHOD;
2662 
2663 /* zeroconf_finding represents a single device discovery finding.
2664  * Multiple findings can point to the same device, and even
2665  * endpoints may duplicate between findings (say, if the same
2666  * device found using multiple network interfaces or using various
2667  * discovery methods)
2668  *
2669  * zeroconf_finding are bound to method and interface index
2670  */
2671 typedef struct {
2672     ZEROCONF_METHOD   method;     /* Discovery method */
2673     const char        *name;      /* Network-unique name, NULL for WSD */
2674     const char        *model;     /* Model name, may be NULL for
2675                                      WSDD non-scanner devices */
2676     uuid              uuid;       /* Device UUID */
2677     ip_addrset        *addrs;     /* Device addresses */
2678     int               ifindex;    /* Network interface index */
2679     zeroconf_endpoint *endpoints; /* List of endpoints */
2680 
2681     /* The following fields are reserved for zeroconf core
2682      * and should not be used by discovery providers
2683      */
2684     zeroconf_device   *device;    /* Device the finding points to */
2685     ll_node           list_node;  /* Node in device's list of findings */
2686 } zeroconf_finding;
2687 
2688 /* Publish the zeroconf_finding.
2689  *
2690  * Memory, referred by the finding, remains owned by
2691  * caller, and caller is responsible to keep this
2692  * memory valid until zeroconf_finding_withdraw()
2693  * is called
2694  *
2695  * The 'endpoinds' field may be NULL. This mechanism is
2696  * used by WS-Discovery to notify zeroconf that scanning
2697  * for particular UUID has been finished, though without
2698  * success.
2699  */
2700 void
2701 zeroconf_finding_publish (zeroconf_finding *finding);
2702 
2703 /* Withdraw the finding
2704  */
2705 void
2706 zeroconf_finding_withdraw (zeroconf_finding *finding);
2707 
2708 /* Notify zeroconf subsystem that initial scan
2709  * for the method is done
2710  */
2711 void
2712 zeroconf_finding_done (ZEROCONF_METHOD method);
2713 
2714 /* zeroconf_devinfo represents a device information
2715  */
2716 typedef struct {
2717     const char        *ident;     /* Unique ident */
2718     const char        *name;      /* Human-friendly name */
2719     zeroconf_endpoint *endpoints; /* Device endpoints */
2720 } zeroconf_devinfo;
2721 
2722 /* Initialize ZeroConf
2723  */
2724 SANE_Status
2725 zeroconf_init (void);
2726 
2727 /* Cleanup ZeroConf
2728  */
2729 void
2730 zeroconf_cleanup (void);
2731 
2732 /* Get list of devices, in SANE format
2733  */
2734 const SANE_Device**
2735 zeroconf_device_list_get (void);
2736 
2737 /* Free list of devices, returned by zeroconf_device_list_get()
2738  */
2739 void
2740 zeroconf_device_list_free (const SANE_Device **dev_list);
2741 
2742 /* Lookup device by ident (ident is reported as SANE_Device::name)
2743  * by zeroconf_device_list_get())
2744  *
2745  * Caller becomes owner of resources (name and list of endpoints),
2746  * referred by the returned zeroconf_devinfo
2747  *
2748  * Caller must free these resources, using zeroconf_devinfo_free()
2749  */
2750 zeroconf_devinfo*
2751 zeroconf_devinfo_lookup (const char *ident);
2752 
2753 /* Free zeroconf_devinfo, returned by zeroconf_devinfo_lookup()
2754  */
2755 void
2756 zeroconf_devinfo_free (zeroconf_devinfo *devinfo);
2757 
2758 /* Check if initial scan still in progress
2759  */
2760 bool
2761 zeroconf_init_scan (void);
2762 
2763 /* Create new zeroconf_endpoint. Newly created endpoint
2764  * takes ownership of uri string
2765  */
2766 zeroconf_endpoint*
2767 zeroconf_endpoint_new (ID_PROTO proto, http_uri *uri);
2768 
2769 /* Create a copy of zeroconf_endpoint list
2770  */
2771 zeroconf_endpoint*
2772 zeroconf_endpoint_list_copy (const zeroconf_endpoint *list);
2773 
2774 /* Free zeroconf_endpoint list
2775  */
2776 void
2777 zeroconf_endpoint_list_free (zeroconf_endpoint *list);
2778 
2779 /* Sort list of endpoints
2780  */
2781 zeroconf_endpoint*
2782 zeroconf_endpoint_list_sort (zeroconf_endpoint *list);
2783 
2784 /* Sort list of endpoints and remove duplicates
2785  */
2786 zeroconf_endpoint*
2787 zeroconf_endpoint_list_sort_dedup (zeroconf_endpoint *list);
2788 
2789 /* Check if endpoints list contains a non-link-local address
2790  * of the specified address family
2791  */
2792 bool
2793 zeroconf_endpoint_list_has_non_link_local_addr (int af,
2794         const zeroconf_endpoint *list);
2795 
2796 /******************** MDNS Discovery ********************/
2797 /* Called by zeroconf to notify MDNS about initial scan timer expiration
2798  */
2799 void
2800 mdns_initscan_timer_expired (void);
2801 
2802 /* Initialize MDNS
2803  */
2804 SANE_Status
2805 mdns_init (void);
2806 
2807 /* Cleanup MDNS
2808  */
2809 void
2810 mdns_cleanup (void);
2811 
2812 /******************** WS-Discovery ********************/
2813 /* Called by zeroconf to notify wsdd about initial scan timer expiration
2814  */
2815 void
2816 wsdd_initscan_timer_expired (void);
2817 
2818 /* Send WD-Discovery directed probe
2819  */
2820 void
2821 wsdd_send_directed_probe (int ifindex, int af, const void *addr);
2822 
2823 /* Initialize WS-Discovery
2824  */
2825 SANE_Status
2826 wsdd_init (void);
2827 
2828 /* Cleanup WS-Discovery
2829  */
2830 void
2831 wsdd_cleanup (void);
2832 
2833 /******************** Device Management ********************/
2834 /* Type device represents a scanner device
2835  */
2836 typedef struct device device;
2837 
2838 /* Open a device
2839  */
2840 device*
2841 device_open (const char *name, SANE_Status *status);
2842 
2843 /* Close the device
2844  * If log_msg is not NULL, it is written to the device log as late as possible
2845  */
2846 void
2847 device_close (device *dev, const char *log_msg);
2848 
2849 /* Get device's logging context
2850  */
2851 log_ctx*
2852 device_log_ctx (device *dev);
2853 
2854 /* Get option descriptor
2855  */
2856 const SANE_Option_Descriptor*
2857 device_get_option_descriptor (device *dev, SANE_Int option);
2858 
2859 /* Get device option
2860  */
2861 SANE_Status
2862 device_get_option (device *dev, SANE_Int option, void *value);
2863 
2864 /* Set device option
2865  */
2866 SANE_Status
2867 device_set_option (device *dev, SANE_Int option, void *value, SANE_Word *info);
2868 
2869 /* Get current scan parameters
2870  */
2871 SANE_Status
2872 device_get_parameters (device *dev, SANE_Parameters *params);
2873 
2874 SANE_Status
2875 device_start (device *dev);
2876 
2877 /* Cancel scanning operation
2878  */
2879 void
2880 device_cancel (device *dev);
2881 
2882 /* Set I/O mode
2883  */
2884 SANE_Status
2885 device_set_io_mode (device *dev, SANE_Bool non_blocking);
2886 
2887 /* Get select file descriptor
2888  */
2889 SANE_Status
2890 device_get_select_fd (device *dev, SANE_Int *fd);
2891 
2892 /* Read scanned image
2893  */
2894 SANE_Status
2895 device_read (device *dev, SANE_Byte *data, SANE_Int max_len, SANE_Int *len);
2896 
2897 /* Initialize device management
2898  */
2899 SANE_Status
2900 device_management_init (void);
2901 
2902 /* Cleanup device management
2903  */
2904 void
2905 device_management_cleanup (void);
2906 
2907 /******************** Image filters ********************/
2908 /* Type filter represents image filter
2909  */
2910 typedef struct filter filter;
2911 struct filter {
2912     filter      *next;               /* Next filter in a chain */
2913     void        (*dump) (filter *f,  /* Dump filter to the log */
2914         log_ctx *log);
2915     void        (*free) (filter *f); /* Free the filter */
2916     void        (*apply) (filter *f, /* Apply filter to the line of image */
2917         uint8_t *line, size_t size);
2918 };
2919 
2920 /* Free chain of filters
2921  */
2922 void
2923 filter_chain_free (filter *chain);
2924 
2925 /* Push translation table based filter, that handles the
2926  * following options:
2927  *     - brightness
2928  *     - contrast
2929  *     - negative
2930  *
2931  * Returns updated chain
2932  */
2933 filter*
2934 filter_chain_push_xlat (filter *old_chain, const devopt *opt);
2935 
2936 /* Dump filter chain to the log
2937  */
2938 void
2939 filter_chain_dump (filter *chain, log_ctx *log);
2940 
2941 /* Apply filter chain to the image line
2942  */
2943 void
2944 filter_chain_apply (filter *chain, uint8_t *line, size_t size);
2945 
2946 /******************** Scan Protocol handling ********************/
2947 /* PROTO_OP represents operation
2948  */
2949 typedef enum {
2950     PROTO_OP_NONE,    /* No operation */
2951     PROTO_OP_PRECHECK,/* Pre-scan check */
2952     PROTO_OP_SCAN,    /* New scan */
2953     PROTO_OP_LOAD,    /* Load image */
2954     PROTO_OP_CHECK,   /* Check device status */
2955     PROTO_OP_CLEANUP, /* Cleanup after scan */
2956     PROTO_OP_FINISH   /* Finish scanning */
2957 } PROTO_OP;
2958 
2959 /* Get PROTO_OP name, for logging
2960  */
2961 const char*
2962 proto_op_name (PROTO_OP op);
2963 
2964 /* proto_scan_params represents scan parameters
2965  */
2966 typedef struct {
2967     int           x_off, y_off; /* Scan area X/Y offset */
2968     int           wid, hei;     /* Scan area width and height */
2969     int           x_res, y_res; /* X/Y resolution */
2970     ID_SOURCE     src;          /* Desired source */
2971     ID_COLORMODE  colormode;    /* Desired color mode */
2972     ID_FORMAT     format;       /* Image format */
2973 } proto_scan_params;
2974 
2975 /* proto_ctx represents request context
2976  */
2977 typedef struct {
2978     /* Common context */
2979     log_ctx              *log;            /* Logging context */
2980     struct proto_handler *proto;          /* Link to proto_handler */
2981     const devcaps        *devcaps;        /* Device capabilities */
2982     PROTO_OP             op;              /* Current operation */
2983     http_client          *http;           /* HTTP client for sending requests */
2984     http_uri             *base_uri;       /* HTTP base URI for protocol */
2985     http_uri             *base_uri_nozone;/* base_uri without IPv6 zone */
2986     proto_scan_params    params;          /* Scan parameters */
2987     const char           *location;       /* Image location */
2988     unsigned int         images_received; /* Total count of received images */
2989 
2990     /* Extra context for xxx_decode callbacks */
2991     const http_query     *query;    /* Passed to xxx_decode callbacks */
2992 
2993     /* Extra context for status_decode callback */
2994     PROTO_OP             failed_op;          /* Failed operation */
2995     int                  failed_http_status; /* Its HTTP status */
2996     int                  failed_attempt;     /* Retry count, 0-based */
2997 } proto_ctx;
2998 
2999 /* proto_result represents decoded query results
3000  */
3001 typedef struct {
3002     PROTO_OP          next;   /* Next operation */
3003     int               delay;  /* In milliseconds */
3004     SANE_Status       status; /* Job status */
3005     error             err;    /* Error string, may be NULL */
3006     union {
3007         const char *location; /* Image location, protocol-specific */
3008         http_data  *image;    /* Image buffer */
3009     } data;
3010 } proto_result;
3011 
3012 /* proto represents scan protocol implementation
3013  */
3014 typedef struct proto_handler proto_handler;
3015 struct proto_handler {
3016     const char *name;  /* Protocol name (i.e., "eSCL", "WSD", "IPP") */
3017 
3018     /* Free protocol handler
3019      */
3020     void         (*free) (proto_handler *proto);
3021 
3022     /* Query and decode device capabilities
3023      */
3024     http_query*  (*devcaps_query) (const proto_ctx *ctx);
3025     error        (*devcaps_decode) (const proto_ctx *ctx, devcaps *caps);
3026 
3027     /* Create pre-scan check query and decode result
3028      * These callback are optional, set to NULL, if
3029      * they are not implemented by the protocol
3030      * handler
3031      */
3032     http_query*  (*precheck_query) (const proto_ctx *ctx);
3033     proto_result (*precheck_decode) (const proto_ctx *ctx);
3034 
3035     /* Initiate scanning and decode result.
3036      * On success, scan_decode must set ctx->data.location
3037      */
3038     http_query*  (*scan_query) (const proto_ctx *ctx);
3039     proto_result (*scan_decode) (const proto_ctx *ctx);
3040 
3041     /* Initiate image downloading and decode result.
3042      * On success, load_decode must set ctx->data.image
3043      */
3044     http_query*  (*load_query) (const proto_ctx *ctx);
3045     proto_result (*load_decode) (const proto_ctx *ctx);
3046 
3047     /* Request device status and decode result
3048      */
3049     http_query*  (*status_query) (const proto_ctx *ctx);
3050     proto_result (*status_decode) (const proto_ctx *ctx);
3051 
3052     /* Cleanup after scan
3053      */
3054     http_query*  (*cleanup_query) (const proto_ctx *ctx);
3055 
3056     /* Cancel scan in progress
3057      */
3058     http_query*  (*cancel_query) (const proto_ctx *ctx);
3059 };
3060 
3061 /* proto_handler_escl_new creates new eSCL protocol handler
3062  */
3063 proto_handler*
3064 proto_handler_escl_new (void);
3065 
3066 /* proto_handler_wsd_new creates new WSD protocol handler
3067  */
3068 proto_handler*
3069 proto_handler_wsd_new (void);
3070 
3071 /* proto_handler_new creates new protocol handler by protocol ID
3072  */
3073 static inline proto_handler*
proto_handler_new(ID_PROTO proto)3074 proto_handler_new (ID_PROTO proto)
3075 {
3076     switch (proto) {
3077     case ID_PROTO_ESCL:
3078         return proto_handler_escl_new();
3079     case ID_PROTO_WSD:
3080         return proto_handler_wsd_new();
3081     default:
3082         return NULL;
3083     }
3084 }
3085 
3086 /******************** Image decoding ********************/
3087 /* The window withing the image
3088  *
3089  * Note, all sizes and coordinates are in pixels
3090  */
3091 typedef struct {
3092     int x_off, y_off;  /* Top-left corner offset */
3093     int wid, hei;      /* Image width and height */
3094 } image_window;
3095 
3096 /* Image decoder, with virtual methods
3097  */
3098 typedef struct image_decoder image_decoder;
3099 struct image_decoder {
3100     const char *content_type;
3101     void  (*free) (image_decoder *decoder);
3102     error (*begin) (image_decoder *decoder, const void *data, size_t size);
3103     void  (*reset) (image_decoder *decoder);
3104     int   (*get_bytes_per_pixel) (image_decoder *decoder);
3105     void  (*get_params) (image_decoder *decoder, SANE_Parameters *params);
3106     error (*set_window) (image_decoder *decoder, image_window *win);
3107     error (*read_line) (image_decoder *decoder, void *buffer);
3108 };
3109 
3110 /* Create JPEG image decoder
3111  */
3112 image_decoder*
3113 image_decoder_jpeg_new (void);
3114 
3115 /* Create PNG image decoder
3116  */
3117 image_decoder*
3118 image_decoder_png_new (void);
3119 
3120 /* Create BMP image decoder
3121  */
3122 image_decoder*
3123 image_decoder_bmp_new (void);
3124 
3125 /* Free image decoder
3126  */
3127 static inline void
image_decoder_free(image_decoder * decoder)3128 image_decoder_free (image_decoder *decoder)
3129 {
3130     decoder->free(decoder);
3131 }
3132 
3133 /* Get content type
3134  */
3135 static inline const char*
image_content_type(image_decoder * decoder)3136 image_content_type (image_decoder *decoder)
3137 {
3138     return decoder->content_type;
3139 }
3140 
3141 /* Begin image decoding. Decoder may assume that provided data
3142  * buffer remains valid during a whole decoding cycle
3143  */
3144 static inline error
image_decoder_begin(image_decoder * decoder,const void * data,size_t size)3145 image_decoder_begin (image_decoder *decoder, const void *data, size_t size)
3146 {
3147     return decoder->begin(decoder, data, size);
3148 }
3149 
3150 /* Reset image decoder after use. After reset, decoding of the
3151  * another image can be started
3152  */
3153 static inline void
image_decoder_reset(image_decoder * decoder)3154 image_decoder_reset (image_decoder *decoder)
3155 {
3156     decoder->reset(decoder);
3157 }
3158 
3159 /* Get bytes count per pixel
3160  */
3161 static inline int
image_decoder_get_bytes_per_pixel(image_decoder * decoder)3162 image_decoder_get_bytes_per_pixel (image_decoder *decoder)
3163 {
3164     return decoder->get_bytes_per_pixel(decoder);
3165 }
3166 
3167 /* Get image parameters. Can be called at any time between
3168  * image_decoder_begin() and image_decoder_reset()
3169  *
3170  * Decoder must return an actual image parameters, regardless
3171  * of clipping window set by image_decoder_set_window()
3172  */
3173 static inline void
image_decoder_get_params(image_decoder * decoder,SANE_Parameters * params)3174 image_decoder_get_params (image_decoder *decoder, SANE_Parameters *params)
3175 {
3176     decoder->get_params(decoder, params);
3177 }
3178 
3179 /* Set window within the image. Only part of image that fits the
3180  * window needs to be decoded. Decoder may assume that window is
3181  * always within the actual image boundaries
3182  *
3183  * Note, if decoder cannot handle exact window boundaries, it
3184  * it must update window to keep actual values
3185  *
3186  * In particular, if decoder doesn't implement image clipping
3187  * at all, it is safe that decoder will simply set window boundaries
3188  * to contain an entire image
3189  */
3190 static inline error
image_decoder_set_window(image_decoder * decoder,image_window * win)3191 image_decoder_set_window (image_decoder *decoder, image_window *win)
3192 {
3193     return decoder->set_window(decoder, win);
3194 }
3195 
3196 /* Read next line of image. Decoder may safely assume the provided
3197  * buffer is big enough to keep the entire line
3198  */
3199 static inline error
image_decoder_read_line(image_decoder * decoder,void * buffer)3200 image_decoder_read_line (image_decoder *decoder, void *buffer)
3201 {
3202     return decoder->read_line(decoder, buffer);
3203 }
3204 
3205 /******************** Mathematical Functions ********************/
3206 /* Find greatest common divisor of two positive integers
3207  */
3208 SANE_Word
3209 math_gcd (SANE_Word x, SANE_Word y);
3210 
3211 /* Find least common multiple of two positive integers
3212  */
3213 SANE_Word
3214 math_lcm (SANE_Word x, SANE_Word y);
3215 
3216 /* Find min of two words
3217  */
3218 static inline SANE_Word
math_min(SANE_Word a,SANE_Word b)3219 math_min (SANE_Word a, SANE_Word b)
3220 {
3221     return a < b ? a : b;
3222 }
3223 
3224 /* Find max of two words
3225  */
3226 static inline SANE_Word
math_max(SANE_Word a,SANE_Word b)3227 math_max (SANE_Word a, SANE_Word b)
3228 {
3229     return a > b ? a : b;
3230 }
3231 
3232 /* Bound integer within range
3233  */
3234 static inline SANE_Word
math_bound(SANE_Word x,SANE_Word min,SANE_Word max)3235 math_bound (SANE_Word x, SANE_Word min, SANE_Word max)
3236 {
3237     if (x < min) {
3238         return min;
3239     } else if (x > max) {
3240         return max;
3241     } else {
3242         return x;
3243     }
3244 }
3245 
3246 /* Bound double within range
3247  */
3248 static inline double
math_bound_double(double x,double min,double max)3249 math_bound_double (double x, double min, double max)
3250 {
3251     if (x < min) {
3252         return min;
3253     } else if (x > max) {
3254         return max;
3255     } else {
3256         return x;
3257     }
3258 }
3259 
3260 /* Compute x * mul / div, taking in account rounding
3261  * and integer overflow
3262  */
3263 static inline SANE_Word
math_muldiv(SANE_Word x,SANE_Word mul,SANE_Word div)3264 math_muldiv (SANE_Word x, SANE_Word mul, SANE_Word div)
3265 {
3266     int64_t tmp;
3267 
3268     tmp = (int64_t) x * (int64_t) mul;
3269     tmp += div / 2;
3270     tmp /= div;
3271 
3272     return (SANE_Word) tmp;
3273 }
3274 
3275 /* Merge two ranges, if possible
3276  */
3277 bool
3278 math_range_merge (SANE_Range *out, const SANE_Range *r1, const SANE_Range *r2);
3279 
3280 /* Choose nearest integer in range
3281  */
3282 SANE_Word
3283 math_range_fit (const SANE_Range *r, SANE_Word i);
3284 
3285 /* Convert pixels to millimeters, using given resolution
3286  */
3287 static inline SANE_Fixed
math_px2mm_res(SANE_Word px,SANE_Word res)3288 math_px2mm_res (SANE_Word px, SANE_Word res)
3289 {
3290     return SANE_FIX((double) px * 25.4 / res);
3291 }
3292 
3293 /* Convert millimeters to pixels, using given resolution
3294  */
3295 static inline SANE_Word
math_mm2px_res(SANE_Fixed mm,SANE_Word res)3296 math_mm2px_res (SANE_Fixed mm, SANE_Word res)
3297 {
3298     return (SANE_Word) roundl(SANE_UNFIX(mm) * res / 25.4);
3299 }
3300 
3301 /* Format millimeters, for printing
3302  */
3303 char*
3304 math_fmt_mm (SANE_Word mm, char buf[]);
3305 
3306 /* Genrate random 32-bit integer
3307  */
3308 uint32_t
3309 math_rand_u32 (void);
3310 
3311 /* Generate random integer in range [0...max], inclusively
3312  */
3313 uint32_t
3314 math_rand_max (uint32_t max);
3315 
3316 /* Generate random integer in range [min...max], inclusively
3317  */
3318 uint32_t
3319 math_rand_range (uint32_t min, uint32_t max);
3320 
3321 /* Count nonzero bits in 32-bit integer
3322  */
3323 static inline unsigned int
math_popcount(unsigned int n)3324 math_popcount (unsigned int n)
3325 {
3326     unsigned int count = (n & 0x55555555) + ((n >> 1) & 0x55555555);
3327     count = (count & 0x33333333) + ((count >> 2) & 0x33333333);
3328     count = (count & 0x0F0F0F0F) + ((count >> 4) & 0x0F0F0F0F);
3329     count = (count & 0x00FF00FF) + ((count >> 8) & 0x00FF00FF);
3330     return (count & 0x0000FFFF) + ((count >> 16) & 0x0000FFFF);
3331 }
3332 
3333 /******************** Logging ********************/
3334 /* Initialize logging
3335  *
3336  * No log messages should be generated before this call
3337  */
3338 void
3339 log_init (void);
3340 
3341 /* Cleanup logging
3342  *
3343  * No log messages should be generated after this call
3344  */
3345 void
3346 log_cleanup (void);
3347 
3348 /* Notify logger that configuration is loaded and
3349  * logger can configure itself
3350  *
3351  * This is safe to generate log messages before log_configure()
3352  * is called. These messages will be buffered, and after
3353  * logger is configured, either written or abandoned, depending
3354  * on configuration
3355  */
3356 void
3357 log_configure (void);
3358 
3359 /* log_ctx_new creates new logging context
3360  * If parent != NULL, new logging context will have its own prefix,
3361  * but trace file will be inherited from parent
3362  */
3363 log_ctx*
3364 log_ctx_new (const char *name, log_ctx *parent);
3365 
3366 /* log_ctx_free destroys logging context
3367  */
3368 void
3369 log_ctx_free (log_ctx *log);
3370 
3371 /* Get protocol trace associated with logging context
3372  */
3373 trace*
3374 log_ctx_trace (log_ctx *log);
3375 
3376 /* Write a debug message.
3377  */
3378 void
3379 log_debug (log_ctx *log, const char *fmt, ...);
3380 
3381 /* Write a protocol trace message
3382  */
3383 void
3384 log_trace (log_ctx *log, const char *fmt, ...);
3385 
3386 /* Write a block of data into protocol trace
3387  */
3388 void
3389 log_trace_data (log_ctx *log, const char *content_type,
3390         const void *bytes, size_t size);
3391 
3392 /* Write an error message and terminate a program.
3393  */
3394 void
3395 log_panic (log_ctx *log, const char *fmt, ...);
3396 
3397 /* Panic if assertion fails
3398  */
3399 #define log_assert(log,expr)                                            \
3400      do {                                                               \
3401          if (!(expr)) {                                                 \
3402              log_panic(log,"file %s: line %d (%s): assertion failed: (%s)",\
3403                      __FILE__, __LINE__, __PRETTY_FUNCTION__, #expr);   \
3404              __builtin_unreachable();                                   \
3405          }                                                              \
3406      } while (0)
3407 
3408 /* Panic if this code is reached
3409  */
3410 #define log_internal_error(log)                                         \
3411      do {                                                               \
3412          log_panic(log,"file %s: line %d (%s): internal error",         \
3413                  __FILE__, __LINE__, __PRETTY_FUNCTION__);              \
3414          __builtin_unreachable();                                       \
3415      } while (0)
3416 
3417 /******************** Initialization/Cleanup ********************/
3418 /* AIRSCAN_INIT_FLAGS represents airscan_init() flags
3419  */
3420 typedef enum {
3421     AIRSCAN_INIT_NO_CONF        = (1 << 0),     // Don't load configuration
3422     AIRSCAN_INIT_NO_THREAD      = (1 << 1)      // Don't start worker thread
3423 } AIRSCAN_INIT_FLAGS;
3424 
3425 /* Initialize airscan.
3426  * If log_msg is not NULL, it is written to the log early
3427  */
3428 SANE_Status
3429 airscan_init (AIRSCAN_INIT_FLAGS flags, const char *log_msg);
3430 
3431 /* Cleanup airscan
3432  * If log_msg is not NULL, it is written to the log as late as possible
3433  */
3434 void
3435 airscan_cleanup (const char *log_msg);
3436 
3437 #ifdef  __cplusplus
3438 };
3439 #endif
3440 
3441 #endif
3442 /* vim:ts=8:sw=4:et
3443  */
3444