]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - gnu/libexec/uucp/libuuconf/tport.c
This commit was generated by cvs2svn to compensate for changes in r53796,
[FreeBSD/FreeBSD.git] / gnu / libexec / uucp / libuuconf / tport.c
1 /* tport.c
2    Find a port in the Taylor UUCP configuration files.
3
4    Copyright (C) 1992, 1993 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 or
23    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
24    */
25
26 #include "uucnfi.h"
27
28 #if USE_RCS_ID
29 const char _uuconf_tport_rcsid[] = "$FreeBSD$";
30 #endif
31
32 #include <errno.h>
33 \f
34 static int ipport P((pointer pglobal, int argc, char **argv, pointer pvar,
35                      pointer pinfo));
36 static int ipunknown P((pointer pglobal, int argc, char **argv,
37                         pointer pvar, pointer pinfo));
38 \f
39 /* Find a port in the Taylor UUCP configuration files by name, baud
40    rate, and special purpose function.  */
41
42 int
43 uuconf_taylor_find_port (pglobal, zname, ibaud, ihighbaud, pifn, pinfo,
44                          qport)
45      pointer pglobal;
46      const char *zname;
47      long ibaud;
48      long ihighbaud;
49      int (*pifn) P((struct uuconf_port *, pointer));
50      pointer pinfo;
51      struct uuconf_port *qport;
52 {
53   struct sglobal *qglobal = (struct sglobal *) pglobal;
54   FILE *e;
55   pointer pblock;
56   char *zfree;
57   int iret;
58   char **pz;
59
60   if (ihighbaud == 0L)
61     ihighbaud = ibaud;
62
63   e = NULL;
64   pblock = NULL;
65   zfree = NULL;
66   iret = UUCONF_NOT_FOUND;
67
68   for (pz = qglobal->qprocess->pzportfiles; *pz != NULL; pz++)
69     {
70       struct uuconf_cmdtab as[2];
71       char *zport;
72       struct uuconf_port sdefault;
73       int ilineno;
74
75       e = fopen (*pz, "r");
76       if (e == NULL)
77         {
78           if (FNO_SUCH_FILE ())
79             continue;
80           qglobal->ierrno = errno;
81           iret = UUCONF_FOPEN_FAILED | UUCONF_ERROR_ERRNO;
82           break;
83         }
84
85       qglobal->ilineno = 0;
86
87       /* Gather the default information from the top of the file.  We
88          do this by handling the "port" command ourselves and passing
89          every other command to _uuconf_iport_cmd via ipunknown.  The
90          value of zport will be an malloc block.  */
91       as[0].uuconf_zcmd = "port";
92       as[0].uuconf_itype = UUCONF_CMDTABTYPE_FN | 2;
93       as[0].uuconf_pvar = (pointer) &zport;
94       as[0].uuconf_pifn = ipport;
95
96       as[1].uuconf_zcmd = NULL;
97
98       pblock = uuconf_malloc_block ();
99       if (pblock == NULL)
100         {
101           qglobal->ierrno = errno;
102           iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
103           break;
104         }
105
106       _uuconf_uclear_port (&sdefault);
107       sdefault.uuconf_palloc = pblock;
108       zport = NULL;
109       iret = uuconf_cmd_file (pglobal, e, as, (pointer) &sdefault,
110                               ipunknown, UUCONF_CMDTABFLAG_BACKSLASH,
111                               pblock);
112       if (iret != UUCONF_SUCCESS)
113         {
114           zfree = zport;
115           break;
116         }
117
118       /* Now skip until we find a port with a matching name.  If the
119          zname argument is NULL, we will have to read every port.  */
120       iret = UUCONF_NOT_FOUND;
121       while (zport != NULL)
122         {
123           uuconf_cmdtabfn piunknown;
124           boolean fmatch;
125
126           if (zname == NULL || strcmp (zname, zport) == 0)
127             {
128               piunknown = ipunknown;
129               *qport = sdefault;
130               qport->uuconf_zname = zport;
131               zfree = zport;
132               fmatch = TRUE;
133             }
134           else
135             {
136               piunknown = NULL;
137               free ((pointer) zport);
138               fmatch = FALSE;
139             }
140
141           zport = NULL;
142           ilineno = qglobal->ilineno;
143           iret = uuconf_cmd_file (pglobal, e, as, (pointer) qport,
144                                   piunknown, UUCONF_CMDTABFLAG_BACKSLASH,
145                                   pblock);
146           qglobal->ilineno += ilineno;
147           if (iret != UUCONF_SUCCESS)
148             break;
149           iret = UUCONF_NOT_FOUND;
150
151           /* We may have just gathered information about a port.  See
152              if it matches the name, the baud rate and the special
153              function.  */
154           if (fmatch)
155             {
156               if (ibaud != 0)
157                 {
158                   if (qport->uuconf_ttype == UUCONF_PORTTYPE_MODEM)
159                     {
160                       long imbaud, imhigh, imlow;
161
162                       imbaud = qport->uuconf_u.uuconf_smodem.uuconf_ibaud;
163                       imhigh = qport->uuconf_u.uuconf_smodem.uuconf_ihighbaud;
164                       imlow = qport->uuconf_u.uuconf_smodem.uuconf_ilowbaud;
165
166                       if (imbaud == 0 && imlow == 0)
167                         ;
168                       else if (ibaud <= imbaud && imbaud <= ihighbaud)
169                         ;
170                       else if (imlow != 0
171                                && imlow <= ihighbaud
172                                && imhigh >= ibaud)
173                         ;
174                       else
175                         fmatch = FALSE;
176                     }
177                   else if (qport->uuconf_ttype == UUCONF_PORTTYPE_DIRECT)
178                     {
179                       long idbaud;
180
181                       idbaud = qport->uuconf_u.uuconf_sdirect.uuconf_ibaud;
182                       if (idbaud != 0 && idbaud != ibaud)
183                         fmatch = FALSE;
184                     }
185                 }
186             }
187
188           if (fmatch)
189             {
190               if (pifn != NULL)
191                 {
192                   iret = (*pifn) (qport, pinfo);
193                   if (iret == UUCONF_NOT_FOUND)
194                     fmatch = FALSE;
195                   else if (iret != UUCONF_SUCCESS)
196                     break;
197                 }
198             }
199
200           if (fmatch)
201             {
202               if (uuconf_add_block (pblock, zfree) == 0)
203                 {
204                   zfree = NULL;
205                   iret = UUCONF_SUCCESS;
206                 }
207               else
208                 {
209                   qglobal->ierrno = errno;
210                   iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
211                 }
212               break;
213             }
214
215           if (zfree != NULL)
216             {
217               free ((pointer) zfree);
218               zfree = NULL;
219             }
220         }
221
222       (void) fclose (e);
223       e = NULL;
224
225       if (iret != UUCONF_NOT_FOUND)
226         break;
227
228       uuconf_free_block (pblock);
229       pblock = NULL;
230     }
231
232   if (e != NULL)
233     (void) fclose (e);
234   if (zfree != NULL)
235     free ((pointer) zfree);
236   if (iret != UUCONF_SUCCESS && pblock != NULL)
237     uuconf_free_block (pblock);
238
239   if (iret != UUCONF_SUCCESS && iret != UUCONF_NOT_FOUND)
240     {
241       qglobal->zfilename = *pz;
242       iret |= UUCONF_ERROR_FILENAME;
243     }
244
245   return iret;
246 }
247 \f
248 /* Handle a "port" command.  This copies the string onto the heap and
249    returns the pointer in *pvar.  It returns UUCONF_CMDTABRET_EXIT to
250    force uuconf_cmd_file to stop reading and return to the code above,
251    which will then check the port just read to see if it matches.  */
252
253 /*ARGSUSED*/
254 static int
255 ipport (pglobal, argc, argv, pvar, pinfo)
256      pointer pglobal;
257      int argc;
258      char **argv;
259      pointer pvar;
260      pointer pinfo;
261 {
262   struct sglobal *qglobal = (struct sglobal *) pglobal;
263   char **pz = (char **) pvar;
264   size_t csize;
265
266   csize = strlen (argv[1]) + 1;
267   *pz = malloc (csize);
268   if (*pz == NULL)
269     {
270       qglobal->ierrno = errno;
271       return (UUCONF_MALLOC_FAILED
272               | UUCONF_ERROR_ERRNO
273               | UUCONF_CMDTABRET_EXIT);
274     }
275   memcpy ((pointer) *pz, (pointer) argv[1], csize);
276   return UUCONF_CMDTABRET_EXIT;
277 }
278 \f
279 /* Handle an unknown command by passing it on to _uuconf_iport_cmd,
280    which will parse it into the port structure. */
281
282 /*ARGSUSED*/
283 static int
284 ipunknown (pglobal, argc, argv, pvar, pinfo)
285      pointer pglobal;
286      int argc;
287      char **argv;
288      pointer pvar;
289      pointer pinfo;
290 {
291   struct sglobal *qglobal = (struct sglobal *) pglobal;
292   struct uuconf_port *qport = (struct uuconf_port *) pinfo;
293   int iret;
294
295   iret = _uuconf_iport_cmd (qglobal, argc, argv, qport);
296   if (UUCONF_ERROR_VALUE (iret) != UUCONF_SUCCESS)
297     iret |= UUCONF_CMDTABRET_EXIT;
298   return iret;
299 }