Better and more debug output (based on patch from Jochen Eisinger <jochen.eisinger@gmx.de>).

Fixed some debug output and formatting issues of the byte order patch. Increased version number
to 1.0.5.
Henning Meier-Geinitz <henning@meier-geinitz.de>
DEVEL_2_0_BRANCH-1
Henning Geinitz 2001-10-12 18:39:31 +00:00
rodzic 7cf0f78888
commit fe5ce9118f
2 zmienionych plików z 405 dodań i 175 usunięć

Wyświetl plik

@ -42,7 +42,7 @@
/* Please increase version number with every change
(don't forget to update net.desc) */
#define NET_VERSION "1.0.4"
#define NET_VERSION "1.0.5"
#ifdef _AIX
# include "../include/lalloca.h" /* MUST come first for AIX! */
@ -91,13 +91,15 @@ static int saned_port;
static int client_big_endian; /* 1 == big endian; 0 == little endian */
static int server_big_endian; /* 1 == big endian; 0 == little endian */
static int depth; /* bits per pixel */
static int hang_over; /*-1 == no hangover; otherwise cast value to unsigned char */
static int hang_over; /* -1 == no hangover; otherwise cast value to
unsigned char */
static SANE_Status
add_device (const char *name, Net_Device ** ndp)
{
struct hostent *he;
Net_Device *nd;
struct sockaddr_in *sin;
DBG (1, "add_device: adding backend %s\n", name);
@ -117,18 +119,23 @@ add_device (const char *name, Net_Device ** ndp)
nd = malloc (sizeof (*nd));
if (!nd)
{
DBG (1, "add_device: not enough memory for Net_Device struct\n");
return SANE_STATUS_NO_MEM;
}
memset (nd, 0, sizeof (*nd));
nd->name = strdup (name);
if (!nd->name)
return SANE_STATUS_NO_MEM;
nd->addr.sa_family = he->h_addrtype;
if (nd->addr.sa_family == AF_INET)
{
struct sockaddr_in *sin = (struct sockaddr_in *) &nd->addr;
memcpy (&sin->sin_addr, he->h_addr_list[0], he->h_length);
DBG (1, "add_device: not enough memory to duplicate name\n");
free (nd);
return SANE_STATUS_NO_MEM;
}
nd->addr.sa_family = he->h_addrtype;
sin = (struct sockaddr_in *) &nd->addr;
memcpy (&sin->sin_addr, he->h_addr_list[0], he->h_length);
nd->ctl = -1;
nd->next = first_device;
@ -152,6 +159,8 @@ connect_dev (Net_Device * dev)
int level = -1;
#endif
DBG (2, "connect_dev: trying to connect to %s\n", dev->name);
if (dev->addr.sa_family != AF_INET)
{
DBG (1, "connect_dev: don't know how to deal with addr family %d\n",
@ -176,6 +185,7 @@ connect_dev (Net_Device * dev)
dev->ctl = -1;
return SANE_STATUS_IO_ERROR;
}
DBG (3, "connect_dev: connection succeeded\n");
#ifdef TCP_NODELAY
# ifdef SOL_TCP
@ -198,6 +208,7 @@ connect_dev (Net_Device * dev)
strerror (errno));
#endif /* !TCP_NODELAY */
DBG (2, "connect_dev: sanei_w_init\n");
sanei_w_init (&dev->wire, sanei_codec_bin_init);
dev->wire.io.fd = dev->ctl;
dev->wire.io.read = read;
@ -207,6 +218,8 @@ connect_dev (Net_Device * dev)
req.version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR,
SANEI_NET_PROTOCOL_VERSION);
req.username = getlogin ();
DBG (2, "connect_dev: net_init (user=%s, local version=%d.%d.%d)\n",
req.username, V_MAJOR, V_MINOR, SANEI_NET_PROTOCOL_VERSION);
sanei_w_call (&dev->wire, SANE_NET_INIT,
(WireCodecFunc) sanei_w_init_req, &req,
(WireCodecFunc) sanei_w_init_reply, &reply);
@ -220,9 +233,17 @@ connect_dev (Net_Device * dev)
status = reply.status;
version_code = reply.version_code;
DBG (2, "connect_dev: freeing init reply (status=%s, remote "
"version=%d.%d.%d)\n", sane_strstatus (status),
SANE_VERSION_MAJOR (version_code),
SANE_VERSION_MINOR (version_code), SANE_VERSION_BUILD (version_code));
sanei_w_free (&dev->wire, (WireCodecFunc) sanei_w_init_reply, &reply);
if (status != 0)
{
DBG (1, "connect_dev: access to %s denied\n", dev->name);
goto fail;
}
if (SANE_VERSION_MAJOR (version_code) != V_MAJOR)
{
DBG (1, "connect_dev: major version mismatch: got %d, expected %d\n",
@ -238,9 +259,11 @@ connect_dev (Net_Device * dev)
goto fail;
}
dev->wire.version = SANE_VERSION_BUILD (version_code);
DBG (4, "connect_dev: done\n");
return SANE_STATUS_GOOD;
fail:
DBG (2, "connect_dev: closing connection to %s\n", dev->name);
close (dev->ctl);
dev->ctl = -1;
return SANE_STATUS_IO_ERROR;
@ -249,32 +272,46 @@ fail:
static SANE_Status
fetch_options (Net_Scanner * s)
{
DBG(3, "fetch_options\n");
DBG (3, "fetch_options: %p\n", s);
if (s->opt.num_options)
{
DBG (2, "fetch_options: %d option descriptors cached... freeing\n",
s->opt.num_options);
sanei_w_set_dir (&s->hw->wire, WIRE_FREE);
s->hw->wire.status = 0;
sanei_w_option_descriptor_array (&s->hw->wire, &s->opt);
if (s->hw->wire.status)
{
DBG (1, "fetch_options: failed to free old list (%s)\n",
strerror (s->hw->wire.status));
return SANE_STATUS_IO_ERROR;
}
}
DBG (3, "fetch_options: get_option_descriptors\n");
sanei_w_call (&s->hw->wire, SANE_NET_GET_OPTION_DESCRIPTORS,
(WireCodecFunc) sanei_w_word, &s->handle,
(WireCodecFunc) sanei_w_option_descriptor_array, &s->opt);
if (s->hw->wire.status)
{
DBG (1, "fetch_options: failed to get option descriptors (%s)\n",
strerror (s->hw->wire.status));
return SANE_STATUS_IO_ERROR;
}
s->options_valid = 1;
DBG (3, "fetch_options: %d options fetched\n", s->opt.num_options);
return SANE_STATUS_GOOD;
}
static SANE_Status
do_cancel (Net_Scanner * s)
{
DBG (2, "do_cancel: %p\n", s);
s->hw->auth_active = 0;
if (s->data >= 0)
{
DBG (3, "do_cancel: closing data pipe\n");
close (s->data);
s->data = -1;
}
@ -289,31 +326,42 @@ do_authorization (Net_Device * dev, SANE_String resource)
SANE_Char password[SANE_MAX_PASSWORD_LEN];
char *net_resource;
DBG (2, "do_authorization: dev=%p resource=%s\n", dev, resource);
dev->auth_active = 1;
memset (&req, 0, sizeof (req));
memset (username, 0, sizeof (SANE_Char) * SANE_MAX_USERNAME_LEN);
memset (password, 0, sizeof (SANE_Char) * SANE_MAX_PASSWORD_LEN);
net_resource = malloc (strlen (resource) + 6 + strlen (dev->name));
if (net_resource != NULL)
sprintf (net_resource, "net:%s:%s", dev->name, resource);
else
{
SANE_Word ack;
DBG (1, "do_authorization: not enough memory\n");
req.resource = resource;
sanei_w_call (&dev->wire, SANE_NET_AUTHORIZE,
(WireCodecFunc) sanei_w_authorization_req, &req,
(WireCodecFunc) sanei_w_word, &ack);
return;
}
sprintf (net_resource, "net:%s:%s", dev->name, resource);
if (auth_callback)
{
DBG (2, "do_authorization: invoking auth_callback, resource = %s\n",
net_resource);
(*auth_callback) (net_resource, username, password);
}
else
DBG (1, "do_authorization: no auth_callback present\n");
free (net_resource);
}
else /* Is this necessary? If we don't have these few bytes we will get
in trouble later anyway */
{
DBG (1, "do_authorization: not enough memory for net_resource\n");
if (auth_callback)
{
DBG (2, "do_authorization: invoking auth_callback, resource = %s\n",
resource);
(*auth_callback) (resource, username, password);
}
else
DBG (1, "do_authorization: no auth_callback present\n");
}
if (dev->auth_active)
{
@ -322,35 +370,31 @@ do_authorization (Net_Device * dev, SANE_String resource)
req.resource = resource;
req.username = username;
req.password = password;
DBG (2, "do_authorization: relaying authentication data\n");
sanei_w_call (&dev->wire, SANE_NET_AUTHORIZE,
(WireCodecFunc) sanei_w_authorization_req, &req,
(WireCodecFunc) sanei_w_word, &ack);
}
else
DBG (1, "do_authorization: auth_active is false... strange\n");
}
SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
SANE_Status
sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
{
char device_name[PATH_MAX];
struct servent *serv;
const char *env;
size_t len;
FILE *fp;
/* determine (client) machine byte order */
short ns = 0x1234;
unsigned char *p = (unsigned char *)(&ns);
if(*p == 0x12)
{
client_big_endian = 1;
DBG(1,"Client has big endian byte order");
}
else
{
client_big_endian = 0;
DBG(1,"Client has little endian byte order");
}
DBG_INIT ();
DBG (2, "sane_init: authorize = %p, version_code = %p\n", authorize,
version_code);
auth_callback = authorize;
/* Return the version number of the sane-backends package to allow
@ -360,13 +404,29 @@ SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
*version_code = SANE_VERSION_CODE (SANE_DLL_V_MAJOR, SANE_DLL_V_MINOR,
SANE_DLL_V_BUILD);
DBG(1, "sane_init: SANE net backend version %s from %s\n", NET_VERSION,
DBG (1, "sane_init: SANE net backend version %s from %s\n", NET_VERSION,
PACKAGE_VERSION);
/* determine (client) machine byte order */
if (*p == 0x12)
{
client_big_endian = 1;
DBG (3, "sane_init: Client has big endian byte order\n");
}
else
{
client_big_endian = 0;
DBG (3, "sane_init: Client has little endian byte order\n");
}
DBG (2, "sane_init: determining sane service port\n");
serv = getservbyname ("sane", "tcp");
if (serv)
{
DBG (2, "sane_init: found port %d\n", ntohs (serv->s_port));
saned_port = serv->s_port;
}
else
{
saned_port = htons (6566);
@ -374,6 +434,7 @@ SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
"port %d\n", strerror (errno), ntohs (saned_port));
}
DBG (2, "sane_init: searching for config file\n");
fp = sanei_config_open (NET_CONFIG_FILE);
if (fp)
{
@ -386,25 +447,37 @@ SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
if (!len)
continue; /* ignore empty lines */
DBG (2, "sane_init: trying to add %s\n", device_name);
add_device (device_name, 0);
}
fclose (fp);
DBG (2, "sane_init: done reading config\n");
}
else
DBG(1, "sane_init: could not open config file (%s): %s\n", NET_CONFIG_FILE,
strerror (errno));
DBG (1, "sane_init: could not open config file (%s): %s\n",
NET_CONFIG_FILE, strerror (errno));
DBG (2, "sane_init: evaluating environment variable SANE_NET_HOSTS\n");
env = getenv ("SANE_NET_HOSTS");
if (env)
{
char *copy, *next, *host;
copy = strdup (env);
if ((copy = strdup (env)) != NULL)
{
next = copy;
while ((host = strsep (&next, ":")))
{
DBG (2, "sane_init: trying to add %s\n", host);
add_device (host, 0);
}
free (copy);
}
else
DBG (1, "sane_init: not enough memory to duplicate "
"environment variable\n");
}
DBG (2, "sane_init: done\n");
return SANE_STATUS_GOOD;
}
@ -441,7 +514,7 @@ sane_exit (void)
close (dev->ctl);
}
if (dev->name)
free((void *) dev->name);
free ((void *) dev->name);
free (dev);
}
if (devlist)
@ -488,11 +561,14 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
else \
devlist = malloc (devlist_size * sizeof (devlist[0])); \
if (!devlist) \
{ \
DBG (1, "sane_get_devices: not enough memory\n"); \
return SANE_STATUS_NO_MEM; \
} \
} \
}
DBG(3, "sane_get_devices: local_only = %d\n", local_only);
DBG (3, "sane_get_devices: local_only = %d\n", local_only);
if (local_only)
{
@ -559,12 +635,18 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
len = strlen (dev->name) + 1 + strlen (reply.device_list[i]->name);
mem = malloc (sizeof (*dev) + len + 1);
if (!mem)
{
DBG (1, "sane_get_devices: not enough free memory\n");
sanei_w_free (&dev->wire,
(WireCodecFunc) sanei_w_get_devices_reply,
&reply);
return SANE_STATUS_NO_MEM;
}
full_name = mem + sizeof (*dev);
strcpy (full_name, dev->name);
strcat (full_name, ":");
strcat (full_name, reply.device_list[i]->name);
DBG (3, "sane_get_devices: got %s\n", full_name);
rdev = (SANE_Device *) mem;
rdev->name = full_name;
@ -572,6 +654,22 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
rdev->model = strdup (reply.device_list[i]->model);
rdev->type = strdup (reply.device_list[i]->type);
if ((!rdev->vendor) || (!rdev->model) || (!rdev->type))
{
DBG (1, "sane_get_devices: not enough free memory\n");
if (rdev->vendor)
free (rdev->vendor);
if (rdev->model)
free (rdev->model);
if (rdev->type)
free (rdev->type);
free (rdev);
sanei_w_free (&dev->wire,
(WireCodecFunc) sanei_w_get_devices_reply,
&reply);
return SANE_STATUS_NO_MEM;
}
devlist[devlist_len++] = rdev;
}
/* now free up the rpc return value: */
@ -584,11 +682,12 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
devlist[devlist_len++] = 0;
*device_list = devlist;
DBG (2, "sane_get_devices: finished\n");
DBG (2, "sane_get_devices: finished (%d devices)\n", devlist_len - 1);
return SANE_STATUS_GOOD;
}
SANE_Status sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
SANE_Status
sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
{
SANE_Open_Reply reply;
const char *dev_name;
@ -606,10 +705,20 @@ SANE_Status sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
{
#ifdef strndupa
nd_name = strndupa (full_name, dev_name - full_name);
if (!nd_name)
{
DBG (1, "sane_open: not enough free memory\n");
return SANE_STATUS_NO_MEM;
}
#else
char *tmp;
tmp = alloca (dev_name - full_name + 1);
if (!tmp)
{
DBG (1, "sane_open: not enough free memory\n");
return SANE_STATUS_NO_MEM;
}
memcpy (tmp, full_name, dev_name - full_name);
tmp[dev_name - full_name] = '\0';
nd_name = tmp;
@ -624,13 +733,18 @@ SANE_Status sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
nd_name = (char *) full_name;
dev_name = "";
}
DBG (2, "sane_open: host = %s, device = %s\n", nd_name, dev_name);
if (!nd_name[0])
{
/* Unlike other backends, we never allow an empty backend-name.
Otherwise, it's possible that sane_open("") will result in
endless looping (consider the case where NET is the first
backend...) */
DBG (1, "sane_open: empty backend name is not allowed\n");
return SANE_STATUS_INVAL;
}
else
for (dev = first_device; dev; dev = dev->next)
if (strcmp (dev->name, nd_name) == 0)
@ -638,18 +752,30 @@ SANE_Status sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
if (!dev)
{
DBG (1,
"sane_open: device %s not found, trying to register it anyway\n");
status = add_device (nd_name, &dev);
if (status != SANE_STATUS_GOOD)
{
DBG (1, "sane_open: could not open device\n");
return status;
}
}
else
DBG (2, "sane_open: device found in list\n");
if (dev->ctl < 0)
{
DBG (2, "sane_open: device not connected yet...\n");
status = connect_dev (dev);
if (status != SANE_STATUS_GOOD)
{
DBG (1, "sane_open: could not connect to device\n");
return status;
}
}
DBG (3, "sane_open: net_open\n");
sanei_w_call (&dev->wire, SANE_NET_OPEN,
(WireCodecFunc) sanei_w_string, &dev_name,
(WireCodecFunc) sanei_w_open_reply, &reply);
@ -668,6 +794,7 @@ SANE_Status sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
if (need_auth)
{
DBG (3, "sane_open: authorization required\n");
do_authorization (dev, reply.resource_to_authorize);
sanei_w_free (&dev->wire, (WireCodecFunc) sanei_w_open_reply,
@ -683,7 +810,10 @@ SANE_Status sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
sanei_w_free (&dev->wire, (WireCodecFunc) sanei_w_open_reply, &reply);
if (need_auth && !dev->auth_active)
{
DBG (2, "sane_open: open cancelled\n");
return SANE_STATUS_CANCELLED;
}
if (status != SANE_STATUS_GOOD)
{
@ -695,7 +825,10 @@ SANE_Status sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
s = malloc (sizeof (*s));
if (!s)
{
DBG (1, "sane_open: not enough free memory\n");
return SANE_STATUS_NO_MEM;
}
memset (s, 0, sizeof (*s));
s->hw = dev;
@ -704,7 +837,7 @@ SANE_Status sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle)
s->next = first_handle;
first_handle = s;
*meta_handle = s;
DBG (3, "sane_open: success\n");
return SANE_STATUS_GOOD;
}
@ -714,7 +847,7 @@ sane_close (SANE_Handle handle)
Net_Scanner *prev, *s;
SANE_Word ack;
DBG(3, "sane_close: handle %p\n", handle);
DBG (3, "sane_close: handle %p\n", handle);
prev = 0;
for (s = first_handle; s; s = s->next)
@ -735,20 +868,26 @@ sane_close (SANE_Handle handle)
if (s->opt.num_options)
{
DBG (2, "sane_close: removing cached option descriptors\n");
sanei_w_set_dir (&s->hw->wire, WIRE_FREE);
s->hw->wire.status = 0;
sanei_w_option_descriptor_array (&s->hw->wire, &s->opt);
if (s->hw->wire.status)
DBG(1, "sane_close: couldn't free sanei_w_option_descriptor_array "
DBG (1, "sane_close: couldn't free sanei_w_option_descriptor_array "
"(%s)\n", sane_strstatus (s->hw->wire.status));
}
DBG (2, "sane_close: net_close\n");
sanei_w_call (&s->hw->wire, SANE_NET_CLOSE,
(WireCodecFunc) sanei_w_word, &s->handle,
(WireCodecFunc) sanei_w_word, &ack);
if (s->data >= 0)
{
DBG (2, "sane_close: closing data pipe\n");
close (s->data);
}
free (s);
DBG (2, "sane_close: done\n");
}
const SANE_Option_Descriptor *
@ -757,17 +896,25 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
Net_Scanner *s = handle;
SANE_Status status;
DBG(3, "sane_get_option_descriptor: option %d\n", option);
DBG (3, "sane_get_option_descriptor: option %d\n", option);
if (!s->options_valid)
{
DBG (3, "sane_get_option_descripter: getting option descriptors\n");
status = fetch_options (s);
if (status != SANE_STATUS_GOOD)
{
DBG (1, "sane_get_option_descriptor: fetch_options failed (%s)\n",
sane_strstatus (status));
return 0;
}
}
if (((SANE_Word) option >= s->opt.num_options) || (option < 0))
{
DBG (2, "sane_get_option_descriptor: invalid option number\n");
return 0;
}
return s->opt.desc[option];
}
@ -782,16 +929,25 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
size_t value_size;
int need_auth;
DBG(3, "sane_control_option: option %d, action %d\n", option, action);
DBG (3, "sane_control_option: option %d, action %d\n", option, action);
if (!s->options_valid)
{
DBG (3, "sane_control_option: getting option descriptors\n");
status = fetch_options (s);
if (status != SANE_STATUS_GOOD)
{
DBG (1, "sane_control_option: fetch_options failed (%s)\n",
sane_strstatus (status));
return status;
}
}
if (((SANE_Word) option >= s->opt.num_options) || (option < 0))
{
DBG (1, "sane_control_option: invalid option number\n");
return SANE_STATUS_INVAL;
}
switch (s->opt.desc[option]->type)
{
@ -824,6 +980,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
req.value_size = value_size;
req.value = value;
DBG (3, "sane_control_option: remote control option\n");
sanei_w_call (&s->hw->wire, SANE_NET_CONTROL_OPTION,
(WireCodecFunc) sanei_w_control_option_req, &req,
(WireCodecFunc) sanei_w_control_option_reply, &reply);
@ -834,6 +991,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
need_auth = (reply.resource_to_authorize != 0);
if (need_auth)
{
DBG (3, "sane_control_option: auth required\n");
do_authorization (s->hw, reply.resource_to_authorize);
sanei_w_free (&s->hw->wire,
(WireCodecFunc) sanei_w_control_option_reply, &reply);
@ -866,20 +1024,26 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
return SANE_STATUS_CANCELLED;
}
while (need_auth);
DBG (2, "sane_control_option: done\n");
return status;
}
SANE_Status sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
SANE_Status
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
{
Net_Scanner *s = handle;
SANE_Get_Parameters_Reply reply;
SANE_Status status;
DBG(3, "sane_get_parameters\n");
DBG (3, "sane_get_parameters\n");
if (!params)
{
DBG (1, "sane_get_parameters: parameter params not supplied\n");
return SANE_STATUS_INVAL;
}
DBG (3, "sane_get_parameters: remote get parameters\n");
sanei_w_call (&s->hw->wire, SANE_NET_GET_PARAMETERS,
(WireCodecFunc) sanei_w_word, &s->handle,
(WireCodecFunc) sanei_w_get_parameters_reply, &reply);
@ -890,10 +1054,13 @@ SANE_Status sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
sanei_w_free (&s->hw->wire,
(WireCodecFunc) sanei_w_get_parameters_reply, &reply);
DBG (3, "sane_get_parameters: returned status %s\n",
sane_strstatus (status));
return status;
}
SANE_Status sane_start (SANE_Handle handle)
SANE_Status
sane_start (SANE_Handle handle)
{
Net_Scanner *s = handle;
SANE_Start_Reply reply;
@ -901,15 +1068,18 @@ SANE_Status sane_start (SANE_Handle handle)
SANE_Status status;
int fd, need_auth;
socklen_t len;
short port; /* Internet-specific */
u_int16_t port; /* Internet-specific */
DBG(3, "sane_start\n");
DBG (3, "sane_start\n");
hang_over = -1;
if (s->data >= 0)
{
DBG (2, "sane_start: data pipe already exists\n");
return SANE_STATUS_INVAL;
}
/* Do this ahead of time so in case anything fails, we can
recover gracefully (without hanging our server). */
@ -927,6 +1097,7 @@ SANE_Status sane_start (SANE_Handle handle)
return SANE_STATUS_IO_ERROR;
}
DBG (3, "sane_start: remote start\n");
sanei_w_call (&s->hw->wire, SANE_NET_START,
(WireCodecFunc) sanei_w_word, &s->handle,
(WireCodecFunc) sanei_w_start_reply, &reply);
@ -935,19 +1106,20 @@ SANE_Status sane_start (SANE_Handle handle)
status = reply.status;
port = reply.port;
if(reply.byte_order == 0x1234)
if (reply.byte_order == 0x1234)
{
server_big_endian = 0;
DBG(1,"Server has little endian byte order");
DBG (1, "sane_start: server has little endian byte order\n");
}
else
{
server_big_endian = 1;
DBG(1,"Server has big endian byte order");
DBG (1, "sane_start: server has big endian byte order\n");
}
need_auth = (reply.resource_to_authorize != 0);
if (need_auth)
{
DBG (3, "sane_start: auth required\n");
do_authorization (s->hw, reply.resource_to_authorize);
sanei_w_free (&s->hw->wire,
@ -966,12 +1138,14 @@ SANE_Status sane_start (SANE_Handle handle)
if (status != SANE_STATUS_GOOD)
{
DBG (1, "sane_start: remote start failed (%s)\n",
sane_strstatus (status));
close (fd);
return status;
}
}
while (need_auth);
DBG (3, "sane_start: remote start finished, data at port %hu\n", port);
sin.sin_port = htons (port);
if (connect (fd, (struct sockaddr *) &sin, len) < 0)
@ -984,6 +1158,7 @@ SANE_Status sane_start (SANE_Handle handle)
s->data = fd;
s->reclen_buf_offset = 0;
s->bytes_remaining = 0;
DBG (3, "sane_start: done (%s)\n", sane_strstatus (status));
return status;
}
@ -993,37 +1168,55 @@ sane_read (SANE_Handle handle, SANE_Byte * data, SANE_Int max_length,
{
Net_Scanner *s = handle;
ssize_t nread;
unsigned long cnt;
unsigned char swap_buf;
DBG(3, "sane_read: max_length = %d\n", max_length);
SANE_Int cnt;
SANE_Byte swap_buf;
if (s->data < 0)
return SANE_STATUS_CANCELLED;
DBG (3, "sane_read: max_length = %d\n", max_length);
if (!length)
{
DBG (1, "sane_read: length == NULL\n");
return SANE_STATUS_INVAL;
}
*length = 0;
if (s->data < 0)
return SANE_STATUS_INVAL;
{
DBG (1, "sane_read: data pipe doesn't exist, scan cancelled?\n");
return SANE_STATUS_CANCELLED;
}
if (s->bytes_remaining == 0)
{
/* boy, is this painful or what? */
DBG (4, "sane_read: reading paket length\n");
nread = read (s->data, s->reclen_buf + s->reclen_buf_offset,
4 - s->reclen_buf_offset);
if (nread < 0)
{
DBG (3, "sane_read: read failed (%s)\n", strerror (errno));
if (errno == EAGAIN)
{
DBG (3, "sane_read: try again later\n");
return SANE_STATUS_GOOD;
}
else
{
DBG (1, "sane_read: cancelling read\n");
do_cancel (s);
return SANE_STATUS_IO_ERROR;
}
}
DBG (4, "sane_read: read %d bytes, %d from 4 total\n", nread,
s->reclen_buf_offset);
s->reclen_buf_offset += nread;
if (s->reclen_buf_offset < 4)
{
DBG (4, "sane_read: enough for now\n");
return SANE_STATUS_GOOD;
}
s->reclen_buf_offset = 0;
s->bytes_remaining = (((u_long) s->reclen_buf[0] << 24)
@ -1036,12 +1229,19 @@ sane_read (SANE_Handle handle, SANE_Byte * data, SANE_Int max_length,
{
char ch;
DBG (2, "sane_read: received error signal\n");
/* turn off non-blocking I/O (s->data will be closed anyhow): */
fcntl (s->data, F_SETFL, 0);
/* read the status byte: */
if (read (s->data, &ch, sizeof (ch)) != 1)
{
DBG (1, "sane_read: failed to read error code\n");
ch = SANE_STATUS_IO_ERROR;
}
DBG (1, "sane_read: error code %s\n",
sane_strstatus ((SANE_Status) ch));
do_cancel (s);
return (SANE_Status) ch;
}
@ -1049,71 +1249,85 @@ sane_read (SANE_Handle handle, SANE_Byte * data, SANE_Int max_length,
if (max_length > (SANE_Int) s->bytes_remaining)
max_length = s->bytes_remaining;
/* XXX How do we handle endian problems */
/*If we are scanning with 16bit/pixel, we must be sure to scan complete pixels.
Otherwise it's impossible to swap the bytes, since we don't have access to the
previous data if sane_read is called the next time. Therefore we check, whether
an odd number ob bytes was read. If this is true, the last byte is stored in
hang_over and length is decreased by 1.*/
/*Check whether we are scanning with a depth of 16bit/pixel and whether server and
client have different byte order. If this is true, then it's neccessary to check
whether there's a hang_over from a previous call to sane_read.*/
if((depth == 16) && (server_big_endian != client_big_endian))
/* If we are scanning with 16 bits/pixel, we must be sure to scan complete
pixels. Otherwise it's impossible to swap the bytes, since we don't have
access to the previous data if sane_read is called the next
time. Therefore we check, whether an odd number ob bytes was read. If
this is true, the last byte is stored in hang_over and length is
decreased by 1.
*/
/* Check whether we are scanning with a depth of 16 bits/pixel and whether
server and client have different byte order. If this is true, then it's
neccessary to check whether there's a hang_over from a previous call to
sane_read.
*/
if ((depth == 16) && (server_big_endian != client_big_endian))
{
DBG(1,"client/server have different byte order; check for hang_over");
if(hang_over > -1)
DBG (4, "sane_read: client/server have different byte order\n");
if (hang_over > -1)
{
DBG(1,"hang_over from previous call to sane_read()");
/* hang_over from previous call to sane_read; apply it now*/
DBG (4, "sane_read: hang_over from previous call to sane_read()\n");
*(data) = (unsigned char) hang_over;
nread = read (s->data, data+1, max_length-1);
DBG (4, "sane_read: reading image data now\n");
nread = read (s->data, data + 1, max_length - 1);
}
else
{
DBG(1,"no hang_over from previous call to sane_read()");
/*no hang_over*/
DBG (4, "sane_read: no hang_over from previous call to "
"sane_read()\n");
DBG (4, "sane_read: reading image data now\n");
nread = read (s->data, data, max_length);
}
}
else
{
DBG (4, "sane_read: reading image data now\n");
nread = read (s->data, data, max_length);
}
if (nread < 0)
{
DBG (2, "sane_read: error code %s\n", strerror (errno));
if (errno == EAGAIN)
return SANE_STATUS_GOOD;
else
{
DBG (1, "sane_read: cancelling scan\n");
do_cancel (s);
return SANE_STATUS_IO_ERROR;
}
}
/*Check whether we are scanning with a depth of 16bit/pixel and whether server and
client have different byte order. If this is true, then it's neccessary to check
whether read returned an odd number. If an odd number has been returned, we must save the
last byte.*/
if((depth == 16) && (server_big_endian != client_big_endian))
/* Check whether we are scanning with a depth of 16 bits/pixel and whether
server and client have different byte order. If this is true, then it's
neccessary to check whether read returned an odd number. If an odd number
has been returned, we must save the last byte.
*/
if ((depth == 16) && (server_big_endian != client_big_endian))
{
DBG(1,"client/server have different byte order; must swap");
DBG (1,"sane_read: client/server have different byte order; "
"must swap\n");
s->bytes_remaining -= nread;
if(0 != nread % 2)
if (0 != nread % 2)
{
DBG(1,"client/server have different byte order; store hang_over");
/*nread is odd; decrease length and store hang_over*/
DBG (1, "sane_read: number of bytes read is odd; store hang_over\n");
*length = nread - 1;
hang_over = *(data + nread);
}
else
{
/*nread is even; no hang_over*/
*length = nread;
hang_over = -1;
}
/*Finally step through the buffer and swap bytes*/
for(cnt = 0;cnt < *length - 1;cnt += 2)
/* Finally step through the buffer and swap bytes */
for (cnt = 0; cnt < *length - 1; cnt += 2)
{
swap_buf = *(data +cnt);
*(data + cnt) = *(data +cnt + 1);
*(data + cnt) = *(data + cnt + 1);
*(data + cnt + 1) = swap_buf;
}
}
@ -1122,6 +1336,9 @@ sane_read (SANE_Handle handle, SANE_Byte * data, SANE_Int max_length,
s->bytes_remaining -= nread;
*length = nread;
}
DBG (3, "sane_read: %d bytes read, %d remaining\n", nread,
s->bytes_remaining);
return SANE_STATUS_GOOD;
}
@ -1131,37 +1348,50 @@ sane_cancel (SANE_Handle handle)
Net_Scanner *s = handle;
SANE_Word ack;
DBG(3, "sane_cancel\n");
DBG (3, "sane_cancel: sending net_cancel\n");
sanei_w_call (&s->hw->wire, SANE_NET_CANCEL,
(WireCodecFunc) sanei_w_word, &s->handle,
(WireCodecFunc) sanei_w_word, &ack);
do_cancel (s);
DBG (4, "sane_cancel: done\n");
}
SANE_Status sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
SANE_Status
sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
{
Net_Scanner *s = handle;
DBG(3, "sane_set_io_mode: non_blocking = %d\n", non_blocking);
DBG (3, "sane_set_io_mode: non_blocking = %d\n", non_blocking);
if (s->data < 0)
{
DBG (1, "sane_set_io_mode: pipe doesn't exist\n");
return SANE_STATUS_INVAL;
}
if (fcntl (s->data, F_SETFL, non_blocking ? O_NONBLOCK : 0) < 0)
{
DBG (1, "sane_set_io_mode: fcntl failed (%s)\n", strerror (errno));
return SANE_STATUS_IO_ERROR;
}
return SANE_STATUS_GOOD;
}
SANE_Status sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
SANE_Status
sane_get_select_fd (SANE_Handle handle, SANE_Int * fd)
{
Net_Scanner *s = handle;
DBG(3, "sane_get_select_fd: *fd = %d\n", *fd);
DBG (3, "sane_get_select_fd\n");
if (s->data < 0)
{
DBG (1, "sane_get_select_fd: pipe doesn't exist\n");
return SANE_STATUS_INVAL;
}
*fd = s->data;
DBG (3, "sane_get_select_fd: done; *fd = %d\n", *fd);
return SANE_STATUS_GOOD;
}

Wyświetl plik

@ -1,5 +1,5 @@
:backend "net" ; name of backend
:version "1.0.4"
:version "1.0.5"
:status :beta
:manpage "sane-net"
:url "http://home.nexgo.de/jochen.eisinger/saned/"