Added lots of "(void)" casts to standard function calls.
[exim.git] / src / src / buildconfig.c
CommitLineData
f1e894f3 1/* $Cambridge: exim/src/src/buildconfig.c,v 1.10 2005/06/27 14:29:43 ph10 Exp $ */
059ec3d9
PH
2
3/*************************************************
4* Exim - an Internet mail transport agent *
5*************************************************/
6
c988f1f4 7/* Copyright (c) University of Cambridge 1995 - 2005 */
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
288if (strcmp(cc, "gcc") == 0 && strstr(ostype, "IRIX") != NULL)
289 {
290 fprintf(new, "\n/* This switch includes the code to fix the inet_ntoa() */");
291 fprintf(new, "\n/* bug when using gcc on an IRIX system. */");
292 fprintf(new, "\n#define USE_INET_NTOA_FIX");
293 }
294
295fprintf(new, "\n");
f1e894f3 296(void)fclose(base);
059ec3d9
PH
297
298
299/* Now handle the macros listed in the defaults */
300
301base = fopen("../src/config.h.defaults", "rb");
302if (base == NULL)
303 {
304 printf("*** Buildconfig: failed to open ../src/config.h.defaults\n");
f1e894f3 305 (void)fclose(new);
059ec3d9
PH
306 exit(1);
307 }
308
309while (fgets(buffer, sizeof(buffer), base) != NULL)
310 {
311 int i;
312 char name[256];
313 char *value;
314 char *p = buffer;
315 char *q = name;
316
317 while (*p == ' ' || *p == '\t') p++;
318
319 if (strncmp(p, "#define ", 8) != 0) continue;
320
321 p += 8;
322 while (*p == ' ' || *p == '\t') p++;
323
324 if (*p < last_initial) fprintf(new, "\n");
325 last_initial = *p;
326
327 while (*p && (isalnum((unsigned char)*p) || *p == '_')) *q++ = *p++;
328 *q = 0;
329
330 /* USE_DB, USE_GDBM, and USE_TDB are special cases. We want to have only
331 one of them set. The scan of the Makefile has saved which was the last one
332 encountered. */
333
334 for (i = 1; i < sizeof(db_opts)/sizeof(char *); i++)
335 {
336 if (strcmp(name, db_opts[i]) == 0)
337 {
338 if (use_which_db == i)
339 fprintf(new, "#define %s %.*syes\n", db_opts[i],
340 21 - (int)strlen(db_opts[i]), " ");
341 else
342 fprintf(new, "/* %s not set */\n", name);
343 break;
344 }
345 }
346 if (i < sizeof(db_opts)/sizeof(char *)) continue;
347
348 /* EXIM_USER is a special case. We look in the environment for EXIM_USER or
349 EXIM_UID (the latter for backward compatibility with Exim 3). If the value is
350 not numeric, we look up the user, and default the GID if found. Otherwise,
351 EXIM_GROUP or EXIM_GID must be in the environment. */
352
353 if (strcmp(name, "EXIM_UID") == 0)
354 {
355 uid_t uid = 0;
356 gid_t gid = 0;
357 int gid_set = 0;
358 char *username = NULL;
359 char *groupname = NULL;
360 char *s;
361 char *user = getenv("EXIM_USER");
362 char *group = getenv("EXIM_GROUP");
363
364 if (user == NULL) user = getenv("EXIM_UID");
365 if (group == NULL) group = getenv("EXIM_GID");
366
367 if (user == NULL)
368 {
369 printf("\n*** EXIM_USER has not been defined in any of the Makefiles in "
370 "the\n \"Local\" directory. Please review your build-time "
371 "configuration.\n\n");
372 return 1;
373 }
374
375 while (isspace((unsigned char)(*user))) user++;
376 if (*user == 0)
377 {
378 printf("\n*** EXIM_USER is defined as an empty string in one of the "
379 "files\n in the \"Local\" directory. Please review your build-time"
380 "\n configuration.\n\n");
381 return 1;
382 }
383
384 for (s = user; *s != 0; s++)
385 {
386 if (iscntrl((unsigned char)(*s)))
387 {
388 printf("\n*** EXIM_USER contains the control character 0x%02X in one "
389 "of the files\n in the \"Local\" directory. Please review your "
390 "build-time\n configuration.\n\n", *s);
391 return 1;
392 }
393 }
394
395 /* Numeric uid given */
396
397 if (user[strspn(user, "0123456789")] == 0)
398 {
399 uid = (uid_t)atoi(user);
400 }
401
402 /* User name given. Normally, we look up the uid right away. However,
403 people building binary distributions sometimes want to retain the name till
404 runtime. This is supported if the name begins "ref:". */
405
406 else if (strncmp(user, "ref:", 4) == 0)
407 {
408 user += 4;
409 while (isspace(*user)) user++;
410 username = user;
411 gid_set = 1;
412 }
413
414 else
415 {
416 struct passwd *pw = getpwnam(user);
417 if (pw == NULL)
418 {
419 printf("\n*** User \"%s\" (specified in one of the Makefiles) does not "
420 "exist.\n Please review your build-time configuration.\n\n",
421 user);
422 return 1;
423 }
424
425 uid = pw->pw_uid;
426 gid = pw->pw_gid;
427 gid_set = 1;
428 }
429
430 /* Use explicit group if set. */
431
432 if (group != NULL)
433 {
434 while (isspace((unsigned char)(*group))) group++;
435 if (*group == 0)
436 {
437 printf("\n*** EXIM_GROUP is defined as an empty string in one of "
438 "the files in the\n \"Local\" directory. ");
439 if (gid_set)
440 {
441 printf("If you want the Exim group to be taken from the\n "
442 "password data for the Exim user, just remove the EXIM_GROUP "
443 "setting.\n Otherwise, p");
444 }
445 else printf("EXIM_USER is defined numerically, so there is no"
446 "\n default for EXIM_GROUP and you must set it explicitly.\n P");
447 printf("lease review your build-time configuration.\n\n");
448 return 1;
449 }
450
451 for (s = group; *s != 0; s++)
452 {
453 if (iscntrl((unsigned char)(*s)))
454 {
455 printf("\n*** EXIM_GROUP contains the control character 0x%02X in one "
456 "of the files\n in the \"Local\" directory. Please review your "
457 "build-time\n configuration.\n\n", *s);
458 return 1;
459 }
460 }
461
462 /* Group name given. This may be by reference or to be looked up now,
463 as for user. */
464
465 if (strncmp(group, "ref:", 4) == 0)
466 {
467 group += 4;
468 while (isspace(*group)) group++;
469 groupname = group;
470 }
471
472 else if (username != NULL)
473 {
474 groupname = group;
475 }
476
477 else if (group[strspn(group, "0123456789")] == 0)
478 {
479 gid = (gid_t)atoi(group);
480 }
481
482 else
483 {
484 struct group *gr = getgrnam(group);
485 if (gr == NULL)
486 {
487 printf("\n*** Group \"%s\" (specified in one of the Makefiles) does "
488 "not exist.\n Please review your build-time configuration.\n\n",
489 group);
490 return 1;
491 }
492 gid = gr->gr_gid;
493 }
494 }
495
496 /* Else trouble unless found in passwd file with user */
497
498 else if (!gid_set)
499 {
500 printf("\n*** No group set for Exim. Please review your build-time "
501 "configuration.\n\n");
502 return 1;
503 }
504
505 /* Output user and group names or uid/gid. When names are set, uid/gid
506 are set to zero but will be replaced at runtime. */
507
508 if (username != NULL)
509 fprintf(new, "#define EXIM_USERNAME \"%s\"\n", username);
510 if (groupname != NULL)
511 fprintf(new, "#define EXIM_GROUPNAME \"%s\"\n", groupname);
512
513 fprintf(new, "#define EXIM_UID %d\n", (int)uid);
514 fprintf(new, "#define EXIM_GID %d\n", (int)gid);
515 continue;
516 }
517
35edf2ff
PH
518 /* CONFIGURE_OWNER and CONFIGURE_GROUP are special cases. We look in the
519 environment for first. If the value is not numeric, we look up the user or
520 group. A lot of this code is similar to that for EXIM_USER, but it's easier
521 to keep it separate. */
059ec3d9 522
35edf2ff
PH
523 if (strcmp(name, "CONFIGURE_OWNER") == 0 ||
524 strcmp(name, "CONFIGURE_GROUP") == 0)
059ec3d9 525 {
8e669ac1 526 int isgroup = name[10] == 'G';
059ec3d9 527 uid_t uid = 0;
8e669ac1 528 gid_t gid = 0;
059ec3d9
PH
529 char *s;
530 char *username = NULL;
35edf2ff 531 char *user = getenv(name);
059ec3d9
PH
532
533 if (user == NULL) user = "";
534 while (isspace((unsigned char)(*user))) user++;
535 if (*user == 0)
536 {
537 fprintf(new, "/* %s not set */\n", name);
538 continue;
539 }
540
541 for (s = user; *s != 0; s++)
542 {
543 if (iscntrl((unsigned char)(*s)))
544 {
35edf2ff 545 printf("\n*** %s contains the control character 0x%02X in "
059ec3d9 546 "one of the files\n in the \"Local\" directory. Please review "
35edf2ff 547 "your build-time\n configuration.\n\n", name, *s);
059ec3d9
PH
548 return 1;
549 }
550 }
551
552 /* Numeric uid given */
553
554 if (user[strspn(user, "0123456789")] == 0)
555 {
35edf2ff
PH
556 if (isgroup)
557 gid = (gid_t)atoi(user);
8e669ac1 558 else
35edf2ff 559 uid = (uid_t)atoi(user);
059ec3d9
PH
560 }
561
35edf2ff 562 /* Name given. Normally, we look up the uid or gid right away. However,
059ec3d9
PH
563 people building binary distributions sometimes want to retain the name till
564 runtime. This is supported if the name begins "ref:". */
565
566 else if (strncmp(user, "ref:", 4) == 0)
567 {
568 user += 4;
569 while (isspace(*user)) user++;
570 username = user;
571 }
572
35edf2ff
PH
573 else if (isgroup)
574 {
575 struct group *gr = getgrnam(user);
576 if (gr == NULL)
577 {
578 printf("\n*** Group \"%s\" (specified in one of the Makefiles) does not "
579 "exist.\n Please review your build-time configuration.\n\n",
580 user);
581 return 1;
582 }
583 gid = gr->gr_gid;
584 }
585
059ec3d9
PH
586 else
587 {
588 struct passwd *pw = getpwnam(user);
589 if (pw == NULL)
590 {
591 printf("\n*** User \"%s\" (specified in one of the Makefiles) does not "
592 "exist.\n Please review your build-time configuration.\n\n",
593 user);
594 return 1;
595 }
059ec3d9
PH
596 uid = pw->pw_uid;
597 }
598
599 /* Output user and group names or uid/gid. When names are set, uid/gid
600 are set to zero but will be replaced at runtime. */
601
602 if (username != NULL)
35edf2ff
PH
603 {
604 if (isgroup)
605 fprintf(new, "#define CONFIGURE_GROUPNAME \"%s\"\n", username);
8e669ac1 606 else
35edf2ff
PH
607 fprintf(new, "#define CONFIGURE_OWNERNAME \"%s\"\n", username);
608 }
8e669ac1 609
35edf2ff
PH
610 if (isgroup)
611 fprintf(new, "#define CONFIGURE_GROUP %d\n", (int)gid);
8e669ac1 612 else
35edf2ff 613 fprintf(new, "#define CONFIGURE_OWNER %d\n", (int)uid);
059ec3d9
PH
614 continue;
615 }
616
617 /* FIXED_NEVER_USERS is another special case. Look up the uid values and
618 create suitable initialization data for a vector. */
619
620 if (strcmp(name, "FIXED_NEVER_USERS") == 0)
621 {
622 char *list = getenv("FIXED_NEVER_USERS");
623 if (list == NULL)
624 {
625 fprintf(new, "#define FIXED_NEVER_USERS 0\n");
626 }
627 else
628 {
629 int count = 1;
926e1192 630 int i, j;
059ec3d9
PH
631 uid_t *vector;
632 char *p = list;
633 while (*p != 0) if (*p++ == ':') count++;
634
635 vector = malloc((count+1) * sizeof(uid_t));
636 vector[0] = (uid_t)count;
637
926e1192 638 for (i = 1, j = 0; i <= count; list++, i++)
059ec3d9
PH
639 {
640 char name[64];
8e669ac1 641
059ec3d9
PH
642 p = list;
643 while (*list != 0 && *list != ':') list++;
644 strncpy(name, p, list-p);
645 name[list-p] = 0;
8e669ac1 646
926e1192
PH
647 if (name[0] == 0)
648 {
8e669ac1
PH
649 continue;
650 }
926e1192 651 else if (name[strspn(name, "0123456789")] == 0)
059ec3d9 652 {
926e1192 653 vector[j++] = (uid_t)atoi(name);
059ec3d9
PH
654 }
655 else
656 {
657 struct passwd *pw = getpwnam(name);
658 if (pw == NULL)
659 {
660 printf("\n*** User \"%s\" (specified for FIXED_NEVER_USERS in one of the Makefiles) does not "
661 "exist.\n Please review your build-time configuration.\n\n",
662 name);
663 return 1;
664 }
926e1192 665 vector[j++] = pw->pw_uid;
059ec3d9
PH
666 }
667 }
926e1192
PH
668 fprintf(new, "#define FIXED_NEVER_USERS %d", j);
669 for (i = 0; i < j; i++) fprintf(new, ", %d", (unsigned int)vector[i]);
670 fprintf(new, "\n");
059ec3d9
PH
671 }
672 continue;
673 }
674
8e669ac1
PH
675 /* WITH_CONTENT_SCAN is another special case: it must be set if either it or
676 WITH_OLD_DEMIME is set. */
c6e692d7
PH
677
678 if (strcmp(name, "WITH_CONTENT_SCAN") == 0)
679 {
680 char *wcs = getenv("WITH_CONTENT_SCAN");
681 char *wod = getenv("WITH_OLD_DEMIME");
682 if (wcs != NULL || wod != NULL)
683 fprintf(new, "#define WITH_CONTENT_SCAN yes\n");
684 else fprintf(new, "/* WITH_CONTENT_SCAN not set */\n");
685 continue;
8e669ac1 686 }
c6e692d7 687
059ec3d9
PH
688 /* Otherwise, check whether a value exists in the environment. Remember if
689 it is an AUTH setting or SUPPORT_CRYPTEQ. */
690
691 if ((value = getenv(name)) != NULL)
692 {
693 int len;
694 len = 21 - (int)strlen(name);
695
696 if (strncmp(name, "AUTH_", 5) == 0) have_auth = 1;
697 if (strncmp(name, "SUPPORT_CRYPTEQ", 15) == 0) support_crypteq = 1;
698
699 /* The text value of LDAP_LIB_TYPE refers to a macro that gets set. */
700
701 if (strcmp(name, "LDAP_LIB_TYPE") == 0)
702 {
703 if (strcmp(value, "NETSCAPE") == 0 ||
704 strcmp(value, "UMICHIGAN") == 0 ||
705 strcmp(value, "OPENLDAP1") == 0 ||
706 strcmp(value, "OPENLDAP2") == 0 ||
707 strcmp(value, "SOLARIS") == 0 ||
708 strcmp(value, "SOLARIS7") == 0) /* Compatibility */
709 {
710 fprintf(new, "#define LDAP_LIB_%s\n", value);
711 }
712 else
713 {
714 printf("\n*** LDAP_LIB_TYPE=%s is not a recognized LDAP library type."
715 "\n*** Please review your build-time configuration.\n\n", value);
716 return 1;
717 }
718 }
719
720 else if (strcmp(name, "RADIUS_LIB_TYPE") == 0)
721 {
722 if (strcmp(value, "RADIUSCLIENT") == 0 ||
7766a4f0 723 strcmp(value, "RADIUSCLIENTNEW") == 0 ||
059ec3d9
PH
724 strcmp(value, "RADLIB") == 0)
725 {
726 fprintf(new, "#define RADIUS_LIB_%s\n", value);
727 }
728 else
729 {
730 printf("\n*** RADIUS_LIB_TYPE=%s is not a recognized RADIUS library type."
731 "\n*** Please review your build-time configuration.\n\n", value);
732 return 1;
733 }
734 }
735
736 /* Other macros get set to the environment value. */
737
738 else
739 {
740 fprintf(new, "#define %s ", name);
741 while(len-- > 0) fputc(' ', new);
742
743 /* LOG_FILE_PATH is now messy because it can be a path containing %s or
744 it can be "syslog" or ":syslog" or "syslog:path" or even "path:syslog". */
745
746 if (strcmp(name, "LOG_FILE_PATH") == 0)
747 {
748 char *ss = value;
749 for(;;)
750 {
751 char *pp;
752 char *sss = strchr(ss, ':');
753 if (sss != NULL)
754 {
755 strncpy(buffer, ss, sss-ss);
756 buffer[sss-ss] = 0; /* For empty case */
757 }
758 else strcpy(buffer, ss);
759 pp = buffer + (int)strlen(buffer);
760 while (pp > buffer && isspace((unsigned char)pp[-1])) pp--;
761 *pp = 0;
762 if (buffer[0] != 0 && strcmp(buffer, "syslog") != 0)
763 check_percent_ess(buffer, name);
764 if (sss == NULL) break;
765 ss = sss + 1;
766 while (isspace((unsigned char)*ss)) ss++;
767 }
768 fprintf(new, "\"%s\"\n", value);
769 }
770
771 /* Timezone values and HEADERS_CHARSET get quoted */
772
773 else if (strcmp(name, "TIMEZONE_DEFAULT") == 0||
774 strcmp(name, "HEADERS_CHARSET") == 0)
775 fprintf(new, "\"%s\"\n", value);
776
777 /* For others, quote any paths and don't quote anything else */
778
779 else
780 {
781 if (value[0] == '/') fprintf(new, "\"%s\"\n", value);
782 else fprintf(new, "%s\n", value);
783 }
784 }
785 }
786
787 /* Value not defined in the environment; use the default */
788
789 else
790 {
791 char *t = p;
792 while (*p == ' ' || *p == '\t') p++;
793 if (*p != '\n') fputs(buffer, new); else
794 {
795 *t = 0;
796 if (strcmp(name, "BIN_DIRECTORY") == 0 ||
797 strcmp(name, "CONFIGURE_FILE") == 0)
798 {
799 printf("\n*** %s has not been defined in any of the Makefiles in the\n"
800 " \"Local\" directory. "
801 "Please review your build-time configuration.\n\n", name);
802 return 1;
803 }
804
805 if (strcmp(name, "TIMEZONE_DEFAULT") == 0)
806 {
807 char *tz = getenv("TZ");
808 fprintf(new, "#define TIMEZONE_DEFAULT ");
809 if (tz == NULL) fprintf(new, "NULL\n"); else
810 fprintf(new, "\"%s\"\n", tz);
811 }
812
813 else fprintf(new, "/* %s not set */\n", name);
814 }
815 }
816 }
817
f1e894f3 818(void)fclose(base);
059ec3d9
PH
819
820/* If any AUTH macros were defined, ensure that SUPPORT_CRYPTEQ is also
821defined. */
822
823if (have_auth)
824 {
825 if (!support_crypteq) fprintf(new, "/* Force SUPPORT_CRYPTEQ for AUTH */\n"
826 "#define SUPPORT_CRYPTEQ\n");
827 }
828
829/* End off */
830
831fprintf(new, "\n/* End of config.h */\n");
f1e894f3 832(void)fclose(new);
059ec3d9
PH
833return 0;
834}
835
836/* End of buildconfig.c */