xref: /netbsd-src/external/gpl2/gmake/dist/misc.c (revision 69606e3f5c9388e52aed8c120ad63c049ca45d8f)
1*69606e3fSchristos /* Miscellaneous generic support functions for GNU Make.
2*69606e3fSchristos Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
3*69606e3fSchristos 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
4*69606e3fSchristos Foundation, Inc.
5*69606e3fSchristos This file is part of GNU Make.
6*69606e3fSchristos 
7*69606e3fSchristos GNU Make is free software; you can redistribute it and/or modify it under the
8*69606e3fSchristos terms of the GNU General Public License as published by the Free Software
9*69606e3fSchristos Foundation; either version 2, or (at your option) any later version.
10*69606e3fSchristos 
11*69606e3fSchristos GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
12*69606e3fSchristos WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13*69606e3fSchristos A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
14*69606e3fSchristos 
15*69606e3fSchristos You should have received a copy of the GNU General Public License along with
16*69606e3fSchristos GNU Make; see the file COPYING.  If not, write to the Free Software
17*69606e3fSchristos Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.  */
18*69606e3fSchristos 
19*69606e3fSchristos #include "make.h"
20*69606e3fSchristos #include "dep.h"
21*69606e3fSchristos #include "debug.h"
22*69606e3fSchristos 
23*69606e3fSchristos /* Variadic functions.  We go through contortions to allow proper function
24*69606e3fSchristos    prototypes for both ANSI and pre-ANSI C compilers, and also for those
25*69606e3fSchristos    which support stdarg.h vs. varargs.h, and finally those which have
26*69606e3fSchristos    vfprintf(), etc. and those who have _doprnt... or nothing.
27*69606e3fSchristos 
28*69606e3fSchristos    This fancy stuff all came from GNU fileutils, except for the VA_PRINTF and
29*69606e3fSchristos    VA_END macros used here since we have multiple print functions.  */
30*69606e3fSchristos 
31*69606e3fSchristos #if USE_VARIADIC
32*69606e3fSchristos # if HAVE_STDARG_H
33*69606e3fSchristos #  include <stdarg.h>
34*69606e3fSchristos #  define VA_START(args, lastarg) va_start(args, lastarg)
35*69606e3fSchristos # else
36*69606e3fSchristos #  include <varargs.h>
37*69606e3fSchristos #  define VA_START(args, lastarg) va_start(args)
38*69606e3fSchristos # endif
39*69606e3fSchristos # if HAVE_VPRINTF
40*69606e3fSchristos #  define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args))
41*69606e3fSchristos # else
42*69606e3fSchristos #  define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp))
43*69606e3fSchristos # endif
44*69606e3fSchristos # define VA_END(args) va_end(args)
45*69606e3fSchristos #else
46*69606e3fSchristos /* We can't use any variadic interface! */
47*69606e3fSchristos # define va_alist a1, a2, a3, a4, a5, a6, a7, a8
48*69606e3fSchristos # define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
49*69606e3fSchristos # define VA_START(args, lastarg)
50*69606e3fSchristos # define VA_PRINTF(fp, lastarg, args) fprintf((fp), (lastarg), va_alist)
51*69606e3fSchristos # define VA_END(args)
52*69606e3fSchristos #endif
53*69606e3fSchristos 
54*69606e3fSchristos 
55*69606e3fSchristos /* Compare strings *S1 and *S2.
56*69606e3fSchristos    Return negative if the first is less, positive if it is greater,
57*69606e3fSchristos    zero if they are equal.  */
58*69606e3fSchristos 
59*69606e3fSchristos int
alpha_compare(const void * v1,const void * v2)60*69606e3fSchristos alpha_compare (const void *v1, const void *v2)
61*69606e3fSchristos {
62*69606e3fSchristos   const char *s1 = *((char **)v1);
63*69606e3fSchristos   const char *s2 = *((char **)v2);
64*69606e3fSchristos 
65*69606e3fSchristos   if (*s1 != *s2)
66*69606e3fSchristos     return *s1 - *s2;
67*69606e3fSchristos   return strcmp (s1, s2);
68*69606e3fSchristos }
69*69606e3fSchristos 
70*69606e3fSchristos /* Discard each backslash-newline combination from LINE.
71*69606e3fSchristos    Backslash-backslash-newline combinations become backslash-newlines.
72*69606e3fSchristos    This is done by copying the text at LINE into itself.  */
73*69606e3fSchristos 
74*69606e3fSchristos void
collapse_continuations(char * line)75*69606e3fSchristos collapse_continuations (char *line)
76*69606e3fSchristos {
77*69606e3fSchristos   register char *in, *out, *p;
78*69606e3fSchristos   register int backslash;
79*69606e3fSchristos   register unsigned int bs_write;
80*69606e3fSchristos 
81*69606e3fSchristos   in = strchr (line, '\n');
82*69606e3fSchristos   if (in == 0)
83*69606e3fSchristos     return;
84*69606e3fSchristos 
85*69606e3fSchristos   out = in;
86*69606e3fSchristos   while (out > line && out[-1] == '\\')
87*69606e3fSchristos     --out;
88*69606e3fSchristos 
89*69606e3fSchristos   while (*in != '\0')
90*69606e3fSchristos     {
91*69606e3fSchristos       /* BS_WRITE gets the number of quoted backslashes at
92*69606e3fSchristos 	 the end just before IN, and BACKSLASH gets nonzero
93*69606e3fSchristos 	 if the next character is quoted.  */
94*69606e3fSchristos       backslash = 0;
95*69606e3fSchristos       bs_write = 0;
96*69606e3fSchristos       for (p = in - 1; p >= line && *p == '\\'; --p)
97*69606e3fSchristos 	{
98*69606e3fSchristos 	  if (backslash)
99*69606e3fSchristos 	    ++bs_write;
100*69606e3fSchristos 	  backslash = !backslash;
101*69606e3fSchristos 
102*69606e3fSchristos 	  /* It should be impossible to go back this far without exiting,
103*69606e3fSchristos 	     but if we do, we can't get the right answer.  */
104*69606e3fSchristos 	  if (in == out - 1)
105*69606e3fSchristos 	    abort ();
106*69606e3fSchristos 	}
107*69606e3fSchristos 
108*69606e3fSchristos       /* Output the appropriate number of backslashes.  */
109*69606e3fSchristos       while (bs_write-- > 0)
110*69606e3fSchristos 	*out++ = '\\';
111*69606e3fSchristos 
112*69606e3fSchristos       /* Skip the newline.  */
113*69606e3fSchristos       ++in;
114*69606e3fSchristos 
115*69606e3fSchristos       /* If the newline is quoted, discard following whitespace
116*69606e3fSchristos 	 and any preceding whitespace; leave just one space.  */
117*69606e3fSchristos       if (backslash)
118*69606e3fSchristos 	{
119*69606e3fSchristos 	  in = next_token (in);
120*69606e3fSchristos 	  while (out > line && isblank ((unsigned char)out[-1]))
121*69606e3fSchristos 	    --out;
122*69606e3fSchristos 	  *out++ = ' ';
123*69606e3fSchristos 	}
124*69606e3fSchristos       else
125*69606e3fSchristos 	/* If the newline isn't quoted, put it in the output.  */
126*69606e3fSchristos 	*out++ = '\n';
127*69606e3fSchristos 
128*69606e3fSchristos       /* Now copy the following line to the output.
129*69606e3fSchristos 	 Stop when we find backslashes followed by a newline.  */
130*69606e3fSchristos       while (*in != '\0')
131*69606e3fSchristos 	if (*in == '\\')
132*69606e3fSchristos 	  {
133*69606e3fSchristos 	    p = in + 1;
134*69606e3fSchristos 	    while (*p == '\\')
135*69606e3fSchristos 	      ++p;
136*69606e3fSchristos 	    if (*p == '\n')
137*69606e3fSchristos 	      {
138*69606e3fSchristos 		in = p;
139*69606e3fSchristos 		break;
140*69606e3fSchristos 	      }
141*69606e3fSchristos 	    while (in < p)
142*69606e3fSchristos 	      *out++ = *in++;
143*69606e3fSchristos 	  }
144*69606e3fSchristos 	else
145*69606e3fSchristos 	  *out++ = *in++;
146*69606e3fSchristos     }
147*69606e3fSchristos 
148*69606e3fSchristos   *out = '\0';
149*69606e3fSchristos }
150*69606e3fSchristos 
151*69606e3fSchristos /* Print N spaces (used in debug for target-depth).  */
152*69606e3fSchristos 
153*69606e3fSchristos void
print_spaces(unsigned int n)154*69606e3fSchristos print_spaces (unsigned int n)
155*69606e3fSchristos {
156*69606e3fSchristos   while (n-- > 0)
157*69606e3fSchristos     putchar (' ');
158*69606e3fSchristos }
159*69606e3fSchristos 
160*69606e3fSchristos 
161*69606e3fSchristos /* Return a newly-allocated string whose contents
162*69606e3fSchristos    concatenate those of s1, s2, s3.  */
163*69606e3fSchristos 
164*69606e3fSchristos char *
concat(const char * s1,const char * s2,const char * s3)165*69606e3fSchristos concat (const char *s1, const char *s2, const char *s3)
166*69606e3fSchristos {
167*69606e3fSchristos   unsigned int len1, len2, len3;
168*69606e3fSchristos   char *result;
169*69606e3fSchristos 
170*69606e3fSchristos   len1 = *s1 != '\0' ? strlen (s1) : 0;
171*69606e3fSchristos   len2 = *s2 != '\0' ? strlen (s2) : 0;
172*69606e3fSchristos   len3 = *s3 != '\0' ? strlen (s3) : 0;
173*69606e3fSchristos 
174*69606e3fSchristos   result = (char *) xmalloc (len1 + len2 + len3 + 1);
175*69606e3fSchristos 
176*69606e3fSchristos   if (*s1 != '\0')
177*69606e3fSchristos     bcopy (s1, result, len1);
178*69606e3fSchristos   if (*s2 != '\0')
179*69606e3fSchristos     bcopy (s2, result + len1, len2);
180*69606e3fSchristos   if (*s3 != '\0')
181*69606e3fSchristos     bcopy (s3, result + len1 + len2, len3);
182*69606e3fSchristos   *(result + len1 + len2 + len3) = '\0';
183*69606e3fSchristos 
184*69606e3fSchristos   return result;
185*69606e3fSchristos }
186*69606e3fSchristos 
187*69606e3fSchristos /* Print a message on stdout.  */
188*69606e3fSchristos 
189*69606e3fSchristos void
190*69606e3fSchristos #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
message(int prefix,const char * fmt,...)191*69606e3fSchristos message (int prefix, const char *fmt, ...)
192*69606e3fSchristos #else
193*69606e3fSchristos message (prefix, fmt, va_alist)
194*69606e3fSchristos      int prefix;
195*69606e3fSchristos      const char *fmt;
196*69606e3fSchristos      va_dcl
197*69606e3fSchristos #endif
198*69606e3fSchristos {
199*69606e3fSchristos #if USE_VARIADIC
200*69606e3fSchristos   va_list args;
201*69606e3fSchristos #endif
202*69606e3fSchristos 
203*69606e3fSchristos   log_working_directory (1);
204*69606e3fSchristos 
205*69606e3fSchristos   if (fmt != 0)
206*69606e3fSchristos     {
207*69606e3fSchristos       if (prefix)
208*69606e3fSchristos 	{
209*69606e3fSchristos 	  if (makelevel == 0)
210*69606e3fSchristos 	    printf ("%s: ", program);
211*69606e3fSchristos 	  else
212*69606e3fSchristos 	    printf ("%s[%u]: ", program, makelevel);
213*69606e3fSchristos 	}
214*69606e3fSchristos       VA_START (args, fmt);
215*69606e3fSchristos       VA_PRINTF (stdout, fmt, args);
216*69606e3fSchristos       VA_END (args);
217*69606e3fSchristos       putchar ('\n');
218*69606e3fSchristos     }
219*69606e3fSchristos 
220*69606e3fSchristos   fflush (stdout);
221*69606e3fSchristos }
222*69606e3fSchristos 
223*69606e3fSchristos /* Print an error message.  */
224*69606e3fSchristos 
225*69606e3fSchristos void
226*69606e3fSchristos #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
error(const struct floc * flocp,const char * fmt,...)227*69606e3fSchristos error (const struct floc *flocp, const char *fmt, ...)
228*69606e3fSchristos #else
229*69606e3fSchristos error (flocp, fmt, va_alist)
230*69606e3fSchristos      const struct floc *flocp;
231*69606e3fSchristos      const char *fmt;
232*69606e3fSchristos      va_dcl
233*69606e3fSchristos #endif
234*69606e3fSchristos {
235*69606e3fSchristos #if USE_VARIADIC
236*69606e3fSchristos   va_list args;
237*69606e3fSchristos #endif
238*69606e3fSchristos 
239*69606e3fSchristos   log_working_directory (1);
240*69606e3fSchristos 
241*69606e3fSchristos   if (flocp && flocp->filenm)
242*69606e3fSchristos     fprintf (stderr, "%s:%lu: ", flocp->filenm, flocp->lineno);
243*69606e3fSchristos   else if (makelevel == 0)
244*69606e3fSchristos     fprintf (stderr, "%s: ", program);
245*69606e3fSchristos   else
246*69606e3fSchristos     fprintf (stderr, "%s[%u]: ", program, makelevel);
247*69606e3fSchristos 
248*69606e3fSchristos   VA_START(args, fmt);
249*69606e3fSchristos   VA_PRINTF (stderr, fmt, args);
250*69606e3fSchristos   VA_END (args);
251*69606e3fSchristos 
252*69606e3fSchristos   putc ('\n', stderr);
253*69606e3fSchristos   fflush (stderr);
254*69606e3fSchristos }
255*69606e3fSchristos 
256*69606e3fSchristos /* Print an error message and exit.  */
257*69606e3fSchristos 
258*69606e3fSchristos void
259*69606e3fSchristos #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
fatal(const struct floc * flocp,const char * fmt,...)260*69606e3fSchristos fatal (const struct floc *flocp, const char *fmt, ...)
261*69606e3fSchristos #else
262*69606e3fSchristos fatal (flocp, fmt, va_alist)
263*69606e3fSchristos      const struct floc *flocp;
264*69606e3fSchristos      const char *fmt;
265*69606e3fSchristos      va_dcl
266*69606e3fSchristos #endif
267*69606e3fSchristos {
268*69606e3fSchristos #if USE_VARIADIC
269*69606e3fSchristos   va_list args;
270*69606e3fSchristos #endif
271*69606e3fSchristos 
272*69606e3fSchristos   log_working_directory (1);
273*69606e3fSchristos 
274*69606e3fSchristos   if (flocp && flocp->filenm)
275*69606e3fSchristos     fprintf (stderr, "%s:%lu: *** ", flocp->filenm, flocp->lineno);
276*69606e3fSchristos   else if (makelevel == 0)
277*69606e3fSchristos     fprintf (stderr, "%s: *** ", program);
278*69606e3fSchristos   else
279*69606e3fSchristos     fprintf (stderr, "%s[%u]: *** ", program, makelevel);
280*69606e3fSchristos 
281*69606e3fSchristos   VA_START(args, fmt);
282*69606e3fSchristos   VA_PRINTF (stderr, fmt, args);
283*69606e3fSchristos   VA_END (args);
284*69606e3fSchristos 
285*69606e3fSchristos   fputs (_(".  Stop.\n"), stderr);
286*69606e3fSchristos 
287*69606e3fSchristos   die (2);
288*69606e3fSchristos }
289*69606e3fSchristos 
290*69606e3fSchristos #ifndef HAVE_STRERROR
291*69606e3fSchristos 
292*69606e3fSchristos #undef	strerror
293*69606e3fSchristos 
294*69606e3fSchristos char *
strerror(int errnum)295*69606e3fSchristos strerror (int errnum)
296*69606e3fSchristos {
297*69606e3fSchristos   extern int errno, sys_nerr;
298*69606e3fSchristos #ifndef __DECC
299*69606e3fSchristos   extern char *sys_errlist[];
300*69606e3fSchristos #endif
301*69606e3fSchristos   static char buf[] = "Unknown error 12345678901234567890";
302*69606e3fSchristos 
303*69606e3fSchristos   if (errno < sys_nerr)
304*69606e3fSchristos     return sys_errlist[errnum];
305*69606e3fSchristos 
306*69606e3fSchristos   sprintf (buf, _("Unknown error %d"), errnum);
307*69606e3fSchristos   return buf;
308*69606e3fSchristos }
309*69606e3fSchristos #endif
310*69606e3fSchristos 
311*69606e3fSchristos /* Print an error message from errno.  */
312*69606e3fSchristos 
313*69606e3fSchristos void
perror_with_name(const char * str,const char * name)314*69606e3fSchristos perror_with_name (const char *str, const char *name)
315*69606e3fSchristos {
316*69606e3fSchristos   error (NILF, _("%s%s: %s"), str, name, strerror (errno));
317*69606e3fSchristos }
318*69606e3fSchristos 
319*69606e3fSchristos /* Print an error message from errno and exit.  */
320*69606e3fSchristos 
321*69606e3fSchristos void
pfatal_with_name(const char * name)322*69606e3fSchristos pfatal_with_name (const char *name)
323*69606e3fSchristos {
324*69606e3fSchristos   fatal (NILF, _("%s: %s"), name, strerror (errno));
325*69606e3fSchristos 
326*69606e3fSchristos   /* NOTREACHED */
327*69606e3fSchristos }
328*69606e3fSchristos 
329*69606e3fSchristos /* Like malloc but get fatal error if memory is exhausted.  */
330*69606e3fSchristos /* Don't bother if we're using dmalloc; it provides these for us.  */
331*69606e3fSchristos 
332*69606e3fSchristos #ifndef HAVE_DMALLOC_H
333*69606e3fSchristos 
334*69606e3fSchristos #undef xmalloc
335*69606e3fSchristos #undef xrealloc
336*69606e3fSchristos #undef xstrdup
337*69606e3fSchristos 
338*69606e3fSchristos char *
xmalloc(unsigned int size)339*69606e3fSchristos xmalloc (unsigned int size)
340*69606e3fSchristos {
341*69606e3fSchristos   /* Make sure we don't allocate 0, for pre-ANSI libraries.  */
342*69606e3fSchristos   char *result = (char *) malloc (size ? size : 1);
343*69606e3fSchristos   if (result == 0)
344*69606e3fSchristos     fatal (NILF, _("virtual memory exhausted"));
345*69606e3fSchristos   return result;
346*69606e3fSchristos }
347*69606e3fSchristos 
348*69606e3fSchristos 
349*69606e3fSchristos char *
xrealloc(char * ptr,unsigned int size)350*69606e3fSchristos xrealloc (char *ptr, unsigned int size)
351*69606e3fSchristos {
352*69606e3fSchristos   char *result;
353*69606e3fSchristos 
354*69606e3fSchristos   /* Some older implementations of realloc() don't conform to ANSI.  */
355*69606e3fSchristos   if (! size)
356*69606e3fSchristos     size = 1;
357*69606e3fSchristos   result = ptr ? realloc (ptr, size) : malloc (size);
358*69606e3fSchristos   if (result == 0)
359*69606e3fSchristos     fatal (NILF, _("virtual memory exhausted"));
360*69606e3fSchristos   return result;
361*69606e3fSchristos }
362*69606e3fSchristos 
363*69606e3fSchristos 
364*69606e3fSchristos char *
xstrdup(const char * ptr)365*69606e3fSchristos xstrdup (const char *ptr)
366*69606e3fSchristos {
367*69606e3fSchristos   char *result;
368*69606e3fSchristos 
369*69606e3fSchristos #ifdef HAVE_STRDUP
370*69606e3fSchristos   result = strdup (ptr);
371*69606e3fSchristos #else
372*69606e3fSchristos   result = (char *) malloc (strlen (ptr) + 1);
373*69606e3fSchristos #endif
374*69606e3fSchristos 
375*69606e3fSchristos   if (result == 0)
376*69606e3fSchristos     fatal (NILF, _("virtual memory exhausted"));
377*69606e3fSchristos 
378*69606e3fSchristos #ifdef HAVE_STRDUP
379*69606e3fSchristos   return result;
380*69606e3fSchristos #else
381*69606e3fSchristos   return strcpy(result, ptr);
382*69606e3fSchristos #endif
383*69606e3fSchristos }
384*69606e3fSchristos 
385*69606e3fSchristos #endif  /* HAVE_DMALLOC_H */
386*69606e3fSchristos 
387*69606e3fSchristos char *
savestring(const char * str,unsigned int length)388*69606e3fSchristos savestring (const char *str, unsigned int length)
389*69606e3fSchristos {
390*69606e3fSchristos   register char *out = (char *) xmalloc (length + 1);
391*69606e3fSchristos   if (length > 0)
392*69606e3fSchristos     bcopy (str, out, length);
393*69606e3fSchristos   out[length] = '\0';
394*69606e3fSchristos   return out;
395*69606e3fSchristos }
396*69606e3fSchristos 
397*69606e3fSchristos 
398*69606e3fSchristos /* Limited INDEX:
399*69606e3fSchristos    Search through the string STRING, which ends at LIMIT, for the character C.
400*69606e3fSchristos    Returns a pointer to the first occurrence, or nil if none is found.
401*69606e3fSchristos    Like INDEX except that the string searched ends where specified
402*69606e3fSchristos    instead of at the first null.  */
403*69606e3fSchristos 
404*69606e3fSchristos char *
lindex(const char * s,const char * limit,int c)405*69606e3fSchristos lindex (const char *s, const char *limit, int c)
406*69606e3fSchristos {
407*69606e3fSchristos   while (s < limit)
408*69606e3fSchristos     if (*s++ == c)
409*69606e3fSchristos       return (char *)(s - 1);
410*69606e3fSchristos 
411*69606e3fSchristos   return 0;
412*69606e3fSchristos }
413*69606e3fSchristos 
414*69606e3fSchristos /* Return the address of the first whitespace or null in the string S.  */
415*69606e3fSchristos 
416*69606e3fSchristos char *
end_of_token(const char * s)417*69606e3fSchristos end_of_token (const char *s)
418*69606e3fSchristos {
419*69606e3fSchristos   while (*s != '\0' && !isblank ((unsigned char)*s))
420*69606e3fSchristos     ++s;
421*69606e3fSchristos   return (char *)s;
422*69606e3fSchristos }
423*69606e3fSchristos 
424*69606e3fSchristos #ifdef WINDOWS32
425*69606e3fSchristos /*
426*69606e3fSchristos  * Same as end_of_token, but take into account a stop character
427*69606e3fSchristos  */
428*69606e3fSchristos char *
end_of_token_w32(char * s,char stopchar)429*69606e3fSchristos end_of_token_w32 (char *s, char stopchar)
430*69606e3fSchristos {
431*69606e3fSchristos   register char *p = s;
432*69606e3fSchristos   register int backslash = 0;
433*69606e3fSchristos 
434*69606e3fSchristos   while (*p != '\0' && *p != stopchar
435*69606e3fSchristos 	 && (backslash || !isblank ((unsigned char)*p)))
436*69606e3fSchristos     {
437*69606e3fSchristos       if (*p++ == '\\')
438*69606e3fSchristos         {
439*69606e3fSchristos           backslash = !backslash;
440*69606e3fSchristos           while (*p == '\\')
441*69606e3fSchristos             {
442*69606e3fSchristos               backslash = !backslash;
443*69606e3fSchristos               ++p;
444*69606e3fSchristos             }
445*69606e3fSchristos         }
446*69606e3fSchristos       else
447*69606e3fSchristos         backslash = 0;
448*69606e3fSchristos     }
449*69606e3fSchristos 
450*69606e3fSchristos   return p;
451*69606e3fSchristos }
452*69606e3fSchristos #endif
453*69606e3fSchristos 
454*69606e3fSchristos /* Return the address of the first nonwhitespace or null in the string S.  */
455*69606e3fSchristos 
456*69606e3fSchristos char *
next_token(const char * s)457*69606e3fSchristos next_token (const char *s)
458*69606e3fSchristos {
459*69606e3fSchristos   while (isblank ((unsigned char)*s))
460*69606e3fSchristos     ++s;
461*69606e3fSchristos   return (char *)s;
462*69606e3fSchristos }
463*69606e3fSchristos 
464*69606e3fSchristos /* Find the next token in PTR; return the address of it, and store the
465*69606e3fSchristos    length of the token into *LENGTHPTR if LENGTHPTR is not nil.  */
466*69606e3fSchristos 
467*69606e3fSchristos char *
find_next_token(char ** ptr,unsigned int * lengthptr)468*69606e3fSchristos find_next_token (char **ptr, unsigned int *lengthptr)
469*69606e3fSchristos {
470*69606e3fSchristos   char *p = next_token (*ptr);
471*69606e3fSchristos   char *end;
472*69606e3fSchristos 
473*69606e3fSchristos   if (*p == '\0')
474*69606e3fSchristos     return 0;
475*69606e3fSchristos 
476*69606e3fSchristos   *ptr = end = end_of_token (p);
477*69606e3fSchristos   if (lengthptr != 0)
478*69606e3fSchristos     *lengthptr = end - p;
479*69606e3fSchristos   return p;
480*69606e3fSchristos }
481*69606e3fSchristos 
482*69606e3fSchristos 
483*69606e3fSchristos /* Allocate a new `struct dep' with all fields initialized to 0.   */
484*69606e3fSchristos 
485*69606e3fSchristos struct dep *
alloc_dep()486*69606e3fSchristos alloc_dep ()
487*69606e3fSchristos {
488*69606e3fSchristos   struct dep *d = (struct dep *) xmalloc (sizeof (struct dep));
489*69606e3fSchristos   bzero ((char *) d, sizeof (struct dep));
490*69606e3fSchristos   return d;
491*69606e3fSchristos }
492*69606e3fSchristos 
493*69606e3fSchristos 
494*69606e3fSchristos /* Free `struct dep' along with `name' and `stem'.   */
495*69606e3fSchristos 
496*69606e3fSchristos void
free_dep(struct dep * d)497*69606e3fSchristos free_dep (struct dep *d)
498*69606e3fSchristos {
499*69606e3fSchristos   if (d->name != 0)
500*69606e3fSchristos     free (d->name);
501*69606e3fSchristos 
502*69606e3fSchristos   if (d->stem != 0)
503*69606e3fSchristos     free (d->stem);
504*69606e3fSchristos 
505*69606e3fSchristos   free ((char *)d);
506*69606e3fSchristos }
507*69606e3fSchristos 
508*69606e3fSchristos /* Copy a chain of `struct dep', making a new chain
509*69606e3fSchristos    with the same contents as the old one.  */
510*69606e3fSchristos 
511*69606e3fSchristos struct dep *
copy_dep_chain(const struct dep * d)512*69606e3fSchristos copy_dep_chain (const struct dep *d)
513*69606e3fSchristos {
514*69606e3fSchristos   register struct dep *c;
515*69606e3fSchristos   struct dep *firstnew = 0;
516*69606e3fSchristos   struct dep *lastnew = 0;
517*69606e3fSchristos 
518*69606e3fSchristos   while (d != 0)
519*69606e3fSchristos     {
520*69606e3fSchristos       c = (struct dep *) xmalloc (sizeof (struct dep));
521*69606e3fSchristos       bcopy ((char *) d, (char *) c, sizeof (struct dep));
522*69606e3fSchristos 
523*69606e3fSchristos       if (c->name != 0)
524*69606e3fSchristos 	c->name = xstrdup (c->name);
525*69606e3fSchristos       if (c->stem != 0)
526*69606e3fSchristos 	c->stem = xstrdup (c->stem);
527*69606e3fSchristos 
528*69606e3fSchristos       c->next = 0;
529*69606e3fSchristos       if (firstnew == 0)
530*69606e3fSchristos 	firstnew = lastnew = c;
531*69606e3fSchristos       else
532*69606e3fSchristos 	lastnew = lastnew->next = c;
533*69606e3fSchristos 
534*69606e3fSchristos       d = d->next;
535*69606e3fSchristos     }
536*69606e3fSchristos 
537*69606e3fSchristos   return firstnew;
538*69606e3fSchristos }
539*69606e3fSchristos 
540*69606e3fSchristos /* Free a chain of 'struct dep'.  */
541*69606e3fSchristos 
542*69606e3fSchristos void
free_dep_chain(struct dep * d)543*69606e3fSchristos free_dep_chain (struct dep *d)
544*69606e3fSchristos {
545*69606e3fSchristos   while (d != 0)
546*69606e3fSchristos     {
547*69606e3fSchristos       struct dep *df = d;
548*69606e3fSchristos       d = d->next;
549*69606e3fSchristos       free_dep (df);
550*69606e3fSchristos     }
551*69606e3fSchristos }
552*69606e3fSchristos 
553*69606e3fSchristos /* Free a chain of `struct nameseq'. Each nameseq->name is freed
554*69606e3fSchristos    as well.  For `struct dep' chains use free_dep_chain.  */
555*69606e3fSchristos 
556*69606e3fSchristos void
free_ns_chain(struct nameseq * n)557*69606e3fSchristos free_ns_chain (struct nameseq *n)
558*69606e3fSchristos {
559*69606e3fSchristos   register struct nameseq *tmp;
560*69606e3fSchristos 
561*69606e3fSchristos   while (n != 0)
562*69606e3fSchristos   {
563*69606e3fSchristos     if (n->name != 0)
564*69606e3fSchristos       free (n->name);
565*69606e3fSchristos 
566*69606e3fSchristos     tmp = n;
567*69606e3fSchristos 
568*69606e3fSchristos     n = n->next;
569*69606e3fSchristos 
570*69606e3fSchristos     free (tmp);
571*69606e3fSchristos   }
572*69606e3fSchristos 
573*69606e3fSchristos }
574*69606e3fSchristos #ifdef	iAPX286
575*69606e3fSchristos /* The losing compiler on this machine can't handle this macro.  */
576*69606e3fSchristos 
577*69606e3fSchristos char *
dep_name(struct dep * dep)578*69606e3fSchristos dep_name (struct dep *dep)
579*69606e3fSchristos {
580*69606e3fSchristos   return dep->name == 0 ? dep->file->name : dep->name;
581*69606e3fSchristos }
582*69606e3fSchristos #endif
583*69606e3fSchristos 
584*69606e3fSchristos #ifdef	GETLOADAVG_PRIVILEGED
585*69606e3fSchristos 
586*69606e3fSchristos #ifdef POSIX
587*69606e3fSchristos 
588*69606e3fSchristos /* Hopefully if a system says it's POSIX.1 and has the setuid and setgid
589*69606e3fSchristos    functions, they work as POSIX.1 says.  Some systems (Alpha OSF/1 1.2,
590*69606e3fSchristos    for example) which claim to be POSIX.1 also have the BSD setreuid and
591*69606e3fSchristos    setregid functions, but they don't work as in BSD and only the POSIX.1
592*69606e3fSchristos    way works.  */
593*69606e3fSchristos 
594*69606e3fSchristos #undef HAVE_SETREUID
595*69606e3fSchristos #undef HAVE_SETREGID
596*69606e3fSchristos 
597*69606e3fSchristos #else	/* Not POSIX.  */
598*69606e3fSchristos 
599*69606e3fSchristos /* Some POSIX.1 systems have the seteuid and setegid functions.  In a
600*69606e3fSchristos    POSIX-like system, they are the best thing to use.  However, some
601*69606e3fSchristos    non-POSIX systems have them too but they do not work in the POSIX style
602*69606e3fSchristos    and we must use setreuid and setregid instead.  */
603*69606e3fSchristos 
604*69606e3fSchristos #undef HAVE_SETEUID
605*69606e3fSchristos #undef HAVE_SETEGID
606*69606e3fSchristos 
607*69606e3fSchristos #endif	/* POSIX.  */
608*69606e3fSchristos 
609*69606e3fSchristos #ifndef	HAVE_UNISTD_H
610*69606e3fSchristos extern int getuid (), getgid (), geteuid (), getegid ();
611*69606e3fSchristos extern int setuid (), setgid ();
612*69606e3fSchristos #ifdef HAVE_SETEUID
613*69606e3fSchristos extern int seteuid ();
614*69606e3fSchristos #else
615*69606e3fSchristos #ifdef	HAVE_SETREUID
616*69606e3fSchristos extern int setreuid ();
617*69606e3fSchristos #endif	/* Have setreuid.  */
618*69606e3fSchristos #endif	/* Have seteuid.  */
619*69606e3fSchristos #ifdef HAVE_SETEGID
620*69606e3fSchristos extern int setegid ();
621*69606e3fSchristos #else
622*69606e3fSchristos #ifdef	HAVE_SETREGID
623*69606e3fSchristos extern int setregid ();
624*69606e3fSchristos #endif	/* Have setregid.  */
625*69606e3fSchristos #endif	/* Have setegid.  */
626*69606e3fSchristos #endif	/* No <unistd.h>.  */
627*69606e3fSchristos 
628*69606e3fSchristos /* Keep track of the user and group IDs for user- and make- access.  */
629*69606e3fSchristos static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1;
630*69606e3fSchristos #define	access_inited	(user_uid != -1)
631*69606e3fSchristos static enum { make, user } current_access;
632*69606e3fSchristos 
633*69606e3fSchristos 
634*69606e3fSchristos /* Under -d, write a message describing the current IDs.  */
635*69606e3fSchristos 
636*69606e3fSchristos static void
log_access(const char * flavor)637*69606e3fSchristos log_access (const char *flavor)
638*69606e3fSchristos {
639*69606e3fSchristos   if (! ISDB (DB_JOBS))
640*69606e3fSchristos     return;
641*69606e3fSchristos 
642*69606e3fSchristos   /* All the other debugging messages go to stdout,
643*69606e3fSchristos      but we write this one to stderr because it might be
644*69606e3fSchristos      run in a child fork whose stdout is piped.  */
645*69606e3fSchristos 
646*69606e3fSchristos   fprintf (stderr, _("%s: user %lu (real %lu), group %lu (real %lu)\n"),
647*69606e3fSchristos 	   flavor, (unsigned long) geteuid (), (unsigned long) getuid (),
648*69606e3fSchristos            (unsigned long) getegid (), (unsigned long) getgid ());
649*69606e3fSchristos   fflush (stderr);
650*69606e3fSchristos }
651*69606e3fSchristos 
652*69606e3fSchristos 
653*69606e3fSchristos static void
init_access(void)654*69606e3fSchristos init_access (void)
655*69606e3fSchristos {
656*69606e3fSchristos #ifndef VMS
657*69606e3fSchristos   user_uid = getuid ();
658*69606e3fSchristos   user_gid = getgid ();
659*69606e3fSchristos 
660*69606e3fSchristos   make_uid = geteuid ();
661*69606e3fSchristos   make_gid = getegid ();
662*69606e3fSchristos 
663*69606e3fSchristos   /* Do these ever fail?  */
664*69606e3fSchristos   if (user_uid == -1 || user_gid == -1 || make_uid == -1 || make_gid == -1)
665*69606e3fSchristos     pfatal_with_name ("get{e}[gu]id");
666*69606e3fSchristos 
667*69606e3fSchristos   log_access (_("Initialized access"));
668*69606e3fSchristos 
669*69606e3fSchristos   current_access = make;
670*69606e3fSchristos #endif
671*69606e3fSchristos }
672*69606e3fSchristos 
673*69606e3fSchristos #endif	/* GETLOADAVG_PRIVILEGED */
674*69606e3fSchristos 
675*69606e3fSchristos /* Give the process appropriate permissions for access to
676*69606e3fSchristos    user data (i.e., to stat files, or to spawn a child process).  */
677*69606e3fSchristos void
user_access(void)678*69606e3fSchristos user_access (void)
679*69606e3fSchristos {
680*69606e3fSchristos #ifdef	GETLOADAVG_PRIVILEGED
681*69606e3fSchristos 
682*69606e3fSchristos   if (!access_inited)
683*69606e3fSchristos     init_access ();
684*69606e3fSchristos 
685*69606e3fSchristos   if (current_access == user)
686*69606e3fSchristos     return;
687*69606e3fSchristos 
688*69606e3fSchristos   /* We are in "make access" mode.  This means that the effective user and
689*69606e3fSchristos      group IDs are those of make (if it was installed setuid or setgid).
690*69606e3fSchristos      We now want to set the effective user and group IDs to the real IDs,
691*69606e3fSchristos      which are the IDs of the process that exec'd make.  */
692*69606e3fSchristos 
693*69606e3fSchristos #ifdef	HAVE_SETEUID
694*69606e3fSchristos 
695*69606e3fSchristos   /* Modern systems have the seteuid/setegid calls which set only the
696*69606e3fSchristos      effective IDs, which is ideal.  */
697*69606e3fSchristos 
698*69606e3fSchristos   if (seteuid (user_uid) < 0)
699*69606e3fSchristos     pfatal_with_name ("user_access: seteuid");
700*69606e3fSchristos 
701*69606e3fSchristos #else	/* Not HAVE_SETEUID.  */
702*69606e3fSchristos 
703*69606e3fSchristos #ifndef	HAVE_SETREUID
704*69606e3fSchristos 
705*69606e3fSchristos   /* System V has only the setuid/setgid calls to set user/group IDs.
706*69606e3fSchristos      There is an effective ID, which can be set by setuid/setgid.
707*69606e3fSchristos      It can be set (unless you are root) only to either what it already is
708*69606e3fSchristos      (returned by geteuid/getegid, now in make_uid/make_gid),
709*69606e3fSchristos      the real ID (return by getuid/getgid, now in user_uid/user_gid),
710*69606e3fSchristos      or the saved set ID (what the effective ID was before this set-ID
711*69606e3fSchristos      executable (make) was exec'd).  */
712*69606e3fSchristos 
713*69606e3fSchristos   if (setuid (user_uid) < 0)
714*69606e3fSchristos     pfatal_with_name ("user_access: setuid");
715*69606e3fSchristos 
716*69606e3fSchristos #else	/* HAVE_SETREUID.  */
717*69606e3fSchristos 
718*69606e3fSchristos   /* In 4BSD, the setreuid/setregid calls set both the real and effective IDs.
719*69606e3fSchristos      They may be set to themselves or each other.  So you have two alternatives
720*69606e3fSchristos      at any one time.  If you use setuid/setgid, the effective will be set to
721*69606e3fSchristos      the real, leaving only one alternative.  Using setreuid/setregid, however,
722*69606e3fSchristos      you can toggle between your two alternatives by swapping the values in a
723*69606e3fSchristos      single setreuid or setregid call.  */
724*69606e3fSchristos 
725*69606e3fSchristos   if (setreuid (make_uid, user_uid) < 0)
726*69606e3fSchristos     pfatal_with_name ("user_access: setreuid");
727*69606e3fSchristos 
728*69606e3fSchristos #endif	/* Not HAVE_SETREUID.  */
729*69606e3fSchristos #endif	/* HAVE_SETEUID.  */
730*69606e3fSchristos 
731*69606e3fSchristos #ifdef	HAVE_SETEGID
732*69606e3fSchristos   if (setegid (user_gid) < 0)
733*69606e3fSchristos     pfatal_with_name ("user_access: setegid");
734*69606e3fSchristos #else
735*69606e3fSchristos #ifndef	HAVE_SETREGID
736*69606e3fSchristos   if (setgid (user_gid) < 0)
737*69606e3fSchristos     pfatal_with_name ("user_access: setgid");
738*69606e3fSchristos #else
739*69606e3fSchristos   if (setregid (make_gid, user_gid) < 0)
740*69606e3fSchristos     pfatal_with_name ("user_access: setregid");
741*69606e3fSchristos #endif
742*69606e3fSchristos #endif
743*69606e3fSchristos 
744*69606e3fSchristos   current_access = user;
745*69606e3fSchristos 
746*69606e3fSchristos   log_access (_("User access"));
747*69606e3fSchristos 
748*69606e3fSchristos #endif	/* GETLOADAVG_PRIVILEGED */
749*69606e3fSchristos }
750*69606e3fSchristos 
751*69606e3fSchristos /* Give the process appropriate permissions for access to
752*69606e3fSchristos    make data (i.e., the load average).  */
753*69606e3fSchristos void
make_access(void)754*69606e3fSchristos make_access (void)
755*69606e3fSchristos {
756*69606e3fSchristos #ifdef	GETLOADAVG_PRIVILEGED
757*69606e3fSchristos 
758*69606e3fSchristos   if (!access_inited)
759*69606e3fSchristos     init_access ();
760*69606e3fSchristos 
761*69606e3fSchristos   if (current_access == make)
762*69606e3fSchristos     return;
763*69606e3fSchristos 
764*69606e3fSchristos   /* See comments in user_access, above.  */
765*69606e3fSchristos 
766*69606e3fSchristos #ifdef	HAVE_SETEUID
767*69606e3fSchristos   if (seteuid (make_uid) < 0)
768*69606e3fSchristos     pfatal_with_name ("make_access: seteuid");
769*69606e3fSchristos #else
770*69606e3fSchristos #ifndef	HAVE_SETREUID
771*69606e3fSchristos   if (setuid (make_uid) < 0)
772*69606e3fSchristos     pfatal_with_name ("make_access: setuid");
773*69606e3fSchristos #else
774*69606e3fSchristos   if (setreuid (user_uid, make_uid) < 0)
775*69606e3fSchristos     pfatal_with_name ("make_access: setreuid");
776*69606e3fSchristos #endif
777*69606e3fSchristos #endif
778*69606e3fSchristos 
779*69606e3fSchristos #ifdef	HAVE_SETEGID
780*69606e3fSchristos   if (setegid (make_gid) < 0)
781*69606e3fSchristos     pfatal_with_name ("make_access: setegid");
782*69606e3fSchristos #else
783*69606e3fSchristos #ifndef	HAVE_SETREGID
784*69606e3fSchristos   if (setgid (make_gid) < 0)
785*69606e3fSchristos     pfatal_with_name ("make_access: setgid");
786*69606e3fSchristos #else
787*69606e3fSchristos   if (setregid (user_gid, make_gid) < 0)
788*69606e3fSchristos     pfatal_with_name ("make_access: setregid");
789*69606e3fSchristos #endif
790*69606e3fSchristos #endif
791*69606e3fSchristos 
792*69606e3fSchristos   current_access = make;
793*69606e3fSchristos 
794*69606e3fSchristos   log_access (_("Make access"));
795*69606e3fSchristos 
796*69606e3fSchristos #endif	/* GETLOADAVG_PRIVILEGED */
797*69606e3fSchristos }
798*69606e3fSchristos 
799*69606e3fSchristos /* Give the process appropriate permissions for a child process.
800*69606e3fSchristos    This is like user_access, but you can't get back to make_access.  */
801*69606e3fSchristos void
child_access(void)802*69606e3fSchristos child_access (void)
803*69606e3fSchristos {
804*69606e3fSchristos #ifdef	GETLOADAVG_PRIVILEGED
805*69606e3fSchristos 
806*69606e3fSchristos   if (!access_inited)
807*69606e3fSchristos     abort ();
808*69606e3fSchristos 
809*69606e3fSchristos   /* Set both the real and effective UID and GID to the user's.
810*69606e3fSchristos      They cannot be changed back to make's.  */
811*69606e3fSchristos 
812*69606e3fSchristos #ifndef	HAVE_SETREUID
813*69606e3fSchristos   if (setuid (user_uid) < 0)
814*69606e3fSchristos     pfatal_with_name ("child_access: setuid");
815*69606e3fSchristos #else
816*69606e3fSchristos   if (setreuid (user_uid, user_uid) < 0)
817*69606e3fSchristos     pfatal_with_name ("child_access: setreuid");
818*69606e3fSchristos #endif
819*69606e3fSchristos 
820*69606e3fSchristos #ifndef	HAVE_SETREGID
821*69606e3fSchristos   if (setgid (user_gid) < 0)
822*69606e3fSchristos     pfatal_with_name ("child_access: setgid");
823*69606e3fSchristos #else
824*69606e3fSchristos   if (setregid (user_gid, user_gid) < 0)
825*69606e3fSchristos     pfatal_with_name ("child_access: setregid");
826*69606e3fSchristos #endif
827*69606e3fSchristos 
828*69606e3fSchristos   log_access (_("Child access"));
829*69606e3fSchristos 
830*69606e3fSchristos #endif	/* GETLOADAVG_PRIVILEGED */
831*69606e3fSchristos }
832*69606e3fSchristos 
833*69606e3fSchristos #ifdef NEED_GET_PATH_MAX
834*69606e3fSchristos unsigned int
get_path_max(void)835*69606e3fSchristos get_path_max (void)
836*69606e3fSchristos {
837*69606e3fSchristos   static unsigned int value;
838*69606e3fSchristos 
839*69606e3fSchristos   if (value == 0)
840*69606e3fSchristos     {
841*69606e3fSchristos       long int x = pathconf ("/", _PC_PATH_MAX);
842*69606e3fSchristos       if (x > 0)
843*69606e3fSchristos 	value = x;
844*69606e3fSchristos       else
845*69606e3fSchristos 	return MAXPATHLEN;
846*69606e3fSchristos     }
847*69606e3fSchristos 
848*69606e3fSchristos   return value;
849*69606e3fSchristos }
850*69606e3fSchristos #endif
851*69606e3fSchristos 
852*69606e3fSchristos 
853*69606e3fSchristos /* This code is stolen from gnulib.
854*69606e3fSchristos    If/when we abandon the requirement to work with K&R compilers, we can
855*69606e3fSchristos    remove this (and perhaps other parts of GNU make!) and migrate to using
856*69606e3fSchristos    gnulib directly.
857*69606e3fSchristos 
858*69606e3fSchristos    This is called only through atexit(), which means die() has already been
859*69606e3fSchristos    invoked.  So, call exit() here directly.  Apparently that works...?
860*69606e3fSchristos */
861*69606e3fSchristos 
862*69606e3fSchristos /* Close standard output, exiting with status 'exit_failure' on failure.
863*69606e3fSchristos    If a program writes *anything* to stdout, that program should close
864*69606e3fSchristos    stdout and make sure that it succeeds before exiting.  Otherwise,
865*69606e3fSchristos    suppose that you go to the extreme of checking the return status
866*69606e3fSchristos    of every function that does an explicit write to stdout.  The last
867*69606e3fSchristos    printf can succeed in writing to the internal stream buffer, and yet
868*69606e3fSchristos    the fclose(stdout) could still fail (due e.g., to a disk full error)
869*69606e3fSchristos    when it tries to write out that buffered data.  Thus, you would be
870*69606e3fSchristos    left with an incomplete output file and the offending program would
871*69606e3fSchristos    exit successfully.  Even calling fflush is not always sufficient,
872*69606e3fSchristos    since some file systems (NFS and CODA) buffer written/flushed data
873*69606e3fSchristos    until an actual close call.
874*69606e3fSchristos 
875*69606e3fSchristos    Besides, it's wasteful to check the return value from every call
876*69606e3fSchristos    that writes to stdout -- just let the internal stream state record
877*69606e3fSchristos    the failure.  That's what the ferror test is checking below.
878*69606e3fSchristos 
879*69606e3fSchristos    It's important to detect such failures and exit nonzero because many
880*69606e3fSchristos    tools (most notably `make' and other build-management systems) depend
881*69606e3fSchristos    on being able to detect failure in other tools via their exit status.  */
882*69606e3fSchristos 
883*69606e3fSchristos void
close_stdout(void)884*69606e3fSchristos close_stdout (void)
885*69606e3fSchristos {
886*69606e3fSchristos   int prev_fail = ferror (stdout);
887*69606e3fSchristos   int fclose_fail = fclose (stdout);
888*69606e3fSchristos 
889*69606e3fSchristos   if (prev_fail || fclose_fail)
890*69606e3fSchristos     {
891*69606e3fSchristos       if (fclose_fail)
892*69606e3fSchristos         error (NILF, _("write error: %s"), strerror (errno));
893*69606e3fSchristos       else
894*69606e3fSchristos         error (NILF, _("write error"));
895*69606e3fSchristos       exit (EXIT_FAILURE);
896*69606e3fSchristos     }
897*69606e3fSchristos }
898