1 /* tdialc.c
2    Handle a Taylor UUCP dialer command.
3 
4    Copyright (C) 1992, 2002 Ian Lance Taylor
5 
6    This file is part of the Taylor UUCP uuconf library.
7 
8    This library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Library General Public License
10    as published by the Free Software Foundation; either version 2 of
11    the License, or (at your option) any later version.
12 
13    This library is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Library General Public License for more details.
17 
18    You should have received a copy of the GNU Library General Public
19    License along with this library; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
21 
22    The author of the program may be contacted at ian@airs.com.
23    */
24 
25 #include "uucnfi.h"
26 
27 #if USE_RCS_ID
28 const char _uuconf_tdialc_rcsid[] = "$FreeBSD$";
29 #endif
30 
31 static int idchat P((pointer pglobal, int argc, char **argv, pointer pvar,
32 		     pointer pinfo));
33 static int iddtr_toggle P((pointer pglobal, int argc, char **argv,
34 			   pointer pvar, pointer pinfo));
35 static int idcomplete P((pointer pglobal, int argc, char **argv,
36 			 pointer pvar, pointer pinfo));
37 static int idproto_param P((pointer pglobal, int argc, char **argv,
38 			    pointer pvar, pointer pinfo));
39 static int idcunknown P((pointer pglobal, int argc, char **argv,
40 			 pointer pvar, pointer pinfo));
41 
42 /* The command table for dialer commands.  The "dialer" command is
43    handled specially.  */
44 static const struct cmdtab_offset asDialer_cmds[] =
45 {
46   { "chat", UUCONF_CMDTABTYPE_PREFIX | 0,
47       offsetof (struct uuconf_dialer, uuconf_schat), idchat },
48   { "dialtone", UUCONF_CMDTABTYPE_STRING,
49       offsetof (struct uuconf_dialer, uuconf_zdialtone), NULL },
50   { "pause", UUCONF_CMDTABTYPE_STRING,
51       offsetof (struct uuconf_dialer, uuconf_zpause), NULL },
52   { "carrier", UUCONF_CMDTABTYPE_BOOLEAN,
53       offsetof (struct uuconf_dialer, uuconf_fcarrier), NULL },
54   { "carrier-wait", UUCONF_CMDTABTYPE_INT,
55       offsetof (struct uuconf_dialer, uuconf_ccarrier_wait), NULL },
56   { "dtr-toggle", UUCONF_CMDTABTYPE_FN | 0, (size_t) -1, iddtr_toggle },
57   { "complete", UUCONF_CMDTABTYPE_FN | 2,
58       offsetof (struct uuconf_dialer, uuconf_scomplete), idcomplete },
59   { "complete-chat", UUCONF_CMDTABTYPE_PREFIX,
60       offsetof (struct uuconf_dialer, uuconf_scomplete), idchat },
61   { "abort", UUCONF_CMDTABTYPE_FN | 2,
62       offsetof (struct uuconf_dialer, uuconf_sabort), idcomplete },
63   { "abort-chat", UUCONF_CMDTABTYPE_PREFIX,
64       offsetof (struct uuconf_dialer, uuconf_sabort), idchat },
65   { "protocol-parameter", UUCONF_CMDTABTYPE_FN | 0,
66       offsetof (struct uuconf_dialer, uuconf_qproto_params), idproto_param },
67   { "seven-bit", UUCONF_CMDTABTYPE_FN | 2,
68       offsetof (struct uuconf_dialer, uuconf_ireliable), _uuconf_iseven_bit },
69   { "reliable", UUCONF_CMDTABTYPE_FN | 2,
70       offsetof (struct uuconf_dialer, uuconf_ireliable), _uuconf_ireliable },
71   { "half-duplex", UUCONF_CMDTABTYPE_FN | 2,
72       offsetof (struct uuconf_dialer, uuconf_ireliable),
73       _uuconf_ihalf_duplex },
74   { NULL, 0, 0, NULL }
75 };
76 
77 #define CDIALER_CMDS (sizeof asDialer_cmds / sizeof asDialer_cmds[0])
78 
79 /* Handle a command passed to a dialer from a Taylor UUCP
80    configuration file.  This can be called when reading the dialer
81    file, the port file, or the sys file.  The return value may have
82    UUCONF_CMDTABRET_KEEP set, but not UUCONF_CMDTABRET_EXIT.  It
83    assigns values to the elements of qdialer.  The first time this is
84    called, qdialer->uuconf_palloc should be set.  This will not set
85    qdialer->uuconf_zname.  */
86 
87 int
_uuconf_idialer_cmd(qglobal,argc,argv,qdialer)88 _uuconf_idialer_cmd (qglobal, argc, argv, qdialer)
89      struct sglobal *qglobal;
90      int argc;
91      char **argv;
92      struct uuconf_dialer *qdialer;
93 {
94   struct uuconf_cmdtab as[CDIALER_CMDS];
95   int iret;
96 
97   _uuconf_ucmdtab_base (asDialer_cmds, CDIALER_CMDS, (char *) qdialer, as);
98 
99   iret = uuconf_cmd_args ((pointer) qglobal, argc, argv, as,
100 			  (pointer) qdialer, idcunknown, 0,
101 			  qdialer->uuconf_palloc);
102 
103   return iret &~ UUCONF_CMDTABRET_EXIT;
104 }
105 
106 /* Reroute a chat script command.  */
107 
108 static int
idchat(pglobal,argc,argv,pvar,pinfo)109 idchat (pglobal, argc, argv, pvar, pinfo)
110      pointer pglobal;
111      int argc;
112      char **argv;
113      pointer pvar;
114      pointer pinfo;
115 {
116   struct sglobal *qglobal = (struct sglobal *) pglobal;
117   struct uuconf_chat *qchat = (struct uuconf_chat *) pvar;
118   struct uuconf_dialer *qdialer = (struct uuconf_dialer *) pinfo;
119 
120   return _uuconf_ichat_cmd (qglobal, argc, argv, qchat,
121 			    qdialer->uuconf_palloc);
122 }
123 
124 /* Handle the "dtr-toggle" command, which may take two arguments.  */
125 
126 /*ARGSUSED*/
127 static int
iddtr_toggle(pglobal,argc,argv,pvar,pinfo)128 iddtr_toggle (pglobal, argc, argv, pvar, pinfo)
129      pointer pglobal;
130      int argc;
131      char **argv;
132      pointer pvar ATTRIBUTE_UNUSED;
133      pointer pinfo;
134 {
135   struct sglobal *qglobal = (struct sglobal *) pglobal;
136   struct uuconf_dialer *qdialer = (struct uuconf_dialer *) pinfo;
137   int iret;
138 
139   if (argc < 2 || argc > 3)
140     return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
141 
142   iret = _uuconf_iboolean (qglobal, argv[1], &qdialer->uuconf_fdtr_toggle);
143   if ((iret &~ UUCONF_CMDTABRET_KEEP) != UUCONF_SUCCESS)
144     return iret;
145 
146   if (argc < 3)
147     return iret;
148 
149   iret |= _uuconf_iboolean (qglobal, argv[2],
150 			    &qdialer->uuconf_fdtr_toggle_wait);
151 
152   return iret;
153 }
154 
155 /* Handle the "complete" and "abort" commands.  These just turn a
156    string into a trivial chat script.  */
157 
158 /*ARGSUSED*/
159 static int
idcomplete(pglobal,argc,argv,pvar,pinfo)160 idcomplete (pglobal, argc, argv, pvar, pinfo)
161      pointer pglobal;
162      int argc ATTRIBUTE_UNUSED;
163      char **argv;
164      pointer pvar;
165      pointer pinfo;
166 {
167   struct sglobal *qglobal = (struct sglobal *) pglobal;
168   struct uuconf_chat *qchat = (struct uuconf_chat *) pvar;
169   struct uuconf_dialer *qdialer = (struct uuconf_dialer *) pinfo;
170   char *azargs[3];
171 
172   azargs[0] = (char *) "complete-chat";
173   azargs[1] = (char *) "\"\"";
174   azargs[2] = (char *) argv[1];
175 
176   return _uuconf_ichat_cmd (qglobal, 3, azargs, qchat,
177 			    qdialer->uuconf_palloc);
178 }
179 
180 /* Handle the "protocol-parameter" command.  */
181 
182 static int
idproto_param(pglobal,argc,argv,pvar,pinfo)183 idproto_param (pglobal, argc, argv, pvar, pinfo)
184      pointer pglobal;
185      int argc;
186      char **argv;
187      pointer pvar;
188      pointer pinfo;
189 {
190   struct sglobal *qglobal = (struct sglobal *) pglobal;
191   struct uuconf_proto_param **pqparam = (struct uuconf_proto_param **) pvar;
192   struct uuconf_dialer *qdialer = (struct uuconf_dialer *) pinfo;
193 
194   return _uuconf_iadd_proto_param (qglobal, argc - 1, argv + 1, pqparam,
195 				   qdialer->uuconf_palloc);
196 }
197 
198 /* Give an error for an unknown dialer command.  */
199 
200 /*ARGSUSED*/
201 static int
idcunknown(pglobal,argc,argv,pvar,pinfo)202 idcunknown (pglobal, argc, argv, pvar, pinfo)
203      pointer pglobal ATTRIBUTE_UNUSED;
204      int argc ATTRIBUTE_UNUSED;
205      char **argv ATTRIBUTE_UNUSED;
206      pointer pvar ATTRIBUTE_UNUSED;
207      pointer pinfo ATTRIBUTE_UNUSED;
208 {
209   return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
210 }
211