1 /* sane - Scanner Access Now Easy.
2    Copyright (C) 1997 David Mosberger-Tang
3    This file is part of the SANE package.
4 
5    This program is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 
18    As a special exception, the authors of SANE give permission for
19    additional uses of the libraries contained in this release of SANE.
20 
21    The exception is that, if you link a SANE library with other files
22    to produce an executable, this does not by itself cause the
23    resulting executable to be covered by the GNU General Public
24    License.  Your use of that executable is in no way restricted on
25    account of linking the SANE library code into it.
26 
27    This exception does not, however, invalidate any other reasons why
28    the executable file might be covered by the GNU General Public
29    License.
30 
31    If you submit changes to SANE to the maintainers to be included in
32    a subsequent release, you agree by submitting the changes that
33    those changes may be distributed with this exception intact.
34 
35    If you write modifications of your own for SANE, it is your choice
36    whether to permit this exception to apply to your modifications.
37    If you do not wish that, delete this exception notice.  */
38 
39 #include "../include/sane/config.h"
40 
41 #include <errno.h>
42 #include <stdlib.h>
43 #include <string.h>
44 
45 #include <sys/types.h>
46 
47 #include "../include/sane/sane.h"
48 #include "../include/sane/sanei_wire.h"
49 
50 #define BACKEND_NAME	sanei_wire
51 #include "../include/sane/sanei_backend.h"
52 
53 void
sanei_w_space(Wire * w,size_t howmuch)54 sanei_w_space (Wire * w, size_t howmuch)
55 {
56   size_t nbytes, left_over;
57   int fd = w->io.fd;
58   ssize_t nread, nwritten;
59 
60   DBG (3, "sanei_w_space: %lu bytes for wire %d\n", (u_long) howmuch, fd);
61 
62   if (howmuch > w->buffer.size)
63     DBG (2, "sanei_w_space: bigger than buffer (%lu bytes), "
64 	 "may be flush()\n", (u_long) w->buffer.size);
65 
66   if (w->status != 0)
67     {
68       DBG (1, "sanei_w_space: wire is in invalid state %d\n",
69 	   w->status);
70       return;
71     }
72 
73   if (w->buffer.curr + howmuch > w->buffer.end)
74     {
75       DBG (4, "sanei_w_space: free buffer size is %lu\n",
76 	   (u_long) (w->buffer.end - w->buffer.curr));
77       switch (w->direction)
78 	{
79 	case WIRE_ENCODE:
80 	  nbytes = w->buffer.curr - w->buffer.start;
81 	  w->buffer.curr = w->buffer.start;
82 	  DBG (4, "sanei_w_space: ENCODE: sending %lu bytes\n",
83 	       (u_long) nbytes);
84 	  while (nbytes > 0)
85 	    {
86 	      nwritten = (*w->io.write) (fd, w->buffer.curr, nbytes);
87 	      if (nwritten < 0)
88 		{
89 		  DBG (1, "sanei_w_space: ENCODE: write failed (%d)\n", errno);
90 		  w->status = errno;
91 		  return;
92 		}
93 	      w->buffer.curr += nwritten;
94 	      nbytes -= nwritten;
95 	    }
96 	  w->buffer.curr = w->buffer.start;
97 	  w->buffer.end = w->buffer.start + w->buffer.size;
98 	  DBG (4, "sanei_w_space: ENCODE: free buffer is now %lu\n",
99 	       (u_long) w->buffer.size);
100 	  break;
101 
102 	case WIRE_DECODE:
103 	  left_over = w->buffer.end - w->buffer.curr;
104 
105 	  if ((signed) left_over < 0)
106 	    {
107 	      DBG (1, "sanei_w_space: DECODE: buffer underflow\n");
108 	      return;
109 	    }
110 
111 	  if (left_over)
112 	    {
113 	      DBG (4, "sanei_w_space: DECODE: %lu bytes left in buffer\n",
114 		   (u_long) left_over);
115 	      memmove (w->buffer.start, w->buffer.curr, left_over);
116 	    }
117 	  w->buffer.curr = w->buffer.start;
118 	  w->buffer.end = w->buffer.start + left_over;
119 
120 	  DBG (4, "sanei_w_space: DECODE: receiving data\n");
121 	  do
122 	    {
123 	      nread = (*w->io.read) (fd, w->buffer.end,
124 				     w->buffer.size - left_over);
125 	      if (nread <= 0)
126 		{
127 		  DBG (2, "sanei_w_space: DECODE: no data received (%d)\n",
128 		       errno);
129 		  if (nread == 0)
130 		    errno = EINVAL;
131 		  w->status = errno;
132 		  return;
133 		}
134 	      left_over += nread;
135 	      w->buffer.end += nread;
136 	    }
137 	  while (left_over < howmuch);
138 	  DBG (4, "sanei_w_space: DECODE: %lu bytes read\n",
139 	       (u_long) (w->buffer.end - w->buffer.start));
140 	  break;
141 
142 	case WIRE_FREE:
143 	  DBG (4, "sanei_w_space: FREE: doing nothing for free operation\n");
144 	  break;
145 	}
146     }
147   DBG (4, "sanei_w_space: done\n");
148 }
149 
150 void
sanei_w_void(Wire * w,void __sane_unused__ * v)151 sanei_w_void (Wire * w, void __sane_unused__ * v)
152 {
153   DBG (3, "sanei_w_void: wire %d (void debug output)\n", w->io.fd);
154 }
155 
156 void
sanei_w_array(Wire * w,SANE_Word * len_ptr,void ** v,WireCodecFunc w_element,size_t element_size)157 sanei_w_array (Wire * w, SANE_Word * len_ptr, void **v,
158 	       WireCodecFunc w_element, size_t element_size)
159 {
160   SANE_Word len;
161   char *val;
162   int i;
163 
164   DBG (3, "sanei_w_array: wire %d, elements of size %lu\n", w->io.fd,
165        (u_long) element_size);
166 
167   if (w->direction == WIRE_FREE)
168     {
169       if (*len_ptr && *v)
170 	{
171 	  DBG (4, "sanei_w_array: FREE: freeing array (%d elements)\n",
172 	       *len_ptr);
173 	  val = *v;
174 	  for (i = 0; i < *len_ptr; ++i)
175 	    {
176 	      (*w_element) (w, val);
177 	      val += element_size;
178 	    }
179 	  free (*v);
180 	  w->allocated_memory -= (*len_ptr * element_size);
181 	}
182       else
183 	DBG (1, "sanei_w_array: FREE: tried to free array but *len_ptr or *v "
184 	     "was NULL\n");
185 
186       DBG (4, "sanei_w_array: FREE: done\n");
187       return;
188     }
189 
190   if (w->direction == WIRE_ENCODE)
191     len = *len_ptr;
192   DBG (4, "sanei_w_array: send/receive array length\n");
193   sanei_w_word (w, &len);
194 
195   if (w->status)
196     {
197       DBG (1, "sanei_w_array: bad status: %d\n", w->status);
198       return;
199     }
200   DBG (4, "sanei_w_array: array has %d elements\n", len);
201 
202   if (w->direction == WIRE_DECODE)
203     {
204       *len_ptr = len;
205       if (len)
206 	{
207 	  if (((unsigned int) len) > MAX_MEM
208 	      || ((unsigned int) len * element_size) > MAX_MEM
209 	      || (w->allocated_memory + len * element_size) > MAX_MEM)
210 	    {
211 	      DBG (0, "sanei_w_array: DECODE: maximum amount of allocated memory "
212 		   "exceeded (limit: %u, new allocation: %lu, total: %lu bytes)\n",
213 			   MAX_MEM, (unsigned long)(len * element_size),
214 			   (unsigned long)(MAX_MEM + len * element_size));
215 	      w->status = ENOMEM;
216 	      return;
217 	    }
218 	  *v = malloc (len * element_size);
219 	  if (*v == 0)
220 	    {
221 	      /* Malloc failed, so return an error. */
222 	      DBG (1, "sanei_w_array: DECODE: not enough free memory\n");
223 	      w->status = ENOMEM;
224 	      return;
225 	    }
226 	  memset (*v, 0, len * element_size);
227 	  w->allocated_memory += (len * element_size);
228 	}
229       else
230 	*v = 0;
231     }
232 
233   val = *v;
234   DBG (4, "sanei_w_array: transferring array elements\n");
235   for (i = 0; i < len; ++i)
236     {
237       (*w_element) (w, val);
238       val += element_size;
239       if (w->status)
240 	{
241 	  DBG (1, "sanei_w_array: bad status: %d\n", w->status);
242 	  return;
243 	}
244     }
245   DBG (4, "sanei_w_array: done\n");
246 }
247 
248 void
sanei_w_ptr(Wire * w,void ** v,WireCodecFunc w_value,size_t value_size)249 sanei_w_ptr (Wire * w, void **v, WireCodecFunc w_value, size_t value_size)
250 {
251   SANE_Word is_null;
252 
253   DBG (3, "sanei_w_ptr: wire %d, value pointer at is %lu bytes\n", w->io.fd,
254        (u_long) value_size);
255 
256   if (w->direction == WIRE_FREE)
257     {
258       if (*v && value_size)
259 	{
260 	  DBG (4, "sanei_w_ptr: FREE: freeing value\n");
261 	  (*w_value) (w, *v);
262 	  free (*v);
263 	  w->allocated_memory -= value_size;
264 	}
265       else
266 	DBG (1, "sanei_w_ptr: FREE: tried to free value but *v or value_size "
267 	     "was NULL\n");
268 
269       DBG (4, "sanei_w_ptr: FREE: done\n");
270       return;
271     }
272   if (w->direction == WIRE_ENCODE)
273     is_null = (*v == 0);
274 
275   DBG (4, "sanei_w_ptr: send/receive is_null\n");
276   sanei_w_word (w, &is_null);
277   if (w->status)
278     {
279       DBG (1, "sanei_w_ptr: bad status: %d\n", w->status);
280       return;
281     }
282 
283   if (!is_null)
284     {
285       if (w->direction == WIRE_DECODE)
286 	{
287 	  DBG (4, "sanei_w_ptr: DECODE: receive data pointed at\n");
288 	  if (value_size > MAX_MEM)
289 	    {
290 	      DBG (0, "sanei_w_ptr: DECODE: maximum amount of allocated memory "
291 		   "exceeded (limit: %u, new allocation: %lu, total: %lu bytes)\n",
292 		   MAX_MEM, (unsigned long)value_size,
293 			   (unsigned long)(w->allocated_memory + value_size));
294 	      w->status = ENOMEM;
295 	      return;
296 	    }
297 
298 	  *v = malloc (value_size);
299 	  if (*v == 0)
300 	    {
301 	      /* Malloc failed, so return an error. */
302 	      DBG (1, "sanei_w_ptr: DECODE: not enough free memory\n");
303 	      w->status = ENOMEM;
304 	      return;
305 	    }
306 	  w->allocated_memory += value_size;
307 	  memset (*v, 0, value_size);
308 	}
309       (*w_value) (w, *v);
310     }
311   else if (w->direction == WIRE_DECODE)
312     *v = 0;
313 
314   DBG (4, "sanei_w_ptr: done\n");
315 }
316 
317 void
sanei_w_byte(Wire * w,SANE_Byte * v)318 sanei_w_byte (Wire * w, SANE_Byte * v)
319 {
320   DBG (3, "sanei_w_byte: wire %d\n", w->io.fd);
321   (*w->codec.w_byte) (w, v);
322   if (w->direction != WIRE_FREE)
323     DBG (4, "sanei_w_byte: value = %d\n", *v);
324 }
325 
326 void
sanei_w_char(Wire * w,SANE_Char * v)327 sanei_w_char (Wire * w, SANE_Char * v)
328 {
329   DBG (3, "sanei_w_char: wire %d\n", w->io.fd);
330   (*w->codec.w_char) (w, v);
331   if (w->direction != WIRE_FREE)
332     DBG (4, "sanei_w_char: value = %d\n", *v);
333 }
334 
335 void
sanei_w_word(Wire * w,SANE_Word * v)336 sanei_w_word (Wire * w, SANE_Word * v)
337 {
338   DBG (3, "sanei_w_word: wire %d\n", w->io.fd);
339   (*w->codec.w_word) (w, v);
340   if (w->direction != WIRE_FREE)
341     DBG (4, "sanei_w_word: value = %d\n", *v);
342 }
343 
344 void
sanei_w_string(Wire * w,SANE_String * v)345 sanei_w_string (Wire * w, SANE_String * v)
346 {
347   DBG (3, "sanei_w_string: wire %d\n", w->io.fd);
348   (*w->codec.w_string) (w, v);
349   if (w->direction != WIRE_FREE && w->status == 0)
350     DBG (4, "sanei_w_string: value = %s\n", *v);
351 }
352 
353 void
sanei_w_status(Wire * w,SANE_Status * v)354 sanei_w_status (Wire * w, SANE_Status * v)
355 {
356   SANE_Word word = *v;
357 
358   DBG (3, "sanei_w_status: wire %d\n", w->io.fd);
359 
360   sanei_w_word (w, &word);
361   if (w->direction == WIRE_DECODE)
362     *v = word;
363 
364   if (w->direction != WIRE_FREE)
365     DBG (4, "sanei_w_status: value = %d\n", word);
366 }
367 
368 void
sanei_w_bool(Wire * w,SANE_Bool * v)369 sanei_w_bool (Wire * w, SANE_Bool * v)
370 {
371   SANE_Word word = *v;
372 
373   DBG (3, "sanei_w_bool: wire %d\n", w->io.fd);
374   sanei_w_word (w, &word);
375   if (w->direction == WIRE_DECODE)
376     *v = word;
377 
378   if (w->direction != WIRE_FREE)
379     DBG (4, "sanei_w_bool: value = %s\n",
380 	 ((word == SANE_TRUE) ? ("true") : ("false")));
381 }
382 
383 void
sanei_w_constraint_type(Wire * w,SANE_Constraint_Type * v)384 sanei_w_constraint_type (Wire * w, SANE_Constraint_Type * v)
385 {
386   SANE_Word word = *v;
387 
388   DBG (3, "sanei_w_constraint_type: wire %d\n", w->io.fd);
389 
390   sanei_w_word (w, &word);
391   if (w->direction == WIRE_DECODE)
392     *v = word;
393 
394   if (w->direction != WIRE_FREE)
395     DBG (4, "sanei_w_constraint_type: value = %d\n", word);
396 }
397 
398 void
sanei_w_value_type(Wire * w,SANE_Value_Type * v)399 sanei_w_value_type (Wire * w, SANE_Value_Type * v)
400 {
401   SANE_Word word = *v;
402 
403   DBG (3, "sanei_w_value_type: wire %d\n", w->io.fd);
404 
405   sanei_w_word (w, &word);
406   if (w->direction == WIRE_DECODE)
407     *v = word;
408   if (w->direction != WIRE_FREE)
409     DBG (4, "sanei_w_value_type: value = %d\n", word);
410 }
411 
412 void
sanei_w_unit(Wire * w,SANE_Unit * v)413 sanei_w_unit (Wire * w, SANE_Unit * v)
414 {
415   SANE_Word word = *v;
416 
417   DBG (3, "sanei_w_unit: wire %d\n", w->io.fd);
418   sanei_w_word (w, &word);
419   if (w->direction == WIRE_DECODE)
420     *v = word;
421 
422   if (w->direction != WIRE_FREE)
423     DBG (4, "sanei_w_unit: value = %d\n", word);
424   /* gosh... all the sane_w_something should be a macro or something */
425 }
426 
427 void
sanei_w_action(Wire * w,SANE_Action * v)428 sanei_w_action (Wire * w, SANE_Action * v)
429 {
430   SANE_Word word = *v;
431 
432   DBG (3, "sanei_w_action: wire %d\n", w->io.fd);
433 
434   sanei_w_word (w, &word);
435   if (w->direction == WIRE_DECODE)
436     *v = word;
437 
438   if (w->direction != WIRE_FREE)
439     DBG (4, "sanei_w_action: value = %d\n", word);
440 }
441 
442 void
sanei_w_frame(Wire * w,SANE_Frame * v)443 sanei_w_frame (Wire * w, SANE_Frame * v)
444 {
445   SANE_Word word = *v;
446 
447   DBG (3, "sanei_w_frame: wire %d\n", w->io.fd);
448 
449   sanei_w_word (w, &word);
450   if (w->direction == WIRE_DECODE)
451     *v = word;
452 
453   if (w->direction != WIRE_FREE)
454     DBG (4, "sanei_w_frame: value = %d\n", word);
455 }
456 
457 void
sanei_w_range(Wire * w,SANE_Range * v)458 sanei_w_range (Wire * w, SANE_Range * v)
459 {
460   DBG (3, "sanei_w_range: wire %d\n", w->io.fd);
461   sanei_w_word (w, &v->min);
462   sanei_w_word (w, &v->max);
463   sanei_w_word (w, &v->quant);
464   if (w->direction != WIRE_FREE)
465     DBG (4, "sanei_w_range: min/max/step = %f/%f/%f\n",
466 	 SANE_UNFIX (v->min), SANE_UNFIX (v->max), SANE_UNFIX (v->quant));
467 }
468 
469 void
sanei_w_device(Wire * w,SANE_Device * v)470 sanei_w_device (Wire * w, SANE_Device * v)
471 {
472   DBG (3, "sanei_w_device: wire %d\n", w->io.fd);
473   sanei_w_string (w, (SANE_String *) & v->name);
474   sanei_w_string (w, (SANE_String *) & v->vendor);
475   sanei_w_string (w, (SANE_String *) & v->model);
476   sanei_w_string (w, (SANE_String *) & v->type);
477   if (w->direction != WIRE_FREE)
478     DBG (4, "sanei_w_device: %s %s from %s (%s)\n", v->name, v->model,
479 	 v->vendor, v->type);
480 }
481 
482 void
sanei_w_device_ptr(Wire * w,SANE_Device ** v)483 sanei_w_device_ptr (Wire * w, SANE_Device ** v)
484 {
485   DBG (3, "sanei_w_device_ptr: wire %d\n", w->io.fd);
486   sanei_w_ptr (w, (void **) v, (WireCodecFunc) sanei_w_device, sizeof (**v));
487   if (w->direction != WIRE_FREE)
488     DBG (4, "sanei_w_device_ptr: device struct at %p\n", (void*) *v);
489 }
490 
491 void
sanei_w_option_descriptor(Wire * w,SANE_Option_Descriptor * v)492 sanei_w_option_descriptor (Wire * w, SANE_Option_Descriptor * v)
493 {
494   SANE_Word len;
495 
496   DBG (3, "sanei_w_option_descriptor: wire %d\n", w->io.fd);
497 
498   sanei_w_string (w, (SANE_String *) & v->name);
499   sanei_w_string (w, (SANE_String *) & v->title);
500   sanei_w_string (w, (SANE_String *) & v->desc);
501   sanei_w_value_type (w, &v->type);
502   sanei_w_unit (w, &v->unit);
503   sanei_w_word (w, &v->size);
504   sanei_w_word (w, &v->cap);
505   sanei_w_constraint_type (w, &v->constraint_type);
506 
507   if (w->direction != WIRE_FREE)
508     DBG (4, "sanei_w_option_descriptor: option %s\n", v->name);
509 
510   switch (v->constraint_type)
511     {
512     case SANE_CONSTRAINT_NONE:
513       break;
514 
515     case SANE_CONSTRAINT_RANGE:
516       sanei_w_ptr (w, (void **) &v->constraint.range,
517 		   (WireCodecFunc) sanei_w_range, sizeof (SANE_Range));
518       break;
519 
520     case SANE_CONSTRAINT_WORD_LIST:
521       if (w->direction != WIRE_DECODE)
522 	len = v->constraint.word_list[0] + 1;
523       sanei_w_array (w, &len, (void **) &v->constraint.word_list,
524 		     w->codec.w_word, sizeof (SANE_Word));
525       break;
526 
527     case SANE_CONSTRAINT_STRING_LIST:
528       if (w->direction != WIRE_DECODE)
529 	{
530 	  for (len = 0; v->constraint.string_list[len]; ++len);
531 	  ++len;		/* send NULL string, too */
532 	}
533       sanei_w_array (w, &len, (void **) &v->constraint.string_list,
534 		     w->codec.w_string, sizeof (SANE_String));
535       break;
536     }
537   DBG (4, "sanei_w_option_descriptor: done\n");
538 }
539 
540 void
sanei_w_option_descriptor_ptr(Wire * w,SANE_Option_Descriptor ** v)541 sanei_w_option_descriptor_ptr (Wire * w, SANE_Option_Descriptor ** v)
542 {
543   DBG (3, "sanei_w_option_descriptor_ptr: wire %d\n", w->io.fd);
544   sanei_w_ptr (w, (void **) v,
545 	       (WireCodecFunc) sanei_w_option_descriptor, sizeof (**v));
546   DBG (4, "sanei_w_option_descriptor_ptr: done\n");
547 }
548 
549 void
sanei_w_parameters(Wire * w,SANE_Parameters * v)550 sanei_w_parameters (Wire * w, SANE_Parameters * v)
551 {
552   DBG (3, "sanei_w_parameters: wire %d\n", w->io.fd);
553   sanei_w_frame (w, &v->format);
554   sanei_w_bool (w, &v->last_frame);
555   sanei_w_word (w, &v->bytes_per_line);
556   sanei_w_word (w, &v->pixels_per_line);
557   sanei_w_word (w, &v->lines);
558   sanei_w_word (w, &v->depth);
559   if (w->direction != WIRE_FREE)
560     DBG (4,
561 	 "sanei_w_parameters: format/last/bpl/ppl/lines/depth = "
562 	 "%d/%d/%d/%d/%d/%d\n", v->format, v->last_frame, v->bytes_per_line,
563 	 v->pixels_per_line, v->lines, v->depth);
564 }
565 
566 static void
flush(Wire * w)567 flush (Wire * w)
568 {
569   DBG (3, "flush: wire %d\n", w->io.fd);
570   if (w->direction == WIRE_ENCODE)
571     sanei_w_space (w, w->buffer.size + 1);
572   else if (w->direction == WIRE_DECODE)
573     w->buffer.curr = w->buffer.end = w->buffer.start;
574   if (w->status != 0)
575     DBG (2, "flush: error status %d\n", w->status);
576   DBG (4, "flush: wire flushed\n");
577 }
578 
579 void
sanei_w_set_dir(Wire * w,WireDirection dir)580 sanei_w_set_dir (Wire * w, WireDirection dir)
581 {
582   DBG (3, "sanei_w_set_dir: wire %d, old direction WIRE_%s\n", w->io.fd,
583        w->direction == WIRE_ENCODE ? "ENCODE" :
584        (w->direction == WIRE_DECODE ? "DECODE" : "FREE"));
585   if (w->direction == WIRE_DECODE && w->buffer.curr != w->buffer.end)
586     DBG (1, "sanei_w_set_dir: WARNING: will delete %lu bytes from buffer\n",
587 	 (u_long) (w->buffer.end - w->buffer.curr));
588   flush (w);
589   w->direction = dir;
590   DBG (4, "sanei_w_set_dir: direction changed\n");
591   flush (w);
592   DBG (3, "sanei_w_set_dir: wire %d, new direction WIRE_%s\n", w->io.fd,
593        dir == WIRE_ENCODE ? "ENCODE" :
594        (dir == WIRE_DECODE ? "DECODE" : "FREE"));
595 }
596 
597 void
sanei_w_call(Wire * w,SANE_Word procnum,WireCodecFunc w_arg,void * arg,WireCodecFunc w_reply,void * reply)598 sanei_w_call (Wire * w,
599 	      SANE_Word procnum,
600 	      WireCodecFunc w_arg, void *arg,
601 	      WireCodecFunc w_reply, void *reply)
602 {
603 
604   DBG (3, "sanei_w_call: wire %d (old status %d)\n", w->io.fd, w->status);
605   w->status = 0;
606   sanei_w_set_dir (w, WIRE_ENCODE);
607 
608   DBG (4, "sanei_w_call: sending request (procedure number: %d)\n", procnum);
609   sanei_w_word (w, &procnum);
610   (*w_arg) (w, arg);
611 
612   if (w->status == 0)
613     {
614       DBG (4, "sanei_w_call: receiving reply\n");
615       sanei_w_set_dir (w, WIRE_DECODE);
616       (*w_reply) (w, reply);
617     }
618 
619   if (w->status != 0)
620     DBG (2, "sanei_w_call: error status %d\n", w->status);
621   DBG (4, "sanei_w_call: done\n");
622 }
623 
624 void
sanei_w_reply(Wire * w,WireCodecFunc w_reply,void * reply)625 sanei_w_reply (Wire * w, WireCodecFunc w_reply, void *reply)
626 {
627   DBG (3, "sanei_w_reply: wire %d (old status %d)\n", w->io.fd, w->status);
628   w->status = 0;
629   sanei_w_set_dir (w, WIRE_ENCODE);
630   (*w_reply) (w, reply);
631   flush (w);
632   if (w->status != 0)
633     DBG (2, "sanei_w_reply: error status %d\n", w->status);
634   DBG (4, "sanei_w_reply: done\n");
635 }
636 
637 void
sanei_w_free(Wire * w,WireCodecFunc w_reply,void * reply)638 sanei_w_free (Wire * w, WireCodecFunc w_reply, void *reply)
639 {
640   WireDirection saved_dir = w->direction;
641 
642   DBG (3, "sanei_w_free: wire %d\n", w->io.fd);
643 
644   w->direction = WIRE_FREE;
645   (*w_reply) (w, reply);
646   w->direction = saved_dir;
647 
648   if (w->status != 0)
649     DBG (2, "sanei_w_free: error status %d\n", w->status);
650   DBG (4, "sanei_w_free: done\n");
651 }
652 
653 void
sanei_w_init(Wire * w,void (* codec_init_func)(Wire *))654 sanei_w_init (Wire * w, void (*codec_init_func) (Wire *))
655 {
656   DBG_INIT ();
657 
658   DBG (3, "sanei_w_init: initializing\n");
659   w->status = 0;
660   w->direction = WIRE_ENCODE;
661   w->buffer.size = 8192;
662   w->buffer.start = malloc (w->buffer.size);
663 
664   if (w->buffer.start == 0)
665     {
666       /* Malloc failed, so return an error. */
667       w->status = ENOMEM;
668       DBG (1, "sanei_w_init: not enough free memory\n");
669     }
670 
671   w->buffer.curr = w->buffer.start;
672   w->buffer.end = w->buffer.start + w->buffer.size;
673   if (codec_init_func != 0)
674     {
675       DBG (4, "sanei_w_init: initializing codec\n");
676       (*codec_init_func) (w);
677     }
678   w->allocated_memory = 0;
679   DBG (4, "sanei_w_init: done\n");
680 }
681 
682 void
sanei_w_exit(Wire * w)683 sanei_w_exit (Wire * w)
684 {
685   DBG (3, "sanei_w_exit: wire %d\n", w->io.fd);
686   if (w->buffer.start)
687     {
688       DBG (4, "sanei_w_exit: freeing buffer\n");
689       free (w->buffer.start);
690     }
691   w->buffer.start = 0;
692   w->buffer.size = 0;
693   DBG (4, "sanei_w_exit: done\n");
694 }
695