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