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