~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/3rdparty/qmake/misc.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

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