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