]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
2e4ff8af | 2 | * "$Id: ieee1284.c 7019 2007-10-10 22:48:52Z mike $" |
ef416fc2 | 3 | * |
4 | * IEEE-1284 support functions for the Common UNIX Printing System (CUPS). | |
5 | * | |
bc44d920 | 6 | * Copyright 2007 by Apple Inc. |
f7deaa1a | 7 | * Copyright 1997-2007 by Easy Software Products, all rights reserved. |
ef416fc2 | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
bc44d920 | 10 | * property of Apple Inc. and are protected by Federal copyright |
11 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
ef416fc2 | 12 | * "LICENSE" which should have been included with this file. If this |
bc44d920 | 13 | * file is missing or damaged, see the license at "http://www.cups.org/". |
ef416fc2 | 14 | * |
15 | * This file is subject to the Apple OS-Developed Software exception. | |
16 | * | |
17 | * Contents: | |
18 | * | |
ed486911 | 19 | * backendGetDeviceID() - Get the IEEE-1284 device ID string and |
20 | * corresponding URI. | |
21 | * backendGetMakeModel() - Get the make and model string from the device ID. | |
ef416fc2 | 22 | */ |
23 | ||
24 | /* | |
25 | * Include necessary headers. | |
26 | */ | |
27 | ||
ed486911 | 28 | #include "backend-private.h" |
ef416fc2 | 29 | |
ed486911 | 30 | #ifdef __linux |
31 | # include <sys/ioctl.h> | |
32 | # include <linux/lp.h> | |
33 | # define IOCNR_GET_DEVICE_ID 1 | |
34 | # define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len) | |
2e4ff8af MS |
35 | # include <linux/parport.h> |
36 | # include <linux/ppdev.h> | |
37 | # include <unistd.h> | |
38 | # include <fcntl.h> | |
ed486911 | 39 | #endif /* __linux */ |
89d46774 | 40 | |
ed486911 | 41 | #ifdef __sun |
42 | # ifdef __sparc | |
43 | # include <sys/ecppio.h> | |
44 | # else | |
45 | # include <sys/ioccom.h> | |
46 | # include <sys/ecppsys.h> | |
47 | # endif /* __sparc */ | |
48 | #endif /* __sun */ | |
ef416fc2 | 49 | |
50 | ||
51 | /* | |
ed486911 | 52 | * 'backendGetDeviceID()' - Get the IEEE-1284 device ID string and |
53 | * corresponding URI. | |
ef416fc2 | 54 | */ |
55 | ||
56 | int /* O - 0 on success, -1 on failure */ | |
ed486911 | 57 | backendGetDeviceID( |
ef416fc2 | 58 | int fd, /* I - File descriptor */ |
59 | char *device_id, /* O - 1284 device ID */ | |
60 | int device_id_size, /* I - Size of buffer */ | |
61 | char *make_model, /* O - Make/model */ | |
62 | int make_model_size, /* I - Size of buffer */ | |
63 | const char *scheme, /* I - URI scheme */ | |
64 | char *uri, /* O - Device URI */ | |
65 | int uri_size) /* I - Size of buffer */ | |
66 | { | |
db0bd74a MS |
67 | #ifdef __APPLE__ /* This function is a no-op */ |
68 | return (-1); | |
69 | ||
70 | #else /* Get the device ID from the specified file descriptor... */ | |
ef416fc2 | 71 | char *attr, /* 1284 attribute */ |
72 | *delim, /* 1284 delimiter */ | |
73 | *uriptr, /* Pointer into URI */ | |
89d46774 | 74 | manufacturer[256], /* Manufacturer string */ |
ef416fc2 | 75 | serial_number[1024]; /* Serial number string */ |
89d46774 | 76 | int manulen; /* Length of manufacturer string */ |
db0bd74a | 77 | # ifdef __linux |
ef416fc2 | 78 | int length; /* Length of device ID info */ |
2e4ff8af | 79 | int got_id = 0; |
db0bd74a MS |
80 | # endif /* __linux */ |
81 | # if defined(__sun) && defined(ECPPIOC_GETDEVID) | |
ef416fc2 | 82 | struct ecpp_device_id did; /* Device ID buffer */ |
db0bd74a | 83 | # endif /* __sun && ECPPIOC_GETDEVID */ |
ef416fc2 | 84 | |
89d46774 | 85 | |
ed486911 | 86 | DEBUG_printf(("backendGetDeviceID(fd=%d, device_id=%p, device_id_size=%d, " |
ef416fc2 | 87 | "make_model=%p, make_model_size=%d, scheme=\"%s\", " |
88 | "uri=%p, uri_size=%d)\n", fd, device_id, device_id_size, | |
89 | make_model, make_model_size, scheme ? scheme : "(null)", | |
90 | uri, uri_size)); | |
91 | ||
92 | /* | |
93 | * Range check input... | |
94 | */ | |
95 | ||
f7deaa1a | 96 | if (!device_id || device_id_size < 32) |
ef416fc2 | 97 | { |
ed486911 | 98 | DEBUG_puts("backendGetDeviceID: Bad args!"); |
ef416fc2 | 99 | return (-1); |
100 | } | |
101 | ||
f7deaa1a | 102 | if (make_model) |
103 | *make_model = '\0'; | |
ef416fc2 | 104 | |
f7deaa1a | 105 | if (fd >= 0) |
ef416fc2 | 106 | { |
107 | /* | |
f7deaa1a | 108 | * Get the device ID string... |
ef416fc2 | 109 | */ |
110 | ||
f7deaa1a | 111 | *device_id = '\0'; |
ef416fc2 | 112 | |
db0bd74a | 113 | # ifdef __linux |
2e4ff8af MS |
114 | if (ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id)) |
115 | { | |
116 | /* | |
117 | * Linux has to implement things differently for every device it seems. | |
118 | * Since the standard parallel port driver does not provide a simple | |
119 | * ioctl() to get the 1284 device ID, we have to open the "raw" parallel | |
120 | * device corresponding to this port and do some negotiation trickery | |
121 | * to get the current device ID. | |
122 | */ | |
123 | ||
124 | if (uri && !strncmp(uri, "parallel:/dev/", 14)) | |
125 | { | |
126 | char devparport[16]; /* /dev/parportN */ | |
127 | int devparportfd, /* File descriptor for raw device */ | |
2e4ff8af MS |
128 | mode; /* Port mode */ |
129 | ||
130 | ||
131 | /* | |
132 | * Since the Linux parallel backend only supports 4 parallel port | |
133 | * devices, just grab the trailing digit and use it to construct a | |
134 | * /dev/parportN filename... | |
135 | */ | |
136 | ||
137 | snprintf(devparport, sizeof(devparport), "/dev/parport%s", | |
138 | uri + strlen(uri) - 1); | |
139 | ||
140 | if ((devparportfd = open(devparport, O_RDWR | O_NOCTTY)) != -1) | |
141 | { | |
142 | /* | |
143 | * Claim the device... | |
144 | */ | |
145 | ||
146 | if (!ioctl(devparportfd, PPCLAIM)) | |
147 | { | |
0a682745 | 148 | fcntl(devparportfd, F_SETFL, fcntl(devparportfd, F_GETFL) | O_NONBLOCK); |
2e4ff8af MS |
149 | |
150 | mode = IEEE1284_MODE_COMPAT; | |
151 | ||
152 | if (!ioctl(devparportfd, PPNEGOT, &mode)) | |
153 | { | |
154 | /* | |
155 | * Put the device into Device ID mode... | |
156 | */ | |
157 | ||
158 | mode = IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID; | |
159 | ||
160 | if (!ioctl(devparportfd, PPNEGOT, &mode)) | |
161 | { | |
162 | /* | |
163 | * Read the 1284 device ID... | |
164 | */ | |
165 | ||
166 | if ((length = read(devparportfd, device_id, | |
167 | device_id_size - 1)) >= 2) | |
168 | { | |
169 | device_id[length] = '\0'; | |
170 | got_id = 1; | |
171 | } | |
172 | } | |
173 | } | |
174 | ||
175 | /* | |
176 | * Release the device... | |
177 | */ | |
178 | ||
179 | ioctl(devparportfd, PPRELEASE); | |
180 | } | |
181 | ||
182 | close(devparportfd); | |
183 | } | |
184 | } | |
185 | } | |
186 | else | |
187 | got_id = 1; | |
188 | ||
189 | if (got_id) | |
f7deaa1a | 190 | { |
191 | /* | |
192 | * Extract the length of the device ID string from the first two | |
193 | * bytes. The 1284 spec says the length is stored MSB first... | |
194 | */ | |
ef416fc2 | 195 | |
f7deaa1a | 196 | length = (((unsigned)device_id[0] & 255) << 8) + |
197 | ((unsigned)device_id[1] & 255); | |
ef416fc2 | 198 | |
f7deaa1a | 199 | /* |
200 | * Check to see if the length is larger than our buffer; first | |
201 | * assume that the vendor incorrectly implemented the 1284 spec, | |
202 | * and then limit the length to the size of our buffer... | |
203 | */ | |
ef416fc2 | 204 | |
f7deaa1a | 205 | if (length > (device_id_size - 2)) |
206 | length = (((unsigned)device_id[1] & 255) << 8) + | |
207 | ((unsigned)device_id[0] & 255); | |
ef416fc2 | 208 | |
f7deaa1a | 209 | if (length > (device_id_size - 2)) |
210 | length = device_id_size - 2; | |
211 | ||
212 | /* | |
213 | * Copy the device ID text to the beginning of the buffer and | |
214 | * nul-terminate. | |
215 | */ | |
216 | ||
217 | memmove(device_id, device_id + 2, length); | |
218 | device_id[length] = '\0'; | |
219 | } | |
db0bd74a | 220 | # ifdef DEBUG |
f7deaa1a | 221 | else |
222 | printf("backendGetDeviceID: ioctl failed - %s\n", strerror(errno)); | |
db0bd74a MS |
223 | # endif /* DEBUG */ |
224 | # endif /* __linux */ | |
ef416fc2 | 225 | |
db0bd74a | 226 | # if defined(__sun) && defined(ECPPIOC_GETDEVID) |
f7deaa1a | 227 | did.mode = ECPP_CENTRONICS; |
228 | did.len = device_id_size - 1; | |
229 | did.rlen = 0; | |
230 | did.addr = device_id; | |
ef416fc2 | 231 | |
f7deaa1a | 232 | if (!ioctl(fd, ECPPIOC_GETDEVID, &did)) |
233 | { | |
234 | /* | |
235 | * Nul-terminate the device ID text. | |
236 | */ | |
ef416fc2 | 237 | |
f7deaa1a | 238 | if (did.rlen < (device_id_size - 1)) |
239 | device_id[did.rlen] = '\0'; | |
240 | else | |
241 | device_id[device_id_size - 1] = '\0'; | |
242 | } | |
db0bd74a | 243 | # ifdef DEBUG |
f7deaa1a | 244 | else |
245 | printf("backendGetDeviceID: ioctl failed - %s\n", strerror(errno)); | |
db0bd74a MS |
246 | # endif /* DEBUG */ |
247 | # endif /* __sun && ECPPIOC_GETDEVID */ | |
f7deaa1a | 248 | } |
ef416fc2 | 249 | |
ed486911 | 250 | DEBUG_printf(("backendGetDeviceID: device_id=\"%s\"\n", device_id)); |
ef416fc2 | 251 | |
2e4ff8af MS |
252 | if (scheme && uri) |
253 | *uri = '\0'; | |
254 | ||
ef416fc2 | 255 | if (!*device_id) |
256 | return (-1); | |
257 | ||
89d46774 | 258 | /* |
259 | * Get the make and model... | |
260 | */ | |
261 | ||
f7deaa1a | 262 | if (make_model) |
263 | backendGetMakeModel(device_id, make_model, make_model_size); | |
89d46774 | 264 | |
265 | /* | |
266 | * Then generate a device URI... | |
267 | */ | |
268 | ||
269 | if (scheme && uri && uri_size > 32) | |
270 | { | |
271 | /* | |
272 | * Look for the serial number field... | |
273 | */ | |
274 | ||
275 | if ((attr = strstr(device_id, "SERN:")) != NULL) | |
276 | attr += 5; | |
277 | else if ((attr = strstr(device_id, "SERIALNUMBER:")) != NULL) | |
278 | attr += 13; | |
279 | else if ((attr = strstr(device_id, ";SN:")) != NULL) | |
280 | attr += 4; | |
281 | ||
282 | if (attr) | |
283 | { | |
284 | strlcpy(serial_number, attr, sizeof(serial_number)); | |
285 | ||
286 | if ((delim = strchr(serial_number, ';')) != NULL) | |
287 | *delim = '\0'; | |
288 | } | |
289 | else | |
290 | serial_number[0] = '\0'; | |
291 | ||
292 | /* | |
293 | * Generate the device URI from the manufacturer, make_model, and | |
294 | * serial number strings. | |
295 | */ | |
296 | ||
297 | snprintf(uri, uri_size, "%s://", scheme); | |
298 | ||
299 | if ((attr = strstr(device_id, "MANUFACTURER:")) != NULL) | |
300 | attr += 13; | |
301 | else if ((attr = strstr(device_id, "Manufacturer:")) != NULL) | |
302 | attr += 13; | |
303 | else if ((attr = strstr(device_id, "MFG:")) != NULL) | |
304 | attr += 4; | |
305 | ||
306 | if (attr) | |
307 | { | |
308 | strlcpy(manufacturer, attr, sizeof(manufacturer)); | |
309 | ||
310 | if ((delim = strchr(manufacturer, ';')) != NULL) | |
311 | *delim = '\0'; | |
312 | ||
313 | if (!strcasecmp(manufacturer, "Hewlett-Packard")) | |
314 | strcpy(manufacturer, "HP"); | |
d09495fa | 315 | else if (!strcasecmp(manufacturer, "Lexmark International")) |
316 | strcpy(manufacturer, "Lexmark"); | |
89d46774 | 317 | } |
318 | else | |
319 | { | |
320 | strlcpy(manufacturer, make_model, sizeof(manufacturer)); | |
321 | ||
322 | if ((delim = strchr(manufacturer, ' ')) != NULL) | |
323 | *delim = '\0'; | |
324 | } | |
325 | ||
326 | manulen = strlen(manufacturer); | |
327 | ||
328 | for (uriptr = uri + strlen(uri), delim = manufacturer; | |
329 | *delim && uriptr < (uri + uri_size - 3); | |
330 | delim ++) | |
331 | if (*delim == ' ') | |
332 | { | |
333 | *uriptr++ = '%'; | |
334 | *uriptr++ = '2'; | |
335 | *uriptr++ = '0'; | |
336 | } | |
337 | else | |
338 | *uriptr++ = *delim; | |
339 | ||
340 | *uriptr++ = '/'; | |
341 | ||
342 | if (!strncasecmp(make_model, manufacturer, manulen)) | |
343 | { | |
344 | delim = make_model + manulen; | |
345 | ||
346 | while (isspace(*delim & 255)) | |
347 | delim ++; | |
348 | } | |
349 | else | |
350 | delim = make_model; | |
351 | ||
352 | for (; *delim && uriptr < (uri + uri_size - 3); delim ++) | |
353 | if (*delim == ' ') | |
354 | { | |
355 | *uriptr++ = '%'; | |
356 | *uriptr++ = '2'; | |
357 | *uriptr++ = '0'; | |
358 | } | |
359 | else | |
360 | *uriptr++ = *delim; | |
361 | ||
362 | if (serial_number[0]) | |
363 | { | |
364 | /* | |
365 | * Add the serial number to the URI... | |
366 | */ | |
367 | ||
368 | strlcpy(uriptr, "?serial=", uri_size - (uriptr - uri)); | |
369 | strlcat(uriptr, serial_number, uri_size - (uriptr - uri)); | |
370 | } | |
371 | else | |
372 | *uriptr = '\0'; | |
373 | } | |
374 | ||
375 | return (0); | |
db0bd74a | 376 | #endif /* __APPLE__ */ |
89d46774 | 377 | } |
89d46774 | 378 | |
379 | ||
380 | /* | |
ed486911 | 381 | * 'backendGetMakeModel()' - Get the make and model string from the device ID. |
89d46774 | 382 | */ |
383 | ||
384 | int /* O - 0 on success, -1 on failure */ | |
ed486911 | 385 | backendGetMakeModel( |
89d46774 | 386 | const char *device_id, /* O - 1284 device ID */ |
387 | char *make_model, /* O - Make/model */ | |
388 | int make_model_size) /* I - Size of buffer */ | |
389 | { | |
390 | char *attr, /* 1284 attribute */ | |
391 | *delim, /* 1284 delimiter */ | |
392 | *mfg, /* Manufacturer string */ | |
393 | *mdl; /* Model string */ | |
394 | ||
395 | ||
ed486911 | 396 | DEBUG_printf(("backendGetMakeModel(device_id=\"%s\", " |
89d46774 | 397 | "make_model=%p, make_model_size=%d)\n", device_id, |
398 | make_model, make_model_size)); | |
399 | ||
400 | /* | |
401 | * Range check input... | |
402 | */ | |
403 | ||
404 | if (!device_id || !*device_id || !make_model || make_model_size < 32) | |
405 | { | |
ed486911 | 406 | DEBUG_puts("backendGetMakeModel: Bad args!"); |
89d46774 | 407 | return (-1); |
408 | } | |
409 | ||
410 | *make_model = '\0'; | |
411 | ||
ef416fc2 | 412 | /* |
413 | * Look for the description field... | |
414 | */ | |
415 | ||
416 | if ((attr = strstr(device_id, "DES:")) != NULL) | |
417 | attr += 4; | |
418 | else if ((attr = strstr(device_id, "DESCRIPTION:")) != NULL) | |
419 | attr += 12; | |
420 | ||
421 | if (attr) | |
422 | { | |
423 | /* | |
424 | * Make sure the description contains something useful, since some | |
425 | * printer manufacturers (HP) apparently don't follow the standards | |
426 | * they helped to define... | |
427 | * | |
428 | * Here we require the description to be 8 or more characters in length, | |
429 | * containing at least one space and one letter. | |
430 | */ | |
431 | ||
432 | if ((delim = strchr(attr, ';')) == NULL) | |
433 | delim = attr + strlen(attr); | |
434 | ||
435 | if ((delim - attr) < 8) | |
436 | attr = NULL; | |
437 | else | |
438 | { | |
439 | char *ptr; /* Pointer into description */ | |
440 | int letters, /* Number of letters seen */ | |
441 | spaces; /* Number of spaces seen */ | |
442 | ||
443 | ||
444 | for (ptr = attr, letters = 0, spaces = 0; ptr < delim; ptr ++) | |
445 | { | |
446 | if (isspace(*ptr & 255)) | |
447 | spaces ++; | |
448 | else if (isalpha(*ptr & 255)) | |
449 | letters ++; | |
450 | ||
451 | if (spaces && letters) | |
452 | break; | |
453 | } | |
454 | ||
455 | if (!spaces || !letters) | |
456 | attr = NULL; | |
457 | } | |
458 | } | |
459 | ||
460 | if ((mfg = strstr(device_id, "MANUFACTURER:")) != NULL) | |
461 | mfg += 13; | |
89d46774 | 462 | else if ((mfg = strstr(device_id, "Manufacturer:")) != NULL) |
463 | mfg += 13; | |
ef416fc2 | 464 | else if ((mfg = strstr(device_id, "MFG:")) != NULL) |
465 | mfg += 4; | |
466 | ||
467 | if ((mdl = strstr(device_id, "MODEL:")) != NULL) | |
468 | mdl += 6; | |
89d46774 | 469 | else if ((mdl = strstr(device_id, "Model:")) != NULL) |
470 | mdl += 6; | |
ef416fc2 | 471 | else if ((mdl = strstr(device_id, "MDL:")) != NULL) |
472 | mdl += 4; | |
473 | ||
89d46774 | 474 | if (mdl) |
ef416fc2 | 475 | { |
476 | /* | |
89d46774 | 477 | * Build a make-model string from the manufacturer and model attributes... |
ef416fc2 | 478 | */ |
479 | ||
89d46774 | 480 | if (mfg) |
ef416fc2 | 481 | { |
db0bd74a MS |
482 | /* |
483 | * Skip leading whitespace... | |
484 | */ | |
485 | ||
486 | while (isspace(*mfg & 255)) | |
487 | mfg ++; | |
488 | ||
489 | /* | |
490 | * Map common bad names to the ones we use for driver selection... | |
491 | */ | |
492 | ||
89d46774 | 493 | if (!strncasecmp(mfg, "Hewlett-Packard", 15)) |
494 | strlcpy(make_model, "HP", make_model_size); | |
d09495fa | 495 | else if (!strncasecmp(mfg, "Lexmark International", 21)) |
496 | strlcpy(make_model, "Lexmark", make_model_size); | |
89d46774 | 497 | else |
db0bd74a MS |
498 | { |
499 | /* | |
500 | * Use the manufacturer that is supplied... | |
501 | */ | |
502 | ||
89d46774 | 503 | strlcpy(make_model, mfg, make_model_size); |
ef416fc2 | 504 | |
db0bd74a MS |
505 | if ((delim = strchr(make_model, ';')) != NULL) |
506 | *delim = '\0'; | |
507 | ||
508 | /* | |
509 | * But strip trailing whitespace... | |
510 | */ | |
511 | ||
512 | for (delim = make_model + strlen(make_model) - 1; | |
513 | delim > make_model && *delim == ' '; | |
514 | delim --) | |
515 | *delim = '\0'; | |
516 | } | |
89d46774 | 517 | |
518 | if (!strncasecmp(make_model, mdl, strlen(make_model))) | |
519 | { | |
520 | /* | |
521 | * Just copy model string, since it has the manufacturer... | |
522 | */ | |
523 | ||
524 | strlcpy(make_model, mdl, make_model_size); | |
525 | } | |
526 | else | |
527 | { | |
528 | /* | |
529 | * Concatenate the make and model... | |
530 | */ | |
531 | ||
db0bd74a MS |
532 | while (isspace(*mdl & 255)) |
533 | mdl ++; | |
534 | ||
89d46774 | 535 | strlcat(make_model, " ", make_model_size); |
536 | strlcat(make_model, mdl, make_model_size); | |
537 | } | |
ef416fc2 | 538 | } |
539 | else | |
540 | { | |
89d46774 | 541 | /* |
542 | * Just copy model string, since it has the manufacturer... | |
543 | */ | |
544 | ||
db0bd74a MS |
545 | while (isspace(*mdl & 255)) |
546 | mdl ++; | |
547 | ||
89d46774 | 548 | strlcpy(make_model, mdl, make_model_size); |
ef416fc2 | 549 | } |
550 | } | |
89d46774 | 551 | else if (attr) |
ef416fc2 | 552 | { |
553 | /* | |
89d46774 | 554 | * Use description... |
ef416fc2 | 555 | */ |
556 | ||
db0bd74a MS |
557 | while (isspace(*attr & 255)) |
558 | attr ++; | |
559 | ||
89d46774 | 560 | if (!strncasecmp(attr, "Hewlett-Packard hp ", 19)) |
ef416fc2 | 561 | { |
562 | /* | |
89d46774 | 563 | * Check for a common HP bug... |
ef416fc2 | 564 | */ |
565 | ||
89d46774 | 566 | strlcpy(make_model, "HP ", make_model_size); |
567 | strlcpy(make_model + 3, attr + 19, make_model_size - 3); | |
568 | } | |
569 | else if (!strncasecmp(attr, "Hewlett-Packard ", 16)) | |
570 | { | |
571 | strlcpy(make_model, "HP ", make_model_size); | |
572 | strlcpy(make_model + 3, attr + 16, make_model_size - 3); | |
ef416fc2 | 573 | } |
574 | else | |
575 | { | |
89d46774 | 576 | strlcpy(make_model, attr, make_model_size); |
ef416fc2 | 577 | } |
578 | } | |
579 | else | |
580 | { | |
581 | /* | |
582 | * Use "Unknown" as the printer make and model... | |
583 | */ | |
584 | ||
585 | strlcpy(make_model, "Unknown", make_model_size); | |
586 | } | |
587 | ||
89d46774 | 588 | /* |
589 | * Strip trailing data... | |
590 | */ | |
591 | ||
ef416fc2 | 592 | if ((delim = strchr(make_model, ';')) != NULL) |
593 | *delim = '\0'; | |
594 | ||
db0bd74a MS |
595 | for (delim = make_model + strlen(make_model) - 1; |
596 | delim > make_model && *delim == ' '; | |
597 | delim --) | |
598 | *delim = '\0'; | |
599 | ||
89d46774 | 600 | /* |
601 | * Strip trailing whitespace... | |
602 | */ | |
ef416fc2 | 603 | |
89d46774 | 604 | for (delim = make_model + strlen(make_model) - 1; delim >= make_model; delim --) |
605 | if (isspace(*delim & 255)) | |
606 | *delim = '\0'; | |
ef416fc2 | 607 | else |
89d46774 | 608 | break; |
ef416fc2 | 609 | |
89d46774 | 610 | /* |
611 | * Return... | |
612 | */ | |
ef416fc2 | 613 | |
89d46774 | 614 | if (make_model[0]) |
615 | return (0); | |
616 | else | |
617 | return (-1); | |
ef416fc2 | 618 | } |
619 | ||
620 | ||
621 | /* | |
2e4ff8af | 622 | * End of "$Id: ieee1284.c 7019 2007-10-10 22:48:52Z mike $". |
ef416fc2 | 623 | */ |