1 /* vport.c
2 Find a port in the V2 configuration files.
3
4 Copyright (C) 1992, 1993, 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_vport_rcsid[] = "$FreeBSD$";
29 #endif
30
31 #include <errno.h>
32 #include <ctype.h>
33
34 /* Find a port in the V2 configuration files by name, baud rate, and
35 special purpose function. */
36
37 int
uuconf_v2_find_port(pglobal,zname,ibaud,ihighbaud,pifn,pinfo,qport)38 uuconf_v2_find_port (pglobal, zname, ibaud, ihighbaud, pifn, pinfo, qport)
39 pointer pglobal;
40 const char *zname;
41 long ibaud;
42 long ihighbaud ATTRIBUTE_UNUSED;
43 int (*pifn) P((struct uuconf_port *, pointer));
44 pointer pinfo;
45 struct uuconf_port *qport;
46 {
47 struct sglobal *qglobal = (struct sglobal *) pglobal;
48 FILE *e;
49 char *zline;
50 size_t cline;
51 char **pzsplit;
52 size_t csplit;
53 int iret;
54 int cchars;
55
56 e = fopen (qglobal->qprocess->zv2devices, "r");
57 if (e == NULL)
58 {
59 if (FNO_SUCH_FILE ())
60 return UUCONF_NOT_FOUND;
61 qglobal->ierrno = errno;
62 qglobal->zfilename = qglobal->qprocess->zv2devices;
63 return (UUCONF_FOPEN_FAILED
64 | UUCONF_ERROR_ERRNO
65 | UUCONF_ERROR_FILENAME);
66 }
67
68 zline = NULL;
69 cline = 0;
70 pzsplit = NULL;
71 csplit = 0;
72
73 iret = UUCONF_NOT_FOUND;
74
75 qglobal->ilineno = 0;
76
77 while ((cchars = getline (&zline, &cline, e)) > 0)
78 {
79 int ctoks;
80 char *zend;
81 long ilow, ihigh;
82 pointer pblock;
83
84 ++qglobal->ilineno;
85
86 iret = UUCONF_NOT_FOUND;
87
88 --cchars;
89 if (zline[cchars] == '\n')
90 zline[cchars] = '\0';
91 zline[strcspn (zline, "#")] = '\0';
92
93 ctoks = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit);
94 if (ctoks < 0)
95 {
96 qglobal->ierrno = errno;
97 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
98 break;
99 }
100
101 /* An entry in L-devices is
102
103 type device dial-device baud dialer
104
105 The type (normally "ACU") is treated as the name. */
106
107 /* If there aren't enough entries, ignore the line; this
108 should probably do something more useful. */
109 if (ctoks < 4)
110 continue;
111
112 /* Make sure the name matches any argument. */
113 if (zname != NULL
114 && strcmp (pzsplit[0], zname) != 0)
115 continue;
116
117 /* Get the baud rate. */
118 ilow = strtol (pzsplit[3], &zend, 10);
119 if (*zend == '-')
120 ihigh = strtol (zend + 1, (char **) NULL, 10);
121 else
122 ihigh = ilow;
123
124 /* Make sure the baud rate matches any argument. */
125 if (ibaud != 0
126 && ilow != 0
127 && (ilow > ibaud || ihigh < ibaud))
128 continue;
129
130 /* Now we must construct the port information, so that we can
131 pass it to pifn. The port type is determined by it's name,
132 unfortunately. The name "DIR" is used for a direct port, and
133 anything else for a modem port. */
134 pblock = NULL;
135 _uuconf_uclear_port (qport);
136 qport->uuconf_zname = pzsplit[0];
137 if (strcmp (pzsplit[0], "DIR") == 0)
138 {
139 qport->uuconf_ttype = UUCONF_PORTTYPE_DIRECT;
140 qport->uuconf_u.uuconf_sdirect.uuconf_zdevice = pzsplit[1];
141 qport->uuconf_u.uuconf_sdirect.uuconf_ibaud = ilow;
142 qport->uuconf_u.uuconf_sdirect.uuconf_fcarrier = FALSE;
143 qport->uuconf_u.uuconf_sdirect.uuconf_fhardflow = TRUE;
144 }
145 else
146 {
147 qport->uuconf_ttype = UUCONF_PORTTYPE_MODEM;
148 qport->uuconf_u.uuconf_smodem.uuconf_zdevice = pzsplit[1];
149 if (strcmp (pzsplit[2], "-") != 0)
150 qport->uuconf_u.uuconf_smodem.uuconf_zdial_device = pzsplit[2];
151 else
152 qport->uuconf_u.uuconf_smodem.uuconf_zdial_device = NULL;
153 if (ilow == ihigh)
154 {
155 qport->uuconf_u.uuconf_smodem.uuconf_ibaud = ilow;
156 qport->uuconf_u.uuconf_smodem.uuconf_ilowbaud = 0L;
157 qport->uuconf_u.uuconf_smodem.uuconf_ihighbaud = 0L;
158 }
159 else
160 {
161 qport->uuconf_u.uuconf_smodem.uuconf_ibaud = 0L;
162 qport->uuconf_u.uuconf_smodem.uuconf_ilowbaud = ilow;
163 qport->uuconf_u.uuconf_smodem.uuconf_ihighbaud = ihigh;
164 }
165 qport->uuconf_u.uuconf_smodem.uuconf_fcarrier = TRUE;
166 qport->uuconf_u.uuconf_smodem.uuconf_fhardflow = TRUE;
167 if (ctoks < 5)
168 qport->uuconf_u.uuconf_smodem.uuconf_pzdialer = NULL;
169 else
170 {
171 size_t c;
172 char **pzd;
173
174 /* We support dialer/token pairs, although normal V2
175 doesn't. */
176 pblock = uuconf_malloc_block ();
177 if (pblock == NULL)
178 {
179 qglobal->ierrno = errno;
180 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
181 break;
182 }
183 c = (ctoks - 4) * sizeof (char *);
184 pzd = (char **) uuconf_malloc (pblock, c + sizeof (char *));
185 if (pzd == NULL)
186 {
187 qglobal->ierrno = errno;
188 uuconf_free_block (pblock);
189 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
190 break;
191 }
192 memcpy ((pointer) pzd, (pointer) (pzsplit + 4), c);
193 pzd[ctoks - 4] = NULL;
194
195 qport->uuconf_u.uuconf_smodem.uuconf_pzdialer = pzd;
196 }
197 qport->uuconf_u.uuconf_smodem.uuconf_qdialer = NULL;
198 }
199
200 if (pifn != NULL)
201 {
202 iret = (*pifn) (qport, pinfo);
203 if (iret != UUCONF_SUCCESS)
204 {
205 if (pblock != NULL)
206 uuconf_free_block (pblock);
207 if (iret != UUCONF_NOT_FOUND)
208 break;
209 continue;
210 }
211 }
212
213 /* This is the port we want. */
214 if (pblock == NULL)
215 {
216 pblock = uuconf_malloc_block ();
217 if (pblock == NULL)
218 {
219 qglobal->ierrno = errno;
220 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
221 break;
222 }
223 }
224
225 if (uuconf_add_block (pblock, zline) != 0)
226 {
227 qglobal->ierrno = errno;
228 uuconf_free_block (pblock);
229 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
230 break;
231 }
232 zline = NULL;
233
234 qport->uuconf_palloc = pblock;
235
236 break;
237 }
238
239 (void) fclose (e);
240
241 if (zline != NULL)
242 free ((pointer) zline);
243 if (pzsplit != NULL)
244 free ((pointer) pzsplit);
245
246 if (iret != UUCONF_SUCCESS && iret != UUCONF_NOT_FOUND)
247 {
248 qglobal->zfilename = qglobal->qprocess->zv2devices;
249 iret |= UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
250 }
251
252 return iret;
253 }
254