]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/sconfig/sconfig.c
Merge libcxxrt master fd484be8d1e94a1fcf6bc5c67e5c07b65ada19b6
[FreeBSD/FreeBSD.git] / sbin / sconfig / sconfig.c
1 /*
2  * Channel configuration utility for Cronyx serial adapters.
3  *
4  * Copyright (C) 1997-2002 Cronyx Engineering.
5  * Author: Serge Vakulenko, <vak@cronyx.ru>
6  *
7  * Copyright (C) 1999-2005 Cronyx Engineering.
8  * Author: Roman Kurakin, <rik@cronyx.ru>
9  *
10  * This software is distributed with NO WARRANTIES, not even the implied
11  * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * Authors grant any other persons or organisations permission to use
14  * or modify this software as long as this message is kept with the software,
15  * all derivative works or modified versions.
16  *
17  * Cronyx Id: sconfig.c,v 1.4.2.2 2005/11/09 13:01:35 rik Exp $
18  */
19
20 #include <sys/cdefs.h>
21 __FBSDID("$FreeBSD$");
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <errno.h>
29 #include <ctype.h>
30 #include <sys/ioctl.h>
31 #include <sys/types.h>
32 #include "cserial.h"
33
34 #define MAXCHAN 128
35
36 int vflag, eflag, sflag, mflag, cflag, fflag, iflag, aflag, xflag;
37 int tflag, uflag;
38 char mask[64];
39 int adapter_type;               /* 0-sigma, 1-tau, 2-taupci, 3-tau32 */
40 char chan_name[16];
41
42 static void
43 usage (void)
44 {
45         printf(
46 "Serial Adapter Configuration Utility\n"
47 "Copyright (C) 1998-2005 Cronyx Engineering.\n"
48 "See also man sconfig (8)\n"
49 "Usage:\n"
50 "\tsconfig [-aimsxeftuc] [device [parameters ...]]\n"
51 "\n"
52 "Options:\n"
53 "\t<no options>\t\t -- print channel options\n"
54 "\t-a\t\t\t -- print all settings of the channel\n"
55 "\t-i\t\t\t -- print network interface status\n"
56 "\t-m\t\t\t -- print modem signal status\n"
57 "\t-s\t\t\t -- print channel statistics\n"
58 "\t-x\t\t\t -- print extended channel statistics\n"
59 "\t-e\t\t\t -- print short E1/G703 statistics\n"
60 "\t-f\t\t\t -- print full E1/G703 statistics\n"
61 "\t-t\t\t\t -- print short E3/T3/STS-1 statistics\n"
62 "\t-u\t\t\t -- print full E3/T3/STS-1 statistics\n"
63 "\t-c\t\t\t -- clear statistics\n"
64 "\nParameters:\n"
65 "\t<number>\t\t -- baud rate, internal clock\n"
66 "\textclock\t\t -- external clock (default)\n"
67 "\nProtocol options:\n"
68 "\tasync\t\t\t -- asynchronous protocol\n"
69 #ifdef __linux__
70 "\tsync\t\t\t -- synchronous protocol\n"
71 #endif
72 "\tcisco\t\t\t -- Cisco/HDLC protocol\n"
73 "\tfr\t\t\t -- Frame Relay protocol\n"
74 #ifdef __linux__
75 "\t    dlci<number>\t -- Add new DLCI\n"
76 #endif
77 "\tppp\t\t\t -- PPP protocol\n"
78 #ifdef __linux__
79 "\trbrg\t\t\t -- Remote bridge\n"
80 "\traw\t\t\t -- raw HDLC protocol\n"
81 "\tpacket\t\t\t -- packetized HDLC protocol\n"
82 "\tidle\t\t\t -- no protocol\n"
83 #else
84 "\t    keepalive={on,of}\t -- Enable/disable keepalive\n"
85 #endif
86 "\nInterface options:\n"
87 "\tport={rs232,v35,rs449}\t -- port type (for old models of Sigma)\n"
88 "\tcfg={A,B,C}\t\t -- adapter configuration\n"
89 "\tloop={on,off}\t\t -- internal loopback\n"
90 "\trloop={on,off}\t\t -- remote loopback\n"
91 "\tdpll={on,off}\t\t -- DPLL mode\n"
92 "\tnrzi={on,off}\t\t -- NRZI encoding\n"
93 "\tinvclk={on,off}\t\t -- invert receive and transmit clock\n"
94 "\tinvrclk={on,off}\t -- invert receive clock\n"
95 "\tinvtclk={on,off}\t -- invert transmit clock\n"
96 "\thigain={on,off}\t\t -- E1 high non linear input sensitivity \n\t\t\t\t    (long line)\n"
97 "\tmonitor={on,off}\t -- E1 high linear input sensitivity \n\t\t\t\t    (interception mode)\n"
98 "\tphony={on,off}\t\t -- E1 telepnony mode\n"
99 "\tunfram={on,off}\t\t -- E1 unframed mode\n"
100 "\tscrambler={on,off}\t -- G.703 scrambling mode\n"
101 "\tuse16={on,off}\t\t -- E1 timeslot 16 usage\n"
102 "\tcrc4={on,off}\t\t -- E1 CRC4 mode\n"
103 #ifdef __linux__
104 "\tami={on,off}\t\t -- E1 AMI or HDB3 line code\n"
105 "\tmtu={size}\t\t -- set MTU in bytes\n"
106 #endif
107 "\tsyn={int,rcv,rcvX}\t -- G.703 transmit clock\n"
108 "\tts=...\t\t\t -- E1 timeslots\n"
109 "\tpass=...\t\t -- E1 subchannel timeslots\n"
110 "\tdir=<num>\t\t -- connect channel to link<num>\n"
111 /*"\trqken={size}\t\t -- set receive queue length in packets\n"*/
112 /*"\tcablen={on,off}\t\t -- T3/STS-1 high transmitter output for long cable\n"*/
113 "\tdebug={0,1,2}\t\t -- enable/disable debug messages\n"
114         );
115         exit (0);
116 }
117
118 static unsigned long
119 scan_timeslots (char *s)
120 {
121         char *e;
122         long v;
123         int i;
124         unsigned long ts, lastv;
125
126         ts = lastv = 0;
127         for (;;) {
128                 v = strtol (s, &e, 10);
129                 if (e == s)
130                         break;
131                 if (*e == '-') {
132                         lastv = v;
133                         s = e+1;
134                         continue;
135                 }
136                 if (*e == ',')
137                         ++e;
138
139                 if (lastv)
140                         for (i=lastv; i<v; ++i)
141                                 ts |= 1L << i;
142                 ts |= 1L << v;
143
144                 lastv = 0;
145                 s = e;
146         }
147         return ts;
148 }
149
150 static int
151 ppp_ok (void)
152 {
153 #ifdef __linux__
154         int s, p;
155         struct ifreq ifr;
156         char pttyname[32];
157         char *p1, *p2;
158         int i, j;
159         int ppp_disc = N_PPP;
160
161         /*
162          * Open a socket for doing the ioctl operations.
163          */
164         s = socket (AF_INET, SOCK_DGRAM, 0);
165         if (s < 0) {
166                 fprintf (stderr, "Error opening socket.\n");
167                 return 0;
168         }
169         strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
170         if (ioctl (s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0) {
171                 /* Ok. */
172                 close (s);
173                 return 1;
174         }
175         close (s);
176
177         /* open pseudo-tty and try to set PPP discipline */
178         sprintf (pttyname, "/dev/ptyXX");
179         p1 = &pttyname[8];
180         p2 = &pttyname[9];
181         for (i=0; i<16; i++) {
182                 struct stat stb;
183
184                 *p1 = "pqrstuvwxyzabcde"[i];
185                 *p2 = '0';
186                 if (stat (pttyname, &stb) < 0)
187                         continue;
188                 for (j=0; j<16; j++) {
189                         *p2 = "0123456789abcdef"[j];
190                         p = open (pttyname, 2);
191                         if (p > 0) {
192                                 if (ioctl (p, TIOCSETD, &ppp_disc) < 0) {
193                                         fprintf (stderr, "No PPP discipline in kernel.\n");
194                                         close (p);
195                                         return 0;
196                                 }
197                                 close (p);
198                                 return 1;
199                         }
200                 }
201         }
202         fprintf (stderr, "Cannot get pseudo-tty.\n");
203         return 0;
204 #else
205         return 1;
206 #endif
207 }
208
209 static char *
210 format_timeslots (unsigned long s)
211 {
212         static char buf [100];
213         char *p = buf;
214         int i;
215
216         for (i=1; i<32; ++i)
217                 if ((s >> i) & 1) {
218                         int prev = (i > 1)  & (s >> (i-1));
219                         int next = (i < 31) & (s >> (i+1));
220
221                         if (prev) {
222                                 if (next)
223                                         continue;
224                                 *p++ = '-';
225                         } else if (p > buf)
226                                 *p++ = ',';
227
228                         if (i >= 10)
229                                 *p++ = '0' + i / 10;
230                         *p++ = '0' + i % 10;
231                 }
232         *p = 0;
233         return buf;
234 }
235
236 static void
237 print_modems (int fd, int need_header)
238 {
239         int status;
240
241         if (ioctl (fd, TIOCMGET, &status) < 0) {
242                 perror ("getting modem status");
243                 return;
244         }
245         if (need_header)
246                 printf ("Channel\tLE\tDTR\tDSR\tRTS\tCTS\tCD\n");
247         printf ("%s\t%s\t%s\t%s\t%s\t%s\t%s\n", chan_name,
248                 status & TIOCM_LE  ? "On" : "-",
249                 status & TIOCM_DTR ? "On" : "-",
250                 status & TIOCM_DSR ? "On" : "-",
251                 status & TIOCM_RTS ? "On" : "-",
252                 status & TIOCM_CTS ? "On" : "-",
253                 status & TIOCM_CD  ? "On" : "-");
254 }
255
256 static void
257 #ifdef __linux__
258 print_ifconfig (int fd)
259 #else
260 print_ifconfig (int fd __unused)
261 #endif
262 {
263         char buf [64];
264 #ifdef __linux__
265         char protocol [8];
266
267         if (ioctl (fd, SERIAL_GETPROTO, &protocol) >= 0 &&
268             strcmp (protocol, "fr") == 0)
269                 sprintf (buf, "ifconfig %sd16 2>/dev/null", chan_name);
270         else
271 #endif
272         sprintf (buf, "ifconfig %s 2>/dev/null", chan_name);
273         system (buf);
274 }
275
276 static void
277 set_debug_ifconfig (int on)
278 {
279         char buf [64];
280         sprintf (buf, "ifconfig %s %sdebug 2>/dev/null", chan_name,
281                  on ? "" : "-");
282         system (buf);
283 }
284
285 static char *
286 format_long (unsigned long val)
287 {
288         static char s[32];
289         int l;
290         l = sprintf (s, "%lu", val);
291         if (l>7 && !sflag) {
292                 s[3] = s[2];
293                 s[2] = s[1];
294                 s[1] = '.';
295                 s[4] = 'e';
296                 sprintf (s + 5, "%02d", l-1);
297         }
298         return s;
299 }
300
301 static void
302 print_stats (int fd, int need_header)
303 {
304         struct serial_statistics st;
305         unsigned long sarr [9];
306         int i;
307
308         if (ioctl (fd, SERIAL_GETSTAT, &st) < 0) {
309                 perror ("getting statistics");
310                 return;
311         }
312         if (need_header) {
313                 if (sflag) {
314                         printf ("        ------------Receive-----------      "
315                                 "------------Transmit----------\n");
316                         printf ("Channel Interrupts  Packets     Errors      "
317                                 "Interrupts  Packets     Errors\n");
318                 }
319                 else    {
320                         printf ("        --------Receive---------------  "
321                                 "--------Transmit--------------  Modem\n");
322                         printf ("Channel Intrs   Bytes   Packets Errors  "
323                                 "Intrs   Bytes   Packets Errors  Intrs\n");
324                 }
325         }
326         
327         sarr [0] = st.rintr;
328         sarr [1] = st.ibytes;
329         sarr [2] = st.ipkts;
330         sarr [3] = st.ierrs;
331         sarr [4] = st.tintr;
332         sarr [5] = st.obytes;
333         sarr [6] = st.opkts;
334         sarr [7] = st.oerrs;
335         sarr [8] = st.mintr;
336         printf ("%s", chan_name);
337         if (sflag) {
338                 printf ("\t%-12lu%-12lu%-12lu%-12lu%-12lu%-12lu", sarr[0],
339                         sarr[2], sarr[3], sarr[4], sarr[6], sarr[7]);
340         } else {
341                 for (i = 0; i < 9; i++)
342                         printf ("\t%s", format_long (sarr [i]));
343                 printf ("\n");
344         }
345 }
346
347 static void
348 clear_stats (int fd)
349 {
350         if (ioctl (fd, SERIAL_CLRSTAT, 0) < 0) {
351                 perror ("clearing statistics");
352                 exit (-1);
353         }
354 }
355
356 static char *
357 format_e1_status (unsigned long status)
358 {
359         static char buf [80];
360
361         if (status == 0)
362                 return "n/a";
363         if (status & E1_NOALARM)
364                 return "Ok";
365         buf[0] = 0;
366         if (status & E1_LOS)     strcat (buf, ",LOS");
367         if (status & E1_AIS)     strcat (buf, ",AIS");
368         if (status & E1_LOF)     strcat (buf, ",LOF");
369         if (status & E1_LOMF)    strcat (buf, ",LOMF");
370         if (status & E1_CRC4E)   strcat (buf, ",CRC4E");
371         if (status & E1_FARLOF)  strcat (buf, ",FARLOF");
372         if (status & E1_AIS16)   strcat (buf, ",AIS16");
373         if (status & E1_FARLOMF) strcat (buf, ",FARLOMF");
374 /*      if (status & E1_TSTREQ)  strcat (buf, ",TSTREQ");*/
375 /*      if (status & E1_TSTERR)  strcat (buf, ",TSTERR");*/
376         if (buf[0] == ',')
377                 return buf+1;
378         return "Unknown";
379 }
380
381 static void
382 print_frac (int leftalign, unsigned long numerator, unsigned long divider)
383 {
384         int n;
385
386         if (numerator < 1 || divider < 1) {
387                 printf (leftalign ? "/-   " : "    -");
388                 return;
389         }
390         n = (int) (0.5 + 1000.0 * numerator / divider);
391         if (n < 1000) {
392                 printf (leftalign ? "/.%-3d" : " .%03d", n);
393                 return;
394         }
395         putchar (leftalign ? '/' : ' ');
396
397         if      (n >= 1000000) n = (n+500) / 1000 * 1000;
398         else if (n >= 100000)  n = (n+50)  / 100 * 100;
399         else if (n >= 10000)   n = (n+5)   / 10 * 10;
400
401         switch (n) {
402         case 1000:    printf (".999"); return;
403         case 10000:   n = 9990;   break;
404         case 100000:  n = 99900;  break;
405         case 1000000: n = 999000; break;
406         }
407         if (n < 10000)        printf ("%d.%d", n/1000, n/10%100);
408         else if (n < 100000)  printf ("%d.%d", n/1000, n/100%10);
409         else if (n < 1000000) printf ("%d.", n/1000);
410         else                  printf ("%d", n/1000);
411 }
412
413 static void
414 print_e1_stats (int fd, int need_header)
415 {
416         struct e1_statistics st;
417         int i, maxi;
418
419         if (need_header)
420                 printf ("Chan\t Unav/Degr  Bpv/Fsyn  CRC/RCRC  Err/Lerr  Sev/Bur   Oof/Slp  Status\n");
421
422         if (ioctl (fd, SERIAL_GETESTAT, &st) < 0)
423                 return;
424         printf ("%s\t", chan_name);
425
426         /* Unavailable seconds, degraded minutes */
427         print_frac (0, st.currnt.uas, st.cursec);
428         print_frac (1, 60 * st.currnt.dm, st.cursec);
429
430         /* Bipolar violations, frame sync errors */
431         print_frac (0, st.currnt.bpv, st.cursec);
432         print_frac (1, st.currnt.fse, st.cursec);
433
434         /* CRC errors, remote CRC errors (E-bit) */
435         print_frac (0, st.currnt.crce, st.cursec);
436         print_frac (1, st.currnt.rcrce, st.cursec);
437
438         /* Errored seconds, line errored seconds */
439         print_frac (0, st.currnt.es, st.cursec);
440         print_frac (1, st.currnt.les, st.cursec);
441
442         /* Severely errored seconds, bursty errored seconds */
443         print_frac (0, st.currnt.ses, st.cursec);
444         print_frac (1, st.currnt.bes, st.cursec);
445
446         /* Out of frame seconds, controlled slip seconds */
447         print_frac (0, st.currnt.oofs, st.cursec);
448         print_frac (1, st.currnt.css, st.cursec);
449
450         printf (" %s\n", format_e1_status (st.status));
451
452         if (fflag) {
453                 /* Print total statistics. */
454                 printf ("\t");
455                 print_frac (0, st.total.uas, st.totsec);
456                 print_frac (1, 60 * st.total.dm, st.totsec);
457
458                 print_frac (0, st.total.bpv, st.totsec);
459                 print_frac (1, st.total.fse, st.totsec);
460
461                 print_frac (0, st.total.crce, st.totsec);
462                 print_frac (1, st.total.rcrce, st.totsec);
463
464                 print_frac (0, st.total.es, st.totsec);
465                 print_frac (1, st.total.les, st.totsec);
466
467                 print_frac (0, st.total.ses, st.totsec);
468                 print_frac (1, st.total.bes, st.totsec);
469
470                 print_frac (0, st.total.oofs, st.totsec);
471                 print_frac (1, st.total.css, st.totsec);
472
473                 printf (" -- Total\n");
474
475                 /* Print 24-hour history. */
476                 maxi = (st.totsec - st.cursec) / 900;
477                 if (maxi > 48)
478                         maxi = 48;
479                 for (i=0; i<maxi; ++i) {
480                         printf ("       ");
481                         print_frac (0, st.interval[i].uas, 15*60);
482                         print_frac (1, 60 * st.interval[i].dm, 15*60);
483
484                         print_frac (0, st.interval[i].bpv, 15*60);
485                         print_frac (1, st.interval[i].fse, 15*60);
486
487                         print_frac (0, st.interval[i].crce, 15*60);
488                         print_frac (1, st.interval[i].rcrce, 15*60);
489
490                         print_frac (0, st.interval[i].es, 15*60);
491                         print_frac (1, st.interval[i].les, 15*60);
492
493                         print_frac (0, st.interval[i].ses, 15*60);
494                         print_frac (1, st.interval[i].bes, 15*60);
495
496                         print_frac (0, st.interval[i].oofs, 15*60);
497                         print_frac (1, st.interval[i].css, 15*60);
498
499                         if (i < 3)
500                                 printf (" -- %dm\n", (i+1)*15);
501                         else
502                                 printf (" -- %dh %dm\n", (i+1)/4, (i+1)%4*15);
503                 }
504         }
505 }
506
507 static char *
508 format_e3_status (unsigned long status)
509 {
510         static char buf [80];
511
512         buf[0] = 0;
513         if (status & E3_LOS)     strcat (buf, ",LOS");
514         if (status & E3_TXE)     strcat (buf, ",XMIT");
515         if (buf[0] == ',')
516                 return buf+1;
517         return "Ok";
518 }
519
520 static char *
521 format_e3_cv (unsigned long cv, unsigned long baud, unsigned long atime)
522 {
523         static char buf[80];
524         
525         if (!cv || !baud || !atime)
526                 sprintf (buf, "         -         ");
527         else
528                 sprintf (buf, "%10lu (%.1e)", cv, (double)cv/baud/atime);
529         return buf;
530 }
531
532 static void
533 print_e3_stats (int fd, int need_header)
534 {
535         struct e3_statistics st;
536         int i, maxi;
537         long baud;
538
539         if (need_header)
540                 printf ("Chan\t--Code Violations---\t\t\t\t\t ----Status----\n");
541
542         if (ioctl (fd, SERIAL_GETE3STAT, &st) < 0 ||
543             ioctl (fd, SERIAL_GETBAUD, &baud) < 0)
544                 return;
545                 
546         if (!st.cursec)
547                 st.cursec = 1;
548
549         printf ("%s\t%s\t\t\t\t\t", chan_name,
550                 format_e3_cv (st.ccv, baud, st.cursec));
551
552         printf (" %s\n", format_e3_status (st.status));
553
554
555         if (uflag) {
556                 /* Print total statistics. */
557                 printf ("\t%s\t\t\t\t\t",
558                         format_e3_cv (st.tcv, baud, st.totsec));
559                 printf (" -- Total\n");
560
561                 /* Print 24-hour history. */
562                 maxi = (st.totsec - st.cursec) / 900;
563                 if (maxi > 48)
564                         maxi = 48;
565                 for (i=0; i<maxi; ++i) {
566                         printf ("\t%s\t\t\t\t\t",
567                                 format_e3_cv (st.icv[i], baud, 15*60));
568                         if (i < 3)
569                                 printf (" -- %2dm\n", (i+1)*15);
570                         else
571                                 printf (" -- %2dh %2dm\n", (i+1)/4, (i+1)%4*15);
572                 }
573         }
574 }
575
576 static void
577 print_chan (int fd)
578 {
579         char protocol [8];
580         char cfg;
581         int loop, dpll, nrzi, invclk, clk, higain, phony, use16, crc4;
582         int level, keepalive, debug, port, invrclk, invtclk, unfram, monitor;
583         int cable, dir, scrambler, ami, mtu;
584         int cablen, rloop, rqlen;
585         long baud, timeslots, subchan;
586         int protocol_valid, baud_valid, loop_valid, use16_valid, crc4_valid;
587         int dpll_valid, nrzi_valid, invclk_valid, clk_valid, phony_valid;
588         int timeslots_valid, subchan_valid, higain_valid, level_valid;
589         int keepalive_valid, debug_valid, cfg_valid, port_valid;
590         int invrclk_valid, invtclk_valid, unfram_valid, monitor_valid;
591         int cable_valid, dir_valid, scrambler_valid, ami_valid, mtu_valid;
592         int cablen_valid, rloop_valid, rqlen_valid;
593
594         protocol_valid  = ioctl (fd, SERIAL_GETPROTO, &protocol) >= 0;
595         cfg_valid       = ioctl (fd, SERIAL_GETCFG, &cfg) >= 0;
596         baud_valid      = ioctl (fd, SERIAL_GETBAUD, &baud) >= 0;
597         loop_valid      = ioctl (fd, SERIAL_GETLOOP, &loop) >= 0;
598         dpll_valid      = ioctl (fd, SERIAL_GETDPLL, &dpll) >= 0;
599         nrzi_valid      = ioctl (fd, SERIAL_GETNRZI, &nrzi) >= 0;
600         invclk_valid    = ioctl (fd, SERIAL_GETINVCLK, &invclk) >= 0;
601         invrclk_valid   = ioctl (fd, SERIAL_GETINVRCLK, &invrclk) >= 0;
602         invtclk_valid   = ioctl (fd, SERIAL_GETINVTCLK, &invtclk) >= 0;
603         clk_valid       = ioctl (fd, SERIAL_GETCLK, &clk) >= 0;
604         timeslots_valid = ioctl (fd, SERIAL_GETTIMESLOTS, &timeslots) >= 0;
605         subchan_valid   = ioctl (fd, SERIAL_GETSUBCHAN, &subchan) >= 0;
606         higain_valid    = ioctl (fd, SERIAL_GETHIGAIN, &higain) >= 0;
607         phony_valid     = ioctl (fd, SERIAL_GETPHONY, &phony) >= 0;
608         unfram_valid    = ioctl (fd, SERIAL_GETUNFRAM, &unfram) >= 0;
609         monitor_valid   = ioctl (fd, SERIAL_GETMONITOR, &monitor) >= 0;
610         use16_valid     = ioctl (fd, SERIAL_GETUSE16, &use16) >= 0;
611         crc4_valid      = ioctl (fd, SERIAL_GETCRC4, &crc4) >= 0;
612         ami_valid       = ioctl (fd, SERIAL_GETLCODE, &ami) >= 0;
613         level_valid     = ioctl (fd, SERIAL_GETLEVEL, &level) >= 0;
614         keepalive_valid = ioctl (fd, SERIAL_GETKEEPALIVE, &keepalive) >= 0;
615         debug_valid     = ioctl (fd, SERIAL_GETDEBUG, &debug) >= 0;
616         port_valid      = ioctl (fd, SERIAL_GETPORT, &port) >= 0;
617         cable_valid     = ioctl (fd, SERIAL_GETCABLE, &cable) >= 0;
618         dir_valid       = ioctl (fd, SERIAL_GETDIR, &dir) >= 0;
619         scrambler_valid = ioctl (fd, SERIAL_GETSCRAMBLER, &scrambler) >= 0;
620         cablen_valid    = ioctl (fd, SERIAL_GETCABLEN, &cablen) >= 0;
621         rloop_valid     = ioctl (fd, SERIAL_GETRLOOP, &rloop) >= 0;
622         mtu_valid       = ioctl (fd, SERIAL_GETMTU, &mtu) >= 0;
623         rqlen_valid     = ioctl (fd, SERIAL_GETRQLEN, &rqlen) >= 0;
624
625         printf ("%s", chan_name);
626         if (port_valid)
627                 switch (port) {
628                 case 0: printf (" (rs232)"); break;
629                 case 1: printf (" (v35)"); break;
630                 case 2: printf (" (rs530)"); break;
631                 }
632         else if (cable_valid)
633                 switch (cable) {
634                 case 0: printf (" (rs232)"); break;
635                 case 1: printf (" (v35)"); break;
636                 case 2: printf (" (rs530)"); break;
637                 case 3: printf (" (x21)"); break;
638                 case 4: printf (" (rs485)"); break;
639                 case 9: printf (" (no cable)"); break;
640                 }
641         if (debug_valid && debug)
642                 printf (" debug=%d", debug);
643         if (protocol_valid && *protocol)
644                 printf (" %.8s", protocol);
645         else
646                 printf (" idle");
647         if (cablen_valid)
648                 printf (" cablen=%s", cablen ? "on" : "off");
649         if (keepalive_valid)
650                 printf (" keepalive=%s", keepalive ? "on" : "off");
651
652         if (cfg_valid)
653                 switch (cfg) {
654                 case 'a' :      printf (" cfg=A");      break;
655                 case 'b' :      printf (" cfg=B");      break;
656                 case 'c' :      printf (" cfg=C");      break;
657                 case 'd' :      printf (" cfg=D");      break;
658                 default  :      printf (" cfg=unknown");
659                 }
660         if (dir_valid)
661                 printf (" dir=%d", dir);
662
663         if (baud_valid) {
664                 if (baud)
665                         printf (" %ld", baud);
666                 else
667                         printf (" extclock");
668         }
669         if (mtu_valid)
670                 printf (" mtu=%d", mtu);
671
672         if (aflag && rqlen_valid)
673                 printf (" rqlen=%d", rqlen);
674
675         if (clk_valid)
676                 switch (clk) {
677                 case E1CLK_INTERNAL:      printf (" syn=int");     break;
678                 case E1CLK_RECEIVE:       printf (" syn=rcv");     break;
679                 case E1CLK_RECEIVE_CHAN0: printf (" syn=rcv0");    break;
680                 case E1CLK_RECEIVE_CHAN1: printf (" syn=rcv1");    break;
681                 case E1CLK_RECEIVE_CHAN2: printf (" syn=rcv2");    break;
682                 case E1CLK_RECEIVE_CHAN3: printf (" syn=rcv3");    break;
683                 default:                  printf (" syn=%d", clk); break;
684                 }
685
686         if (dpll_valid)
687                 printf (" dpll=%s", dpll ? "on" : "off");
688         if (nrzi_valid)
689                 printf (" nrzi=%s", nrzi ? "on" : "off");
690         if (invclk_valid)
691                 printf (" invclk=%s", invclk ? "on" : "off");
692         if (invrclk_valid)
693                 printf (" invrclk=%s", invrclk ? "on" : "off");
694         if (invtclk_valid)
695                 printf (" invtclk=%s", invtclk ? "on" : "off");
696         if (unfram_valid)
697                 printf (" unfram=%s", unfram ? "on" : "off");
698         if (use16_valid)
699                 printf (" use16=%s", use16 ? "on" : "off");
700         if (aflag) {
701                 if (crc4_valid)
702                         printf (" crc4=%s", crc4 ? "on" : "off");
703                 if (higain_valid)
704                         printf (" higain=%s", higain ? "on" : "off");
705                 if (monitor_valid)
706                         printf (" monitor=%s", monitor ? "on" : "off");
707                 if (phony_valid)
708                         printf (" phony=%s", phony ? "on" : "off");
709                 if (scrambler_valid)
710                         printf (" scrambler=%s", scrambler ? "on" : "off");
711                 if (loop_valid)
712                         printf (" loop=%s", loop ? "on" : "off");
713                 if (rloop_valid)
714                         printf (" rloop=%s", rloop ? "on" : "off");
715                 if (ami_valid)
716                         printf (" ami=%s", ami ? "on" : "off");
717         }
718         if (timeslots_valid)
719                 printf (" ts=%s", format_timeslots (timeslots));
720         if (subchan_valid)
721                 printf (" pass=%s", format_timeslots (subchan));
722         if (level_valid)
723                 printf (" (level=-%.1fdB)", level / 10.0);
724         printf ("\n");
725 }
726
727 static void
728 setup_chan (int fd, int argc, char **argv)
729 {
730         int i, mode, loop, nrzi, dpll, invclk, phony, use16, crc4, unfram, ami;
731         int higain, clk, keepalive, debug, port, dlci, invrclk, invtclk;
732         int monitor, dir, scrambler, rloop, cablen;
733         int mode_valid;
734         long baud, timeslots, mtu, rqlen;
735
736         for (i=0; i<argc; ++i) {
737                 if (argv[i][0] >= '0' && argv[i][0] <= '9') {
738                         baud = strtol (argv[i], 0, 10);
739                         ioctl (fd, SERIAL_SETBAUD, &baud);
740                 } else if (strcasecmp ("extclock", argv[i]) == 0) {
741                         baud = 0;
742                         ioctl (fd, SERIAL_SETBAUD, &baud);
743                 } else if (strncasecmp ("cfg=", argv[i], 4) == 0) {
744                         if (strncasecmp ("a", argv[i]+4, 1) == 0)
745                                 ioctl (fd, SERIAL_SETCFG, "a");
746                         else if (strncasecmp ("b", argv[i]+4, 1) == 0)
747                                 ioctl (fd, SERIAL_SETCFG, "b");
748                         else if (strncasecmp ("c", argv[i]+4, 1) == 0)
749                                 ioctl (fd, SERIAL_SETCFG, "c");
750                         else if (strncasecmp ("d", argv[i]+4, 1) == 0)
751                                 ioctl (fd, SERIAL_SETCFG, "d");
752                         else {
753                                 fprintf (stderr, "invalid cfg\n");
754                                 exit (-1);
755                         }
756                 } else if (strcasecmp ("idle", argv[i]) == 0)
757                         ioctl (fd, SERIAL_SETPROTO, "\0\0\0\0\0\0\0");
758                 else if (strcasecmp ("async", argv[i]) == 0) {
759                         mode = SERIAL_ASYNC;
760                         if (ioctl (fd, SERIAL_SETMODE, &mode) >= 0)
761                                 ioctl (fd, SERIAL_SETPROTO, "async\0\0");
762                 } else if (strcasecmp ("sync", argv[i]) == 0) {
763                         mode = SERIAL_HDLC;
764                         if (ioctl (fd, SERIAL_SETMODE, &mode) >= 0)
765                                 ioctl (fd, SERIAL_SETPROTO, "sync\0\0\0");
766                 } else if (strcasecmp ("cisco", argv[i]) == 0) {
767                         mode = SERIAL_HDLC;
768                         ioctl (fd, SERIAL_SETMODE, &mode);
769                         ioctl (fd, SERIAL_SETPROTO, "cisco\0\0");
770                 } else if (strcasecmp ("rbrg", argv[i]) == 0) {
771                         mode = SERIAL_HDLC;
772                         ioctl (fd, SERIAL_SETMODE, &mode);
773                         ioctl (fd, SERIAL_SETPROTO, "rbrg\0\0\0");
774                 } else if (strcasecmp ("raw", argv[i]) == 0) {
775                         mode = SERIAL_HDLC;
776                         ioctl (fd, SERIAL_SETMODE, &mode);
777                         ioctl (fd, SERIAL_SETPROTO, "raw\0\0\0\0");
778                 } else if (strcasecmp ("packet", argv[i]) == 0) {
779                         mode = SERIAL_HDLC;
780                         ioctl (fd, SERIAL_SETMODE, &mode);
781                         ioctl (fd, SERIAL_SETPROTO, "packet\0");
782                 } else if (strcasecmp ("ppp", argv[i]) == 0) {
783                         /* check that ppp line discipline is present */
784                         if (ppp_ok ()) {
785                                 mode = SERIAL_HDLC;
786                                 ioctl (fd, SERIAL_SETMODE, &mode);
787                                 ioctl (fd, SERIAL_SETPROTO, "ppp\0\0\0\0");
788                         }
789                 } else if (strncasecmp ("keepalive=", argv[i], 10) == 0) {
790                         keepalive = (strcasecmp ("on", argv[i] + 10) == 0);
791                         ioctl (fd, SERIAL_SETKEEPALIVE, &keepalive);
792                 } else if (strcasecmp ("fr", argv[i]) == 0) {
793                         mode = SERIAL_HDLC;
794                         ioctl (fd, SERIAL_SETMODE, &mode);
795                         ioctl (fd, SERIAL_SETPROTO, "fr\0\0\0\0\0");
796                 } else if (strcasecmp ("zaptel", argv[i]) == 0) {
797                         mode = SERIAL_HDLC;
798                         ioctl (fd, SERIAL_SETMODE, &mode);
799                         ioctl (fd, SERIAL_SETPROTO, "zaptel\0");
800                 } else if (strncasecmp ("debug=", argv[i], 6) == 0) {
801                         debug = strtol (argv[i]+6, 0, 10);
802                         mode_valid = ioctl (fd, SERIAL_GETMODE, &mode) >= 0;
803                         if (!mode_valid || mode != SERIAL_ASYNC) {
804                                 if (debug == 0) {
805                                         set_debug_ifconfig(0);
806                                 } else {
807                                         ioctl (fd, SERIAL_SETDEBUG, &debug);
808                                         set_debug_ifconfig(1);
809                                 }
810                         } else {
811                                 ioctl (fd, SERIAL_SETDEBUG, &debug);
812                         }
813                 } else if (strncasecmp ("loop=", argv[i], 5) == 0) {
814                         loop = (strcasecmp ("on", argv[i] + 5) == 0);
815                         ioctl (fd, SERIAL_SETLOOP, &loop);
816                 } else if (strncasecmp ("rloop=", argv[i], 6) == 0) {
817                         rloop = (strcasecmp ("on", argv[i] + 6) == 0);
818                         ioctl (fd, SERIAL_SETRLOOP, &rloop);
819                 } else if (strncasecmp ("dpll=", argv[i], 5) == 0) {
820                         dpll = (strcasecmp ("on", argv[i] + 5) == 0);
821                         ioctl (fd, SERIAL_SETDPLL, &dpll);
822                 } else if (strncasecmp ("nrzi=", argv[i], 5) == 0) {
823                         nrzi = (strcasecmp ("on", argv[i] + 5) == 0);
824                         ioctl (fd, SERIAL_SETNRZI, &nrzi);
825                 } else if (strncasecmp ("invclk=", argv[i], 7) == 0) {
826                         invclk = (strcasecmp ("on", argv[i] + 7) == 0);
827                         ioctl (fd, SERIAL_SETINVCLK, &invclk);
828                 } else if (strncasecmp ("invrclk=", argv[i], 8) == 0) {
829                         invrclk = (strcasecmp ("on", argv[i] + 8) == 0);
830                         ioctl (fd, SERIAL_SETINVRCLK, &invrclk);
831                 } else if (strncasecmp ("invtclk=", argv[i], 8) == 0) {
832                         invtclk = (strcasecmp ("on", argv[i] + 8) == 0);
833                         ioctl (fd, SERIAL_SETINVTCLK, &invtclk);
834                 } else if (strncasecmp ("higain=", argv[i], 7) == 0) {
835                         higain = (strcasecmp ("on", argv[i] + 7) == 0);
836                         ioctl (fd, SERIAL_SETHIGAIN, &higain);
837                 } else if (strncasecmp ("phony=", argv[i], 6) == 0) {
838                         phony = (strcasecmp ("on", argv[i] + 6) == 0);
839                         ioctl (fd, SERIAL_SETPHONY, &phony);
840                 } else if (strncasecmp ("unfram=", argv[i], 7) == 0) {
841                         unfram = (strcasecmp ("on", argv[i] + 7) == 0);
842                         ioctl (fd, SERIAL_SETUNFRAM, &unfram);
843                 } else if (strncasecmp ("scrambler=", argv[i], 10) == 0) {
844                         scrambler = (strcasecmp ("on", argv[i] + 10) == 0);
845                         ioctl (fd, SERIAL_SETSCRAMBLER, &scrambler);
846                 } else if (strncasecmp ("monitor=", argv[i], 8) == 0) {
847                         monitor = (strcasecmp ("on", argv[i] + 8) == 0);
848                         ioctl (fd, SERIAL_SETMONITOR, &monitor);
849                 } else if (strncasecmp ("use16=", argv[i], 6) == 0) {
850                         use16 = (strcasecmp ("on", argv[i] + 6) == 0);
851                         ioctl (fd, SERIAL_SETUSE16, &use16);
852                 } else if (strncasecmp ("crc4=", argv[i], 5) == 0) {
853                         crc4 = (strcasecmp ("on", argv[i] + 5) == 0);
854                         ioctl (fd, SERIAL_SETCRC4, &crc4);
855                 } else if (strncasecmp ("ami=", argv[i], 4) == 0) {
856                         ami = (strcasecmp ("on", argv[i] + 4) == 0);
857                         ioctl (fd, SERIAL_SETLCODE, &ami);
858                 } else if (strncasecmp ("mtu=", argv[i], 4) == 0) {
859                         mtu = strtol (argv[i] + 4, 0, 10);
860                         ioctl (fd, SERIAL_SETMTU, &mtu);
861                 } else if (strncasecmp ("rqlen=", argv[i], 6) == 0) {
862                         rqlen = strtol (argv[i] + 6, 0, 10);
863                         ioctl (fd, SERIAL_SETRQLEN, &rqlen);
864                 } else if (strcasecmp ("syn=int", argv[i]) == 0) {
865                         clk = E1CLK_INTERNAL;
866                         ioctl (fd, SERIAL_SETCLK, &clk);
867                 } else if (strcasecmp ("syn=rcv", argv[i]) == 0) {
868                         clk = E1CLK_RECEIVE;
869                         ioctl (fd, SERIAL_SETCLK, &clk);
870                 } else if (strcasecmp ("syn=rcv0", argv[i]) == 0) {
871                         clk = E1CLK_RECEIVE_CHAN0;
872                         ioctl (fd, SERIAL_SETCLK, &clk);
873                 } else if (strcasecmp ("syn=rcv1", argv[i]) == 0) {
874                         clk = E1CLK_RECEIVE_CHAN1;
875                         ioctl (fd, SERIAL_SETCLK, &clk);
876                 } else if (strcasecmp ("syn=rcv2", argv[i]) == 0) {
877                         clk = E1CLK_RECEIVE_CHAN2;
878                         ioctl (fd, SERIAL_SETCLK, &clk);
879                 } else if (strcasecmp ("syn=rcv3", argv[i]) == 0) {
880                         clk = E1CLK_RECEIVE_CHAN3;
881                         ioctl (fd, SERIAL_SETCLK, &clk);
882                 } else if (strncasecmp ("ts=", argv[i], 3) == 0) {
883                         timeslots = scan_timeslots (argv[i] + 3);
884                         ioctl (fd, SERIAL_SETTIMESLOTS, &timeslots);
885                 } else if (strncasecmp ("pass=", argv[i], 5) == 0) {
886                         timeslots = scan_timeslots (argv[i] + 5);
887                         ioctl (fd, SERIAL_SETSUBCHAN, &timeslots);
888                 } else if (strncasecmp ("dlci", argv[i], 4) == 0) {
889                         dlci = strtol (argv[i]+4, 0, 10);
890                         ioctl (fd, SERIAL_ADDDLCI, &dlci);
891                 } else if (strncasecmp ("dir=", argv[i], 4) == 0) {
892                         dir = strtol (argv[i]+4, 0, 10);
893                         ioctl (fd, SERIAL_SETDIR, &dir);
894                 } else if (strncasecmp ("port=", argv[i], 5) == 0) {
895                         if (strncasecmp ("rs232", argv[i]+5, 5) == 0) {
896                                 port = 0;
897                                 ioctl (fd, SERIAL_SETPORT, &port);
898                         } else if (strncasecmp ("v35", argv[i]+5, 3) == 0) {
899                                 port = 1;
900                                 ioctl (fd, SERIAL_SETPORT, &port);
901                         } else if (strncasecmp ("rs449", argv[i]+5, 5) == 0) {
902                                 port = 2;
903                                 ioctl (fd, SERIAL_SETPORT, &port);
904                         } else {
905                                 fprintf (stderr, "invalid port type\n");
906                                 exit (-1);
907                         }
908 #if 1
909                 } else if (strcasecmp ("reset", argv[i]) == 0) {
910                         ioctl (fd, SERIAL_RESET, 0);
911                 } else if (strcasecmp ("hwreset", argv[i]) == 0) {
912                         ioctl (fd, SERIAL_HARDRESET, 0);
913 #endif
914                 } else if (strncasecmp ("cablen=", argv[i], 7) == 0) {
915                         loop = (strcasecmp ("on", argv[i] + 7) == 0);
916                         ioctl (fd, SERIAL_SETCABLEN, &cablen);
917                 }
918         }
919 }
920
921 static void
922 get_mask (void)
923 {
924 #ifdef __linux__
925         int fd;
926
927         fd = open ("/dev/serial/ctl0", 0);
928         if (fd < 0) {
929                 perror ("/dev/serial/ctl0");
930                 exit (-1);
931         }
932         if (ioctl (fd, SERIAL_GETREGISTERED, &mask) < 0) {
933                 perror ("getting list of channels");
934                 exit (-1);
935         }
936         close (fd);
937 #else
938         int fd, fd1, fd2, fd3, i;
939         char buf [80];
940
941         for (i=0, fd=-1; i<12 && fd<0; i++) {
942                 sprintf (buf, "/dev/cx%d", i*4);
943                 fd = open (buf, 0);
944         }
945
946         for (i=0, fd1=-1; i<3 && fd1<0; i++) {
947                 sprintf (buf, "/dev/ct%d", i*2);
948                 fd1 = open (buf, 0);
949         }
950
951         for (i=0, fd2=-1; i<3 && fd2<0; i++) {
952                 sprintf (buf, "/dev/cp%d", i*4);
953                 fd2 = open (buf, 0);
954         }
955
956         /* Try only one */
957         for (i=0, fd3=-1; i<1 && fd3<0; i++) {
958                 sprintf (buf, "/dev/ce%d", i*4);
959                 fd3 = open (buf, 0);
960         }
961
962         if ((fd < 0) && (fd1 < 0) && (fd2 < 0) && (fd3 < 0)) {
963                 fprintf (stderr, "No Cronyx adapters installed\n");
964                 exit (-1);
965         }
966
967         if (fd >= 0) {
968                 if (ioctl (fd, SERIAL_GETREGISTERED, &mask) < 0) {
969                         perror ("getting list of channels");
970                         exit (-1);
971                 }
972                 close (fd);
973         }
974
975         if (fd1 >= 0) {
976                 if (ioctl (fd1, SERIAL_GETREGISTERED, (mask+16)) < 0) {
977                         perror ("getting list of channels");
978                         exit (-1);
979                 }
980                 close (fd1);
981         }
982
983         if (fd2 >= 0) {
984                 if (ioctl (fd2, SERIAL_GETREGISTERED, (mask+32)) < 0) {
985                         perror ("getting list of channels");
986                         exit (-1);
987                 }
988                 close (fd2);
989         }
990
991         if (fd3 >= 0) {
992                 if (ioctl (fd3, SERIAL_GETREGISTERED, (mask+48)) < 0) {
993                         perror ("getting list of channels");
994                         exit (-1);
995                 }
996                 close (fd3);
997         }
998 #endif
999 }
1000
1001 static int
1002 open_chan_ctl (int num)
1003 {
1004         char device [80];
1005         int fd;
1006
1007 #ifdef __linux__
1008         sprintf (device, "/dev/serial/ctl%d", num);
1009 #else
1010         switch (adapter_type) {
1011         case 0:
1012                 sprintf (device, "/dev/cx%d", num);
1013                 break;
1014         case 1:
1015                 sprintf (device, "/dev/ct%d", num);
1016                 break;
1017         case 2:
1018                 sprintf (device, "/dev/cp%d", num);
1019                 break;
1020         case 3:
1021                 sprintf (device, "/dev/ce%d", num);
1022                 break;
1023         }
1024 #endif
1025         fd = open (device, 0);
1026         if (fd < 0) {
1027                 if (errno == ENODEV)
1028                         fprintf (stderr, "chan%d: not configured\n", num);
1029                 else
1030                         perror (device);
1031                 exit (-1);
1032         }
1033 #ifdef __linux__
1034         if (ioctl (fd, SERIAL_GETNAME, &chan_name) < 0)
1035                 sprintf (chan_name, "chan%d", num);
1036 #else
1037         switch (adapter_type) {
1038         case 0: sprintf (chan_name, "cx%d", num); break;
1039         case 1: sprintf (chan_name, "ct%d", num); break;
1040         case 2: sprintf (chan_name, "cp%d", num); break;
1041         case 3: sprintf (chan_name, "ce%d", num); break;
1042         }
1043 #endif
1044         return fd;
1045 }
1046
1047 int
1048 main (int argc, char **argv)
1049 {
1050         char *p;
1051         int fd, need_header, chan_num;
1052
1053         if (argc > 1 && strcmp(argv[1], "help") == 0)
1054                 usage();
1055
1056         for (;;) {
1057                 switch (getopt (argc, argv, "mseftucviax")) {
1058                 case -1:
1059                         break;
1060                 case 'a':
1061                         ++aflag;
1062                         continue;
1063                 case 'm':
1064                         ++mflag;
1065                         continue;
1066                 case 's':
1067                         ++sflag;
1068                         continue;
1069                 case 'e':
1070                         ++eflag;
1071                         continue;
1072                 case 'f':
1073                         ++eflag;
1074                         ++fflag;
1075                         continue;
1076                 case 't':
1077                         ++tflag;
1078                         continue;
1079                 case 'u':
1080                         ++tflag;
1081                         ++uflag;
1082                         continue;
1083                 case 'c':
1084                         ++cflag;
1085                         continue;
1086                 case 'v':
1087                         ++vflag;
1088                         continue;
1089                 case 'i':
1090                         ++iflag;
1091                         continue;
1092                 case 'x':
1093                         ++xflag;
1094                         continue;
1095                 default:
1096                         usage();
1097                 }
1098                 break;
1099         }
1100         argc -= optind;
1101         argv += optind;
1102
1103         if (argc <= 0) {
1104                 get_mask ();
1105                 need_header = 1;
1106                 adapter_type = 0;
1107 #ifndef __linux__
1108                 for (; adapter_type < 4; ++adapter_type)
1109 #endif
1110                 {
1111                 for (chan_num=0; chan_num<MAXCHAN; ++chan_num)
1112                         if (mask[adapter_type*16+chan_num/8] & 1 << (chan_num & 7)) {
1113                                 fd = open_chan_ctl (chan_num);
1114                                 if (vflag) {
1115 #ifdef __linux__
1116                                 char buf[256];
1117                                 if (ioctl (fd, SERIAL_GETVERSIONSTRING, &buf) >= 0) {
1118                                         printf ("Version: %s\n", buf);
1119                                         close (fd);
1120                                         return (0);
1121                                 }
1122 #endif
1123                                 }
1124                                 if (iflag) {
1125                                         print_chan (fd);
1126                                         print_ifconfig (fd);
1127                                 } else if (sflag||xflag)
1128                                         print_stats (fd, need_header);
1129                                 else if (mflag)
1130                                         print_modems (fd, need_header);
1131                                 else if (eflag)
1132                                         print_e1_stats (fd, need_header);
1133                                 else if (tflag)
1134                                         print_e3_stats (fd, need_header);
1135                                 else if (cflag)
1136                                         clear_stats (fd);
1137                                 else
1138                                         print_chan (fd);
1139                                 close (fd);
1140                                 need_header = 0;
1141                         }
1142                 }
1143                 return (0);
1144         }
1145
1146         p = argv[0] + strlen (argv[0]);
1147         while (p > argv[0] && p[-1] >= '0' && p[-1] <= '9')
1148                 --p;
1149         chan_num = strtol (p, 0, 10);
1150 #ifndef __linux__
1151         if (strncasecmp ("cx", argv[0], 2)==0)
1152                 adapter_type = 0;
1153         else if (strncasecmp ("ct", argv[0], 2)==0)
1154                 adapter_type = 1;
1155         else if (strncasecmp ("cp", argv[0], 2)==0)
1156                 adapter_type = 2;
1157         else if (strncasecmp ("ce", argv[0], 2)==0)
1158                 adapter_type = 3;
1159         else {
1160                 fprintf (stderr, "Wrong channel name\n");
1161                 exit (-1);
1162         }
1163 #endif
1164         argc--;
1165         argv++;
1166
1167         fd = open_chan_ctl (chan_num);
1168         if (vflag) {
1169 #ifdef __linux__
1170                 char buf[256];
1171                 if (ioctl (fd, SERIAL_GETVERSIONSTRING, &buf) >= 0)
1172                         printf ("Version: %s\n", buf);
1173 #endif
1174         }
1175         if (iflag) {
1176                 print_chan (fd);
1177                 print_ifconfig (fd);
1178                 close (fd);
1179                 return (0);
1180         }
1181         if (sflag||xflag) {
1182                 print_stats (fd, 1);
1183                 close (fd);
1184                 return (0);
1185         }
1186         if (mflag) {
1187                 print_modems (fd, 1);
1188                 close (fd);
1189                 return (0);
1190         }
1191         if (eflag) {
1192                 print_e1_stats (fd, 1);
1193                 close (fd);
1194                 return (0);
1195         }
1196         if (tflag) {
1197                 print_e3_stats (fd, 1);
1198                 close (fd);
1199                 return (0);
1200         }
1201         if (cflag) {
1202                 clear_stats (fd);
1203                 close (fd);
1204                 return (0);
1205         }
1206         if (argc > 0)
1207                 setup_chan (fd, argc, argv);
1208         else
1209                 print_chan (fd);
1210         close (fd);
1211         return (0);
1212 }