]> git.ipfire.org Git - thirdparty/cups.git/blame - backend/serial.c
Mirror 1.1.x changes.
[thirdparty/cups.git] / backend / serial.c
CommitLineData
43e2fc22 1/*
0cd4970e 2 * "$Id: serial.c,v 1.32.2.15 2003/08/30 23:12:59 mike Exp $"
43e2fc22 3 *
e73c6c0a 4 * Serial port backend for the Common UNIX Printing System (CUPS).
43e2fc22 5 *
1d9595ab 6 * Copyright 1997-2003 by Easy Software Products, all rights reserved.
43e2fc22 7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
8784b6a6 17 * 44141 Airport View Drive, Suite 204
43e2fc22 18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
dab1a4d8 24 * This file is subject to the Apple OS-Developed Software exception.
25 *
43e2fc22 26 * Contents:
27 *
a3e17a89 28 * main() - Send a file to the printer or server.
29 * list_devices() - List all serial devices.
43e2fc22 30 */
31
32/*
33 * Include necessary headers.
34 */
35
e73c6c0a 36#include <cups/cups.h>
37#include <stdio.h>
38#include <stdlib.h>
a3e17a89 39#include <errno.h>
e73c6c0a 40#include <cups/string.h>
4ff40357 41#include <signal.h>
e73c6c0a 42
8c8c32b0 43#ifdef __hpux
44# include <sys/modem.h>
45#endif /* __hpux */
46
c3026ddc 47#ifdef WIN32
7c88bf41 48# include <io.h>
49#else
50# include <unistd.h>
51# include <fcntl.h>
52# include <termios.h>
957d43b0 53# ifdef HAVE_SYS_IOCTL_H
c3258d2d 54# include <sys/ioctl.h>
f30537c6 55# endif /* HAVE_SYS_IOCTL_H */
c3026ddc 56#endif /* WIN32 */
7c88bf41 57
92a63e4c 58#ifdef __sgi
59# include <invent.h>
60# ifndef INV_EPP_ECP_PLP
61# define INV_EPP_ECP_PLP 6 /* From 6.3/6.4/6.5 sys/invent.h */
62# define INV_ASO_SERIAL 14 /* serial portion of SGI ASO board */
63# define INV_IOC3_DMA 16 /* DMA mode IOC3 serial */
64# define INV_IOC3_PIO 17 /* PIO mode IOC3 serial */
65# define INV_ISA_DMA 19 /* DMA mode ISA serial -- O2 */
66# endif /* !INV_EPP_ECP_PLP */
67#endif /* __sgi */
68
14aa7027 69#ifndef CRTSCTS
70# ifdef CNEW_RTSCTS
71# define CRTSCTS CNEW_RTSCTS
72# else
73# define CRTSCTS 0
74# endif /* CNEW_RTSCTS */
75#endif /* !CRTSCTS */
76
3cc7bca4 77#if defined(__APPLE__)
78# include <CoreFoundation/CoreFoundation.h>
79# include <IOKit/IOKitLib.h>
80# include <IOKit/serial/IOSerialKeys.h>
81# include <IOKit/IOBSD.h>
82#endif /* __APPLE__ */
83
e73c6c0a 84
68edc300 85/*
86 * Local functions...
87 */
88
89void list_devices(void);
90
91
e73c6c0a 92/*
93 * 'main()' - Send a file to the printer or server.
94 *
95 * Usage:
96 *
97 * printer-uri job-id user title copies options [file]
98 */
99
100int /* O - Exit status */
101main(int argc, /* I - Number of command-line arguments (6 or 7) */
102 char *argv[]) /* I - Command-line arguments */
103{
7c88bf41 104 char method[255], /* Method in URI */
105 hostname[1024], /* Hostname */
106 username[255], /* Username info (not used) */
107 resource[1024], /* Resource info (device and options) */
108 *options, /* Pointer to options */
109 name[255], /* Name of option */
110 value[255], /* Value of option */
111 *ptr; /* Pointer into name or value */
112 int port; /* Port number (not used) */
267cf96a 113 int fp; /* Print file */
3f9cb6c6 114 int copies; /* Number of copies to print */
7c88bf41 115 int fd; /* Parallel device */
1c33ff6a 116 int wbytes; /* Number of bytes written */
117 size_t nbytes, /* Number of bytes read */
7c88bf41 118 tbytes; /* Total number of bytes written */
14aa7027 119 int dtrdsr; /* Do dtr/dsr flow control? */
120 int bufsize; /* Size of output buffer for writes */
1c33ff6a 121 char buffer[8192], /* Output buffer */
122 *bufptr; /* Pointer into buffer */
8d5eb22e 123 struct termios opts; /* Serial port options */
124 struct termios origopts; /* Original port options */
4ff40357 125#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
126 struct sigaction action; /* Actions for POSIX signals */
127#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
7c88bf41 128
129
4b23f3b3 130 /*
131 * Make sure status messages are not buffered...
132 */
133
134 setbuf(stderr, NULL);
135
98904cd6 136 /*
137 * Ignore SIGPIPE signals...
138 */
139
140#ifdef HAVE_SIGSET
141 sigset(SIGPIPE, SIG_IGN);
142#elif defined(HAVE_SIGACTION)
143 memset(&action, 0, sizeof(action));
144 action.sa_handler = SIG_IGN;
145 sigaction(SIGPIPE, &action, NULL);
146#else
147 signal(SIGPIPE, SIG_IGN);
148#endif /* HAVE_SIGSET */
149
4b23f3b3 150 /*
151 * Check command-line...
152 */
153
68edc300 154 if (argc == 1)
155 {
156 list_devices();
157 return (0);
158 }
159 else if (argc < 6 || argc > 7)
e73c6c0a 160 {
7c88bf41 161 fputs("Usage: serial job-id user title copies options [file]\n", stderr);
e73c6c0a 162 return (1);
163 }
164
7c88bf41 165 /*
166 * If we have 7 arguments, print the file named on the command-line.
167 * Otherwise, send stdin instead...
168 */
169
170 if (argc == 6)
3f9cb6c6 171 {
267cf96a 172 fp = 0;
3f9cb6c6 173 copies = 1;
174 }
7c88bf41 175 else
176 {
177 /*
178 * Try to open the print file...
179 */
180
267cf96a 181 if ((fp = open(argv[6], O_RDONLY)) < 0)
7c88bf41 182 {
decc1f36 183 perror("ERROR: unable to open print file");
7c88bf41 184 return (1);
185 }
3f9cb6c6 186
187 copies = atoi(argv[4]);
7c88bf41 188 }
189
190 /*
191 * Extract the device name and options from the URI...
192 */
193
194 httpSeparate(argv[0], method, username, hostname, &port, resource);
195
196 /*
197 * See if there are any options...
198 */
199
200 if ((options = strchr(resource, '?')) != NULL)
201 {
202 /*
203 * Yup, terminate the device name string and move to the first
204 * character of the options...
205 */
206
207 *options++ = '\0';
208 }
209
210 /*
8ec4b03f 211 * Open the serial port device...
7c88bf41 212 */
213
a3e17a89 214 do
7c88bf41 215 {
753453e4 216 if ((fd = open(resource, O_WRONLY | O_NOCTTY | O_EXCL | O_NDELAY)) == -1)
a3e17a89 217 {
218 if (errno == EBUSY)
219 {
220 fputs("INFO: Serial port busy; will retry in 30 seconds...\n", stderr);
221 sleep(30);
222 }
223 else
224 {
7030b751 225 fprintf(stderr, "ERROR: Unable to open serial port device file \"%s\": %s\n",
226 resource, strerror(errno));
a3e17a89 227 return (1);
228 }
229 }
7c88bf41 230 }
a3e17a89 231 while (fd < 0);
7c88bf41 232
233 /*
234 * Set any options provided...
235 */
236
8d5eb22e 237 tcgetattr(fd, &origopts);
7c88bf41 238 tcgetattr(fd, &opts);
239
240 opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */
753453e4 241 opts.c_oflag &= ~OPOST; /* Don't post-process */
7c88bf41 242
753453e4 243 bufsize = 96; /* 9600 baud / 10 bits/char / 10Hz */
14aa7027 244 dtrdsr = 0; /* No dtr/dsr flow control */
245
7c88bf41 246 if (options != NULL)
247 while (*options)
248 {
249 /*
250 * Get the name...
251 */
252
253 for (ptr = name; *options && *options != '=';)
254 *ptr++ = *options++;
255 *ptr = '\0';
256
257 if (*options == '=')
258 {
259 /*
260 * Get the value...
261 */
262
263 options ++;
264
265 for (ptr = value; *options && *options != '+';)
266 *ptr++ = *options++;
267 *ptr = '\0';
268
269 if (*options == '+')
270 options ++;
271 }
272 else
273 value[0] = '\0';
274
275 /*
276 * Process the option...
277 */
278
279 if (strcasecmp(name, "baud") == 0)
280 {
281 /*
282 * Set the baud rate...
283 */
284
753453e4 285 bufsize = atoi(value) / 100;
14aa7027 286
7c88bf41 287#if B19200 == 19200
288 cfsetispeed(&opts, atoi(value));
289 cfsetospeed(&opts, atoi(value));
290#else
291 switch (atoi(value))
292 {
293 case 1200 :
294 cfsetispeed(&opts, B1200);
295 cfsetospeed(&opts, B1200);
296 break;
297 case 2400 :
298 cfsetispeed(&opts, B2400);
299 cfsetospeed(&opts, B2400);
300 break;
301 case 4800 :
302 cfsetispeed(&opts, B4800);
303 cfsetospeed(&opts, B4800);
304 break;
305 case 9600 :
306 cfsetispeed(&opts, B9600);
307 cfsetospeed(&opts, B9600);
308 break;
309 case 19200 :
310 cfsetispeed(&opts, B19200);
311 cfsetospeed(&opts, B19200);
312 break;
313 case 38400 :
314 cfsetispeed(&opts, B38400);
315 cfsetospeed(&opts, B38400);
316 break;
a540d367 317# ifdef B57600
14aa7027 318 case 57600 :
319 cfsetispeed(&opts, B57600);
320 cfsetospeed(&opts, B57600);
321 break;
a540d367 322# endif /* B57600 */
323# ifdef B115200
14aa7027 324 case 115200 :
325 cfsetispeed(&opts, B115200);
326 cfsetospeed(&opts, B115200);
327 break;
a540d367 328# endif /* B115200 */
329# ifdef B230400
330 case 230400 :
331 cfsetispeed(&opts, B230400);
332 cfsetospeed(&opts, B230400);
333 break;
334# endif /* B230400 */
7c88bf41 335 default :
336 fprintf(stderr, "WARNING: Unsupported baud rate %s!\n", value);
337 break;
338 }
339#endif /* B19200 == 19200 */
340 }
341 else if (strcasecmp(name, "bits") == 0)
342 {
343 /*
344 * Set number of data bits...
345 */
346
347 switch (atoi(value))
348 {
349 case 7 :
350 opts.c_cflag &= ~CSIZE;
351 opts.c_cflag |= CS7;
352 opts.c_cflag |= PARENB;
353 opts.c_cflag &= ~PARODD;
354 break;
355 case 8 :
356 opts.c_cflag &= ~CSIZE;
357 opts.c_cflag |= CS8;
358 opts.c_cflag &= ~PARENB;
359 break;
360 }
361 }
362 else if (strcasecmp(name, "parity") == 0)
363 {
364 /*
365 * Set parity checking...
366 */
367
368 if (strcasecmp(value, "even") == 0)
369 {
370 opts.c_cflag |= PARENB;
371 opts.c_cflag &= ~PARODD;
372 }
373 else if (strcasecmp(value, "odd") == 0)
374 {
375 opts.c_cflag |= PARENB;
376 opts.c_cflag |= PARODD;
377 }
378 else if (strcasecmp(value, "none") == 0)
379 opts.c_cflag &= ~PARENB;
380 }
14aa7027 381 else if (strcasecmp(name, "flow") == 0)
382 {
383 /*
384 * Set flow control...
385 */
386
387 if (strcasecmp(value, "none") == 0)
388 {
389 opts.c_iflag &= ~(IXON | IXOFF | IXANY);
390 opts.c_cflag &= ~CRTSCTS;
391 }
392 else if (strcasecmp(value, "soft") == 0)
393 {
394 opts.c_iflag |= IXON | IXOFF | IXANY;
395 opts.c_cflag &= ~CRTSCTS;
396 }
397 else if (strcasecmp(value, "hard") == 0 ||
398 strcasecmp(value, "rtscts") == 0)
399 {
400 opts.c_iflag &= ~(IXON | IXOFF | IXANY);
401 opts.c_cflag |= CRTSCTS;
402 }
403 else if (strcasecmp(value, "dtrdsr") == 0)
404 {
405 opts.c_iflag &= ~(IXON | IXOFF | IXANY);
406 opts.c_cflag &= ~CRTSCTS;
407
408 dtrdsr = 1;
409 }
410 }
7c88bf41 411 }
412
413 tcsetattr(fd, TCSANOW, &opts);
753453e4 414 fcntl(fd, F_SETFL, 0);
7c88bf41 415
4ff40357 416 /*
417 * Now that we are "connected" to the port, ignore SIGTERM so that we
418 * can finish out any page data the driver sends (e.g. to eject the
8d5eb22e 419 * current page... Only ignore SIGTERM if we are printing data from
420 * stdin (otherwise you can't cancel raw jobs...)
4ff40357 421 */
422
8d5eb22e 423 if (argc < 7)
424 {
4ff40357 425#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
8d5eb22e 426 sigset(SIGTERM, SIG_IGN);
4ff40357 427#elif defined(HAVE_SIGACTION)
8d5eb22e 428 memset(&action, 0, sizeof(action));
4ff40357 429
8d5eb22e 430 sigemptyset(&action.sa_mask);
431 action.sa_handler = SIG_IGN;
432 sigaction(SIGTERM, &action, NULL);
4ff40357 433#else
8d5eb22e 434 signal(SIGTERM, SIG_IGN);
4ff40357 435#endif /* HAVE_SIGSET */
8d5eb22e 436 }
4ff40357 437
7c88bf41 438 /*
439 * Finally, send the print file...
440 */
441
14aa7027 442 if (bufsize > sizeof(buffer))
443 bufsize = sizeof(buffer);
444
3f9cb6c6 445 while (copies > 0)
7c88bf41 446 {
3f9cb6c6 447 copies --;
7c88bf41 448
267cf96a 449 if (fp != 0)
7c88bf41 450 {
3f9cb6c6 451 fputs("PAGE: 1 1\n", stderr);
267cf96a 452 lseek(fp, 0, SEEK_SET);
7c88bf41 453 }
7c88bf41 454
14aa7027 455 if (dtrdsr)
456 {
457 /*
458 * Check the port and sleep until DSR is set...
459 */
460
461 int status;
462
463
464 if (!ioctl(fd, TIOCMGET, &status))
465 if (!(status & TIOCM_DSR))
466 {
467 /*
468 * Wait for DSR to go high...
469 */
470
471 fputs("DEBUG: DSR is low; waiting for device...\n", stderr);
472
473 do
474 {
475 sleep(1);
476 if (ioctl(fd, TIOCMGET, &status))
477 break;
478 }
479 while (!(status & TIOCM_DSR));
480
481 fputs("DEBUG: DSR is high; writing to device...\n", stderr);
482 }
483 }
484
3f9cb6c6 485 tbytes = 0;
a540d367 486 while ((nbytes = read(fp, buffer, bufsize)) > 0)
3f9cb6c6 487 {
488 /*
489 * Write the print data to the printer...
490 */
491
1c33ff6a 492 tbytes += nbytes;
493 bufptr = buffer;
494
495 while (nbytes > 0)
3f9cb6c6 496 {
1c33ff6a 497 if ((wbytes = write(fd, bufptr, nbytes)) < 0)
498 if (errno == ENOTTY)
499 wbytes = write(fd, bufptr, nbytes);
500
501 if (wbytes < 0)
502 {
503 perror("ERROR: Unable to send print file to printer");
504 break;
505 }
506
507 nbytes -= wbytes;
508 bufptr += wbytes;
3f9cb6c6 509 }
3f9cb6c6 510
0cd4970e 511 if (wbytes < 0)
512 break;
513
3f9cb6c6 514 if (argc > 6)
ba31b514 515 fprintf(stderr, "INFO: Sending print file, %lu bytes...\n",
516 (unsigned long)tbytes);
3f9cb6c6 517 }
7c88bf41 518 }
519
520 /*
753453e4 521 * Close the serial port and input file and return...
7c88bf41 522 */
523
8d5eb22e 524 tcsetattr(fd, TCSADRAIN, &origopts);
525
7c88bf41 526 close(fd);
267cf96a 527 if (fp != 0)
528 close(fp);
e73c6c0a 529
a540d367 530 fputs("INFO: Ready to print.\n", stderr);
531
7c88bf41 532 return (0);
e73c6c0a 533}
43e2fc22 534
535
536/*
68edc300 537 * 'list_devices()' - List all serial devices.
538 */
539
540void
541list_devices(void)
542{
91b3b672 543#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__)
92a63e4c 544 static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz";
545 /* Funky hex numbering used for some devices */
91b3b672 546#endif /* __hpux || __sgi || __sun || __FreeBSD__ || __OpenBSD__ */
92a63e4c 547
dab1a4d8 548#if defined(__linux) || defined(linux) || defined(__linux__)
68edc300 549 int i; /* Looping var */
8ec4b03f 550 int fd; /* File descriptor */
68edc300 551 char device[255]; /* Device filename */
552
553
39dabc6c 554 for (i = 0; i < 100; i ++)
68edc300 555 {
556 sprintf(device, "/dev/ttyS%d", i);
a3e17a89 557 if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
8ec4b03f 558 {
559 close(fd);
dab1a4d8 560# if defined(_ARCH_PPC) || defined(powerpc) || defined(__powerpc)
561 printf("serial serial:%s?baud=230400 \"Unknown\" \"Serial Port #%d\"\n",
562 device, i + 1);
563# else
d4c438d4 564 printf("serial serial:%s?baud=115200 \"Unknown\" \"Serial Port #%d\"\n",
565 device, i + 1);
ae2228ca 566# endif /* _ARCH_PPC || powerpc || __powerpc */
8ec4b03f 567 }
68edc300 568 }
69d74c4b 569
570 for (i = 0; i < 16; i ++)
571 {
572 sprintf(device, "/dev/usb/ttyUSB%d", i);
573 if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
574 {
575 close(fd);
576 printf("serial serial:%s?baud=230400 \"Unknown\" \"USB Serial Port #%d\"\n",
577 device, i + 1);
578 }
579 }
68edc300 580#elif defined(__sgi)
92a63e4c 581 int i, j, n; /* Looping vars */
582 char device[255]; /* Device filename */
583 inventory_t *inv; /* Hardware inventory info */
584
585
586 /*
587 * IRIX maintains a hardware inventory of most devices...
588 */
589
590 setinvent();
591
592 while ((inv = getinvent()) != NULL)
593 {
594 if (inv->inv_class == INV_SERIAL)
595 {
596 /*
597 * Some sort of serial port...
598 */
599
600 if (inv->inv_type == INV_CDSIO || inv->inv_type == INV_CDSIO_E)
601 {
602 /*
603 * CDSIO port...
604 */
605
606 for (n = 0; n < 6; n ++)
7c935cd3 607 printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"CDSIO Board %d Serial Port #%d\"\n",
92a63e4c 608 n + 5 + 8 * inv->inv_controller, inv->inv_controller, n + 1);
609 }
610 else if (inv->inv_type == INV_EPC_SERIAL)
611 {
612 /*
613 * Everest serial port...
614 */
615
616 if (inv->inv_unit == 0)
617 i = 1;
618 else
8a2c2126 619 i = 41 + 4 * (int)inv->inv_controller;
92a63e4c 620
8a2c2126 621 for (n = 0; n < (int)inv->inv_state; n ++)
7c935cd3 622 printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"EPC Serial Port %d, Ebus slot %d\"\n",
8a2c2126 623 n + i, n + 1, (int)inv->inv_controller);
92a63e4c 624 }
625 else if (inv->inv_state > 1)
626 {
627 /*
628 * Standard serial port under IRIX 6.4 and earlier...
629 */
630
8a2c2126 631 for (n = 0; n < (int)inv->inv_state; n ++)
7c935cd3 632 printf("serial serial:/dev/ttyd%d?baud=38400 \"Unknown\" \"Onboard Serial Port %d\"\n",
8a2c2126 633 n + (int)inv->inv_unit + 1, n + (int)inv->inv_unit + 1);
92a63e4c 634 }
635 else
636 {
637 /*
638 * Standard serial port under IRIX 6.5 and beyond...
639 */
640
641 printf("serial serial:/dev/ttyd%d?baud=115200 \"Unknown\" \"Onboard Serial Port %d\"\n",
8a2c2126 642 (int)inv->inv_controller, (int)inv->inv_controller);
92a63e4c 643 }
644 }
645 }
646
647 endinvent();
648
649 /*
650 * Central Data makes serial and parallel "servers" that can be
651 * connected in a number of ways. Look for ports...
652 */
653
654 for (i = 0; i < 10; i ++)
655 for (j = 0; j < 8; j ++)
656 for (n = 0; n < 32; n ++)
657 {
658 if (i == 8) /* EtherLite */
659 sprintf(device, "/dev/ttydn%d%c", j, funky_hex[n]);
660 else if (i == 9) /* PCI */
661 sprintf(device, "/dev/ttydp%d%c", j, funky_hex[n]);
662 else /* SCSI */
663 sprintf(device, "/dev/ttyd%d%d%c", i, j, funky_hex[n]);
664
665 if (access(device, 0) == 0)
666 {
667 if (i == 8)
668 printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n",
669 device, j, n);
670 else if (i == 9)
671 printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data PCI Serial Port, ID %d, port %d\"\n",
672 device, j, n);
673 else
674 printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n",
675 device, i, j, n);
676 }
677 }
68edc300 678#elif defined(__sun)
92a63e4c 679 int i, j, n; /* Looping vars */
680 char device[255]; /* Device filename */
681
682
683 /*
684 * Standard serial ports...
685 */
686
687 for (i = 0; i < 26; i ++)
688 {
689 sprintf(device, "/dev/cua/%c", 'a' + i);
690 if (access(device, 0) == 0)
c71a2ea0 691#ifdef B115200
692 printf("serial serial:%s?baud=115200 \"Unknown\" \"Serial Port #%d\"\n",
693 device, i + 1);
694#else
92a63e4c 695 printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n",
696 device, i + 1);
c71a2ea0 697#endif /* B115200 */
92a63e4c 698 }
699
700 /*
701 * MAGMA serial ports...
702 */
703
704 for (i = 0; i < 40; i ++)
705 {
706 sprintf(device, "/dev/term/%02d", i);
707 if (access(device, 0) == 0)
708 printf("serial serial:%s?baud=38400 \"Unknown\" \"MAGMA Serial Board #%d Port #%d\"\n",
709 device, (i / 10) + 1, (i % 10) + 1);
710 }
711
712 /*
713 * Central Data serial ports...
714 */
715
716 for (i = 0; i < 9; i ++)
717 for (j = 0; j < 8; j ++)
718 for (n = 0; n < 32; n ++)
719 {
720 if (i == 8) /* EtherLite */
721 sprintf(device, "/dev/sts/ttyN%d%c", j, funky_hex[n]);
722 else
723 sprintf(device, "/dev/sts/tty%c%d%c", i + 'C', j,
724 funky_hex[n]);
725
726 if (access(device, 0) == 0)
727 {
728 if (i == 8)
729 printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n",
730 device, j, n);
731 else
732 printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n",
733 device, i, j, n);
734 }
735 }
68edc300 736#elif defined(__hpux)
92a63e4c 737 int i, j, n; /* Looping vars */
738 char device[255]; /* Device filename */
739
740
741 /*
742 * Standard serial ports...
743 */
744
745 for (i = 0; i < 10; i ++)
746 {
747 sprintf(device, "/dev/tty%dp0", i);
748 if (access(device, 0) == 0)
749 printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n",
750 device, i + 1);
751 }
752
753 /*
754 * Central Data serial ports...
755 */
756
757 for (i = 0; i < 9; i ++)
758 for (j = 0; j < 8; j ++)
759 for (n = 0; n < 32; n ++)
760 {
761 if (i == 8) /* EtherLite */
762 sprintf(device, "/dev/ttyN%d%c", j, funky_hex[n]);
763 else
764 sprintf(device, "/dev/tty%c%d%c", i + 'C', j,
765 funky_hex[n]);
766
767 if (access(device, 0) == 0)
768 {
769 if (i == 8)
770 printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n",
771 device, j, n);
772 else
773 printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n",
774 device, i, j, n);
775 }
776 }
777#elif defined(__osf__)
778 int i; /* Looping var */
779 char device[255]; /* Device filename */
780
781
782 /*
783 * Standard serial ports...
784 */
785
786 for (i = 0; i < 100; i ++)
787 {
788 sprintf(device, "/dev/tty%02d", i);
789 if (access(device, 0) == 0)
790 printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n",
791 device, i + 1);
792 }
91b3b672 793#elif defined(__FreeBSD__) || defined(__OpenBSD__)
92a63e4c 794 int i, j; /* Looping vars */
795 int fd; /* File descriptor */
796 char device[255]; /* Device filename */
797
798
799 /*
800 * SIO ports...
801 */
802
803 for (i = 0; i < 32; i ++)
804 {
805 sprintf(device, "/dev/ttyd%c", funky_hex[i]);
a3e17a89 806 if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
92a63e4c 807 {
808 close(fd);
809 printf("serial serial:%s?baud=115200 \"Unknown\" \"Standard Serial Port #%d\"\n",
810 device, i + 1);
811 }
812 }
813
814 /*
815 * Cyclades ports...
816 */
817
818 for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */
819 for (j = 0; j < 32; j ++)
820 {
821 sprintf(device, "/dev/ttyc%d%c", i, funky_hex[j]);
a3e17a89 822 if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
92a63e4c 823 {
824 close(fd);
825 printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Port #%d\"\n",
826 device, i, j + 1);
827 }
828 }
829
830 /*
831 * Digiboard ports...
832 */
833
834 for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */
835 for (j = 0; j < 32; j ++)
836 {
837 sprintf(device, "/dev/ttyD%d%c", i, funky_hex[j]);
a3e17a89 838 if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
92a63e4c 839 {
840 close(fd);
841 printf("serial serial:%s?baud=115200 \"Unknown\" \"Digiboard #%d Serial Port #%d\"\n",
842 device, i, j + 1);
843 }
844 }
845
846 /*
847 * Stallion ports...
848 */
849
850 for (i = 0; i < 32; i ++)
851 {
852 sprintf(device, "/dev/ttyE%c", funky_hex[i]);
a3e17a89 853 if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
92a63e4c 854 {
855 close(fd);
856 printf("serial serial:%s?baud=115200 \"Unknown\" \"Stallion Serial Port #%d\"\n",
857 device, i + 1);
858 }
859 }
860
861 /*
862 * SX ports...
863 */
864
865 for (i = 0; i < 128; i ++)
866 {
867 sprintf(device, "/dev/ttyA%d", i + 1);
a3e17a89 868 if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
92a63e4c 869 {
870 close(fd);
871 printf("serial serial:%s?baud=115200 \"Unknown\" \"SX Serial Port #%d\"\n",
872 device, i + 1);
873 }
874 }
5eaf1bc1 875#elif defined(__NetBSD__)
91b3b672 876 int i, j; /* Looping vars */
877 int fd; /* File descriptor */
878 char device[255]; /* Device filename */
879
880
881 /*
882 * Standard serial ports...
883 */
884
885 for (i = 0; i < 4; i ++)
886 {
887 sprintf(device, "/dev/tty%02d", i);
888 if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
889 {
890 close(fd);
891 printf("serial serial:%s?baud=115200 \"Unknown\" \"Serial Port #%d\"\n",
892 device, i + 1);
893 }
894 }
895
896 /*
897 * Cyclades-Z ports...
898 */
899
900 for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */
901 for (j = 0; j < 64; j ++)
902 {
903 sprintf(device, "/dev/ttyCZ%02d%02d", i, j);
904 if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0)
905 {
906 close(fd);
907 printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Prt #%d\"\n",
908 device, i, j + 1);
909 }
910 }
3cc7bca4 911#elif defined(__APPLE__)
912 /*
913 * Standard serial ports on MacOS X...
914 */
915
916 kern_return_t kernResult;
917 mach_port_t masterPort;
918 io_iterator_t serialPortIterator;
919 CFMutableDictionaryRef classesToMatch;
920 io_object_t serialService;
921
922 printf("serial serial \"Unknown\" \"Serial Printer (serial)\"\n");
923
924 kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort);
925 if (KERN_SUCCESS != kernResult)
926 return;
91b3b672 927
3cc7bca4 928 /*
929 * Serial devices are instances of class IOSerialBSDClient.
930 */
931
932 classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
933 if (classesToMatch != NULL)
934 {
935 CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey),
936 CFSTR(kIOSerialBSDRS232Type));
937
938 kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch,
939 &serialPortIterator);
940 if (kernResult == KERN_SUCCESS)
941 {
942 while ((serialService = IOIteratorNext(serialPortIterator)))
943 {
944 CFTypeRef serialNameAsCFString;
945 CFTypeRef bsdPathAsCFString;
946 char serialName[128];
947 char bsdPath[1024];
948 Boolean result;
949
950
951 serialNameAsCFString =
952 IORegistryEntryCreateCFProperty(serialService,
953 CFSTR(kIOTTYDeviceKey),
954 kCFAllocatorDefault, 0);
955 if (serialNameAsCFString)
956 {
957 result = CFStringGetCString(serialNameAsCFString, serialName,
958 sizeof(serialName),
959 kCFStringEncodingASCII);
960 CFRelease(serialNameAsCFString);
961
962 if (result)
963 {
964 bsdPathAsCFString =
965 IORegistryEntryCreateCFProperty(serialService,
966 CFSTR(kIOCalloutDeviceKey),
967 kCFAllocatorDefault, 0);
968 if (bsdPathAsCFString)
969 {
970 result = CFStringGetCString(bsdPathAsCFString, bsdPath,
971 sizeof(bsdPath),
972 kCFStringEncodingASCII);
973 CFRelease(bsdPathAsCFString);
974
975 if (result)
976 printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", bsdPath,
977 serialName);
978 }
979 }
980 }
981
982 IOObjectRelease(serialService);
983 }
984
985 IOObjectRelease(serialPortIterator); /* Release the iterator. */
986 }
987 }
68edc300 988#endif
989}
990
991
992/*
0cd4970e 993 * End of "$Id: serial.c,v 1.32.2.15 2003/08/30 23:12:59 mike Exp $".
43e2fc22 994 */