Added lots of "(void)" casts to standard function calls.
[exim.git] / src / src / buildconfig.c
1 /* $Cambridge: exim/src/src/buildconfig.c,v 1.10 2005/06/27 14:29:43 ph10 Exp $ */
2
3 /*************************************************
4 * Exim - an Internet mail transport agent *
5 *************************************************/
6
7 /* Copyright (c) University of Cambridge 1995 - 2005 */
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
16 process:
17
18 First, it determines the size of off_t and time_t variables, and generates
19 macro code to define OFF_T_FMT and TIME_T_FMT as suitable formats, if they are
20 not already defined in the system-specific header file.
21
22 Then it reads Makefile, looking for certain OS-specific definitions which it
23 uses to define some specific macros. Finally, it reads the defaults file
24 config.h.defaults.
25
26 The defaults file contains normal C #define statements for various macros; if
27 the name of a macro is found in the environment, the environment value replaces
28 the default. If the default #define does not contain any value, then that macro
29 is not copied to the created file unless there is some value in the
30 environment.
31
32 This program is compiled and run as part of the Make process and is not
33 normally 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
44 typedef struct {
45 char *name;
46 int *flag;
47 } have_item;
48
49 typedef struct {
50 char *name;
51 char *data;
52 } save_item;
53
54 static char *db_opts[] = { "", "USE_DB", "USE_GDBM", "USE_TDB" };
55
56 static int have_ipv6 = 0;
57 static int have_iconv = 0;
58
59 static char errno_quota[256];
60 static char ostype[256];
61 static char cc[256];
62
63 /* If any entry is an initial substring of another, the longer one must
64 appear first. */
65
66 static have_item have_list[] = {
67 { "HAVE_IPV6", &have_ipv6 },
68 { "HAVE_ICONV", &have_iconv },
69 { NULL, NULL}
70 };
71
72 static 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,
81 bomb out. */
82
83 void
84 check_percent_ess(char *value, char *name)
85 {
86 int OK = 0;
87 char *p = strstr(value, "%s");
88 if (p != NULL) OK = strstr(p+2, "%s") == NULL;
89 if (!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
101 int
102 main(int argc, char **argv)
103 {
104 off_t test_off_t = 0;
105 time_t test_time_t = 0;
106 FILE *base;
107 FILE *new;
108 int last_initial = 'A';
109 int linecount = 0;
110 int have_auth = 0;
111 int in_local_makefile = 0;
112 int use_which_db = 0;
113 int use_which_db_in_local_makefile = 0;
114 int support_crypteq = 0;
115 char buffer[1024];
116
117 if (argc != 1)
118 {
119 printf("*** Buildconfig: called with incorrect arguments\n");
120 exit(1);
121 }
122
123 new = fopen("config.h", "wb");
124 if (new == NULL)
125 {
126 printf("*** Buildconfig: failed to open config.h for output\n");
127 exit(1);
128 }
129
130 printf("Building configuration file config.h\n");
131
132 fprintf(new, "/*************************************************\n");
133 fprintf(new, "* Configuration header for Exim *\n");
134 fprintf(new, "*************************************************/\n\n");
135
136 fprintf(new, "/* This file was automatically generated from Makefile and "
137 "config.h.defaults,\n");
138 fprintf(new, "using values specified in the configuration file Local/Makefile.\n");
139 fprintf(new, "Do not edit it. Instead, edit Local/Makefile and "
140 "rerun make. */\n\n");
141
142 /* First, deal with the printing format for off_t variables. We assume that if
143 the size of off_t is greater than 4, "%lld" will be available as a format for
144 printing long long variables, and there will be support for the long long type.
145 This assumption is known to be OK for the common operating systems. */
146
147 fprintf(new, "#ifndef OFF_T_FMT\n");
148 if (sizeof(test_off_t) > 4)
149 {
150 fprintf(new, "#define OFF_T_FMT \"%%lld\"\n");
151 fprintf(new, "#define LONGLONG_T long long int\n");
152 }
153 else
154 {
155 fprintf(new, "#define OFF_T_FMT \"%%ld\"\n");
156 fprintf(new, "#define LONGLONG_T long int\n");
157 }
158 fprintf(new, "#endif\n\n");
159
160 /* Now do the same thing for time_t variables. If the length is greater than
161 4, we want to assume long long support (even if off_t was less than 4). If the
162 length is 4 or less, we can leave LONGLONG_T to whatever was defined above for
163 off_t. */
164
165 fprintf(new, "#ifndef TIME_T_FMT\n");
166 if (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 }
172 else
173 {
174 fprintf(new, "#define TIME_T_FMT \"%%ld\"\n");
175 }
176 fprintf(new, "#endif\n\n");
177
178 /* Now search the makefile for certain settings */
179
180 base = fopen("Makefile", "rb");
181 if (base == NULL)
182 {
183 printf("*** Buildconfig: failed to open Makefile\n");
184 (void)fclose(new);
185 exit(1);
186 }
187
188 errno_quota[0] = 0; /* no over-riding value set */
189 ostype[0] = 0; /* just in case */
190 cc[0] = 0;
191
192 while (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
279 fprintf(new, "#define HAVE_IPV6 %s\n",
280 have_ipv6? "TRUE" : "FALSE");
281
282 fprintf(new, "#define HAVE_ICONV %s\n",
283 have_iconv? "TRUE" : "FALSE");
284
285 if (errno_quota[0] != 0)
286 fprintf(new, "\n#define ERRNO_QUOTA %s\n", errno_quota);
287
288 if (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
295 fprintf(new, "\n");
296 (void)fclose(base);
297
298
299 /* Now handle the macros listed in the defaults */
300
301 base = fopen("../src/config.h.defaults", "rb");
302 if (base == NULL)
303 {
304 printf("*** Buildconfig: failed to open ../src/config.h.defaults\n");
305 (void)fclose(new);
306 exit(1);
307 }
308
309 while (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
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. */
522
523 if (strcmp(name, "CONFIGURE_OWNER") == 0 ||
524 strcmp(name, "CONFIGURE_GROUP") == 0)
525 {
526 int isgroup = name[10] == 'G';
527 uid_t uid = 0;
528 gid_t gid = 0;
529 char *s;
530 char *username = NULL;
531 char *user = getenv(name);
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 {
545 printf("\n*** %s contains the control character 0x%02X in "
546 "one of the files\n in the \"Local\" directory. Please review "
547 "your build-time\n configuration.\n\n", name, *s);
548 return 1;
549 }
550 }
551
552 /* Numeric uid given */
553
554 if (user[strspn(user, "0123456789")] == 0)
555 {
556 if (isgroup)
557 gid = (gid_t)atoi(user);
558 else
559 uid = (uid_t)atoi(user);
560 }
561
562 /* Name given. Normally, we look up the uid or gid right away. However,
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
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
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 }
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)
603 {
604 if (isgroup)
605 fprintf(new, "#define CONFIGURE_GROUPNAME \"%s\"\n", username);
606 else
607 fprintf(new, "#define CONFIGURE_OWNERNAME \"%s\"\n", username);
608 }
609
610 if (isgroup)
611 fprintf(new, "#define CONFIGURE_GROUP %d\n", (int)gid);
612 else
613 fprintf(new, "#define CONFIGURE_OWNER %d\n", (int)uid);
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;
630 int i, j;
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
638 for (i = 1, j = 0; i <= count; list++, i++)
639 {
640 char name[64];
641
642 p = list;
643 while (*list != 0 && *list != ':') list++;
644 strncpy(name, p, list-p);
645 name[list-p] = 0;
646
647 if (name[0] == 0)
648 {
649 continue;
650 }
651 else if (name[strspn(name, "0123456789")] == 0)
652 {
653 vector[j++] = (uid_t)atoi(name);
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 }
665 vector[j++] = pw->pw_uid;
666 }
667 }
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");
671 }
672 continue;
673 }
674
675 /* WITH_CONTENT_SCAN is another special case: it must be set if either it or
676 WITH_OLD_DEMIME is set. */
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;
686 }
687
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 ||
723 strcmp(value, "RADIUSCLIENTNEW") == 0 ||
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
818 (void)fclose(base);
819
820 /* If any AUTH macros were defined, ensure that SUPPORT_CRYPTEQ is also
821 defined. */
822
823 if (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
831 fprintf(new, "\n/* End of config.h */\n");
832 (void)fclose(new);
833 return 0;
834 }
835
836 /* End of buildconfig.c */