more environment problems; limit resource exhaustion; fix incorrect
[unix-history] / usr / src / usr.sbin / sendmail / src / conf.c
CommitLineData
d185cb11 1/*
dc45ba8c 2 * Copyright (c) 1983 Eric P. Allman
bee79b64
KB
3 * Copyright (c) 1988 Regents of the University of California.
4 * All rights reserved.
5 *
417f7a11 6 * %sccs.include.redist.c%
bee79b64 7 */
d185cb11
DF
8
9#ifndef lint
6e99f903 10static char sccsid[] = "@(#)conf.c 6.10 (Berkeley) %G%";
bee79b64 11#endif /* not lint */
d185cb11 12
d209c154 13# include <sys/ioctl.h>
611050b6 14# include <pwd.h>
96faada8 15# include "sendmail.h"
84048894 16# include "pathnames.h"
916b3375 17
b3cbe40f 18/*
96faada8 19** CONF.C -- Sendmail Configuration Tables.
b3cbe40f
EA
20**
21** Defines the configuration of this installation.
22**
cb590f52 23** Configuration Variables:
1a12c7d6
EA
24** HdrInfo -- a table describing well-known header fields.
25** Each entry has the field name and some flags,
df960d9b 26** which are described in sendmail.h.
9c6d4c70
EA
27**
28** Notes:
29** I have tried to put almost all the reasonable
30** configuration information into the configuration
31** file read at runtime. My intent is that anything
32** here is a function of the version of UNIX you
33** are running, or is really static -- for example
34** the headers are a superset of widely used
35** protocols. If you find yourself playing with
36** this file too much, you may be making a mistake!
b3cbe40f
EA
37*/
38
39
40
41
b5fd168f 42\f/*
1a12c7d6 43** Header info table
355a2a04 44** Final (null) entry contains the flags used for any other field.
df960d9b
EA
45**
46** Not all of these are actually handled specially by sendmail
47** at this time. They are included as placeholders, to let
48** you know that "someday" I intend to have sendmail do
49** something with them.
1a12c7d6
EA
50*/
51
52struct hdrinfo HdrInfo[] =
53{
6144e1d1 54 /* originator fields, most to least significant */
a90807d8
EA
55 "resent-sender", H_FROM|H_RESENT,
56 "resent-from", H_FROM|H_RESENT,
4e969be0 57 "resent-reply-to", H_FROM|H_RESENT,
be2fcca9
EA
58 "sender", H_FROM,
59 "from", H_FROM,
4e969be0 60 "reply-to", H_FROM,
be2fcca9 61 "full-name", H_ACHECK,
453139c0
EA
62 "return-receipt-to", H_FROM /* |H_RECEIPTTO */,
63 "errors-to", H_FROM|H_ERRORSTO,
6144e1d1 64 /* destination fields */
be2fcca9 65 "to", H_RCPT,
a90807d8 66 "resent-to", H_RCPT|H_RESENT,
be2fcca9 67 "cc", H_RCPT,
a90807d8 68 "resent-cc", H_RCPT|H_RESENT,
be2fcca9 69 "bcc", H_RCPT|H_ACHECK,
a90807d8 70 "resent-bcc", H_RCPT|H_ACHECK|H_RESENT,
5031c0bb 71 "apparently-to", H_RCPT,
6144e1d1 72 /* message identification and control */
a90807d8
EA
73 "message-id", 0,
74 "resent-message-id", H_RESENT,
be2fcca9
EA
75 "message", H_EOH,
76 "text", H_EOH,
a90807d8
EA
77 /* date fields */
78 "date", 0,
79 "resent-date", H_RESENT,
6144e1d1 80 /* trace fields */
be2fcca9
EA
81 "received", H_TRACE|H_FORCE,
82 "via", H_TRACE|H_FORCE,
83 "mail-from", H_TRACE|H_FORCE,
6144e1d1 84
be2fcca9 85 NULL, 0,
1a12c7d6 86};
15b28570
EA
87
88
89/*
90** ARPANET error message numbers.
91*/
92
314d2f52
EA
93char Arpa_Info[] = "050"; /* arbitrary info */
94char Arpa_TSyserr[] = "451"; /* some (transient) system error */
95char Arpa_PSyserr[] = "554"; /* some (permanent) system error */
96char Arpa_Usrerr[] = "554"; /* some (fatal) user error */
4e1f4d4b
EA
97
98
99
4e1f4d4b
EA
100/*
101** Location of system files/databases/etc.
102*/
103
84048894
KB
104char *ConfFile = _PATH_SENDMAILCF; /* runtime configuration */
105char *FreezeFile = _PATH_SENDMAILFC; /* frozen version of above */
acae5a9d
EA
106
107
1744384a
EA
108
109/*
2e3062fe 110** Miscellaneous stuff.
1744384a
EA
111*/
112
2e3062fe
EA
113int DtableSize = 50; /* max open files; reset in 4.2bsd */
114\f/*
115** SETDEFAULTS -- set default values
116**
117** Because of the way freezing is done, these must be initialized
118** using direct code.
119**
120** Parameters:
121** none.
122**
123** Returns:
124** none.
125**
126** Side Effects:
127** Initializes a bunch of global variables to their
128** default values.
129*/
130
131setdefaults()
132{
abccefc9
EA
133 SpaceSub = ' '; /* option B */
134 QueueLA = 8; /* option x */
135 RefuseLA = 12; /* option X */
136 WkRecipFact = 30000L; /* option y */
137 WkClassFact = 1800L; /* option z */
138 WkTimeFact = 90000L; /* option Z */
139 QueueFactor = WkRecipFact * 20; /* option q */
8583ab39 140 FileMode = (getuid() != geteuid()) ? 0644 : 0600;
abccefc9
EA
141 /* option F */
142 DefUid = 1; /* option u */
143 DefGid = 1; /* option g */
144 CheckpointInterval = 10; /* option C */
145 MaxHopCount = 25; /* option h */
146 SendMode = SM_FORK; /* option d */
147 ErrorMode = EM_PRINT; /* option e */
148 EightBit = FALSE; /* option 8 */
149 MaxMciCache = 1; /* option k */
150 MciCacheTimeout = 300; /* option K */
151 LogLevel = 9; /* option L */
152 ReadTimeout = 2 * 60 * 60; /* option r */
153 TimeOut = 3 * 24 * 60 * 60; /* option T */
3fbc69d6 154 setdefuser();
42fa5d67 155 setupmaps();
98e5062b 156 setupmailers();
2e3062fe 157}
a0554f81 158
3fbc69d6
KB
159
160/*
161** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
162*/
163
164setdefuser()
165{
166 struct passwd *defpwent;
84c8a3c6 167 static char defuserbuf[40];
3fbc69d6 168
84c8a3c6 169 DefUser = defuserbuf;
3fbc69d6 170 if ((defpwent = getpwuid(DefUid)) != NULL)
84c8a3c6 171 strcpy(defuserbuf, defpwent->pw_name);
3fbc69d6 172 else
84c8a3c6 173 strcpy(defuserbuf, "nobody");
3fbc69d6 174}
42fa5d67
EA
175\f/*
176** SETUPMAPS -- set up map classes
177**
178** Since these are compiled in, they cannot be in the config file.
179**
180*/
181
182setupmaps()
183{
184 register STAB *s;
32fd13db 185 extern bool host_map_init();
42fa5d67
EA
186 extern char *maphostname();
187
188 /* set up host name lookup map */
189 s = stab("host", ST_MAPCLASS, ST_ENTER);
32fd13db 190 s->s_mapclass.map_init = host_map_init;
42fa5d67 191 s->s_mapclass.map_lookup = maphostname;
42fa5d67
EA
192
193 /*
194 ** Set up other map classes.
195 */
196
197# ifdef DBM_MAP
198 /* dbm file access */
199 {
32fd13db 200 extern bool dbm_map_init();
42fa5d67 201 extern char *dbm_map_lookup();
3fbc69d6 202
42fa5d67
EA
203 s = stab("dbm", ST_MAPCLASS, ST_ENTER);
204 s->s_mapclass.map_init = dbm_map_init;
205 s->s_mapclass.map_lookup = dbm_map_lookup;
206 }
207# endif
3fbc69d6 208
42fa5d67
EA
209# ifdef BTREE_MAP
210 /* new database file access -- btree files */
211 {
5a4c03c6
EA
212 extern bool bt_map_init();
213 extern char *db_map_lookup();
42fa5d67
EA
214
215 s = stab("btree", ST_MAPCLASS, ST_ENTER);
216 s->s_mapclass.map_init = bt_map_init;
5a4c03c6 217 s->s_mapclass.map_lookup = db_map_lookup;
42fa5d67
EA
218 }
219# endif
220
221# ifdef HASH_MAP
222 /* new database file access -- hash files */
223 {
5a4c03c6
EA
224 extern bool hash_map_init();
225 extern char *db_map_lookup();
42fa5d67
EA
226
227 s = stab("hash", ST_MAPCLASS, ST_ENTER);
228 s->s_mapclass.map_init = hash_map_init;
5a4c03c6 229 s->s_mapclass.map_lookup = db_map_lookup;
42fa5d67
EA
230 }
231# endif
232
33844dcf
EA
233# ifdef NIS_MAP
234 /* NIS map access */
235 {
236 extern bool nis_map_init();
237 extern char *nis_map_lookup();
238
239 s = stab("nis", ST_MAPCLASS, ST_ENTER);
240 s->s_mapclass.map_init = nis_map_init;
241 s->s_mapclass.map_lookup = nis_map_lookup;
242 }
243# endif
244
42fa5d67
EA
245# ifdef USERDB_MAP
246 /* user database */
247 {
32fd13db 248 extern bool udb_map_init();
42fa5d67
EA
249 extern char *udb_map_lookup();
250
251 s = stab("udb", ST_MAPCLASS, ST_ENTER);
252 s->s_mapclass.map_init = udb_map_init;
253 s->s_mapclass.map_lookup = udb_map_lookup;
254 }
255# endif
256}
32fd13db
EA
257\f/*
258** HOST_MAP_INIT -- initialize host class structures
259*/
260
261bool
262host_map_init(map, mapname, args)
263 MAP *map;
264 char *mapname;
265 char *args;
266{
267 register char *p = args;
268
269 for (;;)
270 {
271 while (isspace(*p))
272 p++;
273 if (*p != '-')
274 break;
275 switch (*++p)
276 {
277 case 'a':
278 map->map_app = ++p;
279 break;
280 }
281 while (*p != '\0' && !isspace(*p))
282 p++;
283 if (*p != '\0')
284 *p++ = '\0';
285 }
286 if (map->map_app != NULL)
287 map->map_app = newstr(map->map_app);
288 return TRUE;
289}
98e5062b
EA
290\f/*
291** SETUPMAILERS -- initialize default mailers
292*/
293
294setupmailers()
295{
296 char buf[100];
297
0eb3afc4
EA
298 strcpy(buf, "prog, P=/bin/sh, F=lsD, A=sh -c $u");
299 makemailer(buf);
300
98e5062b
EA
301 strcpy(buf, "*file*, P=/dev/null, F=lsDEu, A=FILE");
302 makemailer(buf);
32fd13db 303
98e5062b
EA
304 strcpy(buf, "*include*, P=/dev/null, F=su, A=INCLUDE");
305 makemailer(buf);
306}
42fa5d67 307\f/*
a0554f81
EA
308** GETRUID -- get real user id (V7)
309*/
310
311getruid()
312{
75f95954 313 if (OpMode == MD_DAEMON)
f6a0cc15
EA
314 return (RealUid);
315 else
316 return (getuid());
a0554f81
EA
317}
318
319
320/*
321** GETRGID -- get real group id (V7).
322*/
323
324getrgid()
325{
75f95954 326 if (OpMode == MD_DAEMON)
f6a0cc15
EA
327 return (RealGid);
328 else
329 return (getgid());
a0554f81 330}
42fa5d67 331\f/*
7338e3d4
EA
332** USERNAME -- return the user id of the logged in user.
333**
334** Parameters:
335** none.
336**
337** Returns:
338** The login name of the logged in user.
339**
340** Side Effects:
341** none.
342**
343** Notes:
344** The return value is statically allocated.
345*/
346
347char *
348username()
349{
560a80d9 350 static char *myname = NULL;
7338e3d4 351 extern char *getlogin();
19c3b81a 352 register struct passwd *pw;
7338e3d4 353
560a80d9
EA
354 /* cache the result */
355 if (myname == NULL)
356 {
357 myname = getlogin();
358 if (myname == NULL || myname[0] == '\0')
359 {
560a80d9
EA
360
361 pw = getpwuid(getruid());
362 if (pw != NULL)
2a669966 363 myname = newstr(pw->pw_name);
560a80d9 364 }
19c3b81a
MAN
365 else
366 {
1a626eeb 367
2a669966
KB
368 myname = newstr(myname);
369 if ((pw = getpwnam(myname)) == NULL ||
370 getuid() != pw->pw_uid)
19c3b81a 371 {
1a626eeb 372 pw = getpwuid(getuid());
84f20e6d 373 if (pw != NULL)
2a669966 374 myname = newstr(pw->pw_name);
1a626eeb
MAN
375 }
376 }
560a80d9
EA
377 if (myname == NULL || myname[0] == '\0')
378 {
379 syserr("Who are you?");
380 myname = "postmaster";
381 }
382 }
383
384 return (myname);
7338e3d4
EA
385}
386\f/*
14e42c2b 387** TTYPATH -- Get the path of the user's tty
b3cbe40f
EA
388**
389** Returns the pathname of the user's tty. Returns NULL if
390** the user is not logged in or if s/he has write permission
391** denied.
392**
393** Parameters:
394** none
395**
396** Returns:
397** pathname of the user's tty.
398** NULL if not logged in or write permission denied.
399**
400** Side Effects:
401** none.
402**
403** WARNING:
404** Return value is in a local buffer.
405**
b3cbe40f
EA
406** Called By:
407** savemail
b3cbe40f
EA
408*/
409
b3cbe40f
EA
410# include <sys/stat.h>
411
412char *
413ttypath()
414{
415 struct stat stbuf;
416 register char *pathn;
b3cbe40f 417 extern char *ttyname();
29871fef 418 extern char *getlogin();
b3cbe40f
EA
419
420 /* compute the pathname of the controlling tty */
7338e3d4
EA
421 if ((pathn = ttyname(2)) == NULL && (pathn = ttyname(1)) == NULL &&
422 (pathn = ttyname(0)) == NULL)
b3cbe40f
EA
423 {
424 errno = 0;
425 return (NULL);
426 }
427
428 /* see if we have write permission */
a530c75f 429 if (stat(pathn, &stbuf) < 0 || !bitset(02, stbuf.st_mode))
b3cbe40f
EA
430 {
431 errno = 0;
432 return (NULL);
433 }
434
435 /* see if the user is logged in */
436 if (getlogin() == NULL)
437 return (NULL);
438
439 /* looks good */
440 return (pathn);
441}
a530c75f
EA
442\f/*
443** CHECKCOMPAT -- check for From and To person compatible.
444**
445** This routine can be supplied on a per-installation basis
446** to determine whether a person is allowed to send a message.
447** This allows restriction of certain types of internet
448** forwarding or registration of users.
449**
450** If the hosts are found to be incompatible, an error
7e70d3c8 451** message should be given using "usrerr" and 0 should
a530c75f
EA
452** be returned.
453**
46b14b48
EA
454** 'NoReturn' can be set to suppress the return-to-sender
455** function; this should be done on huge messages.
456**
a530c75f
EA
457** Parameters:
458** to -- the person being sent to.
459**
460** Returns:
396d97e9 461** an exit status
a530c75f
EA
462**
463** Side Effects:
464** none (unless you include the usrerr stuff)
465*/
466
a4076aed 467checkcompat(to, e)
a530c75f 468 register ADDRESS *to;
a4076aed 469 register ENVELOPE *e;
a530c75f 470{
22e6d6b8
EA
471# ifdef lint
472 if (to == NULL)
473 to++;
474# endif lint
97ad25b6
EA
475# ifdef EXAMPLE_CODE
476 /* this code is intended as an example only */
b14547d5
EA
477 register STAB *s;
478
b14547d5 479 s = stab("arpa", ST_MAILER, ST_FIND);
a4076aed 480 if (s != NULL && e->e_from.q_mailer != LocalMailer &&
7338e3d4 481 to->q_mailer == s->s_mailer)
b14547d5
EA
482 {
483 usrerr("No ARPA mail through this machine: see your system administration");
97ad25b6 484 /* NoReturn = TRUE; to supress return copy */
396d97e9 485 return (EX_UNAVAILABLE);
b14547d5 486 }
f3d8f6d6 487# endif /* EXAMPLE_CODE */
396d97e9 488 return (EX_OK);
a530c75f 489}
7338e3d4
EA
490\f/*
491** HOLDSIGS -- arrange to hold all signals
492**
493** Parameters:
494** none.
495**
496** Returns:
497** none.
498**
499** Side Effects:
500** Arranges that signals are held.
501*/
502
503holdsigs()
504{
505}
506\f/*
507** RLSESIGS -- arrange to release all signals
508**
509** This undoes the effect of holdsigs.
510**
511** Parameters:
512** none.
513**
514** Returns:
515** none.
516**
517** Side Effects:
518** Arranges that signals are released.
519*/
520
521rlsesigs()
522{
523}
f7e74083
EA
524\f/*
525** GETLA -- get the current load average
526**
d209c154
EA
527** This code stolen from la.c.
528**
f7e74083
EA
529** Parameters:
530** none.
531**
532** Returns:
533** The current load average as an integer.
534**
535** Side Effects:
536** none.
537*/
538
3620ad97
EA
539/* try to guess what style of load average we have */
540#define LA_ZERO 1 /* always return load average as zero */
541#define LA_INT 2 /* read kmem for avenrun; interpret as int */
542#define LA_FLOAT 3 /* read kmem for avenrun; interpret as float */
543#define LA_SUBR 4 /* call getloadavg */
544
545#ifndef LA_TYPE
546# if defined(sun)
547# define LA_TYPE LA_INT
548# endif
549# if defined(mips)
550 /* Ultrix or RISC/os */
551# define LA_TYPE LA_INT
552# define LA_AVENRUN "avenrun"
553# endif
554# if defined(hpux)
555# define LA_TYPE LA_FLOAT
556# endif
557# if defined(BSD)
558# define LA_TYPE LA_SUBR
559# endif
560
561# ifndef LA_TYPE
562# define LA_TYPE LA_ZERO
563# endif
564#endif
565
566#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT)
f7e74083
EA
567
568#include <nlist.h>
3620ad97
EA
569#include <fcntl.h>
570
571#ifndef LA_AVENRUN
572#define LA_AVENRUN "_avenrun"
573#endif
574
575/* _PATH_UNIX should be defined in <paths.h> */
576#ifndef _PATH_UNIX
577# if defined(hpux)
578# define _PATH_UNIX "/hp-ux"
579# endif
580# if defined(mips) && !defined(ultrix)
581 /* powerful RISC/os */
582# define _PATH_UNIX "/unix"
583# endif
584# ifndef _PATH_UNIX
585# define _PATH_UNIX "/vmunix"
586# endif
587#endif
f7e74083
EA
588
589struct nlist Nl[] =
590{
3620ad97 591 { LA_AVENRUN },
f7e74083
EA
592#define X_AVENRUN 0
593 { 0 },
594};
595
3620ad97
EA
596#if (LA_TYPE == LA_INT) && !defined(FSHIFT)
597# define FSHIFT 8
598# define FSCALE (1 << FSHIFT)
599#endif
27355bf0 600
f7e74083
EA
601getla()
602{
603 static int kmem = -1;
3620ad97 604#if LA_TYPE == LA_INT
2e3062fe 605 long avenrun[3];
3620ad97
EA
606#else
607 double avenrun[3];
608#endif
901911f8 609 extern off_t lseek();
f7e74083
EA
610
611 if (kmem < 0)
612 {
fa483327 613 kmem = open("/dev/kmem", 0, 0);
f7e74083
EA
614 if (kmem < 0)
615 return (-1);
3620ad97
EA
616 (void) fcntl(kmem, F_SETFD, 1);
617 nlist(_PATH_UNIX, Nl);
f7e74083
EA
618 if (Nl[0].n_type == 0)
619 return (-1);
620 }
fa483327 621 if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 ||
17a67c62 622 read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
fa42ff8e
EA
623 {
624 /* thank you Ian */
625 return (-1);
626 }
3620ad97 627#if LA_TYPE == LA_INT
2e3062fe 628 return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
3620ad97
EA
629#else
630 return ((int) (avenrun[0] + 0.5));
631#endif
f7e74083
EA
632}
633
5a85b715 634#else
3620ad97 635#if LA_TYPE == LA_SUBR
5a85b715
EA
636
637getla()
638{
3620ad97
EA
639 double avenrun[3];
640
641 if (getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])) < 0)
642 return (-1);
643 return ((int) (avenrun[0] + 0.5));
5a85b715
EA
644}
645
646#else
647
648getla()
649{
3620ad97 650 return (0);
5a85b715
EA
651}
652
653#endif
654#endif
2e3062fe
EA
655\f/*
656** SHOULDQUEUE -- should this message be queued or sent?
657**
658** Compares the message cost to the load average to decide.
659**
660** Parameters:
661** pri -- the priority of the message in question.
abccefc9 662** ctime -- the message creation time.
2e3062fe
EA
663**
664** Returns:
665** TRUE -- if this message should be queued up for the
666** time being.
667** FALSE -- if the load is low enough to send this message.
668**
669** Side Effects:
670** none.
671*/
672
673bool
abccefc9 674shouldqueue(pri, ctime)
2e3062fe 675 long pri;
abccefc9 676 time_t ctime;
2e3062fe 677{
3620ad97 678 if (CurrentLA < QueueLA)
2e3062fe 679 return (FALSE);
3620ad97 680 return (pri > (QueueFactor / (CurrentLA - QueueLA + 1)));
2e3062fe
EA
681}
682\f/*
a90a7c55
EA
683** REFUSECONNECTIONS -- decide if connections should be refused
684**
685** Parameters:
686** none.
687**
688** Returns:
689** TRUE if incoming SMTP connections should be refused
690** (for now).
691** FALSE if we should accept new work.
692**
693** Side Effects:
694** none.
695*/
696
697bool
698refuseconnections()
699{
700 /* this is probably too simplistic */
701 return (CurrentLA > RefuseLA);
702}
703\f/*
2e3062fe
EA
704** SETPROCTITLE -- set process title for ps
705**
706** Parameters:
707** fmt -- a printf style format string.
708** a, b, c -- possible parameters to fmt.
709**
710** Returns:
711** none.
712**
713** Side Effects:
714** Clobbers argv of our main procedure so ps(1) will
715** display the title.
716*/
717
718/*VARARGS1*/
6e99f903
EA
719#ifdef __STDC__
720setproctitle(char *fmt, ...)
721#else
722setproctitle(fmt, va_alist)
2e3062fe 723 char *fmt;
6e99f903
EA
724 va_dcl
725#endif
2e3062fe
EA
726{
727# ifdef SETPROCTITLE
728 register char *p;
f5ca8c6e 729 register int i;
5229f34d
EA
730 char buf[MAXLINE];
731 VA_LOCAL_DECL
2e3062fe
EA
732 extern char **Argv;
733 extern char *LastArgv;
734
3aace037 735 p = buf;
2e3062fe 736
3aace037
EA
737 /* print sendmail: heading for grep */
738 (void) strcpy(p, "sendmail: ");
739 p += strlen(p);
740
741 /* print the argument string */
5229f34d
EA
742 VA_START(fmt);
743 (void) vsprintf(p, fmt, ap);
744 VA_END;
2e3062fe 745
f5ca8c6e 746 i = strlen(buf);
3aace037 747 if (i > LastArgv - Argv[0] - 2)
f5ca8c6e 748 {
3aace037 749 i = LastArgv - Argv[0] - 2;
f5ca8c6e
EA
750 buf[i] = '\0';
751 }
3aace037 752 (void) strcpy(Argv[0], buf);
1c95ae0f 753 p = &Argv[0][i];
2e3062fe
EA
754 while (p < LastArgv)
755 *p++ = ' ';
f3d8f6d6 756# endif /* SETPROCTITLE */
2e3062fe 757}
8fd13041
EA
758\f/*
759** REAPCHILD -- pick up the body of my child, lest it become a zombie
760**
761** Parameters:
762** none.
763**
764** Returns:
765** none.
766**
767** Side Effects:
768** Picks up extant zombies.
769*/
770
8fd13041 771# include <sys/wait.h>
8fd13041 772
0df908a9 773void
8fd13041
EA
774reapchild()
775{
776# ifdef WNOHANG
777 union wait status;
778
0df908a9 779 while (wait3((int *)&status, WNOHANG, (struct rusage *) NULL) > 0)
8fd13041 780 continue;
f3d8f6d6 781# else /* WNOHANG */
8fd13041
EA
782 auto int status;
783
0df908a9 784 while (wait((int *)&status) > 0)
8fd13041 785 continue;
f3d8f6d6 786# endif /* WNOHANG */
8fd13041 787}
07c63e56
EA
788\f/*
789** UNSETENV -- remove a variable from the environment
790**
791** Not needed on newer systems.
792**
793** Parameters:
794** name -- the string name of the environment variable to be
795** deleted from the current environment.
796**
797** Returns:
798** none.
799**
800** Globals:
801** environ -- a pointer to the current environment.
802**
803** Side Effects:
804** Modifies environ.
805*/
806
807#ifdef UNSETENV
808
809void
810unsetenv(name)
811 char *name;
812{
813 extern char **environ;
814 register char **pp;
815 int len = strlen(name);
816
817 for (pp = environ; *pp != NULL; pp++)
818 {
819 if (strncmp(name, *pp, len) == 0 &&
820 ((*pp)[len] == '=' || (*pp)[len] == '\0'))
821 break;
822 }
823
824 for (; *pp != NULL; pp++)
825 *pp = pp[1];
826}
827
828#endif /* UNSETENV */
5031c0bb
EA
829\f/*
830** GETDTABLESIZE -- return number of file descriptors
831**
832** Only on non-BSD systems
833**
834** Parameters:
835** none
836**
837** Returns:
838** size of file descriptor table
839**
840** Side Effects:
841** none
842*/
843
844#ifdef SYSTEM5
845
846int
847getdtablesize()
848{
849 return NOFILE;
850}
851
852#endif
422bed79
EA
853\f/*
854** UNAME -- get the UUCP name of this system.
855*/
856
857#ifndef UNAME
858
859int
860uname(name)
861 struct utsname *name;
862{
863 FILE *file;
864 char *n;
865
866 name->nodename[0] = '\0';
867
868 if ((file = fopen("/etc/whoami", "r")) != NULL)
869 {
870 (void) fgets(name->nodename, NODE_LENGTH+1, file);
871 (void) fclose(file);
872 n = index(name->nodename, '\n');
873 if (n != NULL)
874 *n = '\0';
875 if (name->nodename[0] != '\0')
876 return (0);
877 }
878
879 if ((file = fopen("/usr/include/whoami.h", "r")) != NULL)
880 {
881 char buf[MAXLINE];
882
883 while (fgets(buf, MAXLINE, file) != NULL)
884 if (sscanf(buf, "#define sysname \"%*[^\"]\"",
885 NODE_LENGTH, name->nodename) > 0)
886 break;
887 (void) fclose(file);
888 if (name->nodename[0] != '\0')
889 return (0);
890 }
891
892#ifdef TRUST_POPEN
893 /*
894 ** Popen is known to have security holes.
895 */
896
897 if ((file = popen("uuname -l", "r")) != NULL)
898 {
899 (void) fgets(name, NODE_LENGTH+1, file);
900 (void) pclose(file);
901 n = index(name, '\n');
902 if (n != NULL)
903 *n = '\0';
904 if (name->nodename[0])
905 return (0);
906 }
907#endif
908
909 return (-1);
910}
911#endif /* UNAME */