]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/cxconfig/cxconfig.c
This commit was generated by cvs2svn to compensate for changes in r91796,
[FreeBSD/FreeBSD.git] / sbin / cxconfig / cxconfig.c
1 /*
2  * Cronyx-Sigma adapter configuration utility for Unix.
3  *
4  * Copyright (C) 1994 Cronyx Ltd.
5  * Author: Serge Vakulenko, <vak@zebub.msk.su>
6  *
7  * This software is distributed with NO WARRANTIES, not even the implied
8  * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9  *
10  * Authors grant any other persons or organisations permission to use
11  * or modify this software as long as this message is kept with the software,
12  * all derivative works or modified versions.
13  *
14  * Version 1.9, Wed Oct  4 18:58:15 MSK 1995
15  *
16  * Usage:
17  *      cxconfig [-a]
18  *              -- print status of all channels
19  *      cxconfig [-a] <channel>
20  *              -- print status of the channel
21  *      cxconfig <channel> <option>...
22  *              -- set channel options
23  */
24
25 #ifndef lint
26 static const char rcsid[] =
27   "$FreeBSD$";
28 #endif /* not lint */
29
30 #include <sys/types.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
33 #include <net/if.h>
34 #include <machine/cronyx.h>
35
36 #include <err.h>
37 #include <fcntl.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42
43 #define NBRD    3
44 #define CXDEV   "/dev/cronyx"
45 #define atoi(a) strtol((a), (char**)0, 0)
46
47 cx_options_t o;
48 cx_stat_t st;
49 int aflag;
50 int sflag;
51
52 static char *
53 symbol(unsigned char sym)
54 {
55         static char buf[40];
56
57         if (sym < ' ')
58                 sprintf (buf, "^%c", sym+0100);
59         else if (sym == '\\')
60                 strcat (buf, "\\\\");
61         else if (sym < 127)
62                 sprintf (buf, "%c", sym);
63         else
64                 sprintf (buf, "\\%03o", sym);
65         return (buf);
66 }
67
68 static unsigned char
69 atosym(char *s)
70 {
71         if (*s == '^')
72                 return (*++s & 037);
73         if (*s == '\\')
74                 return (strtol (++s, 0, 8));
75         return (*s);
76 }
77
78 static void
79 usage(void)
80 {
81         fprintf (stderr,
82                 "Cronyx-Sigma Adapter Configuration Utility, Version 1.0\n");
83         fprintf (stderr, "Copyright (C) 1994 Cronyx Ltd.\n");
84         fprintf (stderr, "usage: cxconfig [-a] [<channel> [<option>...]]\n");
85         exit (1);
86 }
87
88 static const char *
89 chantype(int type)
90 {
91         switch (type) {
92         default:
93         case T_NONE:       return ("none");
94         case T_ASYNC:      return ("RS-232");
95         case T_UNIV_RS232: return ("RS-232");
96         case T_UNIV_RS449: return ("RS-232/RS-449");
97         case T_UNIV_V35:   return ("RS-232/V.35");
98         case T_SYNC_RS232: return ("RS-232");
99         case T_SYNC_V35:   return ("V.35");
100         case T_SYNC_RS449: return ("RS-449");
101         }
102 }
103
104 static const char *
105 chanmode(int mode)
106 {
107         switch (mode) {
108         case M_ASYNC:   return ("Async");
109         case M_HDLC:    return ("HDLC");
110         case M_BISYNC:  return ("Bisync");
111         case M_X21:     return ("X.21");
112         default:        return ("???");
113         }
114 }
115
116 static void
117 getchan(int channel)
118 {
119         int s = open (CXDEV, 0);
120         if (s < 0)
121                 err (1, "%s", CXDEV);
122         o.board = channel/NCHAN;
123         o.channel = channel%NCHAN;
124         if (ioctl (s, CXIOCGETMODE, (caddr_t)&o) < 0)
125                 err (1, "CXIOCGETMODE");
126         close (s);
127         if (o.type == T_NONE)
128                 errx (1, "cx%d: channel %d not configured", o.board,
129                         o.channel);
130 }
131
132 static int
133 printstats(int channel, int hflag)
134 {
135         int s, res;
136
137         s = open (CXDEV, 0);
138         if (s < 0)
139                 err (1, "%s", CXDEV);
140         st.board = channel/NCHAN;
141         st.channel = channel%NCHAN;
142         res = ioctl (s, CXIOCGETSTAT, (caddr_t)&st);
143         close (s);
144         if (res < 0)
145                 return (-1);
146
147         if (hflag)
148                 printf ("Chan   Rintr   Tintr   Mintr   Ibytes   Ipkts   Ierrs   Obytes   Opkts   Oerrs\n");
149         printf ("cx%-2d %7ld %7ld %7ld %8ld %7ld %7ld %8ld %7ld %7ld\n",
150                 channel, st.rintr, st.tintr, st.mintr, st.ibytes, st.ipkts,
151                 st.ierrs, st.obytes, st.opkts, st.oerrs);
152         return (0);
153 }
154
155 static void
156 printallstats(void)
157 {
158         int b, c;
159
160         printf ("Chan   Rintr   Tintr   Mintr   Ibytes   Ipkts   Ierrs   Obytes   Opkts   Oerrs\n");
161         for (b=0; b<NBRD; ++b)
162                 for (c=0; c<NCHAN; ++c)
163                         printstats (b*NCHAN + c, 0);
164 }
165
166 static void
167 setchan(int channel)
168 {
169         int s = open (CXDEV, 0);
170         if (s < 0)
171                 err (1, "%s", CXDEV);
172         o.board = channel/NCHAN;
173         o.channel = channel%NCHAN;
174         if (ioctl (s, CXIOCSETMODE, (caddr_t)&o) < 0)
175                 err (1, "CXIOCSETMODE");
176         close (s);
177 }
178
179 static void
180 printopt(void)
181 {
182         /* Common channel options */
183         /* channel option register 4 */
184         printf ("\t");
185         printf ("fifo=%d ", o.opt.cor4.thr);    /* FIFO threshold */
186         printf ("%cctsdown ", o.opt.cor4.cts_zd ? '+' : '-');   /* detect 1 to 0 transition on the CTS */
187         printf ("%ccddown ", o.opt.cor4.cd_zd ? '+' : '-');     /* detect 1 to 0 transition on the CD */
188         printf ("%cdsrdown ", o.opt.cor4.dsr_zd ? '+' : '-');   /* detect 1 to 0 transition on the DSR */
189         printf ("\n");
190
191         /* channel option register 5 */
192         printf ("\t");
193         printf ("rfifo=%d ", o.opt.cor5.rx_thr);        /* receive flow control FIFO threshold */
194         printf ("%cctsup ", o.opt.cor5.cts_od ? '+' : '-');     /* detect 0 to 1 transition on the CTS */
195         printf ("%ccdup ", o.opt.cor5.cd_od ? '+' : '-');       /* detect 0 to 1 transition on the CD */
196         printf ("%cdsrup ", o.opt.cor5.dsr_od ? '+' : '-');     /* detect 0 to 1 transition on the DSR */
197         printf ("\n");
198
199         /* receive clock option register */
200         printf ("\t");
201         printf ("%s ", o.opt.rcor.encod == ENCOD_NRZ ? "nrz" :  /* signal encoding */
202                 o.opt.rcor.encod == ENCOD_NRZI ? "nrzi" :
203                 o.opt.rcor.encod == ENCOD_MANCHESTER ? "manchester" : "???");
204         printf ("%cdpll ", o.opt.rcor.dpll ? '+' : '-');        /* DPLL enable */
205
206         /* transmit clock option register */
207         printf ("%clloop ", o.opt.tcor.llm ? '+' : '-');        /* local loopback mode */
208         printf ("%cextclock ", o.opt.tcor.ext1x ? '+' : '-');   /* external 1x clock mode */
209         printf ("\n");
210
211         switch (o.mode) {
212         case M_ASYNC:                           /* async mode options */
213                 /* channel option register 1 */
214                 printf ("\t");
215                 printf ("cs%d ", o.aopt.cor1.charlen+1);        /* character length, 5..8 */
216                 printf ("par%s ", o.aopt.cor1.parity ? "odd" : "even"); /* parity */
217                 printf ("%cignpar ", o.aopt.cor1.ignpar ? '+' : '-');   /* ignore parity */
218                 if (o.aopt.cor1.parmode != PARM_NORMAL)                 /* parity mode */
219                         printf ("%s ", o.aopt.cor1.parmode == PARM_NOPAR ? "nopar" :
220                                 o.aopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
221                 printf ("\n");
222
223                 /* channel option register 2 */
224                 printf ("\t");
225                 printf ("%cdsr ", o.aopt.cor2.dsrae ? '+' : '-');  /* DSR automatic enable */
226                 printf ("%ccts ", o.aopt.cor2.ctsae ? '+' : '-');  /* CTS automatic enable */
227                 printf ("%crts ", o.aopt.cor2.rtsao ? '+' : '-');  /* RTS automatic output enable */
228                 printf ("%crloop ", o.aopt.cor2.rlm ? '+' : '-');  /* remote loopback mode enable */
229                 printf ("%cetc ", o.aopt.cor2.etc ? '+' : '-');    /* embedded transmitter cmd enable */
230                 printf ("%cxon ", o.aopt.cor2.ixon ? '+' : '-');   /* in-band XON/XOFF enable */
231                 printf ("%cxany ", o.aopt.cor2.ixany ? '+' : '-'); /* XON on any character */
232                 printf ("\n");
233
234                 /* option register 3 */
235                 printf ("\t");
236                 printf ("%s ", o.aopt.cor3.stopb == STOPB_1 ? "stopb1" : /* stop bit length */
237                         o.aopt.cor3.stopb == STOPB_15 ? "stopb1.5" :
238                         o.aopt.cor3.stopb == STOPB_2 ? "stopb2" : "???");
239                 printf ("%csdt ", o.aopt.cor3.scde ? '+' : '-');        /* special char detection enable */
240                 printf ("%cflowct ", o.aopt.cor3.flowct ? '+' : '-');   /* flow control transparency mode */
241                 printf ("%crdt ", o.aopt.cor3.rngde ? '+' : '-');       /* range detect enable */
242                 printf ("%cexdt ", o.aopt.cor3.escde ? '+' : '-');      /* extended spec. char detect enable */
243                 printf ("\n");
244
245                 /* channel option register 6 */
246                 printf ("\t");
247                 printf ("%s ", o.aopt.cor6.parerr == PERR_INTR ? "parintr" : /* parity/framing error actions */
248                         o.aopt.cor6.parerr == PERR_NULL ? "parnull" :
249                         o.aopt.cor6.parerr == PERR_IGNORE ? "parign" :
250                         o.aopt.cor6.parerr == PERR_DISCARD ? "pardisc" :
251                         o.aopt.cor6.parerr == PERR_FFNULL ? "parffnull" : "???");
252                 printf ("%s ", o.aopt.cor6.brk == BRK_INTR ? "brkintr" : /* action on break condition */
253                         o.aopt.cor6.brk == BRK_NULL ? "brknull" :
254                         o.aopt.cor6.brk == BRK_DISCARD ? "brkdisc" : "???");
255                 printf ("%cinlcr ", o.aopt.cor6.inlcr ? '+' : '-');     /* translate NL to CR on input */
256                 printf ("%cicrnl ", o.aopt.cor6.icrnl ? '+' : '-');     /* translate CR to NL on input */
257                 printf ("%cigncr ", o.aopt.cor6.igncr ? '+' : '-');     /* discard CR on input */
258                 printf ("\n");
259
260                 /* channel option register 7 */
261                 printf ("\t");
262                 printf ("%cocrnl ", o.aopt.cor7.ocrnl ? '+' : '-');     /* translate CR to NL on output */
263                 printf ("%conlcr ", o.aopt.cor7.onlcr ? '+' : '-');     /* translate NL to CR on output */
264                 printf ("%cfcerr ", o.aopt.cor7.fcerr ? '+' : '-');     /* process flow ctl err chars enable */
265                 printf ("%clnext ", o.aopt.cor7.lnext ? '+' : '-');     /* LNext option enable */
266                 printf ("%cistrip ", o.aopt.cor7.istrip ? '+' : '-');   /* strip 8-bit on input */
267                 printf ("\n");
268
269                 printf ("\t");
270                 printf ("schr1=%s ", symbol (o.aopt.schr1));    /* special character register 1 (XON) */
271                 printf ("schr2=%s ", symbol (o.aopt.schr2));    /* special character register 2 (XOFF) */
272                 printf ("schr3=%s ", symbol (o.aopt.schr3));    /* special character register 3 */
273                 printf ("schr4=%s ", symbol (o.aopt.schr4));    /* special character register 4 */
274                 printf ("scrl=%s ", symbol (o.aopt.scrl));      /* special character range low */
275                 printf ("scrh=%s ", symbol (o.aopt.scrh));      /* special character range high */
276                 printf ("lnext=%s ", symbol (o.aopt.lnxt));     /* LNext character */
277                 printf ("\n");
278                 break;
279
280         case M_HDLC:                    /* hdlc mode options */
281                 /* hdlc channel option register 1 */
282                 printf ("\t");
283                 printf ("if%d ", o.hopt.cor1.ifflags);  /* number of inter-frame flags sent */
284                 printf ("%s ", o.hopt.cor1.admode == ADMODE_NOADDR ? "noaddr" : /* addressing mode */
285                         o.hopt.cor1.admode == ADMODE_4_1 ? "addr1" :
286                         o.hopt.cor1.admode == ADMODE_2_2 ? "addr2" : "???");
287                 printf ("%cclrdet ", o.hopt.cor1.clrdet ? '+' : '-'); /* clear detect for X.21 data transfer phase */
288                 printf ("addrlen%d ", o.hopt.cor1.aflo + 1);    /* address field length option */
289                 printf ("\n");
290
291                 /* hdlc channel option register 2 */
292                 printf ("\t");
293                 printf ("%cdsr ", o.hopt.cor2.dsrae ? '+' : '-'); /* DSR automatic enable */
294                 printf ("%ccts ", o.hopt.cor2.ctsae ? '+' : '-'); /* CTS automatic enable */
295                 printf ("%crts ", o.hopt.cor2.rtsao ? '+' : '-'); /* RTS automatic output enable */
296                 printf ("%ccrcinv ", o.hopt.cor2.crcninv ? '-' : '+');  /* CRC invertion option */
297                 printf ("%cfcsapd ", o.hopt.cor2.fcsapd ? '+' : '-');   /* FCS append */
298                 printf ("\n");
299
300                 /* hdlc channel option register 3 */
301                 printf ("\t");
302                 printf ("pad%d ", o.hopt.cor3.padcnt);  /* pad character count */
303                 printf ("idle%s ", o.hopt.cor3.idle ? "mark" : "flag"); /* idle mode */
304                 printf ("%cfcs ", o.hopt.cor3.nofcs ? '-' : '+');       /* FCS disable */
305                 printf ("fcs-%s ", o.hopt.cor3.fcspre ? "crc-16" : "v.41"); /* FCS preset */
306                 printf ("syn=%s ", o.hopt.cor3.syncpat ? "0xAA" : "0x00"); /* send sync pattern */
307                 printf ("%csyn ", o.hopt.cor3.sndpad ? '+' : '-');     /* send pad characters before flag enable */
308                 printf ("\n");
309
310                 printf ("\t");
311                 printf ("rfar1=0x%02x ", o.hopt.rfar1); /* receive frame address register 1 */
312                 printf ("rfar2=0x%02x ", o.hopt.rfar2); /* receive frame address register 2 */
313                 printf ("rfar3=0x%02x ", o.hopt.rfar3); /* receive frame address register 3 */
314                 printf ("rfar4=0x%02x ", o.hopt.rfar4); /* receive frame address register 4 */
315                 printf ("crc-%s ", o.hopt.cpsr ? "16" : "v.41"); /* CRC polynomial select */
316                 printf ("\n");
317                 break;
318
319         case M_BISYNC:                  /* bisync mode options */
320                 /* channel option register 1 */
321                 printf ("\t");
322                 printf ("cs%d ", o.bopt.cor1.charlen+1);        /* character length, 5..8 */
323                 printf ("par%s ", o.bopt.cor1.parity ? "odd" : "even"); /* parity */
324                 printf ("%cignpar ", o.bopt.cor1.ignpar ? '+' : '-');   /* ignore parity */
325                 if (o.bopt.cor1.parmode != PARM_NORMAL)                 /* parity mode */
326                         printf ("%s ", o.bopt.cor1.parmode == PARM_NOPAR ? "nopar" :
327                                 o.bopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
328                 printf ("\n");
329
330                 /* channel option register 2 */
331                 printf ("\t");
332                 printf ("syn%d ", o.bopt.cor2.syns+2);                  /* number of extra SYN chars before a frame */
333                 printf ("%ccrcinv ", o.bopt.cor2.crcninv ? '-' : '+');  /* CRC invertion option */
334                 printf ("%s ", o.bopt.cor2.ebcdic ? "ebcdic" : "ascii"); /* use EBCDIC as char set (instead of ASCII) */
335                 printf ("%cbccapd ", o.bopt.cor2.bcc ? '+' : '-');      /* BCC append enable */
336                 printf ("%s ", o.bopt.cor2.lrc ? "lrc" : "crc-16");     /* longitudinal redundancy check */
337                 printf ("\n");
338
339                 /* channel option register 3 */
340                 printf ("\t");
341                 printf ("pad%d ", o.bopt.cor3.padcnt);  /* pad character count */
342                 printf ("idle%s ", o.bopt.cor3.idle ? "mark" : "syn"); /* idle mode */
343                 printf ("%cfcs ", o.bopt.cor3.nofcs ? '-' : '+');       /* FCS disable */
344                 printf ("fcs-%s ", o.bopt.cor3.fcspre ? "crc-16" : "v.41"); /* FCS preset */
345                 printf ("syn=%s ", o.bopt.cor3.padpat ? "0x55" : "0xAA"); /* send sync pattern */
346                 printf ("%csyn ", o.bopt.cor3.sndpad ? '+' : '-');     /* send pad characters before flag enable */
347                 printf ("\n");
348
349                 /* channel option register 6 */
350                 printf ("\t");
351                 printf ("specterm=%s ", symbol (o.bopt.cor6.specterm)); /* special termination character */
352
353                 printf ("crc-%s ", o.bopt.cpsr ? "16" : "v.41"); /* CRC polynomial select */
354                 printf ("\n");
355                 break;
356
357         case M_X21:                     /* x.21 mode options */
358                 /* channel option register 1 */
359                 printf ("\t");
360                 printf ("cs%d ", o.xopt.cor1.charlen+1);        /* character length, 5..8 */
361                 printf ("par%s ", o.xopt.cor1.parity ? "odd" : "even"); /* parity */
362                 printf ("%cignpar ", o.xopt.cor1.ignpar ? '+' : '-');   /* ignore parity */
363                 if (o.xopt.cor1.parmode != PARM_NORMAL)                 /* parity mode */
364                         printf ("%s ", o.xopt.cor1.parmode == PARM_NOPAR ? "nopar" :
365                                 o.xopt.cor1.parmode == PARM_FORCE ? "forcepar" : "???");
366                 printf ("\n");
367
368                 /* channel option register 2 */
369                 printf ("\t");
370                 printf ("%cetc ", o.xopt.cor2.etc ? '+' : '-'); /* embedded transmitter cmd enable */
371
372                 /* channel option register 3 */
373                 printf ("%csdt ", o.xopt.cor3.scde ? '+' : '-'); /* special char detection enable */
374                 printf ("%cstripsyn ", o.xopt.cor3.stripsyn ? '+' : '-'); /* treat SYN chars as special condition */
375                 printf ("%cssdt ", o.xopt.cor3.ssde ? '+' : '-'); /* steady state detect enable */
376                 printf ("syn%c ", o.xopt.cor3.syn ? '1' : '2'); /* the number of SYN chars on receive */
377                 printf ("\n");
378
379                 /* channel option register 6 */
380                 printf ("\t");
381                 printf ("syn=%s ", symbol (o.xopt.cor6.synchar)); /* syn character */
382
383                 printf ("schr1=%s ", symbol (o.xopt.schr1));    /* special character register 1 */
384                 printf ("schr2=%s ", symbol (o.xopt.schr2));    /* special character register 2 */
385                 printf ("schr3=%s ", symbol (o.xopt.schr3));    /* special character register 3 */
386                 printf ("\n");
387                 break;
388         }
389 }
390
391 static void
392 printchan(int channel)
393 {
394         printf ("cx%d (%s) %s", channel, chantype (o.type), chanmode (o.mode));
395         if (o.txbaud == o.rxbaud)
396                 printf (" %lu", o.rxbaud);
397         else
398                 printf (" ospeed=%lu ispeed=%lu", o.txbaud, o.rxbaud);
399         if ((o.channel == 0 || o.channel == 8) &&
400             (o.type == T_UNIV_V35 || o.type == T_UNIV_RS449))
401                 printf (" port=%s", o.iftype ? (o.type == T_UNIV_V35 ?
402                         "v35" : "rs449") : "rs232");
403         printf (o.sopt.ext ? " ext" : o.sopt.cisco ? " cisco" : " ppp");
404         printf (" %ckeepalive", o.sopt.keepalive ? '+' : '-');
405         printf (" %cautorts", o.sopt.norts ? '-' : '+');
406         if (*o.master)
407                 printf (" master=%s", o.master);
408         printf ("\n");
409         if (aflag)
410                 printopt ();
411 }
412
413 static void
414 printall(void)
415 {
416         struct ifconf ifc;
417         struct ifreq *ifr;
418         char buf[BUFSIZ], *cp;
419         int s, c;
420
421         s = socket (AF_INET, SOCK_DGRAM, 0);
422         if (s < 0)
423                 err (1, "socket");
424         ifc.ifc_len = sizeof (buf);
425         ifc.ifc_buf = buf;
426         if (ioctl (s, SIOCGIFCONF, (caddr_t)&ifc) < 0)
427                 err (1, "SIOCGIFCONF");
428         close (s);
429         s = open (CXDEV, 0);
430         if (s < 0)
431                 err (1, "%s", CXDEV);
432
433         ifr = ifc.ifc_req;
434 #define max(a,b) ((a)>(b) ? (a) : (b))
435 #define size(p) max((p).sa_len, sizeof(p))
436         for (cp=buf; cp<buf+ifc.ifc_len; cp+=sizeof(ifr->ifr_name)+size(ifr->ifr_addr)) {
437                 ifr = (struct ifreq*) cp;
438                 if (ifr->ifr_addr.sa_family != AF_LINK)
439                         continue;
440                 if (strncmp (ifr->ifr_name, "cx", 2) != 0)
441                         continue;
442                 c = atoi (ifr->ifr_name + 2);
443                 o.board = c/NCHAN;
444                 o.channel = c%NCHAN;
445                 if (ioctl (s, CXIOCGETMODE, (caddr_t)&o) < 0)
446                         err (1, "CXIOCGETMODE");
447                 printchan (c);
448         }
449         close (s);
450 }
451
452 static void
453 set_interface_type(char *type)
454 {
455         if (o.channel != 0 && o.channel != 8) {
456                 printf ("interface option is applicable only for channels 0 and 8\n");
457                 exit (1);
458         }
459         if (o.type != T_UNIV_V35 && o.type != T_UNIV_RS449) {
460                 printf ("interface option is applicable only for universal channels\n");
461                 exit (1);
462         }
463         if (! strcasecmp (type, "port=rs232"))
464                 o.iftype = 0;
465         else
466                 o.iftype = 1;
467 }
468
469 static void
470 set_master(char *ifname)
471 {
472         if (o.type == T_ASYNC) {
473                 printf ("master option is not applicable for async channels\n");
474                 exit (1);
475         }
476         strcpy (o.master, ifname);
477 }
478
479 static void
480 set_async_opt(char *opt)
481 {
482         /* channel option register 1 */
483         if (! strncasecmp (opt, "cs", 2))        o.aopt.cor1.charlen = atoi (opt + 2) - 1;
484         else if (! strcasecmp (opt, "parodd"))   o.aopt.cor1.parity = 1;
485         else if (! strcasecmp (opt, "pareven"))  o.aopt.cor1.parity = 0;
486         else if (! strcasecmp (opt, "-ignpar"))  o.aopt.cor1.ignpar = 0;
487         else if (! strcasecmp (opt, "+ignpar"))  o.aopt.cor1.ignpar = 1;
488         else if (! strcasecmp (opt, "nopar"))    o.aopt.cor1.parmode = PARM_NOPAR;
489         else if (! strcasecmp (opt, "forcepar")) o.aopt.cor1.parmode = PARM_FORCE;
490
491         /* channel option register 2 */
492         else if (! strcasecmp (opt, "-dsr"))   o.aopt.cor2.dsrae = 0;
493         else if (! strcasecmp (opt, "+dsr"))   o.aopt.cor2.dsrae = 1;
494         else if (! strcasecmp (opt, "-cts"))   o.aopt.cor2.ctsae = 0;
495         else if (! strcasecmp (opt, "+cts"))   o.aopt.cor2.ctsae = 1;
496         else if (! strcasecmp (opt, "-rts"))   o.aopt.cor2.rtsao = 0;
497         else if (! strcasecmp (opt, "+rts"))   o.aopt.cor2.rtsao = 1;
498         else if (! strcasecmp (opt, "-rloop")) o.aopt.cor2.rlm = 0;
499         else if (! strcasecmp (opt, "+rloop")) o.aopt.cor2.rlm = 1;
500         else if (! strcasecmp (opt, "-etc"))   o.aopt.cor2.etc = 0;
501         else if (! strcasecmp (opt, "+etc"))   o.aopt.cor2.etc = 1;
502         else if (! strcasecmp (opt, "-ixon"))  o.aopt.cor2.ixon = 0;
503         else if (! strcasecmp (opt, "+ixon"))  o.aopt.cor2.ixon = 1;
504         else if (! strcasecmp (opt, "-ixany")) o.aopt.cor2.ixany = 0;
505         else if (! strcasecmp (opt, "+ixany")) o.aopt.cor2.ixany = 1;
506
507         /* option register 3 */
508         else if (! strcasecmp (opt, "stopb1"))   o.aopt.cor3.stopb = STOPB_1;
509         else if (! strcasecmp (opt, "stopb1.5")) o.aopt.cor3.stopb = STOPB_15;
510         else if (! strcasecmp (opt, "stopb2"))   o.aopt.cor3.stopb = STOPB_2;
511         else if (! strcasecmp (opt, "-sdt"))     o.aopt.cor3.scde = 0;
512         else if (! strcasecmp (opt, "+sdt"))     o.aopt.cor3.scde = 1;
513         else if (! strcasecmp (opt, "-flowct"))  o.aopt.cor3.flowct = 0;
514         else if (! strcasecmp (opt, "+flowct"))  o.aopt.cor3.flowct = 1;
515         else if (! strcasecmp (opt, "-rdt"))     o.aopt.cor3.rngde = 0;
516         else if (! strcasecmp (opt, "+rdt"))     o.aopt.cor3.rngde = 1;
517         else if (! strcasecmp (opt, "-exdt"))    o.aopt.cor3.escde = 0;
518         else if (! strcasecmp (opt, "+exdt"))    o.aopt.cor3.escde = 1;
519
520         /* channel option register 6 */
521         else if (! strcasecmp (opt, "parintr"))   o.aopt.cor6.parerr = PERR_INTR;
522         else if (! strcasecmp (opt, "parnull"))   o.aopt.cor6.parerr = PERR_NULL;
523         else if (! strcasecmp (opt, "parign"))    o.aopt.cor6.parerr = PERR_IGNORE;
524         else if (! strcasecmp (opt, "pardisc"))   o.aopt.cor6.parerr = PERR_DISCARD;
525         else if (! strcasecmp (opt, "parffnull")) o.aopt.cor6.parerr = PERR_FFNULL;
526         else if (! strcasecmp (opt, "brkintr"))   o.aopt.cor6.brk = BRK_INTR;
527         else if (! strcasecmp (opt, "brknull"))   o.aopt.cor6.brk = BRK_NULL;
528         else if (! strcasecmp (opt, "brkdisc"))   o.aopt.cor6.brk = BRK_DISCARD;
529         else if (! strcasecmp (opt, "-inlcr"))    o.aopt.cor6.inlcr = 0;
530         else if (! strcasecmp (opt, "+inlcr"))    o.aopt.cor6.inlcr = 1;
531         else if (! strcasecmp (opt, "-icrnl"))    o.aopt.cor6.icrnl = 0;
532         else if (! strcasecmp (opt, "+icrnl"))    o.aopt.cor6.icrnl = 1;
533         else if (! strcasecmp (opt, "-igncr"))    o.aopt.cor6.igncr = 0;
534         else if (! strcasecmp (opt, "+igncr"))    o.aopt.cor6.igncr = 1;
535
536         /* channel option register 7 */
537         else if (! strcasecmp (opt, "-ocrnl"))    o.aopt.cor7.ocrnl = 0;
538         else if (! strcasecmp (opt, "+ocrnl"))    o.aopt.cor7.ocrnl = 1;
539         else if (! strcasecmp (opt, "-onlcr"))    o.aopt.cor7.onlcr = 0;
540         else if (! strcasecmp (opt, "+onlcr"))    o.aopt.cor7.onlcr = 1;
541         else if (! strcasecmp (opt, "-fcerr"))    o.aopt.cor7.fcerr = 0;
542         else if (! strcasecmp (opt, "+fcerr"))    o.aopt.cor7.fcerr = 1;
543         else if (! strcasecmp (opt, "-lnext"))    o.aopt.cor7.lnext = 0;
544         else if (! strcasecmp (opt, "+lnext"))    o.aopt.cor7.lnext = 1;
545         else if (! strcasecmp (opt, "-istrip"))   o.aopt.cor7.istrip = 0;
546         else if (! strcasecmp (opt, "+istrip"))   o.aopt.cor7.istrip = 1;
547
548         else if (! strncasecmp (opt, "schr1=", 6)) o.aopt.schr1 = atosym (opt+6);
549         else if (! strncasecmp (opt, "schr2=", 6)) o.aopt.schr2 = atosym (opt+6);
550         else if (! strncasecmp (opt, "schr3=", 6)) o.aopt.schr3 = atosym (opt+6);
551         else if (! strncasecmp (opt, "schr4=", 6)) o.aopt.schr4 = atosym (opt+6);
552         else if (! strncasecmp (opt, "scrl=", 5))  o.aopt.scrl = atosym (opt+5);
553         else if (! strncasecmp (opt, "scrh=", 5))  o.aopt.scrh = atosym (opt+5);
554         else if (! strncasecmp (opt, "lnext=", 6)) o.aopt.lnxt = atosym (opt+6);
555         else
556                 usage ();
557 }
558
559 static void
560 set_hdlc_opt(char *opt)
561 {
562         /* hdlc channel option register 1 */
563         if (! strncasecmp (opt, "if", 2))        o.hopt.cor1.ifflags = atoi (opt + 2);
564         else if (! strcasecmp (opt, "noaddr"))   o.hopt.cor1.admode = ADMODE_NOADDR;
565         else if (! strcasecmp (opt, "addr1"))    o.hopt.cor1.admode = ADMODE_4_1;
566         else if (! strcasecmp (opt, "addr2"))    o.hopt.cor1.admode = ADMODE_2_2;
567         else if (! strcasecmp (opt, "-clrdet"))  o.hopt.cor1.clrdet = 0;
568         else if (! strcasecmp (opt, "+clrdet"))  o.hopt.cor1.clrdet = 1;
569         else if (! strcasecmp (opt, "addrlen1")) o.hopt.cor1.aflo = 0;
570         else if (! strcasecmp (opt, "addrlen2")) o.hopt.cor1.aflo = 1;
571
572         /* hdlc channel option register 2 */
573         else if (! strcasecmp (opt, "-dsr"))    o.hopt.cor2.dsrae = 0;
574         else if (! strcasecmp (opt, "+dsr"))    o.hopt.cor2.dsrae = 1;
575         else if (! strcasecmp (opt, "-cts"))    o.hopt.cor2.ctsae = 0;
576         else if (! strcasecmp (opt, "+cts"))    o.hopt.cor2.ctsae = 1;
577         else if (! strcasecmp (opt, "-rts"))    o.hopt.cor2.rtsao = 0;
578         else if (! strcasecmp (opt, "+rts"))    o.hopt.cor2.rtsao = 1;
579         else if (! strcasecmp (opt, "-fcsapd")) o.hopt.cor2.fcsapd = 0;
580         else if (! strcasecmp (opt, "+fcsapd")) o.hopt.cor2.fcsapd = 1;
581         else if (! strcasecmp (opt, "-crcinv")) o.hopt.cor2.crcninv = 1;
582         else if (! strcasecmp (opt, "+crcinv")) o.hopt.cor2.crcninv = 0;
583
584         /* hdlc channel option register 3 */
585         else if (! strncasecmp (opt, "pad", 3))    o.hopt.cor3.padcnt = atoi (opt + 3);
586         else if (! strcasecmp (opt, "idlemark"))   o.hopt.cor3.idle = 1;
587         else if (! strcasecmp (opt, "idleflag"))   o.hopt.cor3.idle = 0;
588         else if (! strcasecmp (opt, "-fcs"))       o.hopt.cor3.nofcs = 1;
589         else if (! strcasecmp (opt, "+fcs"))       o.hopt.cor3.nofcs = 0;
590         else if (! strcasecmp (opt, "fcs-crc-16")) o.hopt.cor3.fcspre = 1;
591         else if (! strcasecmp (opt, "fcs-v.41"))   o.hopt.cor3.fcspre = 0;
592         else if (! strcasecmp (opt, "syn=0xaa"))   o.hopt.cor3.syncpat = 1;
593         else if (! strcasecmp (opt, "syn=0x00"))   o.hopt.cor3.syncpat = 0;
594         else if (! strcasecmp (opt, "-syn"))       o.hopt.cor3.sndpad = 0;
595         else if (! strcasecmp (opt, "+syn"))       o.hopt.cor3.sndpad = 1;
596
597         else if (! strncasecmp (opt, "rfar1=", 6)) o.hopt.rfar1 = atoi (opt + 6);
598         else if (! strncasecmp (opt, "rfar2=", 6)) o.hopt.rfar2 = atoi (opt + 6);
599         else if (! strncasecmp (opt, "rfar3=", 6)) o.hopt.rfar3 = atoi (opt + 6);
600         else if (! strncasecmp (opt, "rfar4=", 6)) o.hopt.rfar4 = atoi (opt + 6);
601         else if (! strcasecmp (opt, "crc-16"))     o.hopt.cpsr = 1;
602         else if (! strcasecmp (opt, "crc-v.41"))   o.hopt.cpsr = 0;
603         else usage ();
604 }
605
606 static void
607 set_bisync_opt(char *opt __unused)
608 {
609         usage ();
610 }
611
612 static void
613 set_x21_opt(char *opt __unused)
614 {
615         usage ();
616 }
617
618 int
619 main(int argc, char **argv)
620 {
621         int channel;
622
623         for (--argc, ++argv; argc>0 && **argv=='-'; --argc, ++argv)
624                 if (! strcasecmp (*argv, "-a"))
625                         ++aflag;
626                 else if (! strcasecmp (*argv, "-s"))
627                         ++sflag;
628                 else
629                         usage ();
630
631         if (argc <= 0) {
632                 if (sflag)
633                         printallstats ();
634                 else
635                         printall ();
636                 return (0);
637         }
638
639         if (argv[0][0]=='c' && argv[0][1]=='x')
640                 *argv += 2;
641         if (**argv<'0' || **argv>'9')
642                 usage ();
643         channel = atoi (*argv);
644         --argc, ++argv;
645
646         if (sflag) {
647                 if (printstats (channel, 1) < 0)
648                         printf ("channel cx%d not available\n", channel);
649                 return (0);
650         }
651
652         getchan (channel);
653
654         if (argc <= 0) {
655                 printchan (channel);
656                 return (0);
657         }
658
659         for (; argc>0; --argc, ++argv)
660                 if (**argv == '(')
661                         continue;
662                 else if (! strncasecmp (*argv, "ispeed=", 7))
663                         o.rxbaud = atoi (*argv+7);
664                 else if (! strncasecmp (*argv, "ospeed=", 7))
665                         o.txbaud = atoi (*argv+7);
666                 else if (! strcasecmp (*argv, "async"))
667                         o.mode = M_ASYNC;
668                 else if (! strcasecmp (*argv, "hdlc"))
669                         o.mode = M_HDLC;
670                 else if (! strcasecmp (*argv, "bisync") ||
671                     ! strcasecmp (*argv, "bsc"))
672                         o.mode = M_BISYNC;
673                 else if (! strcasecmp (*argv, "x.21") ||
674                     ! strcasecmp (*argv, "x21"))
675                         o.mode = M_X21;
676                 else if (**argv>='0' && **argv<='9')
677                         o.txbaud = o.rxbaud = atoi (*argv);
678                 else if (! strcasecmp (*argv, "cisco")) {
679                         o.sopt.cisco = 1;
680                         o.sopt.ext = 0;
681                 } else if (! strcasecmp (*argv, "ppp")) {
682                         o.sopt.cisco = 0;
683                         o.sopt.ext = 0;
684                 } else if (! strcasecmp (*argv, "ext"))
685                         o.sopt.ext = 1;
686                 else if (! strcasecmp (*argv, "+keepalive"))
687                         o.sopt.keepalive = 1;
688                 else if (! strcasecmp (*argv, "-keepalive"))
689                         o.sopt.keepalive = 0;
690                 else if (! strcasecmp (*argv, "+autorts"))
691                         o.sopt.norts = 0;
692                 else if (! strcasecmp (*argv, "-autorts"))
693                         o.sopt.norts = 1;
694                 else if (! strcasecmp (*argv, "port=rs232") ||
695                     ! strcasecmp (*argv, "port=rs449") ||
696                     ! strcasecmp (*argv, "port=v35"))
697                         set_interface_type (*argv);
698                 else if (! strncasecmp (*argv, "master=",7))
699                         set_master (*argv+7);
700
701                 /*
702                  * Common channel options
703                  */
704                 /* channel option register 4 */
705                 else if (! strcasecmp (*argv, "-ctsdown"))
706                         o.opt.cor4.cts_zd = 0;
707                 else if (! strcasecmp (*argv, "+ctsdown"))
708                         o.opt.cor4.cts_zd = 1;
709                 else if (! strcasecmp (*argv, "-cddown"))
710                         o.opt.cor4.cd_zd = 0;
711                 else if (! strcasecmp (*argv, "+cddown"))
712                         o.opt.cor4.cd_zd = 1;
713                 else if (! strcasecmp (*argv, "-dsrdown"))
714                         o.opt.cor4.dsr_zd = 0;
715                 else if (! strcasecmp (*argv, "+dsrdown"))
716                         o.opt.cor4.dsr_zd = 1;
717                 else if (! strncasecmp (*argv, "fifo=", 5))
718                         o.opt.cor4.thr = atoi (*argv + 5);
719
720                 /* channel option register 5 */
721                 else if (! strcasecmp (*argv, "-ctsup"))
722                         o.opt.cor5.cts_od = 0;
723                 else if (! strcasecmp (*argv, "+ctsup"))
724                         o.opt.cor5.cts_od = 1;
725                 else if (! strcasecmp (*argv, "-cdup"))
726                         o.opt.cor5.cd_od = 0;
727                 else if (! strcasecmp (*argv, "+cdup"))
728                         o.opt.cor5.cd_od = 1;
729                 else if (! strcasecmp (*argv, "-dsrup"))
730                         o.opt.cor5.dsr_od = 0;
731                 else if (! strcasecmp (*argv, "+dsrup"))
732                         o.opt.cor5.dsr_od = 1;
733                 else if (! strncasecmp (*argv, "rfifo=", 6))
734                         o.opt.cor5.rx_thr = atoi (*argv + 6);
735
736                 /* receive clock option register */
737                 else if (! strcasecmp (*argv, "nrz"))
738                         o.opt.rcor.encod = ENCOD_NRZ;
739                 else if (! strcasecmp (*argv, "nrzi"))
740                         o.opt.rcor.encod = ENCOD_NRZI;
741                 else if (! strcasecmp (*argv, "manchester"))
742                         o.opt.rcor.encod = ENCOD_MANCHESTER;
743                 else if (! strcasecmp (*argv, "-dpll"))
744                         o.opt.rcor.dpll = 0;
745                 else if (! strcasecmp (*argv, "+dpll"))
746                         o.opt.rcor.dpll = 1;
747
748                 /* transmit clock option register */
749                 else if (! strcasecmp (*argv, "-lloop"))
750                         o.opt.tcor.llm = 0;
751                 else if (! strcasecmp (*argv, "+lloop"))
752                         o.opt.tcor.llm = 1;
753                 else if (! strcasecmp (*argv, "-extclock"))
754                         o.opt.tcor.ext1x = 0;
755                 else if (! strcasecmp (*argv, "+extclock"))
756                         o.opt.tcor.ext1x = 1;
757
758                 /*
759                  * Mode dependent channel options
760                  */
761                 else switch (o.mode) {
762                 case M_ASYNC:  set_async_opt (*argv); break;
763                 case M_HDLC:   set_hdlc_opt (*argv); break;
764                 case M_BISYNC: set_bisync_opt (*argv); break;
765                 case M_X21:    set_x21_opt (*argv); break;
766                 }
767
768         setchan (channel);
769         return (0);
770 }