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