~ubuntu-branches/ubuntu/raring/hplip/raring-proposed

« back to all changes in this revision

Viewing changes to .pc/14_charsign_fixes.dpatch/scan/sane/scl.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2012-05-26 11:20:39 UTC
  • mfrom: (1.5.6) (31.1.3 precise)
  • Revision ID: package-import@ubuntu.com-20120526112039-bevxczegxnbyr5m7
Tags: 3.12.4-1
* New upstream release
* Switch to source/format 3.0 (quilt) - drop dpatch
* Refreshed debian/patches
* dh_autoreconf debian/autogen.sh & set local-options single-debian-patch
* Update to debian/compat -> 9
* Fix "hardened build flags" patch from Moritz - thanks (Closes: #667828)
* Fix "duplex descriptor uninitialized" patch from Matej (Closes: #583273)
* Fix "please migrate to kde-runtime" patch from Pino (Closes: #666544)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/************************************************************************************\
 
2
 
 
3
  scl.c - HP SANE backend for multi-function peripherals (libsane-hpaio)
 
4
 
 
5
  (c) 2001-2006 Copyright Hewlett-Packard Development Company, LP
 
6
 
 
7
  Permission is hereby granted, free of charge, to any person obtaining a copy 
 
8
  of this software and associated documentation files (the "Software"), to deal 
 
9
  in the Software without restriction, including without limitation the rights 
 
10
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
 
11
  of the Software, and to permit persons to whom the Software is furnished to do 
 
12
  so, subject to the following conditions:
 
13
 
 
14
  The above copyright notice and this permission notice shall be included in all
 
15
  copies or substantial portions of the Software.
 
16
 
 
17
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 
18
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 
 
19
  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
 
20
  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
 
21
  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
 
22
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
23
 
 
24
  Contributing Authors: David Paschal, Don Welch, David Suffield 
 
25
 
 
26
\************************************************************************************/
 
27
 
 
28
#include <errno.h>
 
29
#include <stdio.h>
 
30
#include <string.h>
 
31
#include "hpmud.h"
 
32
#include "io.h"
 
33
#include "common.h"
 
34
#include "scl.h"
 
35
#include "hpaio.h"
 
36
 
 
37
#define DEBUG_DECLARE_ONLY
 
38
#include "sanei_debug.h"
 
39
 
 
40
static int SclBufferIsPartialReply( unsigned char * data, int datalen )
 
41
{
 
42
    int i = 0, value = 0;
 
43
    unsigned char d;  
 
44
 
 
45
    if( i >= datalen )
 
46
    {
 
47
        return 0;
 
48
    }
 
49
    if( data[i++] != 27 )
 
50
    {
 
51
        return 0;
 
52
    }
 
53
    if( i >= datalen )
 
54
    {
 
55
        return 0;
 
56
    }
 
57
    if( data[i++] != '*' )
 
58
    {
 
59
        return 0;
 
60
    }
 
61
    if( i >= datalen )
 
62
    {
 
63
        return 0;
 
64
    }
 
65
    if( data[i++] != 's' )
 
66
    {
 
67
        return 0;
 
68
    }
 
69
    while( 42 )
 
70
    {
 
71
        if( i >= datalen )
 
72
        {
 
73
            return 0;
 
74
        }
 
75
        d = data[i] - '0';
 
76
        if( d > 9 )
 
77
        {
 
78
            break;
 
79
        }
 
80
        i++;
 
81
    }
 
82
    d = data[i++];
 
83
    if( d<'a' || d>'z' )
 
84
    {
 
85
        return 0;
 
86
    }
 
87
    while( 42 )
 
88
    {
 
89
        if( i >= datalen )
 
90
        {
 
91
            return 0;
 
92
        }
 
93
        d = data[i] - '0';
 
94
        if( d > 9 )
 
95
        {
 
96
            break;
 
97
        }
 
98
        i++;
 
99
        value = ( value * 10 ) + d;
 
100
    }
 
101
    if( i >= datalen )
 
102
    {
 
103
        return 0;
 
104
    }
 
105
    if( data[i++] != 'W' )
 
106
    {
 
107
        return 0;
 
108
    }
 
109
    value = i + value - datalen;
 
110
    if( value < 0 )
 
111
    {
 
112
        value = 0;
 
113
    }
 
114
    return value;
 
115
}
 
116
 
 
117
 
 
118
static int SclChannelRead(int deviceid, int channelid, char * buffer, int countdown, int isSclResponse)
 
119
{
 
120
    char * bufferStart = buffer;
 
121
    int bufferLen = countdown, countup = 0, len;
 
122
    enum HPMUD_RESULT stat;
 
123
 
 
124
    if(!isSclResponse)
 
125
    {
 
126
        stat = hpmud_read_channel(deviceid, channelid, buffer, bufferLen, EXCEPTION_TIMEOUT, &len);  
 
127
        return len;
 
128
    }
 
129
 
 
130
    while(1)
 
131
    {
 
132
        stat = hpmud_read_channel(deviceid, channelid, buffer, countdown, EXCEPTION_TIMEOUT, &len);                                      
 
133
 
 
134
        if(stat != HPMUD_R_OK)
 
135
        {
 
136
            break;
 
137
        }
 
138
        countup += len;
 
139
 
 
140
        countdown = SclBufferIsPartialReply( (unsigned char *)bufferStart, countup );
 
141
        
 
142
        if( countup + countdown > bufferLen )
 
143
        {
 
144
            countdown = bufferLen - countup;
 
145
        }
 
146
        if( countdown <= 0 )
 
147
        {
 
148
            break;
 
149
        }
 
150
 
 
151
        buffer += len;
 
152
        //startTimeout = continueTimeout;
 
153
    }
 
154
 
 
155
    if(!countup)
 
156
    {
 
157
        return len;
 
158
    }
 
159
    return countup;
 
160
 
 
161
}
 
162
 
 
163
SANE_Status __attribute__ ((visibility ("hidden"))) SclSendCommand(int deviceid, int channelid, int cmd, int param)
 
164
{
 
165
    char buffer[LEN_SCL_BUFFER];
 
166
    int datalen, len;
 
167
    char punc = SCL_CMD_PUNC( cmd );
 
168
    char letter1 = SCL_CMD_LETTER1( cmd),letter2 = SCL_CMD_LETTER2( cmd );
 
169
 
 
170
    if( cmd == SCL_CMD_RESET )
 
171
    {
 
172
        datalen = snprintf( buffer, LEN_SCL_BUFFER, "\x1B%c", letter2 );
 
173
    }
 
174
    else
 
175
    {
 
176
        if( cmd == SCL_CMD_CLEAR_ERROR_STACK )
 
177
        {
 
178
            datalen = snprintf( buffer,
 
179
                                LEN_SCL_BUFFER,
 
180
                                "\x1B%c%c%c",
 
181
                                punc,
 
182
                                letter1,
 
183
                                letter2 );
 
184
        }
 
185
        else
 
186
        {
 
187
            datalen = snprintf( buffer,
 
188
                                LEN_SCL_BUFFER,
 
189
                                "\x1B%c%c%d%c",
 
190
                                punc,
 
191
                                letter1,
 
192
                                param,
 
193
                                letter2 );
 
194
        }
 
195
    }
 
196
 
 
197
    hpmud_write_channel(deviceid, channelid, buffer, datalen, EXCEPTION_TIMEOUT, &len);
 
198
 
 
199
    DBG(6, "SclSendCommand: size=%d bytes_wrote=%d: %s %d\n", datalen, len, __FILE__, __LINE__);
 
200
    if (DBG_LEVEL >= 6)
 
201
       sysdump(buffer, datalen);
 
202
 
 
203
    if(len != datalen)
 
204
    {
 
205
        return SANE_STATUS_IO_ERROR;
 
206
    }
 
207
 
 
208
    return SANE_STATUS_GOOD;
 
209
}
 
210
 
 
211
SANE_Status __attribute__ ((visibility ("hidden"))) SclInquire(int deviceid, int channelid, int cmd, int param, int * pValue, char * buffer, int maxlen)
 
212
{
 
213
    SANE_Status retcode;
 
214
    int lenResponse, len, value;
 
215
    char _response[LEN_SCL_BUFFER + 1], * response = _response;
 
216
    char expected[LEN_SCL_BUFFER], expectedChar;
 
217
 
 
218
    if( !pValue )
 
219
    {
 
220
        pValue = &value;
 
221
    }
 
222
    if( buffer && maxlen > 0 )
 
223
    {
 
224
        memset( buffer, 0, maxlen );
 
225
    }
 
226
    memset( _response, 0, LEN_SCL_BUFFER + 1 );
 
227
 
 
228
    /* Send inquiry command. */
 
229
    if( ( retcode = SclSendCommand( deviceid, channelid, cmd, param ) ) != SANE_STATUS_GOOD )
 
230
    {
 
231
        return retcode;
 
232
    }
 
233
 
 
234
    /* Figure out what format of response we expect. */
 
235
    expectedChar = SCL_CMD_LETTER2( cmd ) - 'A' + 'a' - 1;
 
236
    if( expectedChar == 'q' )
 
237
    {
 
238
        expectedChar--;
 
239
    }
 
240
    len = snprintf( expected,
 
241
                    LEN_SCL_BUFFER,
 
242
                    "\x1B%c%c%d%c",
 
243
                    SCL_CMD_PUNC( cmd ),
 
244
                    SCL_CMD_LETTER1( cmd ),
 
245
                    param,
 
246
                    expectedChar );
 
247
 
 
248
    /* Read the response. */
 
249
    lenResponse = SclChannelRead( deviceid, channelid, response, LEN_SCL_BUFFER, 1 );
 
250
                                      
 
251
    DBG(6, "SclChannelRead: len=%d: %s %d\n", lenResponse, __FILE__, __LINE__);
 
252
    if (DBG_LEVEL >= 6)
 
253
       sysdump(response, lenResponse);
 
254
 
 
255
    /* Validate the first part of the response. */
 
256
    if( lenResponse <= len || memcmp( response, expected, len ) )
 
257
    {
 
258
        bug("invalid SclInquire(cmd=%x,param=%d) exp(len=%d)/act(len=%d): %s %d\n", cmd, param, len, lenResponse, __FILE__, __LINE__);
 
259
        bug("exp:\n");
 
260
        bugdump(expected, len);
 
261
        bug("act:\n");
 
262
        bugdump(response, lenResponse);
 
263
        return SANE_STATUS_IO_ERROR;
 
264
    }
 
265
    response += len;
 
266
    lenResponse -= len;
 
267
 
 
268
    /* Null response? */
 
269
    if( response[0] == 'N' )
 
270
    {
 
271
        DBG(6, "SclInquire null response. %s %d\n", __FILE__, __LINE__);
 
272
        return SANE_STATUS_UNSUPPORTED;
 
273
    }
 
274
 
 
275
    /* Parse integer part of non-null response.
 
276
     * If this is a binary-data response, then this value is the
 
277
     * length of the binary-data portion. */
 
278
    if( sscanf( response, "%d%n", pValue, &len ) != 1 )
 
279
    {
 
280
        bug("invalid SclInquire(cmd=%x,param=%d) integer response: %s %d\n", cmd, param, __FILE__, __LINE__);
 
281
        return SANE_STATUS_IO_ERROR;
 
282
    }
 
283
 
 
284
    /* Integer response? */
 
285
    if( response[len] == 'V' )
 
286
    {
 
287
        return SANE_STATUS_GOOD;
 
288
    }
 
289
 
 
290
    /* Binary-data response? */
 
291
    if( response[len] != 'W' )
 
292
    {
 
293
        bug("invalid SclInquire(cmd=%x,param=%d) unexpected character '%c': %s %d\n", cmd, param, response[len], __FILE__, __LINE__);
 
294
        return SANE_STATUS_IO_ERROR;
 
295
    }
 
296
    response += len + 1;
 
297
    lenResponse -= len + 1;
 
298
 
 
299
    /* Make sure we got the right length of binary data. */
 
300
    if( lenResponse<0 || lenResponse != *pValue || lenResponse>maxlen )
 
301
    {
 
302
        bug("invalid SclInquire(cmd=%x,param=%d) binary data lenResponse=%d *pValue=%d maxlen=%d: %s %d\n", 
 
303
                             cmd, param, lenResponse, *pValue, maxlen, __FILE__, __LINE__);
 
304
        return SANE_STATUS_IO_ERROR;
 
305
    }
 
306
 
 
307
    /* Copy binary data into user's buffer. */
 
308
    if( buffer )
 
309
    {
 
310
        maxlen = *pValue;
 
311
        memcpy( buffer, response, maxlen );
 
312
    }
 
313
 
 
314
    return SANE_STATUS_GOOD;
 
315
}
 
316
 
 
317
/*
 
318
 * Phase 2 partial rewrite. des 9/26/07
 
319
 */
 
320
 
 
321
SANE_Status __attribute__ ((visibility ("hidden"))) scl_send_cmd(HPAIO_RECORD *hpaio, const char *buf, int size)
 
322
{
 
323
    int len;
 
324
    
 
325
    hpmud_write_channel(hpaio->deviceid, hpaio->scan_channelid, buf, size, EXCEPTION_TIMEOUT, &len);
 
326
 
 
327
    DBG(6, "scl cmd sent size=%d bytes_wrote=%d: %s %d\n", size, len, __FILE__, __LINE__);
 
328
    if (DBG_LEVEL >= 6)
 
329
       sysdump(buf, size);
 
330
 
 
331
    if(len != size)
 
332
    {
 
333
        return SANE_STATUS_IO_ERROR;
 
334
    }
 
335
 
 
336
    return SANE_STATUS_GOOD;
 
337
}
 
338
 
 
339
SANE_Status __attribute__ ((visibility ("hidden"))) scl_query_int(HPAIO_RECORD *hpaio, const char *buf, int size, int *result)
 
340
{
 
341
    char rbuf[256];
 
342
    int len, stat;
 
343
    char *tail;
 
344
 
 
345
    *result=0;
 
346
 
 
347
    if ((stat = scl_send_cmd(hpaio, buf, size)) != SANE_STATUS_GOOD)
 
348
    {
 
349
        return stat;
 
350
    }
 
351
 
 
352
    if ((stat = hpmud_read_channel(hpaio->deviceid, hpaio->scan_channelid, rbuf, sizeof(rbuf), EXCEPTION_TIMEOUT, &len)) != HPMUD_R_OK)
 
353
    {
 
354
        return SANE_STATUS_IO_ERROR;
 
355
    }
 
356
 
 
357
    DBG(6, "scl response size=%d: %s %d\n", len, __FILE__, __LINE__);
 
358
    if (DBG_LEVEL >= 6)
 
359
       sysdump(buf, size);
 
360
 
 
361
    /* Null response? */
 
362
    if(rbuf[len-1] == 'N')
 
363
    {
 
364
        DBG(6, "scl null response: %s %d\n", __FILE__, __LINE__);
 
365
        return SANE_STATUS_UNSUPPORTED;
 
366
    }
 
367
        
 
368
    /* Integer response? */
 
369
    if(rbuf[len-1] != 'V' )
 
370
    {
 
371
        bug("invalid scl integer response: %s %d\n", __FILE__, __LINE__);
 
372
        return SANE_STATUS_IO_ERROR;
 
373
    }
 
374
 
 
375
    *result = strtol(&rbuf[size], &tail, 10);
 
376
 
 
377
    return SANE_STATUS_GOOD;
 
378
}
 
379