1/* util.c
2   A couple of UUCP utility functions.
3
4   Copyright (C) 1991, 1992, 1993, 2002 Ian Lance Taylor
5
6   This file is part of the Taylor UUCP package.
7
8   This program is free software; you can redistribute it and/or
9   modify it under the terms of the GNU General Public License as
10   published by the Free Software Foundation; either version 2 of the
11   License, or (at your option) any later version.
12
13   This program 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   General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; 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 "uucp.h"
26
27#if USE_RCS_ID
28const char util_rcsid[] = "$Id: util.c,v 1.11 2002/03/05 19:10:42 ian Rel $";
29#endif
30
31#include <ctype.h>
32
33#include "uudefs.h"
34#include "uuconf.h"
35#include "system.h"
36
37/* Get information for an unknown system.  This will leave the name
38   allocated on the heap.  We could fix this by breaking the
39   abstraction and adding the name to qsys->palloc.  It makes sure the
40   name is not too long, but takes no other useful action.  */
41
42boolean
43funknown_system (puuconf, zsystem, qsys)
44     pointer puuconf;
45     const char *zsystem;
46     struct uuconf_system *qsys;
47{
48  char *z;
49  int iuuconf;
50
51  if (strlen (zsystem) <= cSysdep_max_name_len)
52    z = zbufcpy (zsystem);
53  else
54    {
55      char **pznames, **pz;
56      boolean ffound;
57
58      z = zbufalc (cSysdep_max_name_len + 1);
59      memcpy (z, zsystem, cSysdep_max_name_len);
60      z[cSysdep_max_name_len] = '\0';
61
62      iuuconf = uuconf_system_names (puuconf, &pznames, TRUE);
63      if (iuuconf != UUCONF_SUCCESS)
64	ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
65
66      ffound = FALSE;
67      for (pz = pznames; *pz != NULL; pz++)
68	{
69	  if (strcmp (*pz, z) == 0)
70	    ffound = TRUE;
71	  xfree ((pointer) *pz);
72	}
73      xfree ((pointer) pznames);
74
75      if (ffound)
76	{
77	  ubuffree (z);
78	  return FALSE;
79	}
80    }
81
82  iuuconf = uuconf_system_unknown (puuconf, qsys);
83  if (iuuconf == UUCONF_NOT_FOUND)
84    {
85      ubuffree (z);
86      return FALSE;
87    }
88  else if (iuuconf != UUCONF_SUCCESS)
89    ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
90
91  for (; qsys != NULL; qsys = qsys->uuconf_qalternate)
92    qsys->uuconf_zname = z;
93
94  return TRUE;
95}
96
97/* Remove all occurrences of the local system name followed by an
98   exclamation point from the front of a string, returning the new
99   string.  This is used by uucp and uux.  */
100
101char *
102zremove_local_sys (qlocalsys, z)
103     struct uuconf_system *qlocalsys;
104     char *z;
105{
106  size_t clen;
107  char *zexclam;
108
109  clen = strlen (qlocalsys->uuconf_zname);
110  zexclam = strchr (z, '!');
111  while (zexclam != NULL)
112    {
113      if (z == zexclam
114	  || ((size_t) (zexclam - z) == clen
115	      && strncmp (z, qlocalsys->uuconf_zname, clen) == 0))
116	;
117      else if (qlocalsys->uuconf_pzalias == NULL)
118	break;
119      else
120	{
121	  char **pzal;
122
123	  for (pzal = qlocalsys->uuconf_pzalias; *pzal != NULL; pzal++)
124	    if (strlen (*pzal) == (size_t) (zexclam - z)
125		&& strncmp (z, *pzal, (size_t) (zexclam - z)) == 0)
126	      break;
127	  if (*pzal == NULL)
128	    break;
129	}
130      z = zexclam + 1;
131      zexclam = strchr (z, '!');
132    }
133
134  return z;
135}
136
137/* See whether a file is in a directory list, and make sure the user
138   has appropriate access.  */
139
140boolean
141fin_directory_list (zfile, pzdirs, zpubdir, fcheck, freadable, zuser)
142     const char *zfile;
143     char **pzdirs;
144     const char *zpubdir;
145     boolean fcheck;
146     boolean freadable;
147     const char *zuser;
148{
149  boolean fmatch;
150  char **pz;
151
152  fmatch = FALSE;
153
154  for (pz = pzdirs; *pz != NULL; pz++)
155    {
156      char *zuse;
157
158      if (pz[0][0] == '!')
159	{
160	  zuse = zsysdep_local_file (*pz + 1, zpubdir, (boolean *) NULL);
161	  if (zuse == NULL)
162	    return FALSE;
163
164	  if (fsysdep_in_directory (zfile, zuse, FALSE,
165				    FALSE, (const char *) NULL))
166	    fmatch = FALSE;
167	}
168      else
169	{
170	  zuse = zsysdep_local_file (*pz, zpubdir, (boolean *) NULL);
171	  if (zuse == NULL)
172	    return FALSE;
173
174	  if (fsysdep_in_directory (zfile, zuse, fcheck,
175				    freadable, zuser))
176	    fmatch = TRUE;
177	}
178
179      ubuffree (zuse);
180    }
181
182  return fmatch;
183}
184