Build without WITH_CONTENT_SCAN.
[exim.git] / src / src / buildconfig.c
CommitLineData
10385c15 1/* $Cambridge: exim/src/src/buildconfig.c,v 1.16 2010/06/06 02:46:13 pdp Exp $ */
059ec3d9
PH
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
0a49a7a4 7/* Copyright (c) University of Cambridge 1995 - 2009 */
059ec3d9
PH
8/* See the file NOTICE for conditions of use and distribution. */
9
10
11/*************************************************
12* Build configuration header for Exim *
13*************************************************/
14
15/* This auxiliary program builds the file config.h by the following
16process:
17
c6c2dc1d
PH
18First, it determines the size of off_t and time_t variables, and generates
19macro code to define OFF_T_FMT and TIME_T_FMT as suitable formats, if they are
20not already defined in the system-specific header file.
b1c749bb
PH
21
22Then it reads Makefile, looking for certain OS-specific definitions which it
23uses to define some specific macros. Finally, it reads the defaults file
24config.h.defaults.
059ec3d9
PH
25
26The defaults file contains normal C #define statements for various macros; if
27the name of a macro is found in the environment, the environment value replaces
28the default. If the default #define does not contain any value, then that macro
29is not copied to the created file unless there is some value in the
30environment.
31
32This program is compiled and run as part of the Make process and is not
33normally called independently. */
34
35
36#include <ctype.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <sys/types.h>
41#include <pwd.h>
42#include <grp.h>
43
44typedef struct {
45 char *name;
46 int *flag;
47} have_item;
48
49typedef struct {
50 char *name;
51 char *data;
52} save_item;
53
54static char *db_opts[] = { "", "USE_DB", "USE_GDBM", "USE_TDB" };
55
56static int have_ipv6 = 0;
57static int have_iconv = 0;
58
59static char errno_quota[256];
60static char ostype[256];
61static char cc[256];
62
63/* If any entry is an initial substring of another, the longer one must
64appear first. */
65
66static have_item have_list[] = {
67 { "HAVE_IPV6", &have_ipv6 },
68 { "HAVE_ICONV", &have_iconv },
69 { NULL, NULL}
70};
71
72static save_item save_list[] = {
73 { "ERRNO_QUOTA", errno_quota },
74 { "OSTYPE", ostype },
75 { "CC", cc },
76 { NULL, NULL}
77};
78
79
80/* Subroutine to check a string for precisely one instance of "%s". If not,
81bomb out. */
82
83void
84check_percent_ess(char *value, char *name)
85{
86int OK = 0;
87char *p = strstr(value, "%s");
88if (p != NULL) OK = strstr(p+2, "%s") == NULL;
89if (!OK)
90 {
91 printf("\n*** \"%s\" (%s) must contain precisely one occurrence of\n"
92 "*** \"%%s\". Please review your build-time configuration.\n\n/", value,
93 name);
94 exit(1);
95 }
96}
97
98
99/* Main program */
100
101int
102main(int argc, char **argv)
103{
b1c749bb 104off_t test_off_t = 0;
c6c2dc1d 105time_t test_time_t = 0;
059ec3d9
PH
106FILE *base;
107FILE *new;
108int last_initial = 'A';
109int linecount = 0;
110int have_auth = 0;
111int in_local_makefile = 0;
112int use_which_db = 0;
113int use_which_db_in_local_makefile = 0;
114int support_crypteq = 0;
115char buffer[1024];
116
117if (argc != 1)
118 {
119 printf("*** Buildconfig: called with incorrect arguments\n");
120 exit(1);
121 }
122
123new = fopen("config.h", "wb");
124if (new == NULL)
125 {
126 printf("*** Buildconfig: failed to open config.h for output\n");
127 exit(1);
128 }
129
130printf("Building configuration file config.h\n");
131
132fprintf(new, "/*************************************************\n");
133fprintf(new, "* Configuration header for Exim *\n");
134fprintf(new, "*************************************************/\n\n");
135
136fprintf(new, "/* This file was automatically generated from Makefile and "
137 "config.h.defaults,\n");
138fprintf(new, "using values specified in the configuration file Local/Makefile.\n");
139fprintf(new, "Do not edit it. Instead, edit Local/Makefile and "
140 "rerun make. */\n\n");
141
b1c749bb
PH
142/* First, deal with the printing format for off_t variables. We assume that if
143the size of off_t is greater than 4, "%lld" will be available as a format for
144printing long long variables, and there will be support for the long long type.
145This assumption is known to be OK for the common operating systems. */
146
147fprintf(new, "#ifndef OFF_T_FMT\n");
148if (sizeof(test_off_t) > 4)
149 {
150 fprintf(new, "#define OFF_T_FMT \"%%lld\"\n");
c6c2dc1d 151 fprintf(new, "#define LONGLONG_T long long int\n");
b1c749bb
PH
152 }
153else
154 {
155 fprintf(new, "#define OFF_T_FMT \"%%ld\"\n");
c6c2dc1d
PH
156 fprintf(new, "#define LONGLONG_T long int\n");
157 }
158fprintf(new, "#endif\n\n");
159
160/* Now do the same thing for time_t variables. If the length is greater than
1614, we want to assume long long support (even if off_t was less than 4). If the
162length is 4 or less, we can leave LONGLONG_T to whatever was defined above for
163off_t. */
164
165fprintf(new, "#ifndef TIME_T_FMT\n");
166if (sizeof(test_time_t) > 4)
167 {
168 fprintf(new, "#define TIME_T_FMT \"%%lld\"\n");
169 fprintf(new, "#undef LONGLONG_T\n");
170 fprintf(new, "#define LONGLONG_T long long int\n");
171 }
172else
173 {
174 fprintf(new, "#define TIME_T_FMT \"%%ld\"\n");
b1c749bb
PH
175 }
176fprintf(new, "#endif\n\n");
177
178/* Now search the makefile for certain settings */
059ec3d9
PH
179
180base = fopen("Makefile", "rb");
181if (base == NULL)
182 {
183 printf("*** Buildconfig: failed to open Makefile\n");
f1e894f3 184 (void)fclose(new);
059ec3d9
PH
185 exit(1);
186 }
187
188errno_quota[0] = 0; /* no over-riding value set */
189ostype[0] = 0; /* just in case */
190cc[0] = 0;
191
192while (fgets(buffer, sizeof(buffer), base) != NULL)
193 {
194 int i;
195 have_item *h;
196 save_item *s;
197 char *p = buffer + (int)strlen(buffer);
198 linecount++;
199 while (p > buffer && isspace((unsigned char)p[-1])) p--;
200 *p = 0;
201 p = buffer;
202 while (isspace((unsigned char)*p)) p++;
203
204 /* Notice when we hit the user's makefile */
205
206 if (strcmp(p, "# From Local/Makefile") == 0)
207 {
208 in_local_makefile = 1;
209 continue;
210 }
211
212 /* Remember the last DB option setting. If we hit two in the user's
213 Makefile, complain. */
214
215 for (i = 1; i < sizeof(db_opts)/sizeof(char *); i++)
216 {
217 int len = (int)strlen(db_opts[i]);
218 if (strncmp(p, db_opts[i], len) == 0 && (p[len] == ' ' || p[len] == '='))
219 {
220 if (in_local_makefile)
221 {
222 if (use_which_db_in_local_makefile)
223 {
224 printf("*** Only one of USE_DB, USE_GDBM, or USE_TDB should be "
225 "defined in Local/Makefile\n");
226 exit(1);
227 }
228 use_which_db_in_local_makefile = 1;
229 }
230 use_which_db = i;
231 break;
232 }
233 }
234 if (i < sizeof(db_opts)/sizeof(char *)) continue;
235
236 /* Items where we just save a boolean */
237
238 for (h = have_list; h->name != NULL; h++)
239 {
240 int len = (int)strlen(h->name);
241 if (strncmp(p, h->name, len) == 0)
242 {
243 p += len;
244 while (isspace((unsigned char)*p)) p++;
245 if (*p++ != '=')
246 {
247 printf("*** Buildconfig: syntax error in Makefile line %d\n", linecount);
248 exit(1);
249 }
250 while (isspace((unsigned char)*p)) p++;
251 if (strcmp(p, "YES") == 0 || strcmp(p, "yes") == 0) *(h->flag) = 1;
252 else *(h->flag) = 0; /* Must reset in case multiple instances */
253 break;
254 }
255 }
256
257 if (h->name != NULL) continue;
258
259 /* Items where we save the complete string */
260
261 for (s = save_list; s->name != NULL; s++)
262 {
263 int len = (int)strlen(s->name);
264 if (strncmp(p, s->name, len) == 0)
265 {
266 p += len;
267 while (isspace((unsigned char)*p)) p++;
268 if (*p++ != '=')
269 {
270 printf("*** Buildconfig: syntax error in Makefile line %d\n", linecount);
271 exit(1);
272 }
273 while (isspace((unsigned char)*p)) p++;
274 strcpy(s->data, p);
275 }
276 }
277 }
278
279fprintf(new, "#define HAVE_IPV6 %s\n",
280 have_ipv6? "TRUE" : "FALSE");
281
282fprintf(new, "#define HAVE_ICONV %s\n",
283 have_iconv? "TRUE" : "FALSE");
284
285if (errno_quota[0] != 0)
286 fprintf(new, "\n#define ERRNO_QUOTA %s\n", errno_quota);
287
2548ba04
PH
288if (strcmp(cc, "gcc") == 0 &&
289 (strstr(ostype, "IRIX") != NULL || strstr(ostype, "AIX") != NULL))
059ec3d9
PH
290 {
291 fprintf(new, "\n/* This switch includes the code to fix the inet_ntoa() */");
2548ba04 292 fprintf(new, "\n/* bug when using gcc on an IRIX or AIX system. */");
059ec3d9
PH
293 fprintf(new, "\n#define USE_INET_NTOA_FIX");
294 }
295
296fprintf(new, "\n");
f1e894f3 297(void)fclose(base);
059ec3d9
PH
298
299
300/* Now handle the macros listed in the defaults */
301
302base = fopen("../src/config.h.defaults", "rb");
303if (base == NULL)
304 {
305 printf("*** Buildconfig: failed to open ../src/config.h.defaults\n");
f1e894f3 306 (void)fclose(new);
059ec3d9
PH
307 exit(1);
308 }
309
310while (fgets(buffer, sizeof(buffer), base) != NULL)
311 {
312 int i;
313 char name[256];
314 char *value;
315 char *p = buffer;
316 char *q = name;
317
318 while (*p == ' ' || *p == '\t') p++;
319
320 if (strncmp(p, "#define ", 8) != 0) continue;
321
322 p += 8;
323 while (*p == ' ' || *p == '\t') p++;
324
325 if (*p < last_initial) fprintf(new, "\n");
326 last_initial = *p;
327
328 while (*p && (isalnum((unsigned char)*p) || *p == '_')) *q++ = *p++;
329 *q = 0;
330
331 /* USE_DB, USE_GDBM, and USE_TDB are special cases. We want to have only
332 one of them set. The scan of the Makefile has saved which was the last one
333 encountered. */
334
335 for (i = 1; i < sizeof(db_opts)/sizeof(char *); i++)
336 {
337 if (strcmp(name, db_opts[i]) == 0)
338 {
339 if (use_which_db == i)
340 fprintf(new, "#define %s %.*syes\n", db_opts[i],
341 21 - (int)strlen(db_opts[i]), " ");
342 else
343 fprintf(new, "/* %s not set */\n", name);
344 break;
345 }
346 }
347 if (i < sizeof(db_opts)/sizeof(char *)) continue;
348
349 /* EXIM_USER is a special case. We look in the environment for EXIM_USER or
350 EXIM_UID (the latter for backward compatibility with Exim 3). If the value is
351 not numeric, we look up the user, and default the GID if found. Otherwise,
352 EXIM_GROUP or EXIM_GID must be in the environment. */
353
354 if (strcmp(name, "EXIM_UID") == 0)
355 {
356 uid_t uid = 0;
357 gid_t gid = 0;
358 int gid_set = 0;
10385c15 359 int uid_not_set = 0;
059ec3d9
PH
360 char *username = NULL;
361 char *groupname = NULL;
362 char *s;
363 char *user = getenv("EXIM_USER");
364 char *group = getenv("EXIM_GROUP");
365
366 if (user == NULL) user = getenv("EXIM_UID");
367 if (group == NULL) group = getenv("EXIM_GID");
368
369 if (user == NULL)
370 {
371 printf("\n*** EXIM_USER has not been defined in any of the Makefiles in "
372 "the\n \"Local\" directory. Please review your build-time "
373 "configuration.\n\n");
374 return 1;
375 }
376
377 while (isspace((unsigned char)(*user))) user++;
378 if (*user == 0)
379 {
380 printf("\n*** EXIM_USER is defined as an empty string in one of the "
381 "files\n in the \"Local\" directory. Please review your build-time"
382 "\n configuration.\n\n");
383 return 1;
384 }
385
386 for (s = user; *s != 0; s++)
387 {
388 if (iscntrl((unsigned char)(*s)))
389 {
390 printf("\n*** EXIM_USER contains the control character 0x%02X in one "
391 "of the files\n in the \"Local\" directory. Please review your "
392 "build-time\n configuration.\n\n", *s);
393 return 1;
394 }
395 }
396
397 /* Numeric uid given */
398
399 if (user[strspn(user, "0123456789")] == 0)
400 {
401 uid = (uid_t)atoi(user);
402 }
403
404 /* User name given. Normally, we look up the uid right away. However,
405 people building binary distributions sometimes want to retain the name till
406 runtime. This is supported if the name begins "ref:". */
407
408 else if (strncmp(user, "ref:", 4) == 0)
409 {
410 user += 4;
411 while (isspace(*user)) user++;
412 username = user;
413 gid_set = 1;
10385c15 414 uid_not_set = 1;
059ec3d9
PH
415 }
416
417 else
418 {
419 struct passwd *pw = getpwnam(user);
420 if (pw == NULL)
421 {
422 printf("\n*** User \"%s\" (specified in one of the Makefiles) does not "
423 "exist.\n Please review your build-time configuration.\n\n",
424 user);
425 return 1;
426 }
427
428 uid = pw->pw_uid;
429 gid = pw->pw_gid;
430 gid_set = 1;
431 }
432
433 /* Use explicit group if set. */
434
435 if (group != NULL)
436 {
437 while (isspace((unsigned char)(*group))) group++;
438 if (*group == 0)
439 {
440 printf("\n*** EXIM_GROUP is defined as an empty string in one of "
441 "the files in the\n \"Local\" directory. ");
442 if (gid_set)
443 {
444 printf("If you want the Exim group to be taken from the\n "
445 "password data for the Exim user, just remove the EXIM_GROUP "
446 "setting.\n Otherwise, p");
447 }
448 else printf("EXIM_USER is defined numerically, so there is no"
449 "\n default for EXIM_GROUP and you must set it explicitly.\n P");
450 printf("lease review your build-time configuration.\n\n");
451 return 1;
452 }
453
454 for (s = group; *s != 0; s++)
455 {
456 if (iscntrl((unsigned char)(*s)))
457 {
458 printf("\n*** EXIM_GROUP contains the control character 0x%02X in one "
459 "of the files\n in the \"Local\" directory. Please review your "
460 "build-time\n configuration.\n\n", *s);
461 return 1;
462 }
463 }
464
465 /* Group name given. This may be by reference or to be looked up now,
466 as for user. */
467
468 if (strncmp(group, "ref:", 4) == 0)
469 {
470 group += 4;
471 while (isspace(*group)) group++;
472 groupname = group;
473 }
474
475 else if (username != NULL)
476 {
477 groupname = group;
478 }
479
480 else if (group[strspn(group, "0123456789")] == 0)
481 {
482 gid = (gid_t)atoi(group);
483 }
484
485 else
486 {
487 struct group *gr = getgrnam(group);
488 if (gr == NULL)
489 {
490 printf("\n*** Group \"%s\" (specified in one of the Makefiles) does "
491 "not exist.\n Please review your build-time configuration.\n\n",
492 group);
493 return 1;
494 }
495 gid = gr->gr_gid;
496 }
497 }
498
499 /* Else trouble unless found in passwd file with user */
500
501 else if (!gid_set)
502 {
503 printf("\n*** No group set for Exim. Please review your build-time "
504 "configuration.\n\n");
505 return 1;
506 }
507
10385c15
PP
508 /* security sanity checks
509 if ref: is being used, we can never be sure, but we can take reasonable
510 steps to filter out the most obvious ones. */
511
512 if ((!uid_not_set && uid == 0) ||
513 (strcmp(username, "root") == 0) ||
514 (strcmp(username, "toor") == 0) )
515 {
516 printf("\n*** Exim's internal user must not be root.\n\n");
517 return 1;
518 }
519
059ec3d9
PH
520 /* Output user and group names or uid/gid. When names are set, uid/gid
521 are set to zero but will be replaced at runtime. */
522
523 if (username != NULL)
524 fprintf(new, "#define EXIM_USERNAME \"%s\"\n", username);
525 if (groupname != NULL)
526 fprintf(new, "#define EXIM_GROUPNAME \"%s\"\n", groupname);
527
528 fprintf(new, "#define EXIM_UID %d\n", (int)uid);
529 fprintf(new, "#define EXIM_GID %d\n", (int)gid);
530 continue;
531 }
532
35edf2ff
PH
533 /* CONFIGURE_OWNER and CONFIGURE_GROUP are special cases. We look in the
534 environment for first. If the value is not numeric, we look up the user or
535 group. A lot of this code is similar to that for EXIM_USER, but it's easier
536 to keep it separate. */
059ec3d9 537
35edf2ff
PH
538 if (strcmp(name, "CONFIGURE_OWNER") == 0 ||
539 strcmp(name, "CONFIGURE_GROUP") == 0)
059ec3d9 540 {
8e669ac1 541 int isgroup = name[10] == 'G';
059ec3d9 542 uid_t uid = 0;
8e669ac1 543 gid_t gid = 0;
059ec3d9
PH
544 char *s;
545 char *username = NULL;
35edf2ff 546 char *user = getenv(name);
059ec3d9
PH
547
548 if (user == NULL) user = "";
549 while (isspace((unsigned char)(*user))) user++;
550 if (*user == 0)
551 {
552 fprintf(new, "/* %s not set */\n", name);
553 continue;
554 }
555
556 for (s = user; *s != 0; s++)
557 {
558 if (iscntrl((unsigned char)(*s)))
559 {
35edf2ff 560 printf("\n*** %s contains the control character 0x%02X in "
059ec3d9 561 "one of the files\n in the \"Local\" directory. Please review "
35edf2ff 562 "your build-time\n configuration.\n\n", name, *s);
059ec3d9
PH
563 return 1;
564 }
565 }
566
567 /* Numeric uid given */
568
569 if (user[strspn(user, "0123456789")] == 0)
570 {
35edf2ff
PH
571 if (isgroup)
572 gid = (gid_t)atoi(user);
8e669ac1 573 else
35edf2ff 574 uid = (uid_t)atoi(user);
059ec3d9
PH
575 }
576
35edf2ff 577 /* Name given. Normally, we look up the uid or gid right away. However,
059ec3d9
PH
578 people building binary distributions sometimes want to retain the name till
579 runtime. This is supported if the name begins "ref:". */
580
581 else if (strncmp(user, "ref:", 4) == 0)
582 {
583 user += 4;
584 while (isspace(*user)) user++;
585 username = user;
586 }
587
35edf2ff
PH
588 else if (isgroup)
589 {
590 struct group *gr = getgrnam(user);
591 if (gr == NULL)
592 {
593 printf("\n*** Group \"%s\" (specified in one of the Makefiles) does not "
594 "exist.\n Please review your build-time configuration.\n\n",
595 user);
596 return 1;
597 }
598 gid = gr->gr_gid;
599 }
600
059ec3d9
PH
601 else
602 {
603 struct passwd *pw = getpwnam(user);
604 if (pw == NULL)
605 {
606 printf("\n*** User \"%s\" (specified in one of the Makefiles) does not "
607 "exist.\n Please review your build-time configuration.\n\n",
608 user);
609 return 1;
610 }
059ec3d9
PH
611 uid = pw->pw_uid;
612 }
613
614 /* Output user and group names or uid/gid. When names are set, uid/gid
615 are set to zero but will be replaced at runtime. */
616
617 if (username != NULL)
35edf2ff
PH
618 {
619 if (isgroup)
620 fprintf(new, "#define CONFIGURE_GROUPNAME \"%s\"\n", username);
8e669ac1 621 else
35edf2ff
PH
622 fprintf(new, "#define CONFIGURE_OWNERNAME \"%s\"\n", username);
623 }
8e669ac1 624
35edf2ff
PH
625 if (isgroup)
626 fprintf(new, "#define CONFIGURE_GROUP %d\n", (int)gid);
8e669ac1 627 else
35edf2ff 628 fprintf(new, "#define CONFIGURE_OWNER %d\n", (int)uid);
059ec3d9
PH
629 continue;
630 }
631
632 /* FIXED_NEVER_USERS is another special case. Look up the uid values and
633 create suitable initialization data for a vector. */
634
635 if (strcmp(name, "FIXED_NEVER_USERS") == 0)
636 {
637 char *list = getenv("FIXED_NEVER_USERS");
638 if (list == NULL)
639 {
640 fprintf(new, "#define FIXED_NEVER_USERS 0\n");
641 }
642 else
643 {
644 int count = 1;
926e1192 645 int i, j;
059ec3d9
PH
646 uid_t *vector;
647 char *p = list;
648 while (*p != 0) if (*p++ == ':') count++;
649
650 vector = malloc((count+1) * sizeof(uid_t));
651 vector[0] = (uid_t)count;
652
926e1192 653 for (i = 1, j = 0; i <= count; list++, i++)
059ec3d9
PH
654 {
655 char name[64];
8e669ac1 656
059ec3d9
PH
657 p = list;
658 while (*list != 0 && *list != ':') list++;
659 strncpy(name, p, list-p);
660 name[list-p] = 0;
8e669ac1 661
926e1192
PH
662 if (name[0] == 0)
663 {
8e669ac1
PH
664 continue;
665 }
926e1192 666 else if (name[strspn(name, "0123456789")] == 0)
059ec3d9 667 {
926e1192 668 vector[j++] = (uid_t)atoi(name);
059ec3d9
PH
669 }
670 else
671 {
672 struct passwd *pw = getpwnam(name);
673 if (pw == NULL)
674 {
675 printf("\n*** User \"%s\" (specified for FIXED_NEVER_USERS in one of the Makefiles) does not "
676 "exist.\n Please review your build-time configuration.\n\n",
677 name);
678 return 1;
679 }
926e1192 680 vector[j++] = pw->pw_uid;
059ec3d9
PH
681 }
682 }
926e1192
PH
683 fprintf(new, "#define FIXED_NEVER_USERS %d", j);
684 for (i = 0; i < j; i++) fprintf(new, ", %d", (unsigned int)vector[i]);
685 fprintf(new, "\n");
059ec3d9
PH
686 }
687 continue;
688 }
689
8e669ac1
PH
690 /* WITH_CONTENT_SCAN is another special case: it must be set if either it or
691 WITH_OLD_DEMIME is set. */
c6e692d7
PH
692
693 if (strcmp(name, "WITH_CONTENT_SCAN") == 0)
694 {
695 char *wcs = getenv("WITH_CONTENT_SCAN");
696 char *wod = getenv("WITH_OLD_DEMIME");
6a8f9482
TK
697 char *dcc = getenv("EXPERIMENTAL_DCC");
698 if (wcs != NULL || wod != NULL || dcc != NULL)
c6e692d7
PH
699 fprintf(new, "#define WITH_CONTENT_SCAN yes\n");
700 else fprintf(new, "/* WITH_CONTENT_SCAN not set */\n");
701 continue;
8e669ac1 702 }
c6e692d7 703
059ec3d9
PH
704 /* Otherwise, check whether a value exists in the environment. Remember if
705 it is an AUTH setting or SUPPORT_CRYPTEQ. */
706
707 if ((value = getenv(name)) != NULL)
708 {
709 int len;
710 len = 21 - (int)strlen(name);
711
712 if (strncmp(name, "AUTH_", 5) == 0) have_auth = 1;
713 if (strncmp(name, "SUPPORT_CRYPTEQ", 15) == 0) support_crypteq = 1;
714
715 /* The text value of LDAP_LIB_TYPE refers to a macro that gets set. */
716
717 if (strcmp(name, "LDAP_LIB_TYPE") == 0)
718 {
719 if (strcmp(value, "NETSCAPE") == 0 ||
720 strcmp(value, "UMICHIGAN") == 0 ||
721 strcmp(value, "OPENLDAP1") == 0 ||
722 strcmp(value, "OPENLDAP2") == 0 ||
723 strcmp(value, "SOLARIS") == 0 ||
724 strcmp(value, "SOLARIS7") == 0) /* Compatibility */
725 {
726 fprintf(new, "#define LDAP_LIB_%s\n", value);
727 }
728 else
729 {
730 printf("\n*** LDAP_LIB_TYPE=%s is not a recognized LDAP library type."
731 "\n*** Please review your build-time configuration.\n\n", value);
732 return 1;
733 }
734 }
735
736 else if (strcmp(name, "RADIUS_LIB_TYPE") == 0)
737 {
738 if (strcmp(value, "RADIUSCLIENT") == 0 ||
7766a4f0 739 strcmp(value, "RADIUSCLIENTNEW") == 0 ||
059ec3d9
PH
740 strcmp(value, "RADLIB") == 0)
741 {
742 fprintf(new, "#define RADIUS_LIB_%s\n", value);
743 }
744 else
745 {
746 printf("\n*** RADIUS_LIB_TYPE=%s is not a recognized RADIUS library type."
747 "\n*** Please review your build-time configuration.\n\n", value);
748 return 1;
749 }
750 }
751
752 /* Other macros get set to the environment value. */
753
754 else
755 {
756 fprintf(new, "#define %s ", name);
757 while(len-- > 0) fputc(' ', new);
758
759 /* LOG_FILE_PATH is now messy because it can be a path containing %s or
760 it can be "syslog" or ":syslog" or "syslog:path" or even "path:syslog". */
761
762 if (strcmp(name, "LOG_FILE_PATH") == 0)
763 {
764 char *ss = value;
765 for(;;)
766 {
767 char *pp;
768 char *sss = strchr(ss, ':');
769 if (sss != NULL)
770 {
771 strncpy(buffer, ss, sss-ss);
772 buffer[sss-ss] = 0; /* For empty case */
773 }
774 else strcpy(buffer, ss);
775 pp = buffer + (int)strlen(buffer);
776 while (pp > buffer && isspace((unsigned char)pp[-1])) pp--;
777 *pp = 0;
778 if (buffer[0] != 0 && strcmp(buffer, "syslog") != 0)
779 check_percent_ess(buffer, name);
780 if (sss == NULL) break;
781 ss = sss + 1;
782 while (isspace((unsigned char)*ss)) ss++;
783 }
784 fprintf(new, "\"%s\"\n", value);
785 }
786
787 /* Timezone values and HEADERS_CHARSET get quoted */
788
789 else if (strcmp(name, "TIMEZONE_DEFAULT") == 0||
790 strcmp(name, "HEADERS_CHARSET") == 0)
791 fprintf(new, "\"%s\"\n", value);
792
793 /* For others, quote any paths and don't quote anything else */
794
795 else
796 {
797 if (value[0] == '/') fprintf(new, "\"%s\"\n", value);
798 else fprintf(new, "%s\n", value);
799 }
800 }
801 }
802
803 /* Value not defined in the environment; use the default */
804
805 else
806 {
807 char *t = p;
808 while (*p == ' ' || *p == '\t') p++;
809 if (*p != '\n') fputs(buffer, new); else
810 {
811 *t = 0;
812 if (strcmp(name, "BIN_DIRECTORY") == 0 ||
813 strcmp(name, "CONFIGURE_FILE") == 0)
814 {
815 printf("\n*** %s has not been defined in any of the Makefiles in the\n"
816 " \"Local\" directory. "
817 "Please review your build-time configuration.\n\n", name);
818 return 1;
819 }
820
821 if (strcmp(name, "TIMEZONE_DEFAULT") == 0)
822 {
823 char *tz = getenv("TZ");
824 fprintf(new, "#define TIMEZONE_DEFAULT ");
825 if (tz == NULL) fprintf(new, "NULL\n"); else
826 fprintf(new, "\"%s\"\n", tz);
827 }
828
829 else fprintf(new, "/* %s not set */\n", name);
830 }
831 }
832 }
833
f1e894f3 834(void)fclose(base);
059ec3d9
PH
835
836/* If any AUTH macros were defined, ensure that SUPPORT_CRYPTEQ is also
837defined. */
838
839if (have_auth)
840 {
841 if (!support_crypteq) fprintf(new, "/* Force SUPPORT_CRYPTEQ for AUTH */\n"
842 "#define SUPPORT_CRYPTEQ\n");
843 }
844
845/* End off */
846
847fprintf(new, "\n/* End of config.h */\n");
f1e894f3 848(void)fclose(new);
059ec3d9
PH
849return 0;
850}
851
852/* End of buildconfig.c */