1#! /bin/sh 2: 3# Copyright (c) 1990-1997, S.R. van den Berg, The Netherlands 4#$Id: autoconf,v 1.136 2001/08/10 18:52:30 guenther Exp $ 5 6# All possible entries in autoconf.h: 7 8# #define UNISTD_H_MISSING 9# #define STDDEF_H_MISSING 10# #define STDLIB_H_MISSING 11# #define DIRENT_H_MISSING 12# #define SYS_DIRENT_H_MISSING 13# #define NDIR_H_MISSING 14# #define SYS_NDIR_H_MISSING 15# #define SYS_DIR_H_MISSING 16# #define SYS_WAIT_H_MISSING 17# #define SYS_UTSNAME_H_MISSING 18# #define STRING_H_MISSING 19# #define SYSEXITS_H_MISSING 20#Ok #define SYS_FILE_H_MISSING 21#Ok #define SYSLOG_H_MISSING 22# #define MATH_H_MISSING 23# #define LIMITS_H_MISSING 24# #define NO_const 25# #define volatile 26# #define P(args) () 27# #define NO_enum 28# #define void char 29# typedef int mode_t; 30# typedef int pid_t; 31# typedef int uid_t; 32# typedef int gid_t; 33# typedef unsigned size_t; 34# typedef long off_t; 35# typedef long time_t; 36# #define NOmemmove 37#Ok #define NObcopy 38# #define NOstrcspn 39# #define NOstrpbrk 40# #define NOopendir 41# #define NOrename 42# #define NOsetrgid 43# #define NOsetegid 44# #define NOsetregid 45# #define NOsetresgid 46# #define setrgid_BRAIN_DAMAGE 47# #define setrgid_RUNTIME_CHECK 48#Ok #define TOGGLE_SGID_OK 49# #define NOpow 50# #define NOmkdir 51# #define NOfstat 52# #define NOuname 53# #define NO_exit 54# #define NOstrtol 55# #define NOstrtod 56# #define NOstrerror 57#Ok #define NOstrlcat 58#Ok #define NOstrncasecmp 59#Ok #define NOsys_errlist 60#Ok #define NObzero 61# #define NOmemset 62# #define NOwaitpid 63#Ok #define NOftruncate 64# #define SLOWstrstr 65#Ok #define CAN_chown 66# #define strchr(s,c) index(s,c) 67# #define NOinitgroups 68# #define NOfsync 69#Ok #define endpwent() 70#Ok #define endgrent() 71#Ok #define endhostent() 72#Ok #define endservent() 73#Ok #define endprotoent() 74# #define h_0addr_list h_addr 75#Ok #define NOpw_passwd 76#Ok #define NOpw_class 77#Ok #define NOpw_gecos 78#Ok #define NO_COMSAT 79# #define _GUID_T 80#Ok #define UDP_protocolno 17 81#Ok #define BIFF_serviceport "512" 82#Ok #define IP_localhost {127,0,0,1} 83# #define WMACROS_NON_POSIX 84# #define oBRAIN_DAMAGE 85#Ok #define GOT_bin_test 86#Ok #define MAX_argc 128 87#Ok #define MAX_envc 128 88#Ok #define SMALLHEAP 89# #define NOfcntl_lock 90#Ok #define USElockf 91#Ok #define USEflock 92#Ok #define MAILSPOOLDIR "/var/spool/mail/" 93#Ok #define SENDMAIL "/usr/sbin/sendmail" 94# #define buggy_SENDMAIL 95# #define DEFflagsendmail "" 96#Ok #define CF_no_procmail_yet 97#Ok #define defSPATH "PATH=/bin:/usr/bin:/usr/local/bin" 98#Ok #define defPATH "PATH=$HOME/bin:/bin:/usr/bin:/usr/local/bin" 99#Ok #define INEFFICIENTrealloc 100#Ok #define PM_VERSION "n.nn" 101 102# A conforming ISO C compiler and POSIX library should not have any defines 103# not marked as "Ok" in the autoconf.h file. 104# Anything else indicates failure of your system to comply with either 105# the ISO or POSIX standards (but procmail should be installable anyway). 106 107if test -z "$IFS" 108then IFS=" \ 109 \ 110 111" 112 export IFS 113fi 114 115SHELL=$1 116PATH=.:$PATH 117shift; RM="$1" 118shift; MV="$1" 119shift; DEVNULL=$1 120shift; FGREP="$1" 121shift; MAKE="$1" 122shift; O=$1 123shift; LOCKINGTEST="$1" 124shift; BINDIR=$1 125shift; ACONF=$1 126 127test 1 != $# && 128 echo "Don't start this script directly, use \`make ../autoconf.h'" && exit 1 129 130if test -f make_n 131then 132 $RM make_n 133else 134 # We were mistakenly invoked under "make -n", so pretend this didn't happen. 135 exit 0 136fi 137 138export SHELL PATH 139 140test "X$LOCKINGTEST" = X__defaults__ && LOCKINGTEST="" 141 142OLDTESTDIRS="" 143tailpid="" 144echo "" >_locktst.pid 145 146if test -f $ACONF 147then 148 if $FGREP -e "/* autoconf completed */" $ACONF >$DEVNULL 149 then 150 cat <<HERE 151============================================================================== 152Would you like to skip running autoconf and use the existing autoconf.h file? 153When in doubt, press return [n]: 154HERE 155 read a 156 case "$a"n in 157 [yY]*) touch $ACONF; exit 0;; 158 esac 159 fi 160 trap "kill \`cat _locktst.pid\` 2>$DEVNULL;cp $ACONF $ACONF.tmp 161 test ! -z \"\$OLDTESTDIRS\" && $RM -r \$OLDTESTDIRS \$OLDTESTDIRS 2>$DEVNULL 162 test ! -z \"\$tailpid\" && kill \$tailpid 2>$DEVNULL 163 kill \`cat _locktst.pid\` 2>$DEVNULL; exit 1" 1 2 3 13 15 164else 165 trap "kill \`cat _locktst.pid\` 2>$DEVNULL;$RM -r $ACONF.tmp 166 test ! -z \"\$OLDTESTDIRS\" && $RM -r \$OLDTESTDIRS \$OLDTESTDIRS 2>$DEVNULL 167 mv $ACONF $ACONF.tmp 2>$DEVNULL 168 test ! -z \"\$tailpid\" && kill \$tailpid 2>$DEVNULL 169 kill \`cat _locktst.pid\` 2>$DEVNULL; exit 1" 1 2 3 13 15 170fi 171 172nocore=yes 173set dummy *core* 174test -f $2 && nocore=no 175 176set dummy $LOCKINGTEST 177shift 178LOCKINGTEST="$*" 179 180test ! -z "$LOCKINGTEST" && exec 9>&1 1>$DEVNULL # make it shut up 181 182cat <<HERE 183============================================================================== 184In order for the kernel-locking tests to work as intended I have to be able to 185test-lock files on as many semantically different filesystems as possible (for 186more information about this, READ PARAGRAPH TWO in INSTALL). To suppress this 187prompt you can set the LOCKINGTEST variable in the Makefile. 188 189Please add writable directories to the list. You should only add directories 190that reside on filesystems that have unique characteristics. E.g. if you have 191several remote NFS partitions, pick some unique client-server pairs, there is 192little use in picking the same server twice from the same client-machine. 193An excellent candidate would be a remotely mounted mail spool directory. 194============================================================================== 195HERE 196 197testdirs="/tmp ." 198 199case "$LOCKINGTEST" in 200 ""|*[a-zA-Z/]*) b=dummy ;; 201 *) b=""; testdirs=$LOCKINGTEST; LOCKINGTEST=dummy ;; 202esac 203 204while test ! -z "$b" 205do 206 echo "" 207 b="" 208 OLDTESTDIRS="$TESTDIRS" 209 TESTDIRS="" 210 for a in $testdirs 211 do $RM -r $a/_locktest 212 if mkdir $a/_locktest 2>$DEVNULL 213 then 214 b="$b $a" 215 TESTDIRS="$TESTDIRS $a/_locktest" 216 else 217 echo 2>&1 "Can't create $a/_locktest" 218 fi 219 done 220 OLDTESTDIRS="$TESTDIRS" 221 testdirs="$b" 222 echo "" 223 echo "I will temporarily use a testdirectory named _locktest" 224 echo "in the following directories:" 225 echo "" 226 echo $testdirs 227 echo "" 228 echo "If you would like to add any, please specify them below," 229 echo "press return to continue:" 230 echo "" 231 if test -z "$LOCKINGTEST" 232 then 233 #read b 234 b="" 235 elif test dummy = "$LOCKINGTEST" 236 then 237 b="" 238 else 239 testdirs=""; b="$LOCKINGTEST"; LOCKINGTEST=dummy 240 echo $b 241 fi 242 testdirs="$testdirs $b" 243done 244 245if test dummy = "$LOCKINGTEST" 246then 247 exec 1>&9 9>&- # you can speak again 248 echo "Using the following directories for the LOCKINGTESTs:" 249 echo " $testdirs" 250fi 251 252cat >grepfor <<HERE 253$FGREP -e "\$1" _autotst.rrr >$DEVNULL && echo "\$2" >>$ACONF 254HERE 255chmod 0755 grepfor 256 257cat >$ACONF <<HERE 258/* This file was automagically generated by autoconf */ 259 260HERE 261 262echo >_locktst.h 263 264$RM _autotst.$O 265 266cat >_autotst.c <<HERE 267#include "$ACONF" 268#include <sys/types.h> 269#include <time.h> 270void*vvoid; 271int main(){int i=0;char*p="t"; 272 vvoid=p; 273 {time_t vtime;i+=vtime=1;} 274 {off_t voff;i+=voff=1;} 275 return !vvoid+!i;} 276#include <unistd.h> 277int empty() 278{ return setsid(); 279} 280HERE 281 282if $MAKE _autotst.$O 2>&1 | $FGREP -v include/ >_autotst.rrr 283 test -f _autotst.$O 284then 285 $MAKE _autotst >$DEVNULL 2>&1 || echo "#define setsid()" >>_locktst.h 286else 287 grepfor void '#define void char' 288 grepfor time_t 'typedef long time_t;' 289 grepfor off_t 'typedef long off_t;' 290 if $MAKE _autotst.$O >$DEVNULL 2>&1 291 then 292 $MAKE _autotst >$DEVNULL 2>&1 || echo "#define setsid()" >>_locktst.h 293 else 294 echo "#define UNISTD_H_MISSING" >>$ACONF 295 echo "#define setsid()" >>_locktst.h 296 fi 297fi 298 299$RM _autotst.$O _autotst 300 301cat >_autotst.c <<HERE 302#include "$ACONF" 303#include <sys/types.h> 304#ifndef UNISTD_H_MISSING 305#include <unistd.h> 306#endif 307#include <fcntl.h> 308#ifndef SYS_FILE_H_MISSING 309#include <sys/file.h> 310#endif 311int main(){ 312#ifdef F_SETLKW 313 fcntl(0,F_SETLKW,0); 314#endif 315#ifdef F_LOCK 316 lockf(0,F_LOCK,(off_t)0); 317#endif 318#ifdef LOCK_EX 319 flock(0,LOCK_EX); 320#endif 321 return 0;} 322HERE 323 324echo 'Initiating fcntl()/kernel-locking-support tests' 325if $MAKE _autotst.$O >$DEVNULL 2>&1 326then 327: 328else 329 $RM _autotst.$O 330 echo "#define SYS_FILE_H_MISSING" >>$ACONF 331 if $MAKE _autotst.$O >_autotst.rrr 2>&1 332 then 333 : 334 else 335 echo 2>&1 "Whoeaaa! There's something fishy going on here." 336 echo 2>&1 "You have a look and see if you detect anything uncanny:" 337 echo 2>&1 "*******************************************************" 338 cat 2>&1 _autotst.rrr 339 echo 2>&1 "*******************************************************" 340 echo 2>&1 "I suggest you take a look at the definition of CFLAGS* and CC" 341 echo 2>&1 "in the Makefile before you try make again." 342 kill -15 $$ 343 fi 344fi 345$MAKE _autotst >_autotst.rrr 2>&1 346$RM _autotst.$O _autotst 347 348$FGREP fcntl _autotst.rrr >$DEVNULL && echo "#undef F_SETLKW" >>_locktst.h 349$FGREP lockf _autotst.rrr >$DEVNULL && echo "#undef F_LOCK" >>_locktst.h 350$FGREP flock _autotst.rrr >$DEVNULL && cat >>_locktst.h <<HERE 351#ifdef LOCK_EX 352#undef LOCK_EX 353#endif 354#ifndef SYS_FILE_H_MISSING 355#define SYS_FILE_H_MISSING 356#endif 357HERE 358 359cat >_autotst.c <<HERE 360#include "$ACONF" 361#include "../config.h" 362#include <sys/types.h> 363#ifndef UNISTD_H_MISSING 364#include <unistd.h> /* getpid() getppid() */ 365#endif 366#include <stdio.h> 367#include <time.h> 368#include <fcntl.h> 369#include <signal.h> /* SIGKILL */ 370#ifndef tell 371#define tell(fd) lseek(fd,(off_t)0,SEEK_CUR) 372#endif 373#ifndef EXIT_SUCCESS 374#define EXIT_SUCCESS 0 375#endif 376#include "_locktst.h" 377#ifndef SYS_FILE_H_MISSING 378#include <sys/file.h> 379#endif 380#ifndef SEEK_SET 381#define SEEK_SET 0 382#define SEEK_CUR 1 383#define SEEK_END 2 384#endif 385 386#define MIN_locks 128 /* minimum of consecutive successful locks */ 387#define SLEEP_loop 64 /* iterations in the busy loop */ 388#define SLEEP_delay 0 /* sleep() time per busy iteration */ 389#define SLEEP_retreat 1 /* extra sleep() when quota reached */ 390#define TIME_OUT_SEC 16 /* initial timeout per lock */ 391#define NR_of_forks 8 /* concurrent test-programs */ 392#define NR_of_lockfiles 2 /* lockfiles used in testing (<=4) */ 393#define GROW 3 /* when timing got worse */ 394#define DECAY 7/8 /* when timing got better */ 395#define GOBBLE 256 /* for the SunOS crash test */ 396 397#define LOCKS_per_child (((MIN_locks+NR_of_forks-1)/NR_of_forks+1)/2) 398#define SHIFT_childno 3 399#define MASK_fileno ((1<<SHIFT_childno)-1) 400#define MASK_childno (~MASK_fileno) 401 402#ifdef NO_fcntl_LOCK 403#undef F_SETLKW 404#endif 405#ifdef NO_lockf_LOCK 406#undef F_LOCK 407#endif 408#ifdef NO_flock_LOCK 409#undef LOCK_EX 410#endif 411 412#define FIRST_lock 0x04 /* testing is in order of importance */ 413#define MSK_fcntl 0x04 /* don't change this order unless you */ 414#define MSK_lockf 0x02 /* change locking.c as well, fdlock() */ 415#define MSK_flock 0x01 /* and hotwired LOCKINGTEST */ 416 417int dolock,child[NR_of_forks],timeout,fdcollect; 418char dirlocktest[]="_locktest"; 419 420void stimeout() 421{ timeout=1;close(fdcollect);killchildren(); 422} 423 424void Terminate() 425{ stimeout();exit(1); 426} 427 428static unsigned long seed; 429 430unsigned psrand() 431{ return (unsigned)(seed*=69069L)>>8; 432} 433 434unsigned sfork() 435{ int pid; 436 while((pid=fork())<0) 437 fprintf(stderr,"Couldn't fork _locktst, retrying\n"),sleep(TIME_OUT_SEC); 438 return pid; 439} 440 441int main(argc,argv)char*argv[]; 442{ int goodlock,testlock,i,pip[2],pipw[2];time_t otimet;unsigned dtimet; 443 static char filename[]="_locktst.l0"; 444 close(0);goodlock=0;testlock=FIRST_lock;signal(SIGPIPE,SIG_DFL); 445 if(argc==2) 446 { char*p; 447 for(p=argv[1];;) 448 { switch(*p++) /* parse the hotwire */ 449 { case '1':goodlock<<=1;goodlock++; 450 continue; 451 case '0':goodlock<<=1; 452 continue; 453 case '\0': 454#ifndef F_SETLKW /* sanity check, for the less gifted */ 455 goodlock&=~MSK_fcntl; 456#endif 457#ifndef F_LOCK 458 goodlock&=~MSK_lockf; 459#endif 460#ifndef LOCK_EX 461 goodlock&=~MSK_flock; 462#endif 463 goto skip_tests; 464 } 465 break; /* oops, no hotwire */ 466 } 467 goodlock=0; 468 } 469 if(sfork()) /* try to ditch the controlling tty */ 470 return EXIT_SUCCESS; /* to prevent rather messy kernel-diagnostics */ 471 setsid(); /* from appearing on your tty */ 472 fprintf(stderr,"\ 473Every two digits a file is locked. First digit: which file, second digit:\n\ 474which program, XX indicates a lock conflict or failure\n"); 475 do 476 { int countlocks; 477 signal(SIGTERM,SIG_DFL);argc=1;dolock=goodlock|testlock; 478 do 479 { char*curdir; 480 curdir=argv[argc];otimet=time((time_t*)0); 481 if(sfork()) 482 { close(1);close(2);i=NR_of_lockfiles;chdir(curdir); 483 chdir(dirlocktest); 484 do /* prime the lock, see if it vanishes */ 485 { filename[sizeof filename-2]='0'+--i; 486 lseek(goodlock=open(filename,O_WRONLY),(off_t)0,SEEK_END); 487 fdlock(goodlock); 488 } 489 while(i); 490 for(;;) /* synchronising "busy"-wait */ 491 sleep(TIME_OUT_SEC); /* until the games can be started */ 492 } 493 sleep(1);pipe(pip);pipe(pipw);i=NR_of_forks;*child=0; 494 fprintf(stderr,"\nStarting test %x on %s\n",dolock,curdir); 495 while((child[--i]=sfork())&&i); /* divide and conquer */ 496 if(!*child) 497 { unsigned char lockflag;int fd,childno=i<<SHIFT_childno; 498 int mylocks=LOCKS_per_child; 499 close(pipw[0]);close(pip[0]);close(1); 500 seed=time((time_t*)0)+getpid()|1;chdir(curdir);chdir(dirlocktest); 501 close(pipw[1]); 502 for(;;) /* and lock away! */ 503 { filename[sizeof filename-2]='0'+(i=psrand()%NR_of_lockfiles); 504 lockflag=childno|i<<1|1; 505 lseek(fd=open(filename,O_WRONLY),(off_t)0,SEEK_END); 506 if(sfdlock(fd)) 507 lockflag&=~1,fprintf(stderr,"XX%x",lockflag); 508 write(pip[1],&lockflag,1); 509 fprintf(stderr," %x%x",i,childno>>SHIFT_childno); 510 lseek(fd,(off_t)0,SEEK_END);write(fd,&lockflag,1); 511 for(i=SLEEP_loop;i;i--,time((time_t*)0),sleep(SLEEP_delay)); 512 lockflag&=~1;write(pip[1],&lockflag,1); 513 if(fdunlock()||close(fd)) 514 { write(pip[1],&lockflag,1);fprintf(stderr,"XX%x",lockflag); 515 return 1; 516 } 517 if(--mylocks<0) 518 sleep(SLEEP_retreat); 519 } 520 } 521 signal(SIGTERM,Terminate); 522 ;{ unsigned char lckdfil[NR_of_lockfiles],curflag; 523 int j,ppid; /* give all children a chance */ 524 ppid=getppid(); 525 if(sfork()) /* discard the old body, let init adopt our children */ 526 return EXIT_SUCCESS; 527 ;{ FILE*fp; 528 if(fp=fopen("_locktst.pid","w")) 529 fprintf(fp,"%ld",(long)getpid()),fclose(fp); 530 } 531 countlocks=MIN_locks;close(pip[1]);close(pipw[1]); 532 for(j=NR_of_lockfiles;lckdfil[--j]=0,j;); 533 timeout=0;sleep(1);read(pipw[0],&curflag,1);close(pipw[0]); 534 kill(ppid,SIGKILL);fdcollect=pip[0];signal(SIGALRM,stimeout); 535 dtimet=(time((time_t*)0)-otimet)*GROW+TIME_OUT_SEC; 536 do 537 { unlink("_locktst.alive");alarm(dtimet+2); /* watchdog */ 538 dtimet=(otimet=time((time_t*)0)-otimet)>dtimet? 539 otimet*GROW:otimet+(dtimet-otimet)*DECAY+1; /* load dependent */ 540 otimet=time((time_t*)0); 541 } 542 while(1==read(fdcollect,&curflag,1)&& 543 (j=lckdfil[i=(curflag&MASK_fileno)>>1],!timeout)&& 544 ((j^(lckdfil[i]=curflag))==1||!(j&1)&&curflag&1)&&--countlocks); 545 alarm(0);close(fdcollect);killchildren(); 546 fprintf(stdout, 547 "/*locktype: %x, countlocks: %x, timeout %x, watchdog %x, %s*/\n", 548 dolock,countlocks,timeout,dtimet,curdir);fflush(stdout); 549 } 550 } 551 while(!countlocks&&argv[++argc]); 552 if(!countlocks) /* Hurray! Locking was flawless */ 553 goodlock=dolock; /* make a mark on our colt */ 554 } 555 while(testlock>>=1); 556skip_tests: 557 printf("/* Hotwire LOCKINGTEST=%c%c%c */\n",goodlock&0x4?'1':'0', 558 goodlock&0x2?'1':'0',goodlock&0x1?'1':'0'); 559 printf("/* Procmail will lock via: dotlocking"); /* report our findings */ 560 if(goodlock&MSK_fcntl) 561 printf(", fcntl()"); 562 if(goodlock&MSK_lockf) 563 printf(", lockf()"); 564 if(goodlock&MSK_flock) 565 printf(", flock()"); 566 puts(" */"); 567 if(!(goodlock&MSK_fcntl)) /* and in machine readable format */ 568 puts("#define NOfcntl_lock"); 569 if(goodlock&MSK_lockf) 570 puts("#define USElockf"); 571 if(goodlock&MSK_flock) 572 { puts("#define USEflock"); 573#ifdef SYS_FILE_H_MISSING 574 puts("#define SYS_FILE_H_MISSING"); 575#endif 576 } 577 puts("Kernel-locking tests completed.");fprintf(stderr,"\n"); 578 return EXIT_SUCCESS; 579} 580 581int killchildren() 582{ int i; 583 i=NR_of_forks; 584 do 585 if(child[--i]>0) 586 kill(child[i],SIGTERM),child[i]=0; 587 while(i); 588 return 0; 589} 590 591int sfdlock(fd) 592{ int i;unsigned gobble[GOBBLE>>2]; 593 for(i=GOBBLE>>2;i;gobble[--i]=~(unsigned)0); /* SunOS crash test */ 594 return fdlock(fd); 595} 596 597static oldfdlock; 598#ifdef F_SETLKW 599static struct flock flck; /* why can't it be a local variable? */ 600#endif 601#ifdef F_LOCK 602static off_t oldlockoffset; 603#endif 604 605int fdlock(fd) 606{ int i;unsigned gobble[GOBBLE>>2]; 607 for(i=GOBBLE>>2;i;gobble[--i]=~(unsigned)0); /* SunOS crash test */ 608 oldfdlock=fd;fd=0; 609 if(MSK_fcntl&dolock) 610#ifdef F_SETLKW 611 { static unsigned extra; 612 flck.l_type=F_WRLCK;flck.l_whence=SEEK_SET;flck.l_start=tell(oldfdlock); 613 if(!extra--) 614 extra=MIN_locks/4,flck.l_len=2,i|=fcntl(oldfdlock,F_SETLK,&flck); 615 flck.l_len=0;fd|=fcntl(oldfdlock,F_SETLKW,&flck); 616 } 617#else 618 fd=1; 619#endif 620 if(MSK_lockf&dolock) 621#ifdef F_LOCK 622 oldlockoffset=tell(oldfdlock),fd|=lockf(oldfdlock,F_LOCK,(off_t)0); 623#else 624 fd=1; 625#endif 626 if(MSK_flock&dolock) 627#ifdef LOCK_EX 628 fd|=flock(oldfdlock,LOCK_EX); 629#else 630 fd=1; 631#endif 632 return fd; 633} 634 635int fdunlock() 636{ int i;unsigned gobble[GOBBLE]; 637 for(i=GOBBLE;i;gobble[--i]=~(unsigned)0); /* some SunOS libs mess this up */ 638 if(MSK_flock&dolock) 639#ifdef LOCK_EX 640 i|=flock(oldfdlock,LOCK_UN); 641#else 642 i=1; 643#endif 644 if(MSK_lockf&dolock) 645#ifdef F_LOCK 646 { lseek(oldfdlock,oldlockoffset,SEEK_SET); 647 i|=lockf(oldfdlock,F_LOCK,(off_t)2);i|=lockf(oldfdlock,F_ULOCK,(off_t)0); 648 } 649#else 650 i=1; 651#endif 652 if(MSK_fcntl&dolock) 653#ifdef F_SETLKW 654 flck.l_type=F_UNLCK,flck.l_len=0,i|=fcntl(oldfdlock,F_SETLK,&flck); 655#else 656 i=1; 657#endif 658 if(!i) 659 for(i=GOBBLE;i&&gobble[--i]==~(unsigned)0;); 660 return i; 661} 662HERE 663 664if $MAKE _autotst >_autotst.rrr 2>&1 665then 666: 667else 668 echo 2>&1 "Whoeaaa! There's something fishy going on here." 669 echo 2>&1 "You have a look and see if you detect anything uncanny:" 670 echo 2>&1 "*******************************************************" 671 cat 2>&1 _autotst.rrr 672 echo 2>&1 "*******************************************************" 673 echo 2>&1 "I suggest you take a look at the definition of LDFLAGS*" 674 echo 2>&1 "in the Makefile before you try make again." 675 kill -15 $$ 676fi 677 678$MV _locktst _locktst.$$ 2>$DEVNULL 679$RM _autotst.$O _autotst.rrr _locktst* 2>$DEVNULL 680echo "" >_locktst.pid 681$MV _autotst _locktst 682 683case "$testdirs" in 684 *[a-zA-Z/]*) 685 for b in $TESTDIRS 686 do 687 for a in 0 1 2 3 688 do echo dummy_file >$b/_locktst.l$a 689 done 690 done ;; 691 *) TESTDIRS=$testdirs ;; 692esac 693 694echo 2>&1 "" 695 696_locktst $TESTDIRS >_locktst.rrr 2>lock.log # will finish in the background 697echo 'Proceeding with kernel-locking-support tests in the background' 698 699 700cat >_autotst.c <<HERE 701#include "$ACONF" 702#ifndef UNISTD_H_MISSING 703#include <unistd.h> /* execvp() */ 704#endif 705int a(b)const int b[]; 706{ return *++b; /* watcom 10.6 on QNX refuses this */ 707} 708int main() 709{ char r[]="",*const*p;char*q="";const char*s=""; 710 static const char*const nullp=0,*const*d= &nullp; /* AIX 3.2.3 failure */ 711 static struct{const int a;int b;}c[2]={{0,0},{0,0}};/* IRIX 7.3.1 compiler */ 712 /* requires initializers on static const objects */ 713 --(c+1)->b; /* AIX 3.1.5 machines can't do this */ 714 p= &q; 715 ;{ int pip[2]; 716 pipe(pip); 717 if(fork()) /* this should hide core dumps from the shell */ 718 { close(pip[1]); /* close the writing end */ 719 return 1==read(pip[0],r,1)?0:1; /* wait for the rendevouz */ 720 } 721 close(pip[0]); /* close the writing end */ 722 if(!*d&&c[1].b) /* some magic to confuse the optimiser */ 723 d=(const char*const*)p; /* core dumps Ultrix 4.3 ANSI C */ 724 else /* so that it can't complain about the uselessness of this program */ 725 execvp(q,p); /* IRIX 4.0.1 system-includes are wrong on this point */ 726 if(write(pip[1],r,1)!=1) /* notify mam that we survived */ 727 return 1; /* oops, lost mam somehow */ 728 } 729 return r==s; /* Domain/OS warns here, not about "r==s" though */ 730} 731HERE 732 733echo 'Testing for const' 734if $MAKE _autotst.$O 2>&1 | $FGREP -v include/ >_autotst.rrr 735 test -f _autotst.$O && $MAKE _autotst >$DEVNULL 2>&1 && _autotst 736then 737 grepfor const '#define NO_const' 738else 739 echo '#define NO_const' >>$ACONF 740 set dummy *core* 741 if test -f $2 -a $nocore = yes 742 then 743 echo "Removing core file (bogus readonly segment)" 744 $RM *core* 745 fi 746fi 747$RM _autotst.$O _autotst 748 749cat >_autotst.c <<HERE 750int main(){volatile int i;return (i=0);} 751HERE 752 753echo 'Testing for volatile' 754if $MAKE _autotst.$O >$DEVNULL 2>&1 && test -f _autotst.$O 755then 756: 757else 758 echo '#define volatile' >>$ACONF 759 not_ISO=yep 760fi 761$RM _autotst.$O 762 763if $FGREP NO_const $ACONF >$DEVNULL 764then 765 echo '#define P(args) ()' >>$ACONF 766 not_ISO=yep 767else 768 cat >_autotst.c <<HERE 769int main(const int argc,const char*const argv[]){return argc;} 770HERE 771 772 echo 'Testing for prototypes' 773 if $MAKE _autotst.$O >$DEVNULL 2>&1 && test -f _autotst.$O 774 then 775 : 776 else 777 echo '#define P(args) ()' >>$ACONF 778 not_ISO=yep 779 fi 780 $RM _autotst.$O 781fi 782 783cat >_autotst.c <<HERE 784enum foo { A, B, C, D=7, E, F= -3, G }; 785int main(){return !(A==0&&B==1&&C==2&&D==7&&E==8&&F==-3&&G==-2);} 786HERE 787 788echo 'Testing for enum' 789if $MAKE _autotst.$O >$DEVNULL 2>&1 && test -f _autotst.$O && 790 $MAKE _autotst >$DEVNULL 2>&1 && _autotst 791then 792: 793else 794 echo '#define NO_enum' >>$ACONF 795 not_ISO=yep 796fi 797$RM _autotst.$O 798 799if test -n "$not_ISO" 800then 801 cat <<HERE 802 803Your system appears to not (correctly) support at least one of: 804const, volatile, function prototypes, and enum types. Future 805versions of procmail will probably require support for all of them, 806so you should either upgrade your compiler to one that's compliant 807with the ISO C standard (the standard's over 10 years old, for 808goodness sake), or send email to <bug@procmail.org> explaining why 809you need procmail to continue to support K&R C. 810 811HERE 812fi 813 814echo 'Checking for POSIX and ANSI/ISO system include files' 815 816cat >_autotst.c <<HERE 817#include "includes.h" 818int a; 819#ifndef SYS_DIRENT_H_MISSING 820typedef DIR*tDIR; 821tDIR vDIR; 822#endif 823HERE 824 825i0="";i1="";i2="";i3="";i4="";i5="";i6="";i7="";i8="";i9="";i10="";i11=""; 826i12="";i13="" 827oldi="" 828 829while $MAKE _autotst.$O 2>&1 | $FGREP -v include/ >_autotst.rrr 830 test ! -f _autotst.$O 831do 832 test -z "$i0" && grepfor stddef.h "#define STDDEF_H_MISSING" && i0=I 833 test -z "$i1" && grepfor stdlib.h "#define STDLIB_H_MISSING" && i1=I 834 test -z "$i2" && grepfor dirent.h "#define DIRENT_H_MISSING" && i2=I 835 test -z "$i2" && grepfor DIR "#define DIRENT_H_MISSING \ 836/* <dirent.h> is there, but empty */" && i2=I 837 test -z "$i3" && grepfor ndir.h "#define NDIR_H_MISSING" && i3=I 838 test I = "$i3$i4" && grepfor sys/ndir.h "#define SYS_NDIR_H_MISSING" && i4=I 839 test I = "$i4$i5" && grepfor sys/dir.h "#define SYS_DIR_H_MISSING" && i5=I 840 test I = "$i5$i6" && grepfor sys/dirent.h "#define SYS_DIRENT_H_MISSING" \ 841 && i6=I 842 test -z "$i7" && grepfor sys/wait.h "#define SYS_WAIT_H_MISSING" && i7=I 843 test -z "$i8" && grepfor sys/utsname.h "#define SYS_UTSNAME_H_MISSING" && 844 i8=I 845 test -z "$i9" && grepfor string.h "#define STRING_H_MISSING" && i9=I 846 test -z "$i10" && grepfor sysexits.h "#define SYSEXITS_H_MISSING" && i10=I 847 test -z "$i11" && grepfor math.h "#define MATH_H_MISSING" && i11=I 848 test -z "$i12" && grepfor limits.h "#define LIMITS_H_MISSING" && i12=I 849 test -z "$i13" && grepfor syslog.h "#define SYSLOG_H_MISSING" && i13=I 850 newi="$i0$i1$i2$i3$i4$i5$i6$i7$i8$i9$i10$i11$i12$i13" 851 if test a$oldi = a$newi 852 then 853 echo 2>&1 "Whoeaaa! There's something fishy going on here." 854 echo 2>&1 "You have a look and see if you detect anything uncanny:" 855 echo 2>&1 "*******************************************************" 856 $MAKE _autotst.$O >_autotst.rrr 2>&1 857 cat 2>&1 _autotst.rrr 858 echo 2>&1 "*******************************************************" 859 echo 2>&1 "I suggest you take a look at the definition of CFLAGS*" 860 echo 2>&1 "in the Makefile before you try make again." 861 kill -15 $$ 862 fi 863 oldi=$newi 864 echo \ 865 " ...missing `expr $oldi : '.*'` include files, doublechecking..." 866done 867 868$RM _autotst.$O 869 870cat >_autotst.c <<HERE 871#include "includes.h" 872#include "network.h" 873int a; 874HERE 875 876echo 'Checking for network/comsat/biff support' 877 878if $MAKE _autotst.$O >$DEVNULL 2>&1 879 test -f _autotst.$O 880then 881: 882else 883 echo "#define NO_COMSAT" >>$ACONF 884fi 885 886$RM _autotst.$O 887 888cat >_autotst.c <<HERE 889#include "includes.h" 890#ifndef NO_COMSAT 891#include "network.h" 892#endif 893int main(){int i=0; 894 {size_t vsize_t;i+=vsize_t=1;} 895 {pid_t vpid_t;i+=vpid_t=1;} 896 {mode_t vmode_t;i+=vmode_t=1;} 897 {uid_t vuid_t;i+=vuid_t=1;} 898 {gid_t vgid_t;i+=vgid_t=1;} 899#ifndef NO_COMSAT 900 {struct hostent vhostent;i+=!(vhostent.h_addr_list=0);} 901#endif 902#ifndef NOuname 903 {struct utsname vutsname;i+=!(*vutsname.nodename='\0');} 904#endif 905 return !i;} 906HERE 907 908echo 'Testing for void*, size_t, off_t, pid_t, time_t, mode_t, uid_t & gid_t' 909 910i1="";i2="";i3="";i4="";i5="";i6="";i7="" 911oldi="" 912 913while $MAKE _autotst.$O 2>&1 | $FGREP -v include/ >_autotst.rrr 914 test ! -f _autotst.$O 915do 916 test -z "$i1" && grepfor size_t 'typedef unsigned size_t;' && i1=I 917 test -z "$i2" && grepfor pid_t 'typedef int pid_t;' && i2=I 918 test -z "$i3" && grepfor mode_t 'typedef int mode_t;' && i3=I 919 test -z "$i4" && grepfor uid_t 'typedef int uid_t;' && i4=I 920 test -z "$i5" && grepfor gid_t 'typedef int gid_t;' && i5=I 921 test -z "$i6" && grepfor h_addr_list '#define h_0addr_list h_addr' && i6=I 922 test -z "$i6" && grepfor hostent '#define h_0addr_list h_addr' && i6=I 923 test -z "$i6" && grepfor member '#define h_0addr_list h_addr' && i6=I 924 test -z "$i7" && grepfor utsname "#define NOuname \ 925/* <sys/utsname.h> is there, but empty */" && i7=I 926 newi="$i1$i2$i3$i4$i5$i6$i7" 927 if test a$oldi = a$newi 928 then 929 echo 2>&1 "Whoeaaa! There's something fishy going on here." 930 echo 2>&1 "You have a look and see if you detect anything uncanny:" 931 echo 2>&1 "*******************************************************" 932 $MAKE _autotst.$O >_autotst.rrr 2>&1 933 cat 2>&1 _autotst.rrr 934 echo 2>&1 "*******************************************************" 935 echo 2>&1 "I suggest you take a look at the definition of CFLAGS*" 936 echo 2>&1 "in the Makefile before you try make again." 937 kill -15 $$ 938 fi 939 oldi=$newi 940 echo \ 941 " ...missing `expr $oldi : '.*'` types, doublechecking..." 942done 943 944$RM _autotst.$O 945 946cat >_autotst.c <<HERE 947#include "$ACONF" 948#include "../config.h" 949#include <stdio.h> 950#ifndef STDLIB_H_MISSING 951#include <stdlib.h> 952#define INITIAL 60 953#else 954void*realloc(),*malloc(); 955#endif 956int main() 957{ char*p=malloc(1),*q=0; 958 size_t len,last,max=BLKSIZ*64; /* 1M on non-SMALLHEAP systems */ 959 int count=0; 960 for(last=len=INITIAL;len<=max+INITIAL;len+=BLKSIZ) 961 { if(!(p=realloc(p,len))) 962 break; 963 if(p!=q) 964 count++,q=p,fprintf(stderr,"len=%lu p=%p\n",(unsigned long)len,p); 965 for(;last<len;last+=1024) /* touch at least every new page */ 966 p[last]=last%127; 967 } 968 free(q); 969 printf("/* %d move%s in %d steps of size %d when reallocing */\n", 970 count,count==1?"":"s",(int)(max/BLKSIZ),BLKSIZ); 971 if(BLKSIZ*(10*count+1)>max) 972 { puts("#define INEFFICIENTrealloc"); 973 exit(1); 974 } 975 exit(0); 976} 977HERE 978 979echo 'Checking realloc implementation' 980 981$RM -f _autotst 982if $MAKE _autotst >$DEVNULL 2>&1 983 test -f _autotst 984then 985 _autotst >_autotst.rrr 2>realloc.log 986 case "$?" in 987 0) cat _autotst.rrr >>$ACONF;; 988 1) cat _autotst.rrr >>$ACONF 989 echo 'Sorry, repeatedly reallocing is inefficient';; 990 *) echo "The test program failed somehow. Assuming realloc is fine";; 991 esac 992fi 993 994$RM _autotst.$O _autotst _autotst.rrr 995 996cat >_autotst.c <<HERE 997#include "includes.h" 998int main(){int i;i=1; 999 i+=WIFEXITED(i); 1000 i+=WIFSTOPPED(i); 1001 i+=WEXITSTATUS(i); 1002 i+=WSIGTERM(i); 1003 return i;} 1004HERE 1005 1006echo 'Testing for WIFEXITED(), WIFSTOPPED(), WEXITSTATUS() & WSIGTERM()' 1007if $MAKE _autotst.$O >_autotst.rrr 2>&1 1008then 1009 $FGREP -v include/ <_autotst.rrr >_autotst.$O 1010 $MV _autotst.$O _autotst.rrr 1011 grepfor struct '#define WMACROS_NON_POSIX' || 1012 grepfor union '#define WMACROS_NON_POSIX' 1013else 1014 echo '#define WMACROS_NON_POSIX' >>$ACONF 1015fi 1016$RM _autotst.$O _autotst.rrr 1017 1018cat >_autotst.c <<HERE 1019#include <pwd.h> 1020int main() 1021{ struct passwd*pw=getpwuid(0); 1022 return (pw->pw_passwd==0)+(pw->pw_class==0)+(pw->pw_gecos==0); 1023} 1024HERE 1025 1026echo 'Testing for various struct passwd members' 1027$MAKE _autotst.$O >_autotst.rrr 2>&1 1028grepfor pw_passwd '#define NOpw_passwd' 1029grepfor pw_class '#define NOpw_class' 1030grepfor pw_gecos '#define NOpw_gecos' 1031$RM _autotst.$O _autotst.rrr 1032 1033cat >_autotst.c <<HERE 1034#include "includes.h" 1035#ifndef NO_COMSAT 1036#include "network.h" 1037#endif 1038int main(){char a[2]; 1039 endpwent();endgrent();memmove(a,"0",1);bcopy("0",a,1);strcspn(a,"0"); 1040 strtol("0",(char**)0,10);strchr("0",'0');strpbrk(a,"0");rename(a,"0"); 1041 setrgid(0);setegid(0);setregid(0,0);setresgid(0,0,0);opendir("0"); 1042 initgroups("0",0);strstr("0","0");mkdir("0",0);pow(0.,0.);clock(); 1043 waitpid((pid_t)-1,(int*)0,0);ftruncate(0,0);fsync(0);strtod("0.0",(char**)0); 1044 strncasecmp("0","0",3);strerror(ENOENT);strlcat(a,"0",2); 1045 bzero(a,2);memset(a,'\0',2); 1046#ifdef S_ISLNK 1047 {struct stat stbuf;fstat(0,&stbuf);} 1048#endif 1049#ifndef NOuname 1050 {struct utsname b;uname(&b);} 1051#endif 1052#ifndef NO_COMSAT 1053 gethostbyname("0");getprotobyname(COMSATprotocol);endhostent();endservent(); 1054 endprotoent(); 1055#endif 1056 _exit(0); 1057 return 0;} 1058HERE 1059 1060echo 'Testing for memmove, strchr, strpbrk, strcspn, strtol, strstr,' 1061echo ' rename, setrgid, setegid, pow, opendir, mkdir, waitpid, fsync,' 1062echo ' ftruncate, strtod, strncasecmp, strerror, strlcat,' 1063echo ' memset, bzero, and _exit' 1064if $MAKE _autotst.$O >$DEVNULL 2>&1 1065then 1066: 1067else 1068 echo 2>&1 "Whoeaaa! There's something fishy going on here." 1069 echo 2>&1 "You have a look and see if you detect anything uncanny:" 1070 echo 2>&1 "*******************************************************" 1071 cat 2>&1 _autotst.rrr 1072 echo 2>&1 "*******************************************************" 1073 echo 2>&1 "Your include files seem to be beyond repair <sigh>." 1074 echo 2>&1 "I give up." 1075 kill -15 $$ 1076fi 1077$MAKE _autotst >_autotst.rrr 2>&1 1078$RM _autotst _autotst.$O 1079 1080# The simple ones 1081for func in strcspn strpbrk rename pow mkdir fstat initgroups \ 1082 strtol waitpid ftruncate fsync strtod strncasecmp strlcat memset bzero _exit 1083do 1084 grepfor $func "#define NO$func" 1085done 1086 1087NOstrerror=no 1088grepfor strerror "#define NOstrerror" && NOstrerror=yes 1089 1090grepfor opendir " 1091#define NOopendir /* the readdir library does not seem to be available 1092 this will slightly affect the way a filenumber is 1093 selected in MH-folders by procmail */ 1094" 1095a=no 1096grepfor setrgid '#define NOsetrgid' && a=yes 1097if grepfor setegid '#define NOsetegid' || test $a = yes 1098then 1099 grepfor setregid '#define NOsetregid' && 1100 grepfor setresgid '#define NOsetresgid' 1101fi 1102grepfor strchr '#define strchr(s,c) index(s,c)' 1103grepfor uname "\ 1104#define NOuname \ 1105/* <sys/utsname.h> defines it, the libraries don't */" 1106grepfor endpwent '#define endpwent()' 1107grepfor endgrent '#define endgrent()' 1108if grepfor gethostbyname '#define NO_COMSAT' 1109then 1110: 1111else 1112 grepfor getprotobyname '#define UDP_protocolno 17' 1113 grepfor endhostent '#define endhostent()' 1114 grepfor endservent '#define endservent()' 1115 grepfor endprotoent '#define endprotoent()' 1116fi 1117grepfor strstr '#define SLOWstrstr' || 1118 grepfor clock '#define SLOWstrstr' 1119grepfor memmove '#define NOmemmove' && 1120if $FGREP -e bcopy _autotst.rrr >$DEVNULL 1121then 1122 echo '#define NObcopy' >>$ACONF 1123 1124if test $NOstrerror = yes 1125then 1126 cat >_autotst.c <<HERE 1127#include "includes.h" 1128extern int sys_nerr;extern char*sys_errlist[]; 1129int main(){ 1130 return puts(sys_errlist[sys_nerr-1]);} 1131HERE 1132 1133 echo 'Testing for sys_errlist' 1134 if $MAKE _autotst.$O >_autotst.rrr 2>&1 1135 then 1136 if $MAKE _autotst >_autotst.rrr 2>&1 1137 then 1138 echo '' >_autotst.rrr 1139 fi 1140 fi 1141 grepfor sys_errlist '#define NOsys_errlist' 1142 $RM _autotst _autotst.$O _autotst.rrr 1143fi 1144 1145 echo 'Testing for brain damage' 1146 cat >_autotst.c <<HERE 1147#include "includes.h" 1148struct tests{int a,b;}; 1149int main(){ 1150 return offsetof(struct tests,b);} 1151HERE 1152 if $MAKE _autotst.$O >$DEVNULL 2>&1 1153 then 1154 : 1155 else 1156 echo 'Yep, it is' # ISC chokes on its own offsetof() 1157 echo '#define oBRAIN_DAMAGE' >>$ACONF 1158 fi 1159 $RM _autotst.$O 1160 1161else 1162 1163 cat >_autotst.c <<HERE 1164#include "includes.h" 1165#define M256 256 1166#define F33 33 1167int main(){int j=0,i=M256-1;static char a[M256]; 1168 do a[i]=i;while(i--); 1169 bcopy(a+F33,a,M256-F33);bcopy(a,a+F33,M256-F33);i=F33-1; 1170 do j|=a[i]!=(char)(i+F33);while(i--);i=M256-1; 1171 do j|=a[i]!=(char)i;while(--i!=F33-1);return !j;} 1172HERE 1173 1174 echo 'Testing for bcopy handling overlaps' 1175 $MAKE _autotst >$DEVNULL 2>&1 1176 1177 if _autotst 1178 then 1179 echo 'Sorry, incompetent bcopy, using substitute instead' 1180 echo '#define NObcopy' >>$ACONF 1181 fi 1182 $RM _autotst.$O _autotst 1183fi 1184test -f /bin/test && echo "#define GOT_bin_test" >>$ACONF 1185 1186cat >_autotst.c <<\HERE 1187#define BENCHSIZE 16384 1188#define GRANULARITY 64 /* maximal benchmark granularity */ 1189#include "sublib.c" 1190#ifndef NO_COMSAT 1191#include "network.h" /* also for ntohs() */ 1192#endif 1193#undef malloc /* from shell.h */ 1194#ifdef BENCHSIZE 1195#undef strstr /* from includes.h */ 1196#undef free /* from shell.h */ 1197unsigned long dobench(strstr,iter,haystack)char*(*const strstr)(); 1198 unsigned long iter;const char*const haystack; 1199{ unsigned long to; 1200 to=(unsigned long)clock(); 1201 do (*strstr)(haystack,FROM_EXPR); 1202 while(--iter); 1203 return (unsigned long)clock()-to; 1204} 1205#endif 1206int main(argc,argv)int argc;const char*argv[]; 1207{ if(argc==1) 1208 { char*haystack; 1209#ifdef BENCHSIZE 1210 if(haystack=malloc(BENCHSIZE)) 1211 { unsigned c1,c2,i;time_t t; 1212 unsigned long iter,titer,syscnt; 1213 for(i=c1=c2=0;i<BENCHSIZE-1;i++,c1++,c2++) 1214 { haystack[i]='a'; 1215 if(c1==37) 1216 c1=0,haystack[i]='\n'; 1217 if(c2==51) 1218 c2=0,haystack[i]='\n'; 1219 } 1220 haystack[i]='\0'; 1221 for(titer=~(unsigned long)0,t=0,iter=1;t<=1&&iter<<1&&iter<titer;) 1222 { t=time((time_t*)0); 1223 if((syscnt=dobench(strstr,iter<<=1,haystack))&&!~titer) 1224 titer=iter*GRANULARITY; 1225 t=time((time_t*)0)-t; 1226 } 1227 iter=dobench(sstrstr,iter,haystack);free(haystack); 1228 if(!syscnt) 1229 syscnt=1; 1230 if(!iter) 1231 iter=1; 1232 printf("\ 1233/* Your system's strstr() is %.2f times %sER than my C-routine */\n", 1234 syscnt>=iter?(double)syscnt/iter:(double)iter/syscnt, 1235 syscnt>=iter?"SLOW":"FAST"); 1236 if(syscnt>iter+iter/16) /* if at least 1.0625 times slower */ 1237 printf("\ 1238#define SLOWstrstr\t\t\t /* using my substitute instead */\n"); 1239 } 1240 else 1241 printf("/* Insufficient memory to perform the benchmark! */\n"); 1242#endif /* SLOWstrstr */ 1243#ifndef NO_COMSAT 1244#ifndef UDP_protocolno 1245 ;{ const struct protoent*p; 1246 if(p=getprotobyname(COMSATprotocol)) 1247 { printf("#define UDP_protocolno %d\n",p->p_proto); 1248#else 1249 ;{ if(1) 1250 { 1251#endif 1252 ;{ const struct servent*serv; 1253 if(serv=getservbyname(COMSATservice,COMSATprotocol)) 1254 printf("#define BIFF_serviceport \"%d\"\n", 1255 ntohs(serv->s_port)); 1256 } 1257#ifdef AF_INET 1258 ;{ const struct hostent*host; 1259 if(!strcmp("localhost",COMSAThost)&& 1260 (host=gethostbyname(COMSAThost))&& 1261 host->h_0addr_list&&host->h_addrtype==AF_INET&& 1262 host->h_length) 1263 { int j=host->h_length; 1264 const unsigned char*ad=(void*)host->h_0addr_list; 1265 printf("#define IP_localhost {"); 1266 printf("%d",*ad++); 1267 while(--j) 1268 printf(",%d",*ad++); 1269 puts("}"); 1270 } 1271 } 1272#endif /* AF_INET */ 1273 } 1274 else 1275 puts("#define NO_COMSAT"); 1276 } 1277#endif /* NO_COMSAT */ 1278 ;{ unsigned long s=(size_t)~0;int bits; 1279 for(bits=1;s>>=1;bits++); 1280 if(bits<=16) 1281 { puts("#define SMALLHEAP"); 1282 return 0; 1283 } 1284 } 1285#ifdef _GUID_T /* ISC cc hack */ 1286 ;{ struct passwd*p; 1287 if(sizeof(int)>sizeof(uid_t)&&(p=getpwnam("root"))&&(*p->pw_dir!='/'|| 1288 (*p->pw_shell&&!(p->pw_shell)[1]))) 1289 { puts("#define _GUID_T\ntypedef int uid_t;\ntypedef int gid_t;"); 1290 goto skipsetrgid; 1291 } 1292 } 1293#endif 1294#ifndef NOinitgroups 1295 if(geteuid()==ROOT_uid) 1296 { setgid(2); 1297 if(!setrgid(3)&&(getgid()!=3||getegid()!=2)) 1298 puts("#define setrgid_BRAIN_DAMAGE"); 1299 else 1300 { setuid(2); 1301 if(!setgid(3)&&!setgid(2)) 1302 puts("#define TOGGLE_SGID_OK"); 1303 } 1304 } 1305 else 1306#ifndef NGROUPS_MAX /* is this safeguard really needed? */ 1307#define NGROUPS_MAX 3 1308#endif /* some OSes expect an array of ints? */ 1309 { gid_t groups[NGROUPS_MAX*sizeof(int)/sizeof(gid_t)];unsigned i; 1310 for(i=getgroups(NGROUPS_MAX,groups); 1311 --i<NGROUPS_MAX&&groups[i]==getgid();); 1312 if(i<NGROUPS_MAX) 1313 { setegid(groups[i]); 1314 if(!setrgid(groups[i])&&getgid()!=groups[i]) 1315 puts("#define setrgid_BRAIN_DAMAGE"); 1316 } 1317 else 1318 puts("#define setrgid_RUNTIME_CHECK"); 1319 } 1320#endif 1321skipsetrgid:; 1322 } 1323#ifdef DEFsendmail 1324 if(argc==3) 1325 { printf("#define SENDMAIL \"%s\"\n",DEFsendmail); 1326 return 1; 1327 } 1328#endif 1329 if(argc==4) 1330 { FILE*fp; /* in case we are root */ 1331 chown(argv[1],2,getegid());setuid(2); /* adjust the directory first */ 1332 if(!(fp=fopen(argv[2],"w"))) 1333 goto openerr; /* shouldn't happen, really */ 1334 fclose(fp); /* always clean up after yourself */ 1335 if(!chown(argv[2],geteuid()==3?4:3,getegid())) 1336openerr: 1337 printf("#define CAN_chown\n"); 1338 } 1339 if(argc>4) 1340#define MAX_ENVMEM 2048 /* typical environment size */ 1341#define MAX_ARGMEM (2048*1024L) /* upper limit arguments size */ 1342 { static const char arg[]="e%04u=6789012345";unsigned diff; 1343 charNUM(num,diff);char**nargv;const char*einfo=""; 1344#define MAXT(type) (~(type)0>>1) 1345 sscanf(argv[1],"%u",&diff); /* what did our previous incarnation want? */ 1346 if(!diff) /* first run? initialise the environment */ 1347 { char*envs,**nenviron,**nenv; 1348 diff=MAX_ENVMEM/sizeof arg+1; 1349 if(!(nenviron=malloc(diff*sizeof*environ+MAX_ENVMEM))) 1350 goto printit; /* oops, panic already */ 1351 envs=(char*)((nenv=nenviron)+diff); 1352 while(--diff) /* put in some colour */ 1353 sprintf(*nenviron++=envs,arg,diff),envs+=sizeof arg; 1354 *(environ=nenv)="PATH=.";*nenviron=0;diff=argc; /* start doubling */ 1355 } 1356 if(MAX_ARGMEM/sizeof arg<=argc) /* we are satisfied */ 1357 { einfo=" /* soft limit */"; /* no reason to hog memory */ 1358 goto printit; 1359 } 1360 ;{ unsigned narg; 1361 while(narg=argc+diff+1, /* allocate space for the new args */ 1362 !(nargv=malloc(narg*sizeof*argv+(size_t)diff*sizeof arg))) 1363 if(!(diff>>=1)) /* oops, no space, back off */ 1364 goto printit; /* panic */ 1365 tmemmove(nargv,argv,argc*sizeof*argv);nargv[1]=num; /* copy old */ 1366 ;{ char**pargv,*args;unsigned i; 1367 pargv=nargv+argc;args=(char*)(nargv+narg);i=diff; 1368 do 1369 { const char*p; /* and paint in the new ones */ 1370 for(*pargv++=args,p=arg;*args++= *p++;); 1371 } 1372 while(--i); 1373 } 1374 } 1375 for(;;diff>>=1) 1376 { unsigned newdiff=diff>>1; /* take a small step for mankind */ 1377 if(argc==diff) /* or shall we boldly go */ 1378 newdiff=(unsigned)argc<<1; /* where no man has gone before? */ 1379 ;{ unsigned maxdiff=MAXT(unsigned)-argc; 1380 if(newdiff>maxdiff) /* that would overflow argc */ 1381 newdiff=maxdiff; /* and we wouldn't want that, would we now? */ 1382 } 1383 if(!newdiff) /* reductio ad adsurdum? */ 1384 break; /* yes, break off the engagement */ 1385 sprintf(num,"%u",newdiff);nargv[argc+diff]=0; /* pass on the target */ 1386 execv(argv[0],nargv); /* jeronimo! */ 1387 } 1388printit: /* we proudly present the findings */ 1389 printf("#define MAX_argc %d%s\n",argc-2,einfo); /* of the jury! */ 1390 } 1391 return EXIT_SUCCESS; 1392} 1393HERE 1394 1395echo "Determining the maximum number of 16 byte arguments execv() takes" 1396 1397if $MAKE _autotst >$DEVNULL 2>_autotst.rrr && 1398 _autotst 0 012345678901234 012345678901234 012345678901234 \ 1399 >>$ACONF 2>>_autotst.rrr 1400then 1401: 1402else 1403 echo 2>&1 "Whoeaaa! This actually can't happen." 1404 echo 2>&1 "You have a look and see if you detect anything uncanny:" 1405 echo 2>&1 "*******************************************************" 1406 cat 2>&1 _autotst.rrr 1407 echo 2>&1 "*******************************************************" 1408 echo 2>&1 "I suggest you take a look at the definition of LDFLAGS*" 1409 echo 2>&1 "in the Makefile before you try make again." 1410 kill -15 $$ 1411fi 1412 1413$RM _autotst.rrr 1414 1415echo "Benchmarking your system's strstr() implementation" 1416 1417_autotst >>$ACONF 1418 1419found=no 1420 1421for a in /var/spool/mail /usr/spool/mail /var/mail /usr/mail /spool/mail 1422do 1423 test -d $a -a $found != yes && 1424 echo '#define MAILSPOOLDIR "'$a'/"' >>$ACONF && found=yes 1425done 1426if test $found != yes 1427then 1428 echo '#define MAILSPOOLDIR "/var/spool/mail/"' >>$ACONF 1429 echo Could not find the system-mailbox directory, supplied default. 1430fi 1431 1432cat >lookfor <<HERE 1433for a in /usr/sbin /usr/lib /lib /usr/etc /etc /usr/bin /bin /usr/local/bin \ 1434 /usr/lbin /usr/local/lib /usr/local /usr/.lib /local/bin /sbin 1435do 1436 if test -f "\$a/\$1" 1437 then 1438 echo '#define SENDMAIL "'"\$a/\$1"'"' >>$ACONF 1439 exit 0 1440 fi 1441done 1442exit 1 1443HERE 1444chmod 0755 lookfor 1445 1446if _autotst 2 3 >>$ACONF 1447 test $? != 0 || 1448 lookfor sendmail || lookfor smail || lookfor mail #|| lookfor rmail 1449then 1450: 1451else 1452 echo 'Could not find any mailer. It should be a mailer accepting at least' 1453 echo 'one plain destination address as its only argument (any sendmail' 1454 echo 'compatible mailer will do), and the mail-to-be-sent on stdin.' 1455 echo 'What is your mailer called? (You can override this in config.h)' 1456 read a 1457 echo "#define SENDMAIL \"$a\"" >>$ACONF 1458fi 1459 1460grep '^#define SENDMAIL ".*/sendmail"' $ACONF >$DEVNULL || 1461 echo "#define DEFflagsendmail \"\"" >>$ACONF 1462 1463a=/tmp/_chowntst.$$ 1464$RM -r $a 1465OLDTESTDIRS="$a $OLDTESTDIRS" 1466mkdir $a 1467mkdir $a/__ 1468 1469_autotst $a/__ $a/__/__ 4 >>$ACONF 1470 1471cat /usr/lib/sendmail.cf /etc/sendmail.cf /etc/mail/sendmail.cf 2>$DEVNULL | 1472 grep 'Mlocal.*procmail' >$DEVNULL || 1473 echo '#define CF_no_procmail_yet' >>$ACONF 1474 1475cat /usr/lib/sendmail.cf /etc/sendmail.cf /etc/mail/sendmail.cf 2>$DEVNULL | 1476 grep '^V' >$DEVNULL || 1477 echo '#define buggy_SENDMAIL' >>$ACONF 1478 1479lpath='/bin' 1480bins="/bin" 1481 1482for newd in /usr/bin /usr/ucb /usr/5bin $BINDIR /local/bin /usr/local/bin \ 1483 /global/bin /usr/bin/X11 /usr/X*/bin 1484do 1485 if test -d $newd 1486 then 1487 oldid=`cd $newd; ls -id . .. ../.. 2>&1` 1488 for oldd in $bins 1489 do 1490 test "X`cd $oldd; ls -id . .. ../.. 2>&1`" = "X$oldid" && oldid=found 1491 done 1492 test found != "$oldid" && bins="$bins $newd" && lpath="$lpath:$newd" 1493 fi 1494done 1495 1496case ":$lpath:" in 1497 *:/usr/local/bin:*) ;; 1498 *) lpath="$lpath:/usr/local/bin" ;; 1499esac 1500 1501echo "#define defPATH \"PATH=\$HOME/bin:$lpath\"" >>$ACONF 1502echo "#define defSPATH \"PATH=$lpath\"" >>$ACONF 1503 1504sed -n -e 's/^ v\([^ ]*\) .*$/#define PM_VERSION "\1"/p' \ 1505 ../patchlevel.h >>$ACONF 1506 1507while $FGREP -e "Kernel-locking tests completed." _locktst.rrr >$DEVNULL; \ 1508 test 0 != $? 1509do 1510 if test -z "$tailpid" 1511 then 1512 echo "Waiting for the kernel-locking tests to finish..." 1513 exec 9>&2 2>$DEVNULL 1514 tail -f lock.log & 1515 tailpid=$! 1516 exec 2>&9 9>&- 1517 fi 1518# if test ! -f _locktst.alive 1519# then 1520# echo >_locktst.alive 1521# echo "Waiting for kernel-locking tests to finish..." 1522# fi 1523 sleep 4 1524done 1525exec 9>&2 2>$DEVNULL 1526test ! -z "$tailpid" && kill $tailpid && echo "" && echo "" 1527tailpid="" 1528wait # wait now, to prevent a notification message afterward 1529exec 2>&9 9>&- 1530echo "Collecting results from kernel-locking tests" 1531sed -e '/^Kernel-locking tests completed./,$ d' <_locktst.rrr >>$ACONF 1532set dummy *core* 1533if test -f $2 -a $nocore = yes 1534then 1535 echo "Removing core file (probably from the locking tests)" 1536 $RM *core* 1537fi 1538 1539echo "/* autoconf completed */" >>$ACONF 1540 1541$RM -r $OLDTESTDIRS $OLDTESTDIRS 2>$DEVNULL 1542$RM _autotst* _locktst* lookfor grepfor 2>$DEVNULL 1543 1544echo =============================autoconf.h=================================== 1545cat $ACONF 1546echo ========================================================================== 1547