kopia lustrzana https://gitlab.com/sane-project/backends
epsonds: add additional files.
rodzic
aa4d78d2a1
commit
2211322f81
|
@ -0,0 +1,212 @@
|
|||
#define DEBUG_DECLARE_ONLY
|
||||
|
||||
#include "epsonds.h"
|
||||
#include "epsonds-net.h"
|
||||
#include "epsonds-tcp.h"
|
||||
#include "sanei_tcp.h"
|
||||
#include "sane/config.h"
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
|
||||
#include "sane/sanei_debug.h"
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
typedef struct epsonds_scanner epsonds_scanner;
|
||||
|
||||
SANE_Status epsonds_tcp_open(epsonds_scanner* s, const char *host, int port) {
|
||||
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
|
||||
if(s == NULL || host == NULL) {
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
status = sanei_tcp_open(&s->hw->name[4], 1865, &s->fd);
|
||||
if (status == SANE_STATUS_GOOD) {
|
||||
|
||||
ssize_t read;
|
||||
struct timeval tv;
|
||||
unsigned char buf[5];
|
||||
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
setsockopt(s->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
|
||||
|
||||
s->netlen = 0;
|
||||
DBG(5, "host = %s\n", &s->hw->name[4]);
|
||||
|
||||
DBG(32, "awaiting welcome message\n");
|
||||
/* the scanner sends a kind of welcome msg */
|
||||
// XXX check command type, answer to connect is 0x80
|
||||
read = eds_recv(s, buf, 5, &status);
|
||||
if (read != 5) {
|
||||
sanei_tcp_close(s->fd);
|
||||
s->fd = -1;
|
||||
status = SANE_STATUS_INVAL;
|
||||
}
|
||||
else {
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
#ifdef HAVE_OPENSSL
|
||||
SSL_CTX *ssl = NULL;
|
||||
BIO *bio = NULL;
|
||||
crypt_context *crypt_ctx = NULL;
|
||||
|
||||
crypt_ctx = (crypt_context*)malloc(sizeof(crypt_context));
|
||||
if(crypt_ctx == NULL) {
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
ssl = SSL_CTX_new( TLS_client_method());
|
||||
if (ssl == NULL) {
|
||||
free(crypt_ctx);
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
|
||||
bio = BIO_new_ssl_connect(ssl);
|
||||
if (bio == NULL) {
|
||||
SSL_CTX_free(ssl);
|
||||
free(crypt_ctx);
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
char port_s[5];
|
||||
snprintf(port_s, sizeof(port_s), "%d", port);
|
||||
|
||||
DBG(1, "port_s=%s", port_s);
|
||||
BIO_set_conn_hostname(bio, host);
|
||||
BIO_set_conn_port(bio, port_s);
|
||||
|
||||
BIO_set_ssl_renegotiate_timeout(bio, 2);
|
||||
|
||||
if (BIO_do_connect(bio) <= 0) {
|
||||
BIO_free_all(bio);
|
||||
SSL_CTX_free(ssl);
|
||||
free(crypt_ctx);
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
crypt_ctx->bio = bio;
|
||||
crypt_ctx->ssl = ssl;
|
||||
|
||||
s -> cryptContext = crypt_ctx;
|
||||
|
||||
read = eds_recv(s, buf, 5, &status);
|
||||
if (read != 5) {
|
||||
epsonds_tcp_close(s);
|
||||
s->fd = -1;
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void epsonds_tcp_close(epsonds_scanner* s) {
|
||||
#ifdef HAVE_OPENSSL
|
||||
if(s->cryptContext == NULL) {
|
||||
sanei_tcp_close(s->fd);
|
||||
}
|
||||
else {
|
||||
BIO_free_all(s->cryptContext->bio);
|
||||
s->cryptContext->bio = NULL;
|
||||
SSL_CTX_free(s->cryptContext->ssl);
|
||||
s->cryptContext->ssl= NULL;
|
||||
free(s->cryptContext);
|
||||
s->cryptContext = NULL;
|
||||
}
|
||||
#else
|
||||
sanei_tcp_close(s->fd);
|
||||
#endif
|
||||
s->fd = -1;
|
||||
}
|
||||
|
||||
ssize_t epsonds_tcp_read(epsonds_scanner* s, unsigned char *buf, ssize_t wanted) {
|
||||
ssize_t read = -1;
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
if(s->cryptContext == NULL) {
|
||||
int ready;
|
||||
fd_set readable;
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = 10;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&readable);
|
||||
FD_SET(s->fd, &readable);
|
||||
|
||||
ready = select(s->fd + 1, &readable, NULL, NULL, &tv);
|
||||
if (ready > 0) {
|
||||
read = sanei_tcp_read(s->fd, buf, wanted);
|
||||
} else {
|
||||
DBG(15, "%s: select failed: %d\n", __func__, ready);
|
||||
}
|
||||
}
|
||||
else {
|
||||
size_t bytes_recv = 0;
|
||||
ssize_t rc = 1;
|
||||
|
||||
if (wanted > SSIZE_MAX) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (bytes_recv < wanted && rc > 0)
|
||||
{
|
||||
rc = BIO_read(s->cryptContext->bio, buf+bytes_recv, wanted-bytes_recv);
|
||||
if (rc > 0)
|
||||
bytes_recv += rc;
|
||||
DBG(1, "wanted=%d, bytes_recv:%d, rc=%d\n", wanted, bytes_recv, rc);
|
||||
}
|
||||
|
||||
read = bytes_recv;
|
||||
}
|
||||
#else
|
||||
int ready;
|
||||
fd_set readable;
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = 10;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&readable);
|
||||
FD_SET(s->fd, &readable);
|
||||
|
||||
ready = select(s->fd + 1, &readable, NULL, NULL, &tv);
|
||||
if (ready > 0) {
|
||||
read = sanei_tcp_read(s->fd, buf, wanted);
|
||||
} else {
|
||||
DBG(15, "%s: select failed: %d\n", __func__, ready);
|
||||
}
|
||||
#endif
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
ssize_t epsonds_tcp_write(epsonds_scanner* s, unsigned char *buf, size_t count) {
|
||||
#ifdef HAVE_OPENSSL
|
||||
if(s->cryptContext == NULL) {
|
||||
return sanei_tcp_write(s->fd, buf, count);
|
||||
}
|
||||
else {
|
||||
if(INT_MAX < count) {
|
||||
return -1;
|
||||
}
|
||||
return BIO_write(s->cryptContext->bio, buf, count);
|
||||
}
|
||||
#else
|
||||
return sanei_tcp_write(s->fd, buf, count);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#ifndef _EPSONDS_TCP_H_
|
||||
#define _EPSONDS_TCP_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "../include/sane/sane.h"
|
||||
|
||||
extern void epsonds_tcp_close(struct epsonds_scanner* s);
|
||||
extern SANE_Status epsonds_tcp_open(struct epsonds_scanner* s, const char *host, int port);
|
||||
extern ssize_t epsonds_tcp_read(struct epsonds_scanner* s, unsigned char *buf, ssize_t wanted);
|
||||
extern ssize_t epsonds_tcp_write(struct epsonds_scanner* s, unsigned char *buf, size_t count);
|
||||
|
||||
#endif
|
Ładowanie…
Reference in New Issue