1/* wldcrd.c
2   Expand wildcards.
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#include "uudefs.h"
28#include "sysdep.h"
29#include "system.h"
30
31#include <ctype.h>
32#include <errno.h>
33
34#if HAVE_GLOB && ! HAVE_GLOB_H
35#undef HAVE_GLOB
36#define HAVE_GLOB 0
37#endif
38
39#if HAVE_GLOB
40#include <glob.h>
41#endif
42
43/* Local variables to hold the wildcard in progress.  */
44
45#if HAVE_GLOB
46static glob_t sSglob;
47static unsigned int iSglob;
48#else
49static char *zSwildcard_alloc;
50static char *zSwildcard;
51#endif
52
53/* Start getting a wildcarded file spec.  Use the glob function if it
54   is available, and otherwise use the shell.  */
55
56boolean
57fsysdep_wildcard_start (zfile)
58     const char *zfile;
59{
60#if HAVE_GLOB
61
62#if DEBUG > 0
63  if (*zfile != '/')
64    ulog (LOG_FATAL, "fsysdep_wildcard: %s: Can't happen", zfile);
65#endif
66
67  if (glob (zfile, 0, (int (*) ()) NULL, &sSglob) != 0)
68    sSglob.gl_pathc = 0;
69  iSglob = 0;
70  return TRUE;
71
72#else /* ! HAVE_GLOB */
73
74  char *zcmd, *zto;
75  const char *zfrom;
76  size_t c;
77  const char *azargs[4];
78  FILE *e;
79  pid_t ipid;
80
81#if DEBUG > 0
82  if (*zfile != '/')
83    ulog (LOG_FATAL, "fsysdep_wildcard: %s: Can't happen", zfile);
84#endif
85
86  zSwildcard_alloc = NULL;
87  zSwildcard = NULL;
88
89  zcmd = zbufalc (sizeof ECHO_PROGRAM + sizeof " " + 2 * strlen (zfile));
90  memcpy (zcmd, ECHO_PROGRAM, sizeof ECHO_PROGRAM - 1);
91  zto = zcmd + sizeof ECHO_PROGRAM - 1;
92  *zto++ = ' ';
93  zfrom = zfile;
94  while (*zfrom != '\0')
95    {
96      /* To avoid shell trickery, we quote all characters except
97	 letters, digits, and wildcard specifiers.  We don't quote '/'
98	 to avoid an Ultrix sh bug.  */
99      if (! isalnum (*zfrom)
100	  && *zfrom != '*'
101	  && *zfrom != '?'
102	  && *zfrom != '['
103	  && *zfrom != ']'
104	  && *zfrom != '/')
105	*zto++ = '\\';
106      *zto++ = *zfrom++;
107    }
108  *zto = '\0';
109
110  azargs[0] = "/bin/sh";
111  azargs[1] = "-c";
112  azargs[2] = zcmd;
113  azargs[3] = NULL;
114
115  e = espopen (azargs, TRUE, &ipid);
116
117  ubuffree (zcmd);
118
119  if (e == NULL)
120    {
121      ulog (LOG_ERROR, "espopen: %s", strerror (errno));
122      return FALSE;
123    }
124
125  zSwildcard_alloc = NULL;
126  c = 0;
127  if (getline (&zSwildcard_alloc, &c, e) <= 0)
128    {
129      xfree ((pointer) zSwildcard_alloc);
130      zSwildcard_alloc = NULL;
131    }
132
133  if (ixswait ((unsigned long) ipid, ECHO_PROGRAM) != 0)
134    {
135      xfree ((pointer) zSwildcard_alloc);
136      return FALSE;
137    }
138
139  if (zSwildcard_alloc == NULL)
140    return FALSE;
141
142  DEBUG_MESSAGE1 (DEBUG_EXECUTE,
143		  "fsysdep_wildcard_start: got \"%s\"",
144		  zSwildcard_alloc);
145
146  zSwildcard = zSwildcard_alloc;
147
148  return TRUE;
149
150#endif /* ! HAVE_GLOB */
151}
152
153/* Get the next wildcard spec.  */
154
155/*ARGSUSED*/
156char *
157zsysdep_wildcard (zfile)
158     const char *zfile ATTRIBUTE_UNUSED;
159{
160#if HAVE_GLOB
161
162  char *zret;
163
164  if (iSglob >= sSglob.gl_pathc)
165    return NULL;
166  zret = zbufcpy (sSglob.gl_pathv[iSglob]);
167  ++iSglob;
168  return zret;
169
170#else /* ! HAVE_GLOB */
171
172  char *zret;
173
174  if (zSwildcard_alloc == NULL || zSwildcard == NULL)
175    return NULL;
176
177  zret = zSwildcard;
178
179  while (*zSwildcard != '\0' && ! isspace (BUCHAR (*zSwildcard)))
180    ++zSwildcard;
181
182  if (*zSwildcard != '\0')
183    {
184      *zSwildcard = '\0';
185      ++zSwildcard;
186      while (*zSwildcard != '\0' && isspace (BUCHAR (*zSwildcard)))
187	++zSwildcard;
188    }
189
190  if (*zSwildcard == '\0')
191    zSwildcard = NULL;
192
193  return zbufcpy (zret);
194
195#endif /* ! HAVE_GLOB */
196}
197
198/* Finish up getting wildcard specs.  */
199
200boolean
201fsysdep_wildcard_end ()
202{
203#if HAVE_GLOB
204  globfree (&sSglob);
205  return TRUE;
206#else /* ! HAVE_GLOB */
207  xfree ((pointer) zSwildcard_alloc);
208  zSwildcard_alloc = NULL;
209  zSwildcard = NULL;
210  return TRUE;
211#endif /* ! HAVE_GLOB */
212}
213