diff options
| author | Jörg Frings-Fürst <debian@jff.email> | 2022-02-01 15:26:02 +0100 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff.email> | 2022-02-01 15:26:02 +0100 | 
| commit | 5de81480e84023d91763d89e4523de88df42c194 (patch) | |
| tree | cb83e4c8216cf0e8bcaa17a6f2cb64cf4d7f469a /backend/escl | |
| parent | 97e55bdc5cdf59304af739e65f416320bcbcf599 (diff) | |
| parent | 8e5d399808d2270ae9d56c96560a021e594d18a4 (diff) | |
Merge branch 'feature/upstream' into develop
Diffstat (limited to 'backend/escl')
| -rw-r--r-- | backend/escl/escl.c | 45 | ||||
| -rw-r--r-- | backend/escl/escl.h | 4 | ||||
| -rw-r--r-- | backend/escl/escl_capabilities.c | 111 | ||||
| -rw-r--r-- | backend/escl/escl_devices.c | 10 | ||||
| -rw-r--r-- | backend/escl/escl_jpeg.c | 53 | ||||
| -rw-r--r-- | backend/escl/escl_newjob.c | 12 | ||||
| -rw-r--r-- | backend/escl/escl_reset.c | 10 | ||||
| -rw-r--r-- | backend/escl/escl_scan.c | 10 | ||||
| -rw-r--r-- | backend/escl/escl_status.c | 2 | 
9 files changed, 216 insertions, 41 deletions
| diff --git a/backend/escl/escl.c b/backend/escl/escl.c index bb62219..5f02ec8 100644 --- a/backend/escl/escl.c +++ b/backend/escl/escl.c @@ -432,7 +432,8 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line,      int port = 0;      SANE_Status status;      static ESCL_Device *escl_device = NULL; - +    if (*line == '#') return SANE_STATUS_GOOD; +    if (!strncmp(line, "pdfblacklist", 12)) return SANE_STATUS_GOOD;      if (strncmp(line, "device", 6) == 0) {          char *name_str = NULL;          char *opt_model = NULL; @@ -1135,6 +1136,37 @@ finish_hack:    fclose(fp);  } +static char* +_get_blacklist_pdf(void) +{ +  FILE *fp; +  char *blacklist = NULL; +  SANE_Char line[PATH_MAX]; + +  /* open configuration file */ +  fp = sanei_config_open (ESCL_CONFIG_FILE); +  if (!fp) +    { +      DBG (2, "_get_blacklit: couldn't access %s\n", ESCL_CONFIG_FILE); +      DBG (3, "_get_blacklist: exit\n"); +    } + +  /* loop reading the configuration file, all line beginning by "option " are +   * parsed for value to store in configuration structure, other line are +   * used are device to try to attach +   */ +  while (sanei_config_read (line, PATH_MAX, fp)) +    { +       if (!strncmp(line, "pdfblacklist", 12)) { +          blacklist = strdup(line); +	  goto finish_; +       } +    } +finish_: +  DBG (3, "_get_blacklist_pdf: finish\n"); +  fclose(fp); +  return blacklist; +}  /** @@ -1149,6 +1181,7 @@ finish_hack:  SANE_Status  sane_open(SANE_String_Const name, SANE_Handle *h)  { +    char *blacklist = NULL;      DBG (10, "escl sane_open\n");      SANE_Status status;      escl_sane_t *handler = NULL; @@ -1173,7 +1206,8 @@ sane_open(SANE_String_Const name, SANE_Handle *h)          return (SANE_STATUS_NO_MEM);      }      handler->device = device;  // Handler owns device now. -    handler->scanner = escl_capabilities(device, &status); +    blacklist = _get_blacklist_pdf(); +    handler->scanner = escl_capabilities(device, blacklist, &status);      if (status != SANE_STATUS_GOOD) {          escl_free_handler(handler);          return (status); @@ -1222,9 +1256,11 @@ sane_cancel(SANE_Handle h)      }      handler->scanner->work = SANE_FALSE;      handler->cancel = SANE_TRUE; -    escl_scanner(handler->device, handler->result); +    escl_scanner(handler->device, handler->scanner->scanJob, handler->result);      free(handler->result);      handler->result = NULL; +    free(handler->scanner->scanJob); +    handler->scanner->scanJob = NULL;  }  /** @@ -1381,6 +1417,7 @@ sane_control_option(SANE_Handle h, SANE_Int n, SANE_Action a, void *v, SANE_Int  	    break;  	case OPT_RESOLUTION:              handler->val[n].w = _get_resolution(handler, (int)(*(SANE_Word *) v)); +	    handler->scanner->caps[handler->scanner->source].default_resolution = handler->val[n].w;  	    if (i)  		*i |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT;  	    break; @@ -1591,7 +1628,7 @@ sane_start(SANE_Handle h)           return SANE_STATUS_NO_DOCS;         }      } -    status = escl_scan(handler->scanner, handler->device, handler->result); +    status = escl_scan(handler->scanner, handler->device, handler->scanner->scanJob, handler->result);      if (status != SANE_STATUS_GOOD)         return (status);      if (!strcmp(handler->scanner->caps[handler->scanner->source].default_format, "image/jpeg")) diff --git a/backend/escl/escl.h b/backend/escl/escl.h index 67b11c7..142b4b4 100644 --- a/backend/escl/escl.h +++ b/backend/escl/escl.h @@ -156,6 +156,7 @@ typedef struct capabilities      SANE_String_Const *Sources;      int SourcesSize;      FILE *tmp; +    char *scanJob;      unsigned char *img_data;      long img_size;      long img_read; @@ -230,6 +231,7 @@ SANE_Status escl_status(const ESCL_Device *device,                          SANE_Status *job);  capabilities_t *escl_capabilities(ESCL_Device *device, +                                  char *blacklist,                                    SANE_Status *status);  char *escl_newjob(capabilities_t *scanner, @@ -238,9 +240,11 @@ char *escl_newjob(capabilities_t *scanner,  SANE_Status escl_scan(capabilities_t *scanner,                        const ESCL_Device *device, +                      char *scanJob,                        char *result);  void escl_scanner(const ESCL_Device *device, +                  char *scanJob,                    char *result);  typedef void CURL; diff --git a/backend/escl/escl_capabilities.c b/backend/escl/escl_capabilities.c index db194f9..7422896 100644 --- a/backend/escl/escl_capabilities.c +++ b/backend/escl/escl_capabilities.c @@ -40,6 +40,25 @@ struct cap      size_t size;  }; +static size_t +header_callback(void *str, size_t size, size_t nmemb, void *userp) +{ +    struct cap *header = (struct cap *)userp; +    size_t realsize = size * nmemb; +    char *content = realloc(header->memory, header->size + realsize + 1); + +    if (content == NULL) { +        DBG( 1, "Not enough memory (realloc returned NULL)\n"); +        return (0); +    } +    header->memory = content; +    memcpy(&(header->memory[header->size]), str, realsize); +    header->size = header->size + realsize; +    header->memory[header->size] = 0; +    return (realsize); +} + +  /**   * \fn static SANE_String_Const convert_elements(SANE_String_Const str)   * \brief Function that converts the 'color modes' of the scanner (color/gray) to be understood by SANE. @@ -182,10 +201,10 @@ find_valor_of_array_variables(xmlNode *node, capabilities_t *scanner, int type)  {      const char *name = (const char *)node->name;      if (strcmp(name, "ColorMode") == 0) { -		const char *color = (SANE_String_Const)xmlNodeGetContent(node); -		if (type == PLATEN || strcmp(color, "BlackAndWhite1")) +	const char *color = (SANE_String_Const)xmlNodeGetContent(node); +        if (type == PLATEN || strcmp(color, "BlackAndWhite1"))            scanner->caps[type].ColorModes = char_to_array(scanner->caps[type].ColorModes, &scanner->caps[type].ColorModesSize, (SANE_String_Const)xmlNodeGetContent(node), 1); -	} +    }      else if (strcmp(name, "ContentType") == 0)          scanner->caps[type].ContentTypes = char_to_array(scanner->caps[type].ContentTypes, &scanner->caps[type].ContentTypesSize, (SANE_String_Const)xmlNodeGetContent(node), 0);      else if (strcmp(name, "DocumentFormat") == 0) @@ -385,6 +404,16 @@ find_true_variables(xmlNode *node, capabilities_t *scanner, int type)      return (0);  } +static char* +replace_char(char* str, char find, char replace){ +    char *current_pos = strchr(str,find); +    while (current_pos) { +        *current_pos = replace; +        current_pos = strchr(current_pos,find); +    } +    return str; +} +  /**   * \fn static int print_xml_c(xmlNode *node, capabilities_t *scanner)   * \brief Function that browses the xml file, node by node. @@ -454,6 +483,37 @@ _reduce_color_modes(capabilities_t *scanner)      }  } +static void +_delete_pdf(capabilities_t *scanner) +{ +    int type = 0; +    for (type = 0; type < 3; type++) { +         if (scanner->caps[type].ColorModesSize) { +	     if (scanner->caps[type].default_format) { +		 scanner->caps[type].have_pdf = -1; +		 if (!strcmp(scanner->caps[type].default_format, "application/pdf")) { +	             free(scanner->caps[type].default_format); +		     if (scanner->caps[type].have_tiff > -1) +	                scanner->caps[type].default_format = strdup("image/tiff"); +		     else if (scanner->caps[type].have_png > -1) +	                scanner->caps[type].default_format = strdup("image/png"); +		     else if (scanner->caps[type].have_jpeg > -1) +	                scanner->caps[type].default_format = strdup("image/jpeg"); +		 } +	         free(scanner->caps[type].ColorModes); +		 scanner->caps[type].ColorModes = NULL; +	         scanner->caps[type].ColorModesSize = 0; +                 scanner->caps[type].ColorModes = char_to_array(scanner->caps[type].ColorModes, +		             &scanner->caps[type].ColorModesSize, +		    	     (SANE_String_Const)SANE_VALUE_SCAN_MODE_GRAY, 0); +                 scanner->caps[type].ColorModes = char_to_array(scanner->caps[type].ColorModes, +		             &scanner->caps[type].ColorModesSize, +			     (SANE_String_Const)SANE_VALUE_SCAN_MODE_COLOR, 0); +	     } +         } +    } +} +  /**   * \fn capabilities_t *escl_capabilities(const ESCL_Device *device, SANE_Status *status)   * \brief Function that finally recovers all the capabilities of the scanner, using curl. @@ -463,15 +523,17 @@ _reduce_color_modes(capabilities_t *scanner)   * \return scanner (the structure that stocks all the capabilities elements)   */  capabilities_t * -escl_capabilities(ESCL_Device *device, SANE_Status *status) +escl_capabilities(ESCL_Device *device, char *blacklist, SANE_Status *status)  {      capabilities_t *scanner = (capabilities_t*)calloc(1, sizeof(capabilities_t));      CURL *curl_handle = NULL;      struct cap *var = NULL; +    struct cap *header = NULL;      xmlDoc *data = NULL;      xmlNode *node = NULL;      int i = 0;      const char *scanner_capabilities = "/eSCL/ScannerCapabilities"; +    SANE_Bool use_pdf = SANE_TRUE;      *status = SANE_STATUS_GOOD;      if (device == NULL) @@ -481,11 +543,22 @@ escl_capabilities(ESCL_Device *device, SANE_Status *status)          *status = SANE_STATUS_NO_MEM;      var->memory = malloc(1);      var->size = 0; +    header = (struct cap *)calloc(1, sizeof(struct cap)); +    if (header == NULL) +        *status = SANE_STATUS_NO_MEM; +    header->memory = malloc(1); +    header->size = 0;      curl_handle = curl_easy_init();      escl_curl_url(curl_handle, device, scanner_capabilities);      curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, memory_callback_c);      curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)var); +    curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, header_callback); +    curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, (void *)header); +    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); +    curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);      CURLcode res = curl_easy_perform(curl_handle); +    if (res == CURLE_OK) +        DBG( 1, "Create NewJob : the scanner header responded : [%s]\n", header->memory);      if (res != CURLE_OK) {          DBG( 1, "The scanner didn't respond: %s\n", curl_easy_strerror(res));          *status = SANE_STATUS_INVAL; @@ -503,18 +576,46 @@ escl_capabilities(ESCL_Device *device, SANE_Status *status)          goto clean;      } +    if (device->hack && +        header && +        header->memory && +        strstr(header->memory, "Server: HP_Compact_Server")) +        device->hack = curl_slist_append(NULL, "Host: localhost"); +      scanner->source = 0;      scanner->Sources = (SANE_String_Const *)malloc(sizeof(SANE_String_Const) * 4);      for (i = 0; i < 4; i++)         scanner->Sources[i] = NULL;      print_xml_c(node, device, scanner, -1); -    _reduce_color_modes(scanner); +    DBG (3, "1-blacklist_pdf: %s\n", (use_pdf ? "TRUE" : "FALSE") ); +    if (device->model_name != NULL) { +        if (strcasestr(device->model_name, "MFC-J985DW")) { +           DBG (3, "blacklist_pdf: device not support PDF\n"); +           use_pdf = SANE_FALSE; +        } +	else if (blacklist) { +           char *model = strdup(device->model_name); +           replace_char(model, ' ', '_'); +	   if (strcasestr(blacklist, model)) { +               use_pdf = SANE_FALSE; +	   } +	   free(model); +	} +    } +    DBG (3, "1-blacklist_pdf: %s\n", (use_pdf ? "TRUE" : "FALSE") ); +    if (use_pdf) +       _reduce_color_modes(scanner); +    else +       _delete_pdf(scanner);  clean:      xmlFreeDoc(data);  clean_data:      xmlCleanupParser();      xmlMemoryDump();      curl_easy_cleanup(curl_handle); +    if (header) +      free(header->memory); +    free(header);      if (var)        free(var->memory);      free(var); diff --git a/backend/escl/escl_devices.c b/backend/escl/escl_devices.c index 3ca28de..92e064b 100644 --- a/backend/escl/escl_devices.c +++ b/backend/escl/escl_devices.c @@ -74,6 +74,7 @@ resolve_callback(AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interfac          avahi_address_snprint(a, sizeof(a), address);          t = avahi_string_list_to_string(txt);          if (strstr(t, "\"rs=eSCL\"") || strstr(t, "\"rs=/eSCL\"")) { +	    char ip_add[PATH_MAX] = {0};  	    s = avahi_string_list_find(txt, "is");  	    if (s && s->size > 3)  	       is = (const char*)s->text + 3; @@ -84,7 +85,14 @@ resolve_callback(AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interfac  	       uuid = (const char*)s->text + 5;  	    else  	       uuid = (const char*)NULL; -            escl_device_add(port, name, a, is, uuid, (char*)type); +            DBG (10, "resolve_callback [%s]\n", a); +            if (strstr(a, "127.0.0.1") != NULL) { +               snprintf(ip_add, sizeof(ip_add), "%s", "localhost"); +               DBG (10,"resolve_callback fix redirect [localhost]\n"); +            } +            else +               snprintf(ip_add, sizeof(ip_add), "%s", a); +            escl_device_add(port, name, ip_add, is, uuid, (char*)type);          }      }  } diff --git a/backend/escl/escl_jpeg.c b/backend/escl/escl_jpeg.c index 651e7c5..1dd3ec9 100644 --- a/backend/escl/escl_jpeg.c +++ b/backend/escl/escl_jpeg.c @@ -192,34 +192,41 @@ get_JPEG_data(capabilities_t *scanner, int *width, int *height, int *bps)      cinfo.out_color_space = JCS_RGB;      cinfo.quantize_colors = FALSE;      jpeg_calc_output_dimensions(&cinfo); -    if (cinfo.output_width < (unsigned int)scanner->caps[scanner->source].width) -          scanner->caps[scanner->source].width = cinfo.output_width; -    if (scanner->caps[scanner->source].pos_x < 0) -          scanner->caps[scanner->source].pos_x = 0; - -    if (cinfo.output_height < (unsigned int)scanner->caps[scanner->source].height) -           scanner->caps[scanner->source].height = cinfo.output_height; -    if (scanner->caps[scanner->source].pos_y < 0) -          scanner->caps[scanner->source].pos_y = 0; +    double ratio = (double)cinfo.output_width / (double)scanner->caps[scanner->source].width; +    int rw = (int)((double)scanner->caps[scanner->source].width * ratio); +    int rh = (int)((double)scanner->caps[scanner->source].height * ratio); +    int rx = (int)((double)scanner->caps[scanner->source].pos_x * ratio); +    int ry = (int)((double)scanner->caps[scanner->source].pos_y * ratio); + + +    if (cinfo.output_width < (unsigned int)rw) +          rw = cinfo.output_width; +    if (rx < 0) +          rx = 0; + +    if (cinfo.output_height < (unsigned int)rh) +          rh = cinfo.output_height; +    if (ry < 0) +          ry = 0;      DBG(10, "1-JPEF Geometry [%dx%d|%dx%d]\n", -	        scanner->caps[scanner->source].pos_x, -	        scanner->caps[scanner->source].pos_y, -	        scanner->caps[scanner->source].width, -	        scanner->caps[scanner->source].height); -    x_off = scanner->caps[scanner->source].pos_x; -    if (x_off > (unsigned int)scanner->caps[scanner->source].width) { -       w = scanner->caps[scanner->source].width; +	        rx, +	        ry, +	        rw, +	        rh); +    x_off = rx; +    if (x_off > (unsigned int)rw) { +       w = rw;         x_off = 0;      }      else -       w = scanner->caps[scanner->source].width - x_off; -    y_off = scanner->caps[scanner->source].pos_y; -    if(y_off > (unsigned int)scanner->caps[scanner->source].height) { -       h = scanner->caps[scanner->source].height; +       w = rw - x_off; +    y_off = ry; +    if(y_off > (unsigned int)rh) { +       h = rh;         y_off = 0;      }      else -       h = scanner->caps[scanner->source].height - y_off; +       h = rh - y_off;      DBG(10, "2-JPEF Geometry [%dx%d|%dx%d]\n",  	        x_off,  	        y_off, @@ -242,7 +249,7 @@ get_JPEG_data(capabilities_t *scanner, int *width, int *height, int *bps)      if (y_off > 0)          jpeg_skip_scanlines(&cinfo, y_off);      pos = 0; -    while (cinfo.output_scanline < (unsigned int)scanner->caps[scanner->source].height) { +    while (cinfo.output_scanline < (unsigned int)rh) {          rowptr[0] = (JSAMPROW)surface + (lineSize * pos); // ..cinfo.output_scanline);          jpeg_read_scanlines(&cinfo, rowptr, (JDIMENSION) 1);         pos++; @@ -253,7 +260,7 @@ get_JPEG_data(capabilities_t *scanner, int *width, int *height, int *bps)      *width = w;      *height = h;      *bps = cinfo.output_components; -    jpeg_finish_decompress(&cinfo); +    // jpeg_finish_decompress(&cinfo);      jpeg_destroy_decompress(&cinfo);      fclose(scanner->tmp);      scanner->tmp = NULL; diff --git a/backend/escl/escl_newjob.c b/backend/escl/escl_newjob.c index 24bfbc9..98a953f 100644 --- a/backend/escl/escl_newjob.c +++ b/backend/escl/escl_newjob.c @@ -277,6 +277,8 @@ wake_up_device:          curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, upload->size);          curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, download_callback);          curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, (void *)download); +        curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); +        curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);          CURLcode res = curl_easy_perform(curl_handle);          if (res != CURLE_OK) {              DBG( 1, "Create NewJob : the scanner responded incorrectly: %s\n", curl_easy_strerror(res)); @@ -296,7 +298,17 @@ wake_up_device:                            result = strdup(location);                            DBG( 1, "Create NewJob : %s\n", result);                            *temporary = '\n'; +                          *location = '\0'; +                          location = strrchr(tmp_location,'/');                            wakup_count = 0; +                          if (location) { +                             location++; +                             scanner->scanJob = strdup(location); +                             DBG( 1, "Full location header [%s]\n", scanner->scanJob); +                          } +                          else +                             scanner->scanJob = strdup("ScanJobs"); +                          *location = '/';                         }                      }                      if (result == NULL) { diff --git a/backend/escl/escl_reset.c b/backend/escl/escl_reset.c index 7494dda..95e3f2d 100644 --- a/backend/escl/escl_reset.c +++ b/backend/escl/escl_reset.c @@ -44,10 +44,10 @@ write_callback(void __sane_unused__*str,   *        This function is called in the 'sane_cancel' function.   */  void -escl_scanner(const ESCL_Device *device, char *result) +escl_scanner(const ESCL_Device *device, char *scanJob, char *result)  {      CURL *curl_handle = NULL; -    const char *scan_jobs = "/eSCL/ScanJobs"; +    const char *scan_jobs = "/eSCL/";      const char *scanner_start = "/NextDocument";      char scan_cmd[PATH_MAX] = { 0 };      int i = 0; @@ -58,10 +58,12 @@ escl_scanner(const ESCL_Device *device, char *result)  CURL_CALL:      curl_handle = curl_easy_init();      if (curl_handle != NULL) { -        snprintf(scan_cmd, sizeof(scan_cmd), "%s%s%s", -                 scan_jobs, result, scanner_start); +        snprintf(scan_cmd, sizeof(scan_cmd), "%s%s%s%s", +                 scan_jobs, scanJob, result, scanner_start);          escl_curl_url(curl_handle, device, scan_cmd);          curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback); +        curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); +        curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);          if (curl_easy_perform(curl_handle) == CURLE_OK) {              curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &answer);              i++; diff --git a/backend/escl/escl_scan.c b/backend/escl/escl_scan.c index 53bd438..3350c83 100644 --- a/backend/escl/escl_scan.c +++ b/backend/escl/escl_scan.c @@ -57,10 +57,10 @@ write_callback(void *str, size_t size, size_t nmemb, void *userp)   * \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL)   */  SANE_Status -escl_scan(capabilities_t *scanner, const ESCL_Device *device, char *result) +escl_scan(capabilities_t *scanner, const ESCL_Device *device, char *scanJob, char *result)  {      CURL *curl_handle = NULL; -    const char *scan_jobs = "/eSCL/ScanJobs"; +    const char *scan_jobs = "/eSCL/";      const char *scanner_start = "/NextDocument";      char scan_cmd[PATH_MAX] = { 0 };      SANE_Status status = SANE_STATUS_GOOD; @@ -70,10 +70,12 @@ escl_scan(capabilities_t *scanner, const ESCL_Device *device, char *result)      scanner->real_read = 0;      curl_handle = curl_easy_init();      if (curl_handle != NULL) { -        snprintf(scan_cmd, sizeof(scan_cmd), "%s%s%s", -                 scan_jobs, result, scanner_start); +        snprintf(scan_cmd, sizeof(scan_cmd), "%s%s%s%s", +                 scan_jobs, scanJob, result, scanner_start);          escl_curl_url(curl_handle, device, scan_cmd);          curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback); +        curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); +        curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);          if (scanner->tmp)              fclose(scanner->tmp);          scanner->tmp = tmpfile(); diff --git a/backend/escl/escl_status.c b/backend/escl/escl_status.c index a68f6ea..1f848a2 100644 --- a/backend/escl/escl_status.c +++ b/backend/escl/escl_status.c @@ -220,6 +220,8 @@ reload:      escl_curl_url(curl_handle, device, scanner_status);      curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, memory_callback_s);      curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)var); +    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L); +    curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);      CURLcode res = curl_easy_perform(curl_handle);      if (res != CURLE_OK) {          DBG( 1, "The scanner didn't respond: %s\n", curl_easy_strerror(res)); | 
