Commit | Line | Data |
---|---|---|
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 | 10 | static 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 | ||
52 | struct 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 |
93 | char Arpa_Info[] = "050"; /* arbitrary info */ |
94 | char Arpa_TSyserr[] = "451"; /* some (transient) system error */ | |
95 | char Arpa_PSyserr[] = "554"; /* some (permanent) system error */ | |
96 | char 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 |
104 | char *ConfFile = _PATH_SENDMAILCF; /* runtime configuration */ |
105 | char *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 |
113 | int 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 | ||
131 | setdefaults() | |
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 | ||
164 | setdefuser() | |
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 | ||
182 | setupmaps() | |
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 | ||
261 | bool | |
262 | host_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 | ||
294 | setupmailers() | |
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 | ||
311 | getruid() | |
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 | ||
324 | getrgid() | |
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 | ||
347 | char * | |
348 | username() | |
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 | ||
412 | char * | |
413 | ttypath() | |
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 | 467 | checkcompat(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 | ||
503 | holdsigs() | |
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 | ||
521 | rlsesigs() | |
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 | |
589 | struct 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 |
601 | getla() |
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 | |
637 | getla() | |
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 | ||
648 | getla() | |
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 | ||
673 | bool | |
abccefc9 | 674 | shouldqueue(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 | ||
697 | bool | |
698 | refuseconnections() | |
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__ |
720 | setproctitle(char *fmt, ...) | |
721 | #else | |
722 | setproctitle(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 | 773 | void |
8fd13041 EA |
774 | reapchild() |
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 | ||
809 | void | |
810 | unsetenv(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 | ||
846 | int | |
847 | getdtablesize() | |
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 | ||
859 | int | |
860 | uname(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 */ |