1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2019 Touboul Nathane
4    Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com>
5 
6    This file is part of the SANE package.
7 
8    SANE is free software; you can redistribute it and/or modify it under
9    the terms of the GNU General Public License as published by the Free
10    Software Foundation; either version 3 of the License, or (at your
11    option) any later version.
12 
13    SANE is distributed in the hope that it will be useful, but WITHOUT
14    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16    for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with sane; see the file COPYING.
20    If not, see <https://www.gnu.org/licenses/>.
21 
22    This file implements a SANE backend for eSCL scanners.  */
23 
24 #define DEBUG_DECLARE_ONLY
25 #include "../include/sane/config.h"
26 
27 #include "escl.h"
28 
29 #include <stdlib.h>
30 #include <string.h>
31 
32 static size_t
write_callback(void __sane_unused__ * str,size_t __sane_unused__ size,size_t nmemb,void __sane_unused__ * userp)33 write_callback(void __sane_unused__*str,
34                size_t __sane_unused__ size,
35                size_t nmemb,
36                void __sane_unused__ *userp)
37 {
38     return nmemb;
39 }
40 
41 /**
42  * \fn void escl_scanner(const ESCL_Device *device, char *result)
43  * \brief Function that resets the scanner after each scan, using curl.
44  *        This function is called in the 'sane_cancel' function.
45  */
46 void
escl_scanner(const ESCL_Device * device,char * result)47 escl_scanner(const ESCL_Device *device, char *result)
48 {
49     CURL *curl_handle = NULL;
50     const char *scan_jobs = "/eSCL/ScanJobs";
51     const char *scanner_start = "/NextDocument";
52     char scan_cmd[PATH_MAX] = { 0 };
53     int i = 0;
54     long answer = 0;
55 
56     if (device == NULL || result == NULL)
57         return;
58 CURL_CALL:
59     curl_handle = curl_easy_init();
60     if (curl_handle != NULL) {
61         snprintf(scan_cmd, sizeof(scan_cmd), "%s%s%s",
62                  scan_jobs, result, scanner_start);
63         escl_curl_url(curl_handle, device, scan_cmd);
64         curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback);
65         if (curl_easy_perform(curl_handle) == CURLE_OK) {
66             curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &answer);
67             i++;
68             if (i >= 15) return;
69         }
70         curl_easy_cleanup(curl_handle);
71         if (SANE_STATUS_GOOD != escl_status(device,
72                                             PLATEN,
73                                             NULL,
74                                             NULL))
75             goto CURL_CALL;
76     }
77 }
78