summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.inc17
-rw-r--r--bin/cat/Makefile.depend19
-rw-r--r--bin/chflags/Makefile.depend19
-rw-r--r--bin/chio/Makefile.depend19
-rw-r--r--bin/chmod/Makefile.depend19
-rw-r--r--bin/cp/Makefile.depend19
-rw-r--r--bin/csh/Makefile.depend348
-rw-r--r--bin/date/Makefile.depend20
-rw-r--r--bin/dd/Makefile.depend19
-rw-r--r--bin/df/Makefile.depend20
-rw-r--r--bin/domainname/Makefile.depend19
-rw-r--r--bin/echo/Makefile.depend19
-rw-r--r--bin/ed/Makefile.depend20
-rw-r--r--bin/expr/Makefile.depend21
-rw-r--r--bin/getfacl/Makefile.depend19
-rw-r--r--bin/hostname/Makefile.depend19
-rw-r--r--bin/kenv/Makefile.depend19
-rw-r--r--bin/kill/Makefile.depend19
-rw-r--r--bin/ln/Makefile.depend19
-rw-r--r--bin/ls/Makefile.depend21
-rw-r--r--bin/mkdir/Makefile.depend19
-rw-r--r--bin/mv/Makefile.depend19
-rw-r--r--bin/pax/Makefile.depend19
-rw-r--r--bin/pkill/Makefile.depend20
-rw-r--r--bin/ps/Makefile.depend21
-rw-r--r--bin/pwait/Makefile.depend19
-rw-r--r--bin/pwd/Makefile.depend19
-rw-r--r--bin/rcp/Makefile.depend19
-rw-r--r--bin/realpath/Makefile.depend18
-rw-r--r--bin/rm/Makefile.depend19
-rw-r--r--bin/rmail/Makefile.depend23
-rw-r--r--bin/rmdir/Makefile.depend19
-rw-r--r--bin/setfacl/Makefile.depend19
-rw-r--r--bin/sh/Makefile.depend115
-rw-r--r--bin/sleep/Makefile.depend19
-rw-r--r--bin/stty/Makefile.depend19
-rw-r--r--bin/sync/Makefile.depend18
-rw-r--r--bin/test/Makefile.depend19
-rw-r--r--bin/uuidgen/Makefile.depend18
-rw-r--r--cddl/lib/drti/Makefile.depend17
-rw-r--r--cddl/lib/libavl/Makefile.depend17
-rw-r--r--cddl/lib/libctf/Makefile.depend19
-rw-r--r--cddl/lib/libdtrace/Makefile.depend47
-rw-r--r--cddl/lib/libnvpair/Makefile.depend18
-rw-r--r--cddl/lib/libumem/Makefile.depend17
-rw-r--r--cddl/lib/libuutil/Makefile.depend18
-rw-r--r--cddl/lib/libzfs/Makefile.depend22
-rw-r--r--cddl/lib/libzpool/Makefile.depend19
-rw-r--r--cddl/sbin/zfs/Makefile.depend25
-rw-r--r--cddl/sbin/zpool/Makefile.depend26
-rw-r--r--cddl/usr.bin/ctfconvert/Makefile.depend21
-rw-r--r--cddl/usr.bin/ctfdump/Makefile.depend19
-rw-r--r--cddl/usr.bin/ctfmerge/Makefile.depend21
-rw-r--r--cddl/usr.bin/sgsmsg/Makefile.depend19
-rw-r--r--cddl/usr.bin/zinject/Makefile.depend25
-rw-r--r--contrib/gnu-sort/ABOUT-NLS716
-rw-r--r--contrib/gnu-sort/AUTHORS86
-rw-r--r--contrib/gnu-sort/COPYING340
-rw-r--r--contrib/gnu-sort/ChangeLog7511
-rw-r--r--contrib/gnu-sort/FREEBSD-upgrade14
-rw-r--r--contrib/gnu-sort/INSTALL229
-rw-r--r--contrib/gnu-sort/NEWS904
-rw-r--r--contrib/gnu-sort/README147
-rw-r--r--contrib/gnu-sort/THANKS463
-rw-r--r--contrib/gnu-sort/THANKS-to-translators36
-rw-r--r--contrib/gnu-sort/TODO171
-rw-r--r--contrib/gnu-sort/lib/__fpending.c30
-rw-r--r--contrib/gnu-sort/lib/__fpending.h17
-rw-r--r--contrib/gnu-sort/lib/argmatch.c278
-rw-r--r--contrib/gnu-sort/lib/argmatch.h112
-rw-r--r--contrib/gnu-sort/lib/closeout.c93
-rw-r--r--contrib/gnu-sort/lib/closeout.h33
-rw-r--r--contrib/gnu-sort/lib/dup-safer.c59
-rw-r--r--contrib/gnu-sort/lib/error.c306
-rw-r--r--contrib/gnu-sort/lib/error.h66
-rw-r--r--contrib/gnu-sort/lib/exit.h32
-rw-r--r--contrib/gnu-sort/lib/exitfail.c27
-rw-r--r--contrib/gnu-sort/lib/exitfail.h20
-rw-r--r--contrib/gnu-sort/lib/fopen-safer.c72
-rw-r--r--contrib/gnu-sort/lib/gettext.h68
-rw-r--r--contrib/gnu-sort/lib/hard-locale.c76
-rw-r--r--contrib/gnu-sort/lib/hard-locale.h26
-rw-r--r--contrib/gnu-sort/lib/human.c485
-rw-r--r--contrib/gnu-sort/lib/human.h88
-rw-r--r--contrib/gnu-sort/lib/inttostr.c49
-rw-r--r--contrib/gnu-sort/lib/inttostr.h47
-rw-r--r--contrib/gnu-sort/lib/long-options.c91
-rw-r--r--contrib/gnu-sort/lib/long-options.h26
-rw-r--r--contrib/gnu-sort/lib/memcoll.c85
-rw-r--r--contrib/gnu-sort/lib/memcoll.h28
-rw-r--r--contrib/gnu-sort/lib/pathmax.h54
-rw-r--r--contrib/gnu-sort/lib/physmem.c307
-rw-r--r--contrib/gnu-sort/lib/physmem.h27
-rw-r--r--contrib/gnu-sort/lib/posixver.c59
-rw-r--r--contrib/gnu-sort/lib/posixver.h1
-rw-r--r--contrib/gnu-sort/lib/quote.c41
-rw-r--r--contrib/gnu-sort/lib/quote.h22
-rw-r--r--contrib/gnu-sort/lib/quotearg.c673
-rw-r--r--contrib/gnu-sort/lib/quotearg.h137
-rw-r--r--contrib/gnu-sort/lib/stat-macros.h255
-rw-r--r--contrib/gnu-sort/lib/stdio-safer.h23
-rw-r--r--contrib/gnu-sort/lib/strnlen.c48
-rw-r--r--contrib/gnu-sort/lib/timespec.h71
-rw-r--r--contrib/gnu-sort/lib/umaxtostr.c3
-rw-r--r--contrib/gnu-sort/lib/unistd-safer.h21
-rw-r--r--contrib/gnu-sort/lib/version-etc.c181
-rw-r--r--contrib/gnu-sort/lib/version-etc.h37
-rw-r--r--contrib/gnu-sort/lib/xalloc-die.c45
-rw-r--r--contrib/gnu-sort/lib/xalloc.h90
-rw-r--r--contrib/gnu-sort/lib/xmalloc.c221
-rw-r--r--contrib/gnu-sort/lib/xmemcoll.c59
-rw-r--r--contrib/gnu-sort/lib/xmemcoll.h2
-rw-r--r--contrib/gnu-sort/lib/xstrtol.c291
-rw-r--r--contrib/gnu-sort/lib/xstrtol.h89
-rw-r--r--contrib/gnu-sort/lib/xstrtoul.c6
-rw-r--r--contrib/gnu-sort/lib/xstrtoumax.c33
-rw-r--r--contrib/gnu-sort/man/sort.1113
-rw-r--r--contrib/gnu-sort/src/sort.c3237
-rw-r--r--contrib/gnu-sort/src/system.h831
-rw-r--r--crypto/openssl/fips/Makefile230
-rw-r--r--crypto/openssl/fips/aes/Makefile111
-rw-r--r--crypto/openssl/fips/aes/fips_aes_selftest.c101
-rw-r--r--crypto/openssl/fips/aes/fips_aesavs.c939
-rw-r--r--crypto/openssl/fips/des/Makefile111
-rw-r--r--crypto/openssl/fips/des/fips_des_selftest.c137
-rw-r--r--crypto/openssl/fips/des/fips_desmovs.c702
-rw-r--r--crypto/openssl/fips/dh/Makefile115
-rw-r--r--crypto/openssl/fips/dh/dh_gen.c179
-rw-r--r--crypto/openssl/fips/dh/fips_dh_check.c147
-rw-r--r--crypto/openssl/fips/dh/fips_dh_gen.c192
-rw-r--r--crypto/openssl/fips/dh/fips_dh_key.c276
-rw-r--r--crypto/openssl/fips/dh/fips_dh_lib.c95
-rw-r--r--crypto/openssl/fips/dsa/Makefile191
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_gen.c339
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_key.c169
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_lib.c95
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_ossl.c435
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_selftest.c180
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_sign.c258
-rw-r--r--crypto/openssl/fips/dsa/fips_dsatest.c271
-rw-r--r--crypto/openssl/fips/dsa/fips_dssvs.c537
-rw-r--r--crypto/openssl/fips/fips-nodiff.txt7
-rw-r--r--crypto/openssl/fips/fips.c519
-rw-r--r--crypto/openssl/fips/fips.h163
-rw-r--r--crypto/openssl/fips/fips_canister.c187
-rw-r--r--crypto/openssl/fips/fips_locl.h74
-rw-r--r--crypto/openssl/fips/fips_premain.c176
-rw-r--r--crypto/openssl/fips/fips_premain.c.sha11
-rw-r--r--crypto/openssl/fips/fips_test_suite.c579
-rw-r--r--crypto/openssl/fips/fips_utl.h359
-rwxr-xr-xcrypto/openssl/fips/fipsalgtest.pl887
-rwxr-xr-xcrypto/openssl/fips/fipsld178
-rwxr-xr-xcrypto/openssl/fips/fipstests.sh400
-rw-r--r--crypto/openssl/fips/hmac/Makefile123
-rw-r--r--crypto/openssl/fips/hmac/fips_hmac.c191
-rw-r--r--crypto/openssl/fips/hmac/fips_hmac_selftest.c135
-rw-r--r--crypto/openssl/fips/hmac/fips_hmactest.c328
-rwxr-xr-xcrypto/openssl/fips/mkfipsscr.pl657
-rwxr-xr-xcrypto/openssl/fips/openssl_fips_fingerprint31
-rw-r--r--crypto/openssl/fips/rand/Makefile149
-rw-r--r--crypto/openssl/fips/rand/fips_rand.c410
-rw-r--r--crypto/openssl/fips/rand/fips_rand.h77
-rw-r--r--crypto/openssl/fips/rand/fips_rand_selftest.c371
-rw-r--r--crypto/openssl/fips/rand/fips_randtest.c248
-rw-r--r--crypto/openssl/fips/rand/fips_rngvs.c230
-rw-r--r--crypto/openssl/fips/rsa/Makefile215
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_eay.c934
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_gen.c310
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_lib.c101
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_selftest.c432
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_sign.c554
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_x931g.c280
-rw-r--r--crypto/openssl/fips/rsa/fips_rsagtest.c390
-rw-r--r--crypto/openssl/fips/rsa/fips_rsastest.c370
-rw-r--r--crypto/openssl/fips/rsa/fips_rsavtest.c378
-rw-r--r--crypto/openssl/fips/sha/Makefile162
-rw-r--r--crypto/openssl/fips/sha/fips_sha1_selftest.c97
-rw-r--r--crypto/openssl/fips/sha/fips_shatest.c388
-rw-r--r--crypto/openssl/fips/sha/fips_standalone_sha1.c173
-rw-r--r--external/Makefile5
-rw-r--r--external/bsd/Makefile5
-rw-r--r--external/bsd/bmake/Makefile5
-rw-r--r--external/bsd/bmake/dist/ChangeLog1383
-rw-r--r--external/bsd/bmake/dist/FILES121
-rw-r--r--external/bsd/bmake/dist/Makefile.in187
-rw-r--r--external/bsd/bmake/dist/PSD.doc/Makefile8
-rw-r--r--external/bsd/bmake/dist/PSD.doc/tutorial.ms3773
-rw-r--r--external/bsd/bmake/dist/README47
-rw-r--r--external/bsd/bmake/dist/aclocal.m477
-rw-r--r--external/bsd/bmake/dist/arch.c1403
-rw-r--r--external/bsd/bmake/dist/bmake.12043
-rw-r--r--external/bsd/bmake/dist/bmake.cat11305
-rwxr-xr-xexternal/bsd/bmake/dist/boot-strap388
-rw-r--r--external/bsd/bmake/dist/bsd.after-import.mk105
-rw-r--r--external/bsd/bmake/dist/buf.c291
-rw-r--r--external/bsd/bmake/dist/buf.h119
-rw-r--r--external/bsd/bmake/dist/compat.c764
-rw-r--r--external/bsd/bmake/dist/cond.c1410
-rw-r--r--external/bsd/bmake/dist/config.h.in314
-rwxr-xr-xexternal/bsd/bmake/dist/configure7134
-rw-r--r--external/bsd/bmake/dist/configure.in370
-rw-r--r--external/bsd/bmake/dist/dir.c1802
-rw-r--r--external/bsd/bmake/dist/dir.h108
-rw-r--r--external/bsd/bmake/dist/dirname.c95
-rwxr-xr-xexternal/bsd/bmake/dist/find_lib.sh13
-rw-r--r--external/bsd/bmake/dist/for.c496
-rw-r--r--external/bsd/bmake/dist/getopt.c179
-rw-r--r--external/bsd/bmake/dist/hash.c463
-rw-r--r--external/bsd/bmake/dist/hash.h154
-rwxr-xr-xexternal/bsd/bmake/dist/install-sh201
-rw-r--r--external/bsd/bmake/dist/job.c2994
-rw-r--r--external/bsd/bmake/dist/job.h272
-rw-r--r--external/bsd/bmake/dist/lst.h189
-rw-r--r--external/bsd/bmake/dist/lst.lib/Makefile0
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstAppend.c122
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstAtEnd.c79
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstAtFront.c76
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstClose.c86
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstConcat.c185
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstDatum.c77
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstDeQueue.c87
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstDestroy.c101
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstDupl.c107
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstEnQueue.c78
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstFind.c74
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstFindFrom.c90
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstFirst.c77
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstForEach.c76
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstForEachFrom.c125
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstInit.c85
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstInsert.c122
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstInt.h105
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstIsAtEnd.c87
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstIsEmpty.c75
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstLast.c77
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstMember.c74
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstNext.c120
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstOpen.c87
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstPrev.c79
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstRemove.c136
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstReplace.c78
-rw-r--r--external/bsd/bmake/dist/lst.lib/lstSucc.c79
-rwxr-xr-xexternal/bsd/bmake/dist/machine.sh96
-rw-r--r--external/bsd/bmake/dist/main.c2078
-rwxr-xr-xexternal/bsd/bmake/dist/make-bootstrap.sh.in84
-rw-r--r--external/bsd/bmake/dist/make-conf.h162
-rw-r--r--external/bsd/bmake/dist/make.12061
-rw-r--r--external/bsd/bmake/dist/make.c1561
-rw-r--r--external/bsd/bmake/dist/make.h518
-rw-r--r--external/bsd/bmake/dist/make_malloc.c119
-rw-r--r--external/bsd/bmake/dist/make_malloc.h41
-rw-r--r--external/bsd/bmake/dist/meta.c1346
-rw-r--r--external/bsd/bmake/dist/meta.h54
-rwxr-xr-xexternal/bsd/bmake/dist/mkdeps.sh314
-rw-r--r--external/bsd/bmake/dist/nonints.h198
-rwxr-xr-xexternal/bsd/bmake/dist/os.sh228
-rw-r--r--external/bsd/bmake/dist/parse.c3122
-rw-r--r--external/bsd/bmake/dist/pathnames.h62
-rw-r--r--external/bsd/bmake/dist/ranlib.h32
-rw-r--r--external/bsd/bmake/dist/realpath.c196
-rw-r--r--external/bsd/bmake/dist/setenv.c154
-rw-r--r--external/bsd/bmake/dist/sigcompat.c325
-rw-r--r--external/bsd/bmake/dist/sprite.h116
-rw-r--r--external/bsd/bmake/dist/str.c508
-rw-r--r--external/bsd/bmake/dist/stresep.c89
-rw-r--r--external/bsd/bmake/dist/strlcpy.c63
-rw-r--r--external/bsd/bmake/dist/strlist.c93
-rw-r--r--external/bsd/bmake/dist/strlist.h62
-rw-r--r--external/bsd/bmake/dist/suff.c2653
-rw-r--r--external/bsd/bmake/dist/targ.c848
-rw-r--r--external/bsd/bmake/dist/trace.c116
-rw-r--r--external/bsd/bmake/dist/trace.h49
-rw-r--r--external/bsd/bmake/dist/unit-tests/Makefile.in96
-rw-r--r--external/bsd/bmake/dist/unit-tests/comment31
-rw-r--r--external/bsd/bmake/dist/unit-tests/cond1109
-rw-r--r--external/bsd/bmake/dist/unit-tests/doterror20
-rw-r--r--external/bsd/bmake/dist/unit-tests/dotwait61
-rw-r--r--external/bsd/bmake/dist/unit-tests/error10
-rw-r--r--external/bsd/bmake/dist/unit-tests/export22
-rw-r--r--external/bsd/bmake/dist/unit-tests/export-all23
-rw-r--r--external/bsd/bmake/dist/unit-tests/forloop45
-rw-r--r--external/bsd/bmake/dist/unit-tests/forsubst10
-rw-r--r--external/bsd/bmake/dist/unit-tests/hash18
-rw-r--r--external/bsd/bmake/dist/unit-tests/misc16
-rw-r--r--external/bsd/bmake/dist/unit-tests/moderrs31
-rw-r--r--external/bsd/bmake/dist/unit-tests/modmatch25
-rw-r--r--external/bsd/bmake/dist/unit-tests/modmisc38
-rw-r--r--external/bsd/bmake/dist/unit-tests/modorder22
-rw-r--r--external/bsd/bmake/dist/unit-tests/modts43
-rw-r--r--external/bsd/bmake/dist/unit-tests/modword151
-rw-r--r--external/bsd/bmake/dist/unit-tests/phony-end9
-rw-r--r--external/bsd/bmake/dist/unit-tests/posix24
-rw-r--r--external/bsd/bmake/dist/unit-tests/qequals8
-rw-r--r--external/bsd/bmake/dist/unit-tests/sysv26
-rw-r--r--external/bsd/bmake/dist/unit-tests/ternary8
-rw-r--r--external/bsd/bmake/dist/unit-tests/test.exp369
-rw-r--r--external/bsd/bmake/dist/unit-tests/unexport8
-rw-r--r--external/bsd/bmake/dist/unit-tests/unexport-env14
-rw-r--r--external/bsd/bmake/dist/unit-tests/varcmd49
-rw-r--r--external/bsd/bmake/dist/util.c619
-rw-r--r--external/bsd/bmake/dist/var.c4196
-rw-r--r--external/bsd/bmake/dist/wait.h81
-rw-r--r--external/bsd/bmake/usr.bin/Makefile5
-rw-r--r--external/bsd/bmake/usr.bin/bmake/Makefile210
-rw-r--r--external/bsd/bmake/usr.bin/bmake/Makefile.depend19
-rw-r--r--external/bsd/bmake/usr.bin/bmake/Makefile.inc6
-rw-r--r--external/bsd/bmake/usr.bin/bmake/config.h315
-rw-r--r--external/bsd/bmake/usr.bin/bmake/unit-tests/Makefile96
-rw-r--r--games/bcd/Makefile.depend19
-rw-r--r--games/caesar/Makefile.depend20
-rw-r--r--games/factor/Makefile.depend20
-rw-r--r--games/fortune/datfiles/Makefile.depend14
-rw-r--r--games/fortune/fortune/Makefile.depend19
-rw-r--r--games/fortune/strfile/Makefile.depend19
-rw-r--r--games/fortune/unstr/Makefile.depend19
-rw-r--r--games/grdc/Makefile.depend20
-rw-r--r--games/morse/Makefile.depend19
-rw-r--r--games/number/Makefile.depend19
-rw-r--r--games/pom/Makefile.depend20
-rw-r--r--games/ppt/Makefile.depend18
-rw-r--r--games/primes/Makefile.depend20
-rw-r--r--games/random/Makefile.depend19
-rw-r--r--gnu/lib/csu/Makefile.depend46
-rw-r--r--gnu/lib/libdialog/Makefile.depend17
-rw-r--r--gnu/lib/libgcc/Makefile.depend281
-rw-r--r--gnu/lib/libgcov/Makefile.depend128
-rw-r--r--gnu/lib/libgomp/Makefile.depend79
-rw-r--r--gnu/lib/libreadline/history/Makefile.depend16
-rw-r--r--gnu/lib/libreadline/readline/Makefile.depend16
-rw-r--r--gnu/lib/libregex/Makefile.depend19
-rw-r--r--gnu/lib/libssp/Makefile.depend16
-rw-r--r--gnu/lib/libssp/libssp_nonshared/Makefile.depend14
-rw-r--r--gnu/lib/libstdc++/Makefile.depend65
-rw-r--r--gnu/lib/libsupc++/Makefile.depend61
-rw-r--r--gnu/usr.bin/binutils/addr2line/Makefile.depend22
-rw-r--r--gnu/usr.bin/binutils/ar/Makefile.depend21
-rw-r--r--gnu/usr.bin/binutils/as/Makefile.depend21
-rw-r--r--gnu/usr.bin/binutils/ld/Makefile.depend50
-rw-r--r--gnu/usr.bin/binutils/libbfd/Makefile.depend104
-rw-r--r--gnu/usr.bin/binutils/libbinutils/Makefile.depend23
-rw-r--r--gnu/usr.bin/binutils/libiberty/Makefile.depend17
-rw-r--r--gnu/usr.bin/binutils/libopcodes/Makefile.depend16
-rw-r--r--gnu/usr.bin/binutils/nm/Makefile.depend22
-rw-r--r--gnu/usr.bin/binutils/objcopy/Makefile.depend22
-rw-r--r--gnu/usr.bin/binutils/objdump/Makefile.depend23
-rw-r--r--gnu/usr.bin/binutils/ranlib/Makefile.depend21
-rw-r--r--gnu/usr.bin/binutils/readelf/Makefile.depend22
-rw-r--r--gnu/usr.bin/binutils/size/Makefile.depend22
-rw-r--r--gnu/usr.bin/binutils/strings/Makefile.depend22
-rw-r--r--gnu/usr.bin/binutils/strip/Makefile.depend22
-rw-r--r--gnu/usr.bin/cc/c++/Makefile.depend22
-rw-r--r--gnu/usr.bin/cc/c++filt/Makefile.depend21
-rw-r--r--gnu/usr.bin/cc/cc/Makefile.depend21
-rw-r--r--gnu/usr.bin/cc/cc1/Makefile.depend25
-rw-r--r--gnu/usr.bin/cc/cc1plus/Makefile.depend27
-rw-r--r--gnu/usr.bin/cc/cc_int/Makefile.depend17
-rw-r--r--gnu/usr.bin/cc/cc_tools/Makefile.depend247
-rw-r--r--gnu/usr.bin/cc/cpp/Makefile.depend22
-rw-r--r--gnu/usr.bin/cc/gcov/Makefile.depend21
-rw-r--r--gnu/usr.bin/cc/include/Makefile.depend14
-rw-r--r--gnu/usr.bin/cc/libcpp/Makefile.depend18
-rw-r--r--gnu/usr.bin/cc/libdecnumber/Makefile.depend17
-rw-r--r--gnu/usr.bin/cc/libiberty/Makefile.depend16
-rw-r--r--gnu/usr.bin/cvs/cvs/Makefile.depend34
-rw-r--r--gnu/usr.bin/cvs/cvsbug/Makefile.depend14
-rw-r--r--gnu/usr.bin/cvs/lib/Makefile.depend38
-rw-r--r--gnu/usr.bin/cvs/libdiff/Makefile.depend18
-rw-r--r--gnu/usr.bin/dialog/Makefile.depend22
-rw-r--r--gnu/usr.bin/diff/Makefile.depend24
-rw-r--r--gnu/usr.bin/diff3/Makefile.depend21
-rw-r--r--gnu/usr.bin/dtc/Makefile.depend27
-rw-r--r--gnu/usr.bin/gdb/gdb/Makefile.depend33
-rw-r--r--gnu/usr.bin/gdb/gdbserver/Makefile.depend20
-rw-r--r--gnu/usr.bin/gdb/gdbtui/Makefile.depend33
-rw-r--r--gnu/usr.bin/gdb/kgdb/Makefile.depend58
-rw-r--r--gnu/usr.bin/gdb/libgdb/Makefile.depend1201
-rw-r--r--gnu/usr.bin/gperf/Makefile.depend21
-rw-r--r--gnu/usr.bin/grep/Makefile.depend22
-rw-r--r--gnu/usr.bin/groff/font/devX100-12/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devX100/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devX75-12/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devX75/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devascii/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devcp1047/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devdvi/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devhtml/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devkoi8-r/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devlatin1/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devlbp/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devlj4/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devps/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/font/devutf8/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/man/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/src/devices/grodvi/Makefile.depend23
-rw-r--r--gnu/usr.bin/groff/src/devices/grohtml/Makefile.depend23
-rw-r--r--gnu/usr.bin/groff/src/devices/grolbp/Makefile.depend23
-rw-r--r--gnu/usr.bin/groff/src/devices/grolj4/Makefile.depend23
-rw-r--r--gnu/usr.bin/groff/src/devices/grops/Makefile.depend23
-rw-r--r--gnu/usr.bin/groff/src/devices/grotty/Makefile.depend23
-rw-r--r--gnu/usr.bin/groff/src/libs/libbib/Makefile.depend16
-rw-r--r--gnu/usr.bin/groff/src/libs/libdriver/Makefile.depend17
-rw-r--r--gnu/usr.bin/groff/src/libs/libgroff/Makefile.depend19
-rw-r--r--gnu/usr.bin/groff/src/preproc/eqn/Makefile.depend26
-rw-r--r--gnu/usr.bin/groff/src/preproc/grn/Makefile.depend22
-rw-r--r--gnu/usr.bin/groff/src/preproc/html/Makefile.depend22
-rw-r--r--gnu/usr.bin/groff/src/preproc/pic/Makefile.depend26
-rw-r--r--gnu/usr.bin/groff/src/preproc/refer/Makefile.depend25
-rw-r--r--gnu/usr.bin/groff/src/preproc/soelim/Makefile.depend22
-rw-r--r--gnu/usr.bin/groff/src/preproc/tbl/Makefile.depend22
-rw-r--r--gnu/usr.bin/groff/src/roff/groff/Makefile.depend22
-rw-r--r--gnu/usr.bin/groff/src/roff/grog/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/src/roff/nroff/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/src/roff/psroff/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/src/roff/troff/Makefile.depend24
-rw-r--r--gnu/usr.bin/groff/src/utils/addftinfo/Makefile.depend22
-rw-r--r--gnu/usr.bin/groff/src/utils/afmtodit/Makefile.depend14
-rw-r--r--gnu/usr.bin/groff/src/utils/hpftodit/Makefile.depend22
-rw-r--r--gnu/usr.bin/groff/src/utils/indxbib/Makefile.depend23
-rw-r--r--gnu/usr.bin/groff/src/utils/lkbib/Makefile.depend23
-rw-r--r--gnu/usr.bin/groff/src/utils/lookbib/Makefile.depend23
-rw-r--r--gnu/usr.bin/groff/src/utils/pfbtops/Makefile.depend19
-rw-r--r--gnu/usr.bin/groff/src/utils/tfmtodit/Makefile.depend22
-rw-r--r--gnu/usr.bin/groff/tmac/Makefile.depend14
-rw-r--r--gnu/usr.bin/patch/Makefile.depend16
-rw-r--r--gnu/usr.bin/rcs/ci/Makefile.depend20
-rw-r--r--gnu/usr.bin/rcs/co/Makefile.depend20
-rw-r--r--gnu/usr.bin/rcs/ident/Makefile.depend20
-rw-r--r--gnu/usr.bin/rcs/lib/Makefile.depend16
-rw-r--r--gnu/usr.bin/rcs/merge/Makefile.depend20
-rw-r--r--gnu/usr.bin/rcs/rcs/Makefile.depend20
-rw-r--r--gnu/usr.bin/rcs/rcsclean/Makefile.depend20
-rw-r--r--gnu/usr.bin/rcs/rcsdiff/Makefile.depend20
-rw-r--r--gnu/usr.bin/rcs/rcsfreeze/Makefile.depend14
-rw-r--r--gnu/usr.bin/rcs/rcsmerge/Makefile.depend20
-rw-r--r--gnu/usr.bin/rcs/rlog/Makefile.depend20
-rw-r--r--gnu/usr.bin/sdiff/Makefile.depend21
-rw-r--r--gnu/usr.bin/send-pr/Makefile.depend14
-rw-r--r--gnu/usr.bin/sort/Makefile46
-rw-r--r--gnu/usr.bin/sort/Makefile.depend19
-rw-r--r--gnu/usr.bin/sort/alloca.h2
-rw-r--r--gnu/usr.bin/sort/config.h1519
-rw-r--r--gnu/usr.bin/sort/localedir.h2
-rw-r--r--gnu/usr.bin/sort/unlocked-io.h2
-rw-r--r--gnu/usr.bin/texinfo/info/Makefile.depend22
-rw-r--r--gnu/usr.bin/texinfo/infokey/Makefile.depend20
-rw-r--r--gnu/usr.bin/texinfo/install-info/Makefile.depend20
-rw-r--r--gnu/usr.bin/texinfo/libtxi/Makefile.depend16
-rw-r--r--gnu/usr.bin/texinfo/makeinfo/Makefile.depend20
-rw-r--r--gnu/usr.bin/texinfo/texindex/Makefile.depend20
-rw-r--r--include/Makefile34
-rw-r--r--include/Makefile.depend14
-rw-r--r--include/arpa/Makefile1
-rw-r--r--include/arpa/Makefile.depend14
-rw-r--r--include/gssapi/Makefile1
-rw-r--r--include/gssapi/Makefile.depend14
-rw-r--r--include/protocols/Makefile1
-rw-r--r--include/protocols/Makefile.depend14
-rw-r--r--include/rpc/Makefile.depend14
-rw-r--r--include/rpcsvc/Makefile.depend14
-rw-r--r--include/xlocale/Makefile1
-rw-r--r--include/xlocale/Makefile.depend14
-rw-r--r--kerberos5/lib/libasn1/Makefile.depend189
-rw-r--r--kerberos5/lib/libgssapi_krb5/Makefile.depend181
-rw-r--r--kerberos5/lib/libgssapi_ntlm/Makefile.depend18
-rw-r--r--kerberos5/lib/libgssapi_spnego/Makefile.depend117
-rw-r--r--kerberos5/lib/libhdb/Makefile.depend268
-rw-r--r--kerberos5/lib/libheimbase/Makefile.depend16
-rw-r--r--kerberos5/lib/libheimipcc/Makefile.depend18
-rw-r--r--kerberos5/lib/libheimipcs/Makefile.depend18
-rw-r--r--kerberos5/lib/libheimntlm/Makefile.depend25
-rw-r--r--kerberos5/lib/libheimsqlite/Makefile.depend15
-rw-r--r--kerberos5/lib/libhx509/Makefile.depend439
-rw-r--r--kerberos5/lib/libkadm5clnt/Makefile.depend80
-rw-r--r--kerberos5/lib/libkadm5srv/Makefile.depend104
-rw-r--r--kerberos5/lib/libkafs5/Makefile.depend18
-rw-r--r--kerberos5/lib/libkdc/Makefile.depend25
-rw-r--r--kerberos5/lib/libkrb5/Makefile.depend1094
-rw-r--r--kerberos5/lib/libroken/Makefile.depend173
-rw-r--r--kerberos5/lib/libsl/Makefile.depend17
-rw-r--r--kerberos5/lib/libvers/Makefile.depend19
-rw-r--r--kerberos5/lib/libwind/Makefile.depend57
-rw-r--r--kerberos5/libexec/digest-service/Makefile.depend35
-rw-r--r--kerberos5/libexec/hprop/Makefile.depend34
-rw-r--r--kerberos5/libexec/hpropd/Makefile.depend33
-rw-r--r--kerberos5/libexec/ipropd-master/Makefile.depend34
-rw-r--r--kerberos5/libexec/ipropd-slave/Makefile.depend34
-rw-r--r--kerberos5/libexec/kadmind/Makefile.depend36
-rw-r--r--kerberos5/libexec/kcm/Makefile.depend30
-rw-r--r--kerberos5/libexec/kdc/Makefile.depend34
-rw-r--r--kerberos5/libexec/kdigest/Makefile.depend36
-rw-r--r--kerberos5/libexec/kfd/Makefile.depend26
-rw-r--r--kerberos5/libexec/kimpersonate/Makefile.depend28
-rw-r--r--kerberos5/libexec/kpasswdd/Makefile.depend32
-rw-r--r--kerberos5/tools/asn1_compile/Makefile.depend56
-rw-r--r--kerberos5/tools/make-roken/Makefile.depend20
-rw-r--r--kerberos5/tools/slc/Makefile.depend30
-rw-r--r--kerberos5/usr.bin/hxtool/Makefile.depend35
-rw-r--r--kerberos5/usr.bin/kadmin/Makefile.depend73
-rw-r--r--kerberos5/usr.bin/kcc/Makefile.depend42
-rw-r--r--kerberos5/usr.bin/kdestroy/Makefile.depend28
-rw-r--r--kerberos5/usr.bin/kf/Makefile.depend26
-rw-r--r--kerberos5/usr.bin/kgetcred/Makefile.depend27
-rw-r--r--kerberos5/usr.bin/kinit/Makefile.depend29
-rw-r--r--kerberos5/usr.bin/kpasswd/Makefile.depend29
-rw-r--r--kerberos5/usr.bin/krb5-config/Makefile.depend14
-rw-r--r--kerberos5/usr.bin/ksu/Makefile.depend29
-rw-r--r--kerberos5/usr.bin/string2key/Makefile.depend33
-rw-r--r--kerberos5/usr.bin/verify_krb5_conf/Makefile.depend31
-rw-r--r--kerberos5/usr.sbin/iprop-log/Makefile.depend38
-rw-r--r--kerberos5/usr.sbin/kstash/Makefile.depend33
-rw-r--r--kerberos5/usr.sbin/ktutil/Makefile.depend53
-rw-r--r--lib/bind/bind9/Makefile.depend17
-rw-r--r--lib/bind/dns/Makefile.depend17
-rw-r--r--lib/bind/isc/Makefile.depend17
-rw-r--r--lib/bind/isccc/Makefile.depend17
-rw-r--r--lib/bind/isccfg/Makefile.depend17
-rw-r--r--lib/bind/lwres/Makefile.depend17
-rw-r--r--lib/clang/include/Makefile.depend14
-rw-r--r--lib/clang/libclanganalysis/Makefile.depend179
-rw-r--r--lib/clang/libclangarcmigrate/Makefile.depend209
-rw-r--r--lib/clang/libclangast/Makefile.depend489
-rw-r--r--lib/clang/libclangbasic/Makefile.depend45
-rw-r--r--lib/clang/libclangcodegen/Makefile.depend431
-rw-r--r--lib/clang/libclangdriver/Makefile.depend61
-rw-r--r--lib/clang/libclangedit/Makefile.depend29
-rw-r--r--lib/clang/libclangfrontend/Makefile.depend189
-rw-r--r--lib/clang/libclangfrontendtool/Makefile.depend23
-rw-r--r--lib/clang/libclanglex/Makefile.depend83
-rw-r--r--lib/clang/libclangparse/Makefile.depend199
-rw-r--r--lib/clang/libclangrewrite/Makefile.depend79
-rw-r--r--lib/clang/libclangsema/Makefile.depend563
-rw-r--r--lib/clang/libclangserialization/Makefile.depend111
-rw-r--r--lib/clang/libclangstaticanalyzercheckers/Makefile.depend749
-rw-r--r--lib/clang/libclangstaticanalyzercore/Makefile.depend365
-rw-r--r--lib/clang/libclangstaticanalyzerfrontend/Makefile.depend41
-rw-r--r--lib/clang/libllvmanalysis/Makefile.depend47
-rw-r--r--lib/clang/libllvmarchive/Makefile.depend17
-rw-r--r--lib/clang/libllvmarmasmparser/Makefile.depend31
-rw-r--r--lib/clang/libllvmarmcodegen/Makefile.depend209
-rw-r--r--lib/clang/libllvmarmdesc/Makefile.depend49
-rw-r--r--lib/clang/libllvmarmdisassembler/Makefile.depend27
-rw-r--r--lib/clang/libllvmarminfo/Makefile.depend23
-rw-r--r--lib/clang/libllvmarminstprinter/Makefile.depend25
-rw-r--r--lib/clang/libllvmasmparser/Makefile.depend17
-rw-r--r--lib/clang/libllvmasmprinter/Makefile.depend17
-rw-r--r--lib/clang/libllvmbitreader/Makefile.depend19
-rw-r--r--lib/clang/libllvmbitwriter/Makefile.depend17
-rw-r--r--lib/clang/libllvmcodegen/Makefile.depend33
-rw-r--r--lib/clang/libllvmcore/Makefile.depend33
-rw-r--r--lib/clang/libllvmdebuginfo/Makefile.depend17
-rw-r--r--lib/clang/libllvmexecutionengine/Makefile.depend17
-rw-r--r--lib/clang/libllvminstcombine/Makefile.depend43
-rw-r--r--lib/clang/libllvminstrumentation/Makefile.depend21
-rw-r--r--lib/clang/libllvminterpreter/Makefile.depend21
-rw-r--r--lib/clang/libllvmipa/Makefile.depend23
-rw-r--r--lib/clang/libllvmipo/Makefile.depend31
-rw-r--r--lib/clang/libllvmjit/Makefile.depend17
-rw-r--r--lib/clang/libllvmlinker/Makefile.depend17
-rw-r--r--lib/clang/libllvmmc/Makefile.depend17
-rw-r--r--lib/clang/libllvmmcdisassembler/Makefile.depend17
-rw-r--r--lib/clang/libllvmmcjit/Makefile.depend17
-rw-r--r--lib/clang/libllvmmcparser/Makefile.depend17
-rw-r--r--lib/clang/libllvmmipsasmparser/Makefile.depend23
-rw-r--r--lib/clang/libllvmmipscodegen/Makefile.depend131
-rw-r--r--lib/clang/libllvmmipsdesc/Makefile.depend43
-rw-r--r--lib/clang/libllvmmipsinfo/Makefile.depend23
-rw-r--r--lib/clang/libllvmmipsinstprinter/Makefile.depend19
-rw-r--r--lib/clang/libllvmobject/Makefile.depend17
-rw-r--r--lib/clang/libllvmpowerpccodegen/Makefile.depend111
-rw-r--r--lib/clang/libllvmpowerpcdesc/Makefile.depend43
-rw-r--r--lib/clang/libllvmpowerpcinfo/Makefile.depend23
-rw-r--r--lib/clang/libllvmpowerpcinstprinter/Makefile.depend25
-rw-r--r--lib/clang/libllvmruntimedyld/Makefile.depend17
-rw-r--r--lib/clang/libllvmscalaropts/Makefile.depend59
-rw-r--r--lib/clang/libllvmselectiondag/Makefile.depend29
-rw-r--r--lib/clang/libllvmsupport/Makefile.depend17
-rw-r--r--lib/clang/libllvmtablegen/Makefile.depend17
-rw-r--r--lib/clang/libllvmtarget/Makefile.depend17
-rw-r--r--lib/clang/libllvmtransformutils/Makefile.depend41
-rw-r--r--lib/clang/libllvmvectorize/Makefile.depend19
-rw-r--r--lib/clang/libllvmx86asmparser/Makefile.depend33
-rw-r--r--lib/clang/libllvmx86codegen/Makefile.depend127
-rw-r--r--lib/clang/libllvmx86desc/Makefile.depend53
-rw-r--r--lib/clang/libllvmx86disassembler/Makefile.depend23
-rw-r--r--lib/clang/libllvmx86info/Makefile.depend23
-rw-r--r--lib/clang/libllvmx86instprinter/Makefile.depend39
-rw-r--r--lib/clang/libllvmx86utils/Makefile.depend17
-rw-r--r--lib/csu/amd64/Makefile11
-rw-r--r--lib/csu/amd64/Makefile.depend15
-rw-r--r--lib/csu/arm/Makefile.depend15
-rw-r--r--lib/csu/i386-elf/Makefile6
-rw-r--r--lib/csu/i386-elf/Makefile.depend15
-rw-r--r--lib/csu/mips/Makefile.depend15
-rw-r--r--lib/csu/powerpc/Makefile.depend15
-rw-r--r--lib/csu/powerpc64/Makefile.depend15
-rw-r--r--lib/csu/sparc64/Makefile.depend15
-rw-r--r--lib/libalias/libalias/Makefile.depend17
-rw-r--r--lib/libalias/modules/cuseeme/Makefile.depend16
-rw-r--r--lib/libalias/modules/dummy/Makefile.depend16
-rw-r--r--lib/libalias/modules/ftp/Makefile.depend16
-rw-r--r--lib/libalias/modules/irc/Makefile.depend16
-rw-r--r--lib/libalias/modules/nbt/Makefile.depend16
-rw-r--r--lib/libalias/modules/pptp/Makefile.depend16
-rw-r--r--lib/libalias/modules/skinny/Makefile.depend16
-rw-r--r--lib/libalias/modules/smedia/Makefile.depend16
-rw-r--r--lib/libarchive/Makefile.depend16
-rw-r--r--lib/libauditd/Makefile.depend16
-rw-r--r--lib/libbegemot/Makefile.depend16
-rw-r--r--lib/libblocksruntime/Makefile.depend16
-rw-r--r--lib/libbluetooth/Makefile.depend16
-rw-r--r--lib/libbsm/Makefile.depend17
-rw-r--r--lib/libbsnmp/libbsnmp/Makefile.depend16
-rw-r--r--lib/libbz2/Makefile.depend16
-rw-r--r--lib/libc/Makefile10
-rw-r--r--lib/libc/Makefile.depend167
-rw-r--r--lib/libcalendar/Makefile.depend15
-rw-r--r--lib/libcam/Makefile.depend16
-rw-r--r--lib/libcom_err/Makefile.depend16
-rw-r--r--lib/libcompat/Makefile.depend16
-rw-r--r--lib/libcompiler_rt/Makefile.depend15
-rw-r--r--lib/libcrypt/Makefile.depend20
-rw-r--r--lib/libdevinfo/Makefile.depend16
-rw-r--r--lib/libdevstat/Makefile.depend16
-rw-r--r--lib/libdisk/Makefile.depend16
-rw-r--r--lib/libdwarf/Makefile.depend16
-rw-r--r--lib/libedit/Makefile.depend55
-rw-r--r--lib/libedit/edit/readline/Makefile.depend14
-rw-r--r--lib/libelf/Makefile.depend25
-rw-r--r--lib/libexpat/Makefile.depend16
-rw-r--r--lib/libfetch/Makefile.depend22
-rw-r--r--lib/libgeom/Makefile.depend17
-rw-r--r--lib/libgpib/Makefile.depend15
-rw-r--r--lib/libgssapi/Makefile.depend17
-rw-r--r--lib/libipsec/Makefile.depend26
-rw-r--r--lib/libipx/Makefile.depend17
-rw-r--r--lib/libjail/Makefile.depend17
-rw-r--r--lib/libkiconv/Makefile.depend16
-rw-r--r--lib/libkvm/Makefile.depend19
-rw-r--r--lib/liblzma/Makefile.depend16
-rw-r--r--lib/libmagic/Makefile.depend16
-rw-r--r--lib/libmd/Makefile.depend37
-rw-r--r--lib/libmemstat/Makefile.depend17
-rw-r--r--lib/libmilter/Makefile.depend54
-rw-r--r--lib/libmp/Makefile.depend16
-rw-r--r--lib/libncp/Makefile.depend14
-rw-r--r--lib/libnetgraph/Makefile.depend16
-rw-r--r--lib/libngatm/Makefile.depend17
-rw-r--r--lib/libopie/Makefile.depend18
-rw-r--r--lib/libpam/libpam/Makefile.depend40
-rw-r--r--lib/libpam/modules/pam_chroot/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_deny/Makefile.depend15
-rw-r--r--lib/libpam/modules/pam_echo/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_exec/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_ftpusers/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_group/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_guest/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_krb5/Makefile.depend19
-rw-r--r--lib/libpam/modules/pam_ksu/Makefile.depend18
-rw-r--r--lib/libpam/modules/pam_lastlog/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_login_access/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_nologin/Makefile.depend17
-rw-r--r--lib/libpam/modules/pam_opie/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_opieaccess/Makefile.depend15
-rw-r--r--lib/libpam/modules/pam_passwdqc/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_permit/Makefile.depend15
-rw-r--r--lib/libpam/modules/pam_radius/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_rhosts/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_rootok/Makefile.depend15
-rw-r--r--lib/libpam/modules/pam_securetty/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_self/Makefile.depend15
-rw-r--r--lib/libpam/modules/pam_ssh/Makefile.depend18
-rw-r--r--lib/libpam/modules/pam_tacplus/Makefile.depend16
-rw-r--r--lib/libpam/modules/pam_unix/Makefile.depend18
-rw-r--r--lib/libpcap/Makefile.depend32
-rw-r--r--lib/libpmc/Makefile.depend16
-rw-r--r--lib/libproc/Makefile.depend14
-rw-r--r--lib/libprocstat/Makefile.depend19
-rw-r--r--lib/libprocstat/zfs/Makefile.depend18
-rw-r--r--lib/libradius/Makefile.depend17
-rw-r--r--lib/librpcsec_gss/Makefile.depend16
-rw-r--r--lib/librpcsvc/Makefile.depend60
-rw-r--r--lib/librt/Makefile.depend16
-rw-r--r--lib/librtld_db/Makefile.depend14
-rw-r--r--lib/libsbuf/Makefile.depend16
-rw-r--r--lib/libsdp/Makefile.depend18
-rw-r--r--lib/libsm/Makefile.depend155
-rw-r--r--lib/libsmb/Makefile.depend14
-rw-r--r--lib/libsmdb/Makefile.depend25
-rw-r--r--lib/libsmutil/Makefile.depend30
-rw-r--r--lib/libstand/Makefile.depend58
-rw-r--r--lib/libstdbuf/Makefile.depend16
-rw-r--r--lib/libstdthreads/Makefile.depend16
-rw-r--r--lib/libtacplus/Makefile.depend18
-rw-r--r--lib/libtelnet/Makefile.depend20
-rw-r--r--lib/libthr/Makefile.depend15
-rw-r--r--lib/libthread_db/Makefile.depend16
-rw-r--r--lib/libufs/Makefile.depend16
-rw-r--r--lib/libugidfw/Makefile.depend16
-rw-r--r--lib/libulog/Makefile.depend17
-rw-r--r--lib/libusb/Makefile.depend16
-rw-r--r--lib/libusbhid/Makefile.depend16
-rw-r--r--lib/libutil/Makefile.depend17
-rw-r--r--lib/libvgl/Makefile.depend14
-rw-r--r--lib/libwrap/Makefile.depend17
-rw-r--r--lib/liby/Makefile.depend15
-rw-r--r--lib/libypclnt/Makefile.depend51
-rw-r--r--lib/libz/Makefile.depend16
-rw-r--r--lib/msun/Makefile2
-rw-r--r--lib/msun/Makefile.depend19
-rw-r--r--lib/ncurses/form/Makefile.depend134
-rw-r--r--lib/ncurses/formw/Makefile.depend134
-rw-r--r--lib/ncurses/menu/Makefile.depend95
-rw-r--r--lib/ncurses/menuw/Makefile.depend95
-rw-r--r--lib/ncurses/ncurses/Makefile.depend1807
-rw-r--r--lib/ncurses/ncursesw/Makefile.depend2047
-rw-r--r--lib/ncurses/panel/Makefile.depend62
-rw-r--r--lib/ncurses/panelw/Makefile.depend62
-rw-r--r--libexec/atrun/Makefile.depend21
-rw-r--r--libexec/bootpd/Makefile.depend20
-rw-r--r--libexec/bootpd/bootpgw/Makefile.depend20
-rw-r--r--libexec/bootpd/tools/bootpef/Makefile.depend20
-rw-r--r--libexec/bootpd/tools/bootptest/Makefile.depend20
-rw-r--r--libexec/comsat/Makefile.depend19
-rw-r--r--libexec/fingerd/Makefile.depend21
-rw-r--r--libexec/ftpd/Makefile.depend29
-rw-r--r--libexec/getty/Makefile.depend20
-rw-r--r--libexec/mail.local/Makefile.depend24
-rw-r--r--libexec/mknetid/Makefile.depend21
-rw-r--r--libexec/pppoed/Makefile.depend21
-rw-r--r--libexec/rbootd/Makefile.depend19
-rw-r--r--libexec/revnetgroup/Makefile.depend19
-rw-r--r--libexec/rlogind/Makefile.depend21
-rw-r--r--libexec/rpc.rquotad/Makefile.depend24
-rw-r--r--libexec/rpc.rstatd/Makefile.depend25
-rw-r--r--libexec/rpc.rusersd/Makefile.depend23
-rw-r--r--libexec/rpc.rwalld/Makefile.depend23
-rw-r--r--libexec/rpc.sprayd/Makefile.depend22
-rw-r--r--libexec/rshd/Makefile.depend22
-rw-r--r--libexec/rtld-elf/Makefile.depend17
-rw-r--r--libexec/smrsh/Makefile.depend23
-rw-r--r--libexec/talkd/Makefile.depend21
-rw-r--r--libexec/tcpd/Makefile.depend20
-rw-r--r--libexec/telnetd/Makefile.depend33
-rw-r--r--libexec/tftp-proxy/Makefile.depend20
-rw-r--r--libexec/tftpd/Makefile.depend21
-rw-r--r--libexec/ulog-helper/Makefile.depend20
-rw-r--r--libexec/ypxfr/Makefile.depend31
-rw-r--r--sbin/adjkerntz/Makefile.depend19
-rw-r--r--sbin/atacontrol/Makefile.depend19
-rw-r--r--sbin/atm/atmconfig/Makefile.depend24
-rw-r--r--sbin/badsect/Makefile.depend20
-rw-r--r--sbin/bsdlabel/Makefile.depend22
-rw-r--r--sbin/camcontrol/Makefile.depend22
-rw-r--r--sbin/ccdconfig/Makefile.depend20
-rw-r--r--sbin/clri/Makefile.depend19
-rw-r--r--sbin/comcontrol/Makefile.depend19
-rw-r--r--sbin/conscontrol/Makefile.depend19
-rw-r--r--sbin/ddb/Makefile.depend20
-rw-r--r--sbin/devd/Makefile.depend27
-rw-r--r--sbin/devfs/Makefile.depend19
-rw-r--r--sbin/dhclient/Makefile.depend21
-rw-r--r--sbin/dmesg/Makefile.depend20
-rw-r--r--sbin/dump/Makefile.depend20
-rw-r--r--sbin/dumpfs/Makefile.depend20
-rw-r--r--sbin/dumpon/Makefile.depend19
-rw-r--r--sbin/etherswitchcfg/Makefile.depend19
-rw-r--r--sbin/fdisk/Makefile.depend22
-rw-r--r--sbin/fdisk_pc98/Makefile.depend20
-rw-r--r--sbin/ffsinfo/Makefile.depend20
-rw-r--r--sbin/fsck/Makefile.depend19
-rw-r--r--sbin/fsck_ffs/Makefile.depend20
-rw-r--r--sbin/fsck_msdosfs/Makefile.depend19
-rw-r--r--sbin/fsdb/Makefile.depend22
-rw-r--r--sbin/fsirand/Makefile.depend20
-rw-r--r--sbin/gbde/Makefile.depend24
-rw-r--r--sbin/geom/class/cache/Makefile.depend17
-rw-r--r--sbin/geom/class/concat/Makefile.depend17
-rw-r--r--sbin/geom/class/eli/Makefile.depend18
-rw-r--r--sbin/geom/class/journal/Makefile.depend18
-rw-r--r--sbin/geom/class/label/Makefile.depend17
-rw-r--r--sbin/geom/class/mirror/Makefile.depend17
-rw-r--r--sbin/geom/class/mountver/Makefile.depend17
-rw-r--r--sbin/geom/class/multipath/Makefile.depend17
-rw-r--r--sbin/geom/class/nop/Makefile.depend17
-rw-r--r--sbin/geom/class/part/Makefile.depend18
-rw-r--r--sbin/geom/class/raid/Makefile.depend17
-rw-r--r--sbin/geom/class/raid3/Makefile.depend17
-rw-r--r--sbin/geom/class/sched/Makefile.depend17
-rw-r--r--sbin/geom/class/shsec/Makefile.depend17
-rw-r--r--sbin/geom/class/stripe/Makefile.depend17
-rw-r--r--sbin/geom/class/virstor/Makefile.depend17
-rw-r--r--sbin/geom/core/Makefile.depend23
-rw-r--r--sbin/ggate/ggatec/Makefile.depend25
-rw-r--r--sbin/ggate/ggated/Makefile.depend23
-rw-r--r--sbin/ggate/ggatel/Makefile.depend24
-rw-r--r--sbin/growfs/Makefile.depend20
-rw-r--r--sbin/gvinum/Makefile.depend25
-rw-r--r--sbin/hastctl/Makefile.depend28
-rw-r--r--sbin/hastd/Makefile.depend32
-rw-r--r--sbin/ifconfig/Makefile.depend24
-rw-r--r--sbin/init/Makefile.depend20
-rw-r--r--sbin/ipf/ipf/Makefile.depend33
-rw-r--r--sbin/ipf/ipfs/Makefile.depend22
-rw-r--r--sbin/ipf/ipfstat/Makefile.depend24
-rw-r--r--sbin/ipf/ipftest/Makefile.depend52
-rw-r--r--sbin/ipf/ipmon/Makefile.depend32
-rw-r--r--sbin/ipf/ipnat/Makefile.depend32
-rw-r--r--sbin/ipf/ippool/Makefile.depend32
-rw-r--r--sbin/ipf/ipresend/Makefile.depend23
-rw-r--r--sbin/ipf/libipf/Makefile.depend18
-rw-r--r--sbin/ipfw/Makefile.depend22
-rw-r--r--sbin/iscontrol/Makefile.depend22
-rw-r--r--sbin/kldconfig/Makefile.depend19
-rw-r--r--sbin/kldload/Makefile.depend19
-rw-r--r--sbin/kldstat/Makefile.depend18
-rw-r--r--sbin/kldunload/Makefile.depend18
-rw-r--r--sbin/ldconfig/Makefile.depend19
-rw-r--r--sbin/mca/Makefile.depend19
-rw-r--r--sbin/md5/Makefile.depend20
-rw-r--r--sbin/mdconfig/Makefile.depend25
-rw-r--r--sbin/mdmfs/Makefile.depend19
-rw-r--r--sbin/mknod/Makefile.depend19
-rw-r--r--sbin/mksnap_ffs/Makefile.depend19
-rw-r--r--sbin/mount/Makefile.depend20
-rw-r--r--sbin/mount_cd9660/Makefile.depend21
-rw-r--r--sbin/mount_ext2fs/Makefile.depend19
-rw-r--r--sbin/mount_msdosfs/Makefile.depend21
-rw-r--r--sbin/mount_nfs/Makefile.depend22
-rw-r--r--sbin/mount_ntfs/Makefile.depend21
-rw-r--r--sbin/mount_nullfs/Makefile.depend19
-rw-r--r--sbin/mount_reiserfs/Makefile.depend19
-rw-r--r--sbin/mount_std/Makefile.depend19
-rw-r--r--sbin/mount_udf/Makefile.depend20
-rw-r--r--sbin/mount_unionfs/Makefile.depend19
-rw-r--r--sbin/natd/Makefile.depend21
-rw-r--r--sbin/newfs/Makefile.depend21
-rw-r--r--sbin/newfs_msdos/Makefile.depend19
-rw-r--r--sbin/nfsiod/Makefile.depend18
-rw-r--r--sbin/nos-tun/Makefile.depend20
-rw-r--r--sbin/pfctl/Makefile.depend24
-rw-r--r--sbin/pflogd/Makefile.depend20
-rw-r--r--sbin/ping/Makefile.depend22
-rw-r--r--sbin/ping6/Makefile.depend23
-rw-r--r--sbin/quotacheck/Makefile.depend20
-rw-r--r--sbin/rcorder/Makefile.depend22
-rw-r--r--sbin/reboot/Makefile.depend19
-rw-r--r--sbin/recoverdisk/Makefile.depend19
-rw-r--r--sbin/resolvconf/Makefile.depend14
-rw-r--r--sbin/restore/Makefile.depend20
-rw-r--r--sbin/route/Makefile.depend22
-rw-r--r--sbin/routed/Makefile.depend22
-rw-r--r--sbin/routed/rtquery/Makefile.depend22
-rw-r--r--sbin/rtsol/Makefile.depend20
-rw-r--r--sbin/savecore/Makefile.depend20
-rw-r--r--sbin/sconfig/Makefile.depend19
-rw-r--r--sbin/setkey/Makefile.depend28
-rw-r--r--sbin/shutdown/Makefile.depend19
-rw-r--r--sbin/spppcontrol/Makefile.depend19
-rw-r--r--sbin/sunlabel/Makefile.depend20
-rw-r--r--sbin/swapon/Makefile.depend20
-rw-r--r--sbin/sysctl/Makefile.depend19
-rw-r--r--sbin/tunefs/Makefile.depend20
-rw-r--r--sbin/umount/Makefile.depend21
-rw-r--r--secure/lib/libcrypto/Makefile.depend22
-rw-r--r--secure/lib/libcrypto/engines/lib4758cca/Makefile.depend16
-rw-r--r--secure/lib/libcrypto/engines/libaep/Makefile.depend16
-rw-r--r--secure/lib/libcrypto/engines/libatalla/Makefile.depend16
-rw-r--r--secure/lib/libcrypto/engines/libchil/Makefile.depend16
-rw-r--r--secure/lib/libcrypto/engines/libcswift/Makefile.depend16
-rw-r--r--secure/lib/libcrypto/engines/libnuron/Makefile.depend16
-rw-r--r--secure/lib/libcrypto/engines/libsureware/Makefile.depend16
-rw-r--r--secure/lib/libcrypto/engines/libubsec/Makefile.depend16
-rw-r--r--secure/lib/libssh/Makefile.depend22
-rw-r--r--secure/lib/libssl/Makefile.depend17
-rw-r--r--secure/libexec/sftp-server/Makefile.depend26
-rw-r--r--secure/libexec/ssh-keysign/Makefile.depend26
-rw-r--r--secure/libexec/ssh-pkcs11-helper/Makefile.depend26
-rw-r--r--secure/usr.bin/bdes/Makefile.depend20
-rw-r--r--secure/usr.bin/openssl/Makefile.depend23
-rw-r--r--secure/usr.bin/scp/Makefile.depend26
-rw-r--r--secure/usr.bin/sftp/Makefile.depend28
-rw-r--r--secure/usr.bin/ssh-add/Makefile.depend26
-rw-r--r--secure/usr.bin/ssh-agent/Makefile.depend26
-rw-r--r--secure/usr.bin/ssh-keygen/Makefile.depend26
-rw-r--r--secure/usr.bin/ssh-keyscan/Makefile.depend26
-rw-r--r--secure/usr.bin/ssh/Makefile.depend30
-rw-r--r--secure/usr.sbin/sshd/Makefile.depend33
-rw-r--r--share/colldef/Makefile.depend14
-rw-r--r--share/dict/Makefile.depend14
-rw-r--r--share/doc/IPv6/Makefile.depend14
-rw-r--r--share/doc/bind9/Makefile.depend14
-rw-r--r--share/doc/legal/intel_ipw/Makefile.depend14
-rw-r--r--share/doc/legal/intel_iwi/Makefile.depend14
-rw-r--r--share/doc/legal/intel_iwn/Makefile.depend14
-rw-r--r--share/doc/legal/intel_wpi/Makefile.depend14
-rw-r--r--share/doc/llvm/Makefile.depend14
-rw-r--r--share/doc/llvm/clang/Makefile.depend14
-rw-r--r--share/examples/libvgl/Makefile.depend19
-rw-r--r--share/i18n/csmapper/APPLE/Makefile.depend15
-rw-r--r--share/i18n/csmapper/AST/Makefile.depend15
-rw-r--r--share/i18n/csmapper/BIG5/Makefile.depend15
-rw-r--r--share/i18n/csmapper/CNS/Makefile.depend15
-rw-r--r--share/i18n/csmapper/CP/Makefile.depend15
-rw-r--r--share/i18n/csmapper/EBCDIC/Makefile.depend15
-rw-r--r--share/i18n/csmapper/GB/Makefile.depend15
-rw-r--r--share/i18n/csmapper/GEORGIAN/Makefile.depend15
-rw-r--r--share/i18n/csmapper/ISO-8859/Makefile.depend15
-rw-r--r--share/i18n/csmapper/ISO646/Makefile.depend14
-rw-r--r--share/i18n/csmapper/JIS/Makefile.depend15
-rw-r--r--share/i18n/csmapper/KAZAKH/Makefile.depend15
-rw-r--r--share/i18n/csmapper/KOI/Makefile.depend15
-rw-r--r--share/i18n/csmapper/KS/Makefile.depend15
-rw-r--r--share/i18n/csmapper/MISC/Makefile.depend15
-rw-r--r--share/i18n/csmapper/TCVN/Makefile.depend15
-rw-r--r--share/man/man1/Makefile.depend14
-rw-r--r--share/man/man3/Makefile.depend14
-rw-r--r--share/man/man4/Makefile.depend14
-rw-r--r--share/man/man4/man4.arm/Makefile.depend14
-rw-r--r--share/man/man4/man4.i386/Makefile.depend14
-rw-r--r--share/man/man4/man4.powerpc/Makefile.depend14
-rw-r--r--share/man/man4/man4.sparc64/Makefile.depend14
-rw-r--r--share/man/man5/Makefile.depend14
-rw-r--r--share/man/man6/Makefile.depend14
-rw-r--r--share/man/man7/Makefile.depend14
-rw-r--r--share/man/man8/Makefile.depend14
-rw-r--r--share/man/man9/Makefile.depend14
-rw-r--r--share/me/Makefile.depend14
-rw-r--r--share/misc/Makefile.depend14
-rw-r--r--share/mk/Makefile.depend14
-rw-r--r--share/mk/auto.obj.mk57
-rw-r--r--share/mk/bsd.dep.mk11
-rw-r--r--share/mk/bsd.files.mk21
-rw-r--r--share/mk/bsd.incs.mk19
-rw-r--r--share/mk/bsd.init.mk9
-rw-r--r--share/mk/bsd.lib.mk18
-rw-r--r--share/mk/bsd.obj.mk9
-rw-r--r--share/mk/bsd.own.mk16
-rw-r--r--share/mk/bsd.prog.mk26
-rw-r--r--share/mk/bsd.subdir.mk11
-rw-r--r--share/mk/dirdeps.mk368
-rw-r--r--share/mk/gendirdeps.mk301
-rw-r--r--share/mk/host-target.mk31
-rw-r--r--share/mk/install-new.mk53
-rw-r--r--share/mk/local.autodep.mk21
-rw-r--r--share/mk/local.dirdeps.mk15
-rw-r--r--share/mk/local.gendirdeps.mk10
-rw-r--r--share/mk/local.init.mk18
-rw-r--r--share/mk/local.sys.mk197
-rw-r--r--share/mk/meta.autodep.mk261
-rw-r--r--share/mk/meta.stage.mk166
-rw-r--r--share/mk/meta.subdir.mk79
-rw-r--r--share/mk/meta.sys.mk139
-rwxr-xr-xshare/mk/meta2deps.py606
-rwxr-xr-xshare/mk/meta2deps.sh306
-rw-r--r--share/mk/sys.dependfile.mk38
-rw-r--r--share/mklocale/Makefile.depend14
-rw-r--r--share/monetdef/Makefile.depend14
-rw-r--r--share/msgdef/Makefile.depend14
-rw-r--r--share/numericdef/Makefile.depend14
-rw-r--r--share/security/Makefile.depend14
-rw-r--r--share/skel/Makefile.depend14
-rw-r--r--share/snmp/mibs/Makefile.depend14
-rw-r--r--share/syscons/fonts/Makefile.depend14
-rw-r--r--share/syscons/keymaps/Makefile.depend14
-rw-r--r--share/syscons/scrnmaps/Makefile.depend18
-rw-r--r--share/tabset/Makefile.depend14
-rw-r--r--share/termcap/Makefile.depend14
-rw-r--r--share/timedef/Makefile.depend14
-rw-r--r--share/zoneinfo/Makefile.depend14
-rw-r--r--sys/boot/ficl/Makefile.depend14
-rw-r--r--sys/boot/i386/boot2/Makefile.depend14
-rw-r--r--sys/boot/i386/loader/Makefile.depend14
-rw-r--r--sys/boot/i386/zfsloader/Makefile.depend14
-rw-r--r--sys/conf/kmod.mk2
-rw-r--r--sys/contrib/pf/net/if_pflog.c435
-rw-r--r--sys/contrib/pf/net/if_pflog.h101
-rw-r--r--sys/contrib/pf/net/if_pflow.h126
-rw-r--r--sys/contrib/pf/net/if_pfsync.c3474
-rw-r--r--sys/contrib/pf/net/if_pfsync.h324
-rw-r--r--sys/contrib/pf/net/pf.c7620
-rw-r--r--sys/contrib/pf/net/pf_if.c1111
-rw-r--r--sys/contrib/pf/net/pf_ioctl.c4420
-rw-r--r--sys/contrib/pf/net/pf_lb.c793
-rw-r--r--sys/contrib/pf/net/pf_mtag.h84
-rw-r--r--sys/contrib/pf/net/pf_norm.c2359
-rw-r--r--sys/contrib/pf/net/pf_osfp.c698
-rw-r--r--sys/contrib/pf/net/pf_ruleset.c457
-rw-r--r--sys/contrib/pf/net/pf_table.c2516
-rw-r--r--sys/contrib/pf/net/pfvar.h2234
-rw-r--r--sys/contrib/pf/netinet/in4_cksum.c120
-rw-r--r--sys/netinet/ipfw/dn_heap.c552
-rw-r--r--sys/netinet/ipfw/dn_heap.h191
-rw-r--r--sys/netinet/ipfw/dn_sched.h191
-rw-r--r--sys/netinet/ipfw/dn_sched_fifo.c120
-rw-r--r--sys/netinet/ipfw/dn_sched_prio.c229
-rw-r--r--sys/netinet/ipfw/dn_sched_qfq.c864
-rw-r--r--sys/netinet/ipfw/dn_sched_rr.c307
-rw-r--r--sys/netinet/ipfw/dn_sched_wf2q.c373
-rw-r--r--sys/netinet/ipfw/dummynet.txt860
-rw-r--r--sys/netinet/ipfw/ip_dn_glue.c845
-rw-r--r--sys/netinet/ipfw/ip_dn_io.c851
-rw-r--r--sys/netinet/ipfw/ip_dn_private.h403
-rw-r--r--sys/netinet/ipfw/ip_dummynet.c2313
-rw-r--r--sys/netinet/ipfw/ip_fw2.c2783
-rw-r--r--sys/netinet/ipfw/ip_fw_dynamic.c1242
-rw-r--r--sys/netinet/ipfw/ip_fw_log.c469
-rw-r--r--sys/netinet/ipfw/ip_fw_nat.c661
-rw-r--r--sys/netinet/ipfw/ip_fw_pfil.c460
-rw-r--r--sys/netinet/ipfw/ip_fw_private.h313
-rw-r--r--sys/netinet/ipfw/ip_fw_sockopt.c1448
-rw-r--r--sys/netinet/ipfw/ip_fw_table.c758
-rw-r--r--sys/netinet/ipfw/test/Makefile51
-rw-r--r--sys/netinet/ipfw/test/dn_test.h175
-rw-r--r--sys/netinet/ipfw/test/main.c636
-rw-r--r--sys/netinet/ipfw/test/mylist.h49
-rw-r--r--sys/netinet/ipfw/test/test_dn_heap.c162
-rw-r--r--sys/netinet/ipfw/test/test_dn_sched.c89
-rw-r--r--tools/build/mk/Makefile.boot3
-rw-r--r--usr.bin/apply/Makefile.depend20
-rw-r--r--usr.bin/ar/Makefile.depend26
-rw-r--r--usr.bin/asa/Makefile.depend18
-rw-r--r--usr.bin/at/Makefile.depend19
-rw-r--r--usr.bin/atm/sscop/Makefile.depend22
-rw-r--r--usr.bin/awk/Makefile.depend40
-rw-r--r--usr.bin/banner/Makefile.depend19
-rw-r--r--usr.bin/basename/Makefile.depend19
-rw-r--r--usr.bin/bc/Makefile.depend27
-rw-r--r--usr.bin/biff/Makefile.depend19
-rw-r--r--usr.bin/bluetooth/bthost/Makefile.depend20
-rw-r--r--usr.bin/bluetooth/btsockstat/Makefile.depend21
-rw-r--r--usr.bin/bluetooth/rfcomm_sppd/Makefile.depend21
-rw-r--r--usr.bin/brandelf/Makefile.depend19
-rw-r--r--usr.bin/bsdiff/bsdiff/Makefile.depend20
-rw-r--r--usr.bin/bsdiff/bspatch/Makefile.depend20
-rw-r--r--usr.bin/bzip2/Makefile.depend21
-rw-r--r--usr.bin/bzip2recover/Makefile.depend19
-rw-r--r--usr.bin/c89/Makefile.depend19
-rw-r--r--usr.bin/c99/Makefile.depend19
-rw-r--r--usr.bin/calendar/Makefile.depend20
-rw-r--r--usr.bin/cap_mkdb/Makefile.depend19
-rw-r--r--usr.bin/catman/Makefile.depend19
-rw-r--r--usr.bin/chat/Makefile.depend19
-rw-r--r--usr.bin/checknr/Makefile.depend19
-rw-r--r--usr.bin/chkey/Makefile.depend24
-rw-r--r--usr.bin/chpass/Makefile.depend22
-rw-r--r--usr.bin/cksum/Makefile.depend19
-rw-r--r--usr.bin/clang/clang-tblgen/Makefile.depend23
-rw-r--r--usr.bin/clang/clang/Makefile.depend104
-rw-r--r--usr.bin/clang/tblgen/Makefile.depend23
-rw-r--r--usr.bin/cmp/Makefile.depend19
-rw-r--r--usr.bin/col/Makefile.depend19
-rw-r--r--usr.bin/colcrt/Makefile.depend19
-rw-r--r--usr.bin/colldef/Makefile.depend26
-rw-r--r--usr.bin/colrm/Makefile.depend19
-rw-r--r--usr.bin/column/Makefile.depend19
-rw-r--r--usr.bin/comm/Makefile.depend19
-rw-r--r--usr.bin/compile_et/Makefile.depend30
-rw-r--r--usr.bin/compress/Makefile.depend19
-rw-r--r--usr.bin/cpio/Makefile.depend25
-rw-r--r--usr.bin/cpuset/Makefile.depend19
-rw-r--r--usr.bin/csplit/Makefile.depend19
-rw-r--r--usr.bin/csup/Makefile.depend31
-rw-r--r--usr.bin/ctags/Makefile.depend19
-rw-r--r--usr.bin/ctlstat/Makefile.depend19
-rw-r--r--usr.bin/cut/Makefile.depend19
-rw-r--r--usr.bin/dc/Makefile.depend21
-rw-r--r--usr.bin/dig/Makefile.depend28
-rw-r--r--usr.bin/dirname/Makefile.depend18
-rw-r--r--usr.bin/du/Makefile.depend20
-rw-r--r--usr.bin/ee/Makefile.depend21
-rw-r--r--usr.bin/elf2aout/Makefile.depend19
-rw-r--r--usr.bin/elfdump/Makefile.depend19
-rw-r--r--usr.bin/enigma/Makefile.depend20
-rw-r--r--usr.bin/env/Makefile.depend19
-rw-r--r--usr.bin/expand/Makefile.depend19
-rw-r--r--usr.bin/false/Makefile.depend18
-rw-r--r--usr.bin/fetch/Makefile.depend17
-rw-r--r--usr.bin/file/Makefile.depend21
-rw-r--r--usr.bin/file2c/Makefile.depend18
-rw-r--r--usr.bin/find/Makefile.depend21
-rw-r--r--usr.bin/finger/Makefile.depend19
-rw-r--r--usr.bin/fmt/Makefile.depend19
-rw-r--r--usr.bin/fold/Makefile.depend19
-rw-r--r--usr.bin/from/Makefile.depend19
-rw-r--r--usr.bin/fstat/Makefile.depend22
-rw-r--r--usr.bin/fsync/Makefile.depend18
-rw-r--r--usr.bin/ftp/Makefile.depend25
-rw-r--r--usr.bin/gcore/Makefile.depend20
-rw-r--r--usr.bin/gencat/Makefile.depend20
-rw-r--r--usr.bin/getconf/Makefile.depend29
-rw-r--r--usr.bin/getent/Makefile.depend21
-rw-r--r--usr.bin/getopt/Makefile.depend18
-rw-r--r--usr.bin/gprof/Makefile.depend19
-rw-r--r--usr.bin/grep/Makefile.depend23
-rw-r--r--usr.bin/gzip/Makefile.depend22
-rw-r--r--usr.bin/head/Makefile.depend19
-rw-r--r--usr.bin/hexdump/Makefile.depend19
-rw-r--r--usr.bin/host/Makefile.depend28
-rw-r--r--usr.bin/id/Makefile.depend20
-rw-r--r--usr.bin/indent/Makefile.depend19
-rw-r--r--usr.bin/ipcrm/Makefile.depend20
-rw-r--r--usr.bin/ipcs/Makefile.depend20
-rw-r--r--usr.bin/join/Makefile.depend19
-rw-r--r--usr.bin/jot/Makefile.depend19
-rw-r--r--usr.bin/kdump/Makefile.depend31
-rw-r--r--usr.bin/keylogin/Makefile.depend22
-rw-r--r--usr.bin/keylogout/Makefile.depend21
-rw-r--r--usr.bin/killall/Makefile.depend20
-rw-r--r--usr.bin/ktrace/Makefile.depend19
-rw-r--r--usr.bin/ktrdump/Makefile.depend20
-rw-r--r--usr.bin/lam/Makefile.depend19
-rw-r--r--usr.bin/last/Makefile.depend19
-rw-r--r--usr.bin/lastcomm/Makefile.depend19
-rw-r--r--usr.bin/ldd/Makefile.depend20
-rw-r--r--usr.bin/leave/Makefile.depend19
-rw-r--r--usr.bin/less/Makefile.depend21
-rw-r--r--usr.bin/lessecho/Makefile.depend19
-rw-r--r--usr.bin/lesskey/Makefile.depend19
-rw-r--r--usr.bin/lex/Makefile.depend29
-rw-r--r--usr.bin/lex/lib/Makefile.depend14
-rw-r--r--usr.bin/limits/Makefile.depend20
-rw-r--r--usr.bin/locale/Makefile.depend19
-rw-r--r--usr.bin/locate/bigram/Makefile.depend18
-rw-r--r--usr.bin/locate/code/Makefile.depend19
-rw-r--r--usr.bin/locate/locate/Makefile.depend20
-rw-r--r--usr.bin/lock/Makefile.depend20
-rw-r--r--usr.bin/lockf/Makefile.depend18
-rw-r--r--usr.bin/logger/Makefile.depend19
-rw-r--r--usr.bin/login/Makefile.depend22
-rw-r--r--usr.bin/logins/Makefile.depend19
-rw-r--r--usr.bin/logname/Makefile.depend18
-rw-r--r--usr.bin/look/Makefile.depend19
-rw-r--r--usr.bin/lorder/Makefile.depend14
-rw-r--r--usr.bin/lsvfs/Makefile.depend19
-rw-r--r--usr.bin/lzmainfo/Makefile.depend20
-rw-r--r--usr.bin/m4/Makefile.depend27
-rw-r--r--usr.bin/mail/Makefile.depend19
-rw-r--r--usr.bin/make/Makefile.depend18
-rw-r--r--usr.bin/makewhatis/Makefile.depend20
-rw-r--r--usr.bin/man/Makefile.depend14
-rw-r--r--usr.bin/mesg/Makefile.depend19
-rw-r--r--usr.bin/minigzip/Makefile.depend20
-rw-r--r--usr.bin/ministat/Makefile.depend20
-rw-r--r--usr.bin/mkcsmapper_static/Makefile.depend25
-rw-r--r--usr.bin/mkdep/Makefile.depend14
-rw-r--r--usr.bin/mkfifo/Makefile.depend19
-rw-r--r--usr.bin/mklocale/Makefile.depend26
-rw-r--r--usr.bin/mkstr/Makefile.depend19
-rw-r--r--usr.bin/mktemp/Makefile.depend19
-rw-r--r--usr.bin/mkulzma/Makefile.depend20
-rw-r--r--usr.bin/mkuzip/Makefile.depend20
-rw-r--r--usr.bin/msgs/Makefile.depend21
-rw-r--r--usr.bin/mt/Makefile.depend19
-rw-r--r--usr.bin/nc/Makefile.depend22
-rw-r--r--usr.bin/ncal/Makefile.depend22
-rw-r--r--usr.bin/ncplist/Makefile.depend20
-rw-r--r--usr.bin/ncplogin/Makefile.depend20
-rw-r--r--usr.bin/netstat/Makefile.depend25
-rw-r--r--usr.bin/newgrp/Makefile.depend21
-rw-r--r--usr.bin/newkey/Makefile.depend24
-rw-r--r--usr.bin/nfsstat/Makefile.depend20
-rw-r--r--usr.bin/nice/Makefile.depend19
-rw-r--r--usr.bin/nl/Makefile.depend19
-rw-r--r--usr.bin/nohup/Makefile.depend19
-rw-r--r--usr.bin/nslookup/Makefile.depend28
-rw-r--r--usr.bin/nsupdate/Makefile.depend28
-rw-r--r--usr.bin/opieinfo/Makefile.depend21
-rw-r--r--usr.bin/opiekey/Makefile.depend21
-rw-r--r--usr.bin/opiepasswd/Makefile.depend21
-rw-r--r--usr.bin/pagesize/Makefile.depend14
-rw-r--r--usr.bin/pamtest/Makefile.depend20
-rw-r--r--usr.bin/passwd/Makefile.depend19
-rw-r--r--usr.bin/paste/Makefile.depend19
-rw-r--r--usr.bin/pathchk/Makefile.depend19
-rw-r--r--usr.bin/perror/Makefile.depend19
-rw-r--r--usr.bin/pr/Makefile.depend19
-rw-r--r--usr.bin/printenv/Makefile.depend19
-rw-r--r--usr.bin/printf/Makefile.depend19
-rw-r--r--usr.bin/procstat/Makefile.depend23
-rw-r--r--usr.bin/quota/Makefile.depend23
-rw-r--r--usr.bin/rctl/Makefile.depend20
-rw-r--r--usr.bin/renice/Makefile.depend19
-rw-r--r--usr.bin/rev/Makefile.depend19
-rw-r--r--usr.bin/revoke/Makefile.depend18
-rw-r--r--usr.bin/rlogin/Makefile.depend19
-rw-r--r--usr.bin/rpcgen/Makefile.depend19
-rw-r--r--usr.bin/rpcinfo/Makefile.depend21
-rw-r--r--usr.bin/rs/Makefile.depend19
-rw-r--r--usr.bin/rsh/Makefile.depend20
-rw-r--r--usr.bin/rup/Makefile.depend23
-rw-r--r--usr.bin/ruptime/Makefile.depend20
-rw-r--r--usr.bin/rusers/Makefile.depend23
-rw-r--r--usr.bin/rwall/Makefile.depend21
-rw-r--r--usr.bin/rwho/Makefile.depend20
-rw-r--r--usr.bin/script/Makefile.depend20
-rw-r--r--usr.bin/sed/Makefile.depend19
-rw-r--r--usr.bin/seq/Makefile.depend20
-rw-r--r--usr.bin/setchannel/Makefile.depend19
-rw-r--r--usr.bin/shar/Makefile.depend14
-rw-r--r--usr.bin/showmount/Makefile.depend21
-rw-r--r--usr.bin/smbutil/Makefile.depend21
-rw-r--r--usr.bin/sockstat/Makefile.depend20
-rw-r--r--usr.bin/sort/Makefile.depend22
-rw-r--r--usr.bin/split/Makefile.depend19
-rw-r--r--usr.bin/stat/Makefile.depend19
-rw-r--r--usr.bin/stdbuf/Makefile.depend18
-rw-r--r--usr.bin/su/Makefile.depend22
-rw-r--r--usr.bin/systat/Makefile.depend24
-rw-r--r--usr.bin/tabs/Makefile.depend21
-rw-r--r--usr.bin/tail/Makefile.depend19
-rw-r--r--usr.bin/talk/Makefile.depend23
-rw-r--r--usr.bin/tar/Makefile.depend25
-rw-r--r--usr.bin/tcopy/Makefile.depend19
-rw-r--r--usr.bin/tee/Makefile.depend19
-rw-r--r--usr.bin/telnet/Makefile.depend33
-rw-r--r--usr.bin/tftp/Makefile.depend22
-rw-r--r--usr.bin/time/Makefile.depend19
-rw-r--r--usr.bin/tip/tip/Makefile.depend19
-rw-r--r--usr.bin/top/Makefile.depend30
-rw-r--r--usr.bin/touch/Makefile.depend19
-rw-r--r--usr.bin/tput/Makefile.depend21
-rw-r--r--usr.bin/tr/Makefile.depend19
-rw-r--r--usr.bin/true/Makefile.depend17
-rw-r--r--usr.bin/truncate/Makefile.depend20
-rw-r--r--usr.bin/truss/Makefile.depend27
-rw-r--r--usr.bin/tset/Makefile.depend21
-rw-r--r--usr.bin/tsort/Makefile.depend19
-rw-r--r--usr.bin/tty/Makefile.depend18
-rw-r--r--usr.bin/ul/Makefile.depend21
-rw-r--r--usr.bin/uname/Makefile.depend18
-rw-r--r--usr.bin/unexpand/Makefile.depend19
-rw-r--r--usr.bin/unifdef/Makefile.depend19
-rw-r--r--usr.bin/uniq/Makefile.depend19
-rw-r--r--usr.bin/units/Makefile.depend19
-rw-r--r--usr.bin/unvis/Makefile.depend18
-rw-r--r--usr.bin/unzip/Makefile.depend21
-rw-r--r--usr.bin/usbhidaction/Makefile.depend20
-rw-r--r--usr.bin/usbhidctl/Makefile.depend20
-rw-r--r--usr.bin/users/Makefile.depend19
-rw-r--r--usr.bin/uudecode/Makefile.depend20
-rw-r--r--usr.bin/uuencode/Makefile.depend20
-rw-r--r--usr.bin/vacation/Makefile.depend25
-rw-r--r--usr.bin/vgrind/Makefile.depend19
-rw-r--r--usr.bin/vgrind/RETEST/Makefile.depend19
-rw-r--r--usr.bin/vi/Makefile.depend21
-rw-r--r--usr.bin/vis/Makefile.depend19
-rw-r--r--usr.bin/vmstat/Makefile.depend23
-rw-r--r--usr.bin/w/Makefile.depend22
-rw-r--r--usr.bin/wall/Makefile.depend19
-rw-r--r--usr.bin/wc/Makefile.depend19
-rw-r--r--usr.bin/what/Makefile.depend18
-rw-r--r--usr.bin/whereis/Makefile.depend19
-rw-r--r--usr.bin/which/Makefile.depend19
-rw-r--r--usr.bin/who/Makefile.depend19
-rw-r--r--usr.bin/whois/Makefile.depend20
-rw-r--r--usr.bin/write/Makefile.depend19
-rw-r--r--usr.bin/xargs/Makefile.depend19
-rw-r--r--usr.bin/xinstall/Makefile.depend19
-rw-r--r--usr.bin/xlint/lint1/Makefile.depend30
-rw-r--r--usr.bin/xlint/lint2/Makefile.depend19
-rw-r--r--usr.bin/xlint/llib/Makefile.depend14
-rw-r--r--usr.bin/xlint/xlint/Makefile.depend19
-rw-r--r--usr.bin/xstr/Makefile.depend19
-rw-r--r--usr.bin/xz/Makefile.depend20
-rw-r--r--usr.bin/xzdec/Makefile.depend20
-rw-r--r--usr.bin/yacc/Makefile.depend19
-rw-r--r--usr.bin/yes/Makefile.depend18
-rw-r--r--usr.bin/ypcat/Makefile.depend21
-rw-r--r--usr.bin/ypmatch/Makefile.depend21
-rw-r--r--usr.bin/ypwhich/Makefile.depend22
-rw-r--r--usr.sbin/IPXrouted/Makefile.depend20
-rw-r--r--usr.sbin/ac/Makefile.depend19
-rw-r--r--usr.sbin/accton/Makefile.depend19
-rw-r--r--usr.sbin/acpi/acpiconf/Makefile.depend19
-rw-r--r--usr.sbin/acpi/acpidb/Makefile.depend20
-rw-r--r--usr.sbin/acpi/acpidump/Makefile.depend19
-rw-r--r--usr.sbin/acpi/iasl/Makefile.depend87
-rw-r--r--usr.sbin/adduser/Makefile.depend14
-rw-r--r--usr.sbin/amd/amd/Makefile.depend33
-rw-r--r--usr.sbin/amd/amq/Makefile.depend25
-rw-r--r--usr.sbin/amd/fixmount/Makefile.depend26
-rw-r--r--usr.sbin/amd/fsinfo/Makefile.depend33
-rw-r--r--usr.sbin/amd/hlfsd/Makefile.depend25
-rw-r--r--usr.sbin/amd/include/Makefile.depend14
-rw-r--r--usr.sbin/amd/libamu/Makefile.depend25
-rw-r--r--usr.sbin/amd/mk-amd-map/Makefile.depend25
-rw-r--r--usr.sbin/amd/pawd/Makefile.depend25
-rw-r--r--usr.sbin/amd/scripts/Makefile.depend14
-rw-r--r--usr.sbin/amd/wire-test/Makefile.depend25
-rw-r--r--usr.sbin/ancontrol/Makefile.depend21
-rw-r--r--usr.sbin/apm/Makefile.depend19
-rw-r--r--usr.sbin/apmd/Makefile.depend25
-rw-r--r--usr.sbin/arp/Makefile.depend20
-rw-r--r--usr.sbin/arpaname/Makefile.depend28
-rw-r--r--usr.sbin/asf/Makefile.depend20
-rw-r--r--usr.sbin/audit/Makefile.depend20
-rw-r--r--usr.sbin/auditd/Makefile.depend21
-rw-r--r--usr.sbin/auditreduce/Makefile.depend20
-rw-r--r--usr.sbin/authpf/Makefile.depend23
-rw-r--r--usr.sbin/bluetooth/ath3kfw/Makefile.depend20
-rw-r--r--usr.sbin/bluetooth/bcmfw/Makefile.depend20
-rw-r--r--usr.sbin/bluetooth/bt3cfw/Makefile.depend20
-rw-r--r--usr.sbin/bluetooth/bthidcontrol/Makefile.depend28
-rw-r--r--usr.sbin/bluetooth/bthidd/Makefile.depend27
-rw-r--r--usr.sbin/bluetooth/btpand/Makefile.depend22
-rw-r--r--usr.sbin/bluetooth/hccontrol/Makefile.depend20
-rw-r--r--usr.sbin/bluetooth/hcsecd/Makefile.depend26
-rw-r--r--usr.sbin/bluetooth/hcseriald/Makefile.depend20
-rw-r--r--usr.sbin/bluetooth/l2control/Makefile.depend20
-rw-r--r--usr.sbin/bluetooth/l2ping/Makefile.depend21
-rw-r--r--usr.sbin/bluetooth/rfcomm_pppd/Makefile.depend21
-rw-r--r--usr.sbin/bluetooth/sdpcontrol/Makefile.depend21
-rw-r--r--usr.sbin/bluetooth/sdpd/Makefile.depend22
-rw-r--r--usr.sbin/boot0cfg/Makefile.depend22
-rw-r--r--usr.sbin/boot98cfg/Makefile.depend20
-rw-r--r--usr.sbin/bootparamd/bootparamd/Makefile.depend34
-rw-r--r--usr.sbin/bootparamd/callbootd/Makefile.depend31
-rw-r--r--usr.sbin/bsdinstall/Makefile.depend14
-rw-r--r--usr.sbin/bsdinstall/distextract/Makefile.depend23
-rw-r--r--usr.sbin/bsdinstall/distfetch/Makefile.depend23
-rw-r--r--usr.sbin/bsdinstall/partedit/Makefile.depend24
-rw-r--r--usr.sbin/bsnmpd/bsnmpd/Makefile.depend51
-rw-r--r--usr.sbin/bsnmpd/gensnmptree/Makefile.depend19
-rw-r--r--usr.sbin/bsnmpd/modules/Makefile.depend14
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_atm/Makefile.depend30
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/Makefile.depend38
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_hostres/Makefile.depend79
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_mibII/Makefile.depend68
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile.depend27
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_pf/Makefile.depend26
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_target/Makefile.depend25
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_usm/Makefile.depend25
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_vacm/Makefile.depend25
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_wlan/Makefile.depend29
-rw-r--r--usr.sbin/bsnmpd/tools/bsnmptools/Makefile.depend22
-rw-r--r--usr.sbin/bsnmpd/tools/libbsnmptools/Makefile.depend18
-rw-r--r--usr.sbin/btxld/Makefile.depend19
-rw-r--r--usr.sbin/burncd/Makefile.depend20
-rw-r--r--usr.sbin/cdcontrol/Makefile.depend22
-rw-r--r--usr.sbin/chkgrp/Makefile.depend19
-rw-r--r--usr.sbin/chown/Makefile.depend19
-rw-r--r--usr.sbin/chroot/Makefile.depend19
-rw-r--r--usr.sbin/ckdist/Makefile.depend20
-rw-r--r--usr.sbin/clear_locks/Makefile.depend22
-rw-r--r--usr.sbin/config/Makefile.depend36
-rw-r--r--usr.sbin/cpucontrol/Makefile.depend19
-rw-r--r--usr.sbin/crashinfo/Makefile.depend14
-rw-r--r--usr.sbin/cron/cron/Makefile.depend22
-rw-r--r--usr.sbin/cron/crontab/Makefile.depend22
-rw-r--r--usr.sbin/cron/lib/Makefile.depend17
-rw-r--r--usr.sbin/crunch/crunchgen/Makefile.depend21
-rw-r--r--usr.sbin/crunch/crunchide/Makefile.depend19
-rw-r--r--usr.sbin/ctladm/Makefile.depend23
-rw-r--r--usr.sbin/ctm/ctm/Makefile.depend20
-rw-r--r--usr.sbin/ctm/ctm_dequeue/Makefile.depend19
-rw-r--r--usr.sbin/ctm/ctm_rmail/Makefile.depend19
-rw-r--r--usr.sbin/ctm/ctm_smail/Makefile.depend19
-rw-r--r--usr.sbin/daemon/Makefile.depend19
-rw-r--r--usr.sbin/dconschat/Makefile.depend21
-rw-r--r--usr.sbin/ddns-confgen/Makefile.depend28
-rw-r--r--usr.sbin/devinfo/Makefile.depend19
-rw-r--r--usr.sbin/digictl/Makefile.depend19
-rw-r--r--usr.sbin/diskinfo/Makefile.depend20
-rw-r--r--usr.sbin/dnssec-dsfromkey/Makefile.depend28
-rw-r--r--usr.sbin/dnssec-keyfromlabel/Makefile.depend28
-rw-r--r--usr.sbin/dnssec-keygen/Makefile.depend28
-rw-r--r--usr.sbin/dnssec-revoke/Makefile.depend28
-rw-r--r--usr.sbin/dnssec-settime/Makefile.depend28
-rw-r--r--usr.sbin/dnssec-signzone/Makefile.depend28
-rw-r--r--usr.sbin/dumpcis/Makefile.depend19
-rw-r--r--usr.sbin/editmap/Makefile.depend25
-rw-r--r--usr.sbin/edquota/Makefile.depend20
-rw-r--r--usr.sbin/eeprom/Makefile.depend19
-rw-r--r--usr.sbin/extattr/Makefile.depend20
-rw-r--r--usr.sbin/extattrctl/Makefile.depend20
-rw-r--r--usr.sbin/faithd/Makefile.depend21
-rw-r--r--usr.sbin/fdcontrol/Makefile.depend19
-rw-r--r--usr.sbin/fdformat/Makefile.depend19
-rw-r--r--usr.sbin/fdread/Makefile.depend19
-rw-r--r--usr.sbin/fdwrite/Makefile.depend19
-rw-r--r--usr.sbin/fifolog/fifolog_create/Makefile.depend20
-rw-r--r--usr.sbin/fifolog/fifolog_reader/Makefile.depend22
-rw-r--r--usr.sbin/fifolog/fifolog_writer/Makefile.depend22
-rw-r--r--usr.sbin/fifolog/lib/Makefile.depend19
-rw-r--r--usr.sbin/flowctl/Makefile.depend21
-rw-r--r--usr.sbin/freebsd-update/Makefile.depend14
-rw-r--r--usr.sbin/ftp-proxy/ftp-proxy/Makefile.depend21
-rw-r--r--usr.sbin/ftp-proxy/libevent/Makefile.depend16
-rw-r--r--usr.sbin/fwcontrol/Makefile.depend20
-rw-r--r--usr.sbin/genrandom/Makefile.depend27
-rw-r--r--usr.sbin/getfmac/Makefile.depend19
-rw-r--r--usr.sbin/getpmac/Makefile.depend19
-rw-r--r--usr.sbin/gpioctl/Makefile.depend19
-rw-r--r--usr.sbin/gssd/Makefile.depend34
-rw-r--r--usr.sbin/gstat/Makefile.depend27
-rw-r--r--usr.sbin/i2c/Makefile.depend19
-rw-r--r--usr.sbin/ifmcstat/Makefile.depend21
-rw-r--r--usr.sbin/inetd/Makefile.depend24
-rw-r--r--usr.sbin/iostat/Makefile.depend22
-rw-r--r--usr.sbin/ip6addrctl/Makefile.depend19
-rw-r--r--usr.sbin/ipfwpcap/Makefile.depend20
-rw-r--r--usr.sbin/isc-hmac-fixup/Makefile.depend27
-rw-r--r--usr.sbin/jail/Makefile.depend29
-rw-r--r--usr.sbin/jexec/Makefile.depend22
-rw-r--r--usr.sbin/jls/Makefile.depend21
-rw-r--r--usr.sbin/kbdcontrol/Makefile.depend21
-rw-r--r--usr.sbin/kbdmap/Makefile.depend19
-rw-r--r--usr.sbin/keyserv/Makefile.depend30
-rw-r--r--usr.sbin/kgmon/Makefile.depend20
-rw-r--r--usr.sbin/kgzip/Makefile.depend19
-rw-r--r--usr.sbin/kldxref/Makefile.depend19
-rw-r--r--usr.sbin/lastlogin/Makefile.depend19
-rw-r--r--usr.sbin/lmcconfig/Makefile.depend20
-rw-r--r--usr.sbin/lpr/chkprintcap/Makefile.depend20
-rw-r--r--usr.sbin/lpr/common_source/Makefile.depend17
-rw-r--r--usr.sbin/lpr/filters.ru/Makefile.depend14
-rw-r--r--usr.sbin/lpr/filters.ru/koi2855/Makefile.depend18
-rw-r--r--usr.sbin/lpr/filters.ru/koi2alt/Makefile.depend18
-rw-r--r--usr.sbin/lpr/filters/Makefile.depend19
-rw-r--r--usr.sbin/lpr/lp/Makefile.depend14
-rw-r--r--usr.sbin/lpr/lpc/Makefile.depend22
-rw-r--r--usr.sbin/lpr/lpd/Makefile.depend21
-rw-r--r--usr.sbin/lpr/lpq/Makefile.depend20
-rw-r--r--usr.sbin/lpr/lpr/Makefile.depend20
-rw-r--r--usr.sbin/lpr/lprm/Makefile.depend20
-rw-r--r--usr.sbin/lpr/lptest/Makefile.depend18
-rw-r--r--usr.sbin/lpr/pac/Makefile.depend20
-rw-r--r--usr.sbin/lptcontrol/Makefile.depend18
-rw-r--r--usr.sbin/mailstats/Makefile.depend24
-rw-r--r--usr.sbin/mailwrapper/Makefile.depend20
-rw-r--r--usr.sbin/makefs/Makefile.depend20
-rw-r--r--usr.sbin/makemap/Makefile.depend25
-rw-r--r--usr.sbin/manctl/Makefile.depend14
-rw-r--r--usr.sbin/memcontrol/Makefile.depend19
-rw-r--r--usr.sbin/mergemaster/Makefile.depend14
-rw-r--r--usr.sbin/mfiutil/Makefile.depend20
-rw-r--r--usr.sbin/mixer/Makefile.depend19
-rw-r--r--usr.sbin/mld6query/Makefile.depend20
-rw-r--r--usr.sbin/mlxcontrol/Makefile.depend19
-rw-r--r--usr.sbin/mount_nwfs/Makefile.depend20
-rw-r--r--usr.sbin/mount_portalfs/Makefile.depend20
-rw-r--r--usr.sbin/mount_smbfs/Makefile.depend20
-rw-r--r--usr.sbin/mountd/Makefile.depend23
-rw-r--r--usr.sbin/moused/Makefile.depend21
-rw-r--r--usr.sbin/mptable/Makefile.depend19
-rw-r--r--usr.sbin/mptutil/Makefile.depend22
-rw-r--r--usr.sbin/mtest/Makefile.depend20
-rw-r--r--usr.sbin/mtree/Makefile.depend20
-rw-r--r--usr.sbin/named-checkconf/Makefile.depend28
-rw-r--r--usr.sbin/named-checkzone/Makefile.depend28
-rw-r--r--usr.sbin/named-journalprint/Makefile.depend27
-rw-r--r--usr.sbin/named/Makefile.depend28
-rw-r--r--usr.sbin/ndiscvt/Makefile.depend25
-rw-r--r--usr.sbin/ndp/Makefile.depend20
-rw-r--r--usr.sbin/newsyslog/Makefile.depend19
-rw-r--r--usr.sbin/nfscbd/Makefile.depend20
-rw-r--r--usr.sbin/nfsd/Makefile.depend22
-rw-r--r--usr.sbin/nfsdumpstate/Makefile.depend20
-rw-r--r--usr.sbin/nfsrevoke/Makefile.depend19
-rw-r--r--usr.sbin/nfsuserd/Makefile.depend20
-rw-r--r--usr.sbin/ngctl/Makefile.depend23
-rw-r--r--usr.sbin/nghook/Makefile.depend20
-rw-r--r--usr.sbin/nologin/Makefile.depend17
-rw-r--r--usr.sbin/nscd/Makefile.depend22
-rw-r--r--usr.sbin/nsec3hash/Makefile.depend28
-rw-r--r--usr.sbin/ntp/libntp/Makefile.depend20
-rw-r--r--usr.sbin/ntp/libopts/Makefile.depend16
-rw-r--r--usr.sbin/ntp/libparse/Makefile.depend18
-rw-r--r--usr.sbin/ntp/ntp-keygen/Makefile.depend23
-rw-r--r--usr.sbin/ntp/ntpd/Makefile.depend29
-rw-r--r--usr.sbin/ntp/ntpdate/Makefile.depend27
-rw-r--r--usr.sbin/ntp/ntpdc/Makefile.depend30
-rw-r--r--usr.sbin/ntp/ntpq/Makefile.depend30
-rw-r--r--usr.sbin/ntp/ntptime/Makefile.depend20
-rw-r--r--usr.sbin/ntp/sntp/Makefile.depend22
-rw-r--r--usr.sbin/ofwdump/Makefile.depend19
-rw-r--r--usr.sbin/pc-sysinstall/backend-partmanager/Makefile.depend14
-rw-r--r--usr.sbin/pc-sysinstall/backend-query/Makefile.depend14
-rw-r--r--usr.sbin/pc-sysinstall/backend/Makefile.depend14
-rw-r--r--usr.sbin/pc-sysinstall/conf/Makefile.depend14
-rw-r--r--usr.sbin/pc-sysinstall/pc-sysinstall/Makefile.depend14
-rw-r--r--usr.sbin/pciconf/Makefile.depend19
-rw-r--r--usr.sbin/periodic/Makefile.depend14
-rw-r--r--usr.sbin/pkg/Makefile.depend22
-rw-r--r--usr.sbin/pkg_install/add/Makefile.depend25
-rw-r--r--usr.sbin/pkg_install/create/Makefile.depend22
-rw-r--r--usr.sbin/pkg_install/delete/Makefile.depend22
-rw-r--r--usr.sbin/pkg_install/info/Makefile.depend25
-rw-r--r--usr.sbin/pkg_install/lib/Makefile.depend19
-rw-r--r--usr.sbin/pkg_install/updating/Makefile.depend25
-rw-r--r--usr.sbin/pkg_install/version/Makefile.depend25
-rw-r--r--usr.sbin/pmcannotate/Makefile.depend19
-rw-r--r--usr.sbin/pmccontrol/Makefile.depend20
-rw-r--r--usr.sbin/pmcstat/Makefile.depend25
-rw-r--r--usr.sbin/pnpinfo/Makefile.depend19
-rw-r--r--usr.sbin/portsnap/make_index/Makefile.depend19
-rw-r--r--usr.sbin/portsnap/phttpget/Makefile.depend19
-rw-r--r--usr.sbin/portsnap/portsnap/Makefile.depend14
-rw-r--r--usr.sbin/powerd/Makefile.depend20
-rw-r--r--usr.sbin/ppp/Makefile.depend29
-rw-r--r--usr.sbin/pppctl/Makefile.depend23
-rw-r--r--usr.sbin/praliases/Makefile.depend25
-rw-r--r--usr.sbin/praudit/Makefile.depend20
-rw-r--r--usr.sbin/procctl/Makefile.depend19
-rw-r--r--usr.sbin/pstat/Makefile.depend21
-rw-r--r--usr.sbin/pw/Makefile.depend21
-rw-r--r--usr.sbin/pwd_mkdb/Makefile.depend20
-rw-r--r--usr.sbin/quot/Makefile.depend19
-rw-r--r--usr.sbin/quotaon/Makefile.depend20
-rw-r--r--usr.sbin/rarpd/Makefile.depend20
-rw-r--r--usr.sbin/repquota/Makefile.depend20
-rw-r--r--usr.sbin/rip6query/Makefile.depend20
-rw-r--r--usr.sbin/rmt/Makefile.depend19
-rw-r--r--usr.sbin/rndc-confgen/Makefile.depend28
-rw-r--r--usr.sbin/rndc/Makefile.depend28
-rw-r--r--usr.sbin/route6d/Makefile.depend20
-rw-r--r--usr.sbin/rpc.lockd/Makefile.depend26
-rw-r--r--usr.sbin/rpc.statd/Makefile.depend32
-rw-r--r--usr.sbin/rpc.umntall/Makefile.depend21
-rw-r--r--usr.sbin/rpc.yppasswdd/Makefile.depend49
-rw-r--r--usr.sbin/rpc.ypupdated/Makefile.depend30
-rw-r--r--usr.sbin/rpc.ypxfrd/Makefile.depend31
-rw-r--r--usr.sbin/rpcbind/Makefile.depend24
-rw-r--r--usr.sbin/rrenumd/Makefile.depend28
-rw-r--r--usr.sbin/rtadvctl/Makefile.depend20
-rw-r--r--usr.sbin/rtadvd/Makefile.depend21
-rw-r--r--usr.sbin/rtprio/Makefile.depend19
-rw-r--r--usr.sbin/rtsold/Makefile.depend21
-rw-r--r--usr.sbin/rwhod/Makefile.depend21
-rw-r--r--usr.sbin/sa/Makefile.depend19
-rw-r--r--usr.sbin/sade/Makefile.depend24
-rw-r--r--usr.sbin/sendmail/Makefile.depend107
-rw-r--r--usr.sbin/service/Makefile.depend14
-rw-r--r--usr.sbin/services_mkdb/Makefile.depend20
-rw-r--r--usr.sbin/setfib/Makefile.depend19
-rw-r--r--usr.sbin/setfmac/Makefile.depend19
-rw-r--r--usr.sbin/setpmac/Makefile.depend19
-rw-r--r--usr.sbin/sicontrol/Makefile.depend19
-rw-r--r--usr.sbin/smbmsg/Makefile.depend19
-rw-r--r--usr.sbin/snapinfo/Makefile.depend20
-rw-r--r--usr.sbin/spkrtest/Makefile.depend14
-rw-r--r--usr.sbin/spray/Makefile.depend22
-rw-r--r--usr.sbin/syslogd/Makefile.depend21
-rw-r--r--usr.sbin/tcpdchk/Makefile.depend21
-rw-r--r--usr.sbin/tcpdmatch/Makefile.depend21
-rw-r--r--usr.sbin/tcpdrop/Makefile.depend19
-rw-r--r--usr.sbin/tcpdump/tcpdump/Makefile.depend25
-rw-r--r--usr.sbin/timed/timed/Makefile.depend23
-rw-r--r--usr.sbin/timed/timedc/Makefile.depend21
-rw-r--r--usr.sbin/traceroute/Makefile.depend23
-rw-r--r--usr.sbin/traceroute6/Makefile.depend21
-rw-r--r--usr.sbin/trpt/Makefile.depend20
-rw-r--r--usr.sbin/tzsetup/Makefile.depend22
-rw-r--r--usr.sbin/uathload/Makefile.depend19
-rw-r--r--usr.sbin/ugidfw/Makefile.depend20
-rw-r--r--usr.sbin/uhsoctl/Makefile.depend21
-rw-r--r--usr.sbin/usbconfig/Makefile.depend20
-rw-r--r--usr.sbin/usbdump/Makefile.depend19
-rw-r--r--usr.sbin/utx/Makefile.depend19
-rw-r--r--usr.sbin/vidcontrol/Makefile.depend19
-rw-r--r--usr.sbin/vipw/Makefile.depend20
-rw-r--r--usr.sbin/wake/Makefile.depend19
-rw-r--r--usr.sbin/watch/Makefile.depend21
-rw-r--r--usr.sbin/watchdogd/Makefile.depend21
-rw-r--r--usr.sbin/wlandebug/Makefile.depend19
-rw-r--r--usr.sbin/wlconfig/Makefile.depend19
-rw-r--r--usr.sbin/wpa/hostapd/Makefile.depend23
-rw-r--r--usr.sbin/wpa/hostapd_cli/Makefile.depend20
-rw-r--r--usr.sbin/wpa/ndis_events/Makefile.depend20
-rw-r--r--usr.sbin/wpa/wpa_cli/Makefile.depend23
-rw-r--r--usr.sbin/wpa/wpa_passphrase/Makefile.depend20
-rw-r--r--usr.sbin/wpa/wpa_supplicant/Makefile.depend23
-rw-r--r--usr.sbin/yp_mkdb/Makefile.depend21
-rw-r--r--usr.sbin/ypbind/Makefile.depend22
-rw-r--r--usr.sbin/yppoll/Makefile.depend21
-rw-r--r--usr.sbin/yppush/Makefile.depend29
-rw-r--r--usr.sbin/ypserv/Makefile.depend35
-rw-r--r--usr.sbin/ypset/Makefile.depend22
-rw-r--r--usr.sbin/zic/zdump/Makefile.depend19
-rw-r--r--usr.sbin/zic/zic/Makefile.depend19
-rw-r--r--usr.sbin/zzz/Makefile.depend14
1581 files changed, 180371 insertions, 14 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1
index 81bb6bc..945289b3 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -85,6 +85,8 @@ SUBDIR+=sys usr.bin usr.sbin
.if ${MK_OFED} != "no"
SUBDIR+=contrib/ofed
.endif
+SUBDIR+=external/bsd
+
#
# We must do etc/ last for install/distribute to work.
#
@@ -245,6 +247,7 @@ BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \
DESTDIR= \
BOOTSTRAPPING=${OSRELDATE} \
SSP_CFLAGS= \
+ -DWITHOUT_META_MODE \
-DWITHOUT_HTML -DWITHOUT_INFO -DNO_LINT -DWITHOUT_MAN \
-DNO_PIC -DNO_PROFILE -DNO_SHARED \
-DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF -DEARLY_BUILD
@@ -256,12 +259,14 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \
DESTDIR= \
BOOTSTRAPPING=${OSRELDATE} \
SSP_CFLAGS= \
+ -DWITHOUT_META_MODE \
-DNO_LINT \
-DNO_CPU_CFLAGS -DNO_WARNS -DNO_CTF -DEARLY_BUILD
# cross-tools stage
XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \
TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
+ -DWITHOUT_META_MODE \
-DWITHOUT_GDB
# world stage
@@ -1723,3 +1728,5 @@ _xi-links:
xdev xdev-buil xdev-install:
@echo "*** Error: Both XDEV and XDEV_ARCH must be defined for \"${.TARGET}\" target"
.endif
+
+.MAKE.MODE= normal
diff --git a/bin/cat/Makefile.depend b/bin/cat/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/cat/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/chflags/Makefile.depend b/bin/chflags/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/chflags/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/chio/Makefile.depend b/bin/chio/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/chio/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/chmod/Makefile.depend b/bin/chmod/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/chmod/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/cp/Makefile.depend b/bin/cp/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/cp/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/csh/Makefile.depend b/bin/csh/Makefile.depend
new file mode 100644
index 0000000..ee77884
--- /dev/null
+++ b/bin/csh/Makefile.depend
@@ -0,0 +1,348 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ed.chared.o: ed.defns.h
+ed.chared.o: iconv.h
+ed.chared.o: sh.err.h
+ed.chared.o: tc.const.h
+ed.chared.po: ed.defns.h
+ed.chared.po: iconv.h
+ed.chared.po: sh.err.h
+ed.chared.po: tc.const.h
+ed.defns.o: iconv.h
+ed.defns.o: sh.err.h
+ed.defns.o: tc.const.h
+ed.defns.po: iconv.h
+ed.defns.po: sh.err.h
+ed.defns.po: tc.const.h
+ed.init.o: ed.defns.h
+ed.init.o: iconv.h
+ed.init.o: sh.err.h
+ed.init.o: tc.const.h
+ed.init.po: ed.defns.h
+ed.init.po: iconv.h
+ed.init.po: sh.err.h
+ed.init.po: tc.const.h
+ed.inputl.o: ed.defns.h
+ed.inputl.o: iconv.h
+ed.inputl.o: sh.err.h
+ed.inputl.o: tc.const.h
+ed.inputl.po: ed.defns.h
+ed.inputl.po: iconv.h
+ed.inputl.po: sh.err.h
+ed.inputl.po: tc.const.h
+ed.refresh.o: iconv.h
+ed.refresh.o: sh.err.h
+ed.refresh.o: tc.const.h
+ed.refresh.po: iconv.h
+ed.refresh.po: sh.err.h
+ed.refresh.po: tc.const.h
+ed.screen.o: ed.defns.h
+ed.screen.o: iconv.h
+ed.screen.o: sh.err.h
+ed.screen.o: tc.const.h
+ed.screen.po: ed.defns.h
+ed.screen.po: iconv.h
+ed.screen.po: sh.err.h
+ed.screen.po: tc.const.h
+ed.term.o: iconv.h
+ed.term.o: sh.err.h
+ed.term.o: tc.const.h
+ed.term.po: iconv.h
+ed.term.po: sh.err.h
+ed.term.po: tc.const.h
+ed.xmap.o: ed.defns.h
+ed.xmap.o: iconv.h
+ed.xmap.o: sh.err.h
+ed.xmap.o: tc.const.h
+ed.xmap.po: ed.defns.h
+ed.xmap.po: iconv.h
+ed.xmap.po: sh.err.h
+ed.xmap.po: tc.const.h
+glob.o: iconv.h
+glob.o: sh.err.h
+glob.o: tc.const.h
+glob.po: iconv.h
+glob.po: sh.err.h
+glob.po: tc.const.h
+iconv_stub.o: iconv.h
+iconv_stub.po: iconv.h
+mi.termios.o: iconv.h
+mi.termios.o: sh.err.h
+mi.termios.o: tc.const.h
+mi.termios.po: iconv.h
+mi.termios.po: sh.err.h
+mi.termios.po: tc.const.h
+sh.char.o: iconv.h
+sh.char.o: sh.err.h
+sh.char.o: tc.const.h
+sh.char.po: iconv.h
+sh.char.po: sh.err.h
+sh.char.po: tc.const.h
+sh.dir.o: iconv.h
+sh.dir.o: sh.err.h
+sh.dir.o: tc.const.h
+sh.dir.po: iconv.h
+sh.dir.po: sh.err.h
+sh.dir.po: tc.const.h
+sh.dol.o: iconv.h
+sh.dol.o: sh.err.h
+sh.dol.o: tc.const.h
+sh.dol.po: iconv.h
+sh.dol.po: sh.err.h
+sh.dol.po: tc.const.h
+sh.err.o: iconv.h
+sh.err.o: sh.err.h
+sh.err.o: tc.const.h
+sh.err.po: iconv.h
+sh.err.po: sh.err.h
+sh.err.po: tc.const.h
+sh.exec.o: iconv.h
+sh.exec.o: sh.err.h
+sh.exec.o: tc.const.h
+sh.exec.po: iconv.h
+sh.exec.po: sh.err.h
+sh.exec.po: tc.const.h
+sh.exp.o: iconv.h
+sh.exp.o: sh.err.h
+sh.exp.o: tc.const.h
+sh.exp.po: iconv.h
+sh.exp.po: sh.err.h
+sh.exp.po: tc.const.h
+sh.file.o: iconv.h
+sh.file.o: sh.err.h
+sh.file.o: tc.const.h
+sh.file.po: iconv.h
+sh.file.po: sh.err.h
+sh.file.po: tc.const.h
+sh.func.o: iconv.h
+sh.func.o: sh.err.h
+sh.func.o: tc.const.h
+sh.func.po: iconv.h
+sh.func.po: sh.err.h
+sh.func.po: tc.const.h
+sh.glob.o: iconv.h
+sh.glob.o: sh.err.h
+sh.glob.o: tc.const.h
+sh.glob.po: iconv.h
+sh.glob.po: sh.err.h
+sh.glob.po: tc.const.h
+sh.hist.o: iconv.h
+sh.hist.o: sh.err.h
+sh.hist.o: tc.const.h
+sh.hist.po: iconv.h
+sh.hist.po: sh.err.h
+sh.hist.po: tc.const.h
+sh.init.o: iconv.h
+sh.init.o: sh.err.h
+sh.init.o: tc.const.h
+sh.init.po: iconv.h
+sh.init.po: sh.err.h
+sh.init.po: tc.const.h
+sh.lex.o: iconv.h
+sh.lex.o: sh.err.h
+sh.lex.o: tc.const.h
+sh.lex.po: iconv.h
+sh.lex.po: sh.err.h
+sh.lex.po: tc.const.h
+sh.misc.o: iconv.h
+sh.misc.o: sh.err.h
+sh.misc.o: tc.const.h
+sh.misc.po: iconv.h
+sh.misc.po: sh.err.h
+sh.misc.po: tc.const.h
+sh.o: iconv.h
+sh.o: sh.err.h
+sh.o: tc.const.h
+sh.parse.o: iconv.h
+sh.parse.o: sh.err.h
+sh.parse.o: tc.const.h
+sh.parse.po: iconv.h
+sh.parse.po: sh.err.h
+sh.parse.po: tc.const.h
+sh.po: iconv.h
+sh.po: sh.err.h
+sh.po: tc.const.h
+sh.print.o: iconv.h
+sh.print.o: sh.err.h
+sh.print.o: tc.const.h
+sh.print.po: iconv.h
+sh.print.po: sh.err.h
+sh.print.po: tc.const.h
+sh.proc.o: iconv.h
+sh.proc.o: sh.err.h
+sh.proc.o: tc.const.h
+sh.proc.po: iconv.h
+sh.proc.po: sh.err.h
+sh.proc.po: tc.const.h
+sh.sem.o: iconv.h
+sh.sem.o: sh.err.h
+sh.sem.o: tc.const.h
+sh.sem.po: iconv.h
+sh.sem.po: sh.err.h
+sh.sem.po: tc.const.h
+sh.set.o: iconv.h
+sh.set.o: sh.err.h
+sh.set.o: tc.const.h
+sh.set.po: iconv.h
+sh.set.po: sh.err.h
+sh.set.po: tc.const.h
+sh.time.o: iconv.h
+sh.time.o: sh.err.h
+sh.time.o: tc.const.h
+sh.time.po: iconv.h
+sh.time.po: sh.err.h
+sh.time.po: tc.const.h
+tc.alloc.o: iconv.h
+tc.alloc.o: sh.err.h
+tc.alloc.o: tc.const.h
+tc.alloc.po: iconv.h
+tc.alloc.po: sh.err.h
+tc.alloc.po: tc.const.h
+tc.bind.o: ed.defns.h
+tc.bind.o: iconv.h
+tc.bind.o: sh.err.h
+tc.bind.o: tc.const.h
+tc.bind.po: ed.defns.h
+tc.bind.po: iconv.h
+tc.bind.po: sh.err.h
+tc.bind.po: tc.const.h
+tc.const.o: iconv.h
+tc.const.o: sh.err.h
+tc.const.o: tc.const.h
+tc.const.po: iconv.h
+tc.const.po: sh.err.h
+tc.const.po: tc.const.h
+tc.defs.o: iconv.h
+tc.defs.o: sh.err.h
+tc.defs.o: tc.const.h
+tc.defs.o: tc.defs.c
+tc.defs.po: iconv.h
+tc.defs.po: sh.err.h
+tc.defs.po: tc.const.h
+tc.defs.po: tc.defs.c
+tc.disc.o: iconv.h
+tc.disc.o: sh.err.h
+tc.disc.o: tc.const.h
+tc.disc.po: iconv.h
+tc.disc.po: sh.err.h
+tc.disc.po: tc.const.h
+tc.func.o: ed.defns.h
+tc.func.o: iconv.h
+tc.func.o: sh.err.h
+tc.func.o: tc.const.h
+tc.func.po: ed.defns.h
+tc.func.po: iconv.h
+tc.func.po: sh.err.h
+tc.func.po: tc.const.h
+tc.nls.o: iconv.h
+tc.nls.o: sh.err.h
+tc.nls.o: tc.const.h
+tc.nls.po: iconv.h
+tc.nls.po: sh.err.h
+tc.nls.po: tc.const.h
+tc.os.o: ed.defns.h
+tc.os.o: iconv.h
+tc.os.o: sh.err.h
+tc.os.o: tc.const.h
+tc.os.po: ed.defns.h
+tc.os.po: iconv.h
+tc.os.po: sh.err.h
+tc.os.po: tc.const.h
+tc.printf.o: iconv.h
+tc.printf.o: sh.err.h
+tc.printf.o: tc.const.h
+tc.printf.po: iconv.h
+tc.printf.po: sh.err.h
+tc.printf.po: tc.const.h
+tc.prompt.o: iconv.h
+tc.prompt.o: sh.err.h
+tc.prompt.o: tc.const.h
+tc.prompt.po: iconv.h
+tc.prompt.po: sh.err.h
+tc.prompt.po: tc.const.h
+tc.sched.o: iconv.h
+tc.sched.o: sh.err.h
+tc.sched.o: tc.const.h
+tc.sched.po: iconv.h
+tc.sched.po: sh.err.h
+tc.sched.po: tc.const.h
+tc.sig.o: iconv.h
+tc.sig.o: sh.err.h
+tc.sig.o: tc.const.h
+tc.sig.po: iconv.h
+tc.sig.po: sh.err.h
+tc.sig.po: tc.const.h
+tc.str.o: iconv.h
+tc.str.o: sh.err.h
+tc.str.o: tc.const.h
+tc.str.po: iconv.h
+tc.str.po: sh.err.h
+tc.str.po: tc.const.h
+tc.vers.o: iconv.h
+tc.vers.o: sh.err.h
+tc.vers.o: tc.const.h
+tc.vers.po: iconv.h
+tc.vers.po: sh.err.h
+tc.vers.po: tc.const.h
+tc.who.o: iconv.h
+tc.who.o: sh.err.h
+tc.who.o: tc.const.h
+tc.who.po: iconv.h
+tc.who.po: sh.err.h
+tc.who.po: tc.const.h
+tw.color.o: iconv.h
+tw.color.o: sh.err.h
+tw.color.o: tc.const.h
+tw.color.po: iconv.h
+tw.color.po: sh.err.h
+tw.color.po: tc.const.h
+tw.comp.o: iconv.h
+tw.comp.o: sh.err.h
+tw.comp.o: tc.const.h
+tw.comp.po: iconv.h
+tw.comp.po: sh.err.h
+tw.comp.po: tc.const.h
+tw.help.o: iconv.h
+tw.help.o: sh.err.h
+tw.help.o: tc.const.h
+tw.help.po: iconv.h
+tw.help.po: sh.err.h
+tw.help.po: tc.const.h
+tw.init.o: iconv.h
+tw.init.o: sh.err.h
+tw.init.o: tc.const.h
+tw.init.po: iconv.h
+tw.init.po: sh.err.h
+tw.init.po: tc.const.h
+tw.parse.o: iconv.h
+tw.parse.o: sh.err.h
+tw.parse.o: tc.const.h
+tw.parse.po: iconv.h
+tw.parse.po: sh.err.h
+tw.parse.po: tc.const.h
+tw.spell.o: iconv.h
+tw.spell.o: sh.err.h
+tw.spell.o: tc.const.h
+tw.spell.po: iconv.h
+tw.spell.po: sh.err.h
+tw.spell.po: tc.const.h
+.endif
diff --git a/bin/date/Makefile.depend b/bin/date/Makefile.depend
new file mode 100644
index 0000000..25ca344
--- /dev/null
+++ b/bin/date/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/dd/Makefile.depend b/bin/dd/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/dd/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/df/Makefile.depend b/bin/df/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/bin/df/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/domainname/Makefile.depend b/bin/domainname/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/domainname/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/echo/Makefile.depend b/bin/echo/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/echo/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/ed/Makefile.depend b/bin/ed/Makefile.depend
new file mode 100644
index 0000000..1ae71d9
--- /dev/null
+++ b/bin/ed/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/expr/Makefile.depend b/bin/expr/Makefile.depend
new file mode 100644
index 0000000..c4a7277
--- /dev/null
+++ b/bin/expr/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+expr.o: expr.c
+expr.po: expr.c
+.endif
diff --git a/bin/getfacl/Makefile.depend b/bin/getfacl/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/getfacl/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/hostname/Makefile.depend b/bin/hostname/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/hostname/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/kenv/Makefile.depend b/bin/kenv/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/kenv/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/kill/Makefile.depend b/bin/kill/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/kill/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/ln/Makefile.depend b/bin/ln/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/ln/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/ls/Makefile.depend b/bin/ls/Makefile.depend
new file mode 100644
index 0000000..3bf190d
--- /dev/null
+++ b/bin/ls/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/mkdir/Makefile.depend b/bin/mkdir/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/mkdir/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/mv/Makefile.depend b/bin/mv/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/mv/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/pax/Makefile.depend b/bin/pax/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/pax/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/pkill/Makefile.depend b/bin/pkill/Makefile.depend
new file mode 100644
index 0000000..553674c
--- /dev/null
+++ b/bin/pkill/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/ps/Makefile.depend b/bin/ps/Makefile.depend
new file mode 100644
index 0000000..863fe35
--- /dev/null
+++ b/bin/ps/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/pwait/Makefile.depend b/bin/pwait/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/pwait/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/pwd/Makefile.depend b/bin/pwd/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/pwd/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/rcp/Makefile.depend b/bin/rcp/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/rcp/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/realpath/Makefile.depend b/bin/realpath/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/bin/realpath/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/rm/Makefile.depend b/bin/rm/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/rm/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/rmail/Makefile.depend b/bin/rmail/Makefile.depend
new file mode 100644
index 0000000..7ffe408
--- /dev/null
+++ b/bin/rmail/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsm \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+rmail.o: sm_os.h
+rmail.po: sm_os.h
+.endif
diff --git a/bin/rmdir/Makefile.depend b/bin/rmdir/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/rmdir/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/setfacl/Makefile.depend b/bin/setfacl/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/setfacl/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/sh/Makefile.depend b/bin/sh/Makefile.depend
new file mode 100644
index 0000000..4c22a97
--- /dev/null
+++ b/bin/sh/Makefile.depend
@@ -0,0 +1,115 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+alias.o: builtins.h
+alias.po: builtins.h
+arith_yylex.o: syntax.h
+arith_yylex.po: syntax.h
+builtins.o: builtins.c
+builtins.o: builtins.h
+builtins.po: builtins.c
+builtins.po: builtins.h
+cd.o: builtins.h
+cd.o: nodes.h
+cd.po: builtins.h
+cd.po: nodes.h
+echo.o: builtins.h
+echo.po: builtins.h
+error.o: nodes.h
+error.po: nodes.h
+eval.o: builtins.h
+eval.o: nodes.h
+eval.o: syntax.h
+eval.po: builtins.h
+eval.po: nodes.h
+eval.po: syntax.h
+exec.o: builtins.h
+exec.o: nodes.h
+exec.o: syntax.h
+exec.po: builtins.h
+exec.po: nodes.h
+exec.po: syntax.h
+expand.o: builtins.h
+expand.o: nodes.h
+expand.o: syntax.h
+expand.po: builtins.h
+expand.po: nodes.h
+expand.po: syntax.h
+histedit.o: builtins.h
+histedit.po: builtins.h
+init.o: init.c
+init.po: init.c
+input.o: syntax.h
+input.po: syntax.h
+jobs.o: builtins.h
+jobs.o: nodes.h
+jobs.o: syntax.h
+jobs.po: builtins.h
+jobs.po: nodes.h
+jobs.po: syntax.h
+kill.o: builtins.h
+kill.po: builtins.h
+main.o: builtins.h
+main.o: nodes.h
+main.po: builtins.h
+main.po: nodes.h
+mystring.o: syntax.h
+mystring.po: syntax.h
+nodes.o: nodes.c
+nodes.o: nodes.h
+nodes.po: nodes.c
+nodes.po: nodes.h
+options.o: builtins.h
+options.o: nodes.h
+options.po: builtins.h
+options.po: nodes.h
+output.o: syntax.h
+output.po: syntax.h
+parser.o: nodes.h
+parser.o: syntax.h
+parser.o: token.h
+parser.po: nodes.h
+parser.po: syntax.h
+parser.po: token.h
+printf.o: builtins.h
+printf.po: builtins.h
+redir.o: nodes.h
+redir.po: nodes.h
+show.o: nodes.h
+show.po: nodes.h
+syntax.o: syntax.c
+syntax.o: syntax.h
+syntax.po: syntax.c
+syntax.po: syntax.h
+test.o: builtins.h
+test.po: builtins.h
+trap.o: builtins.h
+trap.o: nodes.h
+trap.o: syntax.h
+trap.po: builtins.h
+trap.po: nodes.h
+trap.po: syntax.h
+var.o: builtins.h
+var.o: nodes.h
+var.o: syntax.h
+var.po: builtins.h
+var.po: nodes.h
+var.po: syntax.h
+.endif
diff --git a/bin/sleep/Makefile.depend b/bin/sleep/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/sleep/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/stty/Makefile.depend b/bin/stty/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/stty/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/sync/Makefile.depend b/bin/sync/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/bin/sync/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/test/Makefile.depend b/bin/test/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/bin/test/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/bin/uuidgen/Makefile.depend b/bin/uuidgen/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/bin/uuidgen/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/lib/drti/Makefile.depend b/cddl/lib/drti/Makefile.depend
new file mode 100644
index 0000000..dc1878f
--- /dev/null
+++ b/cddl/lib/drti/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libelf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/lib/libavl/Makefile.depend b/cddl/lib/libavl/Makefile.depend
new file mode 100644
index 0000000..f5418c0
--- /dev/null
+++ b/cddl/lib/libavl/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/lib/libctf/Makefile.depend b/cddl/lib/libctf/Makefile.depend
new file mode 100644
index 0000000..fea4fa0
--- /dev/null
+++ b/cddl/lib/libctf/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libelf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/lib/libdtrace/Makefile.depend b/cddl/lib/libdtrace/Makefile.depend
new file mode 100644
index 0000000..50cff62
--- /dev/null
+++ b/cddl/lib/libdtrace/Makefile.depend
@@ -0,0 +1,47 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libelf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+dt_cc.So: dt_grammar.h
+dt_cc.o: dt_grammar.h
+dt_cc.po: dt_grammar.h
+dt_cg.So: dt_grammar.h
+dt_cg.o: dt_grammar.h
+dt_cg.po: dt_grammar.h
+dt_errtags.So: dt_errtags.c
+dt_errtags.o: dt_errtags.c
+dt_errtags.po: dt_errtags.c
+dt_grammar.So: dt_grammar.c
+dt_grammar.o: dt_grammar.c
+dt_grammar.po: dt_grammar.c
+dt_lex.So: dt_grammar.h
+dt_lex.So: dt_lex.c
+dt_lex.o: dt_grammar.h
+dt_lex.o: dt_lex.c
+dt_lex.po: dt_grammar.h
+dt_lex.po: dt_lex.c
+dt_names.So: dt_names.c
+dt_names.o: dt_names.c
+dt_names.po: dt_names.c
+dt_parser.So: dt_grammar.h
+dt_parser.o: dt_grammar.h
+dt_parser.po: dt_grammar.h
+dt_xlator.So: dt_grammar.h
+dt_xlator.o: dt_grammar.h
+dt_xlator.po: dt_grammar.h
+.endif
diff --git a/cddl/lib/libnvpair/Makefile.depend b/cddl/lib/libnvpair/Makefile.depend
new file mode 100644
index 0000000..eba5cd5
--- /dev/null
+++ b/cddl/lib/libnvpair/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/lib/libumem/Makefile.depend b/cddl/lib/libumem/Makefile.depend
new file mode 100644
index 0000000..f5418c0
--- /dev/null
+++ b/cddl/lib/libumem/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/lib/libuutil/Makefile.depend b/cddl/lib/libuutil/Makefile.depend
new file mode 100644
index 0000000..eba5cd5
--- /dev/null
+++ b/cddl/lib/libuutil/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/lib/libzfs/Makefile.depend b/cddl/lib/libzfs/Makefile.depend
new file mode 100644
index 0000000..95d4662
--- /dev/null
+++ b/cddl/lib/libzfs/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ cddl/lib/libumem \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgeom \
+ lib/libutil \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/lib/libzpool/Makefile.depend b/cddl/lib/libzpool/Makefile.depend
new file mode 100644
index 0000000..420d91b
--- /dev/null
+++ b/cddl/lib/libzpool/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/sbin/zfs/Makefile.depend b/cddl/sbin/zfs/Makefile.depend
new file mode 100644
index 0000000..ac256a5
--- /dev/null
+++ b/cddl/sbin/zfs/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ cddl/lib/libnvpair \
+ cddl/lib/libumem \
+ cddl/lib/libuutil \
+ cddl/lib/libzfs \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgeom \
+ lib/libutil \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/sbin/zpool/Makefile.depend b/cddl/sbin/zpool/Makefile.depend
new file mode 100644
index 0000000..33d5e34
--- /dev/null
+++ b/cddl/sbin/zpool/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ cddl/lib/libavl \
+ cddl/lib/libnvpair \
+ cddl/lib/libumem \
+ cddl/lib/libuutil \
+ cddl/lib/libzfs \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgeom \
+ lib/libutil \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/usr.bin/ctfconvert/Makefile.depend b/cddl/usr.bin/ctfconvert/Makefile.depend
new file mode 100644
index 0000000..75e8094
--- /dev/null
+++ b/cddl/usr.bin/ctfconvert/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ cddl/lib/libctf \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libdwarf \
+ lib/libelf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/usr.bin/ctfdump/Makefile.depend b/cddl/usr.bin/ctfdump/Makefile.depend
new file mode 100644
index 0000000..fea4fa0
--- /dev/null
+++ b/cddl/usr.bin/ctfdump/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libelf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/usr.bin/ctfmerge/Makefile.depend b/cddl/usr.bin/ctfmerge/Makefile.depend
new file mode 100644
index 0000000..75e8094
--- /dev/null
+++ b/cddl/usr.bin/ctfmerge/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ cddl/lib/libctf \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libdwarf \
+ lib/libelf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/usr.bin/sgsmsg/Makefile.depend b/cddl/usr.bin/sgsmsg/Makefile.depend
new file mode 100644
index 0000000..fea4fa0
--- /dev/null
+++ b/cddl/usr.bin/sgsmsg/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libelf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/cddl/usr.bin/zinject/Makefile.depend b/cddl/usr.bin/zinject/Makefile.depend
new file mode 100644
index 0000000..695f032
--- /dev/null
+++ b/cddl/usr.bin/zinject/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ cddl/lib/libnvpair \
+ cddl/lib/libumem \
+ cddl/lib/libuutil \
+ cddl/lib/libzfs \
+ cddl/lib/libzpool \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgeom \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/contrib/gnu-sort/ABOUT-NLS b/contrib/gnu-sort/ABOUT-NLS
new file mode 100644
index 0000000..8ffb467
--- /dev/null
+++ b/contrib/gnu-sort/ABOUT-NLS
@@ -0,0 +1,716 @@
+Notes on the Free Translation Project
+*************************************
+
+Free software is going international! The Free Translation Project is
+a way to get maintainers of free software, translators, and users all
+together, so that will gradually become able to speak many languages.
+A few packages already provide translations for their messages.
+
+ If you found this `ABOUT-NLS' file inside a distribution, you may
+assume that the distributed package does use GNU `gettext' internally,
+itself available at your nearest GNU archive site. But you do _not_
+need to install GNU `gettext' prior to configuring, installing or using
+this package with messages translated.
+
+ Installers will find here some useful hints. These notes also
+explain how users should proceed for getting the programs to use the
+available translations. They tell how people wanting to contribute and
+work at translations should contact the appropriate team.
+
+ When reporting bugs in the `intl/' directory or bugs which may be
+related to internationalization, you should tell about the version of
+`gettext' which is used. The information can be found in the
+`intl/VERSION' file, in internationalized packages.
+
+Quick configuration advice
+==========================
+
+If you want to exploit the full power of internationalization, you
+should configure it using
+
+ ./configure --with-included-gettext
+
+to force usage of internationalizing routines provided within this
+package, despite the existence of internationalizing capabilities in the
+operating system where this package is being installed. So far, only
+the `gettext' implementation in the GNU C library version 2 provides as
+many features (such as locale alias, message inheritance, automatic
+charset conversion or plural form handling) as the implementation here.
+It is also not possible to offer this additional functionality on top
+of a `catgets' implementation. Future versions of GNU `gettext' will
+very likely convey even more functionality. So it might be a good idea
+to change to GNU `gettext' as soon as possible.
+
+ So you need _not_ provide this option if you are using GNU libc 2 or
+you have installed a recent copy of the GNU gettext package with the
+included `libintl'.
+
+INSTALL Matters
+===============
+
+Some packages are "localizable" when properly installed; the programs
+they contain can be made to speak your own native language. Most such
+packages use GNU `gettext'. Other packages have their own ways to
+internationalization, predating GNU `gettext'.
+
+ By default, this package will be installed to allow translation of
+messages. It will automatically detect whether the system already
+provides the GNU `gettext' functions. If not, the GNU `gettext' own
+library will be used. This library is wholly contained within this
+package, usually in the `intl/' subdirectory, so prior installation of
+the GNU `gettext' package is _not_ required. Installers may use
+special options at configuration time for changing the default
+behaviour. The commands:
+
+ ./configure --with-included-gettext
+ ./configure --disable-nls
+
+will respectively bypass any pre-existing `gettext' to use the
+internationalizing routines provided within this package, or else,
+_totally_ disable translation of messages.
+
+ When you already have GNU `gettext' installed on your system and run
+configure without an option for your new package, `configure' will
+probably detect the previously built and installed `libintl.a' file and
+will decide to use this. This might be not what is desirable. You
+should use the more recent version of the GNU `gettext' library. I.e.
+if the file `intl/VERSION' shows that the library which comes with this
+package is more recent, you should use
+
+ ./configure --with-included-gettext
+
+to prevent auto-detection.
+
+ The configuration process will not test for the `catgets' function
+and therefore it will not be used. The reason is that even an
+emulation of `gettext' on top of `catgets' could not provide all the
+extensions of the GNU `gettext' library.
+
+ Internationalized packages have usually many `po/LL.po' files, where
+LL gives an ISO 639 two-letter code identifying the language. Unless
+translations have been forbidden at `configure' time by using the
+`--disable-nls' switch, all available translations are installed
+together with the package. However, the environment variable `LINGUAS'
+may be set, prior to configuration, to limit the installed set.
+`LINGUAS' should then contain a space separated list of two-letter
+codes, stating which languages are allowed.
+
+Using This Package
+==================
+
+As a user, if your language has been installed for this package, you
+only have to set the `LANG' environment variable to the appropriate
+`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code,
+and `CC' is an ISO 3166 two-letter country code. For example, let's
+suppose that you speak German and live in Germany. At the shell
+prompt, merely execute `setenv LANG de_DE' (in `csh'),
+`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
+This can be done from your `.login' or `.profile' file, once and for
+all.
+
+ You might think that the country code specification is redundant.
+But in fact, some languages have dialects in different countries. For
+example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The
+country code serves to distinguish the dialects.
+
+ The locale naming convention of `LL_CC', with `LL' denoting the
+language and `CC' denoting the country, is the one use on systems based
+on GNU libc. On other systems, some variations of this scheme are
+used, such as `LL' or `LL_CC.ENCODING'. You can get the list of
+locales supported by your system for your country by running the command
+`locale -a | grep '^LL''.
+
+ Not all programs have translations for all languages. By default, an
+English message is shown in place of a nonexistent translation. If you
+understand other languages, you can set up a priority list of languages.
+This is done through a different environment variable, called
+`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG'
+for the purpose of message handling, but you still need to have `LANG'
+set to the primary language; this is required by other parts of the
+system libraries. For example, some Swedish users who would rather
+read translations in German than English for when Swedish is not
+available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
+
+ In the `LANGUAGE' environment variable, but not in the `LANG'
+environment variable, `LL_CC' combinations can be abbreviated as `LL'
+to denote the language's main dialect. For example, `de' is equivalent
+to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
+(Portuguese as spoken in Portugal) in this context.
+
+Translating Teams
+=================
+
+For the Free Translation Project to be a success, we need interested
+people who like their own language and write it well, and who are also
+able to synergize with other translators speaking the same language.
+Each translation team has its own mailing list. The up-to-date list of
+teams can be found at the Free Translation Project's homepage,
+`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams"
+area.
+
+ If you'd like to volunteer to _work_ at translating messages, you
+should become a member of the translating team for your own language.
+The subscribing address is _not_ the same as the list itself, it has
+`-request' appended. For example, speakers of Swedish can send a
+message to `sv-request@li.org', having this message body:
+
+ subscribe
+
+ Keep in mind that team members are expected to participate
+_actively_ in translations, or at solving translational difficulties,
+rather than merely lurking around. If your team does not exist yet and
+you want to start one, or if you are unsure about what to do or how to
+get started, please write to `translation@iro.umontreal.ca' to reach the
+coordinator for all translator teams.
+
+ The English team is special. It works at improving and uniformizing
+the terminology in use. Proven linguistic skill are praised more than
+programming skill, here.
+
+Available Packages
+==================
+
+Languages are not equally supported in all packages. The following
+matrix shows the current state of internationalization, as of December
+2003. The matrix shows, in regard of each package, for which languages
+PO files have been submitted to translation coordination, with a
+translation percentage of at least 50%.
+
+ Ready PO files am az be bg ca cs da de el en en_GB eo es
+ +-------------------------------------------+
+ a2ps | [] [] [] [] |
+ aegis | () |
+ ant-phone | () |
+ anubis | |
+ ap-utils | |
+ bash | [] [] [] [] |
+ batchelor | |
+ bfd | [] [] |
+ binutils | [] [] |
+ bison | [] [] [] |
+ bluez-pin | [] [] |
+ clisp | |
+ clisp | [] [] [] |
+ coreutils | [] [] [] [] |
+ cpio | [] [] [] |
+ darkstat | [] () [] |
+ diffutils | [] [] [] [] [] [] [] |
+ e2fsprogs | [] [] |
+ enscript | [] [] [] [] |
+ error | [] [] [] [] [] |
+ fetchmail | [] () [] [] [] [] |
+ fileutils | [] [] [] |
+ findutils | [] [] [] [] [] [] [] |
+ flex | [] [] [] [] |
+ fslint | |
+ gas | [] |
+ gawk | [] [] [] [] |
+ gbiff | [] |
+ gcal | [] |
+ gcc | [] [] |
+ gettext | [] [] [] [] [] |
+ gettext-examples | [] [] [] |
+ gettext-runtime | [] [] [] [] [] |
+ gettext-tools | [] [] [] |
+ gimp-print | [] [] [] [] [] |
+ gliv | |
+ glunarclock | [] [] |
+ gnubiff | [] |
+ gnucash | [] () [] [] |
+ gnucash-glossary | [] () [] |
+ gnupg | [] () [] [] [] [] |
+ gpe-aerial | [] |
+ gpe-beam | [] [] |
+ gpe-calendar | [] [] |
+ gpe-clock | [] [] |
+ gpe-conf | [] [] |
+ gpe-contacts | [] [] |
+ gpe-edit | [] |
+ gpe-go | [] |
+ gpe-login | [] [] |
+ gpe-ownerinfo | [] [] |
+ gpe-sketchbook | [] [] |
+ gpe-su | [] [] |
+ gpe-taskmanager | [] [] |
+ gpe-timesheet | [] |
+ gpe-today | [] [] |
+ gpe-todo | [] [] |
+ gphoto2 | [] [] [] [] |
+ gprof | [] [] [] |
+ gpsdrive | () () () |
+ gramadoir | [] |
+ grep | [] [] [] [] [] [] |
+ gretl | [] |
+ gtick | () |
+ hello | [] [] [] [] [] [] |
+ id-utils | [] [] |
+ indent | [] [] [] [] |
+ jpilot | [] [] [] |
+ jtag | |
+ jwhois | [] |
+ kbd | [] [] [] [] [] |
+ latrine | () |
+ ld | [] [] |
+ libc | [] [] [] [] [] [] |
+ libgpewidget | [] [] |
+ libiconv | [] [] [] [] [] |
+ lifelines | [] () |
+ lilypond | [] |
+ lingoteach | |
+ lingoteach_lessons | () () |
+ lynx | [] [] [] [] |
+ m4 | [] [] [] [] |
+ mailutils | [] [] |
+ make | [] [] [] |
+ man-db | [] () [] [] () |
+ minicom | [] [] [] |
+ mysecretdiary | [] [] [] |
+ nano | [] () [] [] [] |
+ nano_1_0 | [] () [] [] [] |
+ opcodes | [] |
+ parted | [] [] [] [] [] |
+ ptx | [] [] [] [] [] |
+ python | |
+ radius | [] |
+ recode | [] [] [] [] [] [] [] |
+ rpm | [] [] |
+ screem | |
+ scrollkeeper | [] [] [] [] [] [] |
+ sed | [] [] [] [] [] |
+ sh-utils | [] [] [] |
+ shared-mime-info | |
+ sharutils | [] [] [] [] [] [] |
+ silky | () |
+ skencil | [] () [] |
+ sketch | [] () [] |
+ soundtracker | [] [] [] |
+ sp | [] |
+ tar | [] [] [] [] |
+ texinfo | [] [] [] |
+ textutils | [] [] [] [] |
+ tin | () () |
+ tuxpaint | [] [] [] [] [] [] [] |
+ util-linux | [] [] [] [] [] |
+ vorbis-tools | [] [] [] [] |
+ wastesedge | () |
+ wdiff | [] [] [] [] |
+ wget | [] [] [] [] [] [] |
+ xchat | [] [] [] [] |
+ xfree86_xkb_xml | [] |
+ xpad | [] |
+ +-------------------------------------------+
+ am az be bg ca cs da de el en en_GB eo es
+ 0 0 8 3 37 38 56 73 15 1 5 12 64
+
+ et fa fi fr ga gl he hr hu id is it ja
+ +----------------------------------------+
+ a2ps | [] [] [] () |
+ aegis | |
+ ant-phone | |
+ anubis | [] |
+ ap-utils | [] |
+ bash | [] [] |
+ batchelor | [] |
+ bfd | [] |
+ binutils | [] [] |
+ bison | [] [] [] [] |
+ bluez-pin | [] [] [] [] [] |
+ clisp | |
+ clisp | [] |
+ coreutils | [] [] [] [] [] [] |
+ cpio | [] [] [] |
+ darkstat | () [] [] [] |
+ diffutils | [] [] [] [] [] [] [] |
+ e2fsprogs | |
+ enscript | [] [] |
+ error | [] [] [] [] |
+ fetchmail | [] |
+ fileutils | [] [] [] [] [] [] |
+ findutils | [] [] [] [] [] [] [] [] [] [] |
+ flex | [] [] |
+ fslint | |
+ gas | [] |
+ gawk | [] [] [] |
+ gbiff | |
+ gcal | [] |
+ gcc | [] |
+ gettext | [] [] |
+ gettext-examples | [] [] |
+ gettext-runtime | [] [] [] [] |
+ gettext-tools | [] [] |
+ gimp-print | [] [] |
+ gliv | () |
+ glunarclock | [] [] [] [] |
+ gnubiff | |
+ gnucash | () [] |
+ gnucash-glossary | [] |
+ gnupg | [] [] [] [] [] [] [] |
+ gpe-aerial | [] |
+ gpe-beam | [] |
+ gpe-calendar | [] [] [] |
+ gpe-clock | [] |
+ gpe-conf | [] |
+ gpe-contacts | [] [] |
+ gpe-edit | [] [] |
+ gpe-go | [] |
+ gpe-login | [] [] |
+ gpe-ownerinfo | [] [] [] |
+ gpe-sketchbook | [] |
+ gpe-su | [] |
+ gpe-taskmanager | [] |
+ gpe-timesheet | [] [] [] |
+ gpe-today | [] [] |
+ gpe-todo | [] [] |
+ gphoto2 | [] [] [] |
+ gprof | [] [] |
+ gpsdrive | () [] () () |
+ gramadoir | [] |
+ grep | [] [] [] [] [] [] [] [] [] [] [] |
+ gretl | [] |
+ gtick | [] [] |
+ hello | [] [] [] [] [] [] [] [] [] [] [] [] |
+ id-utils | [] [] [] [] |
+ indent | [] [] [] [] [] [] [] [] [] |
+ jpilot | [] () |
+ jtag | |
+ jwhois | [] [] [] [] |
+ kbd | [] |
+ latrine | |
+ ld | [] |
+ libc | [] [] [] [] [] |
+ libgpewidget | [] [] [] [] |
+ libiconv | [] [] [] [] [] [] [] [] [] |
+ lifelines | () |
+ lilypond | [] |
+ lingoteach | [] [] |
+ lingoteach_lessons | |
+ lynx | [] [] [] [] |
+ m4 | [] [] [] [] |
+ mailutils | |
+ make | [] [] [] [] [] |
+ man-db | () () |
+ minicom | [] [] [] [] |
+ mysecretdiary | [] [] |
+ nano | [] [] [] [] |
+ nano_1_0 | [] [] [] [] |
+ opcodes | [] |
+ parted | [] [] [] |
+ ptx | [] [] [] [] [] [] [] |
+ python | |
+ radius | [] |
+ recode | [] [] [] [] [] [] |
+ rpm | |
+ screem | |
+ scrollkeeper | [] |
+ sed | [] [] [] [] [] [] [] [] [] |
+ sh-utils | [] [] [] [] [] [] [] |
+ shared-mime-info | [] |
+ sharutils | [] [] [] [] [] |
+ silky | [] () |
+ skencil | [] |
+ sketch | [] |
+ soundtracker | [] [] [] [] |
+ sp | [] () |
+ tar | [] [] [] [] [] [] [] [] [] |
+ texinfo | [] [] [] [] |
+ textutils | [] [] [] [] [] |
+ tin | [] () |
+ tuxpaint | [] [] [] [] [] [] [] [] |
+ util-linux | [] [] [] [] () [] |
+ vorbis-tools | [] |
+ wastesedge | () |
+ wdiff | [] [] [] [] [] [] |
+ wget | [] [] [] [] [] [] [] |
+ xchat | [] [] [] |
+ xfree86_xkb_xml | |
+ xpad | [] |
+ +----------------------------------------+
+ et fa fi fr ga gl he hr hu id is it ja
+ 21 1 25 86 24 24 8 10 38 31 1 23 32
+
+ ko lg lt lv ms nb nl nn no pl pt pt_BR ro
+ +-------------------------------------------+
+ a2ps | () [] [] () () [] [] |
+ aegis | () () |
+ ant-phone | [] [] |
+ anubis | [] [] [] [] [] |
+ ap-utils | [] () [] |
+ bash | [] [] |
+ batchelor | [] |
+ bfd | [] |
+ binutils | |
+ bison | [] [] [] [] |
+ bluez-pin | [] [] [] |
+ clisp | |
+ clisp | [] |
+ coreutils | [] |
+ cpio | [] [] [] [] [] |
+ darkstat | [] [] [] [] |
+ diffutils | [] [] [] [] |
+ e2fsprogs | [] |
+ enscript | [] [] [] |
+ error | [] [] [] |
+ fetchmail | [] [] () |
+ fileutils | [] [] |
+ findutils | [] [] [] [] [] |
+ flex | [] [] [] [] |
+ fslint | [] [] |
+ gas | |
+ gawk | [] [] [] |
+ gbiff | [] [] |
+ gcal | |
+ gcc | |
+ gettext | [] [] [] |
+ gettext-examples | [] [] |
+ gettext-runtime | [] [] [] |
+ gettext-tools | [] [] [] |
+ gimp-print | [] |
+ gliv | [] [] [] |
+ glunarclock | [] [] [] |
+ gnubiff | |
+ gnucash | [] [] () |
+ gnucash-glossary | [] [] |
+ gnupg | [] |
+ gpe-aerial | [] [] [] |
+ gpe-beam | [] [] [] |
+ gpe-calendar | [] [] [] |
+ gpe-clock | [] [] [] |
+ gpe-conf | [] [] [] |
+ gpe-contacts | [] [] [] |
+ gpe-edit | [] [] [] |
+ gpe-go | [] [] |
+ gpe-login | [] [] [] |
+ gpe-ownerinfo | [] [] [] |
+ gpe-sketchbook | [] [] [] |
+ gpe-su | [] [] [] |
+ gpe-taskmanager | [] [] [] |
+ gpe-timesheet | [] [] [] |
+ gpe-today | [] [] [] |
+ gpe-todo | [] [] [] |
+ gphoto2 | [] |
+ gprof | [] [] |
+ gpsdrive | () () () [] |
+ gramadoir | [] |
+ grep | [] [] [] [] |
+ gretl | |
+ gtick | [] [] |
+ hello | [] [] [] [] [] [] [] [] [] [] |
+ id-utils | [] [] [] |
+ indent | [] [] [] |
+ jpilot | () () |
+ jtag | |
+ jwhois | [] [] [] [] |
+ kbd | [] [] [] |
+ latrine | [] |
+ ld | |
+ libc | [] [] [] [] [] |
+ libgpewidget | [] [] [] |
+ libiconv | [] [] [] [] |
+ lifelines | |
+ lilypond | |
+ lingoteach | |
+ lingoteach_lessons | |
+ lynx | [] [] |
+ m4 | [] [] [] [] |
+ mailutils | [] [] |
+ make | [] [] [] [] |
+ man-db | [] |
+ minicom | [] [] [] |
+ mysecretdiary | [] [] [] |
+ nano | [] [] [] [] |
+ nano_1_0 | [] [] [] [] [] |
+ opcodes | [] [] |
+ parted | [] [] [] [] |
+ ptx | [] [] [] [] [] [] [] |
+ python | |
+ radius | [] |
+ recode | [] [] [] |
+ rpm | [] [] |
+ screem | |
+ scrollkeeper | [] [] [] [] |
+ sed | [] [] [] |
+ sh-utils | [] |
+ shared-mime-info | [] |
+ sharutils | [] |
+ silky | |
+ skencil | [] [] |
+ sketch | [] [] |
+ soundtracker | |
+ sp | |
+ tar | [] [] [] [] [] [] |
+ texinfo | [] [] [] |
+ textutils | [] [] |
+ tin | |
+ tuxpaint | [] [] [] [] [] [] [] [] [] |
+ util-linux | [] [] |
+ vorbis-tools | [] [] |
+ wastesedge | |
+ wdiff | [] [] [] [] |
+ wget | [] [] |
+ xchat | [] [] |
+ xfree86_xkb_xml | [] |
+ xpad | [] [] |
+ +-------------------------------------------+
+ ko lg lt lv ms nb nl nn no pl pt pt_BR ro
+ 12 0 1 2 12 10 60 4 4 38 25 35 76
+
+ ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW
+ +-------------------------------------------+
+ a2ps | [] [] [] [] [] | 16
+ aegis | () | 0
+ ant-phone | | 2
+ anubis | [] [] [] | 9
+ ap-utils | () | 3
+ bash | [] | 9
+ batchelor | | 2
+ bfd | [] [] | 6
+ binutils | [] [] [] | 7
+ bison | [] [] [] | 14
+ bluez-pin | [] [] [] | 13
+ clisp | | 0
+ clisp | | 5
+ coreutils | [] [] [] [] [] | 16
+ cpio | [] [] [] | 14
+ darkstat | [] [] [] () () | 12
+ diffutils | [] [] [] [] | 22
+ e2fsprogs | [] [] | 5
+ enscript | [] [] [] | 12
+ error | [] [] [] | 15
+ fetchmail | [] [] [] | 11
+ fileutils | [] [] [] [] [] [] | 17
+ findutils | [] [] [] [] [] [] [] | 29
+ flex | [] [] [] | 13
+ fslint | | 2
+ gas | [] | 3
+ gawk | [] [] | 12
+ gbiff | | 3
+ gcal | [] [] | 4
+ gcc | [] | 4
+ gettext | [] [] [] [] [] [] | 16
+ gettext-examples | [] [] [] [] | 11
+ gettext-runtime | [] [] [] [] [] [] [] [] [] | 21
+ gettext-tools | [] [] [] [] [] [] | 14
+ gimp-print | [] [] | 10
+ gliv | | 3
+ glunarclock | [] [] [] [] | 13
+ gnubiff | | 1
+ gnucash | [] [] [] | 9
+ gnucash-glossary | [] [] [] | 8
+ gnupg | [] [] [] [] | 17
+ gpe-aerial | [] [] | 7
+ gpe-beam | [] [] | 8
+ gpe-calendar | [] [] [] [] [] | 13
+ gpe-clock | [] [] [] [] | 10
+ gpe-conf | [] [] [] | 9
+ gpe-contacts | [] [] [] [] | 11
+ gpe-edit | [] [] [] [] [] [] | 12
+ gpe-go | [] | 5
+ gpe-login | [] [] [] [] [] [] | 13
+ gpe-ownerinfo | [] [] [] [] [] | 13
+ gpe-sketchbook | [] [] [] | 9
+ gpe-su | [] [] [] [] | 10
+ gpe-taskmanager | [] [] [] [] | 10
+ gpe-timesheet | [] [] [] [] [] | 12
+ gpe-today | [] [] [] [] [] [] | 13
+ gpe-todo | [] [] [] [] [] | 12
+ gphoto2 | [] [] [] | 11
+ gprof | [] [] | 9
+ gpsdrive | [] [] | 4
+ gramadoir | | 3
+ grep | [] [] [] [] [] | 26
+ gretl | | 2
+ gtick | [] | 5
+ hello | [] [] [] [] [] | 33
+ id-utils | [] [] [] | 12
+ indent | [] [] [] [] [] | 21
+ jpilot | [] [] [] [] [] | 9
+ jtag | [] | 1
+ jwhois | () () [] [] | 11
+ kbd | [] [] | 11
+ latrine | | 1
+ ld | [] [] | 5
+ libc | [] [] [] [] | 20
+ libgpewidget | [] [] [] [] | 13
+ libiconv | [] [] [] [] [] [] [] [] [] | 27
+ lifelines | [] | 2
+ lilypond | [] | 3
+ lingoteach | | 2
+ lingoteach_lessons | () | 0
+ lynx | [] [] [] [] | 14
+ m4 | [] [] [] | 15
+ mailutils | [] | 5
+ make | [] [] [] [] | 16
+ man-db | [] | 5
+ minicom | [] | 11
+ mysecretdiary | [] [] | 10
+ nano | [] [] [] [] [] | 17
+ nano_1_0 | [] [] [] [] | 17
+ opcodes | [] [] | 6
+ parted | [] [] [] | 15
+ ptx | [] [] [] | 22
+ python | | 0
+ radius | [] | 4
+ recode | [] [] [] [] | 20
+ rpm | [] [] [] | 7
+ screem | [] [] | 2
+ scrollkeeper | [] [] [] [] | 15
+ sed | [] [] [] [] [] [] | 23
+ sh-utils | [] [] [] | 14
+ shared-mime-info | [] [] | 4
+ sharutils | [] [] [] [] [] | 17
+ silky | () | 2
+ skencil | [] | 6
+ sketch | [] | 6
+ soundtracker | [] [] | 9
+ sp | [] | 3
+ tar | [] [] [] [] [] | 24
+ texinfo | [] [] [] [] | 14
+ textutils | [] [] [] [] [] | 16
+ tin | | 1
+ tuxpaint | [] [] [] [] [] | 29
+ util-linux | [] [] [] | 15
+ vorbis-tools | [] | 8
+ wastesedge | | 0
+ wdiff | [] [] [] [] | 18
+ wget | [] [] [] [] [] [] [] [] | 23
+ xchat | [] [] [] [] [] | 14
+ xfree86_xkb_xml | [] [] [] [] [] [] | 8
+ xpad | | 4
+ +-------------------------------------------+
+ 51 teams ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW
+ 120 domains 59 42 16 25 81 0 56 12 1 10 21 22 1260
+
+ Some counters in the preceding matrix are higher than the number of
+visible blocks let us expect. This is because a few extra PO files are
+used for implementing regional variants of languages, or language
+dialects.
+
+ For a PO file in the matrix above to be effective, the package to
+which it applies should also have been internationalized and
+distributed as such by its maintainer. There might be an observable
+lag between the mere existence a PO file and its wide availability in a
+distribution.
+
+ If December 2003 seems to be old, you may fetch a more recent copy
+of this `ABOUT-NLS' file on most GNU archive sites. The most
+up-to-date matrix with full percentage details can be found at
+`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'.
+
+Using `gettext' in new packages
+===============================
+
+If you are writing a freely available program and want to
+internationalize it you are welcome to use GNU `gettext' in your
+package. Of course you have to respect the GNU Library General Public
+License which covers the use of the GNU `gettext' library. This means
+in particular that even non-free programs can use `libintl' as a shared
+library, whereas only free software can use `libintl' as a static
+library or use modified versions of `libintl'.
+
+ Once the sources are changed appropriately and the setup can handle
+the use of `gettext' the only thing missing are the translations. The
+Free Translation Project is also available for packages which are not
+developed inside the GNU project. Therefore the information given above
+applies also for every other Free Software Project. Contact
+`translation@iro.umontreal.ca' to make the `.pot' files available to
+the translation teams.
diff --git a/contrib/gnu-sort/AUTHORS b/contrib/gnu-sort/AUTHORS
new file mode 100644
index 0000000..4e8a5d4
--- /dev/null
+++ b/contrib/gnu-sort/AUTHORS
@@ -0,0 +1,86 @@
+Here are the names of the programs in this package,
+each followed by the name(s) of its author(s).
+
+basename: FIXME unknown
+cat: Torbjorn Granlund and Richard M. Stallman
+chgrp: David MacKenzie
+chmod: David MacKenzie
+chown: David MacKenzie
+chroot: Roland McGrath
+cksum: Q. Frank Xia
+comm: Richard Stallman and David MacKenzie
+cp: Torbjorn Granlund, David MacKenzie, and Jim Meyering
+csplit: Stuart Kemp and David MacKenzie
+cut: David Ihnat, David MacKenzie, and Jim Meyering
+date: David MacKenzie
+dd: Paul Rubin, David MacKenzie, and Stuart Kemp
+df: Torbjorn Granlund, David MacKenzie, Larry McVoy, and Paul Eggert
+dircolors: H. Peter Anvin
+dirname: David MacKenzie and Jim Meyering
+du: Torbjorn Granlund, David MacKenzie, Larry McVoy, and Paul Eggert
+echo: FIXME unknown
+env: Richard Mlynarik and David MacKenzie
+expand: David MacKenzie
+expr: Mike Parker
+factor: Paul Rubin
+false: no one
+fmt: Ross Paterson
+fold: David MacKenzie
+head: David MacKenzie
+hostid: Jim Meyering
+hostname: Jim Meyering
+id: Arnold Robbins and David MacKenzie
+install: David MacKenzie
+join: Mike Haertel
+kill: Paul Eggert
+link: Michael Stone
+ln: Mike Parker and David MacKenzie
+logname: FIXME: unknown
+ls: Richard Stallman and David MacKenzie
+md5sum: Ulrich Drepper and Scott Miller
+mkdir: David MacKenzie
+mkfifo: David MacKenzie
+mknod: David MacKenzie
+mv: Mike Parker, David MacKenzie, and Jim Meyering
+nice: David MacKenzie
+nl: Scott Bartram and David MacKenzie
+od: Jim Meyering
+paste: David M. Ihnat and David MacKenzie
+pathchk: David MacKenzie and Jim Meyering
+pinky: Joseph Arceneaux, David MacKenzie, and Kaveh Ghazi
+pr: Pete TerMaat and Roland Huebner
+printenv: David MacKenzie and Richard Mlynarik
+printf: David MacKenzie
+ptx: François Pinard
+pwd: Jim Meyering
+rm: Paul Rubin, David MacKenzie, Richard Stallman, and Jim Meyering
+rmdir: David MacKenzie
+seq: Ulrich Drepper
+shred: Colin Plumb
+sleep: Jim Meyering and Paul Eggert
+sort: Mike Haertel and Paul Eggert
+split: Torbjorn Granlund and Richard M. Stallman
+stat: Michael Meskes
+stty: David MacKenzie
+su: David MacKenzie
+sum: Kayvan Aghaiepour and David MacKenzie
+sync: Jim Meyering
+tac: Jay Lepreau and David MacKenzie
+tail: Paul Rubin, David MacKenzie, Ian Lance Taylor, and Jim Meyering
+tee: Mike Parker, Richard M. Stallman, and David MacKenzie
+test: FIXME: ksb and mjb
+touch: Paul Rubin, Arnold Robbins, Jim Kingdon, David MacKenzie, and Randy Smith
+tr: Jim Meyering
+true: no one
+tsort: Mark Kettenis
+tty: David MacKenzie
+uname: David MacKenzie
+unexpand: David MacKenzie
+uniq: Richard Stallman and David MacKenzie
+unlink: Michael Stone
+uptime: Joseph Arceneaux, David MacKenzie, and Kaveh Ghazi
+users: Joseph Arceneaux and David MacKenzie
+wc: Paul Rubin and David MacKenzie
+who: Joseph Arceneaux, David MacKenzie, and Michael Stone
+whoami: Richard Mlynarik
+yes: David MacKenzie
diff --git a/contrib/gnu-sort/COPYING b/contrib/gnu-sort/COPYING
new file mode 100644
index 0000000..d60c31a
--- /dev/null
+++ b/contrib/gnu-sort/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/contrib/gnu-sort/ChangeLog b/contrib/gnu-sort/ChangeLog
new file mode 100644
index 0000000..c027655
--- /dev/null
+++ b/contrib/gnu-sort/ChangeLog
@@ -0,0 +1,7511 @@
+2004-08-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ * tests/install/basic-1: Test for the -d regression.
+
+2004-08-11 Dmitry V. Levin <ldv@altlinux.org>
+
+ * src/install.c (main): Fix -d regression introduced with
+ --target-directory support at 2004-06-25.
+
+2004-08-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/copy.c (copy_internal): When preserving links, unlink
+ a destination with link count greater than one. This is so
+ that commands like "cp -a" don't get confused when copying into
+ a destination that already contains many hard links. Problem
+ reported by Tim Waugh in:
+ http://lists.gnu.org/archive/html/bug-coreutils/2004-08/msg00053.html
+
+2004-08-10 Paul Eggert <eggert@cs.ucla.edu>
+
+ Convert all files to UTF-8.
+ * tests/fmt/basic (8-bit-pfx): Use UTF-8, not Latin-1.
+ * tests/sort/Test.pm (16a): Likewise.
+ * tests/uniq/Test.pm (8): Likewise.
+ * tests/misc/printf-hex: Use ASCII, not Latin-1.
+
+ * NEWS: Document "sort -o -" and "tee -" POSIX-conformance fixes.
+ * src/shred.c (usage): "-" is an operand, not an option.
+ * src/sort.c (die, xfopen, mergefps, first_same_file, merge):
+ A null file arg means standard output.
+ (main): "-o -" means to write to a file named "-",
+ not to standard output.
+ * src/tee.c (usage, tee): "tee -" writes to standard output, not
+ to a file named "-".
+
+2004-08-10 Dmitry V. Levin <ldv@altlinux.org>
+
+ * src/install.c (change_timestamps): Fix int->bool conversion
+ bugs introduced on 2004-07-29.
+
+2004-08-09 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/shred.c (wipename): Work even if the directory is writeable
+ and not readable. Prefer write access, since this should work
+ better with fdatasync.
+
+ * src/csplit.c (xalloc_die): New function.
+ (main): Remove now-obsolete initialization of xalloc_fail_func.
+
+ * src/md5sum.c: Adjust to sha->sha1 renaming.
+
+2004-08-08 Dmitry V. Levin <ldv@altlinux.org>
+
+ Minor code cleanup.
+ * src/readlink.c (canonicalize_fname): Remove unneeded proxy function.
+ (can_mode): Make variable local.
+
+2004-08-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/system.h (O_BINARY) [!O_BINARY && defined O_BINARY]:
+ Do not define, to avoid annoying compiler messages on QNX 6.3.
+ Problem reported by Johan in:
+ http://lists.gnu.org/archive/html/bug-coreutils/2004-08/msg00050.html
+
+2004-08-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/system.h (PRIdMAX, PRIoMAX, PRIuMAX, PRIxMAX):
+ Define to a concatenation of string literals, not to an expression;
+ needed for concatenation contexts.
+ (INTMAX_MAX, INTMAX_MIN): New macros.
+
+ * src/stat.c (print_stat): Don't assume st_ino / st_dev fits in
+ unsigned long; this isn't true for st_ino on Solaris 9.
+
+2004-08-03 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/uname.c: Do not depend on HAVE_SYSCTL when deciding
+ whether to include files. Include <sys/param.h> if
+ HAVE_SYS_PARAM_H (not HAVE_SYSCTL).
+ (main) [defined __POWERPC__]: Add a kludge to work around a
+ Mac OS X bug, so that uname -p defaults to "powerpc" if
+ sysctl ((int[]) {CTL_HW, HW_MACHINE_ARCH}, 2, buffer, &bufsize, 0, 0)
+ fails. Problem reported by Petter Reinholdtsen in:
+ http://lists.gnu.org/archive/html/bug-gnu-utils/2003-02/msg00201.html
+
+ * src/uniq.c (hard_LC_COLLATE, ignore_case, different, check_file,
+ main): Use bool for booleans.
+ (writeline, check_file): Use uintmax_t for line counts.
+ (check_file): Check for and report line number overflow,
+ when that matters.
+ * src/wc.c (iswspace, wc): Use to_uchar rather than a cast.
+ (print_lines, print_words, print_chars, print_bytes, print_linelength,
+ have_read_stdin, wc, wc_file, main):
+ Use bool for booleans.
+ (exit_status): Remove.
+ (wc, wc_file): Return bool status. All callers changed.
+ * src/who.c (scan_entries): 0 -> STDIN_FILENO.
+ * src/whoami.c (main): Print uids using unsigned long int, not
+ unsigned int.
+
+ * src/unexpand.c: Int cleanup and minor reorganization to be more
+ like src/expand.c.
+ Include quote.h, xstrndup.h.
+ (TAB_STOP_SENTINEL): Increase from INT_MAX to INTMAX_MAX.
+ (convert_entire_line, have_read_stdin, parse_tabstops, next_file,
+ unexpand, main):
+ Use bool for booleans.
+ (tab_size, tab_list, add_tabstop, validate_tabstops, unexpand):
+ Use uintmax_t for column counts.
+ (first_free_tab, validate_tabstops, unexpand): Use size_t for sizes.
+ (add_tabstop, parse_tabstops, main): Don't reserve UINTMAX_MAX
+ as a tab stop.
+ (parse_tabstops): Don't use ISBLANK on possibly-signed char.
+ Detect overflow in tab stop string.
+ (next_file, main): Use EXIT_FAILURE/EXIT_SUCCESS instead of 1/0.
+ (unexpand): Concatenate input files the same way expand does.
+
+ * src/touch.c (no_create, use_ref, posix_date, amtime_now,
+ touch, main): Use bool for booleans.
+ (main): Avoid integer overflow when given more than INT_MAX
+ options.
+ * src/tsort.c (struct item, n_strings): Use size_t for sizes.
+ (have_read_stdin, count_items, scan_zeros, detect_loop,
+ recurse_tree, walk_tree, tsort, main):
+ Use bool for booleans.
+ (exit_status): Remove.
+ (tsort): Return a success flag instead of storing into a global.
+ (main): Use it.
+ * src/tty.c (silent, main): Use bool for booleans.
+ (main): 0 -> STDIN_FILENO.
+ * src/uname.c (print_element): Use bool for booleans.
+
+ * src/test.c (TRUE, FALSE, SHELL_BOOLEAN, TRUTH_OR, TRUTH_AND):
+ Remove. All uses replaced by C99 boolean primitives.
+ (TEST_TRUE, TEST_FALSE): New constants, for readability.
+ (test_unop, binop, unary_operator, binary_operator, two_arguments,
+ three_arguments, posixtest, expr, term, and, or, is_int, age_of,
+ one_argument, main): Use bool for booleans.
+ (advance, unary_advance): Now inline procedures rather than a macros.
+ (is_int): Renamed from isint, to avoid namespace clash with ctype.h.
+ (term, and, or): When it's easy, loop instead of recursing.
+ (term): Avoid integer overflow if there are INT_MAX-3 args (!).
+ (binary_operator, unary_operator): Simplify by systematically rewriting
+ true==FOO to FOO (where FOO is a boolean).
+ (unary_operator): Don't consider a file to be a regular file
+ merely because its mode&S_IFMT is zero. Just use S_ISREG.
+ Remove unnecessary casts. Remove ifdefs for things like
+ S_ISSOCK that are no longer needed, since stat-macros.h always
+ defines them now.
+
+ * src/tac-pipe.c (buf_init_from_stdin, find_bol, tac_mem):
+ Use bool for booleans.
+ (buf_init_from_stdin, buf_free, find_bol, print_line):
+ Use size_t for sizes.
+ * src/tac.c (separator_ends_record, tac_seekable, tac_file,
+ tac_stdin, tac_stdin_to_mem, main): Use bool for booleans.
+ (match_length, G_buffer_size, tac_seekable, main): Use size_t for sizes.
+ (tac_seekable): Use ptrdiff_t for pointer subtraction.
+ Report an error if the result is out of range.
+ (tac_seekable, main): Check for integer overflow in buffer size
+ calculations.
+ (main): Remove unnecessary casts.
+
+ * src/su.c (run_shell): Pass a new n_additional_args arg, so that
+ the callee doesn't have to count 'em. All callers changed.
+ Don't allocate more space for the arg vector than we'll need.
+ Use memcpy to copy the args rather than rolling our own loop.
+ Use size_t for sizes.
+ (fast_startup, simulate_login, change_environment, log_su,
+ correct_password, restricted_shell, main): Use bool for booleans.
+ (longopts): Don't assume change_environment is an int.
+ Use NULL, not 0, for pointers.
+ (xsetenv): New function, replacing xputenv and concat.
+ All callers changed.
+ (elements): Remove; no longer needed.
+ (log_su, correct_passwd, main): Prefer !x to x==NULL.
+ (log_su): 2 -> STDERR_FILENO.
+ (modify_environment, main): Don't assume that getenv's returned value
+ has an indefinite lifetime.
+ (modify_environment): Allocate a larger environ.
+ (main): Remove an impossible 'case 0'; if it happens now, it'll
+ get diagnosed. Don't assume getpwnam results outlive endpwent.
+ Check for null or empty pw_name, pw_dir and for null pw_passwd.
+
+ * src/stty.c (VA_START): Remove. All callers now use va_start.
+ (_POSIX_VDISABLE): Remove unnecessary cast.
+ (struct control_info, visible): Use cc_t for control chars.
+ (struct control_info): Use size_t for sizes.
+ (recover_mode, set_mode, display_speed, display_window_size,
+ valid_options, main, display_changed):
+ Use bool for booleans.
+ (integer_arg): Return unsigned long int, not long int.
+ Accept new max arg; all callers changed, to specify a maximum
+ value for integer parameters instead of silently overflowing.
+ (wrap): Do not overrun the stack buffer if the output contains
+ more than 1024 bytes. Instead, malloc a buffer.
+ (main): Remove a "what is this?!?" FIXME. Nobody knows what it is.
+ Remove unnecessary casts.
+ (set_control_char): Allow int values only up to cc_t range.
+ (screen_columns): Don't reject INT_MAX.
+ (display_changed, display_all, display_speed, recover_mode):
+ Don't assume cc_t fits in int.
+
+ * src/remove.h: Add copyright notice.
+ (struct rm_options): Use bool for booleans.
+ * src/rmdir.c (empty_paths, ignore_fail_on_non_empty, verbose,
+ errno_rmdir_non_empty, remove_parents, main): Likewise.
+ * src/sum.c (have_read_stdin, bsd_sum_file, sysv_sum_file,
+ main): Likewise.
+ (main): Don't dump core if invoked with argv[0]==NULL.
+ * src/tee.c (tee, append, ignore_interrupts, main, tee):
+ Use bool for booleans.
+ (tee): Use ssize_t for read returns.
+
+ * src/ptx.c: Add a FIXME mentioning that there are many
+ unchecked integer overflows in this file.
+ (gnu_extensions, auto_reference, input_reference, right_reference,
+ ignore_case, initialize_regex, fix_output_parameters,
+ output_one_roff_line, output_one_text_line, output_one_dumb_line, main):
+ Use bool for booleans.
+ (SKIP_SOMETHING, compare_words, digest_break_file,
+ find_occurs_in_text, fix_output_parameters):
+ Use to_uchar instead of a caset.
+ (print_field): Rewrite to avoid cast.
+
+ * src/printf.c (posixly_correct): Use bool for booleans.
+ (verify, main): Use EXIT_FAILURE/EXIT_SUCCESS instead of 1/0.
+ (STRTOX): Rewrite to avoid casts.
+ (print_esc_char): Arg is char, not int.
+ * src/readlink.c (canonicalize): Remove. All uses now merely inspect
+ can_mode.
+ (no_newline, verbose): Use bool for booleans.
+ (can_mode): Now of type int; use -1 to denote otherwise-uninitialized.
+ * src/shred.c (struct Options, main): Use bool for booleans.
+ (isaac_seed_data, fillpattern, wipefile): Rewrite to avoid casts.
+ * src/split.c (cwrite, bytes_split, lines_split, line_bytes_split):
+ Use bool for booleans.
+ * src/stat.c (G_fail): Remove.
+ (print_statfs): Print various gotta-be-nonnegative values using
+ unsigned long int, not long int or int.
+ (do_statfs, do_stat): Return a boolean success flag.
+ (do_stat, main): Use bool for booleans.
+
+ * src/pr.c: Add a FIXME mentioning that there are many
+ unchecked integer overflows in this file.
+ (TRUE, FALSE): Remove. All uses replaced by true and false.
+ (struct COLUMN, read_line, print_page, print_stored, open_file,
+ skip_to_page, init_fps, parallel_files, align_empty_cols,
+ empty_line, FF_only, explicit_columns, extremities, keep_FF,
+ print_a_FF, print_a_header, use_form_feed, have_read_stdin,
+ print_across_flag, storing_columns, balance_columns,
+ truncate_lines, join_lines, untabify_input, failed_opens,
+ numbered_lines, skip_count, use_esc_sequence, use_cntrl_prefix,
+ double_space, ignore_failed_opens, use_col_separator,
+ pad_vertically, last_line, main, init_parameters, skip_read,
+ read_line, print_stored):
+ Use bool for booleans.
+ (struct COLUMN, char_to_clump, store_char, print_char):
+ Use char for chars.
+ (clump_buff, print_clump): Use char[], not int[], for an array whose
+ elements are always chars.
+ (first_last_page, main, getoptarg, balance, add_line_number,
+ char_to_uclump): Remove unnecessary casts.
+ (init_parameters): Allocate chars, not ints, for clump_buff.
+ (print_char): Use to_uchar before invoking ISPRINT.
+ (char_to_clump): Convert to unsigned char before invoking ISPRINT.
+
+ * src/nohup.c (main): Use bool for booleans.
+ * src/paste.c (paste_parallel, paste_serial, main): Likewise.
+ * src/pathchk.c (validate-path, main, portable_chars_only): Likewise.
+ (portable_chars_only): Use to_uchar rather than a cast.
+ * src/printenv.c (main): Use bool for booleans.
+ Do not assume that the environ has at most one matching entry
+ for each option (integer overflow was possible otherwise).
+
+ * src/od.c (FMT_BYTES_ALLOCATED): Now an enum, not a decimal
+ constant. Do not assume PRIdMAX etc. are strings of length 3 or
+ less.
+ (struct tspec): Use it. fmt_string is now an array, not
+ a pointer, as there's little point to the indirection here.
+ (struct tspec, flag_dump_strings,
+ traditional, flag_pseudo_start, limit_bytes_to_format,
+ abbreviate_duplicate_blocks, have_read_stdin, simple_strtoul,
+ decode_one_format, open_next_file, check_and_close,
+ decode_format_string, skip, write_block, read_char, read_block,
+ parse_old_offset, dump, dump_strings, main):
+ Use bool for booleans.
+ (struct tspec): Use void *, not char *, for generic pointers.
+ (bytes_to_oct_digits, bytes_to_signed_dec_digits,
+ bytes_to_unsigned_dec_digits, bytes_to_hex_digits):
+ Use char, not unsigned int, since char suffices.
+ (print_s_char, print_char, print_s_short, print_short,
+ print_int, print_long, print_long_long, print_float,
+ print_double, print_long_double): Rewrite to avoid casts.
+ These now take void * arguments, instead of char *.
+ Use the same body for all functions, except for the choice
+ of type. Assume C89 to simplify handling of signed char.
+ (dump_hexl_mode_trailer, print_named_ascii, print_ascii):
+ Rewrite to avoid casts.
+ (print_named_ascii, print_ascii): Now takes void *, not char *.
+ (decode_one_format): Use int for printf field widths, not
+ unsigned int. Pass void * to subsidiary printers,
+ not char *. Simplify handling of floating-point formats
+ by factoring out common code dealing with precision and field width.
+ (decode_format_string): Avoid need for temporary copy of
+ each decoded struct tspec.
+ (get_lcm): Remove unnecessary cast.
+ (main): Fix bug where more than INT_MAX failed decodes were ignored.
+
+2004-08-02 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/nl.c (TRUE, FALSE): Remove; all uses changed to true, false.
+ (enum number_format): Remove.
+ (FORMAT_RIGHT_NOLZ, FORMAT_RIGHT_LZ, FORMAT_LEFT): Now strings,
+ not enum values.
+ (DEFAULT_SECTION_DELIMITERS): Now an array constant, not a macro.
+ (section_del): Now const.
+ (print_fmt): Remove.
+ (starting_line_number, page_incr, blank_join, line_no,
+ print_lineno, proc_text, main):
+ Use intmax_t for line numbers.
+ (reset_numbers, have_read_stdin, build_type_arg, nl_file, main):
+ Use bool for booleans.
+ (lineno_format): Now a string, not an enum value.
+ (build_print_fmt): Remove. All calls removed. This work is
+ now done within print_lineno.
+ (build_type_arg): Use size_t for sizes.
+ (print_lineno): Check for line number overflow.
+ (proc_text, main): Remove unnecessary cast.
+
+ * src/ln.c (symbolic_link, interactive, remove_existing_files,
+ verbose, hard_dir_link, dereference_dest_dir_symlinks,
+ do_link, main): Use bool for booleans.
+
+ * src/ls.c (struct fileinfo, file_interesting,
+ extract_dirs_from_files, color_symlink_as_referent,
+ FILE_OR_LINK_MODE, sort_reverse, print_owner, print_group,
+ numeric_ids, print_block_size, dired, print_with_color,
+ check_symlink_color, print_inode, recursive, immediate_dirs,
+ all_files, really_all_files, qmark_funny_chars,
+ print_dir_name, format_needs_stat, format_needs_type, visit_dir,
+ main, decode_switches, parse_ls_color, print_dir, file_interesting,
+ gobble_file, make_link_path, basename_is_dot_or_dotdot,
+ extract_dirs_from_files, print_long_format):
+ Use bool for booleans.
+ (dir_defaulted): Remove; no longer needed.
+ (main): Use int to count files, since it suffices for argv.
+ Rewrite to avoid need for dir_defaulted.
+ (main, print_dir, gobble_file, get_link_name,
+ xstrcoll):
+ Set exit status to EXIT_SUCCES/EXIT_FAILURE rather than 0/1.
+ (decode_switches): Put back check for ws.ws_col <= SIZE_MAX.
+ Remove unnecessary cast to int. Use int instead of unsigned
+ int to count from 0 to 1.
+ (get_funky_string, print_type_indicator): Use char for bytes, not int.
+ (make_link_path): Use NULL for null pointers.
+ (quote_name): Use to_uchar instead of cast.
+
+ * src/id.c (use_name, main, print_user, xgetgroups, print_group_list,
+ print_full_info): Use bool for booleans.
+ (problems): Remove, replacing with....
+ (ok): New var (inverted from old sense).
+ (print_user, print_group, print_full_info):
+ Print uids/gids with %lu, not %u.
+ (xgetgroups): Don't run out of memory if getgroups or getugroups
+ returns -1.
+ * src/setuidgid.c (main): Print uids/gids with %lu, not %ld.
+
+ * src/factor.c (wheel_tab): Use unsigned char instead of unsigned
+ int, since it suffices.
+ (factor, print_factors): Use size_t for sizes.
+ (print_factors, do_stdin, main): Use bool for booleans.
+ * src/fold.c (TAB_WIDTH): New macro; use it instead of "8".
+ (fold_file, main): Use bool for booleans.
+ (fold_file, main): Use size_t for sizes.
+ (main): Allow -w options up to SIZE_MAX - TAB_WIDTH - 1, instead
+ of prohibiting widths greater than INT_MAX.
+ * src/head.c (presume_input_pipe, print_headers, have_read_stdin,
+ write_header, elide_tail_bytes_pipe, elide_tail_bytes_file,
+ elide_tail_lines_pipe, elide_tail_lines_seekable,
+ elide_tail_lines_file, head_bytes, head_lines, head, head_file,
+ string_to_integer, main):
+ Use bool for booleans.
+ (main): Rewrite to avoid cast.
+
+ * src/csplit.c (struct line): Use size_t for sizes.
+ (main): Remove unnecessary cast.
+ * src/cut.c (cut_fields): Use to_uchar rather than a cast.
+ * src/cut.c (cut_file, main): Use bool for booleans.
+ * src/date.c (show_date, rfc_format, batch_convert, main): Likewise.
+ * src/env.c (main): Likewise.
+ * src/expr.c (nextarg): Likewise.
+ * src/env.c (main): Remove unused and nonstandard envp arg.
+
+ * src/fmt.c (COST, MAXWORDS): Add a comment describing some of
+ fmt's arbitrary limits.
+ (TRUE, FALSE): Remove; all uses changed to (true, false).
+ (main): Use bool for booleans.
+ Limit maximum width to MAXCHARS / 2. Use xstrtoul, not xstrtol,
+ to parse width.
+ (copy_rest): Remove unnecessary cast.
+ (get_prefix): Rewrite to avoid cast.
+ (check_punctuation): Use char *, not unsigned char *; C89 requires
+ this. Avoid off-by-one buffer read overrun when line is empty.
+ (flush_paragraph): Don't assume wptr-parabuf is <= INT_MAX.
+ Remove unnecessary casts.
+ * tests/fmt/basic (wide-1, wide-2, bad-suffix): Adjust to above
+ changes.
+
+ * src/expand.c (convert_entire_line, have_read_stdin, parse_tabstops,
+ next_file, expand, main):
+ Use bool for booleans.
+ (tab_size, tab_list, add_tabstop, parse_tabstops, validate_tabstops,
+ expand, main):
+ Use uintmax_t for column counts.
+ (add_tabstop): Don't reserve -1 (now UINTMAX_MAX) as a special value.
+ All callers changed.
+ (parse_tabstops): Don't pass a negative char to isblank.
+ Avoid memory leak with large tab stops.
+ (validate_tabstops, expand): Don't assume number of tab stops is
+ <= INT_MAX.
+ (next_file, main): Use EXIT_SUCCESS/EXIT_FAILURE rather than 0/1 when
+ storing values into exit_status.
+ (expand): Use same pattern as unexpand for reading chars.
+ Report an error when input line is too long, instead of silently
+ screwing up. Do not mishandle tab stops when backspacing left
+ over start of line.
+
+ * src/dircolors.c (have_read_stdin, append_quoted,
+ dc_parse_stream, dc_parse_file, main): Use bool for booleans.
+ (dc_parse_stream): Use enum for state, rather than int.
+ Use ssize_t to store getline result.
+
+ * src/dd.c (translation_needed, parse_integer, scanargs,
+ apply_translations, char_is_saved, swab_buffer, skip_via_lseek):
+ Use bool for booleans.
+ (translate_buffer): Use to_uchar rather than a cast.
+ (swab_buffer, copy_simple, copy_with_unblock):
+ Use size_t for sizes.
+
+ * src/seq.c (equal_width, valid_format, main): Use bool for booleans.
+ * src/sleep.c (apply_suffix): Likewise.
+ * src/tail.c (struct File_spec, reopen_inaccessible_files, count_lines,
+ forever, from_start, print_headers, have_read_stdin, valid_file_spec,
+ write_header, file_lines, pipe_lines, pipe_bytes, recheck,
+ tail_forever, tail_bytes, tail_lines, tail, tail_file,
+ parse_obsolescent_option, parse_options, main): Likewise.
+ * src/sleep.c (apply_suffix): Invert sense of result.
+ Use int (not unsigned int) for multiplier, as this generates better
+ code with some compilers. Simplify code a bit.
+ * src/tail.c (struct File_spec, max_n_unchanged_stats_between_opens,
+ parse_options): Use uintmax_t, not unsigned int or unsigned long int,
+ for state counters.
+ (tail_bytes, tail_lines): Redo test of return value (-1, 0, 1) to
+ make it a bit clearer.
+
+ * src/hostname.c: Include "xgethostname.h".
+ (xgethostname): Remove decl; xgethostname.h has it.
+ (sethostname) [!defined(HAVE_SETHOSTNAME) && defined(HAVE_SYSINFO)
+ && defined (HAVE_SYS_SYSTEMINFO_H) && defined(HAVE_LIMITS_H)]: Use
+ prototypes rather than K&R form. Assume any negative value from
+ sysinfo denotes failure, not just -1.
+ (main): Simplify use of sethostname.
+
+ * src/pinky.c (include_idle, include_heading, include_fullname,
+ include_project, include_plan, include_home_and_shell, do_short_format,
+ include_where, main): Use bool for booleans.
+ (count_ampersands, create_fullname, scan_entries, short_pinky):
+ Use size_t for sizes.
+ (create_fullname): Check for overflow in size calculations.
+ (idle_string): Don't assume that the number of idle days
+ is less than 10**8 and/or INT_MAX/(24*60*60).
+ (main): No need to pass a non-NULL last arg to getopt_long.
+ * src/uptime.c (print_uptime, uptime): Use size_t for sizes.
+ (print_uptime): Remove unused local variable.
+ (main): No need to pass a non-NULL last arg to getopt_long.
+ * src/users.c (list_entries_users, users): Use size_t for sizes.
+ (list_entries_users): Use char for bytes.
+ (main): No need to pass a non-NULL last arg to getopt_long.
+ * src/who.c (do_lookup, short_list, short_output, include_idle,
+ include_heading, include_mesg, include_exit, need_boottime,
+ need_deadprocs, need_login, need_initspawn, need_clockchange,
+ need_runlevel, need_users, my_line_only, main): Use bool for booleans.
+ (print_runlevel): Use unsigned char for bytes.
+ (list_entries_who, scan_entries, who): Use size_t for sizes.
+ (main): No need to pass a non-NULL last arg to getopt_long.
+
+ * src/install.c (isdir): Remove decl.
+ (install_file_to_path): Rely on make_path to fail if the destination
+ is not a directory, by passing preserve_existing==true to it.
+ Hence we no longer need to call isdir.
+ Free dest_dir immediately when it's no longer needed, rather than
+ waiting until the end of the function.
+ (copy_file): Don't bother calling isdir, as copy will do the
+ right thing if the destination is a directory.
+
+ * src/du.c (fts_debug, opt_all, apparent_size, opt_count_all,
+ print_grand_total, opt_separate_dirs, hash_ins, process_file, main):
+ Use bool for booleans.
+ (max_depth): Now size_t, not int, to avoid an arbitrary limit
+ of INT_MAX on depth.
+ (G_fail): Remove: no longer needed, now that the relevant
+ functions return bool.
+ (process_file): Use return value to signal success rather than
+ setting a global. Remove first_call static var; not needed, since
+ we can look at n_alloc. Use size_t for depths. Remove FIXME
+ about size_t casts, as it's now fixed. Use xnrealloc rather
+ than the obsolescent XREALLOC. Don't bother to check whether
+ reallocation is needed unless level > prev_level.
+ (du_files): Invert sense of result, for consistency with
+ other coreutils code. All callers changed.
+ (main): Allow --max-depth values up to SIZE_MAX.
+
+ * src/df.c (inode_format, show_all_fs, show_local_fs,
+ show_listed_fs, posix_format, require_sync, print_type,
+ selected_fstype, excluded_fstype, show_dev, show_point, main):
+ Use bool for booleans.
+ (df_readable, show_dev): Use UINTMAX_MAX instead of -1.
+ (show_dev, show_point, main):
+ Use EXIT_SUCCESS/EXIT_FAILURE instead of 0/1.
+ Don't assume disk name lengths are <= INT_MAX.
+ Rewrite pct calculation to avoid cast.
+ (show_point): Don't assume resolved length is <= SSIZE_MAX.
+
+ * src/cut.c (hash_int) [!defined UINTPTR_MAX]: Use size_t
+ instead of uintptr_t.
+ * src/shred.c (UINT_MAX_32_BITS): Remove.
+ (word32): Remove. All uses changed to uint32_t.
+ (isaac_seed_data): Remove unnecessary cast.
+ * src/system.h (ptr_align): Use size_t; in practice, this is just as
+ good as uintptr_t in checking for alignments, and has fewer
+ configuration hassles.
+
+ * src/Makefile.am (localedir.h): Make it readonly; this
+ undoes part of the 2004-07-27 patch.
+
+2004-07-30 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/sort.c (UCHAR): Remove; all uses changed to to_uchar.
+ (IS_THOUSANDS_SEP): Use bool when appropriate.
+ (numcompare, main): Use char, not int, when the value is always a char.
+ (numcompare): Remove "register"; compilers are smart enough these days.
+ * src/system.h (errno, CHAR_BIT): Remove decls;
+ no longer needed now we assume C89 or better.
+ Include <inttypes.h> before <stdint.h>, as it's the
+ Autoconf-recommended pattern.
+ (to_uchar): New inline function, moved here from tr.c.
+ Use full names for int types, e.g. "long int" rather than "long".
+ * src/tr.c (to_uchar): Remove; now in system.h.
+ (is_char_class_member): Use bool when appropriate.
+
+ * src/mkdir.c (create_parents, main): Use bool when appropriate.
+ (main): Use EXIT_SUCCESS/EXIT_FAILURE instead of 0/1.
+
+2004-07-29 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/mkfifo.c (main): Use EXIT_SUCCESS and EXIT_FAILURE, not 0 and 1.
+
+ * src/chmod.c (recurse, force_silent, process_file, process_files,
+ main): Use bool when appropriate.
+ * src/cksum.c (cksum, main): Likewise.
+ * src/comm.c (hard_LC_COLLATE, only_file_1, only_file_2, both,
+ compare_files, main): Likewise.
+
+ * src/copy.h (struct cp_options): Likewise.
+ * src/copy.c (copy_internal, is_ancestor, copy_dir, copy_reg,
+ same_file_ok, seen_file, copy_internal, valid_options, copy): Likewise.
+ * src/cp-hash.h (remember_created): Likewise.
+ * src/cp-hash.c (remember_created): Likewise.
+ * src/cp.c (struct dir_attr, flag_path, remove_trailing_slashes,
+ re_protect, make_path_private, target_directory_operand, do_copy,
+ cp_option_init, decode_preserve_arg, main): Likewise.
+ * src/install.c (isdir, change_timestamps, change_attributes,
+ copy_file, install_file_to_path, install_file_in_dir,
+ install_file_in_file, strip_files, dir_arg, cp_option_init, main,
+ change_attributes, change_timestamps): Likewise.
+ * src/mv.c (remove_trailing_slashes, rm_option_init,
+ cp_option_init, do_move, movefile, main): Likewise.
+ * src/remove.c (right_justify), full_filename_, AD_pop_and_chdir,
+ AD_push, prompt, remove_dir): Likewise.
+ * src/rm.c (rm_option_init, main): Likewise.
+
+ * src/remove.c (top_dir, pop_dir, full_filename_):
+ Use size_t for sizes.
+ * src/cp.c (target_directory_operand): Do not clear *NEW_DST if stat
+ succeeds. It's not necessary in that case, as *NEW_DST is always
+ false already.
+ (do_copy): Rewrite slightly to avoid need for "unreachable" comment.
+ (main): Use EXIT_SUCCESS, EXIT_FAILURE instead of 0, 1.
+ * src/rm.c (main): Likewise.
+
+ md5sum, sha1sum integer cleanups.
+
+ * src/checksum.h: Don't include config.h, sys/types.h, stdio.h:
+ not needed.
+ (ALG_UNSPECIFIED): Remove.
+ (ALG_MDT): Don't make it equal to CHAR_MAX + 1; this isn't necessary.
+ * src/md5.c: Don't include any files other than checksum.h.
+ * src/sha1sum.c: Likewise.
+ * src/md5sum.c (OPENOPTS, have_read_stdin, status_only, warn,
+ bsd_split_3, split_3, hex_digits, digest_file, digest_check, main):
+ Use bool when appropriate.
+ (digest_check): Increase limit of number of input lines to
+ UINTMAX_MAX from INT_MAX. Diagnose any overflows of this counter.
+ Use ngettext instead of hard-to-i18nize hardcoded stuff for plurals.
+
+2004-07-28 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/cat.c (exit_status): Remove. Now done by passing a boolean
+ 'ok' flag around.
+ (simple_cat, cat): Return true if successful. All callers changed.
+ (simple_cat, cat, main): Use bool for booleans.
+ (simple_cat): Use size_t for sizes.
+ (cat, main): Use the same names for parameters that we use for
+ long options, to avoid confusion. This inverts the sense of the
+ show_tabs (formerly output_tabs) and number_nonblank
+ (formerly numbers_at_empty_lines) variables.
+ (main): Don't mess up (due to integer overflow) if we are given
+ INT_MAX - INT_MIN + 1 options.
+ [O_BINARY]: Don't invoke isatty unless the other options require it.
+ (main): When deciding whether to use simple_cat, don't worry
+ about binary option; it's irrelevant.
+
+ * src/dcgen: Remove comments, trailing white space, and empty
+ lines from the output strings, to save space.
+ Use a narrower type like 'unsigned char' for line lengths, if
+ that will do.
+ Make the output variables static, not extern.
+
+ * src/chgrp.c (parse_group): Require base 10 when parsing
+ groups as integers.
+ (main): int -> bool when appropriate.
+ * src/chown.c (main): Likewise.
+ * src/chown-core.c: Include inttostr.h.
+ (UINT_MAX_DECIMAL_DIGITS, uint_to_string): Remove.
+ (gid_to_name, uid_to_name): Use imaxtostr/umaxtostr
+ instead of uint_to_string).
+ (describe_change): Instead of an int flag, use a char *
+ auxiliary; this avoids the need for casts.
+ Assume free (NULL) works.
+ (change_file_owner): Return true/false, not 0/-1, since
+ we don't set errno. All callers changed.
+ Use bool when appropriate.
+ (chown_files): Likewise.
+ * src/chown-core.h (chown_files): Likewise.
+
+ * tests/chown/basic: Test for proper handling of uids like
+ "010", which must be parsed as decimal.
+
+ * tests/misc/pwd: Don't assume that Perl's getpwd agrees with our
+ pwd when there are multiple names for the working directory
+ (which can happen with an automounter, sigh).
+
+ * src/Makefile.am ($(SCRIPTS)): Don't depend on Makefile;
+ this causes Solaris 8 'make' to refuse to build "groups".
+ (localedir.h): Don't depend on Makefile: this causes Solaris
+ 8 'make' to build localedir.h unnecessarily. The dependence
+ on Makefile is ineffective anyway, since $(localedir) might
+ change even if Makefile hasn't.
+
+ * src/remove.c (remove_dir): If we can't save the state of the
+ working directory, pretend we started from "/", not ".".
+ This avoids a bug on hosts like Solaris that don't let you
+ remove the working directory.
+
+2004-07-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/printf.c (strtiomax, strtoumax): Declare if not already
+ declared: this fixes a portability bug with Solaris 8 + GCC.
+ (STRTOX): Parenthesize use of macro arg as expression.
+ (vstrtoimax, vstrtoumax, vstrtold): Remove now-unnecessary
+ parentheses.
+ * configure.ac: Check for declaration of strtoumax, for
+ src/printf.c.
+
+ * src/Makefile.am (cp_LDADD, ginstall_LDADD, mv_LDADD,
+ pathchk_LDADD, rm_LDADD, test_LDADD): New vars, for eaccess.
+
+ * tests/readlink/can-e: Don't assume that we can remove the
+ working directory: this isn't possible under Solaris 8, say.
+ * tests/readlink/can-f: Likewise.
+ * tests/readlink/can-m: Likewise.
+
+ * src/copy.c (copy_internal): find_backup_file_name no longer
+ returns NULL, so don't bother to check for this.
+ * src/cp.c (do_copy): Likewise.
+ * src/ln.c (do_link): Likewise.
+
+2004-07-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/nice.c (GET_NICE_VALUE): Renamed from GET_PRIORITY.
+ All uses changed.
+ (NZERO): New macro, if system doesn't define it already.
+ (usage): Distinguish priorities from nice values.
+ Don't assume NZERO is 20.
+ (main): Use bool instead of int where appropriate.
+ If user specifies an adjustment out of range, always truncate it
+ to an inrange value instead of sometimes giving an error message
+ and sometimes not.
+ Do not assume that -1 is an error return from "nice" or
+ "getpriority", as it might be the current nice value minus NZERO.
+ If nice/setpriority fails with errno == EPERM, go ahead and run
+ the command anyway; POSIX requires this.
+
+ * src/pathchk.c: Include euidaccess.h.
+ (dir_ok): Use euidaccess, not access.
+ * src/test.c (R_OK, W_OK, X_OK, FOK): Remove; system.h defines them.
+ (eaccess): Remove. All users changed to use euidaccess instead.
+
+2004-07-24 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/uptime.c (print_uptime) [defined BOOT_MSG]:
+ Don't assume ut_line is null-terminated.
+ * src/who.c (print_line): New arguments USERLEN and LINELEN,
+ since USER and LINE might not be null terminated. All callers
+ changed.
+
+2004-07-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix bug with "tail -f" reported by Rob Holland in
+ <http://lists.gnu.org/archive/html/bug-coreutils/2004-07/msg00054.html>.
+ Also, remove the undocumented and unsupported-since-2000
+ --max-consecutive-size-changes options. Fix another related bug:
+ "tail" got confused if stdin, stdout, or stderr were closed.
+ Also, use output buffering even with "tail -f".
+
+ * NEWS: Document this, plus yesterday's patch.
+ * doc/coreutils.texi (tail invocation): "size has remained the same"
+ -> "file has not changed", which is more accurate for fifos.
+ * src/tail.c: Include fcntl-safer.h.
+ (COPY_TO_EOF): Set to UINTMAX_MAX, not OFF_T_MAX (which was wrong).
+ (COPY_A_BUFFER): New macro.
+ (struct File_spec): New members mtime, mode, blocking.
+ Remove member n_consecutive_size_changes.
+ (DEFAULT_MAX_N_CONSECUTIVE_SIZE_CHANGES,
+ max_n_consecutive_size_changes_between_opens,
+ MAX_CONSECUTIVE_SIZE_CHANGES_OPTION): Remove.
+ (long_options, tail_forever, parse_options):
+ Remove (non-)support for --max-consecutive-size-changes.
+ (record_open_fd): New function.
+ (recheck, tail_file): Use it. Don't assume that stdin is open.
+ (dump_remainder): Add support for new COPY_A_BUFFER special value.
+ Treat errno==EAGAIN like EOF, since it might be a nonblocking read.
+ (recheck): New arg BLOCKING, specifying whether to use blocking reads.
+ All uses changed.
+ (n_live_files): Remove, replacing with...
+ (any_live_files): New function. All uses changed.
+ (tail_forever): Use nonblocking I/O unless we know that blocking I/O
+ is safe; this avoids some hangs when reading from a fifo.
+ Avoid invoking fstat or sleep when using blocking I/O.
+ Do not check for changes to size if the file is not a regular file,
+ as the size is undefined in that case.
+ Check for changes to mtime or mode, too; this works for non-regular
+ files.
+ (tail_forever, main): Redo fflush strategy to work even when input
+ is nonblocking. Don't use unbuffered output; just flush when needed.
+
+2004-07-22 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/tail.c (main): Ignore -f if no file operand is specified
+ and standard input is a pipe.
+ * doc/coreutils.texi (tail invocation): Do not ignore -f for
+ all pipes, just for when standard input is a pipe and no
+ file operand is specified.
+ * tests/tail/Test.pm: Reinstate f-1 test, since we now pass.
+ Add a new commented-out f-2 test, which we still fail.
+ (test_vector): All f-* tests are special cases, not just f-1.
+
+2004-07-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/uptime.c: Include c-strtod.h.
+ (print_uptime): Use c_strtod instead of setlocale and sscanf.
+ Use long int rather than int to count days (for 64-bit hosts),
+ and check for arithmetic overflow when converting double to time_t.
+
+2004-07-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/printf.c (vstrtold): Renamed from vstrtod.
+ Now returns long double. All uses changed.
+ (print_direc): Use "L" length modifier when printing floating point
+ numbers, since we're now printing long double.
+
+2004-07-06 Paul Eggert <eggert@cs.ucla.edu>
+
+ * Version 5.3.0.
+
+ printf cleanup, to avoid undefined behavior, to add support for
+ formats that Bash supports, and to support wide integers like
+ Bash does.
+
+ * NEWS: Document this.
+ * src/printf.c (UNSPECIFIED): Remove. All uses now replaced by
+ booleans, so that we don't reserve any values for precision or
+ width (like Bash).
+ (STRTOX): Use prototype, not K&R-style definition.
+ (vstrtoimax): Renamed from xstrtol (to avoid confusion with xstrtol
+ in ../lib), with type change to intmax_t.
+ All uses changed.
+ (vstrtoumax): Renamed from xstrtoul, with type change to uintmax_t.
+ All uses changed.
+ (vstrtod): Renamed from xstrtod. All uses changed.
+ (print_direc): Use boolean arg instead of special value to indicate
+ a missing precision or width. LENGTH no longer includes
+ length modifiers or conversion character. New arg CONVERSION
+ now specifies conversion character.
+ Use intmax_t-width formatting for integers (like Bash).
+ Add support for C99 %a, %A, %F (like Bash).
+ Add support for field width with %c (POSIX requires this).
+ Add a FIXME for lack of support for field width and precision
+ for %b.
+ Add support for '\'', '0' flags.
+ Check for invalid combinations of flags, field width, precision,
+ and conversion, to prevent use of undefined behavior.
+ Allow multiple length modifiers, for formats like "%lld" (like Bash).
+ Add support for C99 'j', 't', 'z' length modifiers (like Bash).
+ In error message, output entire invalid conversion specification,
+ instead of merely outputting % followed by the conversion char.
+ * tests/misc/printf: Add tests for the above.
+
+2004-04-03 Dmitry V. Levin <ldv@altlinux.org>
+
+ Change "readlink -f" to be more compatible with prior implementations.
+ Add more canonicalize options, -e and -m.
+ Add comprehensive tests for all readlink modes.
+
+ * m4/canonicalize.m4 (AC_FUNC_CANONICALIZE_FILE_NAME):
+ Do not add canonicalize.c here.
+
+ * src/readlink.c (longopts): Add new options.
+ (usage): Document them.
+ (canonicalize_fname): New proxy function.
+ (main): Handle new options.
+ * doc/coreutils.texi (readlink invocation): Document new
+ "readlink -f" behaviour and new canonicalize options, -e and -m.
+
+ * configure.ac (AC_CONFIG_FILES): Add tests/readlink/Makefile.
+ * tests/Makefile.am (SUBDIRS): Add readlink.
+ * tests/readlink/Makefile.am: New file.
+ * tests/readlink/{rl-1,can-e,can-f,can-m}: New readlink tests.
+ * tests/misc/Makefile.am (TESTS): Remove basic readlink test.
+ * tests/misc/readlink: Remove file.
+
+2004-07-04 Jim Meyering <jim@meyering.net>
+
+ * src/copy.c (copy_internal): Add a FIXME comment.
+
+2004-07-02 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/copy.c (copy_dir): Assume path_concat returns non-NULL.
+ * src/cp.c (do_copy): Likewise.
+ * src/mv.c (movefile): Likewise.
+
+ * src/cp.c (make_path_private): 2nd arg is now size_t, not int,
+ to avoid problem when path_concat dir name is longer than 2 GiB (!).
+
+ * src/nohup.c (main): Don't pass NULL first argument to path_concat.
+ This cleans up the semantics a bit, as we no longer try to open the
+ same file twice.
+
+2004-07-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ * NEWS: Add short names -t and -T for --target-directory
+ and --no-target-directory options, respectively.
+
+ * src/cp.c (NO_TARGET_DIRECTORY_OPTION, TARGET_DIRECTORY_OPTION):
+ Remove. All uses changed to 'T' and 't', respectively.
+ * src/install.c, src/ln.c, src/mv.c: Likewise.
+
+ * src/cp.c (long_opts, usage, do_copy, main): Add -t and -T as
+ aliases for --target-directory and --no-target-directory,
+ respectively.
+ * src/install.c (long_options, main, usage): Likewise.
+ * src/ln.c, src/mv.c: Likewise.
+
+2004-07-01 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (sc_file_system): New target.
+ (syntax-check-rules): Add it.
+ .x-sc_file_system: New file.
+ * Makefile.am (EXTRA_DIST): Add it.
+
+ * man/sync.x: Use "file system" rather than "filesystem".
+ * man/stat.x, man/df.x: Likewise.
+
+2004-06-30 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/df.c (usage, main): Output "file system" rather than
+ "filesystem".
+ * src/du.c (usage): Likewise.
+ * src/shred.c (usage): Likewise.
+ * src/stat.c (usage): Likewise.
+ * src/stat.c (long_options, usage): Rename "--filesystem" to
+ "--file-system". But keep the old name around, for compatibility
+ reasons.
+
+2004-06-29 Paul Eggert <eggert@cs.ucla.edu>
+
+ Add support for --no-target-directory option.
+
+ * NEWS: Document it.
+ * doc/coreutils.texi (Common options, Target directory, cp
+ invocation, install invocation, mv invocation, ln invocation):
+ Likewise.
+ (link invocation): Explain how to rewrite link using ln now
+ that we have --no-target-directory.
+ (ln invocation): Explain that --no-target-directory subsumes
+ --no-dereference.
+ (unlink invocation): Modify wording to match new wording in
+ link invocation.
+
+ * src/cp.c (NO_TARGET_DIRECTORY_OPTION): New constant.
+ (long_opts, usage, do_copy, main): Add support for
+ --no-target-directory,
+ * src/install.c (NO_TARGET_DIRECTORY_OPTION, long_options, main,
+ usage): Likewise.
+ * src/ln.c (NO_TARGET_DIRECTORY_OPTION, long_options, usage,
+ main): Likewise.
+ * src/mv.c (NO_TARGET_DIRECTORY_OPTION, long_options, usage,
+ main): Likewise.
+ * src/mv.c (enum): Sort values.
+
+2004-06-29 Jim Meyering <jim@meyering.net>
+
+ Don't let verbose-mode output from a subshell obscure actual differences.
+ * tests/rm/inaccessible: Turn off command-echoing just before
+ invoking subshell, then turn it back on if VERBOSE=yes afterward.
+
+2004-06-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Add support for 'install --target-directory', an option
+ that has been documented for years but not implemented (!).
+ * doc/coreutils.texi (install invocation): Document
+ --target-directory in synopsis, too.
+ * src/install.c (TARGET_DIRECTORY_OPTION): New var.
+ (long_options, main, usage): Add --target-directory.
+ (target_directory_operand): New function, stolen from mv.c.
+ (main): Use it. Check for -d and --target-directory.
+ Alter wording of diagnostics to match other programs.
+
+2004-06-28 Jim Meyering <jim@meyering.net>
+
+ * src/cp.c (usage): Fix copy+paste error in description of
+ --target-directory: s/move/copy/. From Paul Jarc.
+
+2004-06-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Use more-consistent rules among cp, ln, and mv when dealing with
+ last operands that are (or look like) directories.
+
+ * src/cp.c (target_directory_operand): New, nearly-common function,
+ It reports an error if the destination appears to be a directory
+ (e.g., because it has a trailing slash) but is not.
+ * src/ln.c, src/mv.c: Likewise.
+ * src/cp.c (do_copy): Use it.
+ * src/ln.c (main): Likewise.
+ * src/mv.c (main): Likewise.
+
+ * src/cp.c (do_copy): Don't assume argc is positive.
+ Don't bother to lstat dest, since copy() will do that for us.
+ Use "const" to avoid the need for cast.
+
+ * src/cp.c (do_copy): Don't output a usage message because of file
+ problems (e.g., an operand is not a directory). Use it only for
+ syntax. Standardize on "target %s is not a directory" for the
+ diagnostic.
+ * src/ln.c (main): Likewise.
+ * src/mv.c (main): Likewise.
+
+ * src/cp.c (do_copy): Remove test for trailing slash, since
+ target_directory_operand now does this.
+ * src/ln.c (main): Likewise.
+ * src/mv.c (movefile): Likewise.
+
+ * src/cp.c (main): Reject multiple target directories.
+ Check whether a specified target is a directory when parsing the
+ options, using stat. This gives more-accurate diagnostics.
+ * src/ln.c (main): Likewise.
+
+ * src/ln.c (isdir): Remove decl; no longer needed.
+ * src/mv.c (isdir, lstat): Likewise.
+
+ * src/ln.c (do_link): New arg dest_is_dir. All uses changed.
+ Don't check the destination ourself; rely on dest_is_dir.
+ This way we can avoid lstatting the destination in the
+ usual case, and in the worst case we lstat 1, not 3 times.
+ Don't bother to unlink unless link failed; this saves a syscall.
+ Remove unnecessary backup_succeeded flag;
+ it was identical to "dest_backup != NULL".
+
+ * src/ln.c (main): Use int to count to argc, not unsigned int.
+ This handles negative operand counts.
+ * src/mv.c (main): Likewise.
+
+ * src/mv.c (do_move): Don't call hash_init; expect the caller to
+ do it, for consistency with cp.c and ln.c. All callers changed.
+ (movefile): dest_is_dir parameter is now bool, not int.
+ (main): Standardize on "missing destination file operand after %s"
+ for the diagnostic, for consistency with cp.c.
+
+ * tests/mv/diag: Don't assume "mv --target=nonexistentdir"
+ will complain about the arg count.
+ Adjust to new (briefer) diagnostics.
+ * tests/cp/fail-perm: Add a test to verify that we get the new
+ diagnostic when failing to copy through a symlink-to-inaccessible-dir.
+
+2004-06-27 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix a bug: formerly, if d/x was a directory and x a file, "ln x
+ d/" incorrectly created a link d/x/x. It also saves some system
+ calls.
+
+ * NEWS: Document the fix.
+
+ * src/ln.c (main): Don't append basename to dest if this
+ results in an existing directory name.
+ * tests/ln/misc: See whether a trailing slash is followed too far.
+
+2004-06-26 Jim Meyering <jim@meyering.net>
+
+ * src/printf.c (main): When given no arguments, print the standard
+ "missing operand\nTry printf --help..." message -- to be consistent.
+
+2004-06-26 Jim Meyering <jim@meyering.net>
+
+ * src/mknod.c (main): Add \n at the end of message output via fprintf.
+
+2004-06-25 Jim Meyering <jim@meyering.net>
+
+ * tests/ln/misc: Add test for ln subscript error.
+
+2004-06-23 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/ln.c (do_link): Remove unnecessary call to lstat.
+ (main): Avoid subscript error when the destination is "".
+
+2004-06-23 Jim Meyering <jim@meyering.net>
+
+ * tests/*: Replace all occurrences of `(exit N); exit' with
+ `(exit N); exit N'. Otherwise, those many tests could exit with
+ improper exit status when exiting via e.g., a trapped interrupt.
+ Thanks to a report from Bob Proulx.
+
+2004-06-22 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/who.c (idle_string, print_user): New arg boottime,
+ specifying the most recent boot time. All uses changed.
+ (idle_string) Consider a line to be "old" if it hasn't been used
+ since the last boot time. Watch out for overflow when computing
+ times, and for times in the future.
+ (idle_string): Record latest boot time.
+
+2004-06-22 Jim Meyering <jim@meyering.net>
+
+ * src/test.c (usage): Correct description of `-t FD'. The file
+ descriptor, FD, is no longer optional. Reported by Ton Nijkes.
+
+2004-06-21 Paul Eggert <eggert@cs.ucla.edu>
+
+ The 2004-06-19 fix for who and pinky was incomplete, as ctime
+ has undefined behavior if the year precedes -999 or follows 9999.
+ Since we have to stop using ctime anyway, we might as well use
+ strftime and fix the FIXME, and support internationalized dates.
+
+ * NEWS: Document the new behavior.
+ * src/who.c: Include "hard-locale.h".
+ (time_format, time_format_width): New vars.
+ (time_string, print_line): Use them.
+ (main): Set them.
+ (time_string): Use localtime + strftime instead of
+ ctime, to avoid problems with years before -999 or after 9999.
+ * src/pinky.c: Likewise.
+
+2004-06-21 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix bug: GNU 'ls' didn't count columns correctly if user or group
+ names contained multibyte characters where the column count
+ differed from the byte count. This patch also corrects
+ some comments.
+
+ * src/ls.c (format_user_or_group): New function, which counts
+ columns correctly.
+ (format_user, format_group): Use it.
+ (format_user_or_group_width): New function, which counts columns
+ correctly.
+ (format_user_width, format_group_width): Use it.
+
+2004-06-21 Jim Meyering <jim@meyering.net>
+
+ * tests/priv-check: Quote "$PATH" in PATH=$PATH.
+ Suggestion from Andreas Schwab.
+
+ * tests/priv-check: When running as root, be sure to propagate
+ PATH through to the process we exec as non-root.
+ Reported by michael@aplatform.com.
+
+ * src/mknod.c (main): Don't segfault when calculating the
+ expected number of operands for `mknod NAME'.
+
+2004-06-20 Jim Meyering <jim@meyering.net>
+
+ * src/dd.c (input_seek_errno): Declare file-scoped variable as static.
+
+2004-06-20 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/basename.c (main):
+ Standardize on the diagnostics given when someone gives
+ too few operands ("missing operand after `xxx'") or
+ too many operands ("extra operand `xxx'").
+ Include "quote.h" and/or "error.h" if it wasn't already being included.
+ * src/chgrp.c (main): Likewise.
+ * src/chmod.c (main): Likewise.
+ * src/chown.c (main): Likewise.
+ * src/chroot.c (main): Likewise.
+ * src/comm.c (main): Likewise.
+ * src/cp.c (do_copy): Likewise.
+ * src/csplit.c (main): Likewise.
+ * src/date.c (main): Likewise.
+ * src/dircolors.c (main): Likewise.
+ * src/dirname.c (main): Likewise.
+ * src/du.c (main): Likewise.
+ * src/expr.c (main): Likewise.
+ * src/hostid.c (main): Likewise.
+ * src/hostname.c (main): Likewise.
+ * src/id.c (main): Likewise.
+ * src/install.c (main): Likewise.
+ * src/join.c (add_file_name, main): Likewise.
+ * src/link.c (main): Likewise.
+ * src/ln.c (main): Likewise.
+ * src/logname.c (main): Likewise.
+ * src/md5sum.c (main): Likewise.
+ * src/mkdir.c (main): Likewise.
+ * src/mkfifo.c (main): Likewise.
+ * src/mknod.c (main): Likewise.
+ * src/mv.c (main): Likewise.
+ * src/nohup.c (main): Likewise.
+ * src/od.c (main): Likewise.
+ * src/pathchk.c (main): Likewise.
+ * src/ptx.c (main): Likewise.
+ * src/readlink.c (main): Likewise.
+ * src/rm.c (main): Likewise.
+ * src/rmdir.c (main): Likewise.
+ * src/seq.c (main): Likewise.
+ * src/setuidgid.c (main): Likewise.
+ * src/shred.c (main): Likewise.
+ * src/sleep.c (main): Likewise.
+ * src/sort.c (main): Likewise.
+ * src/split.c (main): Likewise.
+ * src/stat.c (main): Likewise.
+ * src/test.c (beyond, main): Likewise.
+ * src/touch.c (main): Likewise.
+ * src/tr.c (main): Likewise.
+ * src/tsort.c (main): Likewise.
+ * src/tty.c (main): Likewise.
+ * src/uname.c (main): Likewise.
+ * src/uniq.c (main): Likewise.
+ * src/unlink.c (main): Likewise.
+ * src/uptime.c (main): Likewise.
+ * src/users.c (main): Likewise.
+ * src/who.c (main): Likewise.
+ * src/whoami.c (main): Likewise.
+
+ * tests/basename/basic: Adjust to new diagnostics.
+ * tests/du/files0-from: Likewise.
+ * tests/expr/basic: Likewise.
+ * tests/mv/diag: Likewise.
+ * tests/tsort/basic-1: Likewise.
+
+2004-06-20 Jim Meyering <jim@meyering.net>
+
+ * src/ln.c: Remove declaration of yesno.
+ Instead, include yesno.h.
+ * src/copy.c: Likewise.
+
+ * src/remove.c: Remove declaration of yesno.
+ Instead, include yesno.h.
+ (top_dir): Remove now-unnecessary cast of obstack_base.
+ (pop_dir): Likewise.
+ (full_filename_): Likewise.
+
+2004-06-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don't dump core if ctime returns NULL; this is possible on
+ hosts with 64-bit time_t and 32-bit int.
+ * src/who.c: Include "inttostr.h".
+ (time_string): If ctime fails, print the raw time as an integer
+ instead of dumping core.
+ * src/pinky.c: Likewise, as follows:
+ Include "inttostr.h".
+ (time_string): New function, copied from who.c.
+ (print_entry): Use it.
+
+2004-06-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/who.c (print_line): Don't truncate user names at 8 bytes.
+ Problem reported by Guido Leenders in:
+ http://lists.gnu.org/archive/html/bug-coreutils/2004-06/msg00056.html
+ * NEWS: document this.
+
+2004-06-19 Jim Meyering <jim@meyering.net>
+
+ * src/system.h (case_GETOPT_VERSION_CHAR): Switch back to
+ using GNU_PACKAGE (from PACKAGE) once again. This restores
+ `GNU' to the parenthesized package name in --version output.
+ Before, the first argument from AC_INIT, `GNU coreutils', would
+ be propagated to the PACKAGE variable. Now, `GNU ' is trimmed.
+ Reported by Richard Stallman.
+
+2004-06-17 Jim Meyering <jim@meyering.net>
+
+ * src/tr.c (to_uchar): Rename function from `uchar'. The latter
+ would clash with a typedef in Tru64's <sys/types.h>. From Albert Chin.
+
+2004-06-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ * NEWS: Remove more special cases for POSIXLY_CORRECT when POSIX
+ allows the GNU behavior. "--" is now supported by chroot, hostid,
+ hosname, pwd, sync, yes.
+ * doc/coreutils.texi (yes invocation, false invocation,
+ true invocation): Document this.
+ * src/chroot.c (main): Handle "--".
+ * src/hostid.c (main): Likewise.
+ * src/hostname.c (main): Likewise.
+ * src/pwd.c (main): Likewise.
+ * src/sync.c (main): Likewise.
+ * src/yes.c (main): Likewise.
+ * src/true.c (main): Recognize --help and --version even if
+ POSIXLY_CORRECT is set.
+ * src/yes.c (main): Likewise.
+
+2004-06-09 Paul Eggert <eggert@cs.ucla.edu>
+
+ * NEWS: Remove special cases for POSIXLY_CORRECT when POSIX allows
+ the GNU behavior.
+ * doc/coreutils.texi (pr invocation, unlink invocation): Document this.
+ * src/ls.c (decode_switches): Pay attention to TABSIZE even if
+ POSIXLY_CORRECT is set. POSIX reserves upper-case environment
+ variables to the implementation, so it's OK for ls to depend on
+ TABSIZE.
+ * src/pr.c: Include "hard-locale.h".
+ (main): When in a non-POSIX locale, ignore POSIXLY_CORRECT, since
+ POSIX specifies the behavior only in the POSIX locale.
+ * src/printf.c (print_esc): Support \x, \u, \U even if POSIXLY_CORRECT,
+ since POSIX says the behavior is unspecified here.
+ * src/tail.c (parse_obsolescent_option): Support multiple file operands
+ even if POSIXLY_CORRECT, since POSIX does not require a diagnostic.
+ * src/printf.c (main): Recognize --help, --version even if
+ POSIXLY_CORRECT. POSIX does not specify any options, but it
+ does not prohibit options either, so "printf" is like "expr" here.
+ * src/unlink.c (main): Likewise.
+ * tests/misc/printf: Adjust to the new semantics for \x if
+ POSIXLY_CORRECT.
+
+2004-06-14 Jim Meyering <jim@meyering.net>
+
+ * tests/misc/pwd: New test, for fix of 2004-04-19.
+ * tests/misc/Makefile.am (TESTS): Add pwd.
+ (BUILD_SRC_DIR): Define BUILD_SRC_DIR.
+
+ * src/copy.c: Remove declaration of euidaccess.
+ Instead, include "euidaccess.h".
+
+2004-06-13 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/who.c (PIDSTR_DECL_AND_INIT): Don't assume pid_t fits in int.
+ (UT_ID) [!HAVE_STRUCT_XTMP_UT_ID]: Remove bogus comment,
+ as (sizeof "??") reliably returns 3.
+ (print_line): Guard against idle and pid being too long
+ (which is possible when printing headers).
+ (print_user): Allocate enough bytes for idlestr. Use IDLESTR_LEN.
+ Avoid unnecessary cast of sizeof to int.
+ (make_id_equals_comment): Do not assume that UT_ID returns
+ a string; it might return a non-null-terminated array.
+ Use strncat instead. It's not very often where strncat is
+ exactly what you want, but this is one of those rare cases.
+
+2004-06-11 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/who.c (list_entries_who): Don't output a trailing space.
+
+2004-06-09 Jim Meyering <jim@meyering.net>
+
+ * src/touch.c (usage): Improve wording in description of the
+ --time=WORD option. Reported by Dan Jacobson.
+
+ * src/chown-core.c (change_file_owner): Change names of parameters
+ old_uid and old_gid to required_uid and required_gid respectively.
+
+ * src/chmod.c (mode_changed): Return false, not 0, now that the
+ function returns `bool'.
+
+2004-06-08 Paul Eggert <eggert@cs.ucla.edu>
+
+ Adjust chmod and chown to be similar if -c or -v are given. In
+ particular, a no-op chown is no longer reported as a change; this
+ reverts to previous behavior. Also, fix both commands so that -v
+ report failures even if the failure is not due to the chmod or
+ chown syscalls.
+
+ * src/chmod.c (CH_NOT_APPLIED): New constant.
+ (describe_change): Handle it.
+ (process_file): Use it, if a symlink wasn't changed.
+ (mode_changed): Return bool, not int. Accept new argument
+ NEW_MODE; all callers changed. This lets us avoid statting the
+ file unless the new mode has unusual bits.
+ (process_file): Return -1 on error. With -v, report all errors
+ verbosely, not just some.
+
+ * src/chown-core.c (change_file_owner): Return -1 on error, not
+ 1 sometimes and -1 on others. Our caller ORs together our results,
+ and (-1 | 1) == 0 on ones-complement hosts.
+ With -v report all errors verbosely, not just some.
+ Fix bug when chopt->root_dev_ino && !chopt->affect_symlink_referent:
+ file_stats wasn't set properly in that case.
+
+ * tests/chgrp/basic: Adjust to above changes.
+
+2004-05-20 Paul Eggert <eggert@cs.ucla.edu>
+
+ * tests/chgrp/basic: Test that chgrp -h does not fail on
+ symlinks, even on hosts where that's not supported.
+ Test that if -R is specified without -H or L, -h is assumed.
+ Test that chown() is not optimized away.
+
+2004-05-18 Paul Eggert <eggert@cs.ucla.edu>
+
+ Several fixes to chgrp and chown for compatibility with POSIX and BSD:
+
+ Check for incompatible options. When -R and --dereference are
+ both used, then either -H or -L must also be used. When -R and -h
+ are both used, then -P must be in effect.
+
+ -H, -L, and -P have no effect unless -R is also specified.
+ If -P and -R are both specified, -h is assumed.
+
+ Do not optimize away the chown() system call when the file's owner
+ and group already have the desired value. This optimization was
+ incorrect, as it failed to updated the last-changed time and reset
+ special permission bits, as POSIX requires.
+
+ Do not report an error if the owner or group of a
+ recursively-encountered symbolic link cannot be updated because
+ the file system does not support it.
+
+ * NEWS: Document the above.
+
+ * src/chgrp.c (main): Check for incompatible options. -R --dereference
+ requires either -H or -L, and -R -h requires -P. If -H, specify
+ FTS_PHYSICAL as well as FTS_COMFOLLOW; this is faster. Make this
+ file as much like chown.c as possible.
+ * src/chown.c (main): Likewise.
+
+ * src/chown-core.c (change_file_owner): Use ent->fts_statp only if
+ needed. Chown a directory only after chowning its children; this
+ avoids problems if the new directory ownership doesn't permit
+ access to the children. Dereference symlinks before doing
+ ROOT_DEV_INO_CHECK, not after, so that we catch symlinks to /.
+ Do not optimize away the chown() system call when the file's owner
+ and group already have the desired value. POSIX does not permit
+ this optimization. Rely on chown and lchown to do the right
+ thing with symlinks and/or -1 arguments, now that we have wrappers
+ to do this. Use ENOTSUPP not ENOSYS, and ignore all ENOTSUPP
+ errors, not just command-line errors.
+ (chown_files): Pass FTS_NOSTAT to xfts_open if we don't need file status.
+
+ * src/system.h (ENOTSUP): Remove.
+
+ * tests/chgrp/basic: Use chown --from to discover whether the
+ group changed, since chgrp now changes unconditionally. This
+ complicates the sed script a bit. Do not specify --dereference,
+ since it's the default (and we want to test this). Adjust output
+ to match the fact that chgrp no longer optimizes the case of
+ changing a file's group to the same value as before.
+ * tests/chgrp/posix-H: Do not attempt to combine -h and -H; these
+ options are incompatible, and their behavior is undefined with POSIX.
+ (changed, not_changed): Adjust to match the fact that -h is no longer
+ specified. Sort names.
+ * tests/chown/deref: Adjust error-diagnostic spelling to match new
+ behavior.
+
+2004-06-07 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/uname.c (main): Fix typo introduced on 2003-05-10 that
+ prevented a diagnostic of any operands.
+
+2004-06-08 Jim Meyering <jim@meyering.net>
+
+ * src/shred.c (direct_mode): Turn it on/off with directio, too.
+
+2004-06-07 Jim Meyering <jim@meyering.net>
+
+ Enable direct-mode I/O (bypassing the buffer cache), if possible.
+ Prompted by a suggestion from Kalle Olavi Niemitalo
+ in http://bugs.debian.org/207035.
+ * src/shred.c (direct_mode): New function.
+ (do_wipefd): Turn on direct-mode I/O.
+ (dopass): If a file's first write fails with EINVAL,
+ turn off direct-mode I/O and retry the write.
+
+2004-06-05 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/tr.c (main): "tr -d a b" is now a fatal error even if
+ POSIXLY_CORRECT is set. The POSIX SYNOPSIS does not allow this
+ option combination.
+
+2004-06-04 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/shred.c (dopass): Don't subtract 1 from the offset after
+ a write error. Problem reported by Jon Peatfield in:
+ http://lists.gnu.org/archive/html/bug-coreutils/2004-06/msg00020.html
+
+2004-06-02 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix bug reported by Buciuman Adrian in
+ <http://mail.gnu.org/archive/html/bug-coreutils/2003-08/msg00105.html>
+ where 'dd' created a file that was too large. The bug was that dd
+ assumed that the input file offset does not advance after a failed
+ read; but POSIX says that the input file offset is undefined after
+ a failed read.
+
+ * src/dd.c (MAX_BLOCKSIZE): New macro.
+ (input_seekable, input_seek_errno, input_offset,
+ input_offset_overflow): New vars.
+ (scanargs): Reject block sizes greater than MAX_BLOCKSIZE.
+ (advance_input_offset): New function.
+ (skip_via_lseek): Set errno to zero when reporting our failure,
+ so that we don't report based on garbage errno.
+ (skip): If fdesc is standard input, advance the input offset.
+ Do not quit if reading, and if noerror was specified;
+ POSIX seems to require this.
+ If read fails on output file, report the earlier lseek failure
+ instead; this fixes a FIXME in dd_copy.
+ (advance_input_after_read_error): New function.
+ (dd_copy): Use it, instead of assuming that failed reads
+ do not advance the file pointer. Advance input offset
+ after nonfailed reads. Advance only a partial block if
+ the previous read (before the failed read) succeeded, and
+ do not generate an output block of zeros in this case.
+ (main): Determine initial input offset, seekability of input,
+ and error if it wasn't seekable.
+
+2004-06-02 Jim Meyering <jim@meyering.net>
+
+ rm (without -f) could hang unnecessarily when attempting to
+ remove a symlink to a file on an off-line NFS-mounted partition.
+ Reported by David Howells in https://bugzilla.redhat.com/124699.
+ * src/remove.c (write_protected_non_symlink): New function.
+ Don't invoke euidaccess on symlinks.
+ (prompt): Use write_protected_non_symlink rather than using
+ euidaccess directly, being careful not to call lstat twice for a file.
+
+ Fix a bug in how the --output-delimiter=D option works with
+ abutting byte or character ranges. Reported by David Krider in
+ http://lists.gnu.org/archive/html/bug-coreutils/2004-05/msg00132.html
+ * src/cut.c (print_kth): Remove special case for open-ended range.
+ (set_fields): Record the range start index for an interval even
+ when it abuts another interval on its low side.
+ Also record the range start index of the longest right-open-interval.
+ * tests/cut/Test.pm: Add tests of --output-delimiter=S with
+ abutting and overlapping byte ranges.
+
+2004-06-01 Paul Eggert <eggert@cs.ucla.edu>
+
+ Some POSIX-conformance cleanups for tr.
+
+ * src/tr.c (posix_pedantic): Remove; no longer needed since
+ we need to test this in just one place now.
+ (usage): Mention -C.
+ (unquote): Note that \055, \n, etc are escaped.
+ Do not worry about POSIXLY_CORRECT when warning about ambiguous
+ escape sequences.
+ \ at end of string stands for itself.
+ Do not diagnose invalid backslash escapes: POSIX says the behavior
+ is unspecified in this case, so we don't need to diagnose it.
+ (main): Add support for -C (currently an alias for -c).
+ Do not diagnose 'tr [:upper:] [:upper:], as POSIX does not require
+ a diagnostic here.
+ * tests/tr/Test.pm: New tests bs-055, bs-at-end, repeat-Compl.
+ Fix comment for range-a-a.
+
+2004-05-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ Improve the efficiency (and in one case, correctness) of code
+ that reads symlinks.
+
+ * src/copy.c (copy_internal): Don't use alloca, as it can mess up
+ royally if the link length is long (e.g., GNU/Hurd). Use
+ xreadlink instead, it's safer. Don't bother to read the link if
+ it's the wrong size. Add a FIXME because this area is a bit murky
+ and undocumented.
+ * src/ls.c (get_link_name): Update use of xreadlink.
+ * src/readlink.c (main): Likewise.
+ * src/stat.c (print_stat): Likewise.
+
+2004-06-01 Jim Meyering <jim@meyering.net>
+
+ * src/env.c (main): Prefer the notation `STREQ (a, b)'
+ over `!strcmp (a, b)'.
+ * src/sort.c (main, sort_buffer_size): Prefer the notation
+ `STREQ (a, b)' over `strcmp (a, b) == 0'.
+ * src/date.c (batch_convert): Likewise.
+ * src/expr.c (nextarg): Likewise.
+ * src/su.c (correct_password, restricted_shell, main): Likewise.
+ * src/ptx.c (swallow_file_in_memory, main): Likewise.
+ * src/test.c (binary_operator, and, or, main): Likewise.
+
+2004-05-13 Paul Eggert <eggert@cs.ucla.edu>
+
+ * NEWS: echo compatibility cleanup.
+ * doc/coreutils.texi (echo invocation): Document the changes.
+ * src/echo.c (V9_ECHO): Remove; always enabled.
+ (DEFAULT_ECHO_TO_XPG): Renamed from V9_DEFAULT, so that
+ we use the same naming convention as bash. Now an enum,
+ not a macro.
+ (usage): Reword to mention -e/-E more accurately.
+ Mention \0NNN (the POSIX syntax) rather than \NNN (nonstandard).
+ (hextobin): New function.
+ (main): Use bool rather than int for local vars when appropriate.
+ Do not allow options if POSIXLY_CORRECT, unless we are using
+ BSD semantics and the first argument is "-n".
+ Don't pass unnecessary extra arg to parse_long_options.
+ do_v9 now defaults to DEFAULT_ECHO_TO_XPG, not to allow_options.
+ Do not look for options if !allow_options.
+ Use size_t rather than int when appropriate.
+ Open-code option test rather than using strrchr.
+ Use faster test for "-".
+ Avoid redundant argc test.
+ Add support for \x, for Bash compatibility.
+ Use e.g. '\a' rather than '\007', for portability to EBCDIC hosts.
+ When '\c' is encountered, stop printing immediately, as POSIX
+ requires.
+ Add support for \xhh syntax.
+ Add support for \0ooo syntax; POSIX requires this.
+
+2004-06-01 Jim Meyering <jim@meyering.net>
+
+ * Use automake-1.8b. Regenerate dependent files.
+
+2004-05-31 Jim Meyering <jim@meyering.net>
+
+ * tests/Makefile.am.in (TESTS_ENVIRONMENT): Define PATH to include
+ the build src/ directory -- at the front.
+ ($(srcdir)/$x-tests): Depend on Makefile.am.
+ Use $x as the program name, except when it would be `test' (test is
+ the sole program tested via mk-script that is also a shell built-in).
+ In that case, use the old ../../src/$x.
+
+2004-05-30 Jim Meyering <jim@meyering.net>
+
+ Work around HPUX /bin/cc compiler bug that is exposed, now that
+ sets are arrays of type `bool'. More details here:
+ http://lists.gnu.org/archive/html/bug-gnulib/2004-05/msg00094.html
+ FIXME: verify that the above URL points to the right message
+
+ * src/tr.c (card_of_complement): Use cleaner `sizeof in_set'
+ rather than `N_CHARS * sizeof(in_set[0])'. Using HPUX's /bin/cc
+ (aC++/ANSI C B3910B A.05.55 [Dec 04 2003]) on an ia64-hp-hpux11.22
+ system, those two expressions are not the same (256 vs. 1024).
+ The effect of this problem was that `tr -c x y' would fail:
+ tr: when not truncating set1, string2 must be non-empty
+ (set_initialize): Remove unnecessary initialization of the `in_set'
+ buffer; that initialization triggered the same compiler bug as above.
+
+2004-05-29 Paul Eggert <eggert@cs.ucla.edu>
+
+ tr cleanup, mostly having to do with integer type ranges.
+ Remove all casts.
+
+ * tests/tr/Test.pm: Add a few tests for the below. Alas, most of
+ the test cases wouldn't be portable, or would take too much CPU
+ time, or both.
+
+ * src/tr.c (N_CHARS, N_CHAR_CLASSES): Now an enum, not a macro.
+ This is safe since the code already assumes N_CHARS fits in int.
+ (Filter): Remove: we want to prototype everything.
+ (ORD, CHR): Remove. All uses removed. Some replaced with:
+ (uchar): New function. All places where a char must be converted
+ to an unsigned char are now done this way, not by ad-hoc methods.
+ (count): New type. Use it whenever counts or states are needed.
+ (BEGIN_STATE): Increase from INT_MAX - 1 (which was bogus, anyway,
+ since we used it in an unsigned int context) to UINTMAX_MAX - 1.
+ (REPEAT_COUNT_MAXIMUM): New macro. Use it in place of BEGIN_STATE
+ whenever appropriate.
+ (NOT_A_CHAR): Remove global macro; now a local enum.
+ (UL_LOWER, UL_UPPER, UL_NONE): No longer specify values, since
+ the rest of the code no longer depends on them.
+ (class_ok): Remove; all uses changed to use inline comparisons.
+ (RE_NO_TYPE): Remove; wasn't used or needed.
+ (struct List_element): normal_char and equiv_code are now unsigned
+ char, not int.
+ first_char, last_char, and the_repeated_char are now unsigned char,
+ not unsigned int. repeat_count is now count, not size_t.
+ All uses changed.
+ (struct Spec_list): state is now count, not unsigned int.
+ lengthis now count, not size_t.
+ n_indefinite_repeats is now size_t, not int.
+ has_equiv_class, has_char_class, and has_restricted_char_class
+ are now bool, not int. All uses changed.
+ (struct E_string): s is now char *, not unsigned char *.
+ escaped is now bool *, not int *. All uses changed.
+ (ES_MATCH): Remove macro, replacing with:
+ (es_match): New inline function. All uses changed.
+ (squeeze_repeats, complement, posix_pedantic, truncate_set1,
+ translating): Now bool, not int.
+ (io_buf): Now char array, not unsigned char.
+ (SET_TYPE): Remove. All uses replaced with bool.
+ (is_equiv_class_member, unquote, append_range, append_char_class,
+ append_equiv_class, find_closing_delim, star_digits_closebracket,
+ build_spec_list, parse_str, homogeneous_spec_list):
+ Now returns bool, not int. All uses changed.
+ (is_equiv_class_member): Now inline.
+ (is_equiv_class_member, is_char_class_member, make_printable_str,
+ append_normal_char, append_range, append_repeated_char,
+ get_s2_spec_stats):
+ Args are now of proper integer type.
+ (unquote, look_up_char_class, make_printable_str,
+ append_equiv_class, build_spec_list, squeeze_filter):
+ Avoid unsigned char *p; gently convert *p to unsigned char instead.
+ (unquote, get_spec_stats): Do not jump past declarations and then
+ use them; C doesn't allow this in portable programs.
+ (make_printable_str): Check for overflow in size calculations.
+ (xmemdup): Remove. All uses rewritten.
+ (find_bracketed_repeat): Args are now of proper pointer-to-integer
+ type. Do not reject [c*0]. Use xstrtoumax, not xstrtoul.
+ (find_bracketed_repeat, star_digits_closebracket): Check that the
+ digits are not escaped.
+ (build_spec_list): Don't bother to copy opnd_str; not needed.
+ (build_spec_list, get_next): Simplify internal logic a bit.
+ (card_of_complement): Fix bug due to char overflow.
+ (get_spec_stats): Don't assume len fits into int.
+ Check for integer overflow. Use abort() rather than assert(0).
+ (string2_extend): Fix subscript error: is_char_class_member (..., 255)
+ was being invoked.
+ (squeeze_filter): READER is never null now; simplify code.
+ READER arg now has a simpler type. Remove unnecessary casts.
+ (squeeze_filter, main): Calls to fwrite improperly checked result
+ against zero, rather than against requested size.
+ (plain_read): New function.
+ (read_and_delete, read_and_xlate):
+ Remove unused filter arg, and don't worry about hit_eof.
+ Simplify by using plain_read.
+ (set_initialize): Args are bool and bool *, not int and SET_TYPE *.
+ (main): Always pass a non-null procedure to squeeze_filter.
+ Rewrite so that class_ok isn't needed.
+
+2004-05-29 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/shred.c (dosync): Ignore EBADF errors, as IRIX 6.5
+ fdatasync reports EBADF when syncing (unwritable) directories.
+ Problem reported by Albert Chin-A-Young in:
+ http://lists.gnu.org/archive/html/bug-coreutils/2004-05/msg00165.html
+
+2004-05-29 Jim Meyering <jim@meyering.net>
+
+ * tests/chown/deref: Fix typo: use ls -ldo, not ls -ldg.
+ Patch from Albert Chin.
+
+ * src/ptx.c (text_buffer_maxend): Remove declaration of unused variable.
+
+ * src/remove.c (push_dir): Merge declaration and adjacent assignment
+ into a single statement.
+
+2004-05-28 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (AD_mark_helper): Eliminate an unnecessary comparison.
+
+2004-05-22 Jim Meyering <jim@meyering.net>
+
+ rm -r would get a failed assertion when run from an inaccessible
+ directory and with two or more command line arguments including an
+ absolute-named directory followed by a relative-named directory.
+
+ * src/remove.h (struct rm_options) [require_restore_cwd]: New member.
+ * src/remove.c (struct cwd_state): Define.
+ (AD_pop_and_chdir): Redesign interface so that a restore_cwd failure
+ can be detected by the caller. Instead of returning a malloc'd
+ directory name, communicate it to caller via a new parameter, and
+ return an indication of whether restore_cwd failed. Update caller.
+ Eliminate an unnecessary call to AC_stack_top.
+ (remove_dir): Change type of cwd_state parameter to `struct cwd_state'
+ so we can now communicate to caller whether/how functions like
+ restore_cwd have failed. Update caller.
+ (rm_1): Fail if we've failed to restore the working directory
+ and the name of the next file to remove is `.'-relative.
+ (rm): Fail if the require_restore_cwd flag is true and we've
+ failed to restore the working directory.
+ * src/mv.c (rm_option_init): Initialize new member,
+ x->require_restore_cwd.
+ * src/rm.c (rm_option_init): Likewise.
+
+2004-05-21 Jim Meyering <jim@meyering.net>
+
+ * tests/rm/inaccessible: New test for the above fix.
+ * tests/rm/Makefile.am (TESTS): Add inaccessible.
+
+ * src/remove.c (rm): Use free rather than XFREE.
+ (remove_dir): Use xmalloc, not XMALLOC.
+ (ds_init): Likewise.
+
+2004-05-20 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (sc_unmarked_diagnostics): Now that the unmarked
+ diagnostics in shred.c have been fixed, don't exempt shred.c from
+ this check.
+
+ * src/shred.c: Use translatable diagnostics, e.g.
+ change "%s: remove" to _("%s: failed to remove") and
+ change "%s: close" to _("%s: failed to close").
+
+2004-05-17 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/shred.c (names): Bring back lower-case letters, "_", and
+ ".". But continue to omit +, =, %, @, #, as they're either
+ shell metacharacters (for some shells) or are not in some
+ character sets, or (in the case of '%') must be a
+ metacharacter somewhere.
+
+2004-05-16 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/cut.c (cut_fields): Adjust to new signature of getndelim2.
+
+2004-05-17 Jim Meyering <jim@meyering.net>
+
+ * src/shred.c (incname): Decrement `len' only once per loop iteration.
+
+ chgrp and chown now dereference symlinks by default, per POSIX.
+ Reported by Michal Politowski as http://bugs.debian.org/249177.
+
+ * src/chown-core.c (chopt_init): Affect each symlink referent by default.
+ * src/chown.c (usage): Update to reflect this.
+ * src/chgrp.c (usage): Likewise.
+ * NEWS: Describe the change.
+ Adapt tests accordingly.
+ * tests/chgrp/basic: Use -h where necessary to retain semantics.
+ * tests/chgrp/deref: Likewise.
+ * tests/chgrp/posix-H: Likewise.
+
+2004-05-15 Paul Eggert <eggert@cs.ucla.edu>
+
+ In shred, check for errors from fdatasync more carefully. If
+ fdatasync fails with errno==EINVAL, it means this implementation
+ does not support synchronized I/O for this file. Do not report
+ this as an error, as (for example) AIX 5.2 fdatasync reports it
+ for raw disk devices. Problem reported by Albert Chin in
+ <http://mail.gnu.org/archive/html/bug-gnu-utils/2004-05/msg00028.html>.
+
+ Check for write errors, though: the old code ignored them.
+ Improve error checking in a few other cases, too (e.g., close of a
+ directory).
+
+ Also, change several 'int' values to 'bool', so that the error
+ checking is a bit clearer. Similarly, change unsigned values
+ to size_t where appropriate.
+
+ * src/shred.c: Include "dirname.h".
+ (datasync) [!HAVE_FDATASYNC]: Remove.
+ (dosync): New function.
+ (dopass): Use it. Return 1 on write error, -1 on other error.
+ All callers changed. Report write error if dosync does.
+ (do_wipefd, wipefd, wipename, wipefile): Return bool (true/false),
+ not int (0/-1). All callers changed. Return false if there's a
+ write error.
+ (incname): Return bool (true/false), not int (0/1). Accept
+ size_t length, not unsigned. All callers changed. Do not
+ bother checking for non-digits; it can't happen. Replace
+ recursion with iteration.
+ (wipename): Use dir_name, base_name, etc. instead of assuming
+ Unix file names. Use size_t for length, not unsigned.
+ Report error if unlink or close fails.
+ (wipename, main): Use bool for booleans.
+
+ (names): Use only digits and uppercase letters, for greater
+ portability.
+
+2004-05-16 Jim Meyering <jim@meyering.net>
+
+ * tests/chown/deref: New test for the yesterday's change.
+ * tests/chown/Makefile.am (TESTS): Add deref.
+
+2004-05-15 Jim Meyering <jim@meyering.net>
+
+ chown --dereference did nothing when the owner/group of a
+ symlink matched the desired owner/group. Reported by David Malone.
+ Also reported in 1999 as http://bugs.debian.org/39642.
+
+ * src/chown-core.c (change_file_owner): When --dereference has
+ been specified, and when processing a symlink, stat it to get the
+ owner and group of the referent.
+
+2004-05-14 Jim Meyering <jim@meyering.net>
+
+ * man/pwd.x, man/echo.x, man/printf.x: Fix typo:
+ s/supercede/supersede/ reported by Andrew Fabbro.
+
+2004-05-13 Paul Eggert <eggert@cs.ucla.edu>
+
+ Improve performance of `sort -m' on large files, at the cost of
+ making some contrived examples unsafe. POSIX allows this
+ optimization. Performance problem reported by Jonathan Baker in
+ <http://mail.gnu.org/archive/html/bug-coreutils/2004-05/msg00071.html>.
+
+ * src/sort.c (first_same_file): Do not treat input pipes
+ differently from other files.
+ * doc/coreutils.texi (sort invocation): Document that "sort -m -o F"
+ might write F before reading all the input.
+ * NEWS: Likewise.
+
+2004-05-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/od.c (print_ascii, dump_strings): Use e.g. '\a' rather than
+ '\007', for portability to EBCDIC hosts.
+ * src/printf.c (print_esc_char): Likewise.
+ * src/tr.c (unquote, make_printable_str): Likewise.
+
+2004-05-12 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (AD_pop_and_chdir): Move lstat-`.' into if-block
+ where the result is used. This avoids one unnecessary lstat call
+ per command line argument.
+
+2004-05-12 Paul Eggert <eggert@cs.ucla.edu>
+
+ Don't assume that "make -C" works; Solaris "make" doesn't have -C.
+
+ * src/Makefile.am (all_programs.list): New rule, copied from
+ man/Makefile.am and tests/Makefile.am, except that we use the
+ system tr rather than ./tr and we don't use tr -s.
+ * tests/Makefile.am (all_programs): Use it.
+ * man/Makefile.am (all_programs): Likewise. Renamed from programs,
+ for consistency. All uses changed.
+
+2004-05-11 Jim Meyering <jim@meyering.net>
+
+ * tests/rm/unread3: New test, for the above fix and today's
+ lib/save-cwd.c improvement.
+ * tests/rm/Makefile.am (TESTS): Add unread3.
+
+ * src/rm.c: Don't include "save-cwd.h". It's no longer used.
+
+2004-05-10 Jim Meyering <jim@meyering.net>
+
+ * tests/install/trap: New file. Test for bug fix of 2004-04-18.
+ * tests/install/Makefile.am (TESTS): Add trap.
+
+ * src/remove.c (AD_push): Don't use errno in diagnostic about
+ `changed dev/ino'.
+
+ Remove these generated files from CVS.
+ * tests/cut/cut-tests, tests/date/date-tests, tests/join/join-tests:
+ * tests/ls/ls-tests, tests/pr/pr-tests, tests/tac/tac-tests:
+ * tests/tail/tail-tests, tests/test/test-tests, tests/tr/range-tests:
+ * tests/tr/tr-tests, tests/wc/wc-tests:
+
+2004-05-09 Jim Meyering <jim@meyering.net>
+
+ * src/tr.c (unquote): Use xcalloc rather than xmalloc and
+ a loop initializing the just-allocated memory to zero.
+
+2004-05-08 Jim Meyering <jim@meyering.net>
+
+ * tests/rm/no-give-up: New file; check for today's fix.
+ * tests/rm/Makefile.am (TESTS): Add no-give-up.
+
+2004-05-08 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix bug where "rm" gave up too easily, reported by Dan Jacobsen in
+ <http://mail.gnu.org/archive/html/bug-coreutils/2004-05/msg00013.html>.
+
+ * src/remove.c (remove_entry): Check for errno values like ENOENT
+ that show the file cannot be directory, instead of for errno
+ values like EPERM that show the file might be a directory. This
+ is necessary because, when a single unlink() call has multiple
+ reasons to fail, it can set errno to any of those reasons; it's
+ only the rare errno value like ENOENT that excludes all the other
+ possible reasons to fail even when the file is a directory.
+ (remove_cwd_entries): Don't attempt chdir if the file is known
+ to not be a directory.
+ (remove_dir): Use the same method that remove_cwd_entries uses
+ (for some reason they differed). Don't assert that saved_errno
+ must be EPERM; it might be just about anything.
+
+2004-05-06 Jim Meyering <jim@meyering.net>
+
+ * src/id.c (xgetgroups): Use xnmalloc, rather than xmalloc.
+ Don't add `1' to the buffer size (it was to protect against malloc
+ implementations that fail to allocate a buffer of size zero).
+ That is no longer necessary, since we use a malloc wrapper
+ on such systems.
+
+ * src/wc.c (get_input_fstatus): Use xnmalloc, rather than xmalloc.
+ * src/head.c (elide_tail_bytes_pipe): Likewise.
+ * src/df.c (main): Likewise.
+ * src/shred.c (do_wipefd): Likewise.
+ * src/users.c (list_entries_users): Likewise.
+ * src/tail.c (main): Likewise.
+ * src/md5sum.c (main): Likewise.
+
+2004-04-29 Paul Eggert <eggert@cs.ucla.edu>
+
+ * src/df.c (show_disk, show_point): If several filesystems are
+ mounted on the same mount point, prefer the last one, not the first.
+ Problem reported by Christian Jones in
+ <http://mail.gnu.org/archive/html/bug-coreutils/2004-04/msg00200.html>.
+ (show_disk): Remove unused statp arg. Return bool, not int.
+ (show_point): Rewrite to avoid gotos. Use the same algorithm
+ for lofs and dummies for each pass through the mount table,
+ rather than subtly different algorithms (which are probably
+ inadvertent).
+
+2004-05-03 Jim Meyering <jim@meyering.net>
+
+ * Makefile.am (EXTRA_DIST): Add m4/ChangeLog, now that we no longer
+ have m4/Makefile*.
+
+2004-05-01 Jim Meyering <jim@meyering.net>
+
+ When chown or chgrp is modifying the referent of a symlink,
+ use the chown(2) function, if possible.
+ * src/chown-core.c (change_file_owner): Don't hard-code the
+ open/fchown/close kludge here. Use `chown' instead.
+ The chown function works just fine on conforming systems.
+ Other systems now go through the new chown wrapper that
+ resorts to the old kludge.
+
+ * src/chown-core.c (change_file_owner): Add a comment.
+
+2004-04-27 Jim Meyering <jim@meyering.net>
+
+ * src/ptx.c: Make over 40 global extern variables `static'.
+ (syntax_table, re_syntax_table): Remove declarations of two unused
+ variables (they were exposed by the above change).
+
+ * src/du.c (G_fail, opt_nul_terminate_output): Declare `static'.
+ * src/ln.c (backup_type): Likewise.
+
+ * src/remove.c (rm): Add `extern' keyword.
+ * src/cp-hash.c (forget_created, remember_created)
+ (src_to_dest_lookup, remember_copied, hash_init, forget_all): Likewise.
+ * src/copy.c (dest_info_init, src_info_init, copy): Likewise.
+ * src/chown-core.c (chopt_init, chopt_free, gid_to_name)
+ (uid_to_name, chown_files): Likewise.
+
+ * src/Makefile.am (sc_tight_scope): New rule.
+ * Makefile.maint (sc_tight_scope): New rule.
+ (syntax-check-rules): Add it.
+
+2004-04-26 Jim Meyering <jim@meyering.net>
+
+ * Use automake-1.8.4. Regenerate dependent files.
+
+ * src/sort.c (limfield): Make a comment clearer.
+
+2004-04-25 Paul Eggert <eggert@twinsun.com>
+
+ Fix POSIX-conformance bug: "sort -k 3,3.5b" is supposed to skip
+ leading blanks when computing the location of the field end;
+ it is not supposed to skip trailing blanks. Solaris 8 "sort"
+ does conform to POSIX. Also fix the documentation to clarify
+ this and related issues.
+
+ * doc/coreutils.texi (sort invocation): Mention -k earlier, so
+ that the options are in alphabetical order. Describe how -b works
+ more-accurately; this involves fixing some examples, too. Mention
+ what happens if the start field falls after an end field or after
+ a line end. Warn about using -k without -b, -g, -M, -n, or -t.
+ Add an example of how to sort IPv4 addresses and Apache Common
+ Log Format dates. Remove a duplicate example.
+ (Putting the tools together): Use separate options rather
+ than agglomerating them.
+ * src/sort.c (limfield): Use skipeblanks, not skipsblanks, to
+ decode whether to skip leading blanks.
+ (trailing_blanks): Remove.
+ (fillbuf, getmonth, keycompare): Don't trim trailing blanks.
+
+ * tests/pr/Test.pm: Fix typo in env_default comment.
+ * tests/sort/Test.pm: Likewise.
+ (18c, 18d): Reverse the order of output lines, so that the
+ test cases conform to POSIX.
+
+2004-04-22 Paul Eggert <eggert@twinsun.com>
+
+ More signal-handling cleanup for ls.c. Do not allow signals to
+ happen between arbitrary output bytes, as the
+ restore-default-color sequence can bollix up multibyte chars or
+ color-change sequences in the ordinary output. Instead, process
+ signals only between printing a file name and changing the color
+ back to non_filename_text color. That way, if the signal handler
+ changes the color (to the default), 'ls' will change it back when
+ 'ls' continues (after being suspended).
+
+ Also, do not bother with signal-handling unless stdout is a
+ controlling terminal; this lets stdio buffer better when "ls
+ --color" is piped or sent to a file.
+
+ * src/ls.c (sigprocmask, sigset_t) [!defined SA_NOCLDSTOP]: New macros.
+ Do not include "full-write.h"; no longer needed.
+ (tcgetpgrp) [! HAVE_TCGETPGRP]: New macro.
+ (put_indicator_direct): Remove. All callers changed to use
+ put_indicator.
+ (caught_signals, interrupt_signal, stop_signal_count): New vars.
+ (restore_default_color): Don't bother checking for put_indicator
+ failure.
+ (sighandler): Don't handle SIGTSTP; that's another handler now.
+ Simply set interrupt_signal to the signal, then exit.
+ (stophandler, process_signals): New functions.
+ (main): Don't output any color changes until _after_ the signal
+ handlers are set up. This fixes a race condition where 'ls'
+ could be interrupted while initializing colors, and leaving the
+ terminal in an undesirable state.
+ Don't mess with signal-handling if standard output is not a
+ controlling terminal.
+ When exiting, restore the default color, then restore the
+ default signal handling, then act on any signals that weren't
+ acted on yet.
+ Do not print //DIRED// etc. in colors; this avoids the need
+ to catch signals when printing them.
+ (print_name_with_quoting): Process signals just before switching
+ color back to non_filename_text.
+
+2004-04-23 Jim Meyering <jim@meyering.net>
+
+ Avoid segfault on systems for which SIZE_MAX != (size_t) -1.
+ * src/ls.c (quote_name): Use SIZE_MAX, not -1, in calls
+ of quotearg_buffer. Patch by Mikulas Patocka.
+
+2004-04-18 Paul Eggert <eggert@twinsun.com>
+
+ tee ignored SIGPIPE, but POSIX doesn't allow this.
+
+ * src/tee.c (main): Do not ignore SIGPIPE, as POSIX 1003.1-2001
+ does not allow this. This undoes the 1996-10-24 patch.
+
+2004-04-18 Paul Eggert <eggert@twinsun.com>
+
+ Signal-handling cleanup for coreutils. Here are the highlights:
+
+ - csplit sometimes failed to remove files when interrupted.
+ - csplit didn't clean up if two signals arrived nearly simultaneously.
+ - install -s would infloop on System V if SIGCHLD was ignored.
+ - ls could incorrectly restore color if multiple signals
+ arrived nearly simultaneously.
+
+ * src/csplit.c (sigprocmask, sigset_t) [!defined SA_NOCLDSTOP]:
+ Define.
+ (filename_space, prefix, suffix, digits, files_created, remove_files):
+ Now volatile.
+ (caught_signals): New var.
+ (cleanup): Block signals while deleting all files.
+ (cleanup_fatal, handle_line_error, regexp_error):
+ Mark with ATTRIBUTE_NORETURN.
+ (create_output_file, close_output_file, interrupt_handler):
+ Block signals while changing the number of output files,
+ to fix some race conditions.
+ (delete_all_files): Do nothing if remove_files is zero.
+ Clear files_created.
+ (main): Don't mess with signals until after argument processing
+ is done.
+
+ * src/csplit.c (main): Rewrite signal-catching code to make it
+ similar to other coreutils programs. When processing signals,
+ block all signals that we catch, but do not block signals that we
+ don't catch. Avoid problems with unsigned int warnings.
+ * src/ls.c (main): Likewise.
+ * src/sort.c (main): Likewise.
+
+ * src/csplit.c (interrupt_handler):
+ Use void, not (obsolete) RETSIGTYPE.
+ * src/shred.c (sigill_handler, isaac_seed_machdep): Likewise.
+
+ * src/csplit.c (interrupt_handler) [defined SA_NOCLDSTOP]:
+ Use simpler "signal (sig, SIG_DFL)" rather than sigaction equivalent.
+ * src/ls.c (sighandler) [defined SA_NOCLDSTOP]: Likewise.
+ * src/sort.c (sighandler) [defined SA_NOCLDSTOP]: Likewise.
+ * src/nohup.c (main) [!defined _POSIX_SOURCE]: Likewise, except
+ for SIG_IGN.
+ * src/tee.c (main) [!defined _POSIX_SOURCE]: Likewise.
+
+ * src/install.c: Include <signal.h>.
+ (main) [defined SIGCHLD]: Set SIGCHLD handler to the default, if -s is
+ given, since System V fork+wait does not work if SIGCHLD is ignored.
+
+ * src/ls.c (sighandler) [!defined SA_NOCLDSTOP]: Reset signal
+ handler to self, not to SIG_IGN, since SIGTSTP can be received
+ more than once.
+ (main): Use SA_RESTART, as that is simpler than checking for EINTR
+ failures all over the place.
+
+2004-04-20 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (is_empty_dir): Clarify comment.
+
+ * man/help2man: Accept new option: --program-name=NAME, so that we
+ can override the one in --version output. This is needed solely
+ so that test.1 doesn't refer to `[' as the program name.
+ Reported by Benjamin Cutler as http://bugs.debian.org/205251.
+ * man/Makefile.am (.x.1): Use help2man's new --program-name option.
+
+ * src/pwd.c: Don't include pathmax.h; system.h already does it.
+
+ * src/cut.c (cut_fields): Free buffer upon getndelim2 failure.
+
+2004-04-19 Jim Meyering <jim@meyering.net>
+
+ * src/shred.c (isaac_seed_start) [AVOID_USED_UNINITIALIZED_WARNINGS]:
+ Initialize a buffer to avoid warnings from tools like valgrind.
+
+ * Makefile.maint (sc_trailing_blank): New rule.
+ (syntax-check-rules): Add it.
+ * .x-sc_trailing_blank: New file.
+
+ Make pwd work even if the resulting name is so long that getcwd fails.
+ * src/pwd.c: (path_free, path_init, path_prepend): New functions.
+ (nth_parent, find_dir_entry, robust_getcwd): New functions.
+ (main): First try getcwd, then, upon failure, robust_getcwd.
+
+2004-04-18 Jim Meyering <jim@meyering.net>
+
+ * src/who.c (print_user): Use xrealloc here, rather than
+ unchecked realloc. Remove anachronistic casts.
+
+ * src/remove.c (full_filename_): Don't leak upon failed realloc.
+
+ * src/system.h (readdir_ignoring_dot_and_dotdot): New inline function,
+ from remove.c.
+ * src/remove.c (readdir_ignoring_dotdirs): Move function to system.h,
+ renaming it. Update uses.
+
+2004-04-17 Jim Meyering <jim@meyering.net>
+
+ * configure.ac: Depend on automake-1.8.3.
+
+ * src/join.c (add_file_name): Declare function to be `static'.
+ (string_to_join_field): Likewise.
+ * src/remove.c (ds_init, ds_free): Likewise.
+
+ * Makefile.maint (sc_prohibit_jm_in_m4): New rule.
+ (syntax-check-rules): Add to the list.
+
+2004-04-13 Paul Eggert <eggert@twinsun.com>
+
+ Use page-aligned buffers whenever we bother to do I/O using buffer
+ sizes that are tailored for the files.
+
+ * src/cat.c: Include getpagesize.h.
+ * src/copy.c: Likewise.
+ * src/shred.c: Likewise.
+ * src/split.c: Likewise.
+ * src/cat.c (main): Align I/O buffers to page boundaries.
+ * src/copy.c (copy_reg): Likewise.
+ * src/shred.c (dopass): Likewise.
+ * src/split.c (main): Likewise.
+ * src/dd.c (ROUND_UP_OFFSET, PTR_ALIGN): Remove.
+ All uses replaced by ptr_align.
+ * src/od.c (gcd, lcm): Remove; now in system.h.
+ * src/system.h (gcd, lcm, ptr_align): New functions, moved from od.c.
+
+2004-04-14 Jim Meyering <jim@meyering.net>
+
+ Remove m4/Makefile.am: it's no longer needed, with newer automake
+ * configure.ac (AC_CONFIG_FILES): Remove m4/Makefile.in from the list.
+ * Makefile.am (SUBDIRS): Remove `m4' from the list.
+
+2004-04-13 Jim Meyering <jim@meyering.net>
+
+ * configure.ac: Change `jm_' in AC_DEFINE'd names to `gl_'.
+
+2004-03-27 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS: cp -pu and mv -u (when copying) now take the destination
+ file system time stamp resolution into account.
+ * doc/coreutils.texi (mv invocation): Document this.
+ (cp invocation): Document -u (it was missing!) with new behavior.
+
+ * src/copy.c: Include "utimecmp.h".
+ (copy_internal): Compare time stamps using utimecmp rather than
+ MTIME_CMP.
+
+2004-04-09 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (.re-list): New rule/file, to replace
+ hard-coded list of header file names.
+ (sc_system_h_headers): Use the new file.
+ Don't look for sys2.h anymore.
+
+ * src/system.h: Include new "stat-macros.h" rather than hard-coding
+ all of its macro definitions -- the list was slightly out of date.
+ Suggestion from Dmitry V. Levin.
+
+2004-04-08 Paul Eggert <eggert@cs.ucla.edu>
+
+ * NEWS: Remove noctty flag from dd. Suggested by Philippe Troin.
+ * doc/coreutils.texi (dd invocation): Likewise.
+ * src/shred.c (O_NOCTTY): Remove redundant decl.
+ * src/dd.c (flags, usage): Remove noctty flag.
+ (main): Always use O_NOCTTY when opening files.
+
+2004-04-08 Jim Meyering <jim@meyering.net>
+
+ * src/dd.c (dd_copy): Mark two diagnostics for translations.
+ (set_fd_flags): Undo part of today's change: it's a little
+ cleaner -- and more efficient in the common case -- to go
+ ahead and OR in the -1 when fcntl fails.
+
+ * Makefile.maint (sc_dd_max_sym_length): New target.
+ (syntax-check-rules): Add it.
+
+ * src/md5sum.c (PROGRAM_NAME) [algorithm == ALG_SHA1]:
+ Correct spelling: s/shasum/sha1sum. Reported by Jesse Kornblum.
+
+ * src/dd.c (set_fd_flags): Don't OR in -1 when fcntl fails.
+ Rename parameter, flags, to avoid shadowing global.
+ (LONGEST_SYMBOL): Tweak comment.
+
+2004-04-07 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS: New dd conv= symbols nocreat, excl, fdatasync, fsync,
+ and new dd options iflag= and oflag=.
+ * src/dd.c (usage): Likewise.
+ * src/Makefile.am (dd_LDADD, shred_LDADD): Add fdatasync's lib.
+ * src/dd.c (fdatasync) [!HAVE_FDATASYNC]: New macro.
+ (C_NOCREAT, C_EXCL, C_FDATASYNC, C_FSYNC): New macros.
+ (input_flags, output_flags): New vars.
+ (LONGEST_SYMBOL): New macro.
+ (struct symbol_value): Renamed from struct conversion. Members
+ symbol and value renamed from convname and conversion. The
+ symbol value is now an array instead of a pointer; this saves
+ a bit of space and time in practice. All uses changed.
+ (conversions): Add nocreat, excl, fdatasync, fsync. Now const.
+ (flags): New constant array.
+ (iflag_error_msgid, oflag_error_msgid): New constants.
+ (parse_symbols): Renamed from parse_conversion and generalized
+ to handle either conversion or flag symbols.
+ (scanargs): Adjust uses of parse_symbols accodingly. Add
+ support for iflag= and oflag=. Reject attempts to use
+ both excl and nocreat.
+ (set_fd_flags): New function.
+ (dd_copy): Just return X rather than calling quit (X), since our
+ caller invokes quit with the returned value. Add support for
+ fdatasync and fsync.
+ (main): Add support for iflag=, oflag=, and new conv= symbols.
+ * src/system.h (O_DIRECT, O_DSYNC, O_NDELAY, O_NOFOLLOW,
+ O_RSYNC, O_SYNC): Define to 0 if not already defined.
+
+ * NEWS: Remove duplicate mention of BLOCKSIZE.
+
+2004-04-02 Andreas Schwab <schwab@suse.de>
+
+ * src/stty.c: Add support for IUTF8 input flag.
+
+2004-04-06 Jim Meyering <jim@meyering.net>
+
+ * src/system.h (makedev) [mkdev && !makedev]: Define in terms of mkdev.
+ Interix spells it `mkdev'. Reported by Mark Funkenhauser.
+
+2004-04-04 Jim Meyering <jim@meyering.net>
+
+ A specified format is no longer automatically newline terminated.
+ If you want a newline at the end of your format, use `\n'.
+ * src/stat.c (print_it): Don't print a newline at the end of
+ every format.
+ (do_statfs): Add a newline at end of each default format string.
+
+2004-03-30 Paul Eggert <eggert@twinsun.com>
+
+ * src/nohup.c (main): Adjust to new calling convention
+ for set_cloexec_flag.
+
+2004-03-31 Jim Meyering <jim@meyering.net>
+
+ * tests/Fetish.pm (run_tests): Remove `.orig' file.
+ Remove debugging diagnostic.
+
+ Specifying an invalid --width=N (-w) or --gap-size=N (-g)
+ would not elicit an error.
+ * src/ptx.c: Include "xstrtol.h" and "quotearg.h".
+ (main): Don't use atoi. Use xstrtoul instead.
+
+2004-03-30 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (sc_prohibit_atoi_atof): New rule.
+ (syntax-check-rules): Add it.
+ * .x-sc_prohibit_atoi_atof: New file.
+
+2004-03-29 Jim Meyering <jim@meyering.net>
+
+ * tests/du/files0-from: Use new OUT_SUBST directive, so that this
+ test is not sensitive to system-dependent block size differences.
+ Prompted by a report of Solaris 8 differences from Paul Eggert.
+
+ * tests/Fetish.pm: Accept new directives: OUT_SUBST, ERR_SUBST.
+ Rename `%tmp' to `%actual'. Reverse order of last two args to
+ _compare_files (to $actual, $expected) so as to match declaration.
+
+2004-03-28 Paul Eggert <eggert@twinsun.com>
+
+ Fix some gotchas encountered when porting to Solaris 8, using
+ the Forte 6u2 compiler.
+
+ * src/hostname.c [HAVE_SETHOSTNAME && !defined sethostname]:
+ Declare sethostname, since no Solaris header does it.
+ * src/who.c: Include "vasprintf.h", for asprintf.
+
+2004-03-28 Jim Meyering <jim@meyering.net>
+
+ Minor optimization:
+ * src/du.c (process_file): Don't record dev/inode for directories.
+
+ Under some circumstances, without -c, du would mistakenly count the
+ space of hard-linked files, not just the first one it encountered.
+ Reported by Anthony Thyssen.
+ * src/du.c (du_files): Don't ever clear the set of `seen' dev/inodes.
+
+ * src/du.c: Rename global `print_totals' to `print_grand_total'.
+
+ * src/du.c (main): Rearrange filtering loop to be a tiny bit
+ more efficient.
+
+ * src/chown-core.c: Don't include savedir.h -- no longer needed.
+ * src/chmod.c: Likewise.
+
+2004-03-25 Jim Meyering <jim@meyering.net>
+
+ * src/du.c (main): Remove now-unused declaration of `i'.
+
+2004-03-24 Paul Eggert <eggert@twinsun.com>
+
+ * src/du.c (main): Filter out file names of length zero before
+ invoking fts, so that they don't cause fatal errors.
+
+2004-03-25 Jim Meyering <jim@meyering.net>
+
+ * tests/du/files0-from (zero-len): Add a test for the above.
+
+2004-02-25 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS: New environment var BLOCKSIZE.
+ * lib/human.c (humblock): Support BLOCKSIZE as well as BLOCK_SIZE.
+ * tests/envvar-check: Test for it. Factor the code to simplify it.
+
+2004-03-23 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS: Shorten the du --files0-from announcement, and say
+ "NUL-terminated" rather than "NUL-separated".
+ * src/du.c (EXPECTED_BYTES_PER_FILE_NAME, DEFAULT_PROJECTED_N_FILES):
+ Remove: not used.
+ (usage): Say "NUL-terminated", not "NUL-separated".
+ (main): Check for I/O error when istream is closed.
+ Allow --files0-from=F even if F is empty; this specifies no files.
+ (du_files): Now that we allow the list of files to be empty,
+ handle that case.
+ * tests/du/files0-from: Adjust to above changes to src/du.c.
+
+2004-03-24 Jim Meyering <jim@meyering.net>
+
+ * tests/tail-2/assert: Avoid race condition that could cause
+ spurious failure. Based on a patch from Andreas Schwab.
+
+2004-03-23 Jim Meyering <jim@meyering.net>
+
+ * src/du.c (main): Free the hash table, too.
+
+2004-03-22 Jim Meyering <jim@meyering.net>
+
+ * man/Makefile.am (.x.1): Remove --info-page= option, reverting
+ the change of 2004-01-22. I can no longer reproduce the problem
+ that prompted that change, and `info coreutils pr' would display the
+ `printing text' section of the manual, not the one on `pr invocation'.
+
+ * tests/du/files0-from (nul-1, nul-2): Adjust expected diagnostics
+ to match corrected output.
+
+ * src/du.c: Include "readtokens0.h" rather than "readtokens.h".
+ (main): Use readtoken0 functions rather than readtokens.
+ Don't use errno when diagnosing readtokens0 failure.
+ Fix off-by-one error in the token number reported in a diagnostic.
+ (du_files): Return bool, rather than int.
+ (main): Call readtokens0_free.
+
+2004-03-21 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (ds_free): Plug a small leak.
+
+ * tests/Fetish.pm: Fix typo in comment.
+
+2004-03-07 Jim Meyering <jim@meyering.net>
+
+ * NEWS: du accepts a new option --files0-from=FILE, where FILE
+ contains a list of NUL-separated file names.
+
+ * src/du.c: Include "readtokens.h".
+ (usage): Describe the new option, and adjust the `Usage':
+ with this option, no FILE may be specified on the command line.
+ (main): Handle the new option.
+
+ * tests/du/files0-from: New tests, for the above.
+ * tests/du/Makefile.am (TESTS): Add files0-from.
+
+ * src/factor.c (do_stdin): Reflect changes in use of readtoken.
+ * src/tsort.c (tsort): Likewise.
+
+2004-02-29 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS: Add support for a new notation @N to get_date to represent
+ the time stamp with numeric value N. Improve support for
+ fractional time stamps. date's -d and -f options now accept them.
+ Likewise for touch -t. date has a new option --iso-8601=ns.
+
+ * doc/coreutils.texi (touch invocation):
+ Describe use of fractional seconds.
+ (date invocation, Options for date): Likewise.
+ * doc/getdate.texi (General date syntax, Time of day items): Likewise.
+ * doc/coreutils.texi (date invocation): Mention effect of LC_TIME.
+ (Options for date): Describe new --iso-8601=ns option.
+
+ * doc/getdate.texi: Add copyright notice. Change getdate to
+ get_date when talking about the function name.
+ (Seconds since the Epoch): New section, containing the time_t
+ info moved from Date input formats section, along with new
+ info about the @ syntax. Mention negative time stamps,
+ fractional time stamps, and leap seconds.
+ (General date syntax): Modernize examples a bit to reflect new
+ features.
+ (General date syntax, Relative items in date strings):
+ Use ' rather than " to quote formats.
+ (Time of day items): Add an example with fractional seconds.
+ Describe fractional-second syntax.
+
+ * src/Makefile.am (touch_LDADD): New macro, since `touch' now
+ needs clock_gettime.
+
+ * src/date.c (enum Time_spec): New enum TIME_SPEC_NS.
+ (time_spec_string, time_spec, show_date): Support it.
+ (usage): Remove description of -ITIMESPEC, as it's obsolete and
+ confusing. Mention --iso-8601=ns.
+ (batch_convert): getline returns ssize_t, not int.
+
+ * src/touch.c (newtime): Now an array of two timespecs, one
+ for access and one for modification.
+ (ref_stats): Remove.
+ (get_reldate): Use get_date's parameter profile.
+ (touch, main): Adjust to above changes.
+ (main): Work even if tm_year == INT_MAX (so long as long int is wider).
+ Use gettime instead of gettimeofday, for new get_date signature.
+
+ * tests/date/Test.pm (test_vector): New tests epoch, ns-10, ns-max32,
+ ns-relative.
+
+2004-03-15 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (alpha beta major): `Make' the emit_upload_commands
+ target before updating $(prev_version_file).
+
+ * tests/misc/date-sec: New file, to test for just-fixed bug in date.
+ See today's change in lib/getdate.y.
+ * tests/misc/Makefile.am (TESTS): Add date-sec.
+
+2004-03-14 Jim Meyering <jim@meyering.net>
+
+ * announce-gen (print_changelog_deltas): Use `.sig' suffix for
+ signature files, not `.asc'. Reported by angico@yahoo.com.
+
+2004-03-13 Jim Meyering <jim@meyering.net>
+
+ * src/cp.c (do_copy): Tweak wording in a diagnostic.
+ Suggestion from Karl Berry.
+ Include "quoatearg.h".
+ (do_copy): Use quotearg_colon (not quote) for diagnostics
+ that begin with `"%s:'.
+
+ * src/nl.c (usage): Specify that nl uses _basic_ regular expressions.
+ Suggestion from Dan Jacobson.
+
+2004-03-12 Jim Meyering <jim@meyering.net>
+
+ * Version 5.2.1.
+
+ Sometimes, when source and destination partition are different,
+ mv mistakenly fails to preserve a hard link. Reported by IIDA Yosiaki.
+
+ * src/copy.c: When moving a set of N hard-linked files between
+ partitions, via two or more command line arguments where the
+ command line argument containing the Nth link contains no other
+ link to that same file, mv would mistakenly copy the file, rather
+ than hard-linking it to the other(s). That happens because when the
+ final link is processed, its link count has been reduced to 1 since
+ the other links have been `copied' to the destination partition
+ and the source links have been removed.
+ (copy_internal): When in move mode, use the source dev/inode
+ pair to look up destination name even when st_nlink == 1.
+ * src/cp-hash.c (src_to_dest_lookup): New function.
+ * src/cp-hash.h (src_to_dest_lookup): Add prototype.
+ * tests/mv/part-hardlink: New file. Test for the above fix.
+ * tests/mv/Makefile.am (TESTS): Add part-hardlink.
+
+ * announce-gen: Sync with autoconf.
+
+ * tests/ls/time-1: Exit 77 (not 1) if we can't set up for the test.
+ This was triggered on a Linux-2.2.19 system using a file system
+ NFS-mounted from some sort of Sun.
+
+2004-03-11 Jim Meyering <jim@meyering.net>
+
+ * Use automake-1.8.3. Regenerate dependent files.
+
+2004-03-10 Jim Meyering <jim@meyering.net>
+
+ * tests/du/deref-args: Also convert sizes in the 70-79 kB range,
+ so that this test works with SELinux-enabled systems.
+ Based on a patch from Tim Waugh.
+
+ `join -1 x' would give a misleading diagnostic
+ * src/join.c (string_to_join_field): Report that a non-numeric field
+ number is invalid, rather than `so large that it is not representable'.
+ * tests/join/Test.pm (invalid-j): New partial test for the above fix.
+
+2004-03-06 Jim Meyering <jim@meyering.net>
+
+ cp --sparse=always sparse-image-file.img /dev/hda1 could
+ produce an invalid copy on the destination device.
+
+ * src/copy.c (copy_reg): Even with --sparse=always, try to
+ make `holes' only if the destination is a regular file.
+ Reported by Szakacsits Szabolcs.
+
+2004-03-03 Paul Eggert <eggert@twinsun.com>
+
+ * src/nohup.c (main): Don't invoke set_cloexec_flag with
+ a file descriptor of -1.
+
+2004-03-02 Dmitry V. Levin <ldv@altlinux.org>
+
+ * src/nohup.c: Include "cloexec.h".
+ (main): Set the copy of stderr to close on exec.
+
+2004-03-01 Paul Eggert <eggert@twinsun.com>
+
+ * configure.ac: Include <signal.h> when checking for strsignal,
+ sys_siglist, and friends. Problem reported by Tony Leneis in
+ <http://mail.gnu.org/archive/html/bug-coreutils/2004-02/msg00136.html>.
+
+2004-02-25 Paul Eggert <eggert@twinsun.com>
+
+ * tests/du/deref-args, tests/du/exclude, tests/du/slash:
+ * tests/du/trailing-slash: Run envvar-check in case BLOCK_SIZE
+ etc. are set.
+
+2004-02-23 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS: Document how chown's USER.GROUP argument is now parsed.
+
+2004-02-23 Jim Meyering <jim@meyering.net>
+
+ * src/seq.c (usage): Remove stray space after \n in --help output.
+
+2004-02-22 Jim Meyering <jim@meyering.net>
+
+ * src/du.c (usage): Separate -H and --si. Say that the meaning
+ of -H will soon change to that of --dereference-args (-D).
+
+2004-02-21 Jim Meyering <jim@meyering.net>
+
+ * src/comm.c (usage): Tell what comm does when there are no options.
+ Reword in terms of FILE1 and FILE2 rather than `left file' and
+ `right file'. Suggestion from Dan Jacobson.
+
+2004-02-15 Paul Eggert <eggert@twinsun.com>
+
+ Fix some POSIX-conformance bugs in expr.
+
+ * NEWS: document the following changes to src/expr.c.
+ * doc/coreutils.texi (expr invocation): Likewise.
+ Document what forms integers may take, and say "integer"
+ consistently instead of "number". Warn about operands
+ that "expr" can misinterpret, and how to work around the
+ problem.
+ * src/expr.c (eval, eval7, eval6, eval5, eval4, eval3, eval2, eval1):
+ Accept a bool argument specifying whether to evaluate the
+ expression. This is to allow short-circuit evaluation. All
+ callers changed.
+ (null): Report that a string is zero even if it has
+ a form like "-0" or "00".
+ (eval1, eval): Use short-circuit evaluation for | and &.
+ (eval): Return 0 if both arguments are null or zero, instead
+ of returning the first argument.
+ * tests/expr/basic: Add some tests for the above.
+
+2004-02-17 Jim Meyering <jim@meyering.net>
+
+ * Version 5.2.0.
+
+ `make check' from a build inside a chroot environment would fail
+ * tests/help-version: Specify an argument (`/') for df, in the
+ unusual event that there is no valid entry in /etc/mtab.
+ Likewise for id: add the -u option, so we don't get spurious
+ failures when there are no user or group names.
+ Patch by Tim Waugh.
+
+ * src/sort.c (usage) [-u]: Add punctuation so that the description in
+ the help2man-generated (line-joined) man page is more readable.
+ Reported by Tim Waugh.
+ [-T]: Add a semicolon, for the same reason.
+
+2004-02-15 Jim Meyering <jim@meyering.net>
+
+ * Makefile.am (dist-hook): Qualify target with $(srcdir)/ prefix.
+
+2004-02-11 Jim Meyering <jim@meyering.net>
+
+ * tests/Makefile.am.in ($(srcdir)/Makefile.am): Use more portable
+ $(srcdir)/../Makefile.am.in, rather than $<.
+ Suggestion from Michael Elizabeth Chastain.
+
+2004-02-10 Jim Meyering <jim@meyering.net>
+
+ * config/install-sh: Make this script executable.
+ * Makefile.am (dist-hook): New target, to ensure that config/install-sh
+ is executable. Otherwise, on systems that lack a suitable install
+ binary, `make install' would fail, because of the way this script
+ is invoked (without `$SHELL ' prefix).
+ Reported by Bob Proulx.
+
+2004-02-08 Jim Meyering <jim@meyering.net>
+
+ * Version 5.1.3.
+
+ * tests/rm/rm5: Avoid triggering a bug in OSF/Tru64's sed
+ that would cause an unwarranted test failure.
+ * tests/rm/rm3: Likewise.
+
+2004-02-07 Jim Meyering <jim@meyering.net>
+
+ Remove xstat function pointer member. The way it was used was not
+ portable, since some systems (OSF V5.1, Solaris 2.5.1) provide static
+ inline `stat' and `lstat' functions, thus making the tests of
+ `xstat == lstat' in copy.c always fail.
+ * src/copy.h (struct cp_options) [xstat]: Remove member.
+ (XSTAT): New macro.
+ * src/copy.c (copy_dir): Set `.dereference' member, not .xstat.
+ (copy_internal): Use `XSTAT (x, ...)' in place of `*(x->xstat) (...)'.
+ Use `x->dereference == DEREF_NEVER' in place of `x->xstat == lstat'.
+ (valid_options): Remove now-obsolete FIXME comments.
+
+ * src/cp.c (re_protect): Use `XSTAT (x, ...)' in place of
+ `*(x->xstat) (...)'.
+ (do_copy): Declare/use local xstat rather than x->xstat.
+ (main): Remove code that set x.xstat.
+ * src/mv.c (cp_option_init): Don't initialize xstat member.
+ * src/install.c (cp_option_init): Likewise.
+
+ * Makefile.cfg (gnu_ftp_host-alpha, etc.): Un-factor .gnu.org suffix,
+ so that emit_upload_commands can use these variables, too.
+
+2004-02-06 Jim Meyering <jim@meyering.net>
+
+ * tests/rm/deep-1: Remove `du' stack space test.
+ Apparently, `ulimit -s N' isn't portable enough.
+ This test will be restored (with a guard against losing ulimit)
+ in its own file later.
+
+ * tests/rm/deep-1 (deep): Remove progress-style diagnostics,
+ since this test doesn't take long enough to merit them.
+ Run du on $tmp (the containing dir), not $deep, the full path to leaf.
+
+ * Makefile.maint (signatures): Remove definition.
+ Now, automake's gnupload handles this.
+ (%.sig: %): Remove now-unused rule.
+ (rel-files): Use automake's $(DIST_ARCHIVES), rather than
+ `$(distdir).tar.bz2 $(distdir).tar.gz'.
+ (emit-upload-commands): Adjust to use gnupload.
+
+2004-02-05 Jim Meyering <jim@meyering.net>
+
+ * src/system.h (ST_TIME_CMP_NS, ST_TIME_CMP): Remove definitions.
+ (ATIME_CMP, CTIME_CMP, MTIME_CMP, TIMESPEC_NS): Likewise.
+ Now, those are all defined in timespec.h.
+ Include timespec.h.
+
+ * src/date.c: Don't include timespec.h, now that system.h does it.
+
+2004-02-02 Paul Eggert <eggert@twinsun.com>
+
+ Don't dump core if localtime returns NULL (possible on
+ hosts with 64-bit time_t and 32-bit int).
+ * src/date.c: Include "inttostr.h".
+ (batch_convert, main):
+ If time conversion fails, exit with nonzero status.
+ (show_date): Return int to report conversion failure.
+ Print the time as an int if localtime fails.
+ * src/uptime.c: Print "??" if the current clock can't
+ be converted by localtime. This won't happen until the year
+ 2*31 + 1900, but we don't want to dump core even if the current
+ clock has the wrong value.
+
+ * src/stat.c: Include "inttostr.h".
+ (human_time): Print the date/time as a number of seconds since the
+ epoch if it can't be converted by localtime. This is better than
+ just saying "invalid", and is consistent with what "ls" does.
+ Don't dump core if the year has more than 48 digits; this isn't
+ possible on any contemporary host, but we might as well do it right.
+
+2004-01-31 Paul Eggert <eggert@twinsun.com>
+
+ * src/stat.c (human_time): Accept time rather than
+ pointer-to-const-time parameter, for clarity. All callers changed.
+
+2004-02-02 Jim Meyering <jim@meyering.net>
+
+ * src/stat.c (do_stat): Remove extra trailing newline from
+ default formats. Reported by Nelson H. F. Beebe.
+
+ Print actual fractional seconds in time stamps, not just `.00000000'.
+ * src/stat.c (human_time): Add and use new parameter, t_ns.
+ (print_stat): Update callers.
+ * src/ls.c (TIMESPEC_NS): Remove definition.
+ * src/system.h (TIMESPEC_NS): Define here, instead, now that stat.c
+ also uses this macro.
+ Nelson H. F. Beebe noticed that ls --full-time printed nonzero
+ fractional seconds for files on an XFS file system, but that stat's
+ fractional seconds were always zero.
+
+2004-01-28 Paul Eggert <eggert@twinsun.com>
+
+ * src/seq.c (print_numbers): Use 'double' for loop index, not
+ 'int', to avoid problems with integer overflow. On almost all
+ machines 'double' works in every case where 'int' works, and
+ it works on other cases besides.
+
+2004-01-27 Jim Meyering <jim@meyering.net>
+
+ * src/seq.c (usage): Mention that if INCREMENT is omitted,
+ it defaults to 1, even when FIRST is larger than LAST.
+ Reword so as not to exclude the possibility that INCREMENT be zero.
+
+2004-01-25 Jim Meyering <jim@meyering.net>
+
+ * Version 5.1.2.
+
+ * Makefile.maint (signatures): Comment out definition.
+
+2004-01-23 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (header_regexp): Add exitfail.
+
+ * man/Makefile.am (EXTRA_DIST): Add help2man.
+ Reported by Nelson H. F. Beebe.
+
+ * man/Makefile.am (.x.1): Prefix help2man invocation with `$(PERL) --'
+ so it works on systems with Perl installed somewhere other than in
+ /usr/bin.
+
+ * src/paste.c (paste_parallel): Declare local, chr, to be of type
+ `int', not `char', since it must hold EOF. This bug would make
+ paste infloop on some systems. Test failures reported by
+ Nelson H. F. Beebe and Christian Krackowizer.
+
+2004-01-22 Jim Meyering <jim@meyering.net>
+
+ * tests/rmdir/fail-perm: New file. Test for just-fixed rmdir bug.
+ * tests/rmdir/Makefile.am (TESTS): Add fail-perm.
+
+ * man/help2man: Fix it so using --info-page='coreutils PROG' works.
+ * man/Makefile.am (.x.1): Invoke our own (tweaked) copy of help2man.
+ Use --info-page='coreutils PROG' option.
+ Now, readlink.1 refers the user to `info coreutils readlink'
+ rather than to `info readlink'. Reported by Matt Swift.
+
+2004-01-21 Paul Eggert <eggert@twinsun.com>
+
+ Exit status cleanup.
+
+ * src/basename.c (usage): Use EXIT_SUCCESS, not 0, for clarity.
+ * src/cat.c, src/chgrp.c, src/chmod.c, src/chown.c, src/chroot.c,
+ * src/cksum.c, src/comm.c, src/cp.c, src/csplit.c, src/cut.c,
+ * src/date.c, src/dd.c, src/df.c, src/dircolors.c, src/dirname.c,
+ * src/du.c, src/echo.c, src/env.c, src/expand.c, src/expr.c,
+ * src/factor.c, src/fmt.c, src/fold.c, src/head.c, src/hostid.c,
+ * src/hostname.c, src/id.c, src/install.c, src/join.c, src/kill.c,
+ * src/link.c, src/ln.c, src/logname.c, src/ls.c, src/md5sum.c,
+ * src/mkdir.c, src/mkfifo.c, src/mknod.c, src/mv.c, src/nice.c,
+ * src/nl.c, src/nohup.c, src/od.c, src/paste.c, src/pathchk.c,
+ * src/pinky.c, src/pr.c, src/printenv.c, src/printf.c, src/pwd.c,
+ * src/rm.c, src/rmdir.c, src/seq.c, src/setuidgid.c, src/shred.c,
+ * src/sleep.c, src/sort.c, src/split.c, src/stat.c, src/stty.c,
+ * src/su.c, src/sum.c, src/sync.c, src/tac.c, src/tail.c, src/tee.c,
+ * src/test.c, src/touch.c, src/tr.c, src/tsort.c, src/tty.c,
+ * src/uname.c, src/unexpand.c, src/uniq.c, src/unlink.c, src/uptime.c,
+ * src/users.c, src/wc.c, src/who.c, src/whoami.c, src/yes.c: Likewise.
+
+ * src/cat.c (usage): Don't bother normalizing exit status
+ since the arg is already the correct exit status now.
+ * src/cksum.c, src/comm.c, src/csplit.c, src/cut.c,
+ * src/dircolors.c, src/expand.c, src/fmt.c, src/fold.c, src/head.c,
+ * src/join.c, src/md5sum.c, src/nl.c, src/od.c, src/paste.c,
+ * src/pr.c, src/split.c, src/sum.c, src/tac.c, src/tail.c, src/tr.c,
+ * src/tsort.c, unexpand.c, src/src/uniq.c, src/src/wc.c: Likewise.
+
+ * src/chown.c (main): Removed unused local 'fail'.
+
+ * src/chroot.c (CHROOT_FOUND_BUT_CANNOT_INVOKE, CHROOT_FAILURE):
+ Remove.
+
+ * src/chroot.c (main): Initialize exit_failure to EXIT_FAIL.
+ * src/env.c, src/nice.c, src/su.c: Likewise.
+ * src/nohup.c (main): Likewise, to NOHUP_FAILURE.
+ * src/setuidgid.c (main): Likewise, to SETUIDGID_FAILURE.
+ * src/expr.c (main): Use initialize_exit_failure rather than
+ setting exit_failure directly; this optimizes away redundant
+ assignments.
+ * src/printenv.c, src/sort.c, src/test.c, src/tty.c: Likewise.
+
+ * src/chroot.c (main): Exit with status 1 rather than 127
+ if chroot itself fails, as per documentation.
+
+ * src/chroot.c (main): Use EXIT_ENOENT and EXIT_CANNOT_INVOKE
+ rather than roll-your-own symbols or integers.
+ * src/env.c (main): Likewise.
+ * src/nohup.c (main): Likewise.
+ * src/su.c (run_shell): Likewise.
+
+ * src/cp.c (exit_status): Remove static var....
+ (main): Making it local here instead. Use =, not |=, to set it.
+
+ * src/cut.c (FATAL_ERROR, main): Exit with status EXIT_FAILURE,
+ not 2, on errors.
+ * src/date.c (batch_convert, main): Likewise.
+ * src/dd.c (dd_copy): Likewise.
+ * src/pr.c (first_last_page, main, getoptarg): Likewise.
+ * src/tr.c (main): Likewise.
+ * src/date.c (main): Don't assume EXIT_FAILURE == 1, as
+ POSIX doesn't require it.
+ * src/dd.c (write_output, skip, dd_copy): Likewise.
+ * src/df.c (main): Likewise.
+ * src/id.c (main): Likewise.
+ * src/install.c (main): Likewise.
+ * src/ln.c (main): Likewise.
+ * src/ls.c (main): Likewise.
+ * src/mv.c (main): Likewise.
+ * src/shred.c (main): Likewise.
+
+ * src/env.c (main): Exit with status 1, not 2, on errors detected
+ by env proper.
+ * src/hostname.c (main): Likewise.
+ * src/nl.c (main): Likewise.
+ * src/stty.c (main): Likewise.
+
+ * src/expr.c (EXPR_FAILURE): Renamed from EXPR_ERROR, for
+ consistency with the other programs' naming conventions.
+ All uses changed.
+
+ * src/factor.c (main): Do not report a usage error simply
+ because stdin has bad numbers.
+
+ * src/id.c (problems): Now a boolean int, not a counter,
+ so that we don't have to worry about int overflow. All uses changed.
+ * src/touch.c (err): Likewise.
+
+ * src/md5sum.c (main): Use int, not size_t, to store boolean int.
+
+ * src/mkfifo.c (main): Exit with status 1, not 4, if not implemented.
+ * src/mknod.c: Likewise.
+
+ * src/nice.c (main): Exit with status EXIT_FAIL, not EXIT_FAILURE,
+ on error; this is in case EXIT_FAILURE is unusual.
+ * src/su.c (main): Likewise.
+
+ * src/nohup.c (NOHUP_FOUND_BUT_CANNOT_INVOKE): Remove; all uses
+ changed to EXIT_CANNOT_INVOKE.
+
+ * src/printenv.c (PRINTENV_FAILURE): New constant.
+ (main): Exit with status PRINTENV_FAILURE, not EXIT_FAILURE, on
+ command-line syntax problems.
+
+ * src/rmdir.c (remove_parents): Don't set 'fail' to a negative number.
+ (main): Avoid integer overflow when seeing whether errors occurred.
+
+ * src/seq.c (print_numbers): Now returns void, not (zero) int.
+ All callers changed.
+ (main): Remove unused local variable 'errs'. Always exit successfully
+ if we reach the end.
+
+ * src/setuidgid.c (SETUIDGID_FAILURE): Renamed from FAIL_STATUS,
+ for consistency with other programs here. All uses changed.
+ (main): Use 'error' to exit rather than invoking 'exit' here.
+
+ * src/sort.c: Don't include <assert.h>.
+ (SORT_OUT_OF_ORDER, SORT_FAILURE): Now enums, not macros.
+ (usage): Don't use 'assert'.
+ (main): Remove redundant assignment to exit_failure.
+
+ * src/system.h (EXIT_FAIL, EXIT_CANNOT_INVOKE, EXIT_ENOENT):
+ New enum values.
+ (initialize_exit_failure): New inline function.
+ Include exitfail.h here, since we refer to exit_failure.
+ All callers changed to not include exitfail.h.
+
+ * src/tty.c (TTY_FAILURE, TTY_WRITE_ERROR): New enum values;
+ substitute them for the corresponding integer constants.
+
+ * tests/help-version (expected_failure_status_date): Remove, as
+ 'date' is now normal.
+ (expected_failure_status_nohup): New var.
+
+2004-01-21 Jim Meyering <jim@meyering.net>
+
+ * tests/touch/relative: Remove `command' syntax.
+ Thanks to Nelson H. F. Beebe and Paul Eggert.
+
+ * tests/touch/relative: Test only year/month/day, not hours/min/sec,
+ so as to avoid problems with systems using TAI clocks.
+ Although it's no longer necessary, set TZ=UTC0 also for the
+ initial touch command. Reported by Paul Jarc here:
+ http://article.gmane.org/gmane.comp.gnu.core-utils.bugs/1504
+
+2004-01-20 Diego Biurrun <diego@biurrun.de>
+
+ * src/dircolors.hin: Add .mov to the list of media files.
+
+2004-01-19 Paul Eggert <eggert@twinsun.com>
+
+ * tests/touch/relative: Use TZ=UTC0, not TZ=utc (which isn't
+ portable). Problem reported by Christian Krackowizer. Also, use
+ +0000 rather than +0 to specify a time zone, as the documentation
+ requires four digits.
+
+2004-01-19 Jim Meyering <jim@meyering.net>
+
+ * tests/mv/hard-4: Run envvar-check in case SIMPLE_BACKUP_SUFFIX is set.
+ * tests/mv/backup-is-src: Likewise.
+ Problem reported by Peter Horst
+
+2004-01-17 Jim Meyering <jim@meyering.net>
+
+ * announce-gen (print_changelog_deltas): Use .sig suffix, not .asc.
+
+ * Version 5.1.1.
+
+2003-12-15 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS, doc/coreutils.texi: touch -r and -d can now both be specified,
+ with -r specifying the origin for -d.
+ * src/touch.c (flexible_date): Remove static var.
+ (get_reldate): New function.
+ (main): Use it, to implement this new behavior.
+
+2004-01-16 Jim Meyering <jim@meyering.net>
+
+ * tests/touch/relative: New test for the above.
+ * tests/touch/Makefile.am (TESTS): Add relative.
+
+2004-01-13 Jim Meyering <jim@meyering.net>
+
+ * src/system.h: Include contents of sys2.h.
+ * src/sys2.h: Remove file.
+ * src/Makefile.am (noinst_HEADERS): Remove sys2.h.
+
+ * Use automake-1.8.2. Regenerate dependent files.
+
+ * Update to gettext-0.13.1.
+ * configure.ac: Use gettext-0.13.1.
+ * .x-sc_space_tab: Add m4/po.m4 to the list of exceptions.
+
+2004-01-12 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (%.sig): Use .sig suffix rather than .asc.
+
+ * Makefile.maint (po-check): Ensure that cvsu works before using it.
+ Reported by Alexandre Duret-Lutz.
+
+ * src/tail.c (main): Warn about following stdin only when it's a tty.
+
+ * configure.ac: Use gl_DEFAULT_POSIX2_VERSION.
+
+2004-01-10 Jim Meyering <jim@meyering.net>
+
+ * tests/misc/stat-fmt: Use backticks, not `$()' notation.
+
+2004-01-09 Jim Meyering <jim@meyering.net>
+
+ * configure.ac: Quote underquoted `jm_DUMMY_1' to avoid new warning.
+
+2004-01-08 Jim Meyering <jim@meyering.net>
+
+ * src/stat.c (human_fstype): Use %lx, not %x format for `unsigned long'.
+ From Andreas Schwab.
+
+ * tests/Makefile.am (TESTS_ENVIRONMENT): Remove `/vg' (prerelease test
+ remnant) from PATH component. That would cause tests in this directory
+ not to run the just-built binaries, but rather whatever happened
+ to be in one's PATH. Reported by Christian Krackowizer.
+
+2004-01-04 Jim Meyering <jim@meyering.net>
+
+ * src/csplit.c (new_control_record): Use x2nrealloc
+ rather than xrealloc.
+
+ * src/cp.c (re_protect): Use ASSIGN_STRDUPA rather than
+ alloca and strcpy.
+ (make_path_private): Likewise.
+
+2004-01-03 Jim Meyering <jim@meyering.net>
+
+ * src/paste.c: Use `bool' (not int) as the type for a few
+ global variables.
+ (collapse_escapes): Rewrite to set globals rather than modifying
+ its parameter.
+ Use size_t (not int) for all counters and related index variables.
+ (paste_parallel): Remove needless complexity of
+ using xrealloc in the loop; just allocate the buffers up front.
+ Free the two temporary buffers.
+ Move declarations of locals `down' into scope where used.
+ (paste_serial): Remove `register' attributes.
+ (main): Simplify delim-related code.
+ Free `delims', now that it's malloc'd.
+
+2004-01-02 Jim Meyering <jim@meyering.net>
+
+ * src/chroot.c: Include "quote.h".
+ (CHROOT_FOUND_BUT_CANNOT_INVOKE, CHROOT_FAILURE): Define.
+ (main): Exit with status of 127, not 1, for too-few-args,
+ chroot failure, or chdir failure.
+ Give a better diagnostic upon execvp failure.
+
+ * src/du.c (usage): Mention that, with its current meaning,
+ -H is deprecated.
+
+ * src/tail.c (main): Warn about following stdin when it's a tty.
+ Fail when following by name but no names are specified.
+
+2003-12-30 Jim Meyering <jim@meyering.net>
+
+ * src/fold.c (main): Use memcpy, not strcpy.
+
+ * src/copy.c (copy_internal): Use ASSIGN_STRDUPA rather than
+ alloca and strcpy.
+
+2003-12-28 Jim Meyering <jim@meyering.net>
+
+ * src/unexpand.c (n_tabs_allocated): New global.
+ (add_tabstop): Use x2nrealloc rather than xrealloc.
+ * src/expand.c: Likewise.
+
+ * tests/misc/expand: New file.
+ * tests/misc/Makefile.am (TESTS): Add expand.
+
+ * src/sort.c (add_temp_dir): Use x2nrealloc rather than xrealloc.
+ (fillbuf): Use x2nrealloc rather than xrealloc.
+ (sort): Use xnmalloc rather than xmalloc.
+ (main): Likewise.
+
+2003-12-27 Jim Meyering <jim@meyering.net>
+
+ * src/tee.c (tee): Use xnmalloc rather than xmalloc.
+
+2003-12-29 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS: Remove support for join -j1 FIELD, -j2 FIELD, and -o LIST1
+ LIST2 in POSIX 1003.1-2001 hosts, as required by POSIX.
+
+ * doc/coreutils.texi (join invocation): Remove documentation
+ accordingly. Document that -t makes all separators significant.
+
+ * src/join.c: Include posixver.h.
+ (obsolete_usage): New var.
+ (longopts): Put obsolete options first.
+ (OBSOLETE_LONG_OPTIONS): New constant.
+ (get_option, add_file_name): New functions.
+ (main): Use them to support new behavior.
+ (usage): Remove documentation for -j1 FIELD and -j2 FIELD.
+ Do not mark -j FIELD as obsolescent; it is longstanding
+ UNIX tradition and is a valid extension to POSIX.
+
+ * tests/join/Test.pm (tv): Avoid obsolete -o usage.
+
+2003-12-28 Paul Eggert <eggert@twinsun.com>
+
+ * src/join.c (add_field_list): Don't use alloca with unbounded
+ size; just modify the argument, which is no longer const *.
+
+ Various other minor cleanups, mostly to avoid the need for casts.
+
+ (extract_field): Renamed from ADD_FIELD, as it's now a function.
+
+ (struct field.beg): Now char *, not unsigned char const *. All
+ uses changed. It shouldn't be const since xmemcoll writes on its
+ arguments.
+ (extract_field): Likewise, for 2nd arg.
+ (keycmp): Remove now-unnecessary cast of xmemcoll args.
+
+ (is_blank): New function, to avoid need to cast arg to unsigned char.
+ (extract_field): Use it.
+
+ (xfields): Rewrite pretty much from scratch.
+
+ (hard_LC_COLLATE): Now bool, not int.
+ (get_line, getseq, add_field_list): Now returns bool, not int.
+ (decode_field_spec, add_field_list): Return true on success (not
+ false), for consistency with the rest of the code. All uses changed.
+
+ (tab): Now char, not unsigned char. This wasn't 100% necessary
+ but is slightly cleaner.
+ (prjoin): Hoist (tab ? tab : ' ') expression, to help the compiler.
+
+ (empty_filler): Now const *.
+
+ (make_blank): Remove; wasn't needed. Remove all calls.
+ (main): Don't set uni_blank.nfields; zero is fine.
+
+2003-12-27 Jim Meyering <jim@meyering.net>
+
+ * src/join.c: Include "quote.h".
+ (min, max): Remove definitions.
+ Make a few function parameters and corresponding
+ locals `const'. Use bool for boolean variables.
+ Use size_t (not int) for all counters and related index variables.
+ (prjoin): Remove now-useless assertion.
+ (string_to_join_field): New function.
+ (main): Accept join fields as large as SIZE_MAX.
+ (keycmp): Rename `min' to MIN and max to MAX.
+
+2003-12-26 Jim Meyering <jim@meyering.net>
+
+ fold -s didn't work on e.g., alpha-based systems.
+ * src/fold.c (fold_file): Adjust types (int->size_t) so that using
+ x2nrealloc works properly on systems with differing sizes for int
+ and size_t. Reported by Nelson Beebe.
+
+ * src/fold.c: Use `bool' (not int) as the type for a few
+ global variables.
+
+2003-12-23 Paul Eggert <eggert@twinsun.com>
+
+ * src/ls.c (length_of_file_names_and_frills):
+ Remove forward decl; not needed.
+ (print_file_name_and_frills, length_of_file_name_and_frills):
+ With -m, don't output spaces before inum or size.
+ (print_with_commas): Don't output space just before newline.
+
+2003-12-24 Jim Meyering <jim@meyering.net>
+
+ * tests/ls/Makefile.am (TESTS): Add m-option.
+ * tests/ls/m-option: New file. Test for above fixes.
+
+2003-12-20 Jim Meyering <jim@meyering.net>
+
+ * Version 5.1.0.
+
+ * src/pr.c: Change type of global, buff_allocated, to size_t.
+
+ * src/join.c [struct seq]: Change types of members count and alloc
+ from `int' to `size_t'.
+
+ * tests/Makefile.am (root-hint): Tweak wording.
+
+ * src/du.c: Accept new option (-0, --null) that makes it so each
+ output line is NUL-terminated rather than newline-terminated.
+
+ * src/dd.c (apply_translations): Don't prohibit conv=unblock,sync.
+ Reported by Volker Paul.
+ * tests/dd/Makefile.am (TESTS): Add unblock-sync.
+ * tests/dd/unblock-sync: New test for the above.
+
+2003-12-19 Jim Meyering <jim@meyering.net>
+
+ * tests/misc/nohup: Double quote back-ticked expression,
+ in case it ends up having an unexpected value.
+
+ * tests/ls/no-arg: Use ls's -1 option in both runs.
+
+ * src/du.c (fts_debug): New global.
+ (FTS_CROSS_CHECK, DEBUG_OPT): Define.
+ (main): Make fts use FTS_TIGHT_CYCLE_CHECK.
+ (main) [DU_DEBUG]: Accept -d option.
+
+2003-12-18 Jim Meyering <jim@meyering.net>
+
+ * src/ls.c (format_user): Increment dired_pos via two statements,
+ `dired_pos += width; dired_pos++;' rather than one,
+ `dired_pos += width + 1;' since the latter could conceivably overflow.
+ (format_group): Likewise.
+ From Paul Eggert.
+
+ * configure.ac: Require automake-1.8.
+
+2003-12-12 Jim Meyering <jim@meyering.net>
+
+ * Use automake-1.8. Regenerate dependent files.
+
+2003-12-08 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (news-date-check): New rule.
+ (alpha beta major): Depend on it.
+
+2003-12-03 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS: ls -l (and similar options) now adjust all columns to
+ fit the data. Generalized from a suggestion by Leah Q for file sizes.
+ * src/ls.c (INODE_DIGITS, LOGIN_NAME_MAX, ID_LENGTH_MAX): Remove.
+ (format_user_width, format_group_width, unsigned_file_size,
+ format_group): New functions.
+ (block_size_width): Renamed from block_size_size.
+ (inode_number_width, nlink_width, owner_width, group_width,
+ author_width, major_device_number_width, minor_device_number_width,
+ file_size_width): New vars.
+ (clear_files): Initialize them.
+ (gobble_file): Set them. Don't ceiling block_size_width to 7.
+ (print_long_file): Use them.
+ (gobble_file): Use a new local variable 'f' to make the code
+ smaller and more consistent with other functions.
+ (format_user): Output to stdout, not to a buffer, so that we
+ don't have to worry about buffer overrun. Update dired_pos.
+ (print_long_file): Don't put owner, group, author into buffer;
+ just print them directly. Don't assume link counts and
+ major and minor numbers fit into unsigned long int.
+ * tests/cp/same-file, tests/mv/part-symlink: Don't assume that
+ 'ls' output is fixed-width.
+
+2003-12-02 Jim Meyering <jim@meyering.net>
+
+ * src/md5sum.c: Include sha1.h (reflect renaming: sha.h -> sha1.h.
+
+2003-11-27 Jim Meyering <jim@meyering.net>
+
+ * Use automake-1.7f. Regenerate dependent files.
+
+2003-11-24 Paul Eggert <eggert@twinsun.com>
+
+ Parse floating-point operands and options in the C locale.
+ POSIX requires this for printf, and we might as well be
+ consistent elsewhere (tail, sleep, seq).
+
+ * src/printf.c: Remove decls of strtod, strtol, strtoul; no longer
+ needed now that we assume C89. Include "c-strtod.h".
+ (xstrtod): Call c_strtod, not strtod.
+ * src/sleep.c: Include "c-strtod.h".
+ (main): Update xstrtod call to include new argument, c_strtod.
+ * src/seq.c (scan_double_arg): Likewise.
+ * src/tail.c (parse_options): Likewise.
+
+2003-11-24 Jim Meyering <jim@meyering.net>
+
+ * tests/rm/fail-2eperm: Handle another errno variant (HPUX, EPERM).
+ Reported by Mark Conty.
+
+2003-11-22 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (sc_xalloc_h_in_src): Remove rule. Subsumed by...
+ (sc_system_h_headers): Do this test only if sys2.h exists.
+
+2003-11-20 Jim Meyering <jim@meyering.net>
+
+ * tests/help-version: Ensure that the bug-reporting address is
+ included in the --help output for every program.
+ * tests/Makefile.am (TESTS_ENVIRONMENT): Add $PACKAGE_BUGREPORT.
+
+ * src/ptx.c (usage): Output bug-reporting address.
+ Reported by Dan Jacobson.
+
+2003-11-19 Jim Meyering <jim@meyering.net>
+
+ * src/join.c (usage): Mention that FILE1 and FILE2 must be sorted
+ on the join fields. Suggestion from Bruce Robertson.
+
+2003-11-18 Jim Meyering <jim@meyering.net>
+
+ `od -c -w9999999' could segfault
+ * src/od.c (dump): Use xnmalloc/free, not alloca.
+
+2003-11-16 Jim Meyering <jim@meyering.net>
+
+ * Use autoconf-2.59. Regenerate dependent files.
+
+ * tests/du/hard-link: Minor tweak: use mkdir -p.
+
+ Fix read-from-free'd-buffer error detected by valgrind.
+ * src/csplit.c (remove_line): Don't return a pointer to data in
+ a freed buffer. Instead, arrange to free the buffer on the
+ subsequent call.
+
+ * tests/misc/csplit: New test for above fix.
+
+2003-11-11 Jim Meyering <jim@meyering.net>
+
+ * src/ls.c (extract_dirs_from_files): Avoid useless copy operations.
+ This avoids a warning from valgrind about memcpy with overlapping
+ source and destination.
+
+ * configure.ac: Require automake-1.7.8.
+
+2003-11-09 Jim Meyering <jim@meyering.net>
+
+ * Use automake-1.7.9. Regenerate dependent files.
+
+ * src/rm.c: Support new options: --preserve-root and --no-preserve-root.
+ * src/chown.c: Likewise.
+
+ * src/chown-core.c: Include "root-dev-ino.h".
+ (chopt_init): Initialize new member.
+ (change_file_owner): Support rm's new --preserve-root option.
+
+ * src/remove.c: Include "root-dev-ino.h".
+ (remove_cwd_entries): Remove now-obsolete FIXME comment.
+ (remove_dir): Support rm's new --preserve-root option.
+
+ * src/chown.c: Include "root-dev-ino.h".
+ Add new options: --preserve-root and --no-preserve-root.
+
+ * src/chmod.c: Include "root-dev-ino.h".
+ (process_file): Use newly-factored-out ROOT_DEV_INO_CHECK and
+ ROOT_DEV_INO_WARN macros.
+ (get_root_dev_ino): Remove function definition, now that it's
+ been moved to a separate file.
+ (usage): Describe new options.
+
+ * src/mv.c (rm_option_init): Initialized new member.
+
+ * src/remove.h: Include "dev-ino.h".
+ (struct rm_options): Add new member: root_dev_ino.
+ * src/chown-core.h: Include "dev-ino.h".
+ (struct Chown_option): Add new member: root_dev_ino.
+
+2003-11-06 Jim Meyering <jim@meyering.net>
+
+ * src/paste.c (paste_parallel): Use `sizeof *var' rather than
+ hard-coding `sizeof FILE*'.
+
+2003-11-05 Dennis Smit <ds@nerds-incorporated.org>
+
+ * src/wc.c (main): Free `fstatus' so there is no confusion about
+ whether it's leaked or not.
+ * src/who.c (who): Likewise for `utmp_buf'.
+
+2003-11-05 Paul Eggert <eggert@twinsun.com>
+
+ Fix 'cut' problems with size_t overflow and unsigned int.
+ More generally, resize integer variables to fit use more precisely.
+ * src/cut.c (ADD_RANGE_PAIR): Remove unnecessary parens.
+ (struct range_pair): Make members to be of type size_t, not unsigned.
+ (max_range_endpoint, eol_range_start): Now size_t, not unsigned.
+ (suppress_non_delimited, output_delimiter_specified,
+ have_read_stdin, print_kth, set_fields): Now bool, nt int.
+ (delim): Now unsigned char, not int.
+ (mark_printable_field, is_printable_field, is_range_start_index,
+ set_fields, set_fields, cut_bytes, cut_fields):
+ Use size_t, not unsigned, for field and byte counts.
+ (hash_int): Use uintptr_t, not unsigned, for pointers converted
+ to integers. This squeezes more info out of them.
+ (set_fields, cut_bytes, cut_fields, main):
+ Use bool, not int, for booleans.
+ (set_fields): Allocate zeroed byte array with xzalloc, not xcalloc.
+
+2003-11-05 Paul Eggert <eggert@twinsun.com>
+
+ * man/Makefile.am (check-programs-vs-x):
+ Work even if $(programs) contains '$'.
+ Work even if 'missing=1' in environment.
+ Don't report an error simply because $(programs) outputs nothing.
+
+2003-11-05 Jim Meyering <jim@meyering.net>
+
+ * Use autoconf-2.58. Regenerate dependent files.
+
+ * src/tr.c (spec_init): Fix typo in last change.
+
+ * src/sys2.h (case_GETOPT_VERSION_CHAR): Cast NULL to `(char *)' in
+ call to variadic version_etc function, so that it works even on systems
+ for which sizeof char* != sizeof int.
+ * src/true.c (main): Likewise.
+ * basename.c, chroot.c, cksum.c, dd.c, dirname.c, echo.c, expr.c:
+ * factor.c, hostid.c, hostname.c, link.c, logname.c, nice.c, nohup.c:
+ * pathchk.c, printenv.c, printf.c, pwd.c, setuidgid.c, sleep.c, stty.c:
+ * sync.c, test.c, tsort.c, unlink.c, uptime.c, users.c, whoami.c, yes.c:
+ Similarly, cast NULL to `(char *)' in call to variadic function,
+ parse_long_options, so that it works even on systems for which
+ sizeof char* != sizeof int.
+ A similar problem was reported by Harti Brandt in
+ http://mail.gnu.org/archive/html/bug-gnu-utils/2003-10/msg00320.html.
+
+ * src/users.c (users): Free `utmp_buf' explicitly so that people
+ don't mistake this for a real leak.
+ Patch by Dennis Smit <ds@nerds-incorporated.org.
+
+2003-11-04 Paul Eggert <eggert@twinsun.com>
+
+ * README: Document _POSIX2_VERSION.
+
+2003-11-04 Jim Meyering <jim@meyering.net>
+
+ * src/tac.c (memrchr): Remove #if-0'd function.
+ (tac_stdin_to_mem): Clean up #if-0'd code.
+
+ * src/od.c (decode_format_string): Remove unnecessary casts.
+ Use more maintainable `sizeof *var'.
+ (main): Call decode_format_string rather than decode_one_format,
+ now that `spec' may be NULL.
+
+ * src/chmod.c (AUTHORS): Add my name.
+
+ * src/split.c (next_file_name): Use `sizeof *var' rather than
+ hard-coding `sizeof size_t'.
+
+ * src/sort.c (new_key): Use xzalloc, not xcalloc (1, ...).
+
+ * src/cut.c (ADD_RANGE_PAIR): Use x2nrealloc rather than xrealloc,
+ to avoid potential overflow in pointer arithmetic.
+ (set_fields): Use not `1', but rather `sizeof *printable_field' as
+ second argument to xcalloc.
+ * src/od.c (decode_format_string, dump_strings): Use x2nrealloc
+ rather than xrealloc.
+ * src/date.c (show_date): Likewise.
+ * src/join.c (ADD_FIELD, initseq, getseq): Likewise.
+ * src/pr.c (store_char): Likewise.
+ * src/fold.c (fold_file): Likewise.
+
+ * src/copy.c (triple_hash, triple_hash_no_name): Adjust to reflect
+ type changes (unsigned int -> size_t) in hash.c.
+ * src/cp-hash.c (src_to_dest_hash): Likewise.
+ * src/du.c (entry_hash): Likewise.
+ * src/ls.c (dev_ino_hash): Likewise.
+ * src/cut.c (hash_int): Likewise. Declare function as static.
+
+2003-11-03 Jim Meyering <jim@meyering.net>
+
+ * tests/misc/Makefile.am (TESTS_ENVIRONMENT): Define PACKAGE_VERSION.
+ * tests/misc/fold: Fail the test immediately if we're not running
+ the expected version of fold.
+
+2003-11-02 Jim Meyering <jim@meyering.net>
+
+ * src/tr.c (append_normal_char, append_range, append_char_class)
+ (append_repeated_char, append_equiv_class, spec_init): Use `sizeof *var'
+ rather than `sizeof EXPLICIT_TYPE'. The former is more maintainable
+ and usually shorter.
+ * src/copy.c (copy_internal): Likewise.
+ * src/join.c (initseq, add_field, make_blank): Likewise.
+ * src/od.c (main): Likewise.
+ * src/cp.c (make_path_private): Likewise.
+ * src/tsort.c (new_item, record_relation): Likewise.
+
+ * src/df.c (add_fs_type, add_excluded_fs_type, main): Likewise.
+ (main): Also remove anachronistic cast of xmalloc return value.
+ * src/ptx.c (alloc_and_compile_regex, main): Likewise.
+ (main): Also remove anachronistic cast of xmalloc return value.
+ * src/sort.c (inittables): Likewise.
+ (sort): Also Split a long line.
+
+2003-10-25 Jim Meyering <jim@meyering.net>
+
+ * src/copy.c (triple_hash, triple_hash_no_name): Adjust to reflect
+ type changes (unsigned int -> size_t) in hash.c.
+ * src/cp-hash.c (src_to_dest_hash): Likewise.
+ * src/du.c (entry_hash): Likewise.
+ * src/ls.c (dev_ino_hash): Likewise.
+ * src/cut.c (hash_int): Likewise. Declare function as static.
+
+2003-10-21 Jim Meyering <jim@meyering.net>
+
+ Don't fail when run with VERBOSE=yes.
+ * tests/chgrp/basic: Do `set +x' before starting the subshell
+ from which we invoke chgrp. Otherwise, the output from the
+ VERBOSE=yes-induced `set -x' would result in spurious differences.
+ Reported by Russel Coker via Michael Stone.
+
+2003-10-19 Jim Meyering <jim@meyering.net>
+
+ chmod now uses fts to perform a directory traversal when -R is
+ specified. Before, it operated on full path names, and as such
+ would encounter the PATH_MAX (often 4096) limit.
+
+ * src/chmod.c: Include "xfts.h".
+ (process_file): Rename from change_file_mode.
+ Adapt to be used with fts.
+ (process_files): New function.
+
+2003-10-18 Jim Meyering <jim@meyering.net>
+
+ * tests/du/deref-args: Ensure that du -D now dereferences all
+ symlinks specified on the command line, not just those that
+ reference directories.
+
+ * basename.c, cat.c, chroot.c, cksum.c, comm.c, cp.c, csplit.c, cut.c:
+ * dd.c, df.c, dirname.c, du.c, echo.c, env.c, expr.c, factor.c, head.c:
+ * hostid.c, hostname.c, id.c, link.c, ln.c, logname.c, ls.c, md5sum.c:
+ * mv.c, nice.c, nl.c, nohup.c, paste.c, pathchk.c, pinky.c, pr.c:
+ * printenv.c, printf.c, pwd.c, rm.c, setuidgid.c, sleep.c, sort.c:
+ * split.c, stty.c, sum.c, sync.c, tac.c, tail.c, tee.c, test.c:
+ * touch.c, tsort.c, uniq.c, unlink.c, uptime.c, users.c, wc.c:
+ * who.c, whoami.c, yes.c (AUTHORS): Revert the WRITTEN_BY/AUTHORS change
+ of 2003-09-19. Now, AUTHORS is a comma-separated list of strings.
+ Update the call to parse_long_options so that `AUTHORS, NULL' are the
+ last parameters.
+ * src/true.c (main): Append NULL to version_etc argument list.
+ * src/sys2.h (case_GETOPT_VERSION_CHAR): Likewise.
+
+2003-10-17 Andreas Schwab <schwab@suse.de>
+
+ * tests/mk-script: Get $srcdir from first parameter instead of
+ hardcoding it.
+ (main): Update usage.
+
+ * tests/Makefile.am.in ($(srcdir)/$x-tests): Pass $(srcdir) as
+ first argument of mk-script.
+ ($(srcdir)/Makefile.am): Likewise. Prepend $(srcdir) to target.
+
+2003-10-17 Jim Meyering <jim@meyering.net>
+
+ * src/mv.c (usage): Tweak descriptions of -i and -f so that the
+ generated `man' page is more readable. Suggestion from Dan Jacobson.
+
+ * src/chown-core.c (change_file_owner): Handle the cases in
+ which fts_info indicates an error with the given entry.
+
+ * src/du.c (main): Simply assign to bit_flags.
+ Don't bother with bit arithmetic.
+
+ * tests/chmod/no-x: New file.
+ * tests/chgrp/no-x: New file.
+ * tests/chmod/Makefile.am (TESTS): Add no-x.
+ * tests/chgrp/Makefile.am (TESTS): Likewise.
+
+ * src/du.c: Include "xfts.h".
+ (du_files): Use xfts_open, rather than fts_open.
+ * src/chown-core.c (chown_files): Likewise.
+
+2003-10-16 Jim Meyering <jim@meyering.net>
+
+ * src/chgrp.c (main): Simply assign to bit_flags.
+ Don't bother with bit arithmetic.
+ * src/chown.c (main): Likewise.
+ Rename a couple of local variables.
+ Remove unnecessary casts.
+
+ * src/tail.c (start_bytes): Rename local, remainder, to avoid
+ gcc's warning about shadowing a global.
+
+2003-10-15 Jim Meyering <jim@meyering.net>
+
+ chown and chgrp now accept POSIX-mandated -H, -L, -P options and
+ use fts to perform a directory traversal when -R is specified.
+ Before, they operated on full path names, and as such would
+ encounter the PATH_MAX (often 4096) limit.
+ They are more efficient. For example, before, chgrp -R would
+ take almost 5 seconds to change about 2000 directories and fail
+ (with `File name too long'), while now it succeeds on a hierarchy
+ of depth 20,000 in 1/10 the time.
+
+ * src/chown.c: Include "userspec.h" and "fts_.h".
+ (WRITTEN_BY): Add my name.
+ (getpwnam, getgrnam, getgrgid): Remove declarations.
+ (endpwent): Remove definition.
+ (usage): Update.
+ (main): Handle new options.
+ Call new function, chown_files rather than change_file_owner.
+
+ * src/chgrp.c: Include "fts_.h".
+ (WRITTEN_BY): Add my name.
+ (MAXUID, MAXGID): Remove definitions. Use GID_T_MAX instead of
+ the latter.
+ (usage): Update.
+ (main): Handle new options.
+ Call new function, chown_files rather than change_file_owner.
+
+ Rewrite to iterate through hierarchies using fts rather than
+ via explicit recursion.
+ * src/chown-core.c: Include "fts_.h"
+ (change_file_owner): Rewrite to use FTS* and FTSENT* and to operate
+ on a single file at a time.
+ (chown_files): New function.
+ * src/chown-core.h [enum Dereference_symlink]: Remove declaration.
+ [struct Chown_option] (recurse, force_silent): Change type to `bool'.
+ [struct Chown_option] (dereference): Remove member with ambiguous name.
+ [struct Chown_option] (affect_symlink_referent): New member.
+ (chown_files): New prototype.
+
+ * tests/chgrp/recurse: Update tests accordingly.
+ * tests/chgrp/posix-H: New tests for the above.
+ * tests/chgrp/Makefile.am (TESTS): Add posix-H.
+
+ * src/ln.c (usage): Clarify that --directory, -d, -F probably won't
+ work even for superuser. Suggestion from Dan Jacobson.
+
+2003-10-14 Paul Eggert <eggert@twinsun.com>
+
+ Fix some number-parsing bugs, e.g., "head -n 100k@" wasn't
+ properly diagnosed.
+ * lib/human.c, lib/xstrtoimax.c, lib/xstrtol.c, lib/xstrtol.h,
+ lib/xstrtoul.c, lib/xstrtoumax.c: Sync with gnulib.
+ * src/sort.c (parse_field_count): Handle the case where overflow
+ and invalid suffix char are both reported.
+
+2003-10-14 Jim Meyering <jim@meyering.net>
+
+ * src/ls.c (decode_switches) [TIOCGWINSZ]: Comment out the
+ warning-inducing test, ws.ws_col <= SIZE_MAX, since it was always
+ true on Linux.
+
+2003-10-13 Paul Eggert <eggert@twinsun.com>
+
+ Fix to avoid a denial-of-service attack if the display width is
+ enormous. Also, clean up the code a bit by removing duplicate code.
+
+ * src/ls.c (init_column_info): Remove forward decl; no longer needed.
+ (calculate_columns): New function, that contains code that used
+ to be common to print_many_per_line and print_horizontal.
+ (print_many_per_line, print_horizontal): Use it.
+ (decode_switches): Set max_idx here, not in calculate_columns.
+ (print_current_files): Don't call init_column_info; calculate_columns
+ now does that.
+ (init_column_info): Don't allocate a lot more space than is needed
+ to represent the current set of files. Allocate all the new
+ size_t cells in one call to xnmalloc, rather than a row at a time.
+
+2003-10-13 Jim Meyering <jim@meyering.net>
+
+ * src/ls.c (init_column_info): Add another FIXME comment.
+
+2003-10-13 Paul Eggert <eggert@twinsun.com>
+
+ Fix address-arithmetic bug in 'ls', reported by Georgi Guninski.
+ Remove several arbitrary limits on hosts where int cannot represent
+ all size_t values.
+
+ * src/ls.c (struct bin_str.len, length_of_file_name_and_frills, indent,
+ nfiles, files_index, tabsize, line_length, struct column_info.line_len,
+ struct column_info.col_arr[0], max_idx):
+ Now size_t, not int.
+ (get_funky_string): Return bool indicating success, instead of
+ a negative count to indicate failure. Store number of columns
+ through new parameter OUTPUT_COUNT; that way, they can never
+ go negative. Change equals_end from int to bool. All uses
+ changed.
+ (struct column_info.valid_len): Now bool, not int. All uses changed.
+ (dired_dump_obstack, get_funky_string, clear_files,
+ extract_dirs_from_files, print_current_files,
+ print_many_per_line, print_horizontal, init_column_info,
+ put_indicator, length_of_file_name_and_frills,
+ print_with_commas): Use size_t, not int, for local variables
+ that count sizes.
+ (decode_switches): Decode sizes using xstrtoul, not xstrtol.
+ Check for TIOCGWINSZ returing negative values (or values greater
+ than SIZE_MAX!).
+ (visit_dir, main, parse_ls_color, queue_directory, add_ignore_pattern,
+ init_column_info):
+ Use xmalloc and xnmalloc, not XMALLOC.
+ (gobble_file): Use xnrealloc, not XREALLOC.
+ (print_color_indicator): Remove now-unnecessary cast to size_t.
+
+2003-10-12 Paul Eggert <eggert@twinsun.com>
+
+ * tests/du/no-x: Change wording of diagnostic to match latest du.c.
+ * tests/sort/sort-tests: Remove from CVS; assume that people
+ brave enough to check coreutils out from CVS can rebuild it.
+
+2003-10-12 Jim Meyering <jim@meyering.net>
+
+ New options: --preserve-root and --no-preserve-root.
+ * src/chmod.c (change_file_mode): Honor new option.
+ (change_file_mode): Strip trailing slashes on directory
+ argument passed to change_dir_mode.
+ (get_root_dev_ino): New function.
+ (main): Initialize global, root_dev_ino.
+
+ * src/copy.c (copy_internal): Don't #ifdef-out simple uses of
+ S_ISLNK or S_ISSOCK. The S_IS* macros are guaranteed to be defined
+ via system.h.
+ * src/chmod.c (change_file_mode): Likewise.
+
+2003-10-08 Jim Meyering <jim@meyering.net>
+
+ * src/csplit.c (main): Remove obsolete FIXME.
+
+2003-10-07 Jim Meyering <jim@meyering.net>
+
+ * Use automake-1.7.8. Regenerate dependent files.
+
+2003-09-29 Paul Eggert <eggert@twinsun.com>
+
+ csplit cleanup.
+
+ * doc/coreutils.texi (csplit invocation):
+ The regexp offset need not have a sign; POSIX requires support
+ for signless offets.
+
+ Be more careful about int widths. For example, remove some
+ arbitrary limits by replacing 'unsigned' with 'size_t',
+ 'uintmax_t', etc. Use standard bool rather than a homegrown type.
+ * lib/Makefile.am (libfetish_a_SOURCES): Add xstrtoimax.c.
+ * src/csplit.c (FALSE, TRUE, boolean): Remove. All uses changed
+ to <stdbool.h> usage.
+ (struct control): offset is now intmax_t, not int.
+ repeat_forever is now bool, not int.
+ (struct cstring): len is now size_t, not unsigned int.
+ (struct buffer_record): bytes_alloc, bytes_used, num_lines are now
+ size_t, not unsigned. start_line, first_available are now
+ uintmax_t, not unsigned.
+ (hold_count, control_used): Now size_t, not unsigned.
+ (last_line_number, current_line, bytes_written):
+ Now uintmax_t, not unsigned.
+ (save_to_hold_area, red_input, keep_new_line, record_line_starts,
+ create_new_buffer, get_new_buffer, load_buffer, find_line,
+ process_regexp, split_file, new_control_record, extract_regexp,
+ get_format_width, get_format_prec, max_out):
+ size args, locals, and returned values are now size_t, not unsigned
+ or int.
+ (get_first_line_in_buffer, find_line, write_to_file,
+ handle_line_error, process_line_count, regexp_error, process_regexp,
+ split_file):
+ File line, byte, and repetition counts are now uintmax_t, not unsigned.
+ (check_for_offset): Don't require a sign before the offset.
+ Use xstrtoimax to do the real work.
+ (extract_regexp): Remove harmful cast of size to unsigned.
+ 256 -> 1<<CHAR_BIT, for clarity.
+ (get_format_flags): Return at most 3, to avoid worries about overflow.
+
+ (bytes_to_octal_digits): Remove.
+
+ (cleanup): Don't check whether output_stream is NULL, since
+ close_output_file does that for us.
+
+ (new_line_control, create_new_buffer): Use "foo *p = xmalloc
+ (sizeof *p);" instead of the more long-winded alternatives.
+
+ (get_new_buffer): Use O(1) algorithm for resizing a buffer
+ to a much larger size, instead of an O(N) algorithm.
+
+ (process_regexp): Use plain NULL rather than casted 0.
+
+ (make_filename): Use %u, not %d, to format unsigned file number.
+
+ (new_control_record): Use xrealloc exclusively, since it handles
+ NULL reliably.
+
+ (extract_regexp): Change misspelled word in diagnostic.
+
+ (get_format_width): Even if a minimum field width is specified,
+ allow room for enough octal digits to represent the value of
+ the maximum representible integer. This fixes a potential
+ buffer overrun. Calculate this room at compile-time, not
+ at run-time; this removes the need for bytes_to_octal_digits.
+ Check for overflow; this removes a FIXME.
+
+ (get_format_prec): Don't allow precision to be signed; it's
+ not ANSI. Check for overflow. Remove hardcoded "11" as
+ default precision; this fixes a potential buffer overrun
+ on hosts with wider size_t.
+
+ (get_format_conv_type): Change local variable to be of type
+ unsigned char, not int; this removes a potential subscript
+ violation on hosts where char is signed.
+
+ (max_out): Replace "for (;*p;)" with more-standard "while (*p)".
+ Allow "%%" in format. Don't overflow when
+ counting lots of percents.
+
+ (usage): Default sprintf format is %02u, not %d.
+
+2003-10-05 Jim Meyering <jim@meyering.net>
+
+ * src/chown-core.c (change_file_owner): Remove set-but-not-used local.
+
+ * src/du.c (du_files): Mark diagnostic for translation.
+
+2003-10-04 Jim Meyering <jim@meyering.net>
+
+ * src/du.c (du_files): Ignore any failure of fts_close.
+ Give better diagnostics for failed fts_open.
+
+ * src/du.c (MAX_N_DESCRIPTORS): Remove now-unused definition.
+
+ Deprecate existing use of -H (aka --si).
+ * src/du.c (enum) [HUMAN_SI_OPTION]: New member.
+ [long_options]: Use HUMAN_SI_OPTION, not 'H'.
+ (main): Warn that the meaning of -H will soon change to be
+ POSIX compliant.
+
+2003-10-03 Jim Meyering <jim@meyering.net>
+
+ * src/du.c: Accept --no-dereference (-P).
+
+2003-10-02 Jim Meyering <jim@meyering.net>
+
+ * tests/du/trailing-slash: Adjust for slightly different output.
+
+ Rewrite du.c to use fts.
+ * src/du.c: Include "fts_.h", not ftw.h.
+ (opt_dereference_arguments, arg_length, suffix_length): Remove globals.
+ (IS_FTW_DIR_TYPE): Remove definition.
+ (IS_DIR_TYPE): Define.
+ (is_symlink_to_dir): Remove now-unnecessary function.
+ (process_file, du_files): Rewrite to use fts.
+
+ * tests/du/inaccessible-cwd: Ensure that even when run from an
+ inaccessible directory, du can still operate on accessible
+ directories elsewhere.
+ * tests/du/Makefile.am (TESTS): Add inaccessible-cwd.
+
+ * tests/rm/deep-1: Ensure that du can process a hierarchy
+ of depth 400 while using no more than 50KB of stack space.
+
+2003-10-01 Akim Demaille <akim@epita.fr>
+
+ * announce-gen (print_news_deltas): New function, extracted from main.
+ (main): Make `news_file' an array.
+ Use '...=s' => \@var for --news and --url-directory specs.
+ Before there were a couple of portability problems.
+
+2003-09-28 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (sc_cast_of_alloca_return_value): New rule.
+ (syntax-check-rules): Add it.
+
+ * src/copy.c: Remove unnecessary cast of alloca, since now it's
+ guaranteed to be (void *).
+ * src/cp.c: Likewise.
+ * src/join.c: Likewise.
+ * src/ln.c: Likewise.
+ * src/ls.c: Likewise.
+ * src/od.c: Likewise.
+ * src/sys2.h (ASSIGN_STRDUPA): Likewise.
+
+2003-09-27 Jim Meyering <jim@meyering.net>
+
+ Don't exhaust virtual memory when processing large inputs.
+ Fix this by removing csplit's internal free-list management;
+ instead rely on malloc for that.
+
+ * src/csplit.c (free_list): Remove global.
+ (clear_all_line_control): Remove function.
+ (get_new_buffer): Always use create_new_buffer to obtain a
+ new buffer, rather than searching free_list.
+ (free_buffer): Just call free.
+ Reported by Nikola Milutinovic.
+
+2003-09-26 Jim Meyering <jim@meyering.net>
+
+ * man/rm.x: Also list `chattr' in SEE ALSO section.
+ Suggestion from Mark Hubbart.
+
+2003-09-25 Jim Meyering <jim@meyering.net>
+
+ * configure.ac: Don't invoke AC_AIX or AC_MINIX explicitly, now
+ that we use gl_USE_SYSTEM_EXTENSIONS, since it AC_REQUIREs them.
+
+ * Use autoconf-2.57d. Regenerate dependent files.
+
+2003-09-24 Jim Meyering <jim@meyering.net>
+
+ Minor efficiency tweak.
+ * src/ln.c (PATH_BASENAME_CONCAT): Use memcpy rather than strcpy.
+ (do_link): Likewise.
+
+2003-09-23 Jim Meyering <jim@meyering.net>
+
+ * src/paste.c (paste_serial): Save errno after input error,
+ to report proper errno value.
+ Based on a patch from Paul Eggert.
+
+ * src/tee.c (tee): Adjust fwrite arguments so that the return
+ value is the number of bytes written.
+
+2003-09-16 Paul Eggert <eggert@twinsun.com>
+
+ Don't assume ferror sets errno. Bug reported by Bruno Haible.
+
+ * src/comm.c (compare_files): Save errno after input error,
+ to report proper errno value.
+ * src/fold.c (fold_file): Likewise.
+ * src/od.c (check_and_close, skip, read_char, read_block): Likewise.
+ * src/unexpand.c (unexpand): Likewise.
+
+ * src/csplit.c (close_output_file): Don't report bogus errno value
+ after ferror discovers an output error. We don't know the proper
+ errno value, since it might have been caused by any of a whole
+ bunch of calls, and it might have been trashed in the meantime.
+ Fixing this problem will require much more extensive changes;
+ in the meantime just say "write error".
+ * src/od.c (check_and_close, dump, dump_strings): Likewise.
+ * src/uniq.c (check_file): Likewise.
+
+ * src/join.c (get_line): Report error right away if I/O fails,
+ so that the proper errno value is used.
+ * src/tac.c (tac_seekable, tac_file, save_stdin): Likewise.
+ * src/tee.c (tee): Likewise.
+ * src/uniq.c (check_file): Likewise.
+
+ * src/od.c (skip): If a read fails, don't retry it later, so
+ that we report the proper errno.
+
+ * src/tac.c (tac_mem): Don't return a value; nobody uses it.
+
+ * src/tee.c (tee): Once a write failure has occurred, don't bother
+ writing anything more to that stream.
+
+ * src/uniq.c (check_file): Check for ferror (stdout) even if
+ ostream == stdout.
+
+ * src/yes.c (UNROLL): Remove.
+ (main): Exit immediately when write failure is detected.
+ Simplify code by assigning to argv when argc == 1.
+
+2003-09-21 Paul Eggert <eggert@twinsun.com>
+
+ * src/ptx.c: Switch encoding from Latin-1 to UTF-8.
+ (WRITTEN_BY): Change "Franc,ois" (actually using
+ c-with-cedilla in Latin-1) to "F.", so that it's ASCII, as
+ xgettext requires.
+
+2003-09-19 Jim Meyering <jim@meyering.net>
+
+ `du -D symlink-to-dir' would mistakenly omit the slash in
+ lines like this: 24 symlink-to-dir/subdir
+ * src/du.c (process_file): Fix offset calculation.
+ Reported by Jeff Sheinberg as Debian bug #211591;
+ http://bugs.debian.org/205251
+
+ * tests/du/deref-args: New file/test for the above.
+ * tests/du/Makefile.am (TESTS): Add deref-args.
+
+ * src/du.c (process_file): Remove useless disjunct.
+
+ * src/sys2.h (case_GETOPT_VERSION_CHAR): Rename parameter, Authors,
+ to Written_by.
+ * nearly all src/*.c files (WRITTEN_BY): Rename from AUTHORS.
+ Begin each WRITTEN_BY string with `Written by ' and end it with `.'.
+ Mark each WRITTEN_BY string as translatable.
+
+ * basename.c, cat.c, chroot.c, cksum.c, comm.c, cp.c, csplit.c, cut.c:
+ * dd.c, df.c, dirname.c, du.c, echo.c, env.c, expr.c, factor.c, head.c:
+ * hostid.c, hostname.c, id.c, link.c, ln.c, logname.c, ls.c, md5sum.c:
+ * mv.c, nice.c, nl.c, nohup.c, paste.c, pathchk.c, pinky.c, pr.c:
+ * printenv.c, printf.c, pwd.c, rm.c, setuidgid.c, sleep.c, sort.c:
+ * split.c, stty.c, sum.c, sync.c, tac.c, tail.c, tee.c, test.c:
+ * touch.c, tsort.c, uniq.c, unlink.c, uptime.c, users.c, wc.c:
+ * who.c, whoami.c, yes.c: Revert yesterday's changes.
+ Instead, a subsequent change will embed `Written by ' in
+ each string along with the author names.
+
+ * src/true.c: Revert yesterday's changes.
+ * src/sys2.h: Likewise.
+
+2003-09-18 Jim Meyering <jim@meyering.net>
+
+ * basename.c, cat.c, chroot.c, cksum.c, comm.c, cp.c, csplit.c, cut.c:
+ * dd.c, df.c, dirname.c, du.c, echo.c, env.c, expr.c, factor.c, head.c:
+ * hostid.c, hostname.c, id.c, link.c, ln.c, logname.c, ls.c, md5sum.c:
+ * mv.c, nice.c, nl.c, nohup.c, paste.c, pathchk.c, pinky.c, pr.c:
+ * printenv.c, printf.c, pwd.c, rm.c, setuidgid.c, sleep.c, sort.c:
+ * split.c, stty.c, sum.c, sync.c, tac.c, tail.c, tee.c, test.c:
+ * touch.c, tsort.c, uniq.c, unlink.c, uptime.c, users.c, wc.c:
+ * who.c, whoami.c, yes.c: Update AUTHORS definition to be a
+ comma-separated list of strings and/or update the call to
+ parse_long_options so that `AUTHORS, NULL' are the last parameters.
+ * src/true.c (main): Append NULL to version_etc argument list.
+ * src/sys2.h (case_GETOPT_VERSION_CHAR): Likewise.
+
+ * src/sort.c (numcompare): Rename local, logb, to log_b to avoid
+ shadowing the math function name. Also rename loga to log_a.
+
+2003-09-14 Jim Meyering <jim@meyering.net>
+
+ * src/factor.c (print_factors): Give a separate diagnostic
+ for numbers that are too large, but otherwise valid.
+ Reported by Dániel Varga.
+
+2003-09-10 Jim Meyering <jim@meyering.net>
+
+ * Use automake-1.7.7. Regenerate dependent files.
+
+ * tests/Makefile.am (all_programs): Use ../src/tr -s ' ' '\n' in place
+ of `fmt -1'. Using the just-built tr is a little cleaner.
+ Christian Krackowizer reported that HPUX 10.20 doesn't have fmt.
+ * man/Makefile.am (programs, check-x-vs-1): Likewise.
+
+2003-09-09 Jim Meyering <jim@meyering.net>
+
+ * src/copy.c: Alphabetize includes.
+ Remove duplicate inclusion of "same.h".
+
+2003-09-08 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (GZIP_ENV): Remove --rsyncable.
+ Didn't give enough of a benefit, mainly because it's not yet
+ in wide enough use.
+
+ * Version 5.0.91.
+
+ * man/Makefile.am (programs): Use ../src, not $(srcdir)/../src.
+ (check-programs-vs-x): Fail if $(programs) is empty.
+
+ * src/remove.c: Add a comment.
+
+2003-09-07 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (D_INO, ENABLE_CYCLE_CHECK) [D_INO_IN_DIRENT]:
+ Don't define. These symbols are no longer used.
+
+ * tests/misc/tty-eof: Write ^D as \cD.
+ Complete the change of 2003-08-02.
+
+ * Makefile.maint (po-check): Use cvsu, so that a temporary source
+ file in lib/ or src/ doesn't induce an unwarranted failure.
+ Add a kludge to filter out the sole generated source file that
+ also has translatable messages: src/false.c.
+
+2003-09-06 Jim Meyering <jim@meyering.net>
+
+ * src/tail.c (enum): Add ALLOW_MISSING_OPTION.
+ (parse_options): Give a diagnostic for (but still accept) the
+ deprecated --allow-missing option.
+
+2003-09-04 Paul Eggert <eggert@twinsun.com>
+
+ Don't ignore -S if input is a pipe. Bug report by Michael McFarland in
+ <http://mail.gnu.org/archive/html/bug-coreutils/2003-09/msg00008.html>.
+
+ * src/sort.c (sort_buffer_size): Omit SIZE_BOUND arg. Compute the
+ size_bound ourselves. if an input file is a pipe and the user
+ specified a size, use that size instead of trying to guess the
+ pipe size. This has the beneficial side effect of avoiding the
+ overhead of default_sort_size in that case. All callers changed.
+ (sort): Remove static var size; now done by sort_buffer_size.
+
+2003-09-05 Jim Meyering <jim@meyering.net>
+
+ * Use automake-1.7.6b and autoconf-2.57b. Regenerate dependent files.
+
+ * tests/tail-2/tail-n0f: Wait .5 seconds for backgrounded process
+ to start, rather than just .1. Upon failure, print unexpected state.
+
+2003-09-04 Paul Eggert <eggert@twinsun.com>
+
+ * src/head.c (elide_tail_lines_pipe): Don't assign 0 or
+ SAFE_READ_ERROR to tmp->nbytes.
+ * src/tail.c (pipe_lines, pipe_bytes): Likewise.
+
+ * src/head.c (struct linebuffer): Change nbytes and nlines
+ from unsigned int to size_t. unsigned int is safe (after the
+ 2003-09-03 patch) but size_t is cleaner.
+ * src/tail.c (struct linebuffer, struct charbuffer): Likewise.
+ (pipe_bytes): Likewise for local variable 'i', which was 'int'.
+
+ Standardize on BUFSIZ as opposed to other macro names and values.
+ * src/head.c (BUFSIZE): Remove. All uses changed to BUFSIZ.
+ * src/tail.c (BUFSIZ) [!defined BUFSIZ]: Remove.
+ stdio.h has always defined it,
+ and other code already assumes it's defined.
+ * src/tr.c (BUFSIZ) [!defined BUFSIZ]: Likewise.
+ (IO_BUF_SIZE): Remove; replace all uses with sizeof io_buf.
+ (io_buf): IO_BUF_SIZE -> BUFSIZ.
+
+2003-09-04 Paul Eggert <eggert@twinsun.com>
+
+ * src/seq.c (step): Default to 1.
+ (print_numbers): Allow the output to be empty.
+ (main): The default step is 1, even if LAST < FIRST;
+ as per documentation.
+ * tests/seq/basic (onearg-2): Output should be empty.
+
+2003-09-05 Jim Meyering <jim@meyering.net>
+
+ * Makefile.cfg (wget_files): Temporarily disable, until master
+ versions are restored to ftp.gnu.org.
+
+ * configure.ac (AM_INIT_AUTOMAKE): Specify automake-1.7.6.
+
+ Make seq's --width (-w) option work properly even when the
+ endpoint requiring the larger width is negative and smaller than
+ the other endpoint.
+ * src/seq.c (get_width_format): Include `-' in the set of bytes
+ allowed in a `simple' number (no decimal point, no exponent).
+ Reported by Patrick Mauritz.
+
+2003-09-02 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS: sort -t '\0' now uses a NUL tab.
+ sort option order no longer matters, unless POSIX requires it.
+ * src/sort.c (usage): Say "blanks" instead of "whitespace",
+ Similar fixes for many comments.
+ (TAB_DEFAULT): New constant, so that we can support NUL as
+ the field separator.
+ (tab): Now int, not char. Initialize to TAB_DEFAULT.
+ (specify_sort_size): If multiple sizes are specified, use the largest.
+ (begfield, limfield): Support NUL tab char.
+ (set_ordering): Do not let -i override -d.
+ (main): Report an error if incompatible -o or -t options are given.
+ Report an error for "-t ''". Allow "-t '\0'" to specify a NUL tab.
+
+2003-09-05 Jim Meyering <jim@meyering.net>
+
+ * tests/sort/Test.pm [o2, nul-tab]: New tests for the above.
+
+2003-09-03 Andreas Schwab <schwab@suse.de>
+
+ Bug report and patch here:
+ <http://mail.gnu.org/archive/html/bug-coreutils/2003-09/msg00009.html>
+ * src/tail.c (pipe_lines): Don't truncate return value from safe_read.
+ * src/head.c (elide_tail_lines_pipe): Likewise.
+
+2003-09-03 Jim Meyering <jim@meyering.net>
+
+ * src/du.c (AUTHORS): Remove Larry McVoy's name, since the relatively
+ small amount of code from him was first moved to lib/human.c, and was
+ subsequently rewritten entirely.
+ * src/df.c (AUTHORS): Likewise.
+
+2003-08-22 Lawrence Teo <lcteo@uncc.edu>
+
+ * src/md5sum.c (split_3): Accept the BSD format for generic
+ message digest modes. Currently works with BSD's MD5 and SHA1
+ formats since these are the two algorithms presently used in
+ coreutils. Updated comments to reflect this change.
+ (bsd_split_3): Updated comments.
+
+ * tests/md5sum/basic-1: New test to make sure that
+ `md5sum --check' doesn't accept the BSD SHA1 format (adapted
+ from `check-bsd' test in tests/sha1sum/basic-1).
+
+ * tests/sha1sum/basic-1 (check-bsd2, check-bsd3): New tests for
+ --check exit status and BSD SHA1 format (adapted from tests
+ in tests/md5sum/basic-1).
+
+2003-08-30 Jim Meyering <jim@meyering.net>
+
+ * src/ln.c (do_link): Use SAME_INODE rather than open-coding it.
+
+ When source and destination arguments refer to the same file, reside
+ on a partition (e.g. VFAT) on which distinct names may refer to the
+ same directory entry (often due to variations in case), and when the
+ link count for the file is 1, mv no longer unlinks the file. Instead,
+ it gives the expected diagnostic that the source and destination are
+ the same. WARNING: this is an incomplete fix. If the file happens
+ to have a link count of 2 or greater, such an erroneous mv command
+ will still unlink it.
+ Although that is not possible on vfat or umsdos, it is possible on
+ other file system types, e.g., ntfs, and hpfs.
+ * src/copy.c (same_file_ok): Invoke same_name (which might still
+ return false for names that refer to the same directory entry)
+ only if the link count is 2 or more.
+ * tests/mv/vfat: Show how to demonstrate the above problem.
+ This test is not run.
+ * tests/mv/Makefile.am (EXTRA_DIST): Add vfat.
+
+2003-08-27 Jim Meyering <jim@meyering.net>
+
+ * src/who.c: Change meaning of -l from --lookup to --login, per POSIX.
+ who's -l option has been eliciting an unconditional warning about
+ this impending change since sh-utils-2.0.12 (April 2002).
+
+ * src/paste.c (paste_parallel): Don't output `EOF' (aka -1) as a `char'.
+ This would happen for nonempty files not ending with a newline.
+ Reported by Dan Jacobson.
+ * tests/misc/paste-no-nl: New file. Test for above-fixed bug.
+ * tests/misc/Makefile.am (TESTS): Add paste-no-nl.
+
+ * src/stat.c (print_it): Avoid buffer overrun that would
+ occur when the user-specified format string ends with `%'.
+ Patch by Tommi Kyntola.
+ * tests/misc/stat-fmt: New file. Test for above-fixed bug.
+ * tests/misc/Makefile.am (TESTS): Add stat-fmt.
+
+2003-08-26 Jim Meyering <jim@meyering.net>
+
+ Apply changes from bison.
+ * GNUmakefile (SHELL): Define to `sh', if necessary.
+ Add copyright.
+ * Makefile.maint (WGETFLAGS): Define to `-C off'.
+ Update all uses of $(WGET).
+
+2003-08-22 Akim Demaille <akim@epita.fr>
+
+ * Makefile.cfg (local-checks-to-skip): New.
+ * Makefile.maint (local-check): Rename as...
+ (local-checks-available): this.
+ (local-check): New.
+
+2003-08-26 Akim Demaille <akim@epita.fr>
+
+ * announce-gen (print_changelog_deltas): Neutralize "<#" as
+ "<\#" to avoid magic from Gnus when posting parts of this script.
+
+2003-08-25 Jim Meyering <jim@meyering.net>
+
+ * src/stat.c (main): Warn about use of deprecated `-l' option.
+
+2003-08-22 Jim Meyering <jim@meyering.net>
+
+ * src/stat.c (do_stat): For link count at end of line, use %h format,
+ instead of %-5h. The latter would make stat emit trailing spaces.
+ Reported by Dan Jacobson.
+
+2003-08-20 Jim Meyering <jim@meyering.net>
+
+ * Makefile.am (EXTRA_DIST): Add .x-sc_space_tab .x-sc_sun_os_names
+
+2003-08-19 Jim Meyering <jim@meyering.net>
+
+ * src/system.h: Include stdlib.h unconditionally,
+ as we're now assuming that part of hosted C89.
+
+2003-08-18 Jim Meyering <jim@meyering.net>
+
+ * src/sys2.h (textdomain, bindtextdomain) [! ENABLE_NLS]: Define away,
+ to avoid warnings from gcc.
+
+2003-08-17 Jim Meyering <jim@meyering.net>
+
+ Avoid unnecessary and sometimes time-consuming hostname lookups.
+ * src/who.c (print_user): Use strchr, not strrchr.
+ * src/pinky.c (print_entry): Likewise.
+ Patch by Michael Stone.
+ This fixes a typo I introduced in who-users.c on 1996-02-23.
+
+ * Makefile.maint (makefile-check): Add 0-9 to the range of characters
+ disallowed between `@...@'.
+
+2003-08-16 Paul Eggert <eggert@twinsun.com>
+
+ * configure.ac (fu_cv_sys_truncating_statfs): Remove; now
+ done by gnulib .m4 files.
+ (jm_DUMMY_1): Require gl_READUTMP, not jm_PREREQ_READUTMP.
+ * src/sys2.h (strtoull): Remove unused declaration.
+
+2003-08-16 Jim Meyering <jim@meyering.net>
+
+ * man/Makefile.am (.x.1): Ensure that generated PROGRAM.1 files
+ are read-only.
+
+ * src/tail.c (tail_lines): Fix a potential (but very hard to exercise)
+ race condition bug. The bug would be triggered when tailing a file
+ with file pointer not at beginning of file, and where the file was
+ truncated to have a length of less than the initial offset at just
+ the right moment (between the two lseek calls in this function).
+
+ An invalid initial value for *read_pos would result in
+ `tail -n0 -f FILE' and `tail -c0 -f FILE' doing what amounted to a
+ busy-wait rather than sleeping between iterations. The bug manifests
+ itself only when tailing regular files that are initially nonempty.
+ * src/tail.c (tail_bytes): Set *read_pos to new file offset after
+ each xlseek call.
+ (tail_lines): Likewise, after lseek calls.
+ Reported by Nick Estes. See http://bugs.debian.org/205251 for details.
+ * tests/tail-2/tail-n0f: New file. Test for above fix.
+ * tests/tail-2/Makefile.am (TESTS): Add tail-n0f.
+
+2003-08-15 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (sc_space_tab): Use exclusion list in separate file.
+ (sc_sun_os_names): Likewise.
+ * .x-sc_space_tab, .x-sc_sun_os_names: New files.
+
+ * man/help2man: Remove some SPACEs before TAB.
+
+2003-08-14 Paul Eggert <eggert@twinsun.com>
+
+ * Makefile.maint (LC_ALL): Set to C.
+ * man/Makefile.am (ASSORT): New var.
+ (check-x-vs-1, programs): Use it.
+ * src/Makefile.am (ASSORT, check-README, ../AUTHORS): Likewise.
+ * tests/Makefile.am (ASSORT, all_programs): Likewise.
+
+2003-08-11 Jim Meyering <jim@meyering.net>
+
+ fold -s -wN would infloop for N < 8 with TABs in the input.
+ E.g., this would not terminate: printf 'a\tb' | fold -w2 -s
+ * src/fold.c (fold_file): Move contents of `else'-block
+ out of conditional so it's used also for --spaces (-s).
+ * tests/misc/fold: Test for the above fix.
+ * tests/misc/Makefile.am (TESTS): Add fold.
+
+2003-08-10 Jim Meyering <jim@meyering.net>
+
+ * src/nice.c [!NICE_PRIORITY]: Include <sys/resource.h> after
+ system.h so the types from time.h and sys/time.h are available.
+ It appears that this is necessary for OpenBSD, NetBSD, and
+ Darwin 6.5 (MacOS 10.2.5). Reported by Nelson Beebe.
+
+2003-08-06 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS: Add support for setting file timestamps to microsecond
+ resolution, on hosts that support this.
+ * src/copy.c, src/cp.c, src/install.c, src/touch.c: Include utimens.h.
+ * src/copy.c (copy_internal):
+ Set file timestamps with utimens, not utime.
+ * src/cp.c (re_protect): Likewise.
+ * src/install.c (change_timestamps): Likewise.
+ * src/touch.c (newtime, touch, main): Likewise.
+
+2003-08-09 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (sc_sun_os_names): New rule based on a regexp
+ from Paul Eggert.
+ (syntax-check-rules): Add it.
+
+ * src/tail.c (main): Tweak Solaris OS version number in comment.
+ * src/wc.c (wc): Likewise
+ * tests/tail-2/fflush: Likewise.
+
+ * src/tail.c: Add new undocumented option, --presume-input-pipe.
+ (pipe_lines): Use memchr to skip lines, rather than an explicit loop.
+
+2003-08-08 Paul Eggert <eggert@twinsun.com>
+
+ Use new gnulib 'extensions' module.
+ * configure.ac: Invoke gl_USE_SYSTEM_EXTENSIONS instead of
+ AC_GNU_SOURCE.
+
+2003-08-08 Paul Eggert <eggert@twinsun.com>
+
+ * tests/du/basic: Ensure that a/b/F has at least 65 bytes too.
+
+2003-08-09 Jim Meyering <jim@meyering.net>
+
+ * tests/misc/split-fail: Reflect that `split -a 0' is now accepted.
+ For tests of obsolete behavior, don't presume that unsetting
+ _POSIX2_VERSION is equivalent to _POSIX2_VERSION=199209.
+
+2003-08-07 Paul Eggert <eggert@twinsun.com>
+
+ * doc/coreutils.texi (split invocation):
+ Add -d or --numeric-suffixes option to 'split'.
+ From a suggestion by Jesse Kornblum.
+ * src/split.c (suffix_alphabet): New var.
+ (longopts, usage, next_file_name, main): Support -d.
+ (next_file_name, main): Allow -a0, as POSIX requires.
+ (next_file_name): Don't assume ASCII-like encoding;
+ 'a' through 'z' are not contiguous in EBCDIC.
+
+2003-08-05 Paul Eggert <eggert@twinsun.com>
+
+ Merge getline from gnulib.
+ * lib/getline.h, lib/getline.c, m4/getline.m4: Merge from gnulib.
+ * lib/getndelim2.h, lib/getndelim2.c, m4/getndelim2.m4, m4/ssize_t.m4:
+ New files, from gnulib.
+ * lib/getdelim2.c, lib/getdelim2.h: Remove.
+ * lib/Makefile.am (libfetish_a_SOURCES): Change getdelim2.c and
+ getdelim2.h to getndelim2.c and getndelim2.h.
+ * m4/jm-macros.m4 (jm_MACROS): Use gl_GETNDELIM2 rather than
+ checking for getdelim.
+ (jm_CHECK_ALL_TYPES): Use gt_TYPE_SSIZE_T for ssize_t rather
+ than rolling our own.
+ * src/cut.c: Include getndelim2.h rather than getdelim2.h.
+ (cut_fields): Invoke getndelim2 rather than getdelim2.
+
+2003-08-04 Jim Meyering <jim@meyering.net>
+
+ * src/sort.c (main): Use unsigned int instead of int for `nsigs'
+ and for the indices to iterate through nsigs.
+
+2003-08-02 Paul Eggert <eggert@twinsun.com>
+
+ * src/sort.c: Minor code cleanups, mostly to use more accurate
+ types and to remove unnecessary casts.
+ (min, max): Remove. All uses changed to MIN and MAX.
+ (hard_lc_collate, hard_LC_TIME, struct buffer.eof, struct
+ keyfield.skipsblanks, struct keyfield.skipeblanks, struct
+ keyfield.numeric, struct keyfield.general_numeric, struct
+ keyfield.month, struct keyfield.reverse, reverse, unique,
+ have_read_stdin): Now bool, not int. All uses changed.
+ (eolchar): Now char, not int.
+ (struct keyfield.ignore): Now bool const *, not int *.
+ (struct keyfield.translate): Now char const *, not char *.
+ (struct month.name): Likewise.
+ (blanks, nonprinting, nondictionary): Now bool[], not int[].
+ (cleanup, inittables, keycompare, check, mergefps, first_same_file,
+ check, sort, main): Use const * pointers when possible.
+ (month_cmp): Rewrite to avoid casts.
+ (inittables): Initialize tables unconditionally, to avoid branches.
+ (fillbuf): Return bool, not int. All uses changed.
+ (fillbuf, keycompare, new_key, main):
+ Use SIZE_MAX rather than (size_t) -1.
+ (trailing_blanks): Renamed from trim_trailing_blanks.
+ Return the number of blanks to trim. All uses changed.
+ (getmonth): Use trailing_blanks rather than open code.
+ (keycompare): Do not cast char * to unsigned char *; not needed.
+ CMP_WITH_IGNORE converts args to UCHAR, so no need to convert it
+ ourselves.
+ (compare, main): Use | rather than || to avoid jumps.
+ Replace "diff = NONZERO (alen)" with "diff = 1", since alen must
+ be nonzero there.
+ (check, first_same_file, sort, main):
+ Use bool instead of int local vars when possible.
+ (check): Merge the old 'checkfp' and 'check' into a single function,
+ that returns a boolean (true if the file was ordered).
+ All uses changed.
+ (main): Use int instead of unsigned for iterating through nsigs.
+ Rename local var "posix_pedantic" to "posixly_correct".
+
+2003-08-02 Jim Meyering <jim@meyering.net>
+
+ * src/nice.c [!NICE_PRIORITY]: Include <time.h> before <sys/resource.h>
+ to avoid compilation error on Ultrix. Reported by Christian Krackowizer.
+
+ * src/cut.c (cut_fields): Don't read again after encountering an
+ initial EOF. E.g., `cut -f2' would do so.
+ * tests/misc/tty-eof: Add a test for the above fix.
+
+ * src/sort.c (sortlines): Add description and references.
+ From Paul Eggert.
+
+ * tests/Makefile.am (TESTS_ENVIRONMENT): Set PATH so that
+ the tests in help-version will use the just-built binaries.
+ Reported by Christian Krackowizer.
+
+2003-07-31 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS: Add --rfc-2822 option to GNU date.
+ * doc/coreutils.texi (Time directives, Options for date, Examples
+ of date): Likewise.
+ * src/date.c (long_options, usage, main): Likewise.
+ * doc/getdate.texi (General date syntax): Likewise.
+ * doc/coreutils.texi (Options for date): Fix a typo in format:
+ it's now %d not %_d. Add URLs.
+
+2003-08-01 Jim Meyering <jim@meyering.net>
+
+ * tests/shred/remove: Ensure that $? is 0 for the final `exit 0'.
+ Otherwise, with at least the /bin/sh from HPUX 10.20,
+ the trap code would end up converting that to exit 1 and thus an
+ unexpected test failure. Reported by Christian Krackowizer.
+
+2003-07-31 Paul Eggert <eggert@twinsun.com>
+
+ * src/ptx.c: Do not include bumpalloc.h.
+ (WORD_TABLE): New member alloc.
+ (ALLOC_NEW_WORD): Remove.
+ (occurs_alloc): New var.
+ (digest_word_file, find_occurs_in_text): Check for arithmetic
+ overflow when computing table size. Use xrealloc rather than
+ bumpalloc primitives.
+
+2003-07-29 Jim Meyering <jim@meyering.net>
+
+ * Version 5.0.90.
+
+ * README: When running tests as root, suggest using
+ sudo with NON_ROOT_USERNAME=$USER.
+
+ * tests/Makefile.am (all_programs): Makefile is in ../src, not
+ $(srcdir)/../src.
+
+2003-07-28 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (GZIP_ENV): Try Debian/gzip's new --rsyncable option.
+
+2003-07-28 Paul Eggert <eggert@twinsun.com>
+
+ * lib/stdbool.hin (_Bool): Make it signed char, instead of
+ an enum type, so that it's guaranteed to promote to int.
+ * src/sort.c (sortlines_temp): Undo previous change.
+
+2003-07-28 Jim Meyering <jim@meyering.net>
+
+ * src/sort.c (sortlines_temp): Declare local `swap' to be `int', not
+ `bool'. Otherwise, at least one buggy compiler (alpha gcc-2.95.4)
+ would cause lines[-1 - swap] (with swap = false) to evaluate to
+ lines[4294967295].
+
+2003-07-27 Jim Meyering <jim@meyering.net>
+
+ * tests/priv-check (my_uid): Use `!', not `^' in case pattern `[!0-9]',
+ since /bin/sh of at least NetBSD 1.6 and OpenBSD 3.2 don't accept `^'.
+
+ * src/remove.c (prompt) [! recursive]: Don't prompt about unwritable
+ directories, as required by POSIX. Reported by Karl Berry.
+ * tests/rm/dir-no-w: New file. Test for the above fix.
+ * tests/rm/Makefile.am (TESTS): Add dir-no-w.
+
+ * tests/mk-script: Emit `$xx', not its expansion.
+
+2003-07-27 Paul Eggert <eggert@twinsun.com>
+
+ This change was inspired by a similar proposal by Stepan Kasal.
+ * src/sort.c (mergelines, sortlines_temp): New functions.
+ (sortlines): Use them, to reduce the number of times that
+ we need to copy 'struct line' values. This improved CPU
+ performance by about 30% on one 18 MB test.
+ (sort): Don't invoke sortlines unless we have 2 or more lines.
+
+2003-07-26 Stepan Kasal <kasal@ucw.cz>
+
+ * src/sort.c (sort): Don't require two `struct line's per text line,
+ the new sort algorithm requires just 1.5.
+
+2003-07-27 Jim Meyering <jim@meyering.net>
+
+ * src/pathchk.c (validate_path): Use %lu, not %ld.
+ From Paul Eggert.
+ * src/cut.c (is_printable_field): Simplify bit arithmetic.
+ From Paul Eggert.
+ * src/ls.c (sort_files): Put `volatile' in the right place.
+ From Paul Eggert.
+
+2003-07-26 Jim Meyering <jim@meyering.net>
+
+ Use only one bit per field/offset in array, not one `int'.
+ * src/cut.c (printable_field): Change type to `unsigned char'.
+ (mark_printable_field, is_printable_field): New functions.
+ Use them in place of all direct accesses of `printable_field'.
+
+ * src/expand.c (parse_tabstops): Detect overflow properly.
+ * src/cut.c (set_fields): Likewise.
+
+ * src/rm.c: Include "dirname.h".
+ (usage): Use base_name (program_name) in body of --help output.
+ This lets me...
+ * man/Makefile.am (.x.1): ...back out the kludge of 2003-07-22.
+ Idea from Brendan O'Dea, who suggested using
+ `program_name = basename (argv[0]);' everywhere --
+ can't do that, but using base_name works just fine here.
+
+ * src/Makefile.am (AM_INSTALLCHECK_STD_OPTIONS_EXEMPT): Exempt test.
+
+2003-07-24 Paul Eggert <eggert@twinsun.com>
+
+ Fix some POSIX-compliance problems with 'test'. This makes
+ 'test' more compatible with Bash.
+
+ * NEWS, doc/coreutils.texi: Document the following.
+ * src/test.c: Include exitfail.h.
+ (TEST_FAILURE): New constant, used for exit status if 'test' fails.
+ (test-syntax_error): Use it.
+ (binary_operator): Now takes bool arg specifying whether left operand
+ is -l ARG, so that caller determines this rather than us.
+ All uses changed.
+ (term): Use posixtest to evaluate parenthesized subexpressions.
+ (unary_operator, one_argument): Remove support for -t without operand.
+ (one_argument): Take argument from argv[pos].
+ (one_argument, two_arguments, three_arguments): Advance pos.
+ All callers changed.
+ (three_arguments): Look for binary ops before "!". Then look
+ for parenthesized one_argument expressions, instead of trusting
+ expr () to do the right thing.
+ (posixtest): Now takes number of args. All callers changed.
+ Treat "( A B )" like "A B".
+ (main): Set exit_failure to TEST_FAILURE. Don't depend on
+ POSIXLY_CORRECT, as we now conform to POSIX by default.
+ (main) [!LBRACKET]: Do not recognize "--help" or "--verbose" unless.
+ * tests/test/Test.pm (test_vector): Add several tests to check
+ the above. Syntax errors now exit with status 2, not 1.
+ * man/Makefile.am (mapped_name): Use `../src/[' binary to create test.1.
+
+2003-07-26 Jim Meyering <jim@meyering.net>
+
+ * tests/help-version: Adjust for above change in test behavior:
+ `[' exits with 2, not 1, and test doesn't accept --help or --version.
+
+ * Makefile.maint (ME): Don't use trick suggested in Make manual.
+ It doesn't work for make-3.79.1. Reported by Christian Krackowizer.
+
+ * Makefile.maint (sc_system_h_headers): Another syntax check.
+ (syntax-check-rules): Add it to the list.
+
+ * src/pathchk.c (validate_path): Cast strlen value to `unsigned long'
+ so it matches `%ld' format even on 32-bit systems.
+
+ * src/fmt.c (flush_paragraph): Cast field width to `int' to
+ avoid warning on 64-bit systems.
+
+ * src/ls.c (sort_files): Make `func' volatile, so it can't be
+ clobbered by a `longjmp' into this function.
+
+2003-07-25 Jim Meyering <jim@meyering.net>
+
+ * src/pathchk.c (validate_path): Use %ld format (not %d) for size_t
+ value.
+
+ * tests/misc/split-fail: Disable the --line-bytes=$_4gb test,
+ because it'd evoke spurious failure on 64-bit systems.
+
+2003-07-24 Jim Meyering <jim@meyering.net>
+
+ * src/dd.c (usage): Document the fact that SIGUSR1 makes dd
+ output its current record counts. Reported by Jurriaan.
+
+ * tests/wc/Test.pm (test_vector): Disable the `PIPE' tests when running
+ `wc' with no options. This goes along with the change of 2003-07-20.
+
+2003-07-23 Jim Meyering <jim@meyering.net>
+
+ Don't include headers already included by system.h:
+ * src/tr.c: Don't include errno.h.
+ * src/true.c: Don't include version-etc.h.
+ * src/test.c: Don't include limits.h or error.h.
+ * src/stat.c: Don't include unistd.h or time.h.
+ * src/readlink.c: Don't include stdlib.h, unistd.h, or limits.h.
+ * src/pr.c: Don't include time.h.
+ * src/pathchk.c: Don't include errno.h.
+ * src/nice.c: Don't include sys/time.h.
+ * src/ls.c: Don't include stdlib.h.
+
+ * basename.c, cat.c, chroot.c, cksum.c, comm.c, csplit.c, cut.c, date.c:
+ * dd.c, dirname.c, echo.c, env.c, expand.c, expr.c, factor.c, fmt.c:
+ * fold.c, head.c, hostid.c, hostname.c, id.c, join.c, kill.c, logname.c:
+ * md5sum.c, nice.c, nl.c, nohup.c, od.c, paste.c, pathchk.c, pinky.c:
+ * pr.c, printenv.c, printf.c, ptx.c, pwd.c, seq.c, setuidgid.c, shred.c:
+ * sleep.c, sort.c, split.c, stat.c, stty.c, su.c, sum.c, tac.c, tail.c:
+ * tee.c, test.c, tr.c, true.c, tsort.c, tty.c, uname.c, unexpand.c:
+ * uniq.c, uptime.c, users.c, wc.c, who.c, whoami.c, yes.c:
+ Don't include closeout.h.
+
+ * tests/rm/fail-2eperm: Add a check for whether $NON_ROOT_USERNAME
+ can access the required version of rm.
+ * tests/rm/Makefile.am (TESTS_ENVIRONMENT): Define PACKAGE_VERSION.
+
+ * tests/cut/Test.pm (out-delim3a): New test.
+
+ * man/help2man: Update to version 1.33.
+
+ * src/expand.c (parse_tabstops): Detect overflow in tabstop sizes.
+
+ * src/dircolors.c: Include xstrndup.h.
+ (xstrndup): Remove function, now that it's been factored out into
+ it's own file.
+
+2003-07-22 Paul Eggert <eggert@twinsun.com>
+
+ * src/wc.c (wc): Fix typo in computation of file from file_x,
+ which caused the former to be used uninitialized if file_x was
+ nonzero.
+
+2003-07-22 Jim Meyering <jim@meyering.net>
+
+ * src/cut.c (set_fields): Use xcalloc in place of xmalloc+memset.
+
+ * man/Makefile.am (.x.1): Substitute 's,$t/$*,$*,' on output of
+ help2man, to avoid having `rm.td/rm' appear in rm.1. Reported by
+ Thomas Luzat. See http://bugs.debian.org/202413 for details.
+
+ * src/cut.c (main) [lint]: Initialize spec_list_string to avoid warning.
+
+ * src/hostid.c: Don't include <unistd.h>. system.h already does that.
+
+ * src/cut.c (set_fields): Mark all selected indices before trying to
+ determine range endpoints.
+ * tests/cut/Test.pm: New test for the above fix.
+
+ Begin to address this comment: What if someone wants to
+ extract the 1,000,000-th field of some huge input file?
+ The first step is to rearrange things so that the values
+ in the printable_field array are all 0/1 rather than 0/1/2.
+ * src/cut.c (RANGE_START_SENTINEL): Remove.
+ Store range-start indices in a hash table, rather than
+ overloading the `printable_field' array.
+ (range_start_ht): New global.
+ (hash_int, hash_compare_ints, is_range_start_index): New functions.
+ (print_kth): Use is_range_start_index; don't test printable_field.
+ (set_fields): Detect overflow.
+ (set_fields): Insert each range-start index into range_start_ht.
+ (main): Call set_fields only once, and only after
+ output_delimiter_specified and (if required) range_start_ht have
+ been defined.
+
+2003-07-20 Paul Eggert <eggert@twinsun.com>
+
+ * src/wc.c (get_input_fstatus): Fix typo: `stat' was being
+ invoked with a null pointer when there were no file arguments.
+
+2003-07-20 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (sc_changelog): Add another nit-picky check.
+
+ * src/wc.c (write_counts): Add a comment.
+ (wc): Rename `file' parameter.
+ Set new local, `file', to be the file name, or (when it's NULL)
+ _("standard output") so that all uses of `file' use the proper value.
+ Use STREQ, not strcmp.
+
+2003-07-20 Paul Eggert <eggert@twinsun.com>
+
+ wc count field widths now are heuristically adjusted depending
+ on the input size, if known. If only one count is printed, it
+ is guaranteed to be printed without leading spaces.
+
+ Previously, wc did not align the count fields if
+ POSIXLY_CORRECT was set, but POSIX did not actually require
+ this undesirable behavior, so it has been removed.
+
+ * NEWS: Document this.
+ * doc/coreutils.texi (wc invocation): Likewise.
+
+ * src/wc.c (number_width): New var.
+ (posixly_correct): Remove.
+ (struct fstatus): New struct.
+ (write_counts): Output fields of width number_width.
+ Do not worry about POSIXLY_CORRECT.
+ Use null file, not empty-string file, to denote stdin,
+ since "" is a valid file name on some hosts.
+ (wc, wc_file): New arg fstatus. Use it to avoid invoking fstat
+ if possible.
+ (wc): Avoid problems if end_pos - current_pos overflows.
+ Do not print odd message if stdin has a read error.
+ (get_input_fstatus, compute_number_width): New functions.
+ (main): Use them to implement the new behavior.
+ Ignore POSIXLY_CORRECT.
+
+ * tests/wc/Test.pm: Adjust to the new output widths.
+
+2003-07-19 Jim Meyering <jim@meyering.net>
+
+ * tests/rm/fail-eperm: Don't create temporary directory --
+ we don't use it.
+
+ * tests/shred/remove: Don't open-code test for UID != 0.
+ Use priv-check's require-non-root instead.
+ Update to use newer framework.
+
+ * tests/help-version (expected_failure_status_expr): Record that
+ expr exits with status of 3 for e.g., a write error.
+
+ * tests/priv-check: Use `id -u' to see if we're running as root,
+ rather than trying go write to an write-protected file.
+ When running as root, ensure $NON_ROOT_USERNAME is valid.
+ When running as root with `require-non-root', ensure that `.'
+ is writable by $NON_ROOT_USERNAME, then reinvoke $0 set-user-ID
+ to $NON_ROOT_USERNAME. If `.' is not writable, then skip the test.
+
+ * src/printenv.c: Include "exitfail.h".
+ (main): Set exit_failure rather than calling close_stdout_set_status.
+ * src/date.c: Likewise.
+ * src/sort.c: Likewise.
+ * src/tty.c: Likewise.
+
+2003-07-18 Jim Meyering <jim@meyering.net>
+
+ * tests/touch/not-owner: Update to use newer framework.
+
+ * tests/rm/fail-eperm: Use $srcdir/../priv-check, create a temporary
+ directory, and remove Perl-coded `you may not run as root' test.
+ * tests/cp/fail-perm: Use $srcdir/../priv-check, rather than
+ hard-coding something not quite equivalent.
+ Paul Jarc reported the inconsistent diagnostics.
+
+ * src/sort.c (main): Use close_stdout via atexit.
+ Now `sort --version' and `sort --help' fail, as they should
+ when their output is redirected to /dev/full.
+
+ * src/su.c (usage): Don't call close_stdout here.
+ (main): Use close_stdout via atexit.
+ Now `su --version > /dev/full' fails, as it should.
+ Somehow, the change of 2000-05-07 that purports to fix this
+ was not checked in.
+
+ * tests/help-version (--help/--version vs. /dev/full): Special-case
+ `[' to protect it from expected_failure_status-`eval'.
+
+ * src/uniq.c (writeline): Use a SPACE, not a TAB between the
+ count and the corresponding line, as required by POSIX.
+ Reported by Clement Wang.
+ * tests/uniq/Test.pm (101, 102): Update tests of -c accordingly.
+
+ * tests/expr/basic: Add tests for when exit status is 2.
+
+ * src/nohup.c (NOHUP_FOUND_BUT_CANNOT_INVOKE, NOHUP_FAILURE):
+ Use an anonymous `enum', rather than #define.
+
+2003-07-17 Paul Eggert <eggert@twinsun.com>
+
+ * src/expr.c: Include "exitfail.h", "quotearg.h".
+ (EXPR_INVALID, EXPR_ERROR): New constants.
+ (nomoreargs, null, toarith, nextarg): Return bool, not int.
+ (syntax_error): New function, exiting with status 2. Use it
+ insteading of printing "syntax error" ourselves.
+ (main): Initialize exit_failure to EXPR_ERROR.
+ Exit with EXPR_INVALID on syntax error (too few arguments).
+ (nextarg): Use strcmp, not strcoll; strcoll might return
+ an undesirable 0, or might fail.
+ (docolon, eval4, eval3): Exit with status 3 on invalid argument type
+ or other such error.
+ (eval2): Report an error if strcoll fails in a string comparison.
+ * src/sort.c: Include "exitfail.h".
+ (main): Set exit_failure, not xalloc_exit_failure and
+ xmemcoll_exit_failure.
+ * tests/expr/basic: Invalid value exits with status 3, not 2.
+
+2003-07-16 Jim Meyering <jim@meyering.net>
+
+ * configure.ac (AC_INIT): Use 5.0.90 as the version, rather than 5.0.2,
+ per GNU maintainer guidelines. The next non-beta release will be 5.1.
+
+ This script would have caught at least two recent bugs:
+ those in [ and kill.
+ * tests/help-version: Revive this script.
+ It wasn't doing anything useful, since $all_programs wasn't being
+ defined by the invoking Makefile.am.
+ Reflect that nohup is no longer a script, so don't exclude it.
+ Add framework to handle the programs added since it was last run:
+ kill, stat, unlink, [, link, readlink.
+ Fix path-related problems deriving from the move of this script
+ from src/ to its present location.
+ * tests/Makefile.am (all_programs): Define.
+ (TESTS_ENVIRONMENT): Use it.
+
+ * src/kill.c (main): Fix bug introduced on 2003-05-10 (for 5.0.1)
+ whereby kill would always attempt to operate on argv[0] and fail.
+
+ * src/test.c (integer_expected_error): Improve diagnostic -- now,
+ it also matches the one from bash's builtin test.
+ (binary_operator): Add \n at end of diagnostic.
+
+ * tests/rm/fail-2eperm: Remove setuidgid-related code. Move it to ...
+ * tests/priv-check: Move setuidgid-related and
+ NON_ROOT_USERNAME-checking code to this file.
+
+ * README: Update section on testing as `root'.
+ Suggestion from Paul Jarc.
+
+ * src/test.c (AUTHORS): Replace 3-letter usernames with the actual
+ names of authors that I just found in bash's builtins/test.def.
+
+ Running `[' with no arguments would evoke a segfault.
+ * src/test.c (main) [LBRACKET]: Move initialization of argv to
+ precede potential use via test_syntax_error.
+
+ * src/Makefile.am (AM_CPPFLAGS): Rename from `INCLUDES', to avoid
+ warning from automake -Wall.
+
+2003-07-15 Jim Meyering <jim@meyering.net>
+
+ * Version 5.0.1.
+
+ * Makefile.maint (%.asc): Remove target first, so gpg doesn't
+ prompt us about it.
+
+ * announce-gen (print_changelog_deltas): Relax tests for matching
+ version-number line in NEWS.
+ Change the .sig suffix to .asc here, too.
+
+2003-07-14 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (%.asc): Renamed from %.sig.
+ Generate and use ascii-armored signatures.
+ Use gpg's -o option.
+
+2003-07-13 Jim Meyering <jim@meyering.net>
+
+ * src/nohup.c (NOHUP_FAILURE, NOHUP_FOUND_BUT_CANNOT_INVOKE): Define.
+ (main): Use them.
+
+ * Makefile.maint (syntax-check): Move each individual check into
+ its own target.
+ (syntax-check-rules): This is the list of syntax-check targets.
+ (sc_unmarked_diagnostics, sc_cast_of_argument_to_free):
+ (sc_cast_of_x_alloc_return_value, sc_space_tab):
+ (sc_error_exit_success, sc_xalloc_h_in_src): New targets.
+
+2003-07-12 Jim Meyering <jim@meyering.net>
+
+ * configure.ac: Remove uses of OPTIONAL_BIN_ZCRIPTS and last
+ traces of the nohup script.
+
+ * src/Makefile.am (bin_SCRIPTS): Remove use of just-removed
+ $(OPTIONAL_BIN_ZCRIPTS).
+
+ * src/Makefile.am (localedir.h): Put the `2>&1' after the redirect
+ target, not before the `>'.
+
+ * src/remove.c (remove_dir): Give a diagnostic upon failed save_cwd,
+ now that that function no longer calls `error'.
+
+ * src/df.c (find_mount_point): Emit a diagnostic for each
+ failed syscall, rather than relying on caller to do that.
+ The caller couldn't do a good job, anyhow -- too many different
+ ways to fail (each with a different referent).
+ Give a diagnostic upon failed save_cwd, now that that function
+ no longer calls `error'.
+ (show_point): Don't diagnose find_mount_point's errors, now that
+ it handles them itself.
+
+ * src/df.c (find_mount_point): Don't let free clobber errno upon
+ failed chdir.
+
+ * src/sys2.h: Remove alloca-related block.
+ * src/system.h: Include <alloca.h> here, instead.
+
+ It appears that the `#pragma alloca' included via "system.h" is
+ adequate, since join.c uses alloca, yet lacked an in-file #pragma.
+ * src/copy.c, src/cp.c, src/df.c, src/install.c, src/ln.c:
+ * src/ls.c, src/mv.c, src/remove.c: Remove `#pragma alloca'.
+
+ * src/chown-core.c (change_file_owner): Do not restore any special
+ permission bits (e.g., set-user-ID, set-group-ID) that are reset
+ by chown(2) on some systems. Suggestion and insistence :-) from
+ Michael Stone.
+
+ * tests/input-tty: Also check `test -t 1'.
+ This is necessary on linux-2.4.21. Otherwise, the stty/basic-1
+ test would block when run in the background.
+
+2003-07-11 Jim Meyering <jim@meyering.net>
+
+ * tests/sample-test: Also fail if cat-to-create-expected-output
+ fails. Otherwise, if both `exp' and `out' were to end up empty
+ because of e.g., a full disk, they would mistakenly compare equal.
+
+ * src/nohup.c: New file. Rewrite of nohup.sh in C.
+ This solves a portability problem: on at least Solaris systems,
+ when nohup.sh used the vendor /bin/sh, it would exit with status
+ of `1' rather than the required 126 or 127 upon failure to exec
+ the specified program.
+
+ * src/Makefile.am (EXTRA_SCRIPTS): Remove definition.
+ (bin_PROGRAMS): Add nohup.
+ (EXTRA_DIST): Remove nohup.sh.
+ (all_programs): Remove use of $(EXTRA_SCRIPTS).
+ * src/nohup.sh: Remove file.
+ * man/Makefile.am (nohup.1): Depend on nohup.c, rather than nohup.sh.
+
+ * tests/misc/nohup: Tests for the above.
+ * tests/misc/Makefile.am (TESTS): Add nohup.
+
+ * src/head.c (diagnose_copy_fd_failure): New function, renamed from
+ the macro, COPY_FD_DIAGNOSE.
+ (diagnose_copy_fd_failure): Enclose diagnostic in _(...).
+ (head_file): Likewise.
+
+ * src/date.c: Include "quote.h".
+ (batch_convert): Use the quote function rather than using literal `...'
+ in a diagnostic.
+
+ * src/setuidgid.c (main): Enclose diagnostic in _(...).
+ * src/fmt.c (main): Likewise.
+ * src/mknod.c (main): Likewise.
+ * src/tac.c (tac_seekable): Likewise.
+ * src/yes.c (main): Likewise.
+ * src/od.c (main): Likewise.
+ * src/install.c (change_attributes): Likewise.
+
+2003-07-10 Jim Meyering <jim@meyering.net>
+
+ * src/head.c (usage): Use 1024*1024 in place of 1048576.
+ * src/tail.c (usage): Likewise.
+
+ * tests/rm/fail-2eperm: Now that we have setuidgid, use it in
+ place of the kludge in this test. Suggestion from Paul Jarc.
+
+ * src/Makefile.am (noinst_PROGRAMS): Define to setuidgid.
+ * src/setuidgid.c: New program, solely for testing (not installed).
+
+ * src/chown-core.c (change_file_owner): Don't leak file descriptors
+ when dereferencing symlinks.
+
+2003-07-09 Jim Meyering <jim@meyering.net>
+
+ * tests/du/slash: New file/test for today's lib/ftw.c fix.
+ * tests/du/Makefile.am (TESTS): Add slash
+
+ * src/tail.c (xlseek): Avoid warning about ``return without value
+ from function returning non-void''.
+
+2003-07-08 Jim Meyering <jim@meyering.net>
+
+ * man/help2man: Update to version 1.29.
+
+ * man/help2man: Add END handler to close STDOUT and check for errors.
+
+2003-06-30 Paul Eggert <eggert@twinsun.com>
+
+ Add support for a "[" that conforms to the GNU coding standards,
+ i.e., that does not depend on its name.
+ * src/lbracket.c: New file.
+ * README: Add "[".
+ * man/Makefile.am (programs): Ignore "[", since it doesn't have
+ a separate man page.
+ * src/Makefile.am (bin_PROGRAMS): Add "[".
+ (__SOURCES): New var.
+ * src/test.c (LBRACKET): Define to 0 if not defined.
+ (main): Use LBRACKET rather than argv[0].
+
+ * src/test.c (one_argument): Do not check for -t if POSIXLY_CORRECT.
+ Reported by Paul Jarc and Dan Jacobson.
+
+ * src/test.c (main): Do not recognize --help or --version if
+ POSIXLY_CORRECT, when invoked as "test". Handle "[ ]" correctly.
+ Do not bother testing that margv[margc] is non-null.
+
+2003-07-04 Jim Meyering <jim@meyering.net>
+
+ * src/who.c (print_line): Rewrite to use asprintf, in order to be
+ able to avoid emitting trailing spaces. Reported by Dan Jacobson.
+
+ * tests/misc/head-elide-tail: Add tests of head's new --lines=-N
+ option, and perform the +1600 invocations of head IFF the envvar
+ RUN_EXPENSIVE_TESTS is set.
+
+2003-07-03 Jim Meyering <jim@meyering.net>
+
+ * src/cp.c (do_copy): Give a better diagnostic when failing due
+ to nonexistent destination directory. Reported by Dmitry Rutsky.
+ See http://bugs.debian.org/199730 for details.
+
+2003-06-27 Jim Meyering <jim@meyering.net>
+
+ split's --verbose option did nothing [broken in 4.5.10 and 5.0]
+ * src/split.c (longopts): Use `1', not `0' as the value for
+ for &verbose. Reported by Keith Thompson.
+
+ Test for the above fix.
+ * tests/misc/split-a: Also use --verbose and compare stderr
+ output with what we'd expect.
+
+2003-06-20 Jim Meyering <jim@meyering.net>
+
+ * src/copy.c (copy_internal) [HAVE_STRUCT_STAT_ST_AUTHOR]:
+ Use `error_t' (rather than int) as type for local `err'.
+ From Alfred M. Szmidt.
+
+2003-06-19 Marcus Brinkmann <marcus@gnu.org>
+
+ * src/copy.c (copy_internal) [HAVE_STRUCT_STAT_ST_AUTHOR]:
+ Fix author preservation code.
+
+2003-06-19 Jim Meyering <jim@meyering.net>
+
+ * src/ln.c (ENABLE_HARD_LINK_TO_SYMLINK_WARNING): Define to 0.
+ (do_link): Don't warn about hard link to symlink.
+
+2003-06-18 Jim Meyering <jim@meyering.net>
+
+ * src/cut.c: Include "getdelim2.h", not "getstr.h".
+ Reflect renaming: getstr -> getdelim2.
+
+ * src/comm.c, src/join.c, src/nl.c, src/uniq.c: Reflect renaming:
+ readline -> readlinebuffer.
+
+2003-06-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * src/readlink.c: Include <sys/types.h> before system.h (because
+ the latter includes <sys/stat.h>). Required on Ultrix 4.3.
+
+2003-06-17 Jim Meyering <jim@meyering.net>
+
+ * src/system.h (initialize_main): Define.
+ Use it in every `main'. Applied via this:
+ p='initialize_main (&argc, &argv);'
+ perl -ni -e '/program_name.=.argv.0/ and print " '"$p"'\n"; print' \
+ $(grep -l program_name.=.argv.0 *.c)
+ test.c uses margc/margv, so I made the change manually for that file.
+ Based on a patch from Bernard Giroud.
+
+2003-06-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ Fix for build failure on Ultrix 4.3.
+ * src/stat.c: Include sys/statvfs.h in preference to sys/vfs.h.
+ Include sys/param.h and sys/mount.h on ultrix.
+
+2003-06-16 Jim Meyering <jim@meyering.net>
+
+ * src/touch.c (O_NDELAY, O_NONBLOCK, O_NOCTTY, EISDIR): Remove
+ definitions.
+ * src/system.h (O_NDELAY, O_NONBLOCK, O_NOCTTY, EISDIR): Define
+ them here instead, but with one change: define EISDIR to -1, not 0.
+
+ * src/cat.c (cat): Remove `#ifndef ENOSYS', now that it's
+ guaranteed to be defined.
+ * src/system.h (ENOSYS, ENOTSUP): Define to -1 if not defined.
+
+ * README: Mention the CVS repository.
+ Encourage addition of test cases.
+
+2003-06-12 Jim Meyering <jim@meyering.net>
+
+ * src/touch.c (touch): Call close only if necessary.
+ From Bruno Haible.
+
+ * src/wc.c (usage): Correct wording: wc prints counts in the order
+ `newline, word, byte'. Reported by Keith M. Briggs.
+ * man/wc.x: Fix it here, too. And change `lines' to `newlines'.
+
+2003-06-10 Jim Meyering <jim@meyering.net>
+
+ * tests/date/Test.pm: Add a test for the new format, e.g., May-23-2003.
+
+2003-06-07 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (syntax-check): Add commented-out (over-aggressive)
+ rule.
+
+2003-06-06 Jim Meyering <jim@meyering.net>
+
+ * src/extract-magic (main): Avoid newer 3-arg form of open,
+ so this script works also with e.g., perl5.005_03.
+ Patch by John David Anglin.
+
+2003-06-04 Paul Eggert <eggert@twinsun.com>
+
+ * src/system.h: Include <stdbool.h> unconditionally.
+
+2003-06-04 Jim Meyering <jim@meyering.net>
+
+ * man/Makefile.am (check-programs-vs-x): Rename target
+ from check-programs-vs-1. Adjust rule to check for the
+ primary (.x) file, not the generated one (.1).
+
+2003-06-03 Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>
+
+ * man/kill.x: New file.
+ * man/Makefile.am (dist_man_MANS): Add kill.1.
+ (kill.1): New rule.
+
+2003-06-04 Jim Meyering <jim@meyering.net>
+
+ Ensure that the .x file for a new program is never forgotten again.
+ * man/Makefile.am (programs): Define.
+ (check-programs-vs-1): New phony target.
+ (check-local): Depend on it.
+
+2003-06-03 Jim Meyering <jim@meyering.net>
+
+ Avoid unnecessary copying of environment.
+ * src/env.c (main): Rather than clearing the environment and --
+ unless told to ignore environment -- copying all settings from
+ the saved, original environment, clear the environment only when
+ that is requested. Suggested by Jens Elkner.
+
+2003-06-02 Jim Meyering <jim@meyering.net>
+
+ * src/system.h: Always include <string.h>, since we assume C89.
+ Include <limits.h> without checking for HAVE_LIMITS_H.
+
+ * src/test.c [!TEST_STANDALONE]: Remove #if-0'd block.
+ (STREQ, S_IXUGO): Remove redundant (in system.h) definitions.
+
+2003-06-01 Jim Meyering <jim@meyering.net>
+
+ Avoid a race condition in `tail -f' described by Ken Raeburn in
+ http://mail.gnu.org/archive/html/bug-textutils/2003-05/msg00007.html
+ * src/tail.c (file_lines): Add new parameter, *read_pos, and set it.
+ (pipe_lines, pipe_bytes, start_bytes, start_lines): Likewise.
+ (tail_bytes, tail_lines, tail): Likewise.
+ (tail_file): Use the new `read_pos' value as the size,
+ rather than stats.st_size from the fstat call.
+
+2003-05-28 Jim Meyering <jim@meyering.net>
+
+ * src/extract-magic: Allow expansion of `$file' in the here-
+ document corresponding to the comment at the top of fs.h.
+
+2003-05-26 Jim Meyering <jim@meyering.net>
+
+ * src/stat.c: Fix portability problem on FreeBSD5.0: don't include
+ <sys/statvfs.h> on systems without HAVE_STRUCT_STATVFS_F_BASETYPE.
+ Use #if/#elif/... cascade so we get only one set of include files.
+ Reported by Nelson Beebe.
+
+2003-05-24 Jim Meyering <jim@meyering.net>
+
+ * src/md5sum.c (split_3): Accept the BSD format only when in MD5 mode.
+ * tests/sha1sum/basic-1: Make sure `sha1sum --check' doesn't
+ accept the BSD format.
+
+2003-03-28 Joe Orton <jorton@redhat.com>
+
+ * src/md5sum.c (bsd_split_3): New function.
+ (split_3): Detect checksums from BSD 'md5' command and handle them
+ using bsd_split_3.
+
+ * tests/md5sum/basic-1: New tests for --check exit status, and for
+ BSD-style checksum files.
+
+2003-05-21 Jim Meyering <jim@meyering.net>
+
+ * src/head.c (elide_tail_lines_pipe): Fix a thinko.
+ This sort of thing is why it'd be *Really Good* to factor
+ out the common code used here and in tail.c.
+
+2003-05-14 Jim Meyering <jim@meyering.net>
+
+ * src/head.c (usage): Document new feature: --bytes=-N and --lines=-N.
+
+ * tests/du/slink: Skip this test if `.' is on an XFS file system.
+
+ * tests/du/fd-leak: New file. Test for the bug in du that
+ was fixed by the 2003-05-12 change to lib/ftw.c.
+ * tests/du/Makefile.am (TESTS): Add fd-leak.
+
+ * src/head.c (AUTHORS): Enclose string in N_(...), now that it
+ includes a translatable word, `and'.
+
+ * src/dd.c (usage): Don't use `,' as the thousands separator
+ in e.g. 1,000,000 and 1,048,576. Instead, do this:
+ `SIZE may be ..., MB 1000*1000, M 1024*1024 and so on...'
+ * src/df.c (usage): Likewise.
+ * src/du.c (usage): Likewise.
+ * src/ls.c (usage): Likewise.
+
+ * Makefile.maint (syntax-check): Add another check.
+
+2003-05-13 Paul Eggert <eggert@twinsun.com>
+
+ Fix uniq to conform to POSIX, which requires that "uniq -d -u"
+ must output nothing. Problem reported by Josh Hyman.
+
+ * src/uniq.c (enum output_mode, mode): Remove, replacing with:
+ (output_unique, output_first_repeated, output_later_repeated):
+ New vars. All uses of "mode" changed to use these variables,
+ which are not mutually exclusive as "mode" was.
+ (writeline): New arg "match", used to control whether to
+ obey output_first_repeated or output_later_repeated.
+ All callers changed.
+ (check_file, main): Adjust to above changes.
+
+ * tests/uniq/Test.pm: Test that 'uniq -d -u' outputs nothing.
+
+2003-05-14 Jim Meyering <jim@meyering.net>
+
+ * tests/rm/rm3: Use tr's \n notation rather than \012.
+ This package can afford to do that, since its tests are guaranteed use
+ GNU tr, which has accepted the more modern notation for 10 years.
+ * tests/rm/rm5: Likewise.
+ * tests/cp/same-file: Likewise.
+ * tests/stty/row-col-1: Likewise.
+ * tests/stty/basic-1: Likewise.
+ * tests/rm/deep-1: Likewise.
+ * tests/mv/part-symlink: Likewise.
+ * tests/mkdir/perm: Likewise.
+ * tests/misc/nice: Likewise.
+
+2003-05-13 Jim Meyering <jim@meyering.net>
+
+ * src/copy.c (struct F_triple) [name]: Remove const attribute.
+ (triple_free): Don't apply cast to argument of free.
+ (seen_file): Add cast here instead.
+
+ * src/cp-hash.c (struct Src_to_dest) [name]: Remove const attribute.
+ (src_to_dest_free): Don't apply cast to argument of free.
+
+ * src/sort.c (zaptemp): Don't apply cast to argument of free.
+ * src/pr.c (init_fps, init_store_cols): Likewise.
+ * src/join.c (delseq, freeline): Likewise.
+ * src/expr.c (OLD): Likewise.
+ * src/sort.c (sort): Likewise.
+ * src/head.c (elide_tail_lines_pipe): Likewise.
+
+ * src/tail.c: Include "quote.h".
+ Use quote in diagnostics. Change many error format strings
+ from just `%s' to e.g., `error reading %s'.
+ (pipe_lines): Change type of parameter, n_lines, to uintmax_t.
+ Rewrite newline-counting loop to use memchr.
+
+ * src/head.c (elide_tail_lines_pipe): Use `if', not assert.
+ Now that assert is no longer used, don't include <assert.h>.
+
+2003-05-12 Jim Meyering <jim@meyering.net>
+
+ * src/head.c: Include <assert.h>.
+ (AUTHORS): Add my name.
+ (elide_tail_lines_pipe): New function.
+
+2003-05-10 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (syntax-check): Check for `error (EXIT_SUCCESS,'.
+
+ * src/readlink.c (main): Set program_name before first use.
+ Remove that (redundant) first use.
+ Don't exit successfully just because --verbose was specified.
+ Pass 0, not EXIT_SUCCESS, as first argument to error; when that
+ parameter is 0, error does not exit.
+
+ * src/uname.c (main): When failing due to too many arguments, also say
+ that, rather than just "Try `uname --help' for more information.".
+ * src/comm.c (main): Likewise, but for too few arguments.
+ * src/logname.c: Include error.h.
+ (main): Say why we're failing.
+
+ * src/uniq.c (main): Don't segfault when argc < optind.
+ * src/who.c (main): Handle argc < optind.
+ * src/df.c (main): Likewise.
+ * src/install.c (main): Likewise.
+ * src/mv.c (main): Likewise.
+ * src/pwd.c (main): Likewise.
+ * src/tty.c (main): Likewise.
+ * src/chroot.c (main): Likewise.
+ * src/hostname.c: Likewise.
+ * src/du.c (main): Likewise.
+ * src/expand.c (main): Likewise.
+ * src/env.c (main): Likewise.
+ * src/unexpand.c (main): Likewise.
+ * src/printenv.c (main): Likewise.
+ * src/sync.c (main): Handle argc == 0.
+ * src/expr.c (main): Likewise.
+ * src/printf.c (main): Likewise.
+ * src/basename.c (main): Likewise.
+ * src/ln.c (main): Test for `missing argument' before computing n_files.
+ * src/tail.c (main): Test for the case of no arguments before
+ computing n_files.
+
+ * src/kill.c (send_signals): Don't check command line arguments here.
+ (main): Check them here instead. Handle argc < optind.
+
+ * src/logname.c (main): Use error, rather than fprintf, for the sake
+ of consistency.
+
+ * src/rm.c (main): Don't overrun array bound if argc is 0.
+
+2003-05-09 Jim Meyering <jim@meyering.net>
+
+ * src/sort.c (main): Don't overrun array bound if argc is 0.
+ That would happen when invoked via: execl ("/usr/bin/sort", NULL);
+ Reported by Wartan Hachaturow.
+
+2003-05-07 Jim Meyering <jim@meyering.net>
+
+ Implement support so that `head --lines=-N' works on seekable files.
+ * src/head.c (enum Copy_fd_status): Define.
+ (COPY_FD_DIAGNOSE): New macro.
+ (elide_tail_lines_seekable): New funtion.
+ (elide_tail_lines_file): Call it here.
+
+2003-05-06 Jim Meyering <jim@meyering.net>
+
+ * src/sys2.h (CHAR_BIT): Remove duplicate definition.
+
+2003-05-04 Jim Meyering <jim@meyering.net>
+
+ * tests/head/Test.pm: Remove tests of --bytes=-N; using that framework
+ caused the addition of thousands of small files to the tar archive.
+ * tests/misc/head-elide-tail: New file. Add them here instead.
+ * tests/misc/Makefile.am (TESTS): Add head-elide-tail.
+
+2003-05-04 Paul Eggert <eggert@twinsun.com>
+
+ * src/remove.c (HAVE_WORKING_READDIR): Define to 0 if not defined.
+ (IF_READDIR_NEEDS_REWINDDIR): Remove.
+ (remove_cwd_entries): Rewrite to avoid IF_READDIR_NEEDS_REWINDDIR,
+ which was a bit weird because it couldn't be emulated by a function.
+
+2003-05-03 Jim Meyering <jim@meyering.net>
+
+ Extend head to accept --lines=-N (--bytes=-N) and to print all
+ but the N lines (bytes) at the end of the file.
+ * src/head.c: Include full-write.h, full-read.h, inttostr.h, quote.h.
+ Use quote() in diagnostics, rather than literal `' marks.
+ (copy_fd, elide_tail_bytes_pipe, elide_tail_bytes_file):
+ New functions.
+ (elide_tail_lines_pipe, elide_tail_lines_file): New functions.
+ (head_file): Reorganize so as to call head from only one place.
+ (main): Likewise, for head_file.
+ Handle new, undocumented option, --presume-input-pipe.
+ Handle negative line and byte counts.
+ * tests/head/Test.pm: Add lots of tests to exercise --bytes=-N.
+
+ * tests/du/8gb: Skip test if the file system of `.' doesn't support
+ sparse files -- otherwise it'd create a file of size 8GB.
+
+2003-05-02 Jim Meyering <jim@meyering.net>
+
+ * src/fmt.c (usage): Don't mention obsolescent -WIDTH option.
+ Instead explain about `-' and standard input.
+ (main): Give a proper diagnostic for e.g., `fmt -c -72'.
+ Reported by Keith Thompson.
+ * tests/fmt/basic: Add test for the above fix.
+
+ * src/fmt.c: Include "quote.h".
+ Use quote() in diagnostics, rather than literal `' marks.
+ (main): Exit nonzero when unable to open an input file.
+ * tests/fmt/basic: Add test for the above fix.
+
+ * src/fmt.c (main): Diagnose invalid suffix on obsolescent width
+ specifications like `-72x'.
+ * tests/fmt/basic: Add test for the above fix.
+
+ Work around nasty readdir bug on Darwin6.5.
+ * src/remove.c (IF_READDIR_NEEDS_REWINDDIR): Define.
+ [! HAVE_WORKING_READDIR] (remove_cwd_entries): If readdir has just
+ returned NULL and there has been at least one successful unlink or
+ rmdir call since the opendir or previous rewinddir, then call
+ rewinddir and reiterate the loop.
+
+ Factor out common code.
+ * src/remove.c (readdir_ignoring_dotdirs): New function.
+ (is_empty_dir): Use it here.
+ (remove_cwd_entries): Use it here.
+
+2003-05-01 Jim Meyering <jim@meyering.net>
+
+ * tests/rm/r-3: Create 500 rather than just 300 files.
+ There's a bug in Darwin6.5's readdir that shows up only with
+ 338 or more files.
+ Fix a bug in this test: `cd $pwd' (not to `..'), now that $tmp
+ has two components.
+
+ * src/tail.c:
+ Change type of n_units, n_bytes, n_lines to be `uintmax_t'.
+ (dump_remainder): Move two declarations `down' into the scope
+ where they are used.
+ (xlseek): Return the resulting offset.
+ (file_lines): Rename parameter, file_length, to end_pos.
+ (pipe_lines): Don't coerce safe_read return value to `int'.
+ Adapt tests accordingly.
+ (pipe_bytes) [struct charbuffer] (nbytes): Change type from `int'
+ to `unsigned int'.
+ Change type of `total_bytes' from `int' to `size_t',
+ since the former wouldn't always be wide enough.
+ Don't coerce safe_read return value to `int',
+ and adapt tests accordingly.
+ Now that testing for a read error no longer involves
+ using `tmp', handle that case *after* freeing `tmp'.
+ (start_bytes): Clean up.
+ (tail_bytes): Now that `n_bytes' may be larger than
+ OFF_T_MAX, test for that condition and, if it's true, don't
+ use lseek optimizations.
+ (parse_options): Don't fail just because N_UNITS is larger than
+ the maximum size of a file -- tail may be applied to an input
+ stream (e.g., a pipe) with more data than that.
+
+ * Makefile.maint (syntax-check): Rename from alloc-check.
+ Also check for SPACE-TAB sequences.
+ Also check for malloc/calloc/realloc casts.
+
+2003-05-01 Jim Meyering <jim@meyering.net>
+
+ * src/tail.c (start_lines): Rewrite to use memchr. Clean up.
+
+2003-04-28 Jim Meyering <jim@meyering.net>
+
+ * tests/misc/tty-eof: Send two tokens, not just one, so we don't
+ make the now-more-picky tsort fail.
+
+2003-04-24 Jim Meyering <jim@meyering.net>
+
+ * src/tsort.c (tsort): Remove unnecessary test of have_read_stdin.
+ (main): Minor syntactic clean-up.
+
+ * src/tsort.c (tsort): Fail if the input contains an odd number of
+ tokens. Reported by junkio@cox.net.
+
+ * tests/tsort/basic-1: Test for the above fix.
+
+2003-04-21 Jim Meyering <jim@meyering.net>
+
+ * tests/misc/printf: Add tests for the printf fixes below.
+
+ * Makefile.cfg (cvs_files): Add $(srcdir)/config/depcomp to the list.
+
+2003-04-20 Paul Eggert <eggert@twinsun.com>
+
+ Fix printf POSIX compatibility bug reported by Ben Harris in
+ <http://mail.gnu.org/archive/html/bug-coreutils/2003-04/msg00070.html>.
+ * doc/coreutils.texi (printf invocation): It's \NNN in the format,
+ \0NNN in the %b operand.
+ * src/printf.c (usage): Likewise.
+ (print_esc): New arg OCTAL0 to specify whether \0NNN or \NNN
+ is desired. All uses changed. Behave like Bash printf if %b
+ operand uses \NNN where the initial N is not 0.
+
+2003-04-17 Jim Meyering <jim@meyering.net>
+
+ * src/stty.c: Remove uses of PROTOTYPE macro.
+
+2003-04-15 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint: Remove (or replace-with-TAB(s) to retain alignment)
+ each sequence of spaces before a TAB character.
+
+2003-04-13 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (is_empty_dir): Don't closedir (NULL).
+
+2003-04-12 Jim Meyering <jim@meyering.net>
+
+ Giving nl an invalid STYLE argument (in --header-numbering=STYLE (-h),
+ --body-numbering=STYLE (-b), or --footer-numbering=STYLE (-f)) or
+ FORMAT (--number-format=FORMAT (-n)) would not give a useful diagnostic.
+ * src/nl.c (main): Fix those problems and remove literal quote marks
+ (e.g., "`%s'") from format string; instead use "%s" in each format
+ string and `quote (optarg)' as the corresponding argument.
+ Also, diagnose all invalid command line options before failing.
+
+ * src/nl.c (proc_text): Fix a bug that would make nl output extra
+ newlines in some cases. Details here: http://bugs.debian.org/177256.
+ This bug was introduced on 2001-11-10 for textutils-2.0.17.
+ * tests/misc/nl: Add test for the above-fixed bug.
+
+ * tests/misc/readlink: New file. Test the --canonicalize option.
+ * tests/misc/Makefile.am (TESTS): Add readlink.
+
+2003-04-11 Jim Meyering <jim@meyering.net>
+
+ Clean up.
+ * src/chown.c, src/cp.c, src/dircolors.hin, src/du.c, src/ln.c:
+ * src/mkfifo.c, src/ptx.c, src/spline.c, src/stty.c, src/tail.c:
+ * src/test.c, src/unexpand.c: Remove (or replace-with-TAB(s) to
+ retain alignment) each sequence of spaces before a TAB character.
+
+ * src/ls.c: Include <stdlib.h> unconditionally.
+
+ * Makefile.maint (xalloc-check): Rename from header-check.
+
+ * src/yes.c: Include error.h after system.h, not before.
+
+ Clean up.
+ * src/copy.c, src/cp-hash.c, src/cp.c, src/csplit.c, src/cut.c:
+ * src/date.c, src/df.c, src/du.c, src/expand.c, src/expr.c, src/id.c:
+ * src/join.c, src/md5sum.c, src/nl.c, src/od.c, src/paste.c, src/pr.c:
+ * src/ptx.c, src/sort.c, src/split.c, src/su.c, src/tail.c, src/tee.c:
+ * src/tr.c: * src/unexpand.c, src/users.c:
+ Remove anachronistic casts of xmalloc, xrealloc, and xcalloc
+ return values and of xrealloc's first argument.
+ Fix the former with this:
+ perl -pi -e 's/\([^(]*?\*\) *(x(m|c|re)alloc)\b/$1/'
+
+2003-04-10 Jim Meyering <jim@meyering.net>
+
+ * src/stty.c (wrapf): Declare with format attribute.
+
+ The S_MAGIC_... names shouldn't be maintained in two places (prior
+ to this change, one would have to keep stat.c and fs.h in sync).
+ This change makes it so those names and the corresponding
+ hexadecimal constants all reside in stat.c. fs.h is now generated.
+ * src/Makefile.am (fs.h): New rule to generate fs.h from stat.c.
+ (BUILT_SOURCES): Add fs.h, now that it's generated.
+ (EXTRA_DIST): Add extract-magic.
+ * src/extract-magic: New script to extract fs.h definitions from stat.c.
+ * src/stat.c (human_fstype) [__linux__]: Append each hex constant from
+ fs.h in a comment after the corresponding `case S_MAGIC_...:' statement.
+
+ * tests/tail-2/big-4gb: Skip this test (don't fail) if creating a
+ file with nominal length > 4GB fails. Reported by Michael Deutschmann.
+
+ * man/unexpand.x: Add `SEE ALSO' reference to expand.
+ * man/expand.x: Add `SEE ALSO' reference to unexpand.
+ Suggestion from Dan Jacobson.
+
+2003-04-10 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * src/fs.h (S_MAGIC_DEVPTS): New magic for Linux's devpts.
+ * src/stat.c (human_fstype): Handle Linux's devpts.
+
+2003-04-09 Paul Eggert <eggert@twinsun.com>
+
+ * src/split.c (line_bytes_split): Arg is of type size_t, since
+ that's all that is supported for now.
+ (main): Check for overflow in obsolescent line count option.
+
+2003-04-09 Jim Meyering <jim@meyering.net>
+
+ * tests/misc/split-fail: Add a new test for the above fix.
+
+ * src/split.c (bytes_split): Use size_t temporary (rather than
+ uintmax_t original) in remaining computations. From Paul Eggert.
+
+ Handle command line option arguments larger than 2^31.
+ This allows e.g., splitting into files of size 2GB and larger,
+ and running split --lines=N with N=2^31 or more.
+ But for --line-bytes=N, the restriction that N <= SIZE_MAX
+ remains (for now), due to the way it is implemented.
+
+ * src/split.c: Include "inttostr.h".
+ (bytes_split, lines_split, line_bytes_split, main):
+ Use uintmax_t, not size_t, for file sizes.
+ (main): Give a better diagnostic for option arguments == 0.
+ Use umaxtostr to print file sizes.
+ Reported by Luke Hassell.
+
+2003-04-08 Jim Meyering <jim@meyering.net>
+
+ * src/rm.c (usage): Mention that --directory (-d) works only
+ on some systems. Suggestion from Samuel Tardieu.
+
+ * tests/basename/basic: Run $PERL to see if it is available,
+ rather than testing its value.
+ * tests/sum/sysv, tests/tsort/basic-1, tests/unexpand/basic-1:
+ * tests/basename/basic, tests/dd/skip-seek, tests/dircolors/simple:
+ * tests/expr/basic, tests/factor/basic, tests/fmt/basic:
+ * tests/ls-2/tests, tests/md5sum/basic-1, tests/md5sum/newline-1:
+ * tests/misc/sort, tests/misc/tty-eof, tests/mv/i-1:
+ * tests/rm/empty-name, tests/rm/fail-eperm, tests/rm/unreadable:
+ * tests/seq/basic, tests/sha1sum/basic-1, tests/sha1sum/sample-vec:
+ * tests/sum/basic-1, tests/seq/basic: Likewise.
+
+ * tests/misc/Makefile.am (TESTS): Add split-fail.
+ * tests/misc/split-fail: New file.
+
+ * src/split.c: Rename local variables: nchars -> n_bytes.
+ (lines_split): Rename local, nlines -> n_lines.
+ (main): Rename local variable: s/accum/n_units/.
+ (main): Use STDIN_FILENO, not literal `0'.
+
+2003-04-07 Jim Meyering <jim@meyering.net>
+
+ * src/stat.c: Add #include directives for Ultrix 4.4.
+ Based on a suggested change from Bert Deknuydt.
+
+2003-04-06 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (makefile-check): New rule.
+ (local-check): Add it.
+
+2003-04-05 Jim Meyering <jim@meyering.net>
+
+ * Makefile.am (nearly all of them):
+ Use $(VAR) rather than @VAR@, now that we can rely on automake to
+ emit a definition for each substituted variable.
+ * tests/Makefile.am.in: Likewise.
+
+ * tests/rm/rm5: Add a comment explaining why this test fails when
+ using Tru64's broken sed.
+ * tests/rm/rm3: Likewise.
+
+ Make `kill -t' output signal descriptions (not `?') on Tru64.
+ * src/kill.c (sys_siglist): Also check for __sys_siglist.
+ Patch by Tony Leneis.
+ * configure.ac: Also check for declaration of __sys_siglist.
+ Required for Tru64 4.0D, 4.0F, and 5.1.
+ Reported by Tony Leneis.
+
+2003-04-04 Jim Meyering <jim@meyering.net>
+
+ * src/Makefile.am (PERL): Remove unnecessary definition.
+
+ Because of inappropriate (but POSIX-mandated) behavior of rename,
+ `mv a b' would not remove `a' in some unusual cases. Work around
+ this by unlinking `a' when necessary.
+
+ * src/copy.c (same_file_ok): Add an output parameter.
+ Set it in the offending case.
+ (copy_internal): When necessary, unlink SRC_PATH and inform caller.
+ Reported by Ed Avis.
+ * tests/mv/hard-4: New test for the above.
+ * tests/mv/Makefile.am (TESTS): Add hard-4.
+
+ Clean up rules for automatically generated sources:
+ * src/Makefile.am (dircolors.h, wheel-size.h, wheel.h, false.c):
+ Make each generated file be read-only.
+ Add each file name to BUILT_SOURCES separately.
+ (MAINTAINERCLEANFILES): Set to $(BUILT_SOURCES).
+
+ Put LOCALEDIR macro definition in new file: localedir.h.
+ * src/Makefile.am (DEFS): Remove definition.
+ (localedir.h): New rule.
+ (BUILT_SOURCES, DISTCLEANFILES): Add localedir.h.
+ * src/system.h: Include "localedir.h".
+
+2003-04-02 Jim Meyering <jim@meyering.net>
+
+ * Version 5.0.
+
+ * tests/misc/Makefile.am (TESTS): Add false.
+
+ * Makefile.maint (TMPDIR): Make sure it's defined.
+ (my-distcheck): Build in $(TMPDIR), not `.'.
+
+ * src/Makefile.am (false.c): Change all occurrences of
+ `(EXIT_SUCCESS)' to `(EXIT_FAILURE)' so that false exits
+ unsuccessfully also with --help. Reported by Paul Jarc,
+ * tests/misc/false: New test for the above.
+
+2003-03-30 Jim Meyering <jim@meyering.net>
+
+ * NEWS: Note the location of older NEWS files.
+
+ * src/remove.c (is_empty_dir): Don't let a failing closedir
+ clobber errno. Spotted by Arnold Robbins.
+
+ * src/env.c: Fix typo in comment. From Arnold Robbins.
+
+2003-03-29 Jim Meyering <jim@meyering.net>
+
+ * Version 4.5.12.
+
+ * README: Note to expect build problems for stat.c on Ultrix 4.3.
+ Note that there are some harmless test failures when running
+ `make check' as root on some systems.
+
+2003-03-28 Jim Meyering <jim@meyering.net>
+
+ * tests/stty/row-col-1: Skip this test if stty can't get window size.
+ This happens when connecting to sparc-solaris5.7 via ssh from within
+ emacs. Reported by Karl Berry.
+
+ * tests/du/basic: Use seq, not `yes' to generate 4KB of data.
+ Otherwise, on systems (DJGPP) that emulate pipes using files,
+ this test would never complete, waiting for `yes' to terminate.
+ * tests/du/slink: As above, use seq, not `yes' to generate link target.
+ * tests/rm/hash: As above, use seq, not `yes' to generate dir name.
+ Reported by Rich Dawe.
+
+2003-03-27 Jim Meyering <jim@meyering.net>
+
+ * src/id.c: Remove Arnold Robbins' obsolete e-mail address
+ from `written by...' comment, at his request.
+
+2003-03-24 Paul Eggert <eggert@twinsun.com>
+
+ Fix buffer overrun problem reported by TAKAI Kousuke, along
+ with some other POSIX incompatibilities.
+
+ * src/printf.c (print_esc): Do not treat \x specially if
+ POSIXLY_CORRECT. Avoid buffer overrun if the format ends
+ in backslash. Treat incomplete escape sequences as strings
+ of characters, as POSIX requires.
+ (print_formatted): Allow multiple flags. Avoid buffer overrun
+ if the format is incomplete.
+
+2003-03-24 Jim Meyering <jim@meyering.net>
+
+ * tests/misc/printf: Add tests for the above fixes and changes.
+
+2003-03-26 Jim Meyering <jim@meyering.net>
+
+ * src/copy.h (struct cp_options): Add a comment.
+
+2003-03-23 Jim Meyering <jim@meyering.net>
+
+ * README: Describe problem with 64-bit mode on HPUX 11.x,
+ with patch for /usr/include/inttypes.h.
+ * TODO: Plan to add an autoconf test to work around the bug.
+
+2003-03-22 Jim Meyering <jim@meyering.net>
+
+ * src/stat.c: Don't include <sys/sysmacros.h>.
+ That is already done via system.h. Otherwise, the multiple
+ inclusion would evoke redefinition warnings from Cray's /bin/cc,
+ aka Cray Standard C Version 4.0.3 (057126) Mar 22 2003 22:02:28.
+ (human_fstype): Factor some directives `up', out of this function.
+ Cast away `const' to avoid error from Cray's /bin/cc.
+
+2003-03-20 Jim Meyering <jim@meyering.net>
+
+ * announce-gen (print_changelog_deltas): Ensure that a newline
+ precedes each row of `*'s.
+
+2003-03-20 Jim Meyering <jim@meyering.net>
+
+ * Version 4.5.11.
+
+ * src/seq.c (valid_format): Also accept ` ' and `'' as valid
+ format flag characters.
+ Do not require that a field width be specified.
+ Do not fail when given a field width of `0'.
+ Reported by Dan Jacobson.
+ * tests/seq/basic: Add new tests for the above-fixed bug.
+
+ * src/Makefile.am (all-local): Append $(EXEEXT) to use of `su'
+ (install-root): Likewise.
+ (install-exec-local): Likewise.
+ Based on a patch from Richard Dawe.
+
+2003-03-19 Jim Meyering <jim@meyering.net>
+
+ * man/Makefile.am (.x.1): Use $(LN_S) instead of 'ln -s',
+ because the DJGPP 2.03 port of 'ln -s' doesn't work.
+ Include $(EXEEXT) in program names.
+ Since $(LN_S) may degenerate to `cp -p', be careful
+ to invoke it from the destination directory.
+ Mostly from Richard Dawe.
+ * configure.ac: Use AC_PROG_LN_S.
+
+ * tests/mv/part-symlink: Unset CDPATH. Otherwise, having the
+ CDPATH shell variable set could cause this test to fail.
+ Reported by Karl Berry.
+
+2003-03-18 Jim Meyering <jim@meyering.net>
+
+ * src/fmt.c [struct Word] (paren, period, punct, final): Change the
+ type of each member from bool <MEMBER>:1 to unsigned int <MEMBER>:1.
+ AIX 5.1's xlc could not compile the former.
+ Patch by Petter Reinholdtsen. Also reported by Mike Jetzer.
+
+2003-03-17 Richard Dawe <rich@phekda.freeserve.co.uk>
+
+ * configure.ac: Include $(EXEEXT) in OPTIONAL_BIN_PROGS'
+ program names, since automake only adds $(EXEEXT) to programs
+ in its *_PROGRAMS.
+
+2003-03-16 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (rm): Put two local variables in static storage,
+ so they can't be clobbered by the potential longjmp.
+
+2003-03-15 Jim Meyering <jim@meyering.net>
+
+ * Makefile.cfg (gnu_rel_host): Fix code to match the comment
+ so that a version number with a two-digit component can still count
+ as an alpha release. Reported by Richard A Downing.
+ (gnu_rel_host): Define in terms of $(RELEASE_TYPE) instead.
+
+2003-03-14 Jim Meyering <jim@meyering.net>
+
+ * src/ansi2knr.c: Remove no-longer-used file.
+ * src/ansi2knr.1: Likewise.
+
+ * Makefile.maint (prev_version_file): Don't use ?= for this particular
+ assignment, since it causes trouble with old versions of GNU make
+ (e.g. 3.76.1). The other uses of `?=' are inoffensive. Details here.
+ http://mail.gnu.org/archive/html/bug-coreutils/2003-03/msg00028.html
+ Patch from Alexandre Duret-Lutz.
+
+ * Use patched automake-1.7.3. Regenerate Makefile.in files in
+ subdirectories so that each includes a definition of ACLOCAL_M4.
+
+ * announce-gen (main): Label the compressed source URLs.
+
+ * Version 4.5.10.
+
+ * tests/du/slink: Relax the test for the `local'ness of a file system,
+ so that now it works also for tmpfs.
+
+ * tests/du/hard-link: Transform output from first du, so that this
+ test doesn't fail on file systems like tmpfs that order directory
+ entries differently.
+
+2003-03-13 Jim Meyering <jim@meyering.net>
+
+ * tests/du/8gb: Work around what appears to be an NFS failure that
+ would make this test fail on some systems.
+
+2003-03-11 Jim Meyering <jim@meyering.net>
+
+ * tests/du/basic: Make the test file exactly 4k bytes long.
+
+ * src/split.c (longopts): Don't hard-code `2' here.
+ Instead, just specify `&verbose', and ...
+ (main): ... remove the `case 2:' block for --verbose.
+
+ * tests/du/basic: Make the test file larger than 64 bytes, so that
+ we don't immediately disqualify file systems (e.g., NetApp) on which
+ smaller files take up zero disk blocks. Reported by Vin Shelton.
+
+2003-03-10 Jim Meyering <jim@meyering.net>
+
+ Don't segfault for a negative field width or precision in format string.
+ Note that this is just a stopgap fix. The longer term solution may
+ involve adapting bash's builtins/printf.def.
+
+ * src/printf.c: (UNSPECIFIED): Define.
+ (print_direc): Use the special value, UNSPECIFIED, to indicate
+ that field_width or precision has not been specified.
+ (print_formatted): Fail if field_width or precision is the
+ special value, UNSPECIFIED.
+ Reported by Oliver Kiddle <okiddle@yahoo.co.uk>
+
+ * src/sys2.h (INT_MIN): Define, if necessary.
+ * tests/misc/printf: Add a test for the above-fixed bug.
+
+2003-03-09 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (AD_stack_pop): Cast sizeof... to int before
+ changing its sign. This avoids a warning from gcc on 64-bit systems.
+ Reported by Bob Proulx.
+ (pop_dir): Reverse order of sign change and cast, to be consistent
+ with the above.
+
+2003-03-08 Jim Meyering <jim@meyering.net>
+
+ * tests/Makefile.am (evar-check): Check for POSIXLY_CORRECT not as a
+ shell variable, but only in the environment. With /bin/sh->bash, the
+ shell variable is set to `y', and that would cause a spurious warning.
+ Reported by Bob Proulx.
+
+ * tests/Makefile.am (check-root): Remove touch/fifo.
+ It doesn't appear to have to be run as root.
+
+ * tests/rm/fail-2eperm: Rather than simply using the first non-root
+ user name, make sure that the selected user name has a usable shell.
+ Reported by Paul Jarc.
+
+ Before, when using shred on a device, one had to specify --exact,
+ or be careful to choose a size that would not be rounded up and
+ exceed the maximum value; that could result in a failure of
+ the final write.
+ * src/shred.c (do_wipefd): --exact is now the default for non-regular
+ files. Suggestion from Ben Elliston.
+ (usage): Say it.
+
+ * tests/misc/tty-eof: Require at least version 1.11 of Expect.pm.
+ Old versions of Expect.pm (e.g., 1.07) lack the log_user function.
+ Patch by Bob Proulx.
+
+ * src/Makefile.am (check-misc): Check for use of `defined' in
+ #define directives.
+ Change to $(srcdir) before running grep.
+
+ * src/sleep.c: Remove now-unused #include and #define directives.
+
+ * src/du.c (process_file): If a file's size is not being counted
+ e.g., because it's a hard link to a file we've already counted,
+ then don't print a line for it.
+
+ * tests/du/hard-link: New test for the above-fixed bug.
+ * tests/du/Makefile.am (TESTS): Add hard-link.
+
+ `du -S' didn't work
+ * src/du.c: Revert most of the `reorganization' change of 2003-02-20,
+ and make the two-array approach work.
+
+ * tests/du/basic: Correct/add tests for the above fix.
+ Set LC_ALL, etc., now that we use sort.
+ Check the block/size of a small file, too.
+ Correct expected results for simple dir1/dir2/file case.
+ Add another test of du -S.
+
+2003-03-07 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ Avoid build failure with gcc on hppa1.1-hp-hpux10.20 (see GCC PR
+ middle-end/9986). As one of GCC's optimizations, it transforms a
+ fputs_unlocked call to a fputc_unlocked call when the string is
+ one character long. However, hpux doesn't have fputc_unlocked.
+
+ * expr.c (usage): Use putchar, not fputs, to output a single character.
+ * ls.c (dired_dump_obstack): Likewise.
+ * ptx.c (output_one_tex_line, output_one_dumb_line): Likewise.
+ * stat.c (print_it): Likewise.
+
+2003-03-07 Jim Meyering <jim@meyering.net>
+
+ * src/cp.c: Remove everything associated with mmap-stack.c.
+ This reverts the two changes of 2003-02-21.
+ * src/du.c: Remove everything associated with mmap-stack.c.
+ This reverts the change of 2003-02-19.
+
+2003-03-06 Jim Meyering <jim@meyering.net>
+
+ * tests/cp/same-file: Unset CDPATH. Otherwise, having the
+ CDPATH shell variable set could cause this test to fail.
+ Reported by Karl Berry.
+
+2003-03-05 Jim Meyering <jim@meyering.net>
+
+ * Version 4.5.9.
+
+ * src/printf.c (print_esc): Remove pointless comparison of unsigned
+ integer with zero, to avoid a warning from Intel's ecc.
+ Reported by Nelson Beebe.
+
+ * src/du.c (process_file): Sizes must all be of type uintmax_t.
+ Otherwise, for files or totals that are too big, numbers would
+ be truncated. Patch mostly by Michael Stone.
+ Reported by Ingo Saitz as Debian bug #183210.
+
+ * tests/du/8gb: New test for the above-fixed bug.
+ * tests/du/Makefile.am (TESTS): Add 8gb.
+
+ * src/du.c (MAX_N_DESCRIPTORS): Use 3 * UTILS_OPEN_MAX / 4
+ rather than UTILS_OPEN_MAX - 10.
+
+2003-03-04 Jim Meyering <jim@meyering.net>
+
+ * README: Refer new feature discussion to bug-coreutils@gnu.org,
+ rather than bug-gnu-utils, now that the former is better known.
+ Suggestion from Göran Uddeborg.
+
+ * src/stat.c (usage): Capitalize consistently.
+ Reported by Göran Uddeborg.
+
+ * Makefile.maint (rel-files): Include $(signatures), so that
+ those files are also copied into $(release_archive_dir).
+
+ * src/df.c (find_mount_point): Call error here, now that restore_cwd
+ no longer does it.
+ * src/remove.c (AD_pop_and_chdir): Likewise.
+
+ * tests/Makefile.am (check-root): Add fail-2eperm.
+
+2003-03-03 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (remove_cwd_entries): Include the full filename of
+ the offending file, not just the basename.
+
+ * tests/misc/tty-eof: Set $ME properly.
+
+ * Makefile.maint (THIS_VERSION_REGEXP, PREV_VERSION_REGEXP):
+ Remove now-unused variables.
+ (tag-prev-version, prev-cvs-tag): Likewise.
+
+ * src/remove.c (remove_cwd_entries) [!ROOT_CAN_UNLINK_DIRS]: Give an
+ accurate diagnostic when failing to remove a file owned by some other
+ user. Reported by Ivo Timmermans via Michael Stone.
+ This fixes Debian bug# 178471.
+
+ * tests/rm/Makefile.am (TESTS): Add fail-2eperm.
+ * tests/rm/fail-2eperm: New test, for the above-fixed bug.
+ Based on a report from Ivo Timmermans.
+
+2003-03-02 Jim Meyering <jim@meyering.net>
+
+ * src/copy.c (copy_internal) [un_backup]: When recovering from a
+ failure to create a hard link, do not remove the entry associating
+ the source dev/ino with the destination file name.
+ * tests/mv/Makefile.am (TESTS): Add hard-3.
+ * tests/mv/hard-3: New test, for the above-fixed bug.
+ Inspired by a report from Iida Yosiaki.
+
+2003-03-01 Jim Meyering <jim@meyering.net>
+
+ * src/df.c (print_header): Don't embed spaces in a separate `Type'
+ header string. Instead, put `Filesystem' and `Type' headers in the
+ same string, so translators can use horizontal space as needed.
+ Reported by Jean Charles Delepine.
+
+2003-02-28 Jim Meyering <jim@meyering.net>
+
+ * src/copy.c (copy_internal): When link fails because of an
+ existing destination file, unlink that file and try again.
+ Reported by Iida Yosiaki.
+
+ * tests/mv/Makefile.am (TESTS): Add hard-2.
+ * tests/mv/hard-2: New test for the above-fixed bug.
+ Based on a test case from Iida Yosiaki.
+
+2003-02-26 Jim Meyering <jim@meyering.net>
+
+ * tests/du/basic: Don't test du's -b option here. Directory byte
+ counts are smaller (512 rather than 4096) on at least OSF/1 5.1
+ and IBM AIX 4.2. Reported by Nelson Beebe.
+
+2003-02-25 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (announcement): Now that ChangeLog entries
+ are output by announce-gen, don't do it here.
+ * announce-gen (print_changelog_deltas): New function.
+ (main): Use it.
+
+2003-02-22 Jim Meyering <jim@meyering.net>
+
+ * announce-gen: New option: --release-type=TYPE
+ * Makefile.maint (beta, major): New targets. Remove `release'.
+ Put them all together on a line.
+ Pass the release type (via RELEASE_TYPE envvar) to the MAKE
+ invocation of `announcement'.
+ (announcement): Invoke announce-gen with --release-type=$RELEASE_TYPE.
+
+ * announce-gen: New option: --news=NEWS_FILE.
+ Extract NEWS entries here, not via rules in Makefile.maint.
+ * Makefile.maint (announcement): Now that NEWS entries are
+ extracted by announce-gen, don't do it here.
+ (news-r1, news-r2): Remove now-unused definitions.
+
+2003-02-21 Jim Meyering <jim@meyering.net>
+
+ * Version 4.5.8.
+
+ Merge in changes from autoconf's version of this file.
+ * Makefile.maint (www-gnu): Define.
+ (standards.texi-url_prefix): Use $(www-gnu).
+ (make-stds.texi-url_prefix): Likewise.
+
+ * src/cp.c: Include "mmap-stack.h".
+ (main): Invoke `run' through a macro that (when possible) runs it
+ with a large, mmap'd stack.
+
+ * src/cp.c (run): New function, preparing for the above.
+ Exit from this function, not from main
+ (main): Call run.
+
+ * src/du.c: New option: --apparent-size.
+ (enum) [APPARENT_SIZE_OPTION]: New member.
+ (long_options): Add it.
+ (usage): Describe it.
+ (main): Handle it.
+ ['b']: Set apparent_size.
+ David Eisner reported that the behavior of --bytes had changed.
+ Paul Eggert proposed the use of a new option, --apparent-size.
+
+ * src/du.c (apparent_size): New global.
+ (print_only_size): Reflect the fact that we're printing byte counts,
+ not ST_NBLOCKSIZE-byte-block counts.
+ (print_size): Call print_only_size rather than duplicating its code.
+ (process_file): Accumulate byte counts, rather than block counts.
+
+ * src/du.c (process_file): Always reset size_to_propagate_to_parent
+ for --separate-dirs (-S).
+
+2003-02-20 Jim Meyering <jim@meyering.net>
+
+ * Use automake-1.7.3. Regenerate dependent files.
+
+ * src/stat.c (print_stat): New format: %B (to print ST_NBLOCKSIZE).
+ This makes %b (number of ST_NBLOCKSIZE-byte blocks) more useful.
+ (usage) [%B]: Describe it.
+ [%b]: Refer to %B.
+
+ * src/du.c (process_file): Reorganize the code to use only
+ one `sum' array, and change how -S works back to the way it was
+ before 2003-01-31. Patch by Bruno Haible.
+
+ * tests/du/basic: New test.
+ * tests/du/Makefile.am (TESTS): Add basic.
+
+ * tests/envvar-check: Add checks for the following:
+ BLOCK_SIZE, DU_BLOCK_SIZE, DF_BLOCK_SIZE, LS_BLOCK_SIZE.
+
+ * tests/Makefile.am: Rename phony target envvar-check to evar-check
+ so as not to conflict with the distributed file by the same name.
+
+ * src/du.c (process_file): Set info->skip before any possible return.
+
+ Report correct usage for directories, not 0.
+ * src/du.c (process_file): Return for `file_type == FTW_DPRE'
+ _before_ recording the dev/ino of a directory.
+ Reported by Bruno Haible.
+
+ Now, df always displays the device file name corresponding to the
+ listed mount point under `Filesystem'. Before, for an unmounted
+ block- or character-special file argument, it would display the
+ command-line argument instead.
+ * src/df.c (show_disk): Return a value indicating whether
+ there was a match. Don't try to find a mount point here.
+ (show_entry): If show_disk doesn't find a match, call show_point.
+
+2003-02-19 Jim Meyering <jim@meyering.net>
+
+ * src/du.c: Include "mmap-stack.h".
+ (du_files): Add prototype with ATTRIBUTE_NORETURN.
+ Exit from this function, not from...
+ (main): ...here.
+ Instead, if possible, invoke du_files through a macro that
+ runs it with a large, mmap'd stack.
+
+ * src/join.c (usage): Change wording in --help output:
+ use FILENUM instead of `SIDE' and say what FILENUM means.
+ Reported by Bernhard Gabler.
+
+ * src/df.c (print_header): Rather than using a hard-coded literal
+ string of spaces matching the length of the English `...Type' header,
+ output the right number of spaces to match the selected translation.
+ Reported by Yann Dirson and Jean Charles Delepine as Debian bug 131113.
+
+ * src/split.c (bytes_split): Remove unnecessary `else' after break.
+ (lines_split): Likewise. and correct misleading indentation.
+
+ * src/split.c: Include "full-read.h".
+ (bytes_split, lines_split, line_bytes_split): Use full_read,
+ not safe_read. The way split was using the latter, a short read
+ could cause split to terminate before EOF.
+
+ * tests/misc/tty-eof: Test all programs that can read stdin,
+ requiring no arguments and that write to standard output.
+
+ * tests/misc/tty-eof: New file. Renamed from ...
+ * tests/misc/cat-tty-eof: Remove file. Rename to tty-eof.
+ * tests/misc/Makefile.am (TESTS): Reflect renaming.
+
+2003-02-18 Jim Meyering <jim@meyering.net>
+
+ cksum would perform an extra read after encountering EOF
+ * src/cksum.c (cksum): Exit the loop upon EOF, too.
+ Patch by Michael Bacarella.
+
+ Test for the bug fixed today in cksum, md5sum, and sha1sum.
+ * tests/misc/cat-tty-eof: Generalize, clean-up, and test for
+ cat, cksum, md5sum, and sha1sum all in the same loop.
+
+2003-02-14 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c: Include "euidaccess.h".
+ Remove declaration of euidaccess.
+
+2003-02-12 Jim Meyering <jim@meyering.net>
+
+ * src/pathchk.c (portable_chars_only): Remove unnecessary `const'
+ in cast to avoid warning from icc. Reported by Alexandre Duret-Lutz.
+
+2003-02-10 Jim Meyering <jim@meyering.net>
+
+ * src/test.c: Don't include group-member.h.
+ Include euidaccess.h.
+ (eaccess): Rewrite function to set the real uid and gid temporarily
+ to the effective uid and gid, then invoke 'access', and then set the
+ real uid and gid back. On systems that lack setreuid or setregid,
+ fall back on the kludges in euidaccess. Before, it would not work
+ for e.g., files with ACLs, files that were marked immutable,
+ or on file systems mounted read-only. Nelson Beebe raised the issue.
+ Paul Eggert suggested the new implementation.
+
+2003-02-09 Jim Meyering <jim@meyering.net>
+
+ * src/test.c (test_stat): Remove function. It's job is done (only
+ when necessary) by the wrapper in lib/stat.c. Adjust all uses.
+
+2003-02-08 Jim Meyering <jim@meyering.net>
+
+ * Version 4.5.7.
+
+ * tests/mv/part-symlink: Don't assume that the file owner username
+ length is less than 9 in ls output: instead, omit that field
+ altogether. Reported by, and suggested fix from, Ferdinand.
+
+ * tests/du/restore-wd: New test for just-fixed bug in ftw.c.
+ * tests/du/Makefile.am (TESTS): Add restore-wd.
+
+ * src/rm.c: Correct now-invalid comment about cycle-detection.
+
+2003-02-06 Jim Meyering <jim@meyering.net>
+
+ * NEWS: Add entries from old/*/NEWS
+ from fileutils-4.1 through 4.1.11 and
+ from sh-utils-2.0 through 2.0.15. Suggestion from Karl Berry.
+
+ * Version 4.5.6.
+
+ * src/du.c (process_file): Don't return early for excluded files
+ or for files whose dev/inode we've already seen.
+
+2003-02-05 Jim Meyering <jim@meyering.net>
+
+ * tests/du/exclude: New file.
+ * tests/du/Makefile.am (TESTS): Add exclude.
+
+2003-02-04 Dmitry V. Levin <ldv@altlinux.org>
+
+ * src/who.c (print_boottime, print_deadprocs, print_runlevel):
+ Fix memory allocation arithmetic.
+
+2003-02-04 Jim Meyering <jim@meyering.net>
+
+ `df /dev/block-or-char-device-file--not-mounted' now reports
+ the name of the file system on which the file resides, usually `/'.
+ Before, it would leave the `Mounted on' field blank.
+ * src/df.c (show_disk): Move function to precede find_mount_point.
+ (show_disk): Add parameter: STATP.
+ If we don't find a matching device name, then resort to calling
+ find_mount_point. Reported by Bob Proulx.
+
+2003-02-03 Andreas Schwab <schwab@suse.de>
+
+ * tests/rm/cycle: Require non-root.
+ * tests/rm/isatty: Likewise.
+
+2003-02-02 Jim Meyering <jim@meyering.net>
+
+ * Version 4.5.5.
+
+ * man/Makefile.am (check-x-vs-1): Use @PATH_SEPARATOR@, not `:'.
+
+ Ensure that there are no offending uses of `:'.
+ * Makefile.maint (makefile_path_separator_check): New rule.
+ (local-check): Add it to the list.
+
+2003-02-01 Jim Meyering <jim@meyering.net>
+
+ * src/du.c (MAX_N_DESCRIPTORS): Define.
+
+ * src/stat.c (G_fail): New global.
+ (human_time): Diagnose failed localtime, not failed nstrftime.
+ (main): Fail if G_fail is set.
+
+2003-01-31 Richard Dawe <rich@phekda.freeserve.co.uk>
+
+ * tests/basename/Makefile.am: Use @PATH_SEPARATOR@ instead of
+ hard-coding the path-separator. Also double-quote the new PATH,
+ to avoid problems when the path-separator is a semi-colon or when
+ `pwd` contains e.g. a space.
+ * tests/chgrp/Makefile.am: Likewise.
+ * tests/chmod/Makefile.am: Likewise.
+ * tests/chown/Makefile.am: Likewise.
+ * tests/cp/Makefile.am: Likewise.
+ * tests/dd/Makefile.am: Likewise.
+ * tests/dircolors/Makefile.am: Likewise.
+ * tests/du/Makefile.am: Likewise.
+ * tests/expr/Makefile.am: Likewise.
+ * tests/factor/Makefile.am: Likewise.
+ * tests/fmt/Makefile.am: Likewise.
+ * tests/install/Makefile.am: Likewise.
+ * tests/ln/Makefile.am: Likewise.
+ * tests/ls/Makefile.am: Likewise.
+ * tests/ls-2/Makefile.am: Likewise.
+ * tests/md5sum/Makefile.am: Likewise.
+ * tests/misc/Makefile.am: Likewise.
+ * tests/mkdir/Makefile.am: Likewise.
+ * tests/mv/Makefile.am: Likewise.
+ * tests/od/Makefile.am: Likewise.
+ * tests/rm/Makefile.am: Likewise.
+ * tests/rmdir/Makefile.am: Likewise.
+ * tests/seq/Makefile.am: Likewise.
+ * tests/sha1sum/Makefile.am: Likewise.
+ * tests/shred/Makefile.am: Likewise.
+ * tests/stty/Makefile.am: Likewise.
+ * tests/sum/Makefile.am: Likewise.
+ * tests/tail-2/Makefile.am: Likewise.
+ * tests/touch/Makefile.am: Likewise.
+ * tests/tsort/Makefile.am: Likewise.
+ * tests/unexpand/Makefile.am: Likewise.
+
+2003-01-31 Jim Meyering <jim@meyering.net>
+
+ * src/stat.c: Include "file-type.h"
+ (print_human_type): Remove function.
+ (human_access): Rename from print_human_access. Return a string.
+ (human_time): Rename from print_human_time. Return a string.
+ (print_stat): Arrange so that field width and an alignment specifier
+ are honored for the %A, %F, %x, %y, and %z formats.
+ [%F]: Use file_type; this gives slightly different file type strings,
+ e.g., `directory' instead of `Directory' and `regular file' or
+ `regular empty file' instead of `Regular file'.
+ Prompted by a report from Richard Dawe that the uses of
+ S_IFSOCK and S_IFIFO in print_human_time were not portable
+ to systems using e.g., DJGPP.
+
+2003-01-31 Richard Dawe <rich@phekda.freeserve.co.uk>
+
+ * src/stat.c (print_stat): Use S_ISLNK rather than an explicit
+ test using S_IFMT and S_IFLNK. S_IFLNK may not be defined.
+
+2003-01-31 Jim Meyering <jim@meyering.net>
+
+ * src/du.c (main): Upon processing an invalid option or an invalid
+ --exclude-from or --max-depth option argument, don't exit right away,
+ in case there are others. Rather record the failure and exit after
+ processing other options.
+
+ * GNUmakefile (TAR_OPTIONS): Set and export, in order to make
+ tar archive easier to reproduce.
+
+ Rewrite to perform directory traversal using nftw.
+
+ * src/du.c: Include "dirname.h", "ftw.h", and "quotearg.h".
+ (AUTHORS): Add self.
+ (opt_one_file_system): Move global into `main'.
+ (path, xstat, exit_status): Remove declarations.
+ (arg_length, suffix_length): New globals.
+ (G_fail): New global, sort of like the old `exit_status'.
+ (IS_FTW_DIR_TYPE): Define.
+ (print_only_size): New function.
+ (process_file): New function.
+ (str_init, ensure_space, str_copyc, str_concatc): Remove functions.
+ (str_trunc, pop_dir, count_entry): Likewise.
+ (du_files): Rewrite to use nftw.
+
+2003-01-30 Jim Meyering <jim@meyering.net>
+
+ * tests/du/trailing-slash: Ensure that du/ftw follows a command-line
+ symlink-to-directory with -L, even without the trailing slash.
+
+2003-01-27 Jim Meyering <jim@meyering.net>
+
+ * src/Makefile.am (check-misc): Check for st_blocks, too.
+
+ * src/stat.c (print_stat): Use ST_NBLOCKS rather than `->st_blocks'.
+ Reported by Richard Dawe.
+
+2003-01-27 Andreas Schwab <schwab@suse.de>
+
+ * src/ls.c (quote_name): Add fourth parameter, width, into which to
+ store the screen columns, and return the number of bytes instead.
+ (print_dir): Pass NULL as fourth parameter of quote_name.
+ (print_name_with_quoting): Likewise.
+ (length_of_file_name_and_frills): Get the width from the fourth
+ parameter of quote_name instead of return value.
+
+2003-01-27 Jim Meyering <jim@meyering.net>
+
+ * src/ls.c (decode_switches): If `dired' is set without
+ `format == long_format', then silently reset dired. This doesn't
+ change the behavior of ls (all prior uses of dired were protected
+ by `&& format == long_format'), and lets us...
+ (DIRED_INDENT): ... remove the `format == long_format' conjunct.
+ (PUSH_CURRENT_DIRED_POS): Likewise.
+ (main): Likewise.
+
+2003-01-22 Jim Meyering <jim@meyering.net>
+
+ * tests/du/no-x: New test, for functionality added to lib/ftw.c.
+ * tests/du/Makefile.am (TESTS): Add no-x.
+
+2003-01-21 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (remove_entry) [ROOT_CAN_UNLINK_DIRS
+ && HAVE_STRUCT_DIRENT_D_TYPE]: If a file has d_type == DT_UNKNOWN
+ it may still be a directory -- or not (e.g., with FreeBSD on an
+ NFS-mounted file system), so resort to calling lstat to find out.
+ Based on a patch by Michael van Elst.
+
+ * tests/cp/same-file: Don't assume that the file owner username
+ length is less than 9 in ls output: instead, omit that field
+ altogether. Reported by, and suggested fix from, Ferdinand.
+
+2003-01-20 Jim Meyering <jim@meyering.net>
+
+ * tests/date/Test.pm (wide-fmt): New test to demonstrate that
+ large format widths no longer cause strftime to infloop.
+
+ * Makefile.maint (mail_gpg_sign_cookie): Remove now-unused definition.
+
+2003-01-19 Jim Meyering <jim@meyering.net>
+
+ * src/readlink.c: Include "canonicalize.h".
+
+2003-01-18 Jim Meyering <jim@meyering.net>
+
+ * src/ls.c (Dereference_symlink) [DEREF_COMMAND_LINE_SYMLINK_TO_DIR]:
+ New member.
+ (enum) [DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION]: New member.
+ (long_options): Add option --dereference-command-line-symlink-to-dir.
+ (main): Make DEREF_COMMAND_LINE_SYMLINK_TO_DIR be the default,
+ rather than DEREF_COMMAND_LINE_ARGUMENTS, when none of the
+ -d, -F, -l options is specified.
+ (decode_switches): Handle --dereference-command-line-symlink-to-dir.
+ (gobble_file): Honor DEREF_COMMAND_LINE_SYMLINK_TO_DIR.
+ Change --dereference-command-line (-H) to dereference *all*
+ command line arguments, including broken symlinks.
+
+2003-01-15 Paul Eggert <eggert@twinsun.com>
+
+ Change ls -H back to the way it was yesterday, since this is
+ compatible with FreeBSD and the POSIX spec is confusing
+ and somewhat contradictory.
+
+ * src/ls.c (DEREF_COMMAND_LINE_ARGUMENTS): Change name back
+ from DEREF_COMMAND_LINE_SYMLINK_TO_DIR, updating all uses.
+ (long_options): Change the long option name back.
+ (usage): Change the usage back.
+ (gobble_file): When -H is specified, dereference a top-level
+ arg even if it points to a non-directory.
+
+2003-01-15 Jim Meyering <jim@meyering.net>
+
+ * src/ls.c (gobble_file): Fall back on using lstat when required:
+ when --dereference (-L) is not specified, and
+ - when operating on a dangling symlink
+ - when operating on command-line-symlink-to-directories
+ This fixes numerous problems. Here are examples:
+ - `ls dangling-symlink' would fail with `no such file...'
+ Now it prints `dangling-symlink'.
+ - `ls -i symlink' would mistakenly print the inode of the referent.
+ Now it prints the inode of the symlink. Likewise for --size (-s).
+ Based on a patch from Michael Stone.
+ Reported by Deepak Goel as Debian bug #173793.
+
+ Rename ls's --dereference-command-line (-H)
+ option to --dereference-command-line-symlink-to-dir.
+ * src/ls.c [enum Dereference_symlink]
+ (DEREF_COMMAND_LINE_SYMLINK_TO_DIR): Rename from
+ DEREF_COMMAND_LINE_ARGUMENTS. Update all uses.
+ (long_options): Rename the long option.
+ (usage): Say that --dereference-... changes how ls treats
+ only symlinks to directories specified on the command line.
+
+2003-01-14 Jim Meyering <jim@meyering.net>
+
+ * tests/ls/dangle: New file/test, for the above fix.
+ * tests/ls/inode: Another new file/test, for the above fix.
+ * tests/ls/Makefile.am (TESTS): Add dangle and inode.
+
+ * src/ls.c (gobble_file): Fix a bug introduced in 4.5.4 that made it
+ so that ls --color would no longer highlight the names of files with
+ the execute bit set when not specified on the command line.
+ Patch by Michael Stone. Reported by Stephen Depooter as
+ Debian bug 175135.
+
+ * tests/ls-2/tests (color-exe): New test, for the above fix.
+
+2003-01-13 Jim Meyering <jim@meyering.net>
+
+ * tests/shred/exact: Also test for just fixed bug with --zero.
+
+ * src/shred.c (long_opts): --zero does not require an argument.
+ Patch by Michael Stone. Reported by Roland Turner as Debian bug 172019.
+
+2003-01-12 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (cvs-update): Skip any file with local modifications.
+
+ * src/unexpand.c (usage): Document --first-only and mention that
+ --tabs=N (-t) enables --all (-a). Reported by wiregauze@yahoo.com.
+
+2002-12-01 Dmitry V. Levin <ldv@altlinux.org>
+
+ * src/df.c: Include "canonicalize.h".
+ Use canonicalize_file_name unconditionally.
+
+2003-01-09 Jim Meyering <jim@meyering.net>
+
+ * README: Add readlink.
+
+2002-11-30 Dmitry V. Levin <ldv@altlinux.org>
+
+ * src/df.c: Include "xgetcwd.h".
+ * src/pwd.c: Likewise.
+
+2002-11-30 Dmitry V. Levin <ldv@altlinux.org>
+
+ * src/shred.c: Remove declaration of xstrdup.
+ We already get it via xalloc.h which is included via system.h.
+
+2002-08-27 Dmitry V. Levin <ldv@altlinux.org>
+
+ New program: readlink.
+
+ * src/Makefile.am (bin_PROGRAMS): Add readlink.
+ * src/readlink.c: New file.
+
+ * man/readlink.x: New file.
+ * man/Makefile.am (dist_man_MANS): Add readlink.1.
+ (readlink.1): New rule.
+
+2003-01-09 Jim Meyering <jim@meyering.net>
+
+ When selecting ranges of byte offsets (as opposed to ranges of fields)
+ and when --output-delimiter=STRING is specified, output STRING between
+ ranges of selected bytes.
+ * src/cut.c (RANGE_START_SENTINEL): Define.
+ (output_delimiter_specified): New global.
+ (print_kth): Add parameter. Adjust all callers.
+ (set_fields): Mark each range-start index with RANGE_START_SENTINEL.
+ (cut_bytes): When requested, output STRING between ranges of
+ selected bytes.
+ (main): Make a diagnostic a little clearer.
+ Based on a patch from Jan Nieuwenhuizen.
+
+ * tests/cut/Test.pm: New tests for the above.
+
+ * src/cut.c (set_fields): Make code agree with comment:
+ Don't merge abutting ranges like 4- and 2-3. This makes no
+ difference currently, but is required to support an upcoming change.
+
+2003-01-07 Jim Meyering <jim@meyering.net>
+
+ * src/cut.c (set_fields): Fix typo in comment.
+
+ * tests/touch/not-owner: New test, mostly extracted from fail-diag.
+ * tests/touch/Makefile.am (TESTS): Add not-owner.
+ * tests/touch/fail-diag: Remove the test for non-owner diagnostic.
+ Now, this tests only the nonexistent-directory diagnostic.
+ Suggestion from Michael Stone.
+
+ * tests/touch/fail-diag: Fix typo: s/ld/ls/.
+
+2003-01-04 Jim Meyering <jim@meyering.net>
+
+ * src/copy.h: Remove use of PARAMS.
+ * src/remove.h: Likewise.
+ * src/chown-core.h: Likewise.
+
+ rm could be tricked into mistakenly reporting a cycle.
+ * src/remove.c: [cycle_check_state]: New global.
+ (remove_cwd_entries): Adapt to new semantics of cycle_check.
+ (rm): Call cycle_check_init and cycle_check_free for each file.
+ * tests/rm/cycle (rm): New test, for the above fix.
+ * tests/rm/Makefile.am (TESTS): Add cycle.
+
+ When rm detects a cycle, don't abort the entire command,
+ but rather just the affected command line argument.
+ * src/remove.c: Include <setjmp.h>
+ (struct dirstack_state) [current_arg_jumpbuf]: New member.
+ (remove_cwd_entries): Call longjmp if we detect a cycle.
+ (rm): Call setjmp here.
+
+ * src/remove.c (cycle_check, is_power_of_two): Remove functions.
+ Instead, include cycle-check.h and use it.
+
+ * src/remove.h (struct dev_ino): Remove declaration.
+
+ * src/remove.c (remove_cwd_entries): Fix typos in comment.
+
+ Don't include trailing /. in diagnostics about directories.
+ * src/remove.c (full_filename_): When FILENAME is just `.'
+ and there is a nonempty directory-name part, don't append `/.'.
+ * tests/rm/unread2: Remove trailing /. from diagnostic.
+ * tests/rm/rm2: Likewise.
+
+ * src/remove.c (struct dirstack_state): Define.
+ To be used in place of these file-scoped globals ...
+ (dir_stack, len_stack, Active_dir): Remove globals.
+ (ds_init, ds_free): New functions.
+ (full_filename): Define.
+ (full_filename_): Rename from full_filename.
+
+ Begin to make AD_* functions more generic.
+ * src/remove.c (AD_push_initial): Don't set status to RM_OK here.
+ (AD_push): Likewise.
+ (AD_INIT_OTHER_MEMBERS): Define.
+ (remove_dir): Define the `status' member manually after each
+ call to AD_push or AD_push_initial.
+
+ * src/Makefile.am (check-misc): New rule, to ensure that no more
+ S_IS* macro definitions sneak into the code.
+ (check): Depend on check-misc.
+
+ * src/remove.c [S_ISLNK]: Don't define. It's already defined in sys2.h.
+ * src/du.c (count_entry) [S_ISLNK]: Don't define.
+ * src/shred.c [S_ISLNK, S_ISFIFO, S_ISSOCK]: Don't define.
+
+2003-01-03 Jim Meyering <jim@meyering.net>
+
+ * src/true.c: Add copyright.
+ (AUTHORS): I suppose I've written it.
+
+ * src/Makefile.am (false.c): Make the generated file be read-only.
+
+2003-01-04 Jim Meyering <jim@meyering.net>
+
+ * src/ls.c: Include "dev-ino.h".
+ [struct dev_ino]: Remove declaration.
+
+2003-01-02 Jim Meyering <jim@meyering.net>
+
+ * src/cp.c (do_copy): Tweak diagnostic to be consistent with the one
+ from mv: s/missing file arguments/missing file argument/.
+ With --target-directory=DIR, cp and mv work with a single file argument.
+ Reported by Karl Berry.
+
+ * tests/rm/isatty: Enable this test.
+
+2002-12-31 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (AD_push_initial): Don't set status to RM_OK here.
+ (AD_push): Likewise.
+ (AD_INIT_OTHER_MEMBERS): Define.
+ (remove_dir): Define the `status' member manually after each
+ call to AD_push or AD_push_initial.
+
+ * src/ls.c [struct dev_ino]: Remove definition.
+ Include "dev-ino.h" instead.
+
+2002-12-28 Jim Meyering <jim@meyering.net>
+
+ * tests/du/Makefile.am (TESTS): Add no-deref.
+ * tests/du/no-deref: New script.
+
+2002-12-23 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (remove_cwd_entries): Fix typo in comment.
+
+2002-12-21 Jim Meyering <jim@meyering.net>
+
+ * announce-gen: Generate MML-formatted announcement.
+ This makes it a *lot* harder to send stale MD5/SHA1 signatures.
+
+2002-12-20 Jim Meyering <jim@meyering.net>
+
+ * src/touch.c (touch): Change the wording of a diagnostic so
+ that it makes sense both when the file exists and when it doesn't.
+ Suggestion from Michael Stone.
+
+2002-12-18 Jim Meyering <jim@meyering.net>
+
+ * src/stty.c (valid_options): Declare to be static.
+
+2002-12-15 Jim Meyering <jim@meyering.net>
+
+ * Makefile.cfg: Remove rules related to generating m4/jm-glibc-io.m4.
+
+ * src/chmod.c, src/copy.c, src/copy.h, src/cp-hash.h, src/csplit.c:
+ * src/date.c, src/expr.c, src/fmt.c, src/id.c, src/install.c:
+ * src/ls.c, src/od.c, src/pathchk.c, src/pr.c, src/remove.c:
+ * src/shred.c, src/sort.c, src/stat.c, src/stty.c, src/sum.c:
+ * src/tee.c, src/test.c: Remove all uses of `PARAMS'.
+
+ * src/remove.c (PARAMS): Remove definition.
+ * src/sys2.h: Likewise.
+
+ * src/ls.c, src/stat.c, src/date.c: Remove declaration of nstrftime.
+ Include strftime.h instead.
+
+2002-12-14 Jim Meyering <jim@meyering.net>
+
+ * Makefile.cfg ($(url_dir_list)): Use .../coreutils, not .../fetish.
+
+ * src/system.h [! HAVE_DECL_MEMRCHR]: Declare memrchr.
+ This is necessary at least for Irix6.5 when using c89.
+ Reported by Nelson Beebe.
+
+ * tests/misc/Makefile.am (TESTS): Add cat-tty-eof.
+
+ * tests/misc/cat-tty-eof: New test.
+
+ * src/mknod.c (usage): Specify how major and minor mode numbers
+ are interpreted. Report forwarded by Kristin E Thomas.
+ * src/mknod.c: Remove now-redundant usage-specifying comment.
+
+2002-12-13 Jim Meyering <jim@meyering.net>
+
+ * Version 4.5.4.
+
+ * tests/du/trailing-slash: Allow for a directory of size `0'.
+ That happens at least on file systems of type tmpfs on linux-2.4.18.
+
+ * announce-gen: New script to begin replacing the commands
+ associated with the rule here...
+ * Makefile.maint (announcement): Invoke announce-gen.
+ * Makefile.am (EXTRA_DIST): Add announce-gen.
+
+ * tests/cp/preserve-2: New file/test, for latest fix.
+ * tests/cp/Makefile.am (TESTS): Add preserve-2.
+
+2002-12-11 TAKAI Kousuke <takai@vlsi.kuee.kyoto-u.ac.jp>
+
+ Fix a bug whereby cp would fail to parse an option like
+ --preserve=mode,ownership.
+ * src/cp.c (decode_preserve_arg): Advance `comma' to
+ point the character following the comma.
+
+2002-12-11 Jim Meyering <jim@meyering.net>
+
+ * src/pathchk.c (NEED_PATHCONF_WRAPPER): Undefine before defining,
+ in case it's already defined.
+
+2002-12-09 Jim Meyering <jim@meyering.net>
+
+ * tests/touch/fail-diag: Don't get a test failure if /no exists.
+ Instead, evoke a framework failure if /no-$$ exists.
+ Reported by Michael Stone.
+
+2002-12-08 Jim Meyering <jim@meyering.net>
+
+ * src/du.c (lstat) [! LSTAT_FOLLOWS_SLASHED_SYMLINK]:
+ Define to rpl_lstat, so that even on systems like Solaris 5.8,
+ du honors (per POSIX) the trailing slash on an argument referring
+ to a symlink-to-directory.
+
+2002-12-06 Jim Meyering <jim@meyering.net>
+
+ * Use autoconf-2.57. Regenerate dependent files.
+ * Use automake-1.7.2. Regenerate dependent files.
+
+ * src/ls.c (gobble_file): Also stat the file if it's a
+ regular file and --indicator-style=classify (aka -F).
+ Thanks to Ed Santiago for opening my eyes.
+
+ * tests/ls/file-type: New file. Test for the above.
+ A test to contrast ls -F and ls --indicator-style=file-type.
+ * tests/ls/Makefile.am (TESTS): Add file-type.
+
+2002-12-04 Jim Meyering <jim@meyering.net>
+
+ * tests/ls/follow-slink: Make sure the symlink was created.
+ Richard Dawe reported that `ln -s link link' succeeds, but creates
+ no file on systems running some version of the DJGPP libc.
+
+2002-12-03 Jim Meyering <jim@meyering.net>
+
+ * src/Makefile.am (AUTOMAKE_OPTIONS): Remove definition (to ansi2knr)
+ since this package no longer panders to K&R compilers.
+
+2002-12-02 Jim Meyering <jim@meyering.net>
+
+ * tests/du/slink: Skip this test if `.' is on a non-local file system.
+
+ * tests/Fetish.pm (_at_replace): Do the substitution only if there's
+ something to replace.
+
+2002-12-01 Jim Meyering <jim@meyering.net>
+
+ * src/stat.c: Don't include <string.h> or <ctype.h>.
+ That's already done via system.h.
+ * src/dircolors.c: Don't include <ctype.h>.
+
+2002-11-30 Jim Meyering <jim@meyering.net>
+
+ * ls.c (gobble_file): Remove the block of code that caused
+ `ls --color -F symlink-to-dir' to list the files in
+ `symlink-to-dir/.'. Now, it prints `symlink-to-dir@', (just
+ like `ls -F symlink-to-dir') but with the addition of highlighting.
+ Similarly, `ls --color -dF symlink-to-dir' would print
+ `symlink-to-dir/'; now it prints `symlink-to-dir@'.
+ Reported by Jeff Sheinberg as Debian bug #168203.
+ * tests/ls-2/tests (sl-F-color, sl-dF-color): New tests for the above.
+
+ ls is now more efficient: with certain options, it no longer needs
+ to stat each directory entry on systems with valid dirent.d_type.
+ * src/ls.c (print_dir): Add DT_LNK and DT_REG.
+ (main): Make --recursive set format_needs_type, not format_needs_stat.
+ (gobble_file): Remove a FIXME comment, now that it's fixed.
+
+2002-11-24 Jim Meyering <jim@meyering.net>
+
+ * src/du.c (du_files): Don't strip any trailing slash.
+ Rewrite so that `/' is no longer represented internally as
+ the empty string.
+ (count_entry): When appending a file name component,
+ account for the fact that the current path may end in `/'.
+ François Pinard reported that `du symlink-to-dir/' was not
+ equivalent to `du symlink-to-dir/.'. Now it is.
+ * tests/du/trailing-slash: New file/test, for the above fix.
+ * tests/du/Makefile.am (TESTS): Add trailing-slash.
+
+2002-11-23 Jim Meyering <jim@meyering.net>
+
+ * src/tac.c (output): Declare some local variables to be of type size_t,
+ rather than `int' to avoid warnings from gcc.
+
+2002-11-21 Paul Eggert <eggert@twinsun.com>
+
+ * src/ls.c (decode_switches): Use case-sensitive matching to
+ decode the QUOTING_STYLE environment variable. This is more
+ consistent with the documentation, and with --quoting-style.
+
+2002-11-21 Martin Buck <martin.buck@ascom.ch
+
+ * src/stty.c (struct speeds): Add support for all baud rates defined
+ in linux-2.4.19.
+
+2002-11-19 Jim Meyering <jim@meyering.net>
+
+ * tests/sum/sysv: Export LC_ALL=C, to avoid failure when
+ run in a UTF locale. Report and suggested fix by Bruno Haible.
+ * tests/fmt/basic: Likewise.
+
+2002-11-17 Jim Meyering <jim@meyering.net>
+
+ * configure.ac: Update via autoupdate.
+ Add `AM_GNU_GETTEXT_VERSION(0.11.5)'.
+
+ * src/mv.c (movefile): Don't remove trailing slashes from SOURCE.
+ Reported by Hans Ginzel.
+
+2002-11-15 Jim Meyering <jim@meyering.net>
+
+ * Makefile.cfg (gnu_rel_host): Define.
+ (url_dir_list): Choose from (alpha|ftp).gnu.org depending
+ on whether $(VERSION) looks like a major release number.
+
+ * Makefile.maint (mail_gpg_sign_cookie): Backslash-escape `#'.
+ (release): Rename from `alpha'.
+ (alpha): Depend on release.
+
+ * Makefile.maint (signatures): Define with ?=, so it's easy to override.
+
+2002-11-14 Jim Meyering <jim@meyering.net>
+
+ * Makefile.maint (mail_gpg_sign_cookie): Make optional.
+ (announcement): Use the new variable.
+
+ * Makefile.maint: Sync with Bison, i.e.:
+ (po-check): Scan .l and .y files instead of the
+ .c and the .h files that they generate. This fixes the bug
+ reported by Tim Van Holder in:
+ <http://mail.gnu.org/pipermail/bison-patches/2002-November/001352.html>
+ Look for N_ as well as for _. Try to avoid matching #define for
+ N_ and _.
+ From Paul Eggert.
+
+2002-11-12 Jim Meyering <jim@meyering.net>
+
+ * src/ls.c (HAVE_SYMLINKS): Remove unnecessary macro definition.
+ Replace sole use with equivalent `#ifdef S_ISLNK'.
+ Inconsistency reported by Dmitry V. Levin.
+
+2002-11-11 Jim Meyering <jim@meyering.net>
+
+ * src/stat.c (usage): Transform --help items output via s/ - / /,
+ so that help2man produces properly formatted man pages.
+ Reported by Herbert Xu as Debian bug #168400.
+
+2002-11-10 Jim Meyering <jim@meyering.net>
+
+ * src/ls.c (sighandler): Handle SIGTSTP specially.
+ Based on suggestions from Solar Designer and Dmitry V. Levin.
+ Add comments.
+
+ * Makefile.cfg (cvs_files): Define. From autoconf.
+ (local_updates): Likewise.
+
+ * src/ls.c (restore_default_color_handler, sigtstp_handler):
+ Remove functions.
+ (sighandler): New function, based on the one in sort.c.
+ (main): Use sigaction, if possible; otherwise signal.
+ Handle these signals:
+ SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, SIGTSTP.
+ Don't register our handler if the signal is already being ignored.
+
+ * src/dd.c (interrupt_handler): Use raise, rather than kill+getpid.
+ * src/csplit.c (interrupt_handler): Likewise.
+ * src/sort.c (sighandler): Likewise.
+ (main): Declare `i' and `nsigs' to be unsigned, not int.
+
+2002-11-09 Jim Meyering <jim@meyering.net>
+
+ ls --color: restore terminal text color upon signal.
+ * src/ls.c: Include "full-write.h" and <signal.h>.
+ (restore_default_color, restore_default_color_handler): New functions.
+ (sigtstp_handler, put_indicator_direct): New functions.
+ (main) [print_with_color]: Register signal handlers.
+ Patch mostly by Solar Designer and Stanislav Ievlev.
+
+ Update from autoconf.
+ * Makefile.maint (AMTAR): Remove definition.
+ (update, cvs-update, po-update, do-po-update): New rules.
+ (wget-update): Update (thus renaming to cvs-update).
+ (automake_repo): Use anoncvs@sources.redhat.com.
+
+2002-11-06 Jim Meyering <jim@meyering.net>
+
+ * tests/misc/Makefile.am (TESTS): Add printf-hex.
+
+ * tests/misc/printf: Be careful to test the code in this package,
+ not the shell built-in function.
+
+ * src/printf.c (print_esc): A hexadecimal escape sequence has
+ at most two hex. digits, not three. Reported by Padraig Brady.
+ (usage): Update description.
+ * tests/misc/printf-hex: New file/test, for the above fix.
+
+2002-10-07 Paul Eggert <eggert@twinsun.com>
+
+ Add support for locale-specific size indications (e.g.,
+ thousands-separators) and for explicit size suffixes on output.
+
+ * doc/coreutils.texi (Block size): Say that:
+ This affects display format as well as block size.
+ Fractional block counts are rounded up.
+ ls file size blocksize defaults to 1.
+ A block size spec preceded by ' generates thousands separators.
+ A suffix without a preceding integer generates suffixes.
+ (tail invocation): 32k -> 32 KiB.
+ (What information is listed): ls -h is now equivalent to
+ ls --block-size=human, and ls -H is now equivalent to
+ ls --block-size=si. Displayed file size is now always affected by
+ --block-size.
+
+ * lib/inttostr.c, lib/inttostr.h, lib/imaxtostr.c, lib/offtostr.c,
+ lib/umaxtostr.c: New files, taken from GNU tar.
+
+ * lib/Makefile.am (libfetish_a_SOURCES): Add imaxtostr.c, offtostr.c,
+ umaxtostr.c.
+ (EXTRA_DIST): Add inttostr.c.
+
+ * lib/human.c, lib/human.h: Rewrite to support locale-specific
+ notations like thousands separators.
+ Specify what includer of include.h must include beforehand.
+ (human_group_digits, human_suppress_point_zero, human_autoscale,
+ human_base_1024, human_SI, human_B): New enum values.
+ (human_readable): Rename from human_readable_inexact; put the
+ options before the sizes. All uses changed. The old human_readable
+ function has been removed; use inttostr.h instead.
+ (human_options): Renamed from human_block_size, with new signature
+ that allows block sizes up to UINTMAX_MAX. All callers changed.
+
+ * m4/prereq.m4 (jm_PREREQ_HUMAN): Check for locale.h, localeconv,
+ AC_HEADER_STDBOOL. No need to check for limits.h since it's in
+ freestanding C89. No need to check for stdlib.h or string.h since
+ autoconf does this now.
+
+ * src/cksum.c (cksum): Use primitives from inttostr.h, not
+ human.h, to print large numbers simply.
+ * src/csplit.c (handle_line_error, parse_patterns): Likewise.
+ * src/dd.c (print_stats, main): Likewise.
+ * src/df.c (print_header): Likewise.
+ * src/factor.c (print_factors): Likewise.
+ * src/ls.c (print_long_format, print_file_name_and_frills): Likewise.
+ * src/shred.c (dopass): Likewise.
+ * src/sort.c (checkfp): Likewise.
+ * src/sum.c (bsd_sum_file, sysv_sym_file): Likewise.
+ * src/tail.c (xlseek): Likewise.
+ * src/wc.c (write_counts, wc): Likewise.
+
+ * src/df.c (human_output_opts): New var.
+ (output_block_size): Now uintmax_t, not int, to handle larger
+ block sizes. All uses changed.
+ * src/du.c: Likewise.
+ * src/ls.c: Likewise.
+
+ * src/df.c (print_header): In the header line, prefer SI to human
+ representation if it's shorter; if neither is shorter, try to
+ intuit what the user would prefer.
+
+ * src/expr.c (inttostr): Remove; use new imaxtostr library
+ function instead.
+
+ * src/ls.c (file_output_block_size): New var, to distinguish
+ file sizes from other sizes.
+ (decode_switches): Set it.
+
+ * src/shred.c (OUTPUT_BLOCK_SIZE): remove.
+ (dopass): When printing progress, use floor for what has been done
+ so far (since we should be conservative there), and ceiling for
+ what needs to be done (since that's what other programs use).
+
+2002-10-19 Jim Meyering <jim@meyering.net>
+
+ * src/pinky.c (print_heading): Align TTY and Name headings.
+ Reported by Karl Eichwalder.
+
+2002-10-18 Jim Meyering <jim@meyering.net>
+
+ * src/split.c (cwrite): Change type of `bytes' parameter to size_t
+ Remove now-useless cast.
+ (stdread): Remove function.
+ (bytes_split): Use size_t instead of int.
+ Use safe_read, not stdread.
+ (lines_split): Likewise.
+ Use memchr rather than a `while' loop.
+ (line_bytes_split): Use size_t instead of int.
+ Use safe_read, not stdread.
+ (main): Add some FIXME comments to remind me to remove casts.
+
+ * src/system.h (ST_BLKSIZE): Correct comment describing how to
+ reproduce HPUX-11 cat failure. From Petter Reinholdtsen.
+
+2002-10-17 Jim Meyering <jim@meyering.net>
+
+ Fix a problem that could make e.g., `cat' misbehave on systems which
+ give invalid (unreasonably large) values for stat.st_blksize.
+ * src/system.h (ST_BLKSIZE): Ensure that the result is in [1..4MB].
+ Reported by Petter Reinholdtsen.
+
+2002-10-14 Jim Meyering <jim@meyering.net>
+
+ Specifying a printf conversion specifer as nl's separator string
+ could cause nl to segfault.
+ * src/nl.c (build_print_fmt): Don't include separator string
+ in the printf format; it might contain `%'.
+ Use a better bound on the length of the print_fmt buffer.
+ (print_lineno): Print the separator here instead.
+ Reported by Doug Coleman.
+
+ * tests/misc/nl: New file/tests, including a test for the above.
+ * tests/misc/Makefile.am (TESTS): Add nl.
+
+ * tests/misc/split-l: New test, to make sure `split --lines=N' works.
+ * tests/misc/Makefile.am (TESTS): Add split-l.
+
+2002-10-13 Jim Meyering <jim@meyering.net>
+
+ * Version 4.5.3.
+
+ * src/du.c (usage): Tweak description of --dereference-args/-D.
+
+ * src/du.c (count_entry): Also save cwd when dereferencing (via
+ --dereference-args, -D) a command-line argument.
+ Reported by Michal Svec. Based on a patch by Andreas Schwab.
+
+ * src/Makefile.am (../AUTHORS): New target/rule.
+
+2002-10-12 Jim Meyering <jim@meyering.net>
+
+ * src/paste.c (paste_parallel): Declare local, `delims_saved', to be
+ of type size_t, since that's the way it's used and avoids a warning.
+
+ * src/csplit.c (struct cstring) [len]: Declare to be unsigned int,
+ since that's how it's always used and avoids a new warning from gcc.
+ (read_input): Adapt to new safe_read ABI.
+
+ * src/cut.c (cut_fields): Add a temporary size_t variable, n_bytes,
+ to avoid warnings.
+
+ * src/pinky.c (print_long_entry): fread returns size_t.
+ Declare local `bytes' accordingly, to avoid warning.
+
+ tail -c +N would perform an extra read after encountering EOF
+ [this change is analogous (bytes vs. lines) to the one of 2002-01-27]
+ * src/tail.c (start_bytes): Detect EOF, inform caller.
+ (tail_bytes): Upon EOF in start_bytes, return immediately.
+ (file_lines): Reorganize to use memrchr rather than an explicit loop.
+ Adapt to new safe_read ABI.
+
+2002-10-11 Jim Meyering <jim@meyering.net>
+
+ * tests/du/deref: New file/test, for the above fix.
+ * tests/du/Makefile.am (TESTS): Add deref.
+
+2002-10-10 Jim Meyering <jim@meyering.net>
+
+ * tests/ln/Makefile.am (TESTS): Add target-1.
+ * tests/ln/target-1: New file/test, for the fix on 2002-10-08.
+
+2002-10-09 Jim Meyering <jim@meyering.net>
+
+ * tests/cp/backup-is-src: Ensure that certain environment variables
+ are not set (e.g., SIMPLE_BACKUP_SUFFIX). Reported by Duncan Roe.
+
+ * tests/tail-2/big-4gb: Mark this as an expensive test; it would
+ consume 4GB of disk space on systems without support for sparse files.
+ Fix a logic error that'd make it `cat err' even though dd didn't fail.
+
+ * src/dircolors.hin (.jar): Fix typo: s/;3$/;31/.
+ Patch by steven@magelico.net, forwarded by Michael Stone.
+
+ * tests/ls/dired: Ensure that ls produces English messages.
+ Patch by Alexey Vyskubov, forwarded by Michael Stone.
+
+2002-10-08 Dmitry V. Levin <ldv@altlinux.org>
+
+ * src/ln.c (main): Fix target_directory parsing when n_files == 1.
+
+2002-10-08 Jim Meyering <jim@meyering.net>
+
+ * tests/tail-2/big-4gb: Use double quotes around diagnostic.
+ Fix syntax in test: use =, not ==.
+ Reported by Bob Proulx.
+ Change all the rest like this: grep -lR "testing framework'" .\
+ |xargs perl -pi -e 's/'\''(\$0: failure in testing framework)'\''/"$1"/'
+
+ * src/sum.c (sysv_sum_file): Adapt to new safe_read ABI.
+ * src/tr.c (squeeze_filter, read_and_delete, read_and_xlate): Likewise.
+ * src/tac.c (save_stdin, tac_stdin_to_mem): Likewise.
+ * src/wc.c (wc): Likewise.
+
+2002-10-07 Paul Eggert <eggert@twinsun.com>
+
+ * src/cat.c (cat):
+ Don't advance the write pointer past the end of the write buffer.
+ * src/sort.c (begfield, limfield): Likewise.
+
+2002-10-07 Jim Meyering <jim@meyering.net>
+
+ * src/cat.c (simple_cat, cat): Adapt to new safe_read ABI.
+ * src/head.c (head_bytes, head_lines): Likewise.
+
+2002-10-06 Jim Meyering <jim@meyering.net>
+
+ * src/dd.c (scanargs): Ensure that specified block sizes (specified
+ via ibs=N, obs=N, and bs=N) are no larger than SSIZE_MAX.
+ (skip, dd_copy): Adapt to new safe_read ABI.
+
+ * Makefile.maint (signatures): Define.
+ (%.sig): New rule.
+ (announcement): Depend on $(signatures).
+
+ * Makefile.maint (announcement): Output all URLs for detached
+ signatures, not just the last one from the previous loop.
+
+2002-10-05 Jim Meyering <jim@meyering.net>
+
+ * Version 4.5.2.
+
+ * src/remove.c (remove_entry) [ROOT_CAN_UNLINK_DIRS]: With `rm -i DIR',
+ don't recurse into directory, DIR. Prompted by a report from
+ Leonardo Milano.
+
+ * tests/rm/i-no-r: New file/test, for the above fix.
+ * tests/rm/Makefile.am (TESTS): Add i-no-r.
+
+ * tests/tail-2/big-4gb: New file/test, for the fix of 2002-09-27.
+ * tests/tail-2/Makefile.am (TESTS): Add big-4gb.
+
+2002-10-03 Jim Meyering <jim@meyering.net>
+
+ * src/rm.c (AUTHORS): Mark translatable string with `N_ (...)'.
+ * src/df.c (AUTHORS): Likewise.
+ * src/du.c (AUTHORS): Likewise.
+ * src/tail.c (AUTHORS): Likewise.
+ * src/touch.c (AUTHORS): Likewise.
+
+2002-10-02 Jim Meyering <jim@meyering.net>
+
+ * Makefile.am (SUBDIRS): Remove `old'.
+ (EXTRA_DIST): List the files in old/.
+ * configure.ac (AC_CONFIG_FILES): Remove old/* names.
+ Suggestion from Akim Demaille.
+
+2002-10-01 Jim Meyering <jim@meyering.net>
+
+ * src/sys2.h (SSIZE_MAX): Define.
+
+2002-09-30 Jim Meyering <jim@meyering.net>
+
+ * src/csplit.c: Don't include stdlib.h here. It's already included
+ via system.h.
+
+2002-09-29 Jim Meyering <jim@meyering.net>
+
+ * src/tr.c (find_bracketed_repeat): Rearrange pointer/integer
+ expression to avoid bogus warning from gcc.
+
+ * src/cat.c (simple_cat): Use a temporary to avoid bogus warnings.
+ (cat): Declare insize and outsize to be of type size_t, not int.
+ Rearrange pointer/integer expressions to avoid bogus warnings.
+ (main): Declare insize and outsize to be of type size_t, not int.
+
+ * src/tail.c (parse_options): Give a sensible diagnostic for
+ an invalid byte or line count. Reported by Mikko Tuumanen.
+
+ * src/touch.c (main): Split a long line.
+
+ * tests/du/Makefile.am (TESTS): Add slink.
+ * tests/du/slink: New test for system.h change of 2002-08-31.
+
+ In move mode, always first try to rename. Before, upon failure to
+ rename a directory, this code would never attempt to rename any
+ other file in that directory, but would thenceforth always copy.
+ On some systems (e.g., NetApp's OnTap-6.4), renaming a directory
+ may fail with EXDEV, yet renaming files within that directory to
+ a newly-created destination directory succeeds.
+ * src/copy.c (copy_internal): Remove local, move_mode;
+ use x->move_mode instead. Based on a patch from Tom Haynes.
+
+2002-09-28 Jim Meyering <jim@meyering.net>
+
+ * src/split.c (FAIL_ONLY_ONE_WAY): New macro.
+ Factor out some duplication.
+ (main): Use it.
+ [case 'a']: Use strtoul rather than strtol to avoid compiler warnings.
+
+ * src/sort.c (begfield, limfield): Rearrange comparisons to avoid
+ compiler warnings.
+ (fillbuf, keycompare): Cast literal `-1' to size_t in comparisons,
+ to avoid compiler warnings.
+
+ * src/shred.c (dopass): Use a uintmax_t temporary to avoid bogus
+ compiler warnings.
+
+ Fix things so `mkdir -p' can create very deep directories, e.g.,
+ mkdir -p $(perl -e 'print "a/" x 40000') now works.
+ * src/mkdir.c (main): For --parents (-p), call make_path with the
+ entire directory name, so we don't ever require that file operations
+ like stat or chmod be performed on the entire command line argument.
+ * makepath.c (make_path): Restore umask *before* creating the final
+ component.
+
+2002-09-27 Andreas Schwab <schwab@suse.de>
+
+ * src/tail.c (tail_bytes): Change type of bytes_remaining to off_t
+ to avoid overflow. Reported by Hans Lermen.
+
+2002-09-26 Jim Meyering <jim@meyering.net>
+
+ * src/install.c (get_ids): Use strtoul, not strtol. Remove some casts.
+
+2002-09-25 Jim Meyering <jim@meyering.net>
+
+ * src/test.c (eaccess): Change type of local `euid' from int to uid_t
+ and add a cast, to avoid a warning about `signed and unsigned type in
+ conditional expression'.
+
+2002-09-22 Jim Meyering <jim@meyering.net>
+
+ * src/rmdir.c: Include "dirname.h", for declaration of
+ strip_trailing_slashes.
+
+ * src/stat.c (PRIdMAX, PRIuMAX): Remove definitions.
+ Now they're defined through system.h.
+
+ * src/cp-hash.c, src/dd.c, src/df.c, src/du.c, src/ls.c,
+ * src/stat.c, src/wc.c: Remove all inclusions of inttypes.h,
+ since it's already included from sys2.h via system.h.
+
+ * Use automake-1.6f. Regenerate dependent files.
+
+ * src/Makefile.am (PERL): Remove duplicate definition.
+
+ fmt's -s, -t, -c options didn't work properly for long lines.
+ Since get_line may end up calling put_paragraph (for long lines),
+ be sure to set global, `other_indent', before it is used there.
+
+ * src/fmt.c (set_other_indent): New function, factored out of...
+ (get_paragraph): ... here. Call it.
+ (get_line): Call set_other_indent before calling flush_paragraph,
+ which calls fmt_paragraph, which in turn calls put_paragraph,
+ which uses other_indent.
+
+ * tests/fmt/Makefile.am (TESTS): Add long-line.
+ * tests/fmt/long-line: New file/test, for the above fix.
+
+2002-09-21 Jim Meyering <jim@meyering.net>
+
+ * src/od.c: No longer include deprecated <values.h>.
+ It was required solely for now-removed reference to BITSPERBYTE.
+ * src/install.c: Likewise.
+ Suggestion from Bruno Haible.
+
+2002-09-06 Andreas Schwab <schwab@suse.de>
+
+ `rmdir -p dir-specified-with-trailing-slash/' would fail.
+ * src/rmdir.c (remove_parents): Strip trailing slashes.
+
+2002-09-20 Jim Meyering <jim@meyering.net>
+
+ * tests/rmdir/t-slash: New file/test, for the above fix.
+ * tests/rmdir/Makefile.am (TESTS): Add t-slash.
+
+ * Makefile.maint (announcement): Arrange to gpg-sign the message.
+ Add a URL for each detached signature file.
+
+2002-09-07 Bruno Haible <bruno@clisp.org>
+
+ * configure.ac: Add need-ngettext to AM_GNU_GETTEXT invocation.
+
+2002-09-18 Jim Meyering <jim@meyering.net>
+
+ `od -t x8' used the wrong (`l'-prefixed) printf format.
+ Likewise for the o8 and u8 formats.
+ * src/od.c (ISPEC_TO_FORMAT): Define macro.
+ (decode_one_format): Use PRIdMAX, PRIoMAX, etc. for LONG_LONG.
+ Reported by Arun Sharma.
+
+2002-09-17 Jim Meyering <jim@meyering.net>
+
+ * src/sys2.h (PRIdMAX, PRIoMAX, PRIuMAX, PRIxMAX): Define if necessary.
+ From gettext's intl/loadmsgcat.c.
+
+ * tests/od/x8: New file/test, for the above fix.
+ * tests/od/Makefile.am (TESTS): Add x8.
+
+2002-09-15 Jim Meyering <jim@meyering.net>
+
+ * Use autoconf-2.54. Regenerate dependent files.
+
+ * src/csplit.c (get_format_width): Add cast to avoid
+ warning about `signed and unsigned type in conditional expression'.
+
+2002-09-14 Jim Meyering <jim@meyering.net>
+
+ * src/who.c (print_user): Change type of local to size_t
+ to avoid warnings about `comparison between signed and unsigned'.
+ * src/ptx.c (generate_all_output): Likewise.
+
+ * src/dd.c (main, skip): Add casts to avoid warnings about
+ `comparison between signed and unsigned'.
+
+ * src/id.c (print_full_info, print_group_list): Add casts to avoid
+ warnings about `signed and unsigned type in conditional expression'.
+
+ * src/md5sum.c: Change type of global, digest_hex_bytes, to size_t
+ to avoid warnings about `comparison between signed and unsigned'.
+ (split_3): Change parameter names to be readable and add comment.
+ Clean up the test for whether a line may be ignored.
+
+2002-09-13 Jim Meyering <jim@meyering.net>
+
+ * src/printf.c (main): Handle leading command line argument of `--'.
+ Reported by Raul: DervishD <raul@pleyades.net>
+ * tests/misc/printf: New file: test for the above.
+ * tests/misc/Makefile.am (TESTS): Add printf.
+
+ * src/date.c (usage): Explain that %S's range of [0..60] is required --
+ rather than 0..59 -- to accommodate the occasional positive leap second.
+ Reported by Richard Neill.
+
+2002-09-12 Jim Meyering <jim@meyering.net>
+
+ * src/Makefile.am (nanosec_libs): Define.
+ (sleep_LDADD, tail_LDADD): Use it here.
+
+ Factor nanosleep-related code into ../lib/xnanosleep.c.
+ * src/sleep.c: Include xnanosleep.h.
+ Factor out fenv.h-related code.
+ (timespec_subtract): Remove function.
+ (main): Remove code that deals with computing start and stop times
+ as well as the loop around nanosleep. Now that's in xnanosleep.c.
+
+ Allow S (in --sleep-interval=S) to be a floating point value.
+ * src/tail.c: Include xnanosleep.h and xstrtod.h.
+ Move declaration of global variable, sleep_interval, to ...
+ (main): ...here.
+ (usage): Update description of --sleep-interval option.
+ (tail_forever): New parameter, sleep_interval. Update caller.
+ Use xnanosleep, rather than sleep.
+ (parse_options): New parameter, sleep_interval. Update caller.
+ Use xstrtod, now that we accept floating point values.
+ Prompted by a patch from Augey Mikus.
+
+2002-09-06 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (prompt): Change comment to give a better note to
+ translators. From Michael Piefel.
+
+2002-09-02 Jim Meyering <jim@meyering.net>
+
+ * README: A good problem report/patch includes diffs against
+ the most recent test release.
+
+ * src/pathchk.c (NEED_PATHCONF_WRAPPER): Define.
+ (pathconf_wrapper): Define only if NEED_PATHCONF_WRAPPER is set.
+
+ * src/kill.c (print_table_row): Use an unsigned type for widths
+ to avoid warning about comparison between signed and unsigned.
+ (list_signals): Likewise.
+
+ * src/od.c (skip): Add a cast to avoid warning about comparison
+ between signed and unsigned.
+ * src/install.c (get_ids): Likewise. Also rearrange range-checking
+ comparisons to make them more readable.
+
+2002-09-01 Jim Meyering <jim@meyering.net>
+
+ * Version 4.5.1.
+
+2002-08-31 Jim Meyering <jim@meyering.net>
+
+ Symlinks were always reported as using 0 blocks.
+ * src/system.h (ST_NBLOCKS): Don't depend on file type.
+ This reverts the change of 2000-01-30.
+ Based on a report and patch from Neil Brown via Michael Stone.
+ This fixes Debian Bug#156358.
+
+ * Most files: Change `exit (0)' to `exit (EXIT_SUCCESS)',
+ `exit (1)' to `exit (EXIT_FAILURE)', and
+ `usage (1)' to `usage (EXIT_FAILURE)'.
+
+ * chgrp.c, chmod.c, chown.c, chroot.c, cp.c, date.c, dd.c, du.c,
+ * hostname.c, id.c, install.c, ln.c, mkdir.c, mkfifo.c, mknod.c,
+ * nice.c, pinky.c, printf.c, pwd.c, shred.c, sleep.c, stty.c,
+ * su.c, tac-pipe.c, tail.c, tee.c, touch.c, uname.c, uptime.c,
+ * users.c, who.c: Change `error (1, ...' to `error (EXIT_FAILURE, ...'.
+ But don't change `error (0, ...' to `error (EXIT_SUCCESS, ...', since
+ error never exits successfully.
+
+2002-08-29 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (remove_cwd_entries): Use closedir (not CLOSEDIR)
+ when ignoring any return value.
+
+ * src/remove.c (remove_cwd_entries): Detect and diagnose readdir
+ failures. On some systems (at least EMC Celerra and Solaris5.8),
+ this appears to be necessary.
+ (is_empty_dir): Likewise. Also, always close directory handle.
+ * src/ls.c (print_dir): Likewise.
+ (print_dir): Rename local variable: reading -> dirp.
+ Reported by Mike Coleman.
+
+2002-08-28 Jim Meyering <jim@meyering.net>
+
+ * src/remove.c (remove_cwd_entries): Use CLOSEDIR, not closedir.
+ Give a diagnostic and fail if closedir fails.
+
+2002-08-26 Jim Meyering <jim@meyering.net>
+
+ * Makefile.am (THANKS-to-translators): New rule.
+ (EXTRA_DIST): Add both THANKS-to-translators and THANKStt.in.
+ * THANKStt.in: New file.
+
+ * src/cat.c (close_stdout_wrapper): New, kludgey, function and
+ file-scoped global.
+ (main): Register it with atexit.
+ Close STDOUT_FILENO, to avoid a problem when writing to
+ /dev/audio on at least Solaris 5.7 and 5.8 systems.
+ Reported by Shing-Shong Shei.
+
+2002-08-25 Jim Meyering <jim@meyering.net>
+
+ * src/cat.c (main): Close STDIN_FILENO rather than a literal `0'.
+ * src/tac.c (main): Likewise.
+ * src/tail.c (main): Likewise.
+ * src/tee.c (main): Likewise.
+ * src/tr.c (main): Likewise.
+ * src/wc.c (main): Likewise.
+
+2002-08-20 Jim Meyering <jim@meyering.net>
+
+ * tests/mv/setup: Rewrite not to use `: ${VAR=not_set}' paradigm.
+
+2002-08-10 Paul Eggert <eggert@twinsun.com>
+
+ * src/nohup.sh: Don't use "exec --"; it's not portable and
+ shouldn't be needed.
+
+2002-08-09 Jim Meyering <jim@meyering.net>
+
+ * src/pr.c (main): Don't ignore -COLUMN if it's the last option.
+ (usage): Clarify help text for the -COLUMN option.
+ Patch by Padraig Brady.
+ * tests/pr/Test.pm [col-last]: New test for the above.
+
+ * configure.ac: Start with version 4.5.1, chosen so that it's larger
+ than the latest version numbers of the component packages.
+
+ * man/Makefile.am (check-x-vs-1): Set and export PATH so we use
+ programs in ../src.
+
+2002-08-08 Jim Meyering <jim@meyering.net>
+
+ * src/date.c: Guard inclusion of <langinfo.h> with
+ `#if HAVE_LANGINFO_CODESET', not `#if HAVE_LANGINFO_H'.
+ * src/sort.c: Likewise.
+ Patch by GOTO Masanori.
+
+2002-08-05 Paul Eggert <eggert@twinsun.com>
+
+ Fix some minor time-related bugs with POSIX time arguments.
+ Some valid time stamps were being rejected (notably -1, and
+ time stamps before 1900 on 64-bit hosts). And some invalid
+ time stamps were being accepted, e.g. September 31.
+
+ * src/date.c (main): Adjust to posixtime signature change.
+ * src/touch.c (main): Likewise. Remove unnecessary initialization.
+ Use localtime, not posixtm, to warn about obsolete "touch".
+
+2002-08-05 Jim Meyering <jim@meyering.net>
+
+ * tests/misc/Makefile.am (TESTS): Add nice and pathchk1.
+
+2002-08-04 Jim Meyering <jim@meyering.net>
+
+ * src/Makefile.am (check-README): New target/rule.
+ (check): Depend on it.
+
+ * configure.ac (AC_CONFIG_FILES): Add old/Makefile and old/*/Makefile.
+
+2002-08-03 Jim Meyering <jim@meyering.net>
+
+ * Makefile.am (SUBDIRS): Add old.
+ * old/: New directory, containing legacy ChangeLog* and NEWS files
+ from the fileutils, sh-utils, and textutils packages.
+
+ * src/Makefile.am (AM_INSTALLCHECK_STD_OPTIONS_EXEMPT): Set to false.
+
+2002-08-02 Paul Eggert <eggert@twinsun.com>
+
+ * NEWS, doc/coreutils.texi: uniq now obeys LC_COLLATE.
+
+ * src/uniq.c: Include hard-locale.h, xmemcoll.h.
+ (hard_LC_COLLATE): New var.
+ (different): Args are now char *, not const char *.
+ Use xmemcoll instead of memcmp to compare lines, so that
+ LC_COLLATE has effect. However, use memcmp if it is an
+ easy locale.
+ (check_file): Do not include newline in comparison, so that
+ xmemcoll has a byte to stomp on temporarily.
+ (main): Set hard_LC_COLLATE.
+
+2002-07-29 Jim Meyering <jim@meyering.net>
+
+ * Makefile.am (SUBDIRS): Remove djgpp, for now.
+
+2002-07-20 Jim Meyering <jim@meyering.net>
+
+ * Makefile.am (false.c): Convert only the final EXIT_SUCCESS
+ into EXIT_FAILURE. Otherwise, false --help and false --version
+ would fail.
+
+2002-07-08 Jim Meyering <jim@meyering.net>
+
+ * src/Makefile.am (uninstall-local): Search for @GNU_PACKAGE@,
+ rather than the hard-coded `sh-utils'.
+
+2002-07-01 Jim Meyering <jim@meyering.net>
+
+ * configure.ac: Merge the three files from fileutils,
+ textutils, and sh-utils.
+ * Makefile.am: Likewise.
+ * src/Makefile.am: Likewise.
diff --git a/contrib/gnu-sort/FREEBSD-upgrade b/contrib/gnu-sort/FREEBSD-upgrade
new file mode 100644
index 0000000..5cb5371
--- /dev/null
+++ b/contrib/gnu-sort/FREEBSD-upgrade
@@ -0,0 +1,14 @@
+$FreeBSD$
+
+GNU Sort
+ originals can be found at: ftp://ftp.gnu.org/gnu/coreutils/
+
+Configure by:
+ ./configure --disable-nls --without-libiconv-prefix \
+ --without-libintl-prefix
+
+Imported by:
+
+ cvs import \
+ -m "Virgin import (trimmed) of GNU Sort, coreutils 5.2.1" \
+ src/contrib/gnu-sort FSF SORT_v5_2_1
diff --git a/contrib/gnu-sort/INSTALL b/contrib/gnu-sort/INSTALL
new file mode 100644
index 0000000..54caf7c
--- /dev/null
+++ b/contrib/gnu-sort/INSTALL
@@ -0,0 +1,229 @@
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+ This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on. Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+ Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/contrib/gnu-sort/NEWS b/contrib/gnu-sort/NEWS
new file mode 100644
index 0000000..31f459b
--- /dev/null
+++ b/contrib/gnu-sort/NEWS
@@ -0,0 +1,904 @@
+GNU coreutils NEWS -*- outline -*-
+
+* Major changes in release 5.3.0 (2004-03-17) [unstable]
+
+** Bug fixes
+
+ rm (without -f) no longer hangs when attempting to remove a symlink
+ to a file on an off-line NFS-mounted partition.
+
+ cut's --output-delimiter=D option works with abutting byte ranges.
+
+ rm no longer gets a failed assertion under some unusual conditions.
+
+ Several fixes to chgrp and chown for compatibility with POSIX and BSD:
+
+ Do not affect symbolic links by default.
+ Now, operate on whatever a symbolic points to, instead.
+ To get the old behavior, use --no-dereference (-h).
+
+ --dereference now works, even when the specified owner
+ and/or group match those of an affected symlink.
+
+ Check for incompatible options. When -R and --dereference are
+ both used, then either -H or -L must also be used. When -R and -h
+ are both used, then -P must be in effect.
+
+ -H, -L, and -P have no effect unless -R is also specified.
+ If -P and -R are both specified, -h is assumed.
+
+ Do not optimize away the chown() system call when the file's owner
+ and group already have the desired value. This optimization was
+ incorrect, as it failed to update the last-changed time and reset
+ special permission bits, as POSIX requires.
+
+ Do not report an error if the owner or group of a
+ recursively-encountered symbolic link cannot be updated because
+ the file system does not support it.
+
+ md5sum and sha1sum now report an error when given so many input
+ lines that their line counter overflows, instead of silently
+ reporting incorrect results.
+
+ rm no longer requires read access to the current directory.
+
+ "sort -o -" now writes to a file named "-" instead of to standard
+ output; POSIX requires this.
+
+ tail -f no longer mishandles pipes and fifos. With no operands,
+ tail now ignores -f if standard input is a pipe, as POSIX requires.
+
+ For some types of errors (e.g., read-only file system, I/O error)
+ when first encountering a directory, `rm -r' would mistakenly fail
+ to remove files under that directory.
+
+ If d/x is a directory and x a file, "ln x d/" now reports an error
+ instead of incorrectly creating a link to d/x/x.
+
+ Fixes for "nice":
+
+ If it fails to lower the nice value due to lack of permissions,
+ it goes ahead and runs the command anyway, as POSIX requires.
+
+ It no longer incorrectly reports an error if the current nice
+ value happens to be -1.
+
+ It no longer assumes that nice values range from -20 through 19.
+
+ It now consistently adjusts out-of-range nice values to the
+ closest values in range; formerly it sometimes reported an error.
+
+ ptx now diagnoses invalid values for its --width=N (-w)
+ and --gap-size=N (-g) options.
+
+ tee now exits when it gets a SIGPIPE signal, as POSIX requires.
+ To get tee's old behavior, use the shell command "(trap '' PIPE; tee)".
+ Also, "tee -" now writes to standard output instead of to a file named "-".
+
+ ls no longer segfaults on systems for which SIZE_MAX != (size_t) -1
+
+ echo now conforms to POSIX better. It supports the \0ooo syntax for
+ octal escapes, and \c now terminates printing immediately. If
+ POSIXLY_CORRECT is set and the first argument is not "-n", echo now
+ outputs all option-like arguments instead of treating them as options.
+
+ printf has several changes:
+
+ It now uses 'intmax_t' (not 'long int') to format integers, so it
+ can now format 64-bit integers on most modern hosts.
+
+ On modern hosts it now supports the C99-inspired %a, %A, %F conversion
+ specs, the "'" and "0" flags, and the ll, j, t, and z length modifiers
+ (this is compatible with recent Bash versions).
+
+ The printf command now rejects invalid conversion specifications
+ like %#d, instead of relying on undefined behavior in the underlying
+ printf function.
+
+ who now prints user names in full instead of truncating them after 8 bytes.
+
+** New features
+
+ For efficiency, `sort -m' no longer copies input to a temporary file
+ merely because the input happens to come from a pipe. As a result,
+ some relatively-contrived examples like `cat F | sort -m -o F - G'
+ are no longer safe, as `sort' might start writing F before `cat' is
+ done reading it. This problem cannot occur unless `-m' is used.
+
+ When outside the default POSIX locale, the 'who' and 'pinky'
+ commands now output time stamps like "2004-06-21 13:09" instead of
+ the traditional "Jun 21 13:09".
+
+ pwd now works even when run from a working directory whose name
+ is longer than PATH_MAX.
+
+ cp, install, ln, and mv have a new --no-target-directory (-T) option,
+ and -t is now a short name for their --target-directory option.
+
+ cp -pu and mv -u (when copying) now don't bother to update the
+ destination if the resulting time stamp would be no newer than the
+ preexisting time stamp. This saves work in the common case when
+ copying or moving multiple times to the same destination in a file
+ system with a coarse time stamp resolution.
+
+ dd has new conversions for the conv= option:
+
+ nocreat do not create the output file
+ excl fail if the output file already exists
+ fdatasync physically write output file data before finishing
+ fsync likewise, but also write metadata
+
+ dd has new iflag= and oflag= options with the following flags:
+
+ append append mode (makes sense for output file only)
+ direct use direct I/O for data
+ dsync use synchronized I/O for data
+ sync likewise, but also for metadata
+ nonblock use non-blocking I/O
+ nofollow do not follow symlinks
+
+ stty now provides support (iutf8) for setting UTF-8 input mode.
+
+ With stat, a specified format is no longer automatically newline terminated.
+ If you want a newline at the end of your output, append `\n' to the format
+ string.
+
+ 'df', 'du', and 'ls' now take the default block size from the
+ BLOCKSIZE environment variable if the BLOCK_SIZE, DF_BLOCK_SIZE,
+ DU_BLOCK_SIZE, and LS_BLOCK_SIZE environment variables are not set.
+ Unlike the other variables, though, BLOCKSIZE does not affect
+ values like 'ls -l' sizes that are normally displayed as bytes.
+ This new behavior is for compatibility with BSD.
+
+ du accepts a new option --files0-from=FILE, where FILE contains a
+ list of NUL-terminated file names.
+
+ `date -d' and `touch -d' now accept integer counts of seconds since
+ 1970 when prefixed by `@'. For example, `@321' represents
+ 1970-01-01 00:05:21 UTC.
+
+ `date -d', `date -f' and `touch -d' now handle fractional time
+ stamps like 2004-02-27 14:19:13.489392193.
+
+ `date' has a new option --iso-8601=ns that outputs
+ nanosecond-resolution time stamps.
+
+ echo -e '\xHH' now outputs a byte whose hexadecimal value is HH,
+ for compatibility with bash.
+
+ In the following cases POSIX allows the default GNU behavior,
+ so when POSIXLY_CORRECT is set:
+
+ false, printf, true, unlink, and yes all support --help and --option.
+ ls supports TABSIZE.
+ pr no longer depends on LC_TIME for the date format in non-POSIX locales.
+ printf supports \u, \U, \x.
+ tail supports two or more files when using the obsolete option syntax.
+
+ The usual `--' operand is now supported by chroot, hostid, hostname,
+ pwd, sync, and yes.
+
+ The stat option --filesystem has been renamed to --file-system, for
+ consistency with POSIX "file system" and with cp and du --one-file-system.
+
+** Removed features
+
+ tail's undocumented --max-consecutive-size-changes option has been removed.
+
+* Major changes in release 5.2.1 (2004-03-12) [stable]
+
+** Bug fixes
+
+ mv could mistakenly fail to preserve hard links when moving two
+ or more arguments between partitions.
+
+ `cp --sparse=always F /dev/hdx' no longer tries to use lseek to create
+ holes in the destination.
+
+ nohup now sets the close-on-exec flag for its copy of the stderr file
+ descriptor. This avoids some nohup-induced hangs. For example, before
+ this change, if you ran `ssh localhost', then `nohup sleep 600 </dev/null &',
+ and then exited that remote shell, the ssh session would hang until the
+ 10-minute sleep terminated. With the fixed nohup, the ssh session
+ terminates immediately.
+
+ `expr' now conforms to POSIX better:
+
+ Integers like -0 and 00 are now treated as zero.
+
+ The `|' operator now returns 0, not its first argument, if both
+ arguments are null or zero. E.g., `expr "" \| ""' now returns 0,
+ not the empty string.
+
+ The `|' and `&' operators now use short-circuit evaluation, e.g.,
+ `expr 1 \| 1 / 0' no longer reports a division by zero.
+
+** New features
+
+ `chown user.group file' now has its traditional meaning even when
+ conforming to POSIX 1003.1-2001, so long as no user has a name
+ containing `.' that happens to equal `user.group'.
+
+
+* Major changes in release 5.2.0 (2004-02-19) [stable]
+
+** Bug fixes
+
+ none
+
+
+* Major changes in release 5.1.3 (2004-02-08): candidate to become stable 5.2.0
+
+** Bug fixes
+
+ `cp -d' now works as required even on systems like OSF V5.1 that
+ declare stat and lstat as `static inline' functions.
+
+ time stamps output by stat now include actual fractional seconds,
+ when available -- or .0000000 for files without that information.
+
+ seq no longer infloops when printing 2^31 or more numbers.
+ For reference, seq `echo 2^31|bc` > /dev/null takes about one hour
+ on a 1.6 GHz Athlon 2000 XP. Now it can output 2^53-1 numbers before
+ misbehaving.
+
+* Major changes in release 5.1.2 (2004-01-25):
+
+** Bug fixes
+
+ rmdir -p exits with status 1 on error; formerly it sometimes exited
+ with status 0 when given more than one argument.
+
+ nohup now always exits with status 127 when it finds an error,
+ as POSIX requires; formerly it sometimes exited with status 1.
+
+ Several programs (including cut, date, dd, env, hostname, nl, pr,
+ stty, and tr) now always exit with status 1 when they find an error;
+ formerly they sometimes exited with status 2.
+
+ factor no longer reports a usage error if stdin has the wrong format.
+
+ paste no longer infloops on ppc systems (bug introduced in 5.1.1)
+
+
+* Major changes in release 5.1.1 (2004-01-17):
+
+** Configuration option
+
+ You can select the default level of POSIX conformance at configure-time,
+ e.g., by ./configure DEFAULT_POSIX2_VERSION=199209
+
+** Bug fixes
+
+ fold -s works once again on systems with differing sizes for int
+ and size_t (bug introduced in 5.1.0)
+
+** New features
+
+ touch -r now specifies the origin for any relative times in the -d
+ operand, if both options are given. For example, "touch -r FOO -d
+ '-5 seconds' BAR" sets BAR's modification time to be five seconds
+ before FOO's.
+
+ join: The obsolete options "-j1 FIELD", "-j2 FIELD", and
+ "-o LIST1 LIST2..." are no longer supported on POSIX 1003.1-2001 systems.
+ Portable scripts should use "-1 FIELD", "-2 FIELD", and
+ "-o LIST1,LIST2..." respectively. If join was compiled on a
+ POSIX 1003.1-2001 system, you may enable the old behavior
+ by setting _POSIX2_VERSION=199209 in your environment.
+
+
+* Major changes in release 5.1.0 (2003-12-21):
+
+** New features
+
+ chgrp, chmod, and chown can now process (with -R) hierarchies of virtually
+ unlimited depth. Before, they would fail to operate on any file they
+ encountered with a relative name of length PATH_MAX (often 4096) or longer.
+
+ chgrp, chmod, chown, and rm accept the new options:
+ --preserve-root, --no-preserve-root (default)
+
+ chgrp and chown now accept POSIX-mandated -L, -H, and -P options
+
+ du can now process hierarchies of virtually unlimited depth.
+ Before, du was limited by the user's stack size and it would get a
+ stack overflow error (often a segmentation fault) when applied to
+ a hierarchy of depth around 30,000 or larger.
+
+ du works even when run from an inaccessible directory
+
+ du -D now dereferences all symlinks specified on the command line,
+ not just the ones that reference directories
+
+ du now accepts -P (--no-dereference), for compatibility with du
+ of NetBSD and for consistency with e.g., chown and chgrp
+
+ du's -H option will soon have the meaning required by POSIX
+ (--dereference-args, aka -D) rather then the current meaning of --si.
+ Now, using -H elicits a warning to that effect.
+
+ When given -l and similar options, ls now adjusts the output column
+ widths to fit the data, so that output lines are shorter and have
+ columns that line up better. This may adversely affect shell
+ scripts that expect fixed-width columns, but such shell scripts were
+ not portable anyway, even with old GNU ls where the columns became
+ ragged when a datum was too wide.
+
+ du accepts a new option, -0/--null, to make it produce NUL-terminated
+ output lines
+
+** Bug fixes
+
+ printf, seq, tail, and sleep now parse floating-point operands
+ and options in the C locale. POSIX requires this for printf.
+
+ od -c -w9999999 no longer segfaults
+
+ csplit no longer reads from freed memory (dumping core on some systems)
+
+ csplit would mistakenly exhaust virtual memory in some cases
+
+ ls --width=N (for very large N) is no longer subject to an address
+ arithmetic bug that could result in bounds violations.
+
+ ls --width=N (with -x or -C) no longer allocates more space
+ (potentially much more) than necessary for a given directory.
+
+ dd `unblock' and `sync' may now be combined (e.g., dd conv=unblock,sync)
+
+* Major changes in release 5.0.91 (2003-09-08):
+
+** New features
+
+ date accepts a new option --rfc-2822, an alias for --rfc-822.
+
+ split accepts a new option -d or --numeric-suffixes.
+
+ cp, install, mv, and touch now preserve microsecond resolution on
+ file timestamps, on platforms that have the 'utimes' system call.
+ Unfortunately there is no system call yet to preserve file
+ timestamps to their full nanosecond resolution; microsecond
+ resolution is the best we can do right now.
+
+ sort now supports the zero byte (NUL) as a field separator; use -t '\0'.
+ The -t '' option, which formerly had no effect, is now an error.
+
+ sort option order no longer matters for the options -S, -d, -i, -o, and -t.
+ Stronger options override weaker, and incompatible options are diagnosed.
+
+ `sha1sum --check' now accepts the BSD format for SHA1 message digests
+ in addition to the BSD format for MD5 ones.
+
+ who -l now means `who --login', not `who --lookup', per POSIX.
+ who's -l option has been eliciting an unconditional warning about
+ this impending change since sh-utils-2.0.12 (April 2002).
+
+** Bug fixes
+
+ Mistakenly renaming a file onto itself, e.g., via `mv B b' when `B' is
+ the same directory entry as `b' no longer destroys the directory entry
+ referenced by both `b' and `B'. Note that this would happen only on
+ file systems like VFAT where two different names may refer to the same
+ directory entry, usually due to lower->upper case mapping of file names.
+ Now, the above can happen only on file systems that perform name mapping and
+ that support hard links (stat.st_nlink > 1). This mitigates the problem
+ in two ways: few file systems appear to be affected (hpfs and ntfs are),
+ when the bug is triggered, mv no longer removes the last hard link to a file.
+ *** ATTENTION ***: if you know how to distinguish the following two cases
+ without writing to the file system in question, please let me know:
+ 1) B and b refer to the same directory entry on a file system like NTFS
+ (B may well have a link count larger than 1)
+ 2) B and b are hard links to the same file
+
+ stat no longer overruns a buffer for format strings ending in `%'
+
+ fold -s -wN would infloop for N < 8 with TABs in the input.
+ E.g., this would not terminate: printf 'a\t' | fold -w2 -s
+
+ `split -a0', although of questionable utility, is accepted once again.
+
+ `df DIR' used to hang under some conditions on OSF/1 5.1. Now it doesn't.
+
+ seq's --width (-w) option now works properly even when the endpoint
+ requiring the larger width is negative and smaller than the other endpoint.
+
+ seq's default step is 1, even if LAST < FIRST.
+
+ paste no longer mistakenly outputs 0xFF bytes for a nonempty input file
+ without a trailing newline.
+
+ `tail -n0 -f FILE' and `tail -c0 -f FILE' no longer perform what amounted
+ to a busy wait, rather than sleeping between iterations.
+
+ tail's long-undocumented --allow-missing option now elicits a warning
+
+
+* Major changes in release 5.0.90 (2003-07-29):
+
+** New features
+
+ sort is now up to 30% more CPU-efficient in some cases
+
+ `test' is now more compatible with Bash and POSIX:
+
+ `test -t', `test --help', and `test --version' now silently exit
+ with status 0. To test whether standard output is a terminal, use
+ `test -t 1'. To get help and version info for `test', use
+ `[ --help' and `[ --version'.
+
+ `test' now exits with status 2 (not 1) if there is an error.
+
+ wc count field widths now are heuristically adjusted depending on the input
+ size, if known. If only one count is printed, it is guaranteed to
+ be printed without leading spaces.
+
+ Previously, wc did not align the count fields if POSIXLY_CORRECT was set,
+ but POSIX did not actually require this undesirable behavior, so it
+ has been removed.
+
+** Bug fixes
+
+ kill no longer tries to operate on argv[0] (introduced in 5.0.1)
+ Why wasn't this noticed? Although many tests use kill, none of
+ them made an effort to avoid using the shell's built-in kill.
+
+ `[' invoked with no arguments no longer evokes a segfault
+
+ rm without --recursive (aka -r or -R) no longer prompts regarding
+ unwritable directories, as required by POSIX.
+
+ uniq -c now uses a SPACE, not a TAB between the count and the
+ corresponding line, as required by POSIX.
+
+ expr now exits with status 2 if the expression is syntactically valid,
+ and with status 3 if an error occurred. POSIX requires this.
+
+ expr now reports trouble if string comparison fails due to a collation error.
+
+ split now generates suffixes properly on EBCDIC hosts.
+
+ split -a0 now works, as POSIX requires.
+
+ `sort --version' and `sort --help' fail, as they should
+ when their output is redirected to /dev/full.
+
+ `su --version > /dev/full' now fails, as it should.
+
+** Fewer arbitrary limitations
+
+ cut requires 97% less memory when very large field numbers or
+ byte offsets are specified.
+
+
+* Major changes in release 5.0.1 (2003-07-15):
+
+** New programs
+- new program: `[' (much like `test')
+
+** New features
+- head now accepts --lines=-N (--bytes=-N) to print all but the
+ N lines (bytes) at the end of the file
+- md5sum --check now accepts the output of the BSD md5sum program, e.g.,
+ MD5 (f) = d41d8cd98f00b204e9800998ecf8427e
+- date -d DATE can now parse a DATE string like May-23-2003
+- chown: `.' is no longer recognized as a separator in the OWNER:GROUP
+ specifier on POSIX 1003.1-2001 systems. If chown *was not* compiled
+ on such a system, then it still accepts `.', by default. If chown
+ was compiled on a POSIX 1003.1-2001 system, then you may enable the
+ old behavior by setting _POSIX2_VERSION=199209 in your environment.
+- chown no longer tries to preserve set-user-ID and set-group-ID bits;
+ on some systems, the chown syscall resets those bits, and previous
+ versions of the chown command would call chmod to restore the original,
+ pre-chown(2) settings, but that behavior is problematic.
+ 1) There was a window whereby a malicious user, M, could subvert a
+ chown command run by some other user and operating on files in a
+ directory where M has write access.
+ 2) Before (and even now, on systems with chown(2) that doesn't reset
+ those bits), an unwary admin. could use chown unwittingly to create e.g.,
+ a set-user-ID root copy of /bin/sh.
+
+** Bug fixes
+- chown --dereference no longer leaks a file descriptor per symlink processed
+- `du /' once again prints the `/' on the last line
+- split's --verbose option works once again [broken in 4.5.10 and 5.0]
+- tail -f is no longer subject to a race condition that could make it
+ delay displaying the last part of a file that had stopped growing. That
+ bug could also make tail -f give an unwarranted `file truncated' warning.
+- du no longer runs out of file descriptors unnecessarily
+- df and `readlink --canonicalize' no longer corrupt the heap on
+ non-glibc, non-solaris systems
+- `env -u UNSET_VARIABLE' no longer dumps core on non-glibc systems
+- readlink's --canonicalize option now works on systems like Solaris that
+ lack the canonicalize_file_name function but do have resolvepath.
+- mv now removes `a' in this example on all systems: touch a; ln a b; mv a b
+ This behavior is contrary to POSIX (which requires that the mv command do
+ nothing and exit successfully), but I suspect POSIX will change.
+- date's %r format directive now honors locale settings
+- date's `-' (no-pad) format flag now affects the space-padded-by-default
+ conversion specifiers, %e, %k, %l
+- fmt now diagnoses invalid obsolescent width specifications like `-72x'
+- fmt now exits nonzero when unable to open an input file
+- tsort now fails when given an odd number of input tokens,
+ as required by POSIX. Before, it would act as if the final token
+ appeared one additional time.
+
+** Fewer arbitrary limitations
+- tail's byte and line counts are no longer limited to OFF_T_MAX.
+ Now the limit is UINTMAX_MAX (usually 2^64).
+- split can now handle --bytes=N and --lines=N with N=2^31 or more.
+
+** Portability
+- `kill -t' now prints signal descriptions (rather than `?') on systems
+ like Tru64 with __sys_siglist but no strsignal function.
+- stat.c now compiles on Ultrix systems
+- sleep now works on AIX systems that lack support for clock_gettime
+- rm now works around Darwin6.5's broken readdir function
+ Before `rm -rf DIR' would fail to remove all files in DIR
+ if there were more than 338.
+
+* Major changes in release 5.0 (2003-04-02):
+- false --help now exits nonzero
+
+[4.5.12]
+* printf no longer treats \x specially when POSIXLY_CORRECT is set
+* printf avoids buffer overrun with format ending in a backslash and
+* printf avoids buffer overrun with incomplete conversion specifier
+* printf accepts multiple flags in a single conversion specifier
+
+[4.5.11]
+* seq no longer requires that a field width be specified
+* seq no longer fails when given a field width of `0'
+* seq now accepts ` ' and `'' as valid format flag characters
+* df now shows a HOSTNAME: prefix for each remote-mounted file system on AIX 5.1
+* portability tweaks for HP-UX, AIX 5.1, DJGPP
+
+[4.5.10]
+* printf no longer segfaults for a negative field width or precision
+* shred now always enables --exact for non-regular files
+* du no longer lists hard-linked files more than once
+* du no longer dumps core on some systems due to `infinite' recursion
+ via nftw's use of the buggy replacement function in getcwd.c
+* portability patches for a few vendor compilers and 64-bit systems
+* du -S *really* now works like it did before the change in 4.5.5
+
+[4.5.9]
+* du no longer truncates file sizes or sums to fit in 32-bit size_t
+* work around Linux kernel bug in getcwd (fixed in 2.4.21-pre4), so that pwd
+ now fails if the name of the working directory is so long that getcwd
+ truncates it. Before it would print the truncated name and exit successfully.
+* `df /some/mount-point' no longer hangs on a GNU libc system when another
+ hard-mounted NFS file system (preceding /some/mount-point in /proc/mounts)
+ is inaccessible.
+* rm -rf now gives an accurate diagnostic when failing to remove a file
+ under certain unusual conditions
+* mv and `cp --preserve=links' now preserve multiple hard links even under
+ certain unusual conditions where they used to fail
+
+[4.5.8]
+* du -S once again works like it did before the change in 4.5.5
+* stat accepts a new file format, %B, for the size of each block reported by %b
+* du accepts new option: --apparent-size
+* du --bytes (-b) works the same way it did in fileutils-3.16 and before
+* du reports proper sizes for directories (not zero) (broken in 4.5.6 or 4.5.7)
+* df now always displays under `Filesystem', the device file name
+ corresponding to the listed mount point. Before, for a block- or character-
+ special file command line argument, df would display that argument. E.g.,
+ `df /dev/hda' would list `/dev/hda' as the `Filesystem', rather than say
+ /dev/hda3 (the device on which `/' is mounted), as it does now.
+* test now works properly when invoked from a set user ID or set group ID
+ context and when testing access to files subject to alternate protection
+ mechanisms. For example, without this change, a set-UID program that invoked
+ `test -w F' (to see if F is writable) could mistakenly report that it *was*
+ writable, even though F was on a read-only file system, or F had an ACL
+ prohibiting write access, or F was marked as immutable.
+
+[4.5.7]
+* du would fail with more than one DIR argument when any but the last did not
+ contain a slash (due to a bug in ftw.c)
+
+[4.5.6]
+* du no longer segfaults on Solaris systems (fixed heap-corrupting bug in ftw.c)
+* du --exclude=FILE works once again (this was broken by the rewrite for 4.5.5)
+* du no longer gets a failed assertion for certain hierarchy lay-outs
+ involving hard-linked directories
+* `who -r' no longer segfaults when using non-C-locale messages
+* df now displays a mount point (usually `/') for non-mounted
+ character-special and block files
+
+[4.5.5]
+* ls --dired produces correct byte offset for file names containing
+ nonprintable characters in a multibyte locale
+* du has been rewritten to use a variant of GNU libc's ftw.c
+* du now counts the space associated with a directory's directory entry,
+ even if it cannot list or chdir into that subdirectory.
+* du -S now includes the st_size of each entry corresponding to a subdirectory
+* rm on FreeBSD can once again remove directories from NFS-mounted file systems
+* ls has a new option --dereference-command-line-symlink-to-dir, which
+ corresponds to the new default behavior when none of -d, -l -F, -H, -L
+ has been specified.
+* ls dangling-symlink now prints `dangling-symlink'.
+ Before, it would fail with `no such file or directory'.
+* ls -s symlink-to-non-dir and ls -i symlink-to-non-dir now print
+ attributes of `symlink', rather than attributes of their referents.
+* Fix a bug introduced in 4.5.4 that made it so that ls --color would no
+ longer highlight the names of files with the execute bit set when not
+ specified on the command line.
+* shred's --zero (-z) option no longer gobbles up any following argument.
+ Before, `shred --zero file' would produce `shred: missing file argument',
+ and worse, `shred --zero f1 f2 ...' would appear to work, but would leave
+ the first file untouched.
+* readlink: new program
+* cut: new feature: when used to select ranges of byte offsets (as opposed
+ to ranges of fields) and when --output-delimiter=STRING is specified,
+ output STRING between ranges of selected bytes.
+* rm -r can no longer be tricked into mistakenly reporting a cycle.
+* when rm detects a directory cycle, it no longer aborts the entire command,
+ but rather merely stops processing the affected command line argument.
+
+[4.5.4]
+* cp no longer fails to parse options like this: --preserve=mode,ownership
+* `ls --color -F symlink-to-dir' works properly
+* ls is much more efficient on directories with valid dirent.d_type.
+* stty supports all baud rates defined in linux-2.4.19.
+* `du symlink-to-dir/' would improperly remove the trailing slash
+* `du ""' would evoke a bounds violation.
+* In the unlikely event that running `du /' resulted in `stat ("/", ...)'
+ failing, du would give a diagnostic about `' (empty string) rather than `/'.
+* printf: a hexadecimal escape sequence has at most two hex. digits, not three.
+* The following features have been added to the --block-size option
+ and similar environment variables of df, du, and ls.
+ - A leading "'" generates numbers with thousands separators.
+ For example:
+ $ ls -l --block-size="'1" file
+ -rw-rw-r-- 1 eggert src 47,483,707 Sep 24 23:40 file
+ - A size suffix without a leading integer generates a suffix in the output.
+ For example:
+ $ ls -l --block-size="K"
+ -rw-rw-r-- 1 eggert src 46371K Sep 24 23:40 file
+* ls's --block-size option now affects file sizes in all cases, not
+ just for --block-size=human-readable and --block-size=si. Fractional
+ sizes are now always rounded up, for consistency with df and du.
+* df now displays the block size using powers of 1000 if the requested
+ block size seems to be a multiple of a power of 1000.
+* nl no longer gets a segfault when run like this `yes|nl -s%n'
+
+[4.5.3]
+* du --dereference-args (-D) no longer fails in certain cases
+* `ln --target-dir=DIR' no longer fails when given a single argument
+
+[4.5.2]
+* `rm -i dir' (without --recursive (-r)) no longer recurses into dir
+* `tail -c N FILE' now works with files of size >= 4GB
+* `mkdir -p' can now create very deep (e.g. 40,000-component) directories
+* rmdir -p dir-with-trailing-slash/ no longer fails
+* printf now honors the `--' command line delimiter
+* od's 8-byte formats x8, o8, and u8 now work
+* tail now accepts fractional seconds for its --sleep-interval=S (-s) option
+
+[4.5.1]
+* du and ls now report sizes of symbolic links (before they'd always report 0)
+* uniq now obeys the LC_COLLATE locale, as per POSIX 1003.1-2001 TC1.
+
+========================================================================
+Here are the NEWS entries made from fileutils-4.1 until the
+point at which the packages merged to form the coreutils:
+
+[4.1.11]
+* `rm symlink-to-unwritable' doesn't prompt [introduced in 4.1.10]
+[4.1.10]
+* rm once again gives a reasonable diagnostic when failing to remove a file
+ owned by someone else in a sticky directory [introduced in 4.1.9]
+* df now rounds all quantities up, as per POSIX.
+* New ls time style: long-iso, which generates YYYY-MM-DD HH:MM.
+* Any time style can be preceded by "posix-"; this causes "ls" to
+ use traditional timestamp format when in the POSIX locale.
+* The default time style is now posix-long-iso instead of posix-iso.
+ Set TIME_STYLE="posix-iso" to revert to the behavior of 4.1.1 thru 4.1.9.
+* `rm dangling-symlink' doesn't prompt [introduced in 4.1.9]
+* stat: remove support for --secure/-s option and related %S and %C format specs
+* stat: rename --link/-l to --dereference/-L.
+ The old options will continue to work for a while.
+[4.1.9]
+* rm can now remove very deep hierarchies, in spite of any limit on stack size
+* new programs: link, unlink, and stat
+* New ls option: --author (for the Hurd).
+* `touch -c no-such-file' no longer fails, per POSIX
+[4.1.8]
+* mv no longer mistakenly creates links to preexisting destination files
+ that aren't moved
+[4.1.7]
+* rm: close a hole that would allow a running rm process to be subverted
+[4.1.6]
+* New cp option: --copy-contents.
+* cp -r is now equivalent to cp -R. Use cp -R -L --copy-contents to get the
+ traditional (and rarely desirable) cp -r behavior.
+* ls now accepts --time-style=+FORMAT, where +FORMAT works like date's format
+* The obsolete usage `touch [-acm] MMDDhhmm[YY] FILE...' is no longer
+ supported on systems conforming to POSIX 1003.1-2001. Use touch -t instead.
+* cp and inter-partition mv no longer give a misleading diagnostic in some
+ unusual cases
+[4.1.5]
+* cp -r no longer preserves symlinks
+* The block size notation is now compatible with SI and with IEC 60027-2.
+ For example, --block-size=1MB now means --block-size=1000000,
+ whereas --block-size=1MiB now means --block-size=1048576.
+ A missing `B' (e.g. `1M') has the same meaning as before.
+ A trailing `B' now means decimal, not binary; this is a silent change.
+ The nonstandard `D' suffix (e.g. `1MD') is now obsolescent.
+* -H or --si now outputs the trailing 'B', for consistency with the above.
+* Programs now output trailing 'K' (not 'k') to mean 1024, as per IEC 60027-2.
+* New df, du short option -B is short for --block-size.
+* You can omit an integer `1' before a block size suffix,
+ e.g. `df -BG' is equivalent to `df -B 1G' and to `df --block-size=1G'.
+* The following options are now obsolescent, as their names are
+ incompatible with IEC 60027-2:
+ df, du: -m or --megabytes (use -BM or --block-size=1M)
+ df, du, ls: --kilobytes (use --block-size=1K)
+[4.1.4]
+* df --local no longer lists smbfs file systems whose name starts with //
+* dd now detects the Linux/tape/lseek bug at run time and warns about it.
+[4.1.3]
+* ls -R once again outputs a blank line between per-directory groups of files.
+ This was broken by the cycle-detection change in 4.1.1.
+* dd once again uses `lseek' on character devices like /dev/mem and /dev/kmem.
+ On systems with the linux kernel (at least up to 2.4.16), dd must still
+ resort to emulating `skip=N' behavior using reads on tape devices, because
+ lseek has no effect, yet appears to succeed. This may be a kernel bug.
+[4.1.2]
+* cp no longer fails when two or more source files are the same;
+ now it just gives a warning and doesn't copy the file the second time.
+ E.g., cp a a d/ produces this:
+ cp: warning: source file `a' specified more than once
+* chmod would set the wrong bit when given symbolic mode strings like
+ these: g=o, o=g, o=u. E.g., `chmod a=,o=w,ug=o f' would give a mode
+ of --w-r---w- rather than --w--w--w-.
+[4.1.1]
+* mv (likewise for cp), now fails rather than silently clobbering one of
+ the source files in the following example:
+ rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c
+* ls -R detects directory cycles, per POSIX. It warns and doesn't infloop.
+* cp's -P option now means the same as --no-dereference, per POSIX.
+ Use --parents to get the old meaning.
+* When copying with the -H and -L options, cp can preserve logical
+ links between source files with --preserve=links
+* cp accepts new options:
+ --preserve[={mode,ownership,timestamps,links,all}]
+ --no-preserve={mode,ownership,timestamps,links,all}
+* cp's -p and --preserve options remain unchanged and are equivalent
+ to `--preserve=mode,ownership,timestamps'
+* mv and cp accept a new option: --reply={yes,no,query}; provides a consistent
+ mechanism to control whether one is prompted about certain existing
+ destination files. Note that cp's and mv's -f options don't have the
+ same meaning: cp's -f option no longer merely turns off `-i'.
+* remove portability limitations (e.g., PATH_MAX on the Hurd, fixes for
+ 64-bit systems)
+* mv now prompts before overwriting an existing, unwritable destination file
+ when stdin is a tty, unless --force (-f) is specified, as per POSIX.
+* mv: fix the bug whereby `mv -uf source dest' would delete source,
+ even though it's older than dest.
+* chown's --from=CURRENT_OWNER:CURRENT_GROUP option now works
+* cp now ensures that the set-user-ID and set-group-ID bits are cleared for
+ the destination file when when copying and not preserving permissions.
+* `ln -f --backup k k' gives a clearer diagnostic
+* ls no longer truncates user names or group names that are longer
+ than 8 characters.
+* ls's new --dereference-command-line option causes it to dereference
+ symbolic links on the command-line only. It is the default unless
+ one of the -d, -F, or -l options are given.
+* ls -H now means the same as ls --dereference-command-line, as per POSIX.
+* ls -g now acts like ls -l, except it does not display owner, as per POSIX.
+* ls -n now implies -l, as per POSIX.
+* ls can now display dates and times in one of four time styles:
+
+ - The `full-iso' time style gives full ISO-style time stamps like
+ `2001-05-14 23:45:56.477817180 -0700'.
+ - The 'iso' time style gives ISO-style time stamps like '2001-05-14 '
+ and '05-14 23:45'.
+ - The 'locale' time style gives locale-dependent time stamps like
+ 'touko 14 2001' and 'touko 14 23:45' (in a Finnish locale).
+ - The 'posix-iso' time style gives traditional POSIX-locale
+ time stamps like 'May 14 2001' and 'May 14 23:45' unless the user
+ specifies a non-POSIX locale, in which case it uses ISO-style dates.
+ This is the default.
+
+ You can specify a time style with an option like --time-style='iso'
+ or with an environment variable like TIME_STYLE='iso'. GNU Emacs 21
+ and later can parse ISO dates, but older Emacs versions cannot, so
+ if you are using an older version of Emacs outside the default POSIX
+ locale, you may need to set TIME_STYLE="locale".
+
+* --full-time is now an alias for "-l --time-style=full-iso".
+
+
+========================================================================
+Here are the NEWS entries made from sh-utils-2.0 until the
+point at which the packages merged to form the coreutils:
+
+ [2.0.15]
+* date no longer accepts e.g., September 31 in the MMDDhhmm syntax
+* fix a bug in this package's .m4 files and in configure.ac
+ [2.0.14]
+* nohup's behavior is changed as follows, to conform to POSIX 1003.1-2001:
+ - nohup no longer adjusts scheduling priority; use "nice" for that.
+ - nohup now redirects stderr to stdout, if stderr is not a terminal.
+ - nohup exit status is now 126 if command was found but not invoked,
+ 127 if nohup failed or if command was not found.
+ [2.0.13]
+* uname and uptime work better on *BSD systems
+* pathchk now exits nonzero for a path with a directory component
+ that specifies a non-directory
+ [2.0.12]
+* kill: new program
+* who accepts new options: --all (-a), --boot (-b), --dead (-d), --login,
+ --process (-p), --runlevel (-r), --short (-s), --time (-t), --users (-u).
+ The -u option now produces POSIX-specified results and is the same as
+ the long option `--users'. --idle is no longer the same as -u.
+* The following changes apply on systems conforming to POSIX 1003.1-2001,
+ and are required by the new POSIX standard:
+ - `date -I' is no longer supported. Instead, use `date --iso-8601'.
+ - `nice -NUM' is no longer supported. Instead, use `nice -n NUM'.
+* New 'uname' options -i or --hardware-platform, and -o or --operating-system.
+ 'uname -a' now outputs -i and -o information at the end.
+ New uname option --kernel-version is an alias for -v.
+ Uname option --release has been renamed to --kernel-release,
+ and --sysname has been renamed to --kernel-name;
+ the old options will work for a while, but are no longer documented.
+* 'expr' now uses the LC_COLLATE locale for string comparison, as per POSIX.
+* 'expr' now requires '+' rather than 'quote' to quote tokens;
+ this removes an incompatibility with POSIX.
+* date -d 'last friday' would print a date/time that was one hour off
+ (e.g., 23:00 on *thursday* rather than 00:00 of the preceding friday)
+ when run such that the current time and the target date/time fall on
+ opposite sides of a daylight savings time transition.
+ This problem arose only with relative date strings like `last monday'.
+ It was not a problem with strings that include absolute dates.
+* factor is twice as fast, for large numbers
+ [2.0.11]
+* setting the date now works properly, even when using -u
+* `date -f - < /dev/null' no longer dumps core
+* some DOS/Windows portability changes
+ [2.0j]
+* `date -d DATE' now parses certain relative DATEs correctly
+ [2.0i]
+* fixed a bug introduced in 2.0h that made many programs fail with a
+ `write error' when invoked with the --version option
+ [2.0h]
+* all programs fail when printing --help or --version output to a full device
+* printf exits nonzero upon write failure
+* yes now detects and terminates upon write failure
+* date --rfc-822 now always emits day and month names from the `C' locale
+* portability tweaks for Solaris8, Ultrix, and DOS
+ [2.0g]
+* date now handles two-digit years with leading zeros correctly.
+* printf interprets unicode, \uNNNN \UNNNNNNNN, on systems with the
+ required support; from Bruno Haible.
+* stty's rprnt attribute now works on HPUX 10.20
+* seq's --equal-width option works more portably
+ [2.0f]
+* fix build problems with ut_name vs. ut_user
+ [2.0e]
+* stty: fix long-standing bug that caused test failures on at least HPUX
+ systems when COLUMNS was set to zero
+* still more portability fixes
+* unified lib/: now that directory and most of the configuration framework
+ is common between fileutils, textutils, and sh-utils
+ [2.0d]
+* fix portability problem with sleep vs lib/strtod.c's requirement for -lm
+ [2.0c]
+* fix portability problems with nanosleep.c and with the new code in sleep.c
+ [2.0b]
+* Regenerate lib/Makefile.in so that nanosleep.c is distributed.
+ [2.0a]
+* sleep accepts floating point arguments on command line
+* sleep's clock continues counting down when sleep is suspended
+* when a suspended sleep process is resumed, it continues sleeping if
+ there is any time remaining
+* who once again prints whatever host information it has, even without --lookup
+
+========================================================================
+For older NEWS entries for the fileutils, textutils, and sh-utils
+packages, see ./old/*/NEWS.
+
+ This package began as the union of the following:
+ textutils-2.1, fileutils-4.1.11, sh-utils-2.0.15.
diff --git a/contrib/gnu-sort/README b/contrib/gnu-sort/README
new file mode 100644
index 0000000..df35be4
--- /dev/null
+++ b/contrib/gnu-sort/README
@@ -0,0 +1,147 @@
+These are the GNU core utilities. This package is the union of
+the GNU fileutils, sh-utils, and textutils packages.
+
+Most of these programs have significant advantages over their Unix
+counterparts, such as greater speed, additional options, and fewer
+arbitrary limits.
+
+The programs that can be built with this package are:
+
+ [ basename cat chgrp chmod chown chroot cksum comm cp csplit cut date dd
+ df dir dircolors dirname du echo env expand expr factor false fmt fold
+ ginstall groups head hostid hostname id join kill link ln logname ls
+ md5sum mkdir mkfifo mknod mv nice nl nohup od paste pathchk pinky pr
+ printenv printf ptx pwd readlink rm rmdir seq sha1sum shred sleep sort
+ split stat stty su sum sync tac tail tee test touch tr true tsort tty
+ uname unexpand uniq unlink uptime users vdir wc who whoami yes
+
+See the file NEWS for a list of major changes in the current release.
+
+See the file INSTALL for compilation and installation instructions.
+
+These programs are intended to conform to POSIX (with BSD and other
+extensions), like the rest of the GNU system. By default they conform
+to older POSIX (1003.2-1992), and therefore support obsolete usages
+like "head -10" and "chown owner.group file". This default is
+overridden at build-time by the value of <unistd.h>'s _POSIX2_VERSION
+macro, and this in turn can be overridden at runtime as described in
+the documentation under "Standards conformance".
+
+The ls, dir, and vdir commands are all separate executables instead of
+one program that checks argv[0] because people often rename these
+programs to things like gls, gnuls, l, etc. Renaming a program
+file shouldn't affect how it operates, so that people can get the
+behavior they want with whatever name they want.
+
+Special thanks to Paul Eggert, Brian Matthews, Bruce Evans, Karl Berry,
+Kaveh Ghazi, and François Pinard for help with debugging and porting
+these programs. Many thanks to all of the people who have taken the
+time to submit problem reports and fixes. All contributed changes are
+attributed in the ChangeLog file.
+
+And thanks to the following people who have provided accounts for
+portability testing on many different types of systems: Bob Proulx,
+Christian Robert, François Pinard, Greg McGary, Harlan Stenn,
+Joel N. Weber, Mark D. Roth, Matt Schalit, Nelson H. F. Beebe,
+Réjean Payette, Sam Tardieu.
+
+Thanks to Michael Stone for inflicting test releases of the fileutils
+on Debian's unstable distribution, and to all the kind folks who used
+that distribution and found and reported bugs.
+
+Note that each man page is now automatically generated from a template
+and from the corresponding --help usage message. Patches to the template
+files (man/*.x) are welcome. However, the authoritative documentation
+is in texinfo form in the doc directory.
+
+If you run the tests on a SunOS4.1.4 system, expect the ctime-part of
+the ls `time-1' test to fail. I believe that is due to a bug in the
+way Sun implemented link(2) and chmod(2).
+
+***************************************
+Last-minute notes, before coreutils-5.0
+---------------------------------------
+
+A known problem exists when compiling on HPUX on both hppa and ia64
+in 64-bit mode (i.e. +DD64) on all known HPUX 11.x versions. This
+is not due to a bug in the package but instead due to a bug in the
+system header file which breaks things in 64-bit mode. The default
+compilation mode is 32-bit and the software compiles fine using the
+default mode. To build this software in 64-bit mode you will need
+to fix the system /usr/include/inttypes.h header file. After
+correcting that file the software also compiles fine in 64-bit mode.
+Here is one possible patch to correct the problem.
+
+--- /usr/include/inttypes.h.orig Thu May 30 01:00:00 1996
++++ /usr/include/inttypes.h Sun Mar 23 00:20:36 2003
+@@ -489 +489 @@
+-#ifndef __STDC_32_MODE__
++#ifndef __LP64__
+
+If you run the tests as root, note that a few of them create files
+and/or run programs as a non-root user, `nobody' by default.
+If you want to use some other non-root username, specify it via
+the NON_ROOT_USERNAME environment variable. Depending on the
+permissions with which the working directories have been created,
+using `nobody' may fail, because that user won't have the required
+read and write access to the build and test directories.
+I find that it is best to unpack and build as a non-privileged
+user, and then to run the following command as that user in order
+to run the privilege-requiring tests:
+
+ sudo env NON_ROOT_USERNAME=$USER make check
+
+If you can run the tests as root, please do so and report any
+problems. We get much less test coverage in that mode, and it's
+arguably more important that these tools work well when run by
+root than when run by less privileged users.
+
+***************************************
+
+There are pretty many tests, but nowhere near as many as we need.
+Additions and corrections are very welcome.
+
+If you see a problem that you've already reported, feel free to re-report
+it -- it won't bother me to get a reminder. Besides, the more messages I
+get regarding a particular problem the sooner it'll be fixed -- usually.
+If you sent a complete patch and, after a couple weeks you haven't
+received any acknowledgement, please ping us. A complete patch includes
+a well-written ChangeLog entry, unified (diff -u format) diffs relative
+to the most recent test release (or, better, relative to the latest
+sources in the CVS repository), an explanation for why the patch is
+necessary or useful, and if at all possible, enough information to
+reproduce whatever problem prompted it. Plus, you'll earn lots of
+karma if you include a test case to exercise any bug(s) you fix.
+Instructions for checking out the latest source via CVS are here:
+
+ http://savannah.gnu.org/cvs/?group=coreutils
+
+
+If your patch adds a new feature, please try to get some sort of consensus
+that it is a worthwhile change. One way to do that is to send mail to
+bug-coreutils@gnu.org including as much description and justification
+as you can. Based on the feedback that generates, you may be able to
+convince us that it's worth adding.
+
+
+WARNING: If you modify files like configure.in, m4/*.m4, aclocal.m4,
+or any Makefile.am, then don't be surprised if what gets regenerated no
+longer works. To make things work, you'll have to be using appropriate
+versions of automake and autoconf. As for what versions are `appropriate',
+use the versions of
+
+ * autoconf specified via AC_PREREQ in m4/jm-macros.m4
+ * automake specified via AM_INIT_AUTOMAKE in configure.ac
+
+Usually it's fine to use versions that are newer than those specified.
+
+These programs all recognize the `--version' option. When reporting
+bugs, please include in the subject line both the package name/version
+and the name of the program for which you found a problem.
+
+For general documentation on the coding and usage standards
+this distribution follows, see the GNU Coding Standards,
+http://www.gnu.org/prep/standards_toc.html.
+
+Mail suggestions and bug reports for these programs to
+the address on the last line of --help output.
diff --git a/contrib/gnu-sort/THANKS b/contrib/gnu-sort/THANKS
new file mode 100644
index 0000000..44b7b02
--- /dev/null
+++ b/contrib/gnu-sort/THANKS
@@ -0,0 +1,463 @@
+These people have contributed to the GNU coreutils (formerly, the fileutils,
+textutils, and/or sh-utils packages). Some have reported problems, others
+have contributed improvements to the documentation, actual code, and even
+complete programs. Those contributions are described in the ChangeLog
+files. If your name has been left out, if you'd rather not be listed,
+or if you'd prefer a different address be used, please send a note to
+the bug-report mailing list (as seen on last line of e.g., cp --help).
+
+??? kytek@cybercomm.net
+A Costa agcosta@gis.net
+Achim Blumensath blume@corona.oche.de
+Adam Klein aklein@debian.org
+Akim Demaille demaille@inf.enst.fr
+Alain Magloire alain@qnx.com
+Alan Iwi iwi@atm.ox.ac.uk
+Albert Chin-A-Young china@thewrittenword.com
+Albert Hopkins ahopkins@dynacare.com
+Alberto Accomazzi alberto@cfa0.harvard.edu
+aldomel aldomel@ix.netcom.com
+Alen Muzinic zveki@fly.cc.fer.hr
+Alexandre Duret-Lutz duret_g@epita.fr
+Alexey Solovyov alekso@math.uu.se
+Alexey Vyskubov alexey@pippuri.mawhrin.net
+Alfred M. Szmidt ams@kemisten.nu
+Andi Kleen freitag@alancoxonachip.com
+Andre Novaes Cunha Andre.Cunha@br.global-one.net
+Andreas Gruenbacher ag@bestbits.at
+Andreas Jaeger jaeger@gnu.org
+Andreas Luik luik@isa.de
+Andreas Schwab schwab@suse.de
+Andreas Stolcke stolcke@ICSI.Berkeley.EDU
+Andrei Gaponenko andr@triumf.ca
+Andres Soolo andres@soolo.matti.ee
+Andrew Burgess aab@cichlid.com
+Andrew Dalke dalke@bioreason.com
+Andrew Fabbro andrew@fabbro.org
+Andrew Pham andpha@us.ibm.com
+Andrew Tridgell tridge@samba.org
+Andrey Borzenkov arvidjaar@mail.ru
+Andries Brouwer Andries.Brouwer@cwi.nl
+Andy Longton alongton@metamark.com
+Anthony Thyssen anthony@griffith.edu.au
+Antonio Rendas ajrendas@yahoo.com
+Ariel Faigon ariel@cthulhu.engr.sgi.com
+Arne H. Juul arnej@solan.unit.no
+Arne Henrik Juul arnej@imf.unit.no
+Arnold Robbins arnold@skeeve.com
+Arthur Pool pool@commerce.uq.edu.au
+Arun Sharma arun.sharma@intel.com
+Arvind Autar Autar022@planet.nl
+Augey Mikus mikus@dqc.org
+Austin Donnelly Austin.Donnelly@cl.cam.ac.uk
+Axel Kittenberger Anshil@gmx.net
+Bauke Jan Douma bjdouma@xs4all.nl
+Ben Elliston bje@air.net.au
+Ben Harris bjh21@netbsd.org
+Benjamin Cutler cutlerbc@simla.colostate.edu
+Bengt Martensson bengt@mathematik.uni-Bremen.de
+Bernard Giroud bernard.giroud@creditlyonnais.ch
+Bernd Leibing bernd.leibing@rz.uni-ulm.de
+Bernd Melchers melchers@cis.fu-berlin.de
+Bernhard Baehr bernhard.baehr@gmx.de
+Bernhard Gabler bernhard@uni-koblenz.de
+Bernhard Rosenkraenzer bero@redhat.de
+Bert Deknuydt Bert.Deknuydt@esat.kuleuven.ac.be
+Bill Peters peters@gaffel.as.arizona.edu
+Bjorn Helgaas helgaas@rsn.hp.com
+Bob McCracken kerouac@ravenet.com
+Bob Proulx rwp@fc.hp.com
+Branden Robinson branden@necrotic.deadbeast.net
+Brendan O'Dea bod@compusol.com.au
+Brian Kimball bfk@footbag.org
+Brian Youmans 3diff@gnu.org
+Bruce Korb bkorb@veritas.com
+Bruce Robertson brucer@theodolite.dyndns.org
+Bruno Haible haible@clisp.cons.org
+Carl Johnson carlj@cjlinux.home.org
+Carl Lowenstein cdl@mpl.UCSD.EDU
+Carlos Canau Carlos.Canau@relay.puug.pt
+Charles Karney karney@pppl.gov
+Charles Randall crandall@matchlogic.com
+Chip Salzenberg chip@valinux.com
+Chris Faylor cgf@cygnus.com
+Chris J. Bednar cjb@AdvancedDataSolutions.com
+Chris Lesniewski ctl@mit.edu
+Chris Sylvain csylvain@umm.edu
+Chris Yeo cyeo@biking.org
+Christi Alice Scarborough christi@chiark.greenend.org.uk
+Christian Harkort christian.harkort@web.de
+Christian Krackowizer ckrackowiz@std.schuler-ag.com
+Christian Rose menthos@menthos.com
+Christian von Roques roques@pond.sub.org
+Chuck Hedrick hedrick@klinzhai.rutgers.edu
+Clark Morgan cmorgan@aracnet.com
+Clement Wang clem.wang@overture.com
+Colin Plumb colin@nyx.net
+Colin Watson cjw44@riva.ucam.org
+Collin Rogowski collin@rogowski.de
+Cray-Cyber Project http://www.cray-cyber.org
+Dale Scheetz dwarf@polaris.net
+Dan Hagerty hag@gnu.ai.it.edu
+Dan Jacobson http://www.geocities.com/jidani
+Dan Pascu dan@services.iiruc.ro
+Daniel Bergstrom noa@melody.se
+Dániel Varga danielv@axelero.hu
+Danny Levinson danny.levinson@overture.com
+Darren Salt ds@youmustbejoking.demon.co.uk
+Dave Beckett dajobe@dajobe.org
+David Dyck dcd@tc.fluke.COM
+David Eisner cradle@umd.edu
+David Flynn dav@chess.plus.com
+David Godfrey dave@delta.demon.co.uk
+David Luyer david_luyer@pacific.net.au
+David Malone dwmalone@cnri.dit.ie
+Deepak Goel deego@gnufans.org
+Dennis Henriksen opus@flamingo.osrl.dk
+Dennis Smit ds@nerds-incorporated.org
+Derek Clegg dclegg@next.com
+Dick Streefland dick_streefland@tasking.com
+Dirk Lattermann dlatt@t-online.de
+Dirk-Jan Faber djfaber@snow.nl
+Dmitry Rutsky rutsky@school.ioffe.rssi.ru
+Dmitry V. Levin ldv@altlinux.org
+Don Parsons dparsons@synapse.kent.edu
+Donni Erpel donald@appc11.gsi.de
+Doug Coleman coleman@iarc1.ece.utexas.edu
+Doug McLaren dougmc@comco.com
+Dragos Harabor dharabor@us.oracle.com
+Duncan Roe duncanr@optimation.com.au
+Ed Avis ed@membled.com
+Edzer Pebesma Edzer.Pebesma@rivm.nl
+Eirik Fuller eirik@hackrat.com
+Eivind eivindt@multinet.no
+Eli Zaretskii eliz@is.elta.co.il
+Emile LeBlanc leblanc@math.toronto.edu
+Eric Backus ericb@lsid.hp.com
+Eric G. Miller egm2@jps.net
+Eric Pemente pemente@northpark.edu
+Eric S. Raymond esr@snark.thyrsus.com
+Erik Bennett bennett@cvo.oneworld.com
+Erik Corry erik@kroete2.freinet.de
+Felix Lee flee@teleport.com
+Ferdinand fw@scenic.mine.nu
+Fletcher Mattox fletcher@cs.utexas.edu
+Florin Iucha fiucha@hsys.mic.ro
+François Pinard pinard@iro.umontreal.ca
+Frank Adler fadler@allesklar.de
+Frank T Lofaro ftlofaro@snooks.Egr.UNLV.EDU
+Fred Fish fnf@ninemoons.com
+Frédéric L. W. Meunier 0@pervalidus.net
+Frederik Eaton frederik@caltech.edu
+Gabor Z. Papp gzp@gzp.org.hu
+Gaël Quéri gqueri@mail.dotcom.fr
+Galen Hazelwood galenh@micron.net
+Gary Anderson ganderson@clark.net
+Gary V. Vaughan gary@gnu.org
+Gaute Hvoslef Kvalnes gaute@verdsveven.com
+Geoff Collyer geoff at collyer.net
+Geoff Kuenning geoff@cs.hmc.edu
+Geoff Odhner geoff@franklin.com
+Geoff Whale geoffw@cse.unsw.EDU.AU
+Gerhard Poul gpoul@gnu.org
+Germano Leichsenring germano@jedi.cs.kobe-u.ac.jp
+Göran Uddeborg goeran@uddeborg.pp.se
+GOTO Masanori gotom@debian.or.jp
+Greg Louis glouis@dynamicro.on.ca
+Greg McGary gkm@gnu.org
+Greg Schafer gschafer@zip.com.au
+Greg Troxel gdt@bbn.com
+Greg Wooledge gawooledge@sherwin.com
+Gregory Leblanc gleblanc@cu-portland.edu
+Guido Leenders guido.leenders@invantive.com
+H. J. Lu hjl@valinux.com
+Hans Ginzel hans@matfyz.cz
+Hans Lermen lermen@fgan.de
+Hans Verkuil hans@wyst.hobby.nl
+Harry Liu rliu@lek.ugcs.caltech.edu
+Harti Brandt brandt@fokus.fraunhofer.de
+Herbert Xu herbert@gondor.apana.org.au
+Holger Berger hberger@ess.nec.de
+Hon-Yin Kok hkok@yoda.unl.edu
+Hugh Daniel hugh@xanadu.com
+Ian Bruce ian.bruce@myrealbox.com
+Ian Jackson ijackson@chiark.greenend.org.uk
+Ian Lance Taylor ian@cygnus.com
+Ian Turner vectro@pipeline.com
+Iida Yosiaki iida@gnu.org
+Ingo Saitz ingo@debian.org
+Ivo Timmermans ivo@debian.org
+James james@albion.glarp.com
+James Antill jmanti%essex.ac.uk@seralph21.essex.ac.uk
+James Sneeringer jvs@ocslink.com
+James Tanis jtt@soscorp.com
+James Youngman james+usenet@free-lunch.demon.co.uk
+Jamie Lokier jamie@imbolc.ucc.ie
+Jan Fedak J.Fedak@sh.cvut.cz
+Jan Nieuwenhuizen janneke@gnu.org
+Janos Farkas chexum@shadow.banki.hu
+Jarkko Hietaniemi jhi@epsilon.hut.fi
+Jean Charles Delepine delepine@u-picardie.fr
+Jeff Moore jbm@mordor.com
+Jeff Sheinberg jeff@bsrd.net
+Jens Elkner elkner@imsgroup.de
+Jens Schmidt jms@jsds.hamburg.com
+Jerome Abela abela@hsc.fr
+Jérôme Zago bug-coreutils-ml@agt-the-walker.net
+Jesse Kornblum kornblum@usna.edu
+Jesse Thilo jgt2@eecs.lehigh.edu
+Jie Xu xuj@iag.net
+Jim Blandy jimb@cyclic.com
+Jim Dennis jimd@starshine.org
+Joakim Rosqvist dvljrt@cs.umu.se
+Jochen Hein jochen@jochen.org
+Joe Orton joe@manyfish.co.uk
+Johan Danielsson joda@pdc.kth.se
+John Bley jbb6@acpub.duke.edu
+John David Anglin dave.anglin@nrc.ca
+John Gatewood Ham zappaman@alphabox.compsci.buu.ac.th
+John Gotts jgotts@umich.edu
+John Kendall kendall@capps.com
+John Kodis kodis@acm.org
+John Murphy jam@philabs.research.philips.com
+John Roll john@panic.harvard.edu
+John Salmon johns@mullet.anu.edu.au
+John Summerfield summer@OS2.ami.com.au
+Jon Peatfield J.S.Peatfield@damtp.cam.ac.uk
+Joost van Baal joostvb@xs4all.nl
+Jorge Stolfi stolfi@ic.unicamp.br
+Joseph S. Myers jsm28@cam.ac.uk
+Juan F. Codagnone juam@arnet.com.ar
+Jungshik Shin jshin@pantheon.yale.edu
+Jürgen Fluk louis@dachau.marco.de
+Jurriaan thunder7@xs4all.nl
+jvogel jvogel@linkny.com
+Kai Henningsen kai@debian.org
+Kai-Uwe Rommel rommel@informatik.tu-muenchen.de
+Kalle Olavi Niemitalo kon@iki.fi
+Kamal Paul Nigam Kamal_Paul_Nigam@gs35.sp.cs.cmu.edu
+Karl Eichwalder keichwa@gmx.net
+Karl Heuer kwzh@gnu.org
+Karl-Michael Schneider schneide@phil.uni-passau.de
+Karsten Thygesen karthy@kom.auc.dk
+Kaveh R. Ghazi ghazi@caip.rutgers.edu
+Keith M. Briggs keith.briggs@bt.com
+Keith Owens kaos@audio.apana.org.au
+Keith Thompson kst@cts.com
+Ken Pizzini kenp@halcyon.com
+Kristin E Thomas kristint@us.ibm.com
+Kjetil Torgrim Homme kjetilho@ifi.uio.no
+Kristoffer Rose kris@diku.dk
+Larry McVoy lm@sgi.com
+Lars Hecking lhecking@nmrc.ucc.ie
+Leah Q eequor@earthlink.net
+Lehti Rami rammer@cs.tut.fi
+Leonard N. Zubkoff lnz@dandelion.com
+Leonardo Milano lmilano@udel.edu
+Lorne Baker lbaker@nitro.avint.net
+Luke Hassell lukehassell@yahoo.com
+M. P. Suzuki mpsuzuki@hiroshima-u.ac.jp
+Maciej Kwapulinski pikpok@univ.gda.pl
+Manas Garg manas@cygsoft.com
+Manfred Hollstein manfred@s-direktnet.de
+Marc Boucher marc@mbsi.ca
+Marc Haber mh+debian-bugs@zugschlus.de
+Marc Olzheim marcolz@stack.nl
+Marco Franzen Marco.Franzen@Thyron.com
+Marcus Brinkmann http://www.marcus-brinkmann.de
+Marcus Daniels marcus@ee.pdx.edu
+Mark A. Thomas thommark@access.digex.net
+Mark Conty Mark_Conty@cargill.com
+Mark D. Roth roth@uiuc.edu
+Mark Funkenhauser mfunkenhauser@rogers.com
+Mark Harris mark@monitor.designacc.com
+Mark Hewitt mhewitt@armature.com
+Mark Hounschell markh@compro.net
+Mark Hubbart discord@mac.com
+Mark Kettenis kettenis@phys.uva.nl
+Mark Nudelman marknu@flash.net
+Mark W. Eichin eichin@cygnus.com
+Markus Demleitner msdemlei@auriga.ari.uni-heidelberg.de
+Martin martin@dresden.nacamar.de
+Martin Buck martin.buck@ascom.ch
+Martin Gallant martyg@goodbit.net
+Martin Hippe martin.hippe@schlund.de
+Martin Michlmayr tbm@cyrius.com
+Martin Mitchell martin@debian.org
+Martin P.J. Zinser zinser@decus.de
+Marty Leisner leisner@sdsp.mc.xerox.com
+Masami Takikawa takikawm@CS.ORST.EDU
+Mate Wierdl mw@moni.msci.memphis.edu
+Matej Vela mvela@public.srce.hr
+Matt Perry matt@primefactor.com
+Matt Schalit mschalit@pacbell.net
+Matt Swift swift@alum.mit.edu
+Matthew Arnison maffew@cat.org.au
+Matthew Braun matthew@ans.net
+Matthew Clarke Matthew_Clarke@mindlink.bc.ca
+Matthew S. Levine mslevine@theory.lcs.mit.edu
+Matthew Smith matts@bluesguitar.org
+Matthew Swift swift@alum.mit.edu
+Matthias Urlichs smurf@noris.de
+Matti Aarnio matti.aarnio@zmailer.org
+Mattias Wadenstein maswan@acc.umu.se
+Meelis Roos mroos@tartu.cyber.ee
+Michael michael@aplatform.com
+Michael ??? michael@roka.net
+Michael Bacarella mbac@netgraft.com>
+Michael Deutschmann michael@talamasca.ocis.net
+Michael Elizabeth Chastain mec.gnu@mindspring.com
+Michael Gaughen mgaughen@polyserve.com
+Michael Hasselberg mikelh@zonta.ping.de
+Michael Hohn hohn@math.utah.edu
+Michael J. Croghan mcroghan@usatoday.com
+Michael McFarland sidlon@yahoo.com
+Michael Piefel piefel@informatik.hu-berlin.de
+Michael Steffens michael.steffens@s.netic.de
+Michael Stone mstone@debian.org
+Michael Stutz stutz@dsl.org
+Michael van Elst mlelstv@dev.de.cw.net
+Michael Veksler mveksler@techunix.technion.ac.il
+Michail Litvak mci@owl.openwall.com
+Michal Politowski mpol@charybda.icm.edu.pl
+Michal Svec msvec@suse.cz
+Michel Robitaille robitail@IRO.UMontreal.CA
+Michiel Bacchiani bacchian@raven.bu.edu
+Mike Castle dalgoda@ix.netcom.com
+Mike Coleman mkc@mathdogs.com
+Mike Jetzer mjetzer@mke.catalystwms.com
+Mikko Tuumanen m@sorvankyla.yok.utu.fi
+Mikulas Patocka mikulas@artax.karlin.mff.cuni.cz
+Miles Bader miles@gnu.ai.mit.edu
+Minh Tran-Le tranle@intellicorp.com
+Morten Welinder terra@diku.dk
+Neal H Walfield neal@cs.uml.edu
+Neil Brown neilb@cse.unsw.edu.au
+Nelson H. F. Beebe beebe@math.utah.edu
+Nick Estes debian@nickstoys.com
+Nick Lawes nlawes@silverplatter.com
+Niklas Edmundsson nikke@acc.umu.se
+Nikola Milutinovic Nikola.Milutinovic@ev.co.yu
+Noah Friedman friedman@splode.com
+Noel Cragg noel@red-bean.com
+Olatunji Oluwabukunmi Ruwase tjruwase@stanford.edu
+Olav Morkrid olav@funcom.com
+Ole Laursen olau@hardworking.dk
+Oliver Kiddle okiddle@yahoo.co.uk
+Ørn E. Hansen oehansen@daimi.aau.dk
+Oskar Liljeblad osk@hem.passagen.se
+Patrick Mauritz oxygene@studentenbude.ath.cx
+Paul Eggert eggert@twinsun.com
+Paul Jarc prj@po.cwru.edu
+Paul Nevai nevai@ops.mps.ohio-state.edu
+Paul Sauer paul@alexa.com
+Paul Slootman paul@debian.org
+Paul Worrall paul@basilisk.uklinux.net
+Pawel Prokop pablo@wizard.ae.krakow.pl
+Per Cederqvist ceder@lysator.liu.se
+Per Kristian Hove perhov@math.ntnu.no
+Peter Eriksson peter@ifm.liu.se
+Peter Horst peter@ointment.org
+Peter Moulder reiter@netspace.net.au
+Peter Samuelson psamuels@sampo.creighton.edu
+Peter Seebach seebs@taniemarie.solon.com
+Petter Reinholdtsen pere@hungry.com
+Phelippe Neveu pneveu@pcigeomatics.com
+Phil Richards phil.richards@vf.vodafone.co.uk
+Philippe De Muyter phdm@macqel.be
+Philippe Schnoebelen Philippe.Schnoebelen@imag.fr
+Phillip Jones mouse@datastacks.com
+Piergiorgio Sartor sartor@sony.de
+Piotr Kwapulinski kwap@univ.gda.pl
+Prashant TR tr@eth.net
+Rainer Orth ro@TechFak.Uni-Bielefeld.DE
+Ralf W. Stephan stephan@tmt.de
+Ralph Loader loader@maths.ox.ac.uk
+Raul Miller moth@magenta.com
+Raúl Núñez de Arenas Coronado raul@pleyades.net
+Reuben Thomas rrt@sc3d.org
+Richard A Downing richard.downing@bcs.org.uk
+Richard Braakman dark@xs4all.nl
+Richard Dawe rich@phekda.freeserve.co.uk
+Richard J. Rauenzahn rrauenza@hairball.cup.hp.com
+Richard Neill rn214@hermes.cam.ac.uk
+Richard Sharman rsharman@magmacom.com
+Rick Sladkey jrs@world.std.com
+Rik Faith faith@cs.unc.edu
+Risto Kankkunen kankkune@lingsoft.fi
+Robert H. de Vries robert@and.nl
+Robert Millan zeratul2@wanadoo.es
+Rogier Wolff R.E.Wolff@BitWizard.nl
+Roland Huebner ro-huebner@gmx.de
+Roland Turner raz.tah.bet@raz.cx
+Ronald F. Guilmette rfg@netcom.com
+Ross Alexander r.alexander@auckland.ac.nz
+Ross Paterson rap@doc.ic.ac.uk
+Ross Ridge rridge@calum.csclub.uwaterloo.ca
+Sami Farin sfarin@ratol.fi
+Samuel Tardieu sam@rfc1149.net
+Samuli Karkkainen Samuli.Karkkainen@hut.fi
+Sander van Malssen svm@kozmix.ow.nl
+Santiago Vila Doncel sanvila@unex.es
+Savochkin Andrey Vladimirovich saw@msu.ru
+Scott Lurndal slurn@griffin.engr.sgi.com
+Shing-Shong Shei shei@cs.indiana.edu
+Soeren Sonnenburg sonnenburg@informatik.hu-berlin.de
+Solar Designer solar@owl.openwall.com
+Stanislav Ievlev inger@altlinux.ru
+Stéphane Chazelas Stephane_CHAZELAS@yahoo.fr
+Stephen Depooter sbdep@myrealbox.com
+Stephen Eglen eglen@pcg.wustl.edu
+Stephen Gildea gildea@stop.mail-abuse.org
+Stephen Smoogen smooge@mindspring.com
+Steve McConnel steve@acadcomp.sil.org
+Steven G. Johnson stevenj@alum.mit.edu
+Steven Mocking ufo@quicknet.nl
+Steven P Watson steven@magelico.net
+Stuart Kemp skemp@peter.bmc.com
+Szakacsits Szabolcs szaka@sienet.hu
+Tadayoshi Funaba tadf@kt.rim.or.jp
+TAKAI Kousuke takai@vlsi.kuee.kyoto-u.ac.jp
+Theodore Ts'o tytso@rsts-11.mit.edu
+Thomas Bushnell thomas@gnu.ai.mit.edu
+Thomas Goerlich thomas@schnappmatik.de
+Thomas Luzat thomas@luzat.com
+Thomas Quinot thomas@Cuivre.FR.EU.ORG
+Tim J. Robbins tjr@FreeBSD.org
+Tim Mooney mooney@dogbert.cc.ndsu.NoDak.edu
+Tim Smithers mouse@dmouse.com.au
+Tim Waugh twaugh@redhat
+Todd A. Jacobs tjacobs@codegnome.org
+Tom Haynes thomas@netapp.com
+Tom Quinn trq@dionysos.thphys.ox.ac.uk
+Tommi Kyntola tkyntola@cc.hut.fi
+Ton Hospel thospel@mail.dma.be
+Ton Nijkes ton@murphy.nl
+Tony Kocurko akocurko@mun.ca
+Tony Leneis tony@plaza.ds.adp.com
+Tony Robinson ajr@eng.cam.ac.uk
+Torbjorn Granlund tege@nada.kth.se
+Torbjorn Lindgren tl@funcom.no
+Torsten Landschoff torsten@pclab.ifg.uni-kiel.de
+Ulrich Drepper drepper@gnu.org
+Urs Thuermann urs@isnogud.escape.de
+Uwe H. Steinfeld usteinfeld@gmx.net
+Vesselin Atanasov vesselin@bgnet.bg
+Vin Shelton acs@alumni.princeton.edu
+Volker Borchert bt@teknon.de
+Volker Paul vpaul@dohle.com
+Wartan Hachaturow wart@tepkom.ru
+Wayne Stewart wstewa@atl.com
+Wenjun Zheng zwj@yahoo.com
+Werner Almesberger Werner.Almesberger@epfl.ch
+Wichert Akkerman wichert@cistron.nl
+Will Edgington wedgingt@acm.org
+William Bader william@nscs.fast.net
+William Dowling will@franklin.com
+William Lewis wiml@omnigroup.com
+wiregauze wiregauze@yahoo.com
+Wojciech Purczynski cliph@isec.pl
+Wolfram Kleff kleff@cs.uni-bonn.de
+Won-kyu Park wkpark@chem.skku.ac.kr
+Yann Dirson dirson@debian.org
+Zvi Har'El rl@math.technion.ac.il
diff --git a/contrib/gnu-sort/THANKS-to-translators b/contrib/gnu-sort/THANKS-to-translators
new file mode 100644
index 0000000..c84ff64
--- /dev/null
+++ b/contrib/gnu-sort/THANKS-to-translators
@@ -0,0 +1,36 @@
+The following teams have translated the many diagnostics of this
+package into many different languages. Thank you!
+
+---
+http://www.iro.umontreal.ca/contrib/po/HTML/team-af.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-be.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-ca.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-cs.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-da.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-de.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-el.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-es.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-et.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-fi.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-fr.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-ga.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-gl.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-hu.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-it.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-ja.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-ko.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-lg.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-ms.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-nb.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-nl.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-no.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-pl.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-pt.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-pt_BR.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-ru.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-sk.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-sl.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-sv.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-tr.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-zh_CN.html
+http://www.iro.umontreal.ca/contrib/po/HTML/team-zh_TW.html
diff --git a/contrib/gnu-sort/TODO b/contrib/gnu-sort/TODO
new file mode 100644
index 0000000..82a74bf
--- /dev/null
+++ b/contrib/gnu-sort/TODO
@@ -0,0 +1,171 @@
+restore djgpp, eventually
+merge TODO lists
+add unit tests for lib/*.c
+
+strip: add an option to specify the program used to strip binaries.
+ suggestion from Karl Berry
+
+doc/coreutils.texi:
+ Address this comment: FIXME: mv's behavior in this case is system-dependent
+ Better still: fix the code so it's *not* system-dependent.
+
+implement --target-directory=DIR for install (per texinfo documentation)
+
+ls: add --format=FORMAT option that controls how each line is printed.
+
+cp --no-preserve=X should not attempt to preserve attribute X
+ reported by Andreas Schwab
+
+copy.c: Address the FIXME-maybe comment in copy_internal.
+And once that's done, add an exclusion so that `cp --link'
+no longer incurs the overhead of saving src. dev/ino and dest. filename
+in the hash table.
+
+See if we can be consistent about where --verbose sends its output:
+ These all send --verbose output to stdout:
+ head, tail, rm, cp, mv, ln, chmod, chown, chgrp, install, ln
+ These send it to stderr:
+ shred mkdir split
+ readlink is different
+
+Write an autoconf test to work around build failure in HPUX's 64-bit mode.
+See notes in README -- and remove them once there's a work-around.
+
+Integrate use of sendfile, suggested here:
+ http://mail.gnu.org/archive/html/bug-fileutils/2003-03/msg00030.html
+I don't plan to do that, since a few tests demonstrate no significant benefit.
+
+Should printf '\0123' print "\n3"?
+ per report from TAKAI Kousuke on Mar 27
+ http://mail.gnu.org/archive/html/bug-coreutils/2003-03/index.html
+
+printf: consider adapting builtins/printf.def from bash
+
+df: add `--total' option, suggested here http://bugs.debian.org/186007
+
+seq: give better diagnostics for invalid formats:
+ e.g. no or too many % directives
+seq: consider allowing format string to contain no %-directives
+
+m4: rename all macros that start with AC_ to start with another prefix
+
+resolve RH report on cp -a forwarded by Tim Waugh
+
+Martin Michlmayr's patch to provide ls with `--sort directory' option
+
+tail: don't use xlseek; it *exits*.
+ Instead, maybe use a macro and return nonzero.
+
+add mktemp? Suggested by Nelson Beebe
+
+df: alignment problem of `Used' heading with e.g., -mP
+ reported by Karl Berry
+
+tr: support nontrivial equivalence classes, e.g. [=e=] with LC_COLLATE=fr_FR
+
+fix tail -f to work with named pipes; reported by Ian D. Allen
+ $ mkfifo j; tail -f j & sleep 1; echo x > j
+ ./tail: j: file truncated
+ ./tail: j: cannot seek to offset 0: Illegal seek
+
+lib/strftime.c: Since %N is the only format that we need but that
+ glibc's strftime doesn't support, consider using a wrapper that
+ would expand /%(-_)?\d*N/ to the desired string and then pass the
+ resulting string to glibc's strftime.
+
+sort: Compress temporary files when doing large external sort/merges.
+ This improves performance when you can compress/uncompress faster than
+ you can read/write, which is common in these days of fast CPUs.
+ suggestion from Charles Randall on 2001-08-10
+
+sort: Add an ordering option -R that causes 'sort' to sort according
+ to a random permutation of the correct sort order. Also, add an
+ option --random-seed=SEED that causes 'sort' to use an arbitrary
+ string SEED to select which permutations to use, in a deterministic
+ manner: that is, if you sort a permutation of the same input file
+ with the same --random-seed=SEED option twice, you'll get the same
+ output. The default SEED is chosen at random, and contains enough
+ information to ensure that the output permutation is random.
+ suggestion from Feth AREZKI, Stephan Kasal, and Paul Eggert on 2003-07-17
+
+unexpand: [http://www.opengroup.org/onlinepubs/007908799/xcu/unexpand.html]
+ printf 'x\t \t y\n'|unexpand -t 8,9 should print its input, unmodified.
+ printf 'x\t \t y\n'|unexpand -t 5,8 should print "x\ty\n"
+
+Let GNU su use the `wheel' group if appropriate.
+ (there are a couple patches, already)
+
+sort: Investigate better sorting algorithms; see Knuth vol. 3.
+
+ We tried list merge sort, but it was about 50% slower than the
+ recursive algorithm currently used by sortlines, and it used more
+ comparisons. We're not sure why this was, as the theory suggests it
+ should do fewer comparisons, so perhaps this should be revisited.
+ List merge sort was implemented in the style of Knuth algorithm
+ 5.2.4L, with the optimization suggested by exercise 5.2.4-22. The
+ test case was 140,213,394 bytes, 426,4424 lines, text taken from the
+ GCC 3.3 distribution, sort.c compiled with GCC 2.95.4 and running on
+ Debian 3.0r1 GNU/Linux, 2.4GHz Pentium 4, single pass with no
+ temporary files and plenty of RAM.
+
+ Since comparisons seem to be the bottleneck, perhaps the best
+ algorithm to try next should be merge insertion. See Knuth section
+ 5.3.1, who credits Lester Ford, Jr. and Selmer Johnson, American
+ Mathematical Monthly 66 (1959), 387-389.
+
+cp --recursive: perform dir traversals in source and dest hierarchy rather
+ than forming full file names. The latter (current) approach fails
+ unnecessarily when the names become very long.
+
+tail --p is now ambiguous
+
+Remove suspicious uses of alloca (ones that may allocate more than
+ about 4k)
+
+Adapt these contribution guidelines for coreutils:
+ http://sources.redhat.com/automake/contribute.html
+
+
+Changes expected to go in, post-5.2.1:
+======================================
+
+ wc: add an option, --files0-from [as for du] to make it read NUL-delimited
+ file name arguments from a file.
+
+ dd patch from Olivier Delhomme
+
+ Apply Andreas Gruenbacher's ACL and xattr changes
+
+ Apply Bruno Haible's hostname changes
+
+ test/mv/*: clean up $other_partition_tmpdir in all cases
+
+ ls: when both -l and --dereference-command-line-symlink-to-dir are
+ specified, consider whether to let the latter select whether to
+ dereference command line symlinks to directories. Since -l has
+ an implicit --NO-dereference-command-line-symlink-to-dir meaning.
+ Pointed out by Karl Berry.
+
+ A more efficient version of factor, and possibly one that
+ accepts inputs of size 2^64 and larger.
+
+ Re-add a separate test for du's stack space usage (like the one removed
+ from tests/rm/deep-1).
+
+ dd: consider adding an option to suppress `bytes/block read/written'
+ output to stderr. Suggested here:
+ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=165045
+
+ Pending copyright papers:
+ ------------------------
+ ls --color: Ed Avis' patch to suppress escape sequences for
+ non-highlighted files
+
+ getpwnam from Bruce Korb
+
+ pb (progress bar) from Miika Pekkarinen
+
+ Look into improving the performance of md5sum.
+ `openssl md5' is consistently about 30% faster than md5sum on an idle
+ AMD 2000-XP system with plenty of RAM and a 261 MB input file.
+ openssl's md5 implementation is in assembly, generated by a perl script.
diff --git a/contrib/gnu-sort/lib/__fpending.c b/contrib/gnu-sort/lib/__fpending.c
new file mode 100644
index 0000000..a872102
--- /dev/null
+++ b/contrib/gnu-sort/lib/__fpending.c
@@ -0,0 +1,30 @@
+/* __fpending.c -- return the number of pending output bytes on a stream
+ Copyright (C) 2000 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Jim Meyering. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "__fpending.h"
+
+size_t
+__fpending (FILE *fp)
+{
+ return PENDING_OUTPUT_N_BYTES;
+}
diff --git a/contrib/gnu-sort/lib/__fpending.h b/contrib/gnu-sort/lib/__fpending.h
new file mode 100644
index 0000000..5a51582
--- /dev/null
+++ b/contrib/gnu-sort/lib/__fpending.h
@@ -0,0 +1,17 @@
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+#include <stdio.h>
+
+#if HAVE_STDIO_EXT_H
+# include <stdio_ext.h>
+#endif
+
+#ifndef HAVE_DECL___FPENDING
+"this configure-time declaration test was not run"
+#endif
+#if !HAVE_DECL___FPENDING
+size_t __fpending (FILE *);
+#endif
diff --git a/contrib/gnu-sort/lib/argmatch.c b/contrib/gnu-sort/lib/argmatch.c
new file mode 100644
index 0000000..1a8ec2f
--- /dev/null
+++ b/contrib/gnu-sort/lib/argmatch.c
@@ -0,0 +1,278 @@
+/* argmatch.c -- find a match for a string in an array
+
+ Copyright (C) 1990, 1998, 1999, 2001, 2002, 2003, 2004 Free
+ Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by David MacKenzie <djm@ai.mit.edu>
+ Modified by Akim Demaille <demaille@inf.enst.fr> */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification. */
+#include "argmatch.h"
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+#include "error.h"
+#include "exit.h"
+#include "quotearg.h"
+#include "quote.h"
+#include "unlocked-io.h"
+
+/* When reporting an invalid argument, show nonprinting characters
+ by using the quoting style ARGMATCH_QUOTING_STYLE. Do not use
+ literal_quoting_style. */
+#ifndef ARGMATCH_QUOTING_STYLE
+# define ARGMATCH_QUOTING_STYLE locale_quoting_style
+#endif
+
+/* Non failing version of argmatch call this function after failing. */
+#ifndef ARGMATCH_DIE
+# include "exitfail.h"
+# define ARGMATCH_DIE exit (exit_failure)
+#endif
+
+#ifdef ARGMATCH_DIE_DECL
+ARGMATCH_DIE_DECL;
+#endif
+
+static void
+__argmatch_die (void)
+{
+ ARGMATCH_DIE;
+}
+
+/* Used by XARGMATCH and XARGCASEMATCH. See description in argmatch.h.
+ Default to __argmatch_die, but allow caller to change this at run-time. */
+argmatch_exit_fn argmatch_die = __argmatch_die;
+
+
+/* If ARG is an unambiguous match for an element of the
+ null-terminated array ARGLIST, return the index in ARGLIST
+ of the matched element, else -1 if it does not match any element
+ or -2 if it is ambiguous (is a prefix of more than one element).
+
+ If VALLIST is none null, use it to resolve ambiguities limited to
+ synonyms, i.e., for
+ "yes", "yop" -> 0
+ "no", "nope" -> 1
+ "y" is a valid argument, for `0', and "n" for `1'. */
+
+ptrdiff_t
+argmatch (const char *arg, const char *const *arglist,
+ const char *vallist, size_t valsize)
+{
+ size_t i; /* Temporary index in ARGLIST. */
+ size_t arglen; /* Length of ARG. */
+ ptrdiff_t matchind = -1; /* Index of first nonexact match. */
+ bool ambiguous = false; /* If true, multiple nonexact match(es). */
+
+ arglen = strlen (arg);
+
+ /* Test all elements for either exact match or abbreviated matches. */
+ for (i = 0; arglist[i]; i++)
+ {
+ if (!strncmp (arglist[i], arg, arglen))
+ {
+ if (strlen (arglist[i]) == arglen)
+ /* Exact match found. */
+ return i;
+ else if (matchind == -1)
+ /* First nonexact match found. */
+ matchind = i;
+ else
+ {
+ /* Second nonexact match found. */
+ if (vallist == NULL
+ || memcmp (vallist + valsize * matchind,
+ vallist + valsize * i, valsize))
+ {
+ /* There is a real ambiguity, or we could not
+ disambiguate. */
+ ambiguous = true;
+ }
+ }
+ }
+ }
+ if (ambiguous)
+ return -2;
+ else
+ return matchind;
+}
+
+/* Error reporting for argmatch.
+ CONTEXT is a description of the type of entity that was being matched.
+ VALUE is the invalid value that was given.
+ PROBLEM is the return value from argmatch. */
+
+void
+argmatch_invalid (const char *context, const char *value, ptrdiff_t problem)
+{
+ char const *format = (problem == -1
+ ? _("invalid argument %s for %s")
+ : _("ambiguous argument %s for %s"));
+
+ error (0, 0, format, quotearg_n_style (0, ARGMATCH_QUOTING_STYLE, value),
+ quote_n (1, context));
+}
+
+/* List the valid arguments for argmatch.
+ ARGLIST is the same as in argmatch.
+ VALLIST is a pointer to an array of values.
+ VALSIZE is the size of the elements of VALLIST */
+void
+argmatch_valid (const char *const *arglist,
+ const char *vallist, size_t valsize)
+{
+ size_t i;
+ const char *last_val = NULL;
+
+ /* We try to put synonyms on the same line. The assumption is that
+ synonyms follow each other */
+ fprintf (stderr, _("Valid arguments are:"));
+ for (i = 0; arglist[i]; i++)
+ if ((i == 0)
+ || memcmp (last_val, vallist + valsize * i, valsize))
+ {
+ fprintf (stderr, "\n - `%s'", arglist[i]);
+ last_val = vallist + valsize * i;
+ }
+ else
+ {
+ fprintf (stderr, ", `%s'", arglist[i]);
+ }
+ putc ('\n', stderr);
+}
+
+/* Never failing versions of the previous functions.
+
+ CONTEXT is the context for which argmatch is called (e.g.,
+ "--version-control", or "$VERSION_CONTROL" etc.). Upon failure,
+ calls the (supposed never to return) function EXIT_FN. */
+
+ptrdiff_t
+__xargmatch_internal (const char *context,
+ const char *arg, const char *const *arglist,
+ const char *vallist, size_t valsize,
+ argmatch_exit_fn exit_fn)
+{
+ ptrdiff_t res = argmatch (arg, arglist, vallist, valsize);
+ if (res >= 0)
+ /* Success. */
+ return res;
+
+ /* We failed. Explain why. */
+ argmatch_invalid (context, arg, res);
+ argmatch_valid (arglist, vallist, valsize);
+ (*exit_fn) ();
+
+ return -1; /* To please the compilers. */
+}
+
+/* Look for VALUE in VALLIST, an array of objects of size VALSIZE and
+ return the first corresponding argument in ARGLIST */
+const char *
+argmatch_to_argument (const char *value,
+ const char *const *arglist,
+ const char *vallist, size_t valsize)
+{
+ size_t i;
+
+ for (i = 0; arglist[i]; i++)
+ if (!memcmp (value, vallist + valsize * i, valsize))
+ return arglist[i];
+ return NULL;
+}
+
+#ifdef TEST
+/*
+ * Based on "getversion.c" by David MacKenzie <djm@gnu.ai.mit.edu>
+ */
+char *program_name;
+
+/* When to make backup files. */
+enum backup_type
+{
+ /* Never make backups. */
+ none,
+
+ /* Make simple backups of every file. */
+ simple,
+
+ /* Make numbered backups of files that already have numbered backups,
+ and simple backups of the others. */
+ numbered_existing,
+
+ /* Make numbered backups of every file. */
+ numbered
+};
+
+/* Two tables describing arguments (keys) and their corresponding
+ values */
+static const char *const backup_args[] =
+{
+ "no", "none", "off",
+ "simple", "never",
+ "existing", "nil",
+ "numbered", "t",
+ 0
+};
+
+static const enum backup_type backup_vals[] =
+{
+ none, none, none,
+ simple, simple,
+ numbered_existing, numbered_existing,
+ numbered, numbered
+};
+
+int
+main (int argc, const char *const *argv)
+{
+ const char *cp;
+ enum backup_type backup_type = none;
+
+ program_name = (char *) argv[0];
+
+ if (argc > 2)
+ {
+ fprintf (stderr, "Usage: %s [VERSION_CONTROL]\n", program_name);
+ exit (1);
+ }
+
+ if ((cp = getenv ("VERSION_CONTROL")))
+ backup_type = XARGMATCH ("$VERSION_CONTROL", cp,
+ backup_args, backup_vals);
+
+ if (argc == 2)
+ backup_type = XARGMATCH (program_name, argv[1],
+ backup_args, backup_vals);
+
+ printf ("The version control is `%s'\n",
+ ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals));
+
+ return 0;
+}
+#endif
diff --git a/contrib/gnu-sort/lib/argmatch.h b/contrib/gnu-sort/lib/argmatch.h
new file mode 100644
index 0000000..8952394
--- /dev/null
+++ b/contrib/gnu-sort/lib/argmatch.h
@@ -0,0 +1,112 @@
+/* argmatch.h -- definitions and prototypes for argmatch.c
+
+ Copyright (C) 1990, 1998, 1999, 2001, 2002, 2004 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by David MacKenzie <djm@ai.mit.edu>
+ Modified by Akim Demaille <demaille@inf.enst.fr> */
+
+#ifndef ARGMATCH_H_
+# define ARGMATCH_H_ 1
+
+# include <stddef.h>
+
+# define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
+
+# define ARGMATCH_CONSTRAINT(Arglist, Vallist) \
+ (ARRAY_CARDINALITY (Arglist) == ARRAY_CARDINALITY (Vallist) + 1)
+
+/* Assert there are as many real arguments as there are values
+ (argument list ends with a NULL guard). ARGMATCH_VERIFY is
+ preferred, since it is guaranteed to be checked at compile-time.
+ ARGMATCH_ASSERT is for backward compatibility only. */
+
+# define ARGMATCH_VERIFY(Arglist, Vallist) \
+ struct argmatch_verify \
+ { \
+ char argmatch_verify[ARGMATCH_CONSTRAINT(Arglist, Vallist) ? 1 : -1]; \
+ }
+
+# define ARGMATCH_ASSERT(Arglist, Vallist) \
+ assert (ARGMATCH_CONSTRAINT (Arglist, Vallist))
+
+/* Return the index of the element of ARGLIST (NULL terminated) that
+ matches with ARG. If VALLIST is not NULL, then use it to resolve
+ false ambiguities (i.e., different matches of ARG but corresponding
+ to the same values in VALLIST). */
+
+ptrdiff_t argmatch (char const *arg, char const *const *arglist,
+ char const *vallist, size_t valsize);
+
+# define ARGMATCH(Arg, Arglist, Vallist) \
+ argmatch (Arg, Arglist, (char const *) (Vallist), sizeof *(Vallist))
+
+/* xargmatch calls this function when it fails. This function should not
+ return. By default, this is a function that calls ARGMATCH_DIE which
+ in turn defaults to `exit (exit_failure)'. */
+typedef void (*argmatch_exit_fn) (void);
+extern argmatch_exit_fn argmatch_die;
+
+/* Report on stderr why argmatch failed. Report correct values. */
+
+void argmatch_invalid (char const *context, char const *value,
+ ptrdiff_t problem);
+
+/* Left for compatibility with the old name invalid_arg */
+
+# define invalid_arg(Context, Value, Problem) \
+ argmatch_invalid (Context, Value, Problem)
+
+
+
+/* Report on stderr the list of possible arguments. */
+
+void argmatch_valid (char const *const *arglist,
+ char const *vallist, size_t valsize);
+
+# define ARGMATCH_VALID(Arglist, Vallist) \
+ argmatch_valid (Arglist, (char const *) (Vallist), sizeof *(Vallist))
+
+
+
+/* Same as argmatch, but upon failure, reports a explanation on the
+ failure, and exits using the function EXIT_FN. */
+
+ptrdiff_t __xargmatch_internal (char const *context,
+ char const *arg, char const *const *arglist,
+ char const *vallist, size_t valsize,
+ argmatch_exit_fn exit_fn);
+
+/* Programmer friendly interface to __xargmatch_internal. */
+
+# define XARGMATCH(Context, Arg, Arglist, Vallist) \
+ ((Vallist) [__xargmatch_internal (Context, Arg, Arglist, \
+ (char const *) (Vallist), \
+ sizeof *(Vallist), \
+ argmatch_die)])
+
+/* Convert a value into a corresponding argument. */
+
+char const *argmatch_to_argument (char const *value,
+ char const *const *arglist,
+ char const *vallist, size_t valsize);
+
+# define ARGMATCH_TO_ARGUMENT(Value, Arglist, Vallist) \
+ argmatch_to_argument (Value, Arglist, \
+ (char const *) (Vallist), sizeof *(Vallist))
+
+#endif /* ARGMATCH_H_ */
diff --git a/contrib/gnu-sort/lib/closeout.c b/contrib/gnu-sort/lib/closeout.c
new file mode 100644
index 0000000..3c7bed9
--- /dev/null
+++ b/contrib/gnu-sort/lib/closeout.c
@@ -0,0 +1,93 @@
+/* closeout.c - close standard output
+
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "closeout.h"
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+#include "error.h"
+#include "exitfail.h"
+#include "quotearg.h"
+#include "unlocked-io.h"
+#include "__fpending.h"
+
+static const char *file_name;
+
+/* Set the file name to be reported in the event an error is detected
+ by close_stdout. */
+void
+close_stdout_set_file_name (const char *file)
+{
+ file_name = file;
+}
+
+/* Close standard output, exiting with status 'exit_failure' on failure.
+ If a program writes *anything* to stdout, that program should `fflush'
+ stdout and make sure that it succeeds before exiting. Otherwise,
+ suppose that you go to the extreme of checking the return status
+ of every function that does an explicit write to stdout. The last
+ printf can succeed in writing to the internal stream buffer, and yet
+ the fclose(stdout) could still fail (due e.g., to a disk full error)
+ when it tries to write out that buffered data. Thus, you would be
+ left with an incomplete output file and the offending program would
+ exit successfully.
+
+ FIXME: note the fflush suggested above is implicit in the fclose
+ we actually do below. Consider doing only the fflush and/or using
+ setvbuf to inhibit buffering.
+
+ Besides, it's wasteful to check the return value from every call
+ that writes to stdout -- just let the internal stream state record
+ the failure. That's what the ferror test is checking below.
+
+ It's important to detect such failures and exit nonzero because many
+ tools (most notably `make' and other build-management systems) depend
+ on being able to detect failure in other tools via their exit status. */
+
+void
+close_stdout (void)
+{
+ int e = ferror (stdout) ? 0 : -1;
+
+ /* If the stream's error bit is clear and there is nothing to flush,
+ then return right away. */
+ if (e && __fpending (stdout) == 0)
+ return;
+
+ if (fclose (stdout) != 0)
+ e = errno;
+
+ if (0 <= e)
+ {
+ char const *write_error = _("write error");
+ if (file_name)
+ error (exit_failure, e, "%s: %s", quotearg_colon (file_name),
+ write_error);
+ else
+ error (exit_failure, e, "%s", write_error);
+ }
+}
diff --git a/contrib/gnu-sort/lib/closeout.h b/contrib/gnu-sort/lib/closeout.h
new file mode 100644
index 0000000..1b715ee
--- /dev/null
+++ b/contrib/gnu-sort/lib/closeout.h
@@ -0,0 +1,33 @@
+/* Close standard output.
+
+ Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef CLOSEOUT_H
+# define CLOSEOUT_H 1
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+void close_stdout_set_file_name (const char *file);
+void close_stdout (void);
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
diff --git a/contrib/gnu-sort/lib/dup-safer.c b/contrib/gnu-sort/lib/dup-safer.c
new file mode 100644
index 0000000..408a1bd
--- /dev/null
+++ b/contrib/gnu-sort/lib/dup-safer.c
@@ -0,0 +1,59 @@
+/* Invoke dup, but avoid some glitches.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
+#include <unistd-safer.h>
+
+/* Like dup, but do not return STDIN_FILENO, STDOUT_FILENO, or
+ STDERR_FILENO. */
+
+int
+dup_safer (int fd)
+{
+#ifdef F_DUPFD
+ return fcntl (fd, F_DUPFD, STDERR_FILENO + 1);
+#else
+ int f = dup (fd);
+ if (0 <= f && f <= STDERR_FILENO)
+ {
+ int f1 = dup_safer (f);
+ int e = errno;
+ close (f);
+ errno = e;
+ f = f1;
+ }
+ return f;
+#endif
+}
diff --git a/contrib/gnu-sort/lib/error.c b/contrib/gnu-sort/lib/error.c
new file mode 100644
index 0000000..5a5e126
--- /dev/null
+++ b/contrib/gnu-sort/lib/error.c
@@ -0,0 +1,306 @@
+/* Error handler for noninteractive utilities
+ Copyright (C) 1990-1998, 2000-2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "error.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _LIBC
+# include <libintl.h>
+#else
+# include "gettext.h"
+#endif
+
+#ifdef _LIBC
+# include <wchar.h>
+# define mbsrtowcs __mbsrtowcs
+#endif
+
+#if !_LIBC
+# include "unlocked-io.h"
+#endif
+
+#ifndef _
+# define _(String) String
+#endif
+
+/* If NULL, error will flush stdout, then print on stderr the program
+ name, a colon and a space. Otherwise, error will call this
+ function without parameters instead. */
+void (*error_print_progname) (void);
+
+/* This variable is incremented each time `error' is called. */
+unsigned int error_message_count;
+
+#ifdef _LIBC
+/* In the GNU C library, there is a predefined variable for this. */
+
+# define program_name program_invocation_name
+# include <errno.h>
+# include <libio/libioP.h>
+
+/* In GNU libc we want do not want to use the common name `error' directly.
+ Instead make it a weak alias. */
+extern void __error (int status, int errnum, const char *message, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
+extern void __error_at_line (int status, int errnum, const char *file_name,
+ unsigned int line_number, const char *message,
+ ...)
+ __attribute__ ((__format__ (__printf__, 5, 6)));;
+# define error __error
+# define error_at_line __error_at_line
+
+# include <libio/iolibio.h>
+# define fflush(s) INTUSE(_IO_fflush) (s)
+# undef putc
+# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
+
+# include <bits/libc-lock.h>
+
+#else /* not _LIBC */
+
+# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
+# ifndef HAVE_DECL_STRERROR_R
+"this configure-time declaration test was not run"
+# endif
+char *strerror_r ();
+# endif
+
+# ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+# endif
+
+/* The calling program should define program_name and set it to the
+ name of the executing program. */
+extern char *program_name;
+
+# if HAVE_STRERROR_R || defined strerror_r
+# define __strerror_r strerror_r
+# endif
+#endif /* not _LIBC */
+
+static void
+print_errno_message (int errnum)
+{
+ char const *s = NULL;
+
+#if defined HAVE_STRERROR_R || _LIBC
+ char errbuf[1024];
+# if STRERROR_R_CHAR_P || _LIBC
+ s = __strerror_r (errnum, errbuf, sizeof errbuf);
+# else
+ if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
+ s = errbuf;
+# endif
+#endif
+
+#if !_LIBC
+ if (! s && ! (s = strerror (errnum)))
+ s = _("Unknown system error");
+#endif
+
+#if _LIBC
+ if (_IO_fwide (stderr, 0) > 0)
+ {
+ __fwprintf (stderr, L": %s", s);
+ return;
+ }
+#endif
+
+ fprintf (stderr, ": %s", s);
+}
+
+static void
+error_tail (int status, int errnum, const char *message, va_list args)
+{
+#if _LIBC
+ if (_IO_fwide (stderr, 0) > 0)
+ {
+# define ALLOCA_LIMIT 2000
+ size_t len = strlen (message) + 1;
+ const wchar_t *wmessage = L"out of memory";
+ wchar_t *wbuf = (len < ALLOCA_LIMIT
+ ? alloca (len * sizeof *wbuf)
+ : len <= SIZE_MAX / sizeof *wbuf
+ ? malloc (len * sizeof *wbuf)
+ : NULL);
+
+ if (wbuf)
+ {
+ size_t res;
+ mbstate_t st;
+ const char *tmp = message;
+ memset (&st, '\0', sizeof (st));
+ res = mbsrtowcs (wbuf, &tmp, len, &st);
+ wmessage = res == (size_t) -1 ? L"???" : wbuf;
+ }
+
+ __vfwprintf (stderr, wmessage, args);
+ if (! (len < ALLOCA_LIMIT))
+ free (wbuf);
+ }
+ else
+#endif
+ vfprintf (stderr, message, args);
+ va_end (args);
+
+ ++error_message_count;
+ if (errnum)
+ print_errno_message (errnum);
+#if _LIBC
+ if (_IO_fwide (stderr, 0) > 0)
+ putwc (L'\n', stderr);
+ else
+#endif
+ putc ('\n', stderr);
+ fflush (stderr);
+ if (status)
+ exit (status);
+}
+
+
+/* Print the program name and error message MESSAGE, which is a printf-style
+ format string with optional args.
+ If ERRNUM is nonzero, print its corresponding system error message.
+ Exit with status STATUS if it is nonzero. */
+void
+error (int status, int errnum, const char *message, ...)
+{
+ va_list args;
+
+#if defined _LIBC && defined __libc_ptf_call
+ /* We do not want this call to be cut short by a thread
+ cancellation. Therefore disable cancellation for now. */
+ int state = PTHREAD_CANCEL_ENABLE;
+ __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
+ 0);
+#endif
+
+ fflush (stdout);
+#ifdef _LIBC
+ _IO_flockfile (stderr);
+#endif
+ if (error_print_progname)
+ (*error_print_progname) ();
+ else
+ {
+#if _LIBC
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s: ", program_name);
+ else
+#endif
+ fprintf (stderr, "%s: ", program_name);
+ }
+
+ va_start (args, message);
+ error_tail (status, errnum, message, args);
+
+#ifdef _LIBC
+ _IO_funlockfile (stderr);
+# ifdef __libc_ptf_call
+ __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
+# endif
+#endif
+}
+
+/* Sometimes we want to have at most one error per line. This
+ variable controls whether this mode is selected or not. */
+int error_one_per_line;
+
+void
+error_at_line (int status, int errnum, const char *file_name,
+ unsigned int line_number, const char *message, ...)
+{
+ va_list args;
+
+ if (error_one_per_line)
+ {
+ static const char *old_file_name;
+ static unsigned int old_line_number;
+
+ if (old_line_number == line_number
+ && (file_name == old_file_name
+ || strcmp (old_file_name, file_name) == 0))
+ /* Simply return and print nothing. */
+ return;
+
+ old_file_name = file_name;
+ old_line_number = line_number;
+ }
+
+#if defined _LIBC && defined __libc_ptf_call
+ /* We do not want this call to be cut short by a thread
+ cancellation. Therefore disable cancellation for now. */
+ int state = PTHREAD_CANCEL_ENABLE;
+ __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
+ 0);
+#endif
+
+ fflush (stdout);
+#ifdef _LIBC
+ _IO_flockfile (stderr);
+#endif
+ if (error_print_progname)
+ (*error_print_progname) ();
+ else
+ {
+#if _LIBC
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s: ", program_name);
+ else
+#endif
+ fprintf (stderr, "%s:", program_name);
+ }
+
+ if (file_name != NULL)
+ {
+#if _LIBC
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s:%d: ", file_name, line_number);
+ else
+#endif
+ fprintf (stderr, "%s:%d: ", file_name, line_number);
+ }
+
+ va_start (args, message);
+ error_tail (status, errnum, message, args);
+
+#ifdef _LIBC
+ _IO_funlockfile (stderr);
+# ifdef __libc_ptf_call
+ __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
+# endif
+#endif
+}
+
+#ifdef _LIBC
+/* Make the weak alias. */
+# undef error
+# undef error_at_line
+weak_alias (__error, error)
+weak_alias (__error_at_line, error_at_line)
+#endif
diff --git a/contrib/gnu-sort/lib/error.h b/contrib/gnu-sort/lib/error.h
new file mode 100644
index 0000000..8ed6359
--- /dev/null
+++ b/contrib/gnu-sort/lib/error.h
@@ -0,0 +1,66 @@
+/* Declaration for error-reporting function
+ Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _ERROR_H
+#define _ERROR_H 1
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+# define __attribute__(Spec) /* empty */
+# endif
+/* The __-protected variants of `format' and `printf' attributes
+ are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+# define __format__ format
+# define __printf__ printf
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Print a message with `fprintf (stderr, FORMAT, ...)';
+ if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
+ If STATUS is nonzero, terminate the program with `exit (STATUS)'. */
+
+extern void error (int __status, int __errnum, const char *__format, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
+
+extern void error_at_line (int __status, int __errnum, const char *__fname,
+ unsigned int __lineno, const char *__format, ...)
+ __attribute__ ((__format__ (__printf__, 5, 6)));
+
+/* If NULL, error will flush stdout, then print on stderr the program
+ name, a colon and a space. Otherwise, error will call this
+ function without parameters instead. */
+extern void (*error_print_progname) (void);
+
+/* This variable is incremented each time `error' is called. */
+extern unsigned int error_message_count;
+
+/* Sometimes we want to have at most one error per line. This
+ variable controls whether this mode is selected or not. */
+extern int error_one_per_line;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* error.h */
diff --git a/contrib/gnu-sort/lib/exit.h b/contrib/gnu-sort/lib/exit.h
new file mode 100644
index 0000000..4e8d465
--- /dev/null
+++ b/contrib/gnu-sort/lib/exit.h
@@ -0,0 +1,32 @@
+/* exit() function.
+ Copyright (C) 1995, 2001 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _EXIT_H
+#define _EXIT_H
+
+/* Get exit() declaration. */
+#include <stdlib.h>
+
+/* Some systems do not define EXIT_*, even with STDC_HEADERS. */
+#ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+#endif
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#endif
+
+#endif /* _EXIT_H */
diff --git a/contrib/gnu-sort/lib/exitfail.c b/contrib/gnu-sort/lib/exitfail.c
new file mode 100644
index 0000000..2ae5f69
--- /dev/null
+++ b/contrib/gnu-sort/lib/exitfail.c
@@ -0,0 +1,27 @@
+/* Failure exit status
+
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "exitfail.h"
+#include "exit.h"
+
+int volatile exit_failure = EXIT_FAILURE;
diff --git a/contrib/gnu-sort/lib/exitfail.h b/contrib/gnu-sort/lib/exitfail.h
new file mode 100644
index 0000000..cf5ab71
--- /dev/null
+++ b/contrib/gnu-sort/lib/exitfail.h
@@ -0,0 +1,20 @@
+/* Failure exit status
+
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING.
+ If not, write to the Free Software Foundation,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+extern int volatile exit_failure;
diff --git a/contrib/gnu-sort/lib/fopen-safer.c b/contrib/gnu-sort/lib/fopen-safer.c
new file mode 100644
index 0000000..c5c97c8
--- /dev/null
+++ b/contrib/gnu-sort/lib/fopen-safer.c
@@ -0,0 +1,72 @@
+/* Invoke fopen, but avoid some glitches.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <unistd-safer.h>
+
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdio-safer.h>
+
+/* Like fopen, but do not return stdin, stdout, or stderr. */
+
+FILE *
+fopen_safer (char const *file, char const *mode)
+{
+ FILE *fp = fopen (file, mode);
+
+ if (fp)
+ {
+ int fd = fileno (fp);
+
+ if (0 <= fd && fd <= STDERR_FILENO)
+ {
+ int f = dup_safer (fd);
+
+ if (f < 0)
+ {
+ int e = errno;
+ fclose (fp);
+ errno = e;
+ return NULL;
+ }
+
+ if (fclose (fp) != 0
+ || ! (fp = fdopen (f, mode)))
+ {
+ int e = errno;
+ close (f);
+ errno = e;
+ return NULL;
+ }
+ }
+ }
+
+ return fp;
+}
diff --git a/contrib/gnu-sort/lib/gettext.h b/contrib/gnu-sort/lib/gettext.h
new file mode 100644
index 0000000..835732e
--- /dev/null
+++ b/contrib/gnu-sort/lib/gettext.h
@@ -0,0 +1,68 @@
+/* Convenience header for conditional use of GNU <libintl.h>.
+ Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _LIBGETTEXT_H
+#define _LIBGETTEXT_H 1
+
+/* NLS can be disabled through the configure --disable-nls option. */
+#if ENABLE_NLS
+
+/* Get declarations of GNU message catalog functions. */
+# include <libintl.h>
+
+#else
+
+/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
+ chokes if dcgettext is defined as a macro. So include it now, to make
+ later inclusions of <locale.h> a NOP. We don't include <libintl.h>
+ as well because people using "gettext.h" will not include <libintl.h>,
+ and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
+ is OK. */
+#if defined(__sun)
+# include <locale.h>
+#endif
+
+/* Disabled NLS.
+ The casts to 'const char *' serve the purpose of producing warnings
+ for invalid uses of the value returned from these functions.
+ On pre-ANSI systems without 'const', the config.h file is supposed to
+ contain "#define const". */
+# define gettext(Msgid) ((const char *) (Msgid))
+# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
+# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
+# define ngettext(Msgid1, Msgid2, N) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define dngettext(Domainname, Msgid1, Msgid2, N) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+# define textdomain(Domainname) ((const char *) (Domainname))
+# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
+# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
+
+#endif
+
+/* A pseudo function call that serves as a marker for the automated
+ extraction of messages, but does not call gettext(). The run-time
+ translation is done at a different place in the code.
+ The argument, String, should be a literal string. Concatenated strings
+ and other string expressions won't work.
+ The macro's expansion is not parenthesized, so that it is suitable as
+ initializer for static 'char[]' or 'const char[]' variables. */
+#define gettext_noop(String) String
+
+#endif /* _LIBGETTEXT_H */
diff --git a/contrib/gnu-sort/lib/hard-locale.c b/contrib/gnu-sort/lib/hard-locale.c
new file mode 100644
index 0000000..45b7d05
--- /dev/null
+++ b/contrib/gnu-sort/lib/hard-locale.c
@@ -0,0 +1,76 @@
+/* hard-locale.c -- Determine whether a locale is hard.
+
+ Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+/* $FreeBSD$ */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "hard-locale.h"
+
+#if HAVE_LOCALE_H
+# include <locale.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+/* Return true if the current CATEGORY locale is hard, i.e. if you
+ can't get away with assuming traditional C or POSIX behavior. */
+bool
+hard_locale (int category)
+{
+#if ! HAVE_SETLOCALE
+ return false;
+#else
+
+ bool hard = true;
+ char const *p = setlocale (category, NULL);
+
+ if (p)
+ {
+# if defined(__FreeBSD__) || (defined __GLIBC__ && 2 <= __GLIBC__)
+ if (strcmp (p, "C") == 0 || strcmp (p, "POSIX") == 0)
+ hard = false;
+# else
+ char *locale = malloc (strlen (p) + 1);
+ if (locale)
+ {
+ strcpy (locale, p);
+
+ /* Temporarily set the locale to the "C" and "POSIX" locales
+ to find their names, so that we can determine whether one
+ or the other is the caller's locale. */
+ if (((p = setlocale (category, "C"))
+ && strcmp (p, locale) == 0)
+ || ((p = setlocale (category, "POSIX"))
+ && strcmp (p, locale) == 0))
+ hard = false;
+
+ /* Restore the caller's locale. */
+ setlocale (category, locale);
+ free (locale);
+ }
+# endif
+ }
+
+ return hard;
+
+#endif
+}
diff --git a/contrib/gnu-sort/lib/hard-locale.h b/contrib/gnu-sort/lib/hard-locale.h
new file mode 100644
index 0000000..010cb27
--- /dev/null
+++ b/contrib/gnu-sort/lib/hard-locale.h
@@ -0,0 +1,26 @@
+/* Determine whether a locale is hard.
+
+ Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef HARD_LOCALE_H_
+# define HARD_LOCALE_H_ 1
+
+# include <stdbool.h>
+
+bool hard_locale (int);
+
+#endif /* HARD_LOCALE_H_ */
diff --git a/contrib/gnu-sort/lib/human.c b/contrib/gnu-sort/lib/human.c
new file mode 100644
index 0000000..f024c73
--- /dev/null
+++ b/contrib/gnu-sort/lib/human.c
@@ -0,0 +1,485 @@
+/* human.c -- print human readable file size
+
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert and Larry McVoy. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "human.h"
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+#ifndef UINTMAX_MAX
+# define UINTMAX_MAX ((uintmax_t) -1)
+#endif
+
+#if HAVE_LOCALE_H && HAVE_LOCALECONV
+# include <locale.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+#include <argmatch.h>
+#include <error.h>
+#include <xstrtol.h>
+
+/* The maximum length of a suffix like "KiB". */
+#define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
+
+static const char power_letter[] =
+{
+ 0, /* not used */
+ 'K', /* kibi ('k' for kilo is a special case) */
+ 'M', /* mega or mebi */
+ 'G', /* giga or gibi */
+ 'T', /* tera or tebi */
+ 'P', /* peta or pebi */
+ 'E', /* exa or exbi */
+ 'Z', /* zetta or 2**70 */
+ 'Y' /* yotta or 2**80 */
+};
+
+
+/* If INEXACT_STYLE is not human_round_to_nearest, and if easily
+ possible, adjust VALUE according to the style. */
+
+static long double
+adjust_value (int inexact_style, long double value)
+{
+ /* Do not use the floorl or ceill functions, as that would mean
+ checking for their presence and possibly linking with the
+ standard math library, which is a porting pain. So leave the
+ value alone if it is too large to easily round. */
+ if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
+ {
+ uintmax_t u = value;
+ value = u + (inexact_style == human_ceiling && u != value);
+ }
+
+ return value;
+}
+
+/* Group the digits of NUMBER according to the grouping rules of the
+ current locale. NUMBER contains NUMBERLEN digits. Modify the
+ bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
+ each byte inserted. Return the starting address of the modified
+ number.
+
+ To group the digits, use GROUPING and THOUSANDS_SEP as in `struct
+ lconv' from <locale.h>. */
+
+static char *
+group_number (char *number, size_t numberlen,
+ char const *grouping, char const *thousands_sep)
+{
+ register char *d;
+ size_t grouplen = SIZE_MAX;
+ size_t thousands_seplen = strlen (thousands_sep);
+ size_t i = numberlen;
+
+ /* The maximum possible value for NUMBERLEN is the number of digits
+ in the square of the largest uintmax_t, so double the size of
+ uintmax_t before converting to a bound. 302 / 1000 is ceil
+ (log10 (2.0)). Add 1 for integer division truncation. */
+ char buf[2 * sizeof (uintmax_t) * CHAR_BIT * 302 / 1000 + 1];
+
+ memcpy (buf, number, numberlen);
+ d = number + numberlen;
+
+ for (;;)
+ {
+ unsigned char g = *grouping;
+
+ if (g)
+ {
+ grouplen = g < CHAR_MAX ? g : i;
+ grouping++;
+ }
+
+ if (i < grouplen)
+ grouplen = i;
+
+ d -= grouplen;
+ i -= grouplen;
+ memcpy (d, buf + i, grouplen);
+ if (i == 0)
+ return d;
+
+ d -= thousands_seplen;
+ memcpy (d, thousands_sep, thousands_seplen);
+ }
+}
+
+/* Convert N to a human readable format in BUF, using the options OPTS.
+
+ N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must
+ be nonnegative.
+
+ Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE
+ must be positive.
+
+ Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
+ to determine whether to take the ceiling or floor of any result
+ that cannot be expressed exactly.
+
+ If (OPTS & human_group_digits), group the thousands digits
+ according to the locale, e.g., `1,000,000' in an American English
+ locale.
+
+ If (OPTS & human_autoscale), deduce the output block size
+ automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
+ output. Use powers of 1024 if (OPTS & human_base_1024), and powers
+ of 1000 otherwise. For example, assuming powers of 1024, 8500
+ would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
+ so on. Numbers smaller than the power aren't modified.
+ human_autoscale is normally used together with human_SI.
+
+ If (OPTS & human_SI), append an SI prefix indicating which power is
+ being used. If in addition (OPTS & human_B), append "B" (if base
+ 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
+ human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
+ power of 1024 or of 1000, depending on (OPTS &
+ human_base_1024). */
+
+char *
+human_readable (uintmax_t n, char *buf, int opts,
+ uintmax_t from_block_size, uintmax_t to_block_size)
+{
+ int inexact_style =
+ opts & (human_round_to_nearest | human_floor | human_ceiling);
+ unsigned int base = opts & human_base_1024 ? 1024 : 1000;
+ uintmax_t amt;
+ int tenths;
+ int exponent = -1;
+ int exponent_max = sizeof power_letter - 1;
+ char *p;
+ char *psuffix;
+ char const *integerlim;
+
+ /* 0 means adjusted N == AMT.TENTHS;
+ 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
+ 2 means adjusted N == AMT.TENTHS + 0.05;
+ 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */
+ int rounding;
+
+ char const *decimal_point = ".";
+ size_t decimal_pointlen = 1;
+ char const *grouping = "";
+ char const *thousands_sep = "";
+#if HAVE_LOCALE_H && HAVE_LOCALECONV
+ struct lconv const *l = localeconv ();
+ size_t pointlen = strlen (l->decimal_point);
+ if (0 < pointlen && pointlen <= MB_LEN_MAX)
+ {
+ decimal_point = l->decimal_point;
+ decimal_pointlen = pointlen;
+ }
+ grouping = l->grouping;
+ if (strlen (l->thousands_sep) <= MB_LEN_MAX)
+ thousands_sep = l->thousands_sep;
+#endif
+
+ psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
+ p = psuffix;
+
+ /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
+ units. If this can be done exactly with integer arithmetic, do
+ not use floating point operations. */
+ if (to_block_size <= from_block_size)
+ {
+ if (from_block_size % to_block_size == 0)
+ {
+ uintmax_t multiplier = from_block_size / to_block_size;
+ amt = n * multiplier;
+ if (amt / multiplier == n)
+ {
+ tenths = 0;
+ rounding = 0;
+ goto use_integer_arithmetic;
+ }
+ }
+ }
+ else if (from_block_size != 0 && to_block_size % from_block_size == 0)
+ {
+ uintmax_t divisor = to_block_size / from_block_size;
+ uintmax_t r10 = (n % divisor) * 10;
+ uintmax_t r2 = (r10 % divisor) * 2;
+ amt = n / divisor;
+ tenths = r10 / divisor;
+ rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
+ goto use_integer_arithmetic;
+ }
+
+ {
+ /* Either the result cannot be computed easily using uintmax_t,
+ or from_block_size is zero. Fall back on floating point.
+ FIXME: This can yield answers that are slightly off. */
+
+ long double dto_block_size = to_block_size;
+ long double damt = n * (from_block_size / dto_block_size);
+ size_t buflen;
+ size_t nonintegerlen;
+
+ if (! (opts & human_autoscale))
+ {
+ sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
+ buflen = strlen (buf);
+ nonintegerlen = 0;
+ }
+ else
+ {
+ long double e = 1;
+ exponent = 0;
+
+ do
+ {
+ e *= base;
+ exponent++;
+ }
+ while (e * base <= damt && exponent < exponent_max);
+
+ damt /= e;
+
+ sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
+ buflen = strlen (buf);
+ nonintegerlen = decimal_pointlen + 1;
+
+ if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
+ || ((opts & human_suppress_point_zero)
+ && buf[buflen - 1] == '0'))
+ {
+ sprintf (buf, "%.0Lf",
+ adjust_value (inexact_style, damt * 10) / 10);
+ buflen = strlen (buf);
+ nonintegerlen = 0;
+ }
+ }
+
+ p = psuffix - buflen;
+ memmove (p, buf, buflen);
+ integerlim = p + buflen - nonintegerlen;
+ }
+ goto do_grouping;
+
+ use_integer_arithmetic:
+ {
+ /* The computation can be done exactly, with integer arithmetic.
+
+ Use power of BASE notation if requested and if adjusted AMT is
+ large enough. */
+
+ if (opts & human_autoscale)
+ {
+ exponent = 0;
+
+ if (base <= amt)
+ {
+ do
+ {
+ unsigned int r10 = (amt % base) * 10 + tenths;
+ unsigned int r2 = (r10 % base) * 2 + (rounding >> 1);
+ amt /= base;
+ tenths = r10 / base;
+ rounding = (r2 < base
+ ? (r2 + rounding) != 0
+ : 2 + (base < r2 + rounding));
+ exponent++;
+ }
+ while (base <= amt && exponent < exponent_max);
+
+ if (amt < 10)
+ {
+ if (inexact_style == human_round_to_nearest
+ ? 2 < rounding + (tenths & 1)
+ : inexact_style == human_ceiling && 0 < rounding)
+ {
+ tenths++;
+ rounding = 0;
+
+ if (tenths == 10)
+ {
+ amt++;
+ tenths = 0;
+ }
+ }
+
+ if (amt < 10
+ && (tenths || ! (opts & human_suppress_point_zero)))
+ {
+ *--p = '0' + tenths;
+ p -= decimal_pointlen;
+ memcpy (p, decimal_point, decimal_pointlen);
+ tenths = rounding = 0;
+ }
+ }
+ }
+ }
+
+ if (inexact_style == human_round_to_nearest
+ ? 5 < tenths + (0 < rounding + (amt & 1))
+ : inexact_style == human_ceiling && 0 < tenths + rounding)
+ {
+ amt++;
+
+ if ((opts & human_autoscale)
+ && amt == base && exponent < exponent_max)
+ {
+ exponent++;
+ if (! (opts & human_suppress_point_zero))
+ {
+ *--p = '0';
+ p -= decimal_pointlen;
+ memcpy (p, decimal_point, decimal_pointlen);
+ }
+ amt = 1;
+ }
+ }
+
+ integerlim = p;
+
+ do
+ {
+ int digit = amt % 10;
+ *--p = digit + '0';
+ }
+ while ((amt /= 10) != 0);
+ }
+
+ do_grouping:
+ if (opts & human_group_digits)
+ p = group_number (p, integerlim - p, grouping, thousands_sep);
+
+ if (opts & human_SI)
+ {
+ if (exponent < 0)
+ {
+ uintmax_t power;
+ exponent = 0;
+ for (power = 1; power < to_block_size; power *= base)
+ if (++exponent == exponent_max)
+ break;
+ }
+
+ if (exponent)
+ *psuffix++ = (! (opts & human_base_1024) && exponent == 1
+ ? 'k'
+ : power_letter[exponent]);
+
+ if (opts & human_B)
+ {
+ if ((opts & human_base_1024) && exponent)
+ *psuffix++ = 'i';
+ *psuffix++ = 'B';
+ }
+ }
+
+ *psuffix = '\0';
+
+ return p;
+}
+
+
+/* The default block size used for output. This number may change in
+ the future as disks get larger. */
+#ifndef DEFAULT_BLOCK_SIZE
+# define DEFAULT_BLOCK_SIZE 1024
+#endif
+
+static char const *const block_size_args[] = { "human-readable", "si", 0 };
+static int const block_size_opts[] =
+ {
+ human_autoscale + human_SI + human_base_1024,
+ human_autoscale + human_SI
+ };
+
+static uintmax_t
+default_block_size (void)
+{
+ return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE;
+}
+
+static strtol_error
+humblock (char const *spec, uintmax_t *block_size, int *options)
+{
+ int i;
+ int opts = 0;
+
+ if (! spec
+ && ! (spec = getenv ("BLOCK_SIZE"))
+ && ! (spec = getenv ("BLOCKSIZE")))
+ *block_size = default_block_size ();
+ else
+ {
+ if (*spec == '\'')
+ {
+ opts |= human_group_digits;
+ spec++;
+ }
+
+ if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
+ {
+ opts |= block_size_opts[i];
+ *block_size = 1;
+ }
+ else
+ {
+ char *ptr;
+ strtol_error e = xstrtoumax (spec, &ptr, 0, block_size,
+ "eEgGkKmMpPtTyYzZ0");
+ if (e != LONGINT_OK)
+ return e;
+ for (; ! ('0' <= *spec && *spec <= '9'); spec++)
+ if (spec == ptr)
+ {
+ opts |= human_SI;
+ if (ptr[-1] == 'B')
+ opts |= human_B;
+ if (ptr[-1] != 'B' || ptr[-2] == 'i')
+ opts |= human_base_1024;
+ break;
+ }
+ }
+ }
+
+ *options = opts;
+ return LONGINT_OK;
+}
+
+int
+human_options (char const *spec, bool report_errors, uintmax_t *block_size)
+{
+ int opts;
+ strtol_error e = humblock (spec, block_size, &opts);
+ if (*block_size == 0)
+ {
+ *block_size = default_block_size ();
+ e = LONGINT_INVALID;
+ }
+ if (e != LONGINT_OK && report_errors)
+ STRTOL_FATAL_ERROR (spec, _("block size"), e);
+ return opts;
+}
diff --git a/contrib/gnu-sort/lib/human.h b/contrib/gnu-sort/lib/human.h
new file mode 100644
index 0000000..b67ba4e
--- /dev/null
+++ b/contrib/gnu-sort/lib/human.h
@@ -0,0 +1,88 @@
+/* human.h -- print human readable file size
+
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert and Larry McVoy. */
+
+#ifndef HUMAN_H_
+# define HUMAN_H_ 1
+
+# if HAVE_CONFIG_H
+# include <config.h>
+# endif
+
+# include <limits.h>
+# include <stdbool.h>
+
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+# if HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* A conservative bound on the maximum length of a human-readable string.
+ The output can be the square of the largest uintmax_t, so double
+ its size before converting to a bound.
+ 302 / 1000 is ceil (log10 (2.0)). Add 1 for integer division truncation.
+ Also, the output can have a thousands separator between every digit,
+ so multiply by MB_LEN_MAX + 1 and then subtract MB_LEN_MAX.
+ Finally, append 3, the maximum length of a suffix. */
+# define LONGEST_HUMAN_READABLE \
+ ((2 * sizeof (uintmax_t) * CHAR_BIT * 302 / 1000 + 1) * (MB_LEN_MAX + 1) \
+ - MB_LEN_MAX + 3)
+
+/* Options for human_readable. */
+enum
+{
+ /* Unless otherwise specified these options may be ORed together. */
+
+ /* The following three options are mutually exclusive. */
+ /* Round to plus infinity (default). */
+ human_ceiling = 0,
+ /* Round to nearest, ties to even. */
+ human_round_to_nearest = 1,
+ /* Round to minus infinity. */
+ human_floor = 2,
+
+ /* Group digits together, e.g. `1,000,000'. This uses the
+ locale-defined grouping; the traditional C locale does not group,
+ so this has effect only if some other locale is in use. */
+ human_group_digits = 4,
+
+ /* When autoscaling, suppress ".0" at end. */
+ human_suppress_point_zero = 8,
+
+ /* Scale output and use SI-style units, ignoring the output block size. */
+ human_autoscale = 16,
+
+ /* Prefer base 1024 to base 1000. */
+ human_base_1024 = 32,
+
+ /* Append SI prefix, e.g. "k" or "M". */
+ human_SI = 64,
+
+ /* Append "B" (if base 1000) or "iB" (if base 1024) to SI prefix. */
+ human_B = 128
+};
+
+char *human_readable (uintmax_t, char *, int, uintmax_t, uintmax_t);
+
+int human_options (char const *, bool, uintmax_t *);
+
+#endif /* HUMAN_H_ */
diff --git a/contrib/gnu-sort/lib/inttostr.c b/contrib/gnu-sort/lib/inttostr.c
new file mode 100644
index 0000000..78a48af
--- /dev/null
+++ b/contrib/gnu-sort/lib/inttostr.c
@@ -0,0 +1,49 @@
+/* inttostr.c -- convert integers to printable strings
+
+ Copyright (C) 2001 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert */
+
+#include "inttostr.h"
+
+/* Convert I to a printable string in BUF, which must be at least
+ INT_BUFSIZE_BOUND (INTTYPE) bytes long. Return the address of the
+ printable string, which need not start at BUF. */
+
+char *
+inttostr (inttype i, char *buf)
+{
+ char *p = buf + INT_STRLEN_BOUND (inttype);
+ *p = 0;
+
+ if (i < 0)
+ {
+ do
+ *--p = '0' - i % 10;
+ while ((i /= 10) != 0);
+
+ *--p = '-';
+ }
+ else
+ {
+ do
+ *--p = '0' + i % 10;
+ while ((i /= 10) != 0);
+ }
+
+ return p;
+}
diff --git a/contrib/gnu-sort/lib/inttostr.h b/contrib/gnu-sort/lib/inttostr.h
new file mode 100644
index 0000000..6f2416b
--- /dev/null
+++ b/contrib/gnu-sort/lib/inttostr.h
@@ -0,0 +1,47 @@
+/* inttostr.h -- convert integers to printable strings
+
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include <limits.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+/* Upper bound on the string length of an integer converted to string.
+ 302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit;
+ add 1 for integer division truncation; add 1 more for a minus sign. */
+#define INT_STRLEN_BOUND(t) ((sizeof (t) * CHAR_BIT - 1) * 302 / 1000 + 2)
+
+#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
+
+char *offtostr (off_t, char *);
+char *imaxtostr (intmax_t, char *);
+char *umaxtostr (uintmax_t, char *);
diff --git a/contrib/gnu-sort/lib/long-options.c b/contrib/gnu-sort/lib/long-options.c
new file mode 100644
index 0000000..1c4e74a
--- /dev/null
+++ b/contrib/gnu-sort/lib/long-options.c
@@ -0,0 +1,91 @@
+/* Utility to accept --help and --version options as unobtrusively as possible.
+
+ Copyright (C) 1993, 1994, 1998, 1999, 2000, 2002, 2003, 2004 Free
+ Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Jim Meyering. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification. */
+#include "long-options.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include "version-etc.h"
+
+static struct option const long_options[] =
+{
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'v'},
+ {0, 0, 0, 0}
+};
+
+/* Process long options --help and --version, but only if argc == 2.
+ Be careful not to gobble up `--'. */
+
+void
+parse_long_options (int argc,
+ char **argv,
+ const char *command_name,
+ const char *package,
+ const char *version,
+ void (*usage_func) (int),
+ /* const char *author1, ...*/ ...)
+{
+ int c;
+ int saved_opterr;
+
+ saved_opterr = opterr;
+
+ /* Don't print an error message for unrecognized options. */
+ opterr = 0;
+
+ if (argc == 2
+ && (c = getopt_long (argc, argv, "+", long_options, NULL)) != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ (*usage_func) (EXIT_SUCCESS);
+
+ case 'v':
+ {
+ va_list authors;
+ va_start (authors, usage_func);
+ version_etc_va (stdout, command_name, package, version, authors);
+ exit (0);
+ }
+
+ default:
+ /* Don't process any other long-named options. */
+ break;
+ }
+ }
+
+ /* Restore previous value. */
+ opterr = saved_opterr;
+
+ /* Reset this to zero so that getopt internals get initialized from
+ the probably-new parameters when/if getopt is called later. */
+ optind = 0;
+}
diff --git a/contrib/gnu-sort/lib/long-options.h b/contrib/gnu-sort/lib/long-options.h
new file mode 100644
index 0000000..50f0c34
--- /dev/null
+++ b/contrib/gnu-sort/lib/long-options.h
@@ -0,0 +1,26 @@
+/* long-options.h -- declaration for --help- and --version-handling function.
+ Copyright (C) 1993, 1994, 1998, 1999, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Jim Meyering. */
+
+void parse_long_options (int _argc,
+ char **_argv,
+ const char *_command_name,
+ const char *_package,
+ const char *_version,
+ void (*_usage) (int),
+ /* const char *author1, ...*/ ...);
diff --git a/contrib/gnu-sort/lib/memcoll.c b/contrib/gnu-sort/lib/memcoll.c
new file mode 100644
index 0000000..e777e6a
--- /dev/null
+++ b/contrib/gnu-sort/lib/memcoll.c
@@ -0,0 +1,85 @@
+/* Locale-specific memory comparison.
+ Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Contributed by Paul Eggert <eggert@twinsun.com>. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "memcoll.h"
+
+#include <errno.h>
+#include <string.h>
+
+/* Compare S1 (with length S1LEN) and S2 (with length S2LEN) according
+ to the LC_COLLATE locale. S1 and S2 do not overlap, and are not
+ adjacent. Perhaps temporarily modify the bytes after S1 and S2,
+ but restore their original contents before returning. Set errno to an
+ error number if there is an error, and to zero otherwise. */
+int
+memcoll (char *s1, size_t s1len, char *s2, size_t s2len)
+{
+ int diff;
+
+#if HAVE_STRCOLL
+
+ char n1 = s1[s1len];
+ char n2 = s2[s2len];
+
+ s1[s1len++] = '\0';
+ s2[s2len++] = '\0';
+
+ while (! (errno = 0, (diff = strcoll (s1, s2)) || errno))
+ {
+ /* strcoll found no difference, but perhaps it was fooled by NUL
+ characters in the data. Work around this problem by advancing
+ past the NUL chars. */
+ size_t size1 = strlen (s1) + 1;
+ size_t size2 = strlen (s2) + 1;
+ s1 += size1;
+ s2 += size2;
+ s1len -= size1;
+ s2len -= size2;
+
+ if (s1len == 0)
+ {
+ if (s2len != 0)
+ diff = -1;
+ break;
+ }
+ else if (s2len == 0)
+ {
+ diff = 1;
+ break;
+ }
+ }
+
+ s1[s1len - 1] = n1;
+ s2[s2len - 1] = n2;
+
+#else
+
+ diff = memcmp (s1, s2, s1len < s2len ? s1len : s2len);
+ if (! diff)
+ diff = s1len < s2len ? -1 : s1len != s2len;
+ errno = 0;
+
+#endif
+
+ return diff;
+}
diff --git a/contrib/gnu-sort/lib/memcoll.h b/contrib/gnu-sort/lib/memcoll.h
new file mode 100644
index 0000000..66b2ecb
--- /dev/null
+++ b/contrib/gnu-sort/lib/memcoll.h
@@ -0,0 +1,28 @@
+/* Locale-specific memory comparison.
+
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Contributed by Paul Eggert <eggert@twinsun.com>. */
+
+#ifndef MEMCOLL_H_
+# define MEMCOLL_H_ 1
+
+# include <stddef.h>
+
+int memcoll (char *, size_t, char *, size_t);
+
+#endif /* MEMCOLL_H_ */
diff --git a/contrib/gnu-sort/lib/pathmax.h b/contrib/gnu-sort/lib/pathmax.h
new file mode 100644
index 0000000..bdd756e
--- /dev/null
+++ b/contrib/gnu-sort/lib/pathmax.h
@@ -0,0 +1,54 @@
+/* Define PATH_MAX somehow. Requires sys/types.h.
+ Copyright (C) 1992, 1999, 2001, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _PATHMAX_H
+# define _PATHMAX_H
+
+# if HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
+ PATH_MAX but might cause redefinition warnings when sys/param.h is
+ later included (as on MORE/BSD 4.3). */
+# if defined _POSIX_VERSION || !defined __GNUC__
+# include <limits.h>
+# endif
+
+# ifndef _POSIX_PATH_MAX
+# define _POSIX_PATH_MAX 255
+# endif
+
+# if !defined PATH_MAX && defined _PC_PATH_MAX
+# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 \
+ : pathconf ("/", _PC_PATH_MAX))
+# endif
+
+/* Don't include sys/param.h if it already has been. */
+# if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN
+# include <sys/param.h>
+# endif
+
+# if !defined PATH_MAX && defined MAXPATHLEN
+# define PATH_MAX MAXPATHLEN
+# endif
+
+# ifndef PATH_MAX
+# define PATH_MAX _POSIX_PATH_MAX
+# endif
+
+#endif /* _PATHMAX_H */
diff --git a/contrib/gnu-sort/lib/physmem.c b/contrib/gnu-sort/lib/physmem.c
new file mode 100644
index 0000000..dc67b57
--- /dev/null
+++ b/contrib/gnu-sort/lib/physmem.c
@@ -0,0 +1,307 @@
+/* Calculate the size of physical memory.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "physmem.h"
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_SYS_PSTAT_H
+# include <sys/pstat.h>
+#endif
+
+#if HAVE_SYS_SYSMP_H
+# include <sys/sysmp.h>
+#endif
+
+#if HAVE_SYS_SYSINFO_H && HAVE_MACHINE_HAL_SYSINFO_H
+# include <sys/sysinfo.h>
+# include <machine/hal_sysinfo.h>
+#endif
+
+#if HAVE_SYS_TABLE_H
+# include <sys/table.h>
+#endif
+
+#include <sys/types.h>
+
+#if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+#if HAVE_SYS_SYSCTL_H
+# include <sys/sysctl.h>
+#endif
+
+#if HAVE_SYS_SYSTEMCFG_H
+# include <sys/systemcfg.h>
+#endif
+
+#ifdef _WIN32
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+/* MEMORYSTATUSEX is missing from older windows headers, so define
+ a local replacement. */
+typedef struct
+{
+ DWORD dwLength;
+ DWORD dwMemoryLoad;
+ DWORDLONG ullTotalPhys;
+ DWORDLONG ullAvailPhys;
+ DWORDLONG ullTotalPageFile;
+ DWORDLONG ullAvailPageFile;
+ DWORDLONG ullTotalVirtual;
+ DWORDLONG ullAvailVirtual;
+ DWORDLONG ullAvailExtendedVirtual;
+} lMEMORYSTATUSEX;
+typedef WINBOOL (WINAPI *PFN_MS_EX) (lMEMORYSTATUSEX*);
+#endif
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+/* Return the total amount of physical memory. */
+double
+physmem_total (void)
+{
+#if defined _SC_PHYS_PAGES && defined _SC_PAGESIZE
+ { /* This works on linux-gnu, solaris2 and cygwin. */
+ double pages = sysconf (_SC_PHYS_PAGES);
+ double pagesize = sysconf (_SC_PAGESIZE);
+ if (0 <= pages && 0 <= pagesize)
+ return pages * pagesize;
+ }
+#endif
+
+#if HAVE_PSTAT_GETSTATIC
+ { /* This works on hpux11. */
+ struct pst_static pss;
+ if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0))
+ {
+ double pages = pss.physical_memory;
+ double pagesize = pss.page_size;
+ if (0 <= pages && 0 <= pagesize)
+ return pages * pagesize;
+ }
+ }
+#endif
+
+#if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE
+ { /* This works on irix6. */
+ struct rminfo realmem;
+ if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0)
+ {
+ double pagesize = sysconf (_SC_PAGESIZE);
+ double pages = realmem.physmem;
+ if (0 <= pages && 0 <= pagesize)
+ return pages * pagesize;
+ }
+ }
+#endif
+
+#if HAVE_GETSYSINFO && defined GSI_PHYSMEM
+ { /* This works on Tru64 UNIX V4/5. */
+ int physmem;
+
+ if (getsysinfo (GSI_PHYSMEM, (caddr_t) &physmem, sizeof (physmem),
+ NULL, NULL, NULL) == 1)
+ {
+ double kbytes = physmem;
+
+ if (0 <= kbytes)
+ return kbytes * 1024.0;
+ }
+ }
+#endif
+
+#if HAVE_SYSCTL && defined HW_PHYSMEM
+ { /* This works on *bsd and darwin. */
+ unsigned int physmem;
+ size_t len = sizeof physmem;
+ static int mib[2] = { CTL_HW, HW_PHYSMEM };
+
+ if (sysctl (mib, ARRAY_SIZE (mib), &physmem, &len, NULL, 0) == 0
+ && len == sizeof (physmem))
+ return (double) physmem;
+ }
+#endif
+
+#if HAVE__SYSTEM_CONFIGURATION
+ /* This works on AIX. */
+ return _system_configuration.physmem;
+#endif
+
+#if defined _WIN32
+ { /* this works on windows */
+ PFN_MS_EX pfnex;
+ HMODULE h = GetModuleHandle ("kernel32.dll");
+
+ if (!h)
+ return 0.0;
+
+ /* Use GlobalMemoryStatusEx if available. */
+ if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx")))
+ {
+ lMEMORYSTATUSEX lms_ex;
+ lms_ex.dwLength = sizeof lms_ex;
+ if (!pfnex (&lms_ex))
+ return 0.0;
+ return (double) lms_ex.ullTotalPhys;
+ }
+
+ /* Fall back to GlobalMemoryStatus which is always available.
+ but returns wrong results for physical memory > 4GB. */
+ else
+ {
+ MEMORYSTATUS ms;
+ GlobalMemoryStatus (&ms);
+ return (double) ms.dwTotalPhys;
+ }
+ }
+#endif
+
+ /* Guess 64 MB. It's probably an older host, so guess small. */
+ return 64 * 1024 * 1024;
+}
+
+/* Return the amount of physical memory available. */
+double
+physmem_available (void)
+{
+#if defined _SC_AVPHYS_PAGES && defined _SC_PAGESIZE
+ { /* This works on linux-gnu, solaris2 and cygwin. */
+ double pages = sysconf (_SC_AVPHYS_PAGES);
+ double pagesize = sysconf (_SC_PAGESIZE);
+ if (0 <= pages && 0 <= pagesize)
+ return pages * pagesize;
+ }
+#endif
+
+#if HAVE_PSTAT_GETSTATIC && HAVE_PSTAT_GETDYNAMIC
+ { /* This works on hpux11. */
+ struct pst_static pss;
+ struct pst_dynamic psd;
+ if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0)
+ && 0 <= pstat_getdynamic (&psd, sizeof psd, 1, 0))
+ {
+ double pages = psd.psd_free;
+ double pagesize = pss.page_size;
+ if (0 <= pages && 0 <= pagesize)
+ return pages * pagesize;
+ }
+ }
+#endif
+
+#if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE
+ { /* This works on irix6. */
+ struct rminfo realmem;
+ if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0)
+ {
+ double pagesize = sysconf (_SC_PAGESIZE);
+ double pages = realmem.availrmem;
+ if (0 <= pages && 0 <= pagesize)
+ return pages * pagesize;
+ }
+ }
+#endif
+
+#if HAVE_TABLE && defined TBL_VMSTATS
+ { /* This works on Tru64 UNIX V4/5. */
+ struct tbl_vmstats vmstats;
+
+ if (table (TBL_VMSTATS, 0, &vmstats, 1, sizeof (vmstats)) == 1)
+ {
+ double pages = vmstats.free_count;
+ double pagesize = vmstats.pagesize;
+
+ if (0 <= pages && 0 <= pagesize)
+ return pages * pagesize;
+ }
+ }
+#endif
+
+#if HAVE_SYSCTL && defined HW_USERMEM
+ { /* This works on *bsd and darwin. */
+ unsigned int usermem;
+ size_t len = sizeof usermem;
+ static int mib[2] = { CTL_HW, HW_USERMEM };
+
+ if (sysctl (mib, ARRAY_SIZE (mib), &usermem, &len, NULL, 0) == 0
+ && len == sizeof (usermem))
+ return (double) usermem;
+ }
+#endif
+
+#if defined _WIN32
+ { /* this works on windows */
+ PFN_MS_EX pfnex;
+ HMODULE h = GetModuleHandle ("kernel32.dll");
+
+ if (!h)
+ return 0.0;
+
+ /* Use GlobalMemoryStatusEx if available. */
+ if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx")))
+ {
+ lMEMORYSTATUSEX lms_ex;
+ lms_ex.dwLength = sizeof lms_ex;
+ if (!pfnex (&lms_ex))
+ return 0.0;
+ return (double) lms_ex.ullAvailPhys;
+ }
+
+ /* Fall back to GlobalMemoryStatus which is always available.
+ but returns wrong results for physical memory > 4GB */
+ else
+ {
+ MEMORYSTATUS ms;
+ GlobalMemoryStatus (&ms);
+ return (double) ms.dwAvailPhys;
+ }
+ }
+#endif
+
+ /* Guess 25% of physical memory. */
+ return physmem_total () / 4;
+}
+
+
+#if DEBUG
+
+# include <stdio.h>
+# include <stdlib.h>
+
+int
+main (void)
+{
+ printf ("%12.f %12.f\n", physmem_total (), physmem_available ());
+ exit (0);
+}
+
+#endif /* DEBUG */
+
+/*
+Local Variables:
+compile-command: "gcc -DDEBUG -DHAVE_CONFIG_H -I.. -g -O -Wall -W physmem.c"
+End:
+*/
diff --git a/contrib/gnu-sort/lib/physmem.h b/contrib/gnu-sort/lib/physmem.h
new file mode 100644
index 0000000..67f880c
--- /dev/null
+++ b/contrib/gnu-sort/lib/physmem.h
@@ -0,0 +1,27 @@
+/* Calculate the size of physical memory.
+
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#ifndef PHYSMEM_H_
+# define PHYSMEM_H_ 1
+
+double physmem_total (void);
+double physmem_available (void);
+
+#endif /* PHYSMEM_H_ */
diff --git a/contrib/gnu-sort/lib/posixver.c b/contrib/gnu-sort/lib/posixver.c
new file mode 100644
index 0000000..754d7ac
--- /dev/null
+++ b/contrib/gnu-sort/lib/posixver.c
@@ -0,0 +1,59 @@
+/* Which POSIX version to conform to, for utilities.
+
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "posixver.h"
+
+#include <limits.h>
+#include <stdlib.h>
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifndef _POSIX2_VERSION
+# define _POSIX2_VERSION 0
+#endif
+
+#ifndef DEFAULT_POSIX2_VERSION
+# define DEFAULT_POSIX2_VERSION _POSIX2_VERSION
+#endif
+
+/* The POSIX version that utilities should conform to. The default is
+ specified by the system. */
+
+int
+posix2_version (void)
+{
+ long int v = DEFAULT_POSIX2_VERSION;
+ char const *s = getenv ("_POSIX2_VERSION");
+
+ if (s && *s)
+ {
+ char *e;
+ long int i = strtol (s, &e, 10);
+ if (! *e)
+ v = i;
+ }
+
+ return v < INT_MIN ? INT_MIN : v < INT_MAX ? v : INT_MAX;
+}
diff --git a/contrib/gnu-sort/lib/posixver.h b/contrib/gnu-sort/lib/posixver.h
new file mode 100644
index 0000000..b64f6a2
--- /dev/null
+++ b/contrib/gnu-sort/lib/posixver.h
@@ -0,0 +1 @@
+int posix2_version (void);
diff --git a/contrib/gnu-sort/lib/quote.c b/contrib/gnu-sort/lib/quote.c
new file mode 100644
index 0000000..5f11d83
--- /dev/null
+++ b/contrib/gnu-sort/lib/quote.c
@@ -0,0 +1,41 @@
+/* quote.c - quote arguments for output
+ Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert <eggert@twinsun.com> */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "quotearg.h"
+#include "quote.h"
+
+/* Return an unambiguous printable representation of NAME,
+ allocated in slot N, suitable for diagnostics. */
+char const *
+quote_n (int n, char const *name)
+{
+ return quotearg_n_style (n, locale_quoting_style, name);
+}
+
+/* Return an unambiguous printable representation of NAME,
+ suitable for diagnostics. */
+char const *
+quote (char const *name)
+{
+ return quote_n (0, name);
+}
diff --git a/contrib/gnu-sort/lib/quote.h b/contrib/gnu-sort/lib/quote.h
new file mode 100644
index 0000000..682f9d1
--- /dev/null
+++ b/contrib/gnu-sort/lib/quote.h
@@ -0,0 +1,22 @@
+/* quote.h - prototypes for quote.c
+
+ Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+char const *quote_n (int n, char const *name);
+char const *quote (char const *name);
diff --git a/contrib/gnu-sort/lib/quotearg.c b/contrib/gnu-sort/lib/quotearg.c
new file mode 100644
index 0000000..64fa676
--- /dev/null
+++ b/contrib/gnu-sort/lib/quotearg.c
@@ -0,0 +1,673 @@
+/* quotearg.c - quote arguments for output
+
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert <eggert@twinsun.com> */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "quotearg.h"
+
+#include "xalloc.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+#if HAVE_WCHAR_H
+
+/* BSD/OS 4.1 wchar.h requires FILE and struct tm to be declared. */
+# include <stdio.h>
+# include <time.h>
+
+# include <wchar.h>
+#endif
+
+#if !HAVE_MBRTOWC
+/* Disable multibyte processing entirely. Since MB_CUR_MAX is 1, the
+ other macros are defined only for documentation and to satisfy C
+ syntax. */
+# undef MB_CUR_MAX
+# define MB_CUR_MAX 1
+# define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0)
+# define iswprint(wc) isprint ((unsigned char) (wc))
+# undef HAVE_MBSINIT
+#endif
+
+#if !defined mbsinit && !HAVE_MBSINIT
+# define mbsinit(ps) 1
+#endif
+
+#ifndef iswprint
+# if HAVE_WCTYPE_H
+# include <wctype.h>
+# endif
+# if !defined iswprint && !HAVE_ISWPRINT
+# define iswprint(wc) 1
+# endif
+#endif
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+
+#define INT_BITS (sizeof (int) * CHAR_BIT)
+
+struct quoting_options
+{
+ /* Basic quoting style. */
+ enum quoting_style style;
+
+ /* Quote the characters indicated by this bit vector even if the
+ quoting style would not normally require them to be quoted. */
+ int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
+};
+
+/* Names of quoting styles. */
+char const *const quoting_style_args[] =
+{
+ "literal",
+ "shell",
+ "shell-always",
+ "c",
+ "escape",
+ "locale",
+ "clocale",
+ 0
+};
+
+/* Correspondences to quoting style names. */
+enum quoting_style const quoting_style_vals[] =
+{
+ literal_quoting_style,
+ shell_quoting_style,
+ shell_always_quoting_style,
+ c_quoting_style,
+ escape_quoting_style,
+ locale_quoting_style,
+ clocale_quoting_style
+};
+
+/* The default quoting options. */
+static struct quoting_options default_quoting_options;
+
+/* Allocate a new set of quoting options, with contents initially identical
+ to O if O is not null, or to the default if O is null.
+ It is the caller's responsibility to free the result. */
+struct quoting_options *
+clone_quoting_options (struct quoting_options *o)
+{
+ int e = errno;
+ struct quoting_options *p = xmalloc (sizeof *p);
+ *p = *(o ? o : &default_quoting_options);
+ errno = e;
+ return p;
+}
+
+/* Get the value of O's quoting style. If O is null, use the default. */
+enum quoting_style
+get_quoting_style (struct quoting_options *o)
+{
+ return (o ? o : &default_quoting_options)->style;
+}
+
+/* In O (or in the default if O is null),
+ set the value of the quoting style to S. */
+void
+set_quoting_style (struct quoting_options *o, enum quoting_style s)
+{
+ (o ? o : &default_quoting_options)->style = s;
+}
+
+/* In O (or in the default if O is null),
+ set the value of the quoting options for character C to I.
+ Return the old value. Currently, the only values defined for I are
+ 0 (the default) and 1 (which means to quote the character even if
+ it would not otherwise be quoted). */
+int
+set_char_quoting (struct quoting_options *o, char c, int i)
+{
+ unsigned char uc = c;
+ int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
+ int shift = uc % INT_BITS;
+ int r = (*p >> shift) & 1;
+ *p ^= ((i & 1) ^ r) << shift;
+ return r;
+}
+
+/* MSGID approximates a quotation mark. Return its translation if it
+ has one; otherwise, return either it or "\"", depending on S. */
+static char const *
+gettext_quote (char const *msgid, enum quoting_style s)
+{
+ char const *translation = _(msgid);
+ if (translation == msgid && s == clocale_quoting_style)
+ translation = "\"";
+ return translation;
+}
+
+/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
+ argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
+ non-quoting-style part of O to control quoting.
+ Terminate the output with a null character, and return the written
+ size of the output, not counting the terminating null.
+ If BUFFERSIZE is too small to store the output string, return the
+ value that would have been returned had BUFFERSIZE been large enough.
+ If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
+
+ This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
+ ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
+ style specified by O, and O may not be null. */
+
+static size_t
+quotearg_buffer_restyled (char *buffer, size_t buffersize,
+ char const *arg, size_t argsize,
+ enum quoting_style quoting_style,
+ struct quoting_options const *o)
+{
+ size_t i;
+ size_t len = 0;
+ char const *quote_string = 0;
+ size_t quote_string_len = 0;
+ bool backslash_escapes = false;
+ bool unibyte_locale = MB_CUR_MAX == 1;
+
+#define STORE(c) \
+ do \
+ { \
+ if (len < buffersize) \
+ buffer[len] = (c); \
+ len++; \
+ } \
+ while (0)
+
+ switch (quoting_style)
+ {
+ case c_quoting_style:
+ STORE ('"');
+ backslash_escapes = true;
+ quote_string = "\"";
+ quote_string_len = 1;
+ break;
+
+ case escape_quoting_style:
+ backslash_escapes = true;
+ break;
+
+ case locale_quoting_style:
+ case clocale_quoting_style:
+ {
+ /* Get translations for open and closing quotation marks.
+
+ The message catalog should translate "`" to a left
+ quotation mark suitable for the locale, and similarly for
+ "'". If the catalog has no translation,
+ locale_quoting_style quotes `like this', and
+ clocale_quoting_style quotes "like this".
+
+ For example, an American English Unicode locale should
+ translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and
+ should translate "'" to U+201D (RIGHT DOUBLE QUOTATION
+ MARK). A British English Unicode locale should instead
+ translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and
+ U+2019 (RIGHT SINGLE QUOTATION MARK), respectively. */
+
+ char const *left = gettext_quote (N_("`"), quoting_style);
+ char const *right = gettext_quote (N_("'"), quoting_style);
+ for (quote_string = left; *quote_string; quote_string++)
+ STORE (*quote_string);
+ backslash_escapes = true;
+ quote_string = right;
+ quote_string_len = strlen (quote_string);
+ }
+ break;
+
+ case shell_always_quoting_style:
+ STORE ('\'');
+ quote_string = "'";
+ quote_string_len = 1;
+ break;
+
+ default:
+ break;
+ }
+
+ for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++)
+ {
+ unsigned char c;
+ unsigned char esc;
+
+ if (backslash_escapes
+ && quote_string_len
+ && i + quote_string_len <= argsize
+ && memcmp (arg + i, quote_string, quote_string_len) == 0)
+ STORE ('\\');
+
+ c = arg[i];
+ switch (c)
+ {
+ case '\0':
+ if (backslash_escapes)
+ {
+ STORE ('\\');
+ STORE ('0');
+ STORE ('0');
+ c = '0';
+ }
+ break;
+
+ case '?':
+ switch (quoting_style)
+ {
+ case shell_quoting_style:
+ goto use_shell_always_quoting_style;
+
+ case c_quoting_style:
+ if (i + 2 < argsize && arg[i + 1] == '?')
+ switch (arg[i + 2])
+ {
+ case '!': case '\'':
+ case '(': case ')': case '-': case '/':
+ case '<': case '=': case '>':
+ /* Escape the second '?' in what would otherwise be
+ a trigraph. */
+ c = arg[i + 2];
+ i += 2;
+ STORE ('?');
+ STORE ('\\');
+ STORE ('?');
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case '\a': esc = 'a'; goto c_escape;
+ case '\b': esc = 'b'; goto c_escape;
+ case '\f': esc = 'f'; goto c_escape;
+ case '\n': esc = 'n'; goto c_and_shell_escape;
+ case '\r': esc = 'r'; goto c_and_shell_escape;
+ case '\t': esc = 't'; goto c_and_shell_escape;
+ case '\v': esc = 'v'; goto c_escape;
+ case '\\': esc = c; goto c_and_shell_escape;
+
+ c_and_shell_escape:
+ if (quoting_style == shell_quoting_style)
+ goto use_shell_always_quoting_style;
+ c_escape:
+ if (backslash_escapes)
+ {
+ c = esc;
+ goto store_escape;
+ }
+ break;
+
+ case '{': case '}': /* sometimes special if isolated */
+ if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
+ break;
+ /* Fall through. */
+ case '#': case '~':
+ if (i != 0)
+ break;
+ /* Fall through. */
+ case ' ':
+ case '!': /* special in bash */
+ case '"': case '$': case '&':
+ case '(': case ')': case '*': case ';':
+ case '<':
+ case '=': /* sometimes special in 0th or (with "set -k") later args */
+ case '>': case '[':
+ case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
+ case '`': case '|':
+ /* A shell special character. In theory, '$' and '`' could
+ be the first bytes of multibyte characters, which means
+ we should check them with mbrtowc, but in practice this
+ doesn't happen so it's not worth worrying about. */
+ if (quoting_style == shell_quoting_style)
+ goto use_shell_always_quoting_style;
+ break;
+
+ case '\'':
+ switch (quoting_style)
+ {
+ case shell_quoting_style:
+ goto use_shell_always_quoting_style;
+
+ case shell_always_quoting_style:
+ STORE ('\'');
+ STORE ('\\');
+ STORE ('\'');
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case '%': case '+': case ',': case '-': case '.': case '/':
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9': case ':':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+ case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+ case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
+ case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
+ case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+ case 'o': case 'p': case 'q': case 'r': case 's': case 't':
+ case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
+ /* These characters don't cause problems, no matter what the
+ quoting style is. They cannot start multibyte sequences. */
+ break;
+
+ default:
+ /* If we have a multibyte sequence, copy it until we reach
+ its end, find an error, or come back to the initial shift
+ state. For C-like styles, if the sequence has
+ unprintable characters, escape the whole sequence, since
+ we can't easily escape single characters within it. */
+ {
+ /* Length of multibyte sequence found so far. */
+ size_t m;
+
+ bool printable;
+
+ if (unibyte_locale)
+ {
+ m = 1;
+ printable = isprint (c) != 0;
+ }
+ else
+ {
+ mbstate_t mbstate;
+ memset (&mbstate, 0, sizeof mbstate);
+
+ m = 0;
+ printable = true;
+ if (argsize == SIZE_MAX)
+ argsize = strlen (arg);
+
+ do
+ {
+ wchar_t w;
+ size_t bytes = mbrtowc (&w, &arg[i + m],
+ argsize - (i + m), &mbstate);
+ if (bytes == 0)
+ break;
+ else if (bytes == (size_t) -1)
+ {
+ printable = false;
+ break;
+ }
+ else if (bytes == (size_t) -2)
+ {
+ printable = false;
+ while (i + m < argsize && arg[i + m])
+ m++;
+ break;
+ }
+ else
+ {
+ /* Work around a bug with older shells that "see" a '\'
+ that is really the 2nd byte of a multibyte character.
+ In practice the problem is limited to ASCII
+ chars >= '@' that are shell special chars. */
+ if ('[' == 0x5b && quoting_style == shell_quoting_style)
+ {
+ size_t j;
+ for (j = 1; j < bytes; j++)
+ switch (arg[i + m + j])
+ {
+ case '[': case '\\': case '^':
+ case '`': case '|':
+ goto use_shell_always_quoting_style;
+ }
+ }
+
+ if (! iswprint (w))
+ printable = false;
+ m += bytes;
+ }
+ }
+ while (! mbsinit (&mbstate));
+ }
+
+ if (1 < m || (backslash_escapes && ! printable))
+ {
+ /* Output a multibyte sequence, or an escaped
+ unprintable unibyte character. */
+ size_t ilim = i + m;
+
+ for (;;)
+ {
+ if (backslash_escapes && ! printable)
+ {
+ STORE ('\\');
+ STORE ('0' + (c >> 6));
+ STORE ('0' + ((c >> 3) & 7));
+ c = '0' + (c & 7);
+ }
+ if (ilim <= i + 1)
+ break;
+ STORE (c);
+ c = arg[++i];
+ }
+
+ goto store_c;
+ }
+ }
+ }
+
+ if (! (backslash_escapes
+ && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
+ goto store_c;
+
+ store_escape:
+ STORE ('\\');
+
+ store_c:
+ STORE (c);
+ }
+
+ if (i == 0 && quoting_style == shell_quoting_style)
+ goto use_shell_always_quoting_style;
+
+ if (quote_string)
+ for (; *quote_string; quote_string++)
+ STORE (*quote_string);
+
+ if (len < buffersize)
+ buffer[len] = '\0';
+ return len;
+
+ use_shell_always_quoting_style:
+ return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
+ shell_always_quoting_style, o);
+}
+
+/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
+ argument ARG (of size ARGSIZE), using O to control quoting.
+ If O is null, use the default.
+ Terminate the output with a null character, and return the written
+ size of the output, not counting the terminating null.
+ If BUFFERSIZE is too small to store the output string, return the
+ value that would have been returned had BUFFERSIZE been large enough.
+ If ARGSIZE is SIZE_MAX, use the string length of the argument for
+ ARGSIZE. */
+size_t
+quotearg_buffer (char *buffer, size_t buffersize,
+ char const *arg, size_t argsize,
+ struct quoting_options const *o)
+{
+ struct quoting_options const *p = o ? o : &default_quoting_options;
+ int e = errno;
+ size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
+ p->style, p);
+ errno = e;
+ return r;
+}
+
+/* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
+ allocated storage containing the quoted string. */
+char *
+quotearg_alloc (char const *arg, size_t argsize,
+ struct quoting_options const *o)
+{
+ int e = errno;
+ size_t bufsize = quotearg_buffer (0, 0, arg, argsize, o) + 1;
+ char *buf = xmalloc (bufsize);
+ quotearg_buffer (buf, bufsize, arg, argsize, o);
+ errno = e;
+ return buf;
+}
+
+/* Use storage slot N to return a quoted version of argument ARG.
+ ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
+ null-terminated string.
+ OPTIONS specifies the quoting options.
+ The returned value points to static storage that can be
+ reused by the next call to this function with the same value of N.
+ N must be nonnegative. N is deliberately declared with type "int"
+ to allow for future extensions (using negative values). */
+static char *
+quotearg_n_options (int n, char const *arg, size_t argsize,
+ struct quoting_options const *options)
+{
+ int e = errno;
+
+ /* Preallocate a slot 0 buffer, so that the caller can always quote
+ one small component of a "memory exhausted" message in slot 0. */
+ static char slot0[256];
+ static unsigned int nslots = 1;
+ unsigned int n0 = n;
+ struct slotvec
+ {
+ size_t size;
+ char *val;
+ };
+ static struct slotvec slotvec0 = {sizeof slot0, slot0};
+ static struct slotvec *slotvec = &slotvec0;
+
+ if (n < 0)
+ abort ();
+
+ if (nslots <= n0)
+ {
+ unsigned int n1 = n0 + 1;
+
+ if (xalloc_oversized (n1, sizeof *slotvec))
+ xalloc_die ();
+
+ if (slotvec == &slotvec0)
+ {
+ slotvec = xmalloc (sizeof *slotvec);
+ *slotvec = slotvec0;
+ }
+ slotvec = xrealloc (slotvec, n1 * sizeof *slotvec);
+ memset (slotvec + nslots, 0, (n1 - nslots) * sizeof *slotvec);
+ nslots = n1;
+ }
+
+ {
+ size_t size = slotvec[n].size;
+ char *val = slotvec[n].val;
+ size_t qsize = quotearg_buffer (val, size, arg, argsize, options);
+
+ if (size <= qsize)
+ {
+ slotvec[n].size = size = qsize + 1;
+ if (val != slot0)
+ free (val);
+ slotvec[n].val = val = xmalloc (size);
+ quotearg_buffer (val, size, arg, argsize, options);
+ }
+
+ errno = e;
+ return val;
+ }
+}
+
+char *
+quotearg_n (int n, char const *arg)
+{
+ return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
+}
+
+char *
+quotearg (char const *arg)
+{
+ return quotearg_n (0, arg);
+}
+
+/* Return quoting options for STYLE, with no extra quoting. */
+static struct quoting_options
+quoting_options_from_style (enum quoting_style style)
+{
+ struct quoting_options o;
+ o.style = style;
+ memset (o.quote_these_too, 0, sizeof o.quote_these_too);
+ return o;
+}
+
+char *
+quotearg_n_style (int n, enum quoting_style s, char const *arg)
+{
+ struct quoting_options const o = quoting_options_from_style (s);
+ return quotearg_n_options (n, arg, SIZE_MAX, &o);
+}
+
+char *
+quotearg_n_style_mem (int n, enum quoting_style s,
+ char const *arg, size_t argsize)
+{
+ struct quoting_options const o = quoting_options_from_style (s);
+ return quotearg_n_options (n, arg, argsize, &o);
+}
+
+char *
+quotearg_style (enum quoting_style s, char const *arg)
+{
+ return quotearg_n_style (0, s, arg);
+}
+
+char *
+quotearg_char (char const *arg, char ch)
+{
+ struct quoting_options options;
+ options = default_quoting_options;
+ set_char_quoting (&options, ch, 1);
+ return quotearg_n_options (0, arg, SIZE_MAX, &options);
+}
+
+char *
+quotearg_colon (char const *arg)
+{
+ return quotearg_char (arg, ':');
+}
diff --git a/contrib/gnu-sort/lib/quotearg.h b/contrib/gnu-sort/lib/quotearg.h
new file mode 100644
index 0000000..14dc316
--- /dev/null
+++ b/contrib/gnu-sort/lib/quotearg.h
@@ -0,0 +1,137 @@
+/* quotearg.h - quote arguments for output
+
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
+ Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert <eggert@twinsun.com> */
+
+#ifndef QUOTEARG_H_
+# define QUOTEARG_H_ 1
+
+# include <stddef.h>
+
+/* Basic quoting styles. */
+enum quoting_style
+ {
+ /* Output names as-is (ls --quoting-style=literal). */
+ literal_quoting_style,
+
+ /* Quote names for the shell if they contain shell metacharacters
+ or would cause ambiguous output (ls --quoting-style=shell). */
+ shell_quoting_style,
+
+ /* Quote names for the shell, even if they would normally not
+ require quoting (ls --quoting-style=shell-always). */
+ shell_always_quoting_style,
+
+ /* Quote names as for a C language string (ls --quoting-style=c). */
+ c_quoting_style,
+
+ /* Like c_quoting_style except omit the surrounding double-quote
+ characters (ls --quoting-style=escape). */
+ escape_quoting_style,
+
+ /* Like clocale_quoting_style, but quote `like this' instead of
+ "like this" in the default C locale (ls --quoting-style=locale). */
+ locale_quoting_style,
+
+ /* Like c_quoting_style except use quotation marks appropriate for
+ the locale (ls --quoting-style=clocale). */
+ clocale_quoting_style
+ };
+
+/* For now, --quoting-style=literal is the default, but this may change. */
+# ifndef DEFAULT_QUOTING_STYLE
+# define DEFAULT_QUOTING_STYLE literal_quoting_style
+# endif
+
+/* Names of quoting styles and their corresponding values. */
+extern char const *const quoting_style_args[];
+extern enum quoting_style const quoting_style_vals[];
+
+struct quoting_options;
+
+/* The functions listed below set and use a hidden variable
+ that contains the default quoting style options. */
+
+/* Allocate a new set of quoting options, with contents initially identical
+ to O if O is not null, or to the default if O is null.
+ It is the caller's responsibility to free the result. */
+struct quoting_options *clone_quoting_options (struct quoting_options *o);
+
+/* Get the value of O's quoting style. If O is null, use the default. */
+enum quoting_style get_quoting_style (struct quoting_options *o);
+
+/* In O (or in the default if O is null),
+ set the value of the quoting style to S. */
+void set_quoting_style (struct quoting_options *o, enum quoting_style s);
+
+/* In O (or in the default if O is null),
+ set the value of the quoting options for character C to I.
+ Return the old value. Currently, the only values defined for I are
+ 0 (the default) and 1 (which means to quote the character even if
+ it would not otherwise be quoted). */
+int set_char_quoting (struct quoting_options *o, char c, int i);
+
+/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
+ argument ARG (of size ARGSIZE), using O to control quoting.
+ If O is null, use the default.
+ Terminate the output with a null character, and return the written
+ size of the output, not counting the terminating null.
+ If BUFFERSIZE is too small to store the output string, return the
+ value that would have been returned had BUFFERSIZE been large enough.
+ If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
+size_t quotearg_buffer (char *buffer, size_t buffersize,
+ char const *arg, size_t argsize,
+ struct quoting_options const *o);
+
+/* Like quotearg_buffer, except return the result in a newly allocated
+ buffer. It is the caller's responsibility to free the result. */
+char *quotearg_alloc (char const *arg, size_t argsize,
+ struct quoting_options const *o);
+
+/* Use storage slot N to return a quoted version of the string ARG.
+ Use the default quoting options.
+ The returned value points to static storage that can be
+ reused by the next call to this function with the same value of N.
+ N must be nonnegative. */
+char *quotearg_n (int n, char const *arg);
+
+/* Equivalent to quotearg_n (0, ARG). */
+char *quotearg (char const *arg);
+
+/* Use style S and storage slot N to return a quoted version of the string ARG.
+ This is like quotearg_n (N, ARG), except that it uses S with no other
+ options to specify the quoting method. */
+char *quotearg_n_style (int n, enum quoting_style s, char const *arg);
+
+/* Use style S and storage slot N to return a quoted version of the
+ argument ARG of size ARGSIZE. This is like quotearg_n_style
+ (N, S, ARG), except it can quote null bytes. */
+char *quotearg_n_style_mem (int n, enum quoting_style s,
+ char const *arg, size_t argsize);
+
+/* Equivalent to quotearg_n_style (0, S, ARG). */
+char *quotearg_style (enum quoting_style s, char const *arg);
+
+/* Like quotearg (ARG), except also quote any instances of CH. */
+char *quotearg_char (char const *arg, char ch);
+
+/* Equivalent to quotearg_char (ARG, ':'). */
+char *quotearg_colon (char const *arg);
+
+#endif /* !QUOTEARG_H_ */
diff --git a/contrib/gnu-sort/lib/stat-macros.h b/contrib/gnu-sort/lib/stat-macros.h
new file mode 100644
index 0000000..facbabb
--- /dev/null
+++ b/contrib/gnu-sort/lib/stat-macros.h
@@ -0,0 +1,255 @@
+/* stat-related macros
+
+ Copyright (C) 1993, 1994, 2001, 2002, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert and Jim Meyering. */
+
+#ifndef STAT_MACROS_H
+# define STAT_MACROS_H 1
+
+# if ! defined S_ISREG && ! defined S_IFREG
+# error "you must include <sys/stat.h> before including this file"
+# endif
+
+# ifndef S_IFMT
+# define S_IFMT 0170000
+# endif
+
+# if STAT_MACROS_BROKEN
+# undef S_ISBLK
+# undef S_ISCHR
+# undef S_ISDIR
+# undef S_ISDOOR
+# undef S_ISFIFO
+# undef S_ISLNK
+# undef S_ISNAM
+# undef S_ISMPB
+# undef S_ISMPC
+# undef S_ISNWK
+# undef S_ISREG
+# undef S_ISSOCK
+# endif
+
+
+# ifndef S_ISBLK
+# ifdef S_IFBLK
+# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+# else
+# define S_ISBLK(m) 0
+# endif
+# endif
+
+# ifndef S_ISCHR
+# ifdef S_IFCHR
+# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+# else
+# define S_ISCHR(m) 0
+# endif
+# endif
+
+# ifndef S_ISDIR
+# ifdef S_IFDIR
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+# else
+# define S_ISDIR(m) 0
+# endif
+# endif
+
+# ifndef S_ISDOOR /* Solaris 2.5 and up */
+# ifdef S_IFDOOR
+# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
+# else
+# define S_ISDOOR(m) 0
+# endif
+# endif
+
+# ifndef S_ISFIFO
+# ifdef S_IFIFO
+# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+# else
+# define S_ISFIFO(m) 0
+# endif
+# endif
+
+# ifndef S_ISLNK
+# ifdef S_IFLNK
+# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+# else
+# define S_ISLNK(m) 0
+# endif
+# endif
+
+# ifndef S_ISMPB /* V7 */
+# ifdef S_IFMPB
+# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
+# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
+# else
+# define S_ISMPB(m) 0
+# define S_ISMPC(m) 0
+# endif
+# endif
+
+# ifndef S_ISNAM /* Xenix */
+# ifdef S_IFNAM
+# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM)
+# else
+# define S_ISNAM(m) 0
+# endif
+# endif
+
+# ifndef S_ISNWK /* HP/UX */
+# ifdef S_IFNWK
+# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
+# else
+# define S_ISNWK(m) 0
+# endif
+# endif
+
+# ifndef S_ISREG
+# ifdef S_IFREG
+# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+# else
+# define S_ISREG(m) 0
+# endif
+# endif
+
+# ifndef S_ISSOCK
+# ifdef S_IFSOCK
+# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+# else
+# define S_ISSOCK(m) 0
+# endif
+# endif
+
+
+# ifndef S_TYPEISMQ
+# define S_TYPEISMQ(p) 0
+# endif
+
+# ifndef S_TYPEISTMO
+# define S_TYPEISTMO(p) 0
+# endif
+
+
+# ifndef S_TYPEISSEM
+# ifdef S_INSEM
+# define S_TYPEISSEM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSEM)
+# else
+# define S_TYPEISSEM(p) 0
+# endif
+# endif
+
+# ifndef S_TYPEISSHM
+# ifdef S_INSHD
+# define S_TYPEISSHM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSHD)
+# else
+# define S_TYPEISSHM(p) 0
+# endif
+# endif
+
+/* contiguous */
+# ifndef S_ISCTG
+# define S_ISCTG(p) 0
+# endif
+
+/* Cray DMF (data migration facility): off line, with data */
+# ifndef S_ISOFD
+# define S_ISOFD(p) 0
+# endif
+
+/* Cray DMF (data migration facility): off line, with no data */
+# ifndef S_ISOFL
+# define S_ISOFL(p) 0
+# endif
+
+/* If any of the following are undefined,
+ define them to their de facto standard values. */
+# if !S_ISUID
+# define S_ISUID 04000
+# endif
+# if !S_ISGID
+# define S_ISGID 02000
+# endif
+
+/* S_ISVTX is a common extension to POSIX. */
+# ifndef S_ISVTX
+# define S_ISVTX 01000
+# endif
+
+# if !S_IRUSR && S_IREAD
+# define S_IRUSR S_IREAD
+# endif
+# if !S_IRUSR
+# define S_IRUSR 00400
+# endif
+# if !S_IRGRP
+# define S_IRGRP (S_IRUSR >> 3)
+# endif
+# if !S_IROTH
+# define S_IROTH (S_IRUSR >> 6)
+# endif
+
+# if !S_IWUSR && S_IWRITE
+# define S_IWUSR S_IWRITE
+# endif
+# if !S_IWUSR
+# define S_IWUSR 00200
+# endif
+# if !S_IWGRP
+# define S_IWGRP (S_IWUSR >> 3)
+# endif
+# if !S_IWOTH
+# define S_IWOTH (S_IWUSR >> 6)
+# endif
+
+# if !S_IXUSR && S_IEXEC
+# define S_IXUSR S_IEXEC
+# endif
+# if !S_IXUSR
+# define S_IXUSR 00100
+# endif
+# if !S_IXGRP
+# define S_IXGRP (S_IXUSR >> 3)
+# endif
+# if !S_IXOTH
+# define S_IXOTH (S_IXUSR >> 6)
+# endif
+
+# if !S_IRWXU
+# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
+# endif
+# if !S_IRWXG
+# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
+# endif
+# if !S_IRWXO
+# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
+# endif
+
+/* S_IXUGO is a common extension to POSIX. */
+# if !S_IXUGO
+# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
+# endif
+
+# ifndef S_IRWXUGO
+# define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO)
+# endif
+
+/* All the mode bits that can be affected by chmod. */
+# define CHMOD_MODE_BITS \
+ (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
+
+#endif /* STAT_MACROS_H */
diff --git a/contrib/gnu-sort/lib/stdio-safer.h b/contrib/gnu-sort/lib/stdio-safer.h
new file mode 100644
index 0000000..8a22f12
--- /dev/null
+++ b/contrib/gnu-sort/lib/stdio-safer.h
@@ -0,0 +1,23 @@
+/* Invoke stdio functions, but avoid some glitches.
+
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#include <stdio.h>
+
+FILE *fopen_safer (char const *, char const *);
diff --git a/contrib/gnu-sort/lib/strnlen.c b/contrib/gnu-sort/lib/strnlen.c
new file mode 100644
index 0000000..c9f3898
--- /dev/null
+++ b/contrib/gnu-sort/lib/strnlen.c
@@ -0,0 +1,48 @@
+/* Find the length of STRING, but scan at most MAXLEN characters.
+ Copyright (C) 1996, 1997, 1998, 2000-2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+#undef strnlen
+
+#include <string.h>
+
+#undef __strnlen
+#undef strnlen
+
+#ifndef _LIBC
+# define strnlen rpl_strnlen
+#endif
+
+#ifndef weak_alias
+# define __strnlen strnlen
+#endif
+
+/* Find the length of STRING, but scan at most MAXLEN characters.
+ If no '\0' terminator is found in that many characters, return MAXLEN. */
+
+size_t
+__strnlen (const char *string, size_t maxlen)
+{
+ const char *end = memchr (string, '\0', maxlen);
+ return end ? (size_t) (end - string) : maxlen;
+}
+#ifdef weak_alias
+weak_alias (__strnlen, strnlen)
+#endif
diff --git a/contrib/gnu-sort/lib/timespec.h b/contrib/gnu-sort/lib/timespec.h
new file mode 100644
index 0000000..2c32a23
--- /dev/null
+++ b/contrib/gnu-sort/lib/timespec.h
@@ -0,0 +1,71 @@
+/* timespec -- System time interface
+
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if ! defined TIMESPEC_H
+# define TIMESPEC_H
+
+/* You must include config.h before including this file. */
+
+# include <sys/types.h>
+# if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+# else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+# endif
+
+# if ! HAVE_STRUCT_TIMESPEC
+/* Some systems don't define this struct, e.g., AIX 4.1, Ultrix 4.3. */
+struct timespec
+{
+ time_t tv_sec;
+ long tv_nsec;
+};
+# endif
+
+# ifdef ST_MTIM_NSEC
+# define ST_TIME_CMP_NS(a, b, ns) ((a).ns < (b).ns ? -1 : (a).ns > (b).ns)
+# else
+# define ST_TIME_CMP_NS(a, b, ns) 0
+# endif
+# define ST_TIME_CMP(a, b, s, ns) \
+ ((a).s < (b).s ? -1 : (a).s > (b).s ? 1 : ST_TIME_CMP_NS(a, b, ns))
+# define ATIME_CMP(a, b) ST_TIME_CMP (a, b, st_atime, st_atim.ST_MTIM_NSEC)
+# define CTIME_CMP(a, b) ST_TIME_CMP (a, b, st_ctime, st_ctim.ST_MTIM_NSEC)
+# define MTIME_CMP(a, b) ST_TIME_CMP (a, b, st_mtime, st_mtim.ST_MTIM_NSEC)
+
+# ifdef ST_MTIM_NSEC
+# define TIMESPEC_NS(timespec) ((timespec).ST_MTIM_NSEC)
+# else
+# define TIMESPEC_NS(timespec) 0
+# endif
+
+# if ! HAVE_DECL_NANOSLEEP
+/* Don't specify a prototype here. Some systems (e.g., OSF) declare
+ nanosleep with a conflicting one (const-less first parameter). */
+int nanosleep ();
+# endif
+
+int gettime (struct timespec *);
+int settime (struct timespec const *);
+
+#endif
diff --git a/contrib/gnu-sort/lib/umaxtostr.c b/contrib/gnu-sort/lib/umaxtostr.c
new file mode 100644
index 0000000..4f49a7f
--- /dev/null
+++ b/contrib/gnu-sort/lib/umaxtostr.c
@@ -0,0 +1,3 @@
+#define inttostr umaxtostr
+#define inttype uintmax_t
+#include "inttostr.c"
diff --git a/contrib/gnu-sort/lib/unistd-safer.h b/contrib/gnu-sort/lib/unistd-safer.h
new file mode 100644
index 0000000..2976e9d
--- /dev/null
+++ b/contrib/gnu-sort/lib/unistd-safer.h
@@ -0,0 +1,21 @@
+/* Invoke unistd functions, but avoid some glitches.
+
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+int dup_safer (int);
diff --git a/contrib/gnu-sort/lib/version-etc.c b/contrib/gnu-sort/lib/version-etc.c
new file mode 100644
index 0000000..ccc135b
--- /dev/null
+++ b/contrib/gnu-sort/lib/version-etc.c
@@ -0,0 +1,181 @@
+/* Utility to help print --version output in a consistent format.
+ Copyright (C) 1999-2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* $FreeBSD$ */
+
+/* Written by Jim Meyering. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification. */
+#include "version-etc.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "unlocked-io.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+/* Default copyright goes to the FSF. */
+
+const char* version_etc_copyright =
+ /* Do *not* mark this string for translation. */
+ "Copyright (C) 2004 Free Software Foundation, Inc.";
+
+
+/* Like version_etc, below, but with the NULL-terminated author list
+ provided via a variable of type va_list. */
+void
+version_etc_va (FILE *stream,
+ const char *command_name, const char *package,
+ const char *version, va_list authors)
+{
+ size_t n_authors;
+
+ /* Count the number of authors. */
+ {
+ va_list tmp_authors;
+
+#ifdef va_copy
+ va_copy (tmp_authors, authors);
+#else
+ tmp_authors = authors;
+#endif
+
+ n_authors = 0;
+ while (va_arg (tmp_authors, const char *) != NULL)
+ ++n_authors;
+#ifdef va_copy
+ va_end (tmp_authors);
+#endif
+ }
+
+ if (command_name)
+ fprintf (stream, "%s (%s) %s\n", command_name, package, version);
+ else
+ fprintf (stream, "%s %s\n", package, version);
+
+ switch (n_authors)
+ {
+ case 0:
+ /* The caller must provide at least one author name. */
+ abort ();
+ case 1:
+ /* TRANSLATORS: %s denotes an author name. */
+ vfprintf (stream, _("Written by %s.\n"), authors);
+ break;
+ case 2:
+ /* TRANSLATORS: Each %s denotes an author name. */
+ vfprintf (stream, _("Written by %s and %s.\n"), authors);
+ break;
+ case 3:
+ /* TRANSLATORS: Each %s denotes an author name. */
+ vfprintf (stream, _("Written by %s, %s, and %s.\n"), authors);
+ break;
+ case 4:
+ /* TRANSLATORS: Each %s denotes an author name.
+ You can use line breaks, estimating that each author name occupies
+ ca. 16 screen columns and that a screen line has ca. 80 columns. */
+ vfprintf (stream, _("Written by %s, %s, %s,\nand %s.\n"), authors);
+ break;
+ case 5:
+ /* TRANSLATORS: Each %s denotes an author name.
+ You can use line breaks, estimating that each author name occupies
+ ca. 16 screen columns and that a screen line has ca. 80 columns. */
+ vfprintf (stream, _("Written by %s, %s, %s,\n%s, and %s.\n"), authors);
+ break;
+ case 6:
+ /* TRANSLATORS: Each %s denotes an author name.
+ You can use line breaks, estimating that each author name occupies
+ ca. 16 screen columns and that a screen line has ca. 80 columns. */
+ vfprintf (stream, _("Written by %s, %s, %s,\n%s, %s, and %s.\n"),
+ authors);
+ break;
+ case 7:
+ /* TRANSLATORS: Each %s denotes an author name.
+ You can use line breaks, estimating that each author name occupies
+ ca. 16 screen columns and that a screen line has ca. 80 columns. */
+ vfprintf (stream, _("Written by %s, %s, %s,\n%s, %s, %s, and %s.\n"),
+ authors);
+ break;
+ case 8:
+ /* TRANSLATORS: Each %s denotes an author name.
+ You can use line breaks, estimating that each author name occupies
+ ca. 16 screen columns and that a screen line has ca. 80 columns. */
+ vfprintf (stream, _("\
+Written by %s, %s, %s,\n%s, %s, %s, %s,\nand %s.\n"),
+ authors);
+ break;
+ case 9:
+ /* TRANSLATORS: Each %s denotes an author name.
+ You can use line breaks, estimating that each author name occupies
+ ca. 16 screen columns and that a screen line has ca. 80 columns. */
+ vfprintf (stream, _("\
+Written by %s, %s, %s,\n%s, %s, %s, %s,\n%s, and %s.\n"),
+ authors);
+ break;
+ default:
+ /* 10 or more authors. Use an abbreviation, since the human reader
+ will probably not want to read the entire list anyway. */
+ /* TRANSLATORS: Each %s denotes an author name.
+ You can use line breaks, estimating that each author name occupies
+ ca. 16 screen columns and that a screen line has ca. 80 columns. */
+ vfprintf (stream, _("\
+Written by %s, %s, %s,\n%s, %s, %s, %s,\n%s, %s, and others.\n"),
+ authors);
+ break;
+ }
+ va_end (authors);
+ putc ('\n', stream);
+
+ fputs (version_etc_copyright, stream);
+ putc ('\n', stream);
+
+ fputs (_("\
+This is free software; see the source for copying conditions. There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
+ stream);
+}
+
+
+/* Display the --version information the standard way.
+
+ If COMMAND_NAME is NULL, the PACKAGE is asumed to be the name of
+ the program. The formats are therefore:
+
+ PACKAGE VERSION
+
+ or
+
+ COMMAND_NAME (PACKAGE) VERSION.
+
+ The author names are passed as separate arguments, with an additional
+ NULL argument at the end. */
+void
+version_etc (FILE *stream,
+ const char *command_name, const char *package,
+ const char *version, /* const char *author1, ...*/ ...)
+{
+ va_list authors;
+
+ va_start (authors, version);
+ version_etc_va (stream, command_name, package, version, authors);
+}
diff --git a/contrib/gnu-sort/lib/version-etc.h b/contrib/gnu-sort/lib/version-etc.h
new file mode 100644
index 0000000..d505e75
--- /dev/null
+++ b/contrib/gnu-sort/lib/version-etc.h
@@ -0,0 +1,37 @@
+/* Utility to help print --version output in a consistent format.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Jim Meyering. */
+
+#ifndef VERSION_ETC_H
+# define VERSION_ETC_H 1
+
+# include <stdarg.h>
+# include <stdio.h>
+
+extern const char *version_etc_copyright;
+
+extern void version_etc_va (FILE *stream,
+ const char *command_name, const char *package,
+ const char *version, va_list authors);
+
+extern void version_etc (FILE *stream,
+ const char *command_name, const char *package,
+ const char *version,
+ /* const char *author1, ...*/ ...);
+
+#endif /* VERSION_ETC_H */
diff --git a/contrib/gnu-sort/lib/xalloc-die.c b/contrib/gnu-sort/lib/xalloc-die.c
new file mode 100644
index 0000000..ca3a689
--- /dev/null
+++ b/contrib/gnu-sort/lib/xalloc-die.c
@@ -0,0 +1,45 @@
+/* Report a memory allocation failure and exit.
+
+ Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004 Free
+ Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "xalloc.h"
+
+#include <stdlib.h>
+
+#include "error.h"
+#include "exitfail.h"
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+void
+xalloc_die (void)
+{
+ error (exit_failure, 0, "%s", _("memory exhausted"));
+
+ /* The `noreturn' cannot be given to error, since it may return if
+ its first argument is 0. To help compilers understand the
+ xalloc_die does not return, call abort. Also, the abort is a
+ safety feature if exit_failure is 0 (which shouldn't happen). */
+ abort ();
+}
diff --git a/contrib/gnu-sort/lib/xalloc.h b/contrib/gnu-sort/lib/xalloc.h
new file mode 100644
index 0000000..d81f2a6
--- /dev/null
+++ b/contrib/gnu-sort/lib/xalloc.h
@@ -0,0 +1,90 @@
+/* xalloc.h -- malloc with out-of-memory checking
+
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef XALLOC_H_
+# define XALLOC_H_
+
+# include <stddef.h>
+
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+
+# ifndef __attribute__
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
+# define __attribute__(x)
+# endif
+# endif
+
+# ifndef ATTRIBUTE_NORETURN
+# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
+# endif
+
+/* This function is always triggered when memory is exhausted.
+ It must be defined by the application, either explicitly
+ or by using gnulib's xalloc-die module. This is the
+ function to call when one wants the program to die because of a
+ memory allocation failure. */
+extern void xalloc_die (void) ATTRIBUTE_NORETURN;
+
+void *xmalloc (size_t s);
+void *xnmalloc (size_t n, size_t s);
+void *xzalloc (size_t s);
+void *xcalloc (size_t n, size_t s);
+void *xrealloc (void *p, size_t s);
+void *xnrealloc (void *p, size_t n, size_t s);
+void *x2realloc (void *p, size_t *pn);
+void *x2nrealloc (void *p, size_t *pn, size_t s);
+void *xclone (void const *p, size_t s);
+char *xstrdup (const char *str);
+
+/* Return 1 if an array of N objects, each of size S, cannot exist due
+ to size arithmetic overflow. S must be positive and N must be
+ nonnegative. This is a macro, not an inline function, so that it
+ works correctly even when SIZE_MAX < N.
+
+ By gnulib convention, SIZE_MAX represents overflow in size
+ calculations, so the conservative dividend to use here is
+ SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
+ However, malloc (SIZE_MAX) fails on all known hosts where
+ sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
+ exactly-SIZE_MAX allocations on such hosts; this avoids a test and
+ branch when S is known to be 1. */
+# define xalloc_oversized(n, s) \
+ ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
+
+/* These macros are deprecated; they will go away soon, and are retained
+ temporarily only to ease conversion to the functions described above. */
+# define CCLONE(p, n) xclone (p, (n) * sizeof *(p))
+# define CLONE(p) xclone (p, sizeof *(p))
+# define NEW(type, var) type *var = xmalloc (sizeof (type))
+# define XCALLOC(type, n) xcalloc (n, sizeof (type))
+# define XMALLOC(type, n) xnmalloc (n, sizeof (type))
+# define XREALLOC(p, type, n) xnrealloc (p, n, sizeof (type))
+# define XFREE(p) free (p)
+
+
+# ifdef __cplusplus
+}
+# endif
+
+
+#endif /* !XALLOC_H_ */
diff --git a/contrib/gnu-sort/lib/xmalloc.c b/contrib/gnu-sort/lib/xmalloc.c
new file mode 100644
index 0000000..9b7a948
--- /dev/null
+++ b/contrib/gnu-sort/lib/xmalloc.c
@@ -0,0 +1,221 @@
+/* xmalloc.c -- malloc with out of memory checking
+
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "xalloc.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+
+/* Allocate an array of N objects, each with S bytes of memory,
+ dynamically, with error checking. S must be nonzero. */
+
+static inline void *
+xnmalloc_inline (size_t n, size_t s)
+{
+ void *p;
+ if (xalloc_oversized (n, s) || (! (p = malloc (n * s)) && n != 0))
+ xalloc_die ();
+ return p;
+}
+
+void *
+xnmalloc (size_t n, size_t s)
+{
+ return xnmalloc_inline (n, s);
+}
+
+/* Allocate N bytes of memory dynamically, with error checking. */
+
+void *
+xmalloc (size_t n)
+{
+ return xnmalloc_inline (n, 1);
+}
+
+/* Change the size of an allocated block of memory P to an array of N
+ objects each of S bytes, with error checking. S must be nonzero. */
+
+static inline void *
+xnrealloc_inline (void *p, size_t n, size_t s)
+{
+ if (xalloc_oversized (n, s) || (! (p = realloc (p, n * s)) && n != 0))
+ xalloc_die ();
+ return p;
+}
+
+void *
+xnrealloc (void *p, size_t n, size_t s)
+{
+ return xnrealloc_inline (p, n, s);
+}
+
+/* Change the size of an allocated block of memory P to N bytes,
+ with error checking. */
+
+void *
+xrealloc (void *p, size_t n)
+{
+ return xnrealloc_inline (p, n, 1);
+}
+
+
+/* If P is null, allocate a block of at least *PN such objects;
+ otherwise, reallocate P so that it contains more than *PN objects
+ each of S bytes. *PN must be nonzero unless P is null, and S must
+ be nonzero. Set *PN to the new number of objects, and return the
+ pointer to the new block. *PN is never set to zero, and the
+ returned pointer is never null.
+
+ Repeated reallocations are guaranteed to make progress, either by
+ allocating an initial block with a nonzero size, or by allocating a
+ larger block.
+
+ In the following implementation, nonzero sizes are doubled so that
+ repeated reallocations have O(N log N) overall cost rather than
+ O(N**2) cost, but the specification for this function does not
+ guarantee that sizes are doubled.
+
+ Here is an example of use:
+
+ int *p = NULL;
+ size_t used = 0;
+ size_t allocated = 0;
+
+ void
+ append_int (int value)
+ {
+ if (used == allocated)
+ p = x2nrealloc (p, &allocated, sizeof *p);
+ p[used++] = value;
+ }
+
+ This causes x2nrealloc to allocate a block of some nonzero size the
+ first time it is called.
+
+ To have finer-grained control over the initial size, set *PN to a
+ nonzero value before calling this function with P == NULL. For
+ example:
+
+ int *p = NULL;
+ size_t used = 0;
+ size_t allocated = 0;
+ size_t allocated1 = 1000;
+
+ void
+ append_int (int value)
+ {
+ if (used == allocated)
+ {
+ p = x2nrealloc (p, &allocated1, sizeof *p);
+ allocated = allocated1;
+ }
+ p[used++] = value;
+ }
+
+ */
+
+static inline void *
+x2nrealloc_inline (void *p, size_t *pn, size_t s)
+{
+ size_t n = *pn;
+
+ if (! p)
+ {
+ if (! n)
+ {
+ /* The approximate size to use for initial small allocation
+ requests, when the invoking code specifies an old size of
+ zero. 64 bytes is the largest "small" request for the
+ GNU C library malloc. */
+ enum { DEFAULT_MXFAST = 64 };
+
+ n = DEFAULT_MXFAST / s;
+ n += !n;
+ }
+ }
+ else
+ {
+ if (SIZE_MAX / 2 / s < n)
+ xalloc_die ();
+ n *= 2;
+ }
+
+ *pn = n;
+ return xrealloc (p, n * s);
+}
+
+void *
+x2nrealloc (void *p, size_t *pn, size_t s)
+{
+ return x2nrealloc_inline (p, pn, s);
+}
+
+/* If P is null, allocate a block of at least *PN bytes; otherwise,
+ reallocate P so that it contains more than *PN bytes. *PN must be
+ nonzero unless P is null. Set *PN to the new block's size, and
+ return the pointer to the new block. *PN is never set to zero, and
+ the returned pointer is never null. */
+
+void *
+x2realloc (void *p, size_t *pn)
+{
+ return x2nrealloc_inline (p, pn, 1);
+}
+
+/* Allocate S bytes of zeroed memory dynamically, with error checking.
+ There's no need for xnzalloc (N, S), since it would be equivalent
+ to xcalloc (N, S). */
+
+void *
+xzalloc (size_t s)
+{
+ return memset (xmalloc (s), 0, s);
+}
+
+/* Allocate zeroed memory for N elements of S bytes, with error
+ checking. S must be nonzero. */
+
+void *
+xcalloc (size_t n, size_t s)
+{
+ void *p;
+ /* Test for overflow, since some calloc implementations don't have
+ proper overflow checks. */
+ if (xalloc_oversized (n, s) || (! (p = calloc (n, s)) && n != 0))
+ xalloc_die ();
+ return p;
+}
+
+/* Clone an object P of size S, with error checking. There's no need
+ for xnclone (P, N, S), since xclone (P, N * S) works without any
+ need for an arithmetic overflow check. */
+
+void *
+xclone (void const *p, size_t s)
+{
+ return memcpy (xmalloc (s), p, s);
+}
diff --git a/contrib/gnu-sort/lib/xmemcoll.c b/contrib/gnu-sort/lib/xmemcoll.c
new file mode 100644
index 0000000..433d67f
--- /dev/null
+++ b/contrib/gnu-sort/lib/xmemcoll.c
@@ -0,0 +1,59 @@
+/* Locale-specific memory comparison.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Contributed by Paul Eggert <eggert@twinsun.com>. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+#include "error.h"
+#include "exitfail.h"
+#include "memcoll.h"
+#include "quotearg.h"
+#include "xmemcoll.h"
+
+/* Compare S1 (with length S1LEN) and S2 (with length S2LEN) according
+ to the LC_COLLATE locale. S1 and S2 do not overlap, and are not
+ adjacent. Temporarily modify the bytes after S1 and S2, but
+ restore their original contents before returning. Report an error
+ and exit if there is an error. */
+
+int
+xmemcoll (char *s1, size_t s1len, char *s2, size_t s2len)
+{
+ int diff = memcoll (s1, s1len, s2, s2len);
+ int collation_errno = errno;
+
+ if (collation_errno)
+ {
+ error (0, collation_errno, _("string comparison failed"));
+ error (0, 0, _("Set LC_ALL='C' to work around the problem."));
+ error (exit_failure, 0,
+ _("The strings compared were %s and %s."),
+ quotearg_n_style_mem (0, locale_quoting_style, s1, s1len),
+ quotearg_n_style_mem (1, locale_quoting_style, s2, s2len));
+ }
+
+ return diff;
+}
diff --git a/contrib/gnu-sort/lib/xmemcoll.h b/contrib/gnu-sort/lib/xmemcoll.h
new file mode 100644
index 0000000..2f422e8
--- /dev/null
+++ b/contrib/gnu-sort/lib/xmemcoll.h
@@ -0,0 +1,2 @@
+#include <stddef.h>
+int xmemcoll (char *, size_t, char *, size_t);
diff --git a/contrib/gnu-sort/lib/xstrtol.c b/contrib/gnu-sort/lib/xstrtol.c
new file mode 100644
index 0000000..906e4a1
--- /dev/null
+++ b/contrib/gnu-sort/lib/xstrtol.c
@@ -0,0 +1,291 @@
+/* A more useful interface to strtol.
+
+ Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2003, 2004 Free
+ Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Jim Meyering. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef __strtol
+# define __strtol strtol
+# define __strtol_t long int
+# define __xstrtol xstrtol
+# define STRTOL_T_MINIMUM LONG_MIN
+# define STRTOL_T_MAXIMUM LONG_MAX
+#endif
+
+/* Some pre-ANSI implementations (e.g. SunOS 4)
+ need stderr defined if assertion checking is enabled. */
+#include <stdio.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* The extra casts work around common compiler bugs. */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
+ ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
+ : (t) 0))
+#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
+
+#ifndef STRTOL_T_MINIMUM
+# define STRTOL_T_MINIMUM TYPE_MINIMUM (__strtol_t)
+# define STRTOL_T_MAXIMUM TYPE_MAXIMUM (__strtol_t)
+#endif
+
+#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
+# define IN_CTYPE_DOMAIN(c) 1
+#else
+# define IN_CTYPE_DOMAIN(c) isascii(c)
+#endif
+
+#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
+
+#include "xstrtol.h"
+
+#if !HAVE_DECL_STRTOIMAX && !defined strtoimax
+intmax_t strtoimax ();
+#endif
+
+#if !HAVE_DECL_STRTOUMAX && !defined strtoumax
+uintmax_t strtoumax ();
+#endif
+
+static strtol_error
+bkm_scale (__strtol_t *x, int scale_factor)
+{
+ if (TYPE_SIGNED (__strtol_t) && *x < STRTOL_T_MINIMUM / scale_factor)
+ {
+ *x = STRTOL_T_MINIMUM;
+ return LONGINT_OVERFLOW;
+ }
+ if (STRTOL_T_MAXIMUM / scale_factor < *x)
+ {
+ *x = STRTOL_T_MAXIMUM;
+ return LONGINT_OVERFLOW;
+ }
+ *x *= scale_factor;
+ return LONGINT_OK;
+}
+
+static strtol_error
+bkm_scale_by_power (__strtol_t *x, int base, int power)
+{
+ strtol_error err = LONGINT_OK;
+ while (power--)
+ err |= bkm_scale (x, base);
+ return err;
+}
+
+/* FIXME: comment. */
+
+strtol_error
+__xstrtol (const char *s, char **ptr, int strtol_base,
+ __strtol_t *val, const char *valid_suffixes)
+{
+ char *t_ptr;
+ char **p;
+ __strtol_t tmp;
+ strtol_error err = LONGINT_OK;
+
+ assert (0 <= strtol_base && strtol_base <= 36);
+
+ p = (ptr ? ptr : &t_ptr);
+
+ if (! TYPE_SIGNED (__strtol_t))
+ {
+ const char *q = s;
+ unsigned char ch = *q;
+ while (ISSPACE (ch))
+ ch = *++q;
+ if (ch == '-')
+ return LONGINT_INVALID;
+ }
+
+ errno = 0;
+ tmp = __strtol (s, p, strtol_base);
+
+ if (*p == s)
+ {
+ /* If there is no number but there is a valid suffix, assume the
+ number is 1. The string is invalid otherwise. */
+ if (valid_suffixes && **p && strchr (valid_suffixes, **p))
+ tmp = 1;
+ else
+ return LONGINT_INVALID;
+ }
+ else if (errno != 0)
+ {
+ if (errno != ERANGE)
+ return LONGINT_INVALID;
+ err = LONGINT_OVERFLOW;
+ }
+
+ /* Let valid_suffixes == NULL mean `allow any suffix'. */
+ /* FIXME: update all callers except the ones that allow suffixes
+ after the number, changing last parameter NULL to `""'. */
+ if (!valid_suffixes)
+ {
+ *val = tmp;
+ return err;
+ }
+
+ if (**p != '\0')
+ {
+ int base = 1024;
+ int suffixes = 1;
+ strtol_error overflow;
+
+ if (!strchr (valid_suffixes, **p))
+ {
+ *val = tmp;
+ return err | LONGINT_INVALID_SUFFIX_CHAR;
+ }
+
+ if (strchr (valid_suffixes, '0'))
+ {
+ /* The ``valid suffix'' '0' is a special flag meaning that
+ an optional second suffix is allowed, which can change
+ the base. A suffix "B" (e.g. "100MB") stands for a power
+ of 1000, whereas a suffix "iB" (e.g. "100MiB") stands for
+ a power of 1024. If no suffix (e.g. "100M"), assume
+ power-of-1024. */
+
+ switch (p[0][1])
+ {
+ case 'i':
+ if (p[0][2] == 'B')
+ suffixes += 2;
+ break;
+
+ case 'B':
+ case 'D': /* 'D' is obsolescent */
+ base = 1000;
+ suffixes++;
+ break;
+ }
+ }
+
+ switch (**p)
+ {
+ case 'b':
+ overflow = bkm_scale (&tmp, 512);
+ break;
+
+ case 'B':
+ overflow = bkm_scale (&tmp, 1024);
+ break;
+
+ case 'c':
+ overflow = 0;
+ break;
+
+ case 'E': /* exa or exbi */
+ overflow = bkm_scale_by_power (&tmp, base, 6);
+ break;
+
+ case 'G': /* giga or gibi */
+ case 'g': /* 'g' is undocumented; for compatibility only */
+ overflow = bkm_scale_by_power (&tmp, base, 3);
+ break;
+
+ case 'k': /* kilo */
+ case 'K': /* kibi */
+ overflow = bkm_scale_by_power (&tmp, base, 1);
+ break;
+
+ case 'M': /* mega or mebi */
+ case 'm': /* 'm' is undocumented; for compatibility only */
+ overflow = bkm_scale_by_power (&tmp, base, 2);
+ break;
+
+ case 'P': /* peta or pebi */
+ overflow = bkm_scale_by_power (&tmp, base, 5);
+ break;
+
+ case 'T': /* tera or tebi */
+ case 't': /* 't' is undocumented; for compatibility only */
+ overflow = bkm_scale_by_power (&tmp, base, 4);
+ break;
+
+ case 'w':
+ overflow = bkm_scale (&tmp, 2);
+ break;
+
+ case 'Y': /* yotta or 2**80 */
+ overflow = bkm_scale_by_power (&tmp, base, 8);
+ break;
+
+ case 'Z': /* zetta or 2**70 */
+ overflow = bkm_scale_by_power (&tmp, base, 7);
+ break;
+
+ default:
+ *val = tmp;
+ return err | LONGINT_INVALID_SUFFIX_CHAR;
+ }
+
+ err |= overflow;
+ *p += suffixes;
+ if (**p)
+ err |= LONGINT_INVALID_SUFFIX_CHAR;
+ }
+
+ *val = tmp;
+ return err;
+}
+
+#ifdef TESTING_XSTRTO
+
+# include <stdio.h>
+# include "error.h"
+
+char *program_name;
+
+int
+main (int argc, char **argv)
+{
+ strtol_error s_err;
+ int i;
+
+ program_name = argv[0];
+ for (i=1; i<argc; i++)
+ {
+ char *p;
+ __strtol_t val;
+
+ s_err = __xstrtol (argv[i], &p, 0, &val, "bckmw");
+ if (s_err == LONGINT_OK)
+ {
+ printf ("%s->%lu (%s)\n", argv[i], val, p);
+ }
+ else
+ {
+ STRTOL_FATAL_ERROR (argv[i], "arg", s_err);
+ }
+ }
+ exit (0);
+}
+
+#endif /* TESTING_XSTRTO */
diff --git a/contrib/gnu-sort/lib/xstrtol.h b/contrib/gnu-sort/lib/xstrtol.h
new file mode 100644
index 0000000..0d6b984
--- /dev/null
+++ b/contrib/gnu-sort/lib/xstrtol.h
@@ -0,0 +1,89 @@
+/* A more useful interface to strtol.
+
+ Copyright (C) 1995, 1996, 1998, 1999, 2001, 2002, 2003, 2004 Free
+ Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef XSTRTOL_H_
+# define XSTRTOL_H_ 1
+
+# include "exitfail.h"
+
+# if HAVE_INTTYPES_H
+# include <inttypes.h>
+# endif
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+
+# ifndef _STRTOL_ERROR
+enum strtol_error
+ {
+ LONGINT_OK = 0,
+
+ /* These two values can be ORed together, to indicate that both
+ errors occurred. */
+ LONGINT_OVERFLOW = 1,
+ LONGINT_INVALID_SUFFIX_CHAR = 2,
+
+ LONGINT_INVALID_SUFFIX_CHAR_WITH_OVERFLOW = (LONGINT_INVALID_SUFFIX_CHAR
+ | LONGINT_OVERFLOW),
+ LONGINT_INVALID = 4
+ };
+typedef enum strtol_error strtol_error;
+# endif
+
+# define _DECLARE_XSTRTOL(name, type) \
+ strtol_error name (const char *, char **, int, type *, const char *);
+_DECLARE_XSTRTOL (xstrtol, long int)
+_DECLARE_XSTRTOL (xstrtoul, unsigned long int)
+_DECLARE_XSTRTOL (xstrtoimax, intmax_t)
+_DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
+
+# define _STRTOL_ERROR(Exit_code, Str, Argument_type_string, Err) \
+ do \
+ { \
+ switch ((Err)) \
+ { \
+ default: \
+ abort (); \
+ \
+ case LONGINT_INVALID: \
+ error ((Exit_code), 0, "invalid %s `%s'", \
+ (Argument_type_string), (Str)); \
+ break; \
+ \
+ case LONGINT_INVALID_SUFFIX_CHAR: \
+ case LONGINT_INVALID_SUFFIX_CHAR | LONGINT_OVERFLOW: \
+ error ((Exit_code), 0, "invalid character following %s in `%s'", \
+ (Argument_type_string), (Str)); \
+ break; \
+ \
+ case LONGINT_OVERFLOW: \
+ error ((Exit_code), 0, "%s `%s' too large", \
+ (Argument_type_string), (Str)); \
+ break; \
+ } \
+ } \
+ while (0)
+
+# define STRTOL_FATAL_ERROR(Str, Argument_type_string, Err) \
+ _STRTOL_ERROR (exit_failure, Str, Argument_type_string, Err)
+
+# define STRTOL_FAIL_WARN(Str, Argument_type_string, Err) \
+ _STRTOL_ERROR (0, Str, Argument_type_string, Err)
+
+#endif /* not XSTRTOL_H_ */
diff --git a/contrib/gnu-sort/lib/xstrtoul.c b/contrib/gnu-sort/lib/xstrtoul.c
new file mode 100644
index 0000000..285f7b9
--- /dev/null
+++ b/contrib/gnu-sort/lib/xstrtoul.c
@@ -0,0 +1,6 @@
+#define __strtol strtoul
+#define __strtol_t unsigned long int
+#define __xstrtol xstrtoul
+#define STRTOL_T_MINIMUM 0
+#define STRTOL_T_MAXIMUM ULONG_MAX
+#include "xstrtol.c"
diff --git a/contrib/gnu-sort/lib/xstrtoumax.c b/contrib/gnu-sort/lib/xstrtoumax.c
new file mode 100644
index 0000000..8518ef0
--- /dev/null
+++ b/contrib/gnu-sort/lib/xstrtoumax.c
@@ -0,0 +1,33 @@
+/* xstrtoumax.c -- A more useful interface to strtoumax.
+ Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "xstrtol.h"
+
+#define __strtol strtoumax
+#define __strtol_t uintmax_t
+#define __xstrtol xstrtoumax
+#ifdef UINTMAX_MAX
+# define STRTOL_T_MINIMUM 0
+# define STRTOL_T_MAXIMUM UINTMAX_MAX
+#endif
+#include "xstrtol.c"
diff --git a/contrib/gnu-sort/man/sort.1 b/contrib/gnu-sort/man/sort.1
new file mode 100644
index 0000000..2bb445d
--- /dev/null
+++ b/contrib/gnu-sort/man/sort.1
@@ -0,0 +1,113 @@
+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.33.
+.TH SORT "1" "March 2004" "sort (coreutils) 5.2.1" "User Commands"
+.SH NAME
+sort \- sort lines of text files
+.SH SYNOPSIS
+.B sort
+[\fIOPTION\fR]... [\fIFILE\fR]...
+.SH DESCRIPTION
+.\" Add any additional description here
+.PP
+Write sorted concatenation of all FILE(s) to standard output.
+.PP
+Ordering options:
+.PP
+Mandatory arguments to long options are mandatory for short options too.
+.HP
+\fB\-b\fR, \fB\-\-ignore\-leading\-blanks\fR ignore leading blanks
+.TP
+\fB\-d\fR, \fB\-\-dictionary\-order\fR
+consider only blanks and alphanumeric characters
+.TP
+\fB\-f\fR, \fB\-\-ignore\-case\fR
+fold lower case to upper case characters
+.TP
+\fB\-g\fR, \fB\-\-general\-numeric\-sort\fR
+compare according to general numerical value
+.TP
+\fB\-i\fR, \fB\-\-ignore\-nonprinting\fR
+consider only printable characters
+.TP
+\fB\-M\fR, \fB\-\-month\-sort\fR
+compare (unknown) < `JAN' < ... < `DEC'
+.TP
+\fB\-n\fR, \fB\-\-numeric\-sort\fR
+compare according to string numerical value
+.TP
+\fB\-r\fR, \fB\-\-reverse\fR
+reverse the result of comparisons
+.PP
+Other options:
+.TP
+\fB\-c\fR, \fB\-\-check\fR
+check whether input is sorted; do not sort
+.TP
+\fB\-k\fR, \fB\-\-key\fR=\fIPOS1[\fR,POS2]
+start a key at POS1, end it at POS 2 (origin 1)
+.TP
+\fB\-m\fR, \fB\-\-merge\fR
+merge already sorted files; do not sort
+.TP
+\fB\-o\fR, \fB\-\-output\fR=\fIFILE\fR
+write result to FILE instead of standard output
+.TP
+\fB\-s\fR, \fB\-\-stable\fR
+stabilize sort by disabling last-resort comparison
+.TP
+\fB\-S\fR, \fB\-\-buffer\-size\fR=\fISIZE\fR
+use SIZE for main memory buffer
+.HP
+\fB\-t\fR, \fB\-\-field\-separator\fR=\fISEP\fR use SEP instead of non-blank to blank transition
+.TP
+\fB\-T\fR, \fB\-\-temporary\-directory\fR=\fIDIR\fR
+use DIR for temporaries, not $TMPDIR or /tmp;
+multiple options specify multiple directories
+.TP
+\fB\-u\fR, \fB\-\-unique\fR
+with \fB\-c\fR, check for strict ordering;
+without \fB\-c\fR, output only the first of an equal run
+.TP
+\fB\-z\fR, \fB\-\-zero\-terminated\fR
+end lines with 0 byte, not newline
+.TP
+\fB\-\-help\fR
+display this help and exit
+.TP
+\fB\-\-version\fR
+output version information and exit
+.PP
+POS is F[.C][OPTS], where F is the field number and C the character position
+in the field. OPTS is one or more single-letter ordering options, which
+override global ordering options for that key. If no key is given, use the
+entire line as the key.
+.PP
+SIZE may be followed by the following multiplicative suffixes:
+% 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y.
+.PP
+With no FILE, or when FILE is -, read standard input.
+.PP
+*** WARNING ***
+The locale specified by the environment affects sort order.
+Set LC_ALL=C to get the traditional sort order that uses
+native byte values.
+.SH AUTHOR
+Written by Mike Haertel and Paul Eggert.
+.SH "REPORTING BUGS"
+Report bugs to <bug-coreutils@gnu.org>.
+.SH COPYRIGHT
+Copyright \(co 2004 Free Software Foundation, Inc.
+.br
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+.SH "SEE ALSO"
+The full documentation for
+.B sort
+is maintained as a Texinfo manual. If the
+.B info
+and
+.B sort
+programs are properly installed at your site, the command
+.IP
+.B info coreutils sort
+.PP
+should give you access to the complete manual.
diff --git a/contrib/gnu-sort/src/sort.c b/contrib/gnu-sort/src/sort.c
new file mode 100644
index 0000000..0b9d33f
--- /dev/null
+++ b/contrib/gnu-sort/src/sort.c
@@ -0,0 +1,3237 @@
+/* $FreeBSD$ */
+/* sort - sort lines of text (with all kinds of options).
+ Copyright (C) 88, 1991-2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Written December 1988 by Mike Haertel.
+ The author may be reached (Email) at the address mike@gnu.ai.mit.edu,
+ or (US mail) as Mike Haertel c/o Free Software Foundation.
+
+ Ørn E. Hansen added NLS support in 1997. */
+
+#include <config.h>
+
+#include <assert.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <stdio.h>
+
+/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
+/* Get mbstate_t, mbrtowc(), wcwidth(). */
+#if HAVE_WCHAR_H
+# include <wchar.h>
+#endif
+
+/* Get isw* functions. */
+#if HAVE_WCTYPE_H
+# include <wctype.h>
+#endif
+
+/* Get nl_langinfo(). */
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+
+/* Include this after wctype.h so that we `#undef' ISPRINT
+ (from Solaris's euc.h, from widec.h, from wctype.h) before
+ redefining and using it. */
+#include "system.h"
+#include "error.h"
+#include "hard-locale.h"
+#include "inttostr.h"
+#include "long-options.h"
+#include "physmem.h"
+#include "posixver.h"
+#include "quote.h"
+#include "stdio-safer.h"
+#include "xmemcoll.h"
+#include "xstrtol.h"
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+#ifndef RLIMIT_DATA
+struct rlimit { size_t rlim_cur; };
+# define getrlimit(Resource, Rlp) (-1)
+#endif
+
+/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
+ installation; work around this configuration error. */
+#if !defined MB_LEN_MAX || MB_LEN_MAX == 1
+# define MB_LEN_MAX 16
+#endif
+
+/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
+#if HAVE_MBRTOWC && defined mbstate_t
+# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
+#endif
+
+/* The official name of this program (e.g., no `g' prefix). */
+#define PROGRAM_NAME "sort"
+
+#define AUTHORS "Mike Haertel", "Paul Eggert"
+
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+
+#ifndef SA_NOCLDSTOP
+# define sigprocmask(How, Set, Oset) /* empty */
+# define sigset_t int
+#endif
+
+#ifndef STDC_HEADERS
+double strtod ();
+#endif
+
+#define UCHAR_LIM (UCHAR_MAX + 1)
+
+#ifndef DEFAULT_TMPDIR
+# define DEFAULT_TMPDIR "/tmp"
+#endif
+
+/* Exit statuses. */
+enum
+ {
+ /* POSIX says to exit with status 1 if invoked with -c and the
+ input is not properly sorted. */
+ SORT_OUT_OF_ORDER = 1,
+
+ /* POSIX says any other irregular exit must exit with a status
+ code greater than 1. */
+ SORT_FAILURE = 2
+ };
+
+#define C_DECIMAL_POINT '.'
+#define NEGATION_SIGN '-'
+#define NUMERIC_ZERO '0'
+
+#if HAVE_SETLOCALE
+
+static char decimal_point;
+static int th_sep; /* if CHAR_MAX + 1, then there is no thousands separator */
+static int force_general_numcompare = 0;
+
+/* Nonzero if the corresponding locales are hard. */
+static bool hard_LC_COLLATE;
+# if HAVE_NL_LANGINFO
+static bool hard_LC_TIME;
+# endif
+
+# define IS_THOUSANDS_SEP(x) ((x) == th_sep)
+
+#else
+
+# define decimal_point C_DECIMAL_POINT
+# define IS_THOUSANDS_SEP(x) false
+
+#endif
+
+#define NONZERO(x) (x != 0)
+
+/* get a multibyte character's byte length. */
+#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \
+ do \
+ { \
+ wchar_t wc; \
+ mbstate_t state_bak; \
+ \
+ state_bak = STATE; \
+ mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \
+ \
+ switch (MBLENGTH) \
+ { \
+ case (size_t)-1: \
+ case (size_t)-2: \
+ STATE = state_bak; \
+ /* Fall through. */ \
+ case 0: \
+ MBLENGTH = 1; \
+ } \
+ } \
+ while (0)
+
+/* The kind of blanks for '-b' to skip in various options. */
+enum blanktype { bl_start, bl_end, bl_both };
+
+/* The character marking end of line. Default to \n. */
+static char eolchar = '\n';
+
+/* Lines are held in core as counted strings. */
+struct line
+{
+ char *text; /* Text of the line. */
+ size_t length; /* Length including final newline. */
+ char *keybeg; /* Start of first key. */
+ char *keylim; /* Limit of first key. */
+};
+
+/* Input buffers. */
+struct buffer
+{
+ char *buf; /* Dynamically allocated buffer,
+ partitioned into 3 regions:
+ - input data;
+ - unused area;
+ - an array of lines, in reverse order. */
+ size_t used; /* Number of bytes used for input data. */
+ size_t nlines; /* Number of lines in the line array. */
+ size_t alloc; /* Number of bytes allocated. */
+ size_t left; /* Number of bytes left from previous reads. */
+ size_t line_bytes; /* Number of bytes to reserve for each line. */
+ bool eof; /* An EOF has been read. */
+};
+
+struct keyfield
+{
+ size_t sword; /* Zero-origin 'word' to start at. */
+ size_t schar; /* Additional characters to skip. */
+ size_t eword; /* Zero-origin first word after field. */
+ size_t echar; /* Additional characters in field. */
+ bool const *ignore; /* Boolean array of characters to ignore. */
+ char const *translate; /* Translation applied to characters. */
+ bool skipsblanks; /* Skip leading blanks when finding start. */
+ bool skipeblanks; /* Skip leading blanks when finding end. */
+ bool numeric; /* Flag for numeric comparison. Handle
+ strings of digits with optional decimal
+ point, but no exponential notation. */
+ bool general_numeric; /* Flag for general, numeric comparison.
+ Handle numbers in exponential notation. */
+ bool month; /* Flag for comparison by month name. */
+ bool reverse; /* Reverse the sense of comparison. */
+ struct keyfield *next; /* Next keyfield to try. */
+};
+
+struct month
+{
+ char const *name;
+ int val;
+};
+
+/* The name this program was run with. */
+char *program_name;
+
+/* FIXME: None of these tables work with multibyte character sets.
+ Also, there are many other bugs when handling multibyte characters.
+ One way to fix this is to rewrite `sort' to use wide characters
+ internally, but doing this with good performance is a bit
+ tricky. */
+
+/* Table of blanks. */
+static bool blanks[UCHAR_LIM];
+
+/* Table of non-printing characters. */
+static bool nonprinting[UCHAR_LIM];
+
+/* Table of non-dictionary characters (not letters, digits, or blanks). */
+static bool nondictionary[UCHAR_LIM];
+
+/* Translation table folding lower case to upper. */
+static char fold_toupper[UCHAR_LIM];
+
+#define MONTHS_PER_YEAR 12
+
+/* Table mapping month names to integers.
+ Alphabetic order allows binary search. */
+static struct month monthtab[] =
+{
+ {"APR", 4},
+ {"AUG", 8},
+ {"DEC", 12},
+ {"FEB", 2},
+ {"JAN", 1},
+ {"JUL", 7},
+ {"JUN", 6},
+ {"MAR", 3},
+ {"MAY", 5},
+ {"NOV", 11},
+ {"OCT", 10},
+ {"SEP", 9}
+};
+
+/* During the merge phase, the number of files to merge at once. */
+#define NMERGE 16
+
+/* Minimum size for a merge or check buffer. */
+#define MIN_MERGE_BUFFER_SIZE (2 + sizeof (struct line))
+
+/* Minimum sort size; the code might not work with smaller sizes. */
+#define MIN_SORT_SIZE (NMERGE * MIN_MERGE_BUFFER_SIZE)
+
+/* The number of bytes needed for a merge or check buffer, which can
+ function relatively efficiently even if it holds only one line. If
+ a longer line is seen, this value is increased. */
+static size_t merge_buffer_size = MAX (MIN_MERGE_BUFFER_SIZE, 256 * 1024);
+
+/* The approximate maximum number of bytes of main memory to use, as
+ specified by the user. Zero if the user has not specified a size. */
+static size_t sort_size;
+
+/* The guessed size for non-regular files. */
+#define INPUT_FILE_SIZE_GUESS (1024 * 1024)
+
+/* Array of directory names in which any temporary files are to be created. */
+static char const **temp_dirs;
+
+/* Number of temporary directory names used. */
+static size_t temp_dir_count;
+
+/* Number of allocated slots in temp_dirs. */
+static size_t temp_dir_alloc;
+
+/* Flag to reverse the order of all comparisons. */
+static bool reverse;
+
+/* Flag for stable sort. This turns off the last ditch bytewise
+ comparison of lines, and instead leaves lines in the same order
+ they were read if all keys compare equal. */
+static bool stable;
+
+/* Tab character separating fields. If tab_default, then fields are
+ separated by the empty string between a non-blank character and a blank
+ character. */
+static bool tab_default = true;
+static unsigned char tab[MB_LEN_MAX + 1];
+static size_t tab_length = 1;
+
+/* Flag to remove consecutive duplicate lines from the output.
+ Only the last of a sequence of equal lines will be output. */
+static bool unique;
+
+/* Nonzero if any of the input files are the standard input. */
+static bool have_read_stdin;
+
+/* List of key field comparisons to be tried. */
+static struct keyfield *keylist;
+
+static void sortlines_temp (struct line *, size_t, struct line *);
+
+void
+usage (int status)
+{
+ if (status != EXIT_SUCCESS)
+ fprintf (stderr, _("Try `%s --help' for more information.\n"),
+ program_name);
+ else
+ {
+ printf (_("\
+Usage: %s [OPTION]... [FILE]...\n\
+"),
+ program_name);
+ fputs (_("\
+Write sorted concatenation of all FILE(s) to standard output.\n\
+\n\
+Ordering options:\n\
+\n\
+"), stdout);
+ fputs (_("\
+Mandatory arguments to long options are mandatory for short options too.\n\
+"), stdout);
+ fputs (_("\
+ -b, --ignore-leading-blanks ignore leading blanks\n\
+ -d, --dictionary-order consider only blanks and alphanumeric characters\n\
+ -f, --ignore-case fold lower case to upper case characters\n\
+"), stdout);
+ fputs (_("\
+ -g, --general-numeric-sort compare according to general numerical value\n\
+ -i, --ignore-nonprinting consider only printable characters\n\
+ -M, --month-sort compare (unknown) < `JAN' < ... < `DEC'\n\
+ -n, --numeric-sort compare according to string numerical value\n\
+ -r, --reverse reverse the result of comparisons\n\
+\n\
+"), stdout);
+ fputs (_("\
+Other options:\n\
+\n\
+ -c, --check check whether input is sorted; do not sort\n\
+ -k, --key=POS1[,POS2] start a key at POS1, end it at POS 2 (origin 1)\n\
+ -m, --merge merge already sorted files; do not sort\n\
+ -o, --output=FILE write result to FILE instead of standard output\n\
+ -s, --stable stabilize sort by disabling last-resort comparison\n\
+ -S, --buffer-size=SIZE use SIZE for main memory buffer\n\
+"), stdout);
+ printf (_("\
+ -t, --field-separator=SEP use SEP instead of non-blank to blank transition\n\
+ -T, --temporary-directory=DIR use DIR for temporaries, not $TMPDIR or %s;\n\
+ multiple options specify multiple directories\n\
+ -u, --unique with -c, check for strict ordering;\n\
+ without -c, output only the first of an equal run\n\
+"), DEFAULT_TMPDIR);
+ fputs (_("\
+ -z, --zero-terminated end lines with 0 byte, not newline\n\
+"), stdout);
+ fputs (HELP_OPTION_DESCRIPTION, stdout);
+ fputs (VERSION_OPTION_DESCRIPTION, stdout);
+ fputs (_("\
+\n\
+POS is F[.C][OPTS], where F is the field number and C the character position\n\
+in the field. OPTS is one or more single-letter ordering options, which\n\
+override global ordering options for that key. If no key is given, use the\n\
+entire line as the key.\n\
+\n\
+SIZE may be followed by the following multiplicative suffixes:\n\
+"), stdout);
+ fputs (_("\
+% 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y.\n\
+\n\
+With no FILE, or when FILE is -, read standard input.\n\
+\n\
+*** WARNING ***\n\
+The locale specified by the environment affects sort order.\n\
+Set LC_ALL=C to get the traditional sort order that uses\n\
+native byte values.\n\
+"), stdout );
+ printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+ }
+
+ exit (status);
+}
+
+#define COMMON_SHORT_OPTIONS "-bcdfgik:mMno:rsS:t:T:uz"
+
+static struct option const long_options[] =
+{
+ {"ignore-leading-blanks", no_argument, NULL, 'b'},
+ {"check", no_argument, NULL, 'c'},
+ {"dictionary-order", no_argument, NULL, 'd'},
+ {"ignore-case", no_argument, NULL, 'f'},
+ {"general-numeric-sort", no_argument, NULL, 'g'},
+ {"ignore-nonprinting", no_argument, NULL, 'i'},
+ {"key", required_argument, NULL, 'k'},
+ {"merge", no_argument, NULL, 'm'},
+ {"month-sort", no_argument, NULL, 'M'},
+ {"numeric-sort", no_argument, NULL, 'n'},
+ {"output", required_argument, NULL, 'o'},
+ {"reverse", no_argument, NULL, 'r'},
+ {"stable", no_argument, NULL, 's'},
+ {"buffer-size", required_argument, NULL, 'S'},
+ {"field-separator", required_argument, NULL, 't'},
+ {"temporary-directory", required_argument, NULL, 'T'},
+ {"unique", no_argument, NULL, 'u'},
+ {"zero-terminated", no_argument, NULL, 'z'},
+ {GETOPT_HELP_OPTION_DECL},
+ {GETOPT_VERSION_OPTION_DECL},
+ {0, 0, 0, 0},
+};
+
+/* The set of signals that are caught. */
+static sigset_t caught_signals;
+
+/* The list of temporary files. */
+struct tempnode
+{
+ struct tempnode *volatile next;
+ char name[1]; /* Actual size is 1 + file name length. */
+};
+static struct tempnode *volatile temphead;
+
+/* Fucntion pointers. */
+static void
+(*inittables) (void);
+
+static char *
+(* begfield) (const struct line *line, const struct keyfield *key);
+
+static char *
+(* limfield) (const struct line *line, const struct keyfield *key);
+
+static int
+(*getmonth) (const char *s, size_t len);
+
+static int
+(* keycompare) (const struct line *a, const struct line *b);
+
+/* Test for white space multibyte character.
+ Set LENGTH the byte length of investigated multibyte character. */
+#if HAVE_MBRTOWC
+static int
+ismbblank (const char *str, size_t len, size_t *length)
+{
+ size_t mblength;
+ wchar_t wc;
+ mbstate_t state;
+
+ memset (&state, '\0', sizeof(mbstate_t));
+ mblength = mbrtowc (&wc, str, len, &state);
+
+ if (mblength == (size_t)-1 || mblength == (size_t)-2)
+ {
+ *length = 1;
+ return 0;
+ }
+
+ *length = (mblength < 1) ? 1 : mblength;
+ return iswblank (wc);
+}
+#endif
+
+/* Clean up any remaining temporary files. */
+
+static void
+cleanup (void)
+{
+ struct tempnode const *node;
+
+ for (node = temphead; node; node = node->next)
+ unlink (node->name);
+}
+
+/* Report MESSAGE for FILE, then clean up and exit.
+ If FILE is null, it represents standard output. */
+
+static void die (char const *, char const *) ATTRIBUTE_NORETURN;
+static void
+die (char const *message, char const *file)
+{
+ error (0, errno, "%s: %s", message, file ? file : _("standard output"));
+ exit (SORT_FAILURE);
+}
+
+/* Create a new temporary file, returning its newly allocated name.
+ Store into *PFP a stream open for writing. */
+
+static char *
+create_temp_file (FILE **pfp)
+{
+ static char const slashbase[] = "/sortXXXXXX";
+ static size_t temp_dir_index;
+ sigset_t oldset;
+ int fd;
+ int saved_errno;
+ char const *temp_dir = temp_dirs[temp_dir_index];
+ size_t len = strlen (temp_dir);
+ struct tempnode *node =
+ xmalloc (sizeof node->next + len + sizeof slashbase);
+ char *file = node->name;
+
+ memcpy (file, temp_dir, len);
+ memcpy (file + len, slashbase, sizeof slashbase);
+ node->next = temphead;
+ if (++temp_dir_index == temp_dir_count)
+ temp_dir_index = 0;
+
+ /* Create the temporary file in a critical section, to avoid races. */
+ sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
+ fd = mkstemp (file);
+ if (0 <= fd)
+ temphead = node;
+ saved_errno = errno;
+ sigprocmask (SIG_SETMASK, &oldset, NULL);
+ errno = saved_errno;
+
+ if (fd < 0 || (*pfp = fdopen (fd, "w")) == NULL)
+ die (_("cannot create temporary file"), file);
+
+ return file;
+}
+
+/* Return a stream for FILE, opened with mode HOW. A null FILE means
+ standard output; HOW should be "w". When opening for input, "-"
+ means standard input. To avoid confusion, do not return file
+ descriptors 0, 1, or 2. */
+
+static FILE *
+xfopen (const char *file, const char *how)
+{
+ FILE *fp;
+
+ if (!file)
+ fp = stdout;
+ else if (STREQ (file, "-") && *how == 'r')
+ {
+ have_read_stdin = true;
+ fp = stdin;
+ }
+ else
+ {
+ if ((fp = fopen_safer (file, how)) == NULL)
+ die (_("open failed"), file);
+ }
+
+ return fp;
+}
+
+/* Close FP, whose name is FILE, and report any errors. */
+
+static void
+xfclose (FILE *fp, char const *file)
+{
+ if (fp == stdin)
+ {
+ /* Allow reading stdin from tty more than once. */
+ if (feof (fp))
+ clearerr (fp);
+ }
+ else
+ {
+ if (fclose (fp) != 0)
+ die (_("close failed"), file);
+ }
+}
+
+static void
+write_bytes (const char *buf, size_t n_bytes, FILE *fp, const char *output_file)
+{
+ if (fwrite (buf, 1, n_bytes, fp) != n_bytes)
+ die (_("write failed"), output_file);
+}
+
+/* Append DIR to the array of temporary directory names. */
+static void
+add_temp_dir (char const *dir)
+{
+ if (temp_dir_count == temp_dir_alloc)
+ temp_dirs = x2nrealloc (temp_dirs, &temp_dir_alloc, sizeof *temp_dirs);
+
+ temp_dirs[temp_dir_count++] = dir;
+}
+
+/* Search through the list of temporary files for NAME;
+ remove it if it is found on the list. */
+
+static void
+zaptemp (const char *name)
+{
+ struct tempnode *volatile *pnode;
+ struct tempnode *node;
+
+ for (pnode = &temphead; (node = *pnode); pnode = &node->next)
+ if (node->name == name)
+ {
+ unlink (name);
+ *pnode = node->next;
+ free (node);
+ break;
+ }
+}
+
+#if HAVE_LANGINFO_CODESET
+
+static int
+struct_month_cmp (const void *m1, const void *m2)
+{
+ struct month const *month1 = m1;
+ struct month const *month2 = m2;
+ return strcmp (month1->name, month2->name);
+}
+
+#endif
+
+/* Initialize the character class tables. */
+
+static void
+inittables_uni (void)
+{
+ int i;
+
+ for (i = 0; i < UCHAR_LIM; ++i)
+ {
+ blanks[i] = !!ISBLANK (i);
+ nonprinting[i] = !ISPRINT (i);
+ nondictionary[i] = !ISALNUM (i) && !ISBLANK (i);
+ fold_toupper[i] = (ISLOWER (i) ? toupper (i) : i);
+ }
+
+#if HAVE_NL_LANGINFO
+ /* If we're not in the "C" locale, read different names for months. */
+ if (hard_LC_TIME)
+ {
+ for (i = 0; i < MONTHS_PER_YEAR; i++)
+ {
+ char const *s;
+ size_t s_len;
+ size_t j;
+ char *name;
+
+ s = (char *) nl_langinfo (ABMON_1 + i);
+ s_len = strlen (s);
+ monthtab[i].name = name = xmalloc (s_len + 1);
+ monthtab[i].val = i + 1;
+
+ for (j = 0; j < s_len; j++)
+ name[j] = fold_toupper[to_uchar (s[j])];
+ name[j] = '\0';
+ }
+ qsort ((void *) monthtab, MONTHS_PER_YEAR,
+ sizeof *monthtab, struct_month_cmp);
+ }
+#endif
+}
+
+#if HAVE_MBRTOWC
+static void
+inittables_mb (void)
+{
+ int i, j, k, l;
+ char *name, *s;
+ size_t s_len, mblength;
+ char mbc[MB_LEN_MAX];
+ wchar_t wc, pwc;
+ mbstate_t state_mb, state_wc;
+
+ for (i = 0; i < MONTHS_PER_YEAR; i++)
+ {
+ s = (char *) nl_langinfo (ABMON_1 + i);
+ s_len = strlen (s);
+ monthtab[i].name = name = (char *) xmalloc (s_len + 1);
+ monthtab[i].val = i + 1;
+
+ memset (&state_mb, '\0', sizeof (mbstate_t));
+ memset (&state_wc, '\0', sizeof (mbstate_t));
+
+ for (j = 0; j < s_len;)
+ {
+ if (!ismbblank (s + j, s_len - j, &mblength))
+ break;
+ j += mblength;
+ }
+
+ for (k = 0; j < s_len;)
+ {
+ mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb);
+ assert (mblength != (size_t)-1 && mblength != (size_t)-2);
+ if (mblength == 0)
+ break;
+
+ pwc = towupper (wc);
+ if (pwc == wc)
+ {
+ memcpy (mbc, s + j, mblength);
+ j += mblength;
+ }
+ else
+ {
+ j += mblength;
+ mblength = wcrtomb (mbc, pwc, &state_wc);
+ assert (mblength != (size_t)0 && mblength != (size_t)-1);
+ }
+
+ for (l = 0; l < mblength; l++)
+ name[k++] = mbc[l];
+ }
+ name[k] = '\0';
+ }
+ qsort ((void *) monthtab, MONTHS_PER_YEAR,
+ sizeof (struct month), struct_month_cmp);
+}
+#endif
+
+/* Specify the amount of main memory to use when sorting. */
+static void
+specify_sort_size (char const *s)
+{
+ uintmax_t n;
+ char *suffix;
+ enum strtol_error e = xstrtoumax (s, &suffix, 10, &n, "EgGkKmMPtTYZ");
+
+ /* The default unit is KiB. */
+ if (e == LONGINT_OK && ISDIGIT (suffix[-1]))
+ {
+ if (n <= UINTMAX_MAX / 1024)
+ n *= 1024;
+ else
+ e = LONGINT_OVERFLOW;
+ }
+
+ /* A 'b' suffix means bytes; a '%' suffix means percent of memory. */
+ if (e == LONGINT_INVALID_SUFFIX_CHAR && ISDIGIT (suffix[-1]) && ! suffix[1])
+ switch (suffix[0])
+ {
+ case 'b':
+ e = LONGINT_OK;
+ break;
+
+ case '%':
+ {
+ double mem = physmem_total () * n / 100;
+
+ /* Use "<", not "<=", to avoid problems with rounding. */
+ if (mem < UINTMAX_MAX)
+ {
+ n = mem;
+ e = LONGINT_OK;
+ }
+ else
+ e = LONGINT_OVERFLOW;
+ }
+ break;
+ }
+
+ if (e == LONGINT_OK)
+ {
+ /* If multiple sort sizes are specified, take the maximum, so
+ that option order does not matter. */
+ if (n < sort_size)
+ return;
+
+ sort_size = n;
+ if (sort_size == n)
+ {
+ sort_size = MAX (sort_size, MIN_SORT_SIZE);
+ return;
+ }
+
+ e = LONGINT_OVERFLOW;
+ }
+
+ STRTOL_FATAL_ERROR (s, _("sort size"), e);
+}
+
+/* Return the default sort size. */
+static size_t
+default_sort_size (void)
+{
+ /* Let MEM be available memory or 1/8 of total memory, whichever
+ is greater. */
+ double avail = physmem_available ();
+ double total = physmem_total ();
+ double mem = MAX (avail, total / 8);
+ struct rlimit rlimit;
+
+ /* Let SIZE be MEM, but no more than the maximum object size or
+ system resource limits. Avoid the MIN macro here, as it is not
+ quite right when only one argument is floating point. Don't
+ bother to check for values like RLIM_INFINITY since in practice
+ they are not much less than SIZE_MAX. */
+ size_t size = SIZE_MAX;
+ if (mem < size)
+ size = mem;
+ if (getrlimit (RLIMIT_DATA, &rlimit) == 0 && rlimit.rlim_cur < size)
+ size = rlimit.rlim_cur;
+#ifdef RLIMIT_AS
+ if (getrlimit (RLIMIT_AS, &rlimit) == 0 && rlimit.rlim_cur < size)
+ size = rlimit.rlim_cur;
+#endif
+
+ /* Leave a large safety margin for the above limits, as failure can
+ occur when they are exceeded. */
+ size /= 2;
+
+#ifdef RLIMIT_RSS
+ /* Leave a 1/16 margin for RSS to leave room for code, stack, etc.
+ Exceeding RSS is not fatal, but can be quite slow. */
+ if (getrlimit (RLIMIT_RSS, &rlimit) == 0 && rlimit.rlim_cur / 16 * 15 < size)
+ size = rlimit.rlim_cur / 16 * 15;
+#endif
+
+ /* Use no less than the minimum. */
+ return MAX (size, MIN_SORT_SIZE);
+}
+
+/* Return the sort buffer size to use with the input files identified
+ by FPS and FILES, which are alternate paths to the same files.
+ NFILES gives the number of input files; NFPS may be less. Assume
+ that each input line requires LINE_BYTES extra bytes' worth of line
+ information. Do not exceed a bound on the size: if the bound is
+ not specified by the user, use a default. */
+
+static size_t
+sort_buffer_size (FILE *const *fps, int nfps,
+ char *const *files, int nfiles,
+ size_t line_bytes)
+{
+ /* A bound on the input size. If zero, the bound hasn't been
+ determined yet. */
+ static size_t size_bound;
+
+ /* In the worst case, each input byte is a newline. */
+ size_t worst_case_per_input_byte = line_bytes + 1;
+
+ /* Keep enough room for one extra input line and an extra byte.
+ This extra room might be needed when preparing to read EOF. */
+ size_t size = worst_case_per_input_byte + 1;
+
+ int i;
+
+ for (i = 0; i < nfiles; i++)
+ {
+ struct stat st;
+ off_t file_size;
+ size_t worst_case;
+
+ if ((i < nfps ? fstat (fileno (fps[i]), &st)
+ : STREQ (files[i], "-") ? fstat (STDIN_FILENO, &st)
+ : stat (files[i], &st))
+ != 0)
+ die (_("stat failed"), files[i]);
+
+ if (S_ISREG (st.st_mode))
+ file_size = st.st_size;
+ else
+ {
+ /* The file has unknown size. If the user specified a sort
+ buffer size, use that; otherwise, guess the size. */
+ if (sort_size)
+ return sort_size;
+ file_size = INPUT_FILE_SIZE_GUESS;
+ }
+
+ if (! size_bound)
+ {
+ size_bound = sort_size;
+ if (! size_bound)
+ size_bound = default_sort_size ();
+ }
+
+ /* Add the amount of memory needed to represent the worst case
+ where the input consists entirely of newlines followed by a
+ single non-newline. Check for overflow. */
+ worst_case = file_size * worst_case_per_input_byte + 1;
+ if (file_size != worst_case / worst_case_per_input_byte
+ || size_bound - size <= worst_case)
+ return size_bound;
+ size += worst_case;
+ }
+
+ return size;
+}
+
+/* Initialize BUF. Reserve LINE_BYTES bytes for each line; LINE_BYTES
+ must be at least sizeof (struct line). Allocate ALLOC bytes
+ initially. */
+
+static void
+initbuf (struct buffer *buf, size_t line_bytes, size_t alloc)
+{
+ /* Ensure that the line array is properly aligned. If the desired
+ size cannot be allocated, repeatedly halve it until allocation
+ succeeds. The smaller allocation may hurt overall performance,
+ but that's better than failing. */
+ for (;;)
+ {
+ alloc += sizeof (struct line) - alloc % sizeof (struct line);
+ buf->buf = malloc (alloc);
+ if (buf->buf)
+ break;
+ alloc /= 2;
+ if (alloc <= line_bytes + 1)
+ xalloc_die ();
+ }
+
+ buf->line_bytes = line_bytes;
+ buf->alloc = alloc;
+ buf->used = buf->left = buf->nlines = 0;
+ buf->eof = false;
+}
+
+/* Return one past the limit of the line array. */
+
+static inline struct line *
+buffer_linelim (struct buffer const *buf)
+{
+ return (struct line *) (buf->buf + buf->alloc);
+}
+
+/* Return a pointer to the first character of the field specified
+ by KEY in LINE. */
+
+static char *
+begfield_uni (const struct line *line, const struct keyfield *key)
+{
+ register char *ptr = line->text, *lim = ptr + line->length - 1;
+ register size_t sword = key->sword;
+ register size_t schar = key->schar;
+ register size_t remaining_bytes;
+
+ /* The leading field separator itself is included in a field when -t
+ is absent. */
+
+ if (!tab_default)
+ while (ptr < lim && sword--)
+ {
+ while (ptr < lim && *ptr != tab[0])
+ ++ptr;
+ if (ptr < lim)
+ ++ptr;
+ }
+ else
+ while (ptr < lim && sword--)
+ {
+ while (ptr < lim && blanks[to_uchar (*ptr)])
+ ++ptr;
+ while (ptr < lim && !blanks[to_uchar (*ptr)])
+ ++ptr;
+ }
+
+ if (key->skipsblanks)
+ while (ptr < lim && blanks[to_uchar (*ptr)])
+ ++ptr;
+
+ /* Advance PTR by SCHAR (if possible), but no further than LIM. */
+ remaining_bytes = lim - ptr;
+ if (schar < remaining_bytes)
+ ptr += schar;
+ else
+ ptr = lim;
+
+ return ptr;
+}
+
+#if HAVE_MBRTOWC
+static char *
+begfield_mb (const struct line *line, const struct keyfield *key)
+{
+ int i;
+ char *ptr = line->text, *lim = ptr + line->length - 1;
+ size_t sword = key->sword;
+ size_t schar = key->schar;
+ size_t mblength;
+ mbstate_t state;
+
+ memset (&state, '\0', sizeof(mbstate_t));
+
+ if (!tab_default)
+ while (ptr < lim && sword--)
+ {
+ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0)
+ {
+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
+ ptr += mblength;
+ }
+ if (ptr < lim)
+ {
+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
+ ptr += mblength;
+ }
+ }
+ else
+ while (ptr < lim && sword--)
+ {
+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
+ ptr += mblength;
+ if (ptr < lim)
+ {
+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
+ ptr += mblength;
+ }
+ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength))
+ ptr += mblength;
+ }
+
+ if (key->skipsblanks)
+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
+ ptr += mblength;
+
+ for (i = 0; i < schar; i++)
+ {
+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
+
+ if (ptr + mblength > lim)
+ break;
+ else
+ ptr += mblength;
+ }
+
+ return ptr;
+}
+#endif
+
+/* Return the limit of (a pointer to the first character after) the field
+ in LINE specified by KEY. */
+
+static char *
+limfield_uni (const struct line *line, const struct keyfield *key)
+{
+ register char *ptr = line->text, *lim = ptr + line->length - 1;
+ register size_t eword = key->eword, echar = key->echar;
+ register size_t remaining_bytes;
+
+ /* Move PTR past EWORD fields or to one past the last byte on LINE,
+ whichever comes first. If there are more than EWORD fields, leave
+ PTR pointing at the beginning of the field having zero-based index,
+ EWORD. If a delimiter character was specified (via -t), then that
+ `beginning' is the first character following the delimiting TAB.
+ Otherwise, leave PTR pointing at the first `blank' character after
+ the preceding field. */
+ if (!tab_default)
+ while (ptr < lim && eword--)
+ {
+ while (ptr < lim && *ptr != tab[0])
+ ++ptr;
+ if (ptr < lim && (eword | echar))
+ ++ptr;
+ }
+ else
+ while (ptr < lim && eword--)
+ {
+ while (ptr < lim && blanks[to_uchar (*ptr)])
+ ++ptr;
+ while (ptr < lim && !blanks[to_uchar (*ptr)])
+ ++ptr;
+ }
+
+#ifdef POSIX_UNSPECIFIED
+ /* The following block of code makes GNU sort incompatible with
+ standard Unix sort, so it's ifdef'd out for now.
+ The POSIX spec isn't clear on how to interpret this.
+ FIXME: request clarification.
+
+ From: kwzh@gnu.ai.mit.edu (Karl Heuer)
+ Date: Thu, 30 May 96 12:20:41 -0400
+ [Translated to POSIX 1003.1-2001 terminology by Paul Eggert.]
+
+ [...]I believe I've found another bug in `sort'.
+
+ $ cat /tmp/sort.in
+ a b c 2 d
+ pq rs 1 t
+ $ textutils-1.15/src/sort -k1.7,1.7 </tmp/sort.in
+ a b c 2 d
+ pq rs 1 t
+ $ /bin/sort -k1.7,1.7 </tmp/sort.in
+ pq rs 1 t
+ a b c 2 d
+
+ Unix sort produced the answer I expected: sort on the single character
+ in column 7. GNU sort produced different results, because it disagrees
+ on the interpretation of the key-end spec "M.N". Unix sort reads this
+ as "skip M-1 fields, then N-1 characters"; but GNU sort wants it to mean
+ "skip M-1 fields, then either N-1 characters or the rest of the current
+ field, whichever comes first". This extra clause applies only to
+ key-ends, not key-starts.
+ */
+
+ /* Make LIM point to the end of (one byte past) the current field. */
+ if (!tab_default)
+ {
+ char *newlim;
+ newlim = memchr (ptr, tab[0], lim - ptr);
+ if (newlim)
+ lim = newlim;
+ }
+ else
+ {
+ char *newlim;
+ newlim = ptr;
+ while (newlim < lim && blanks[to_uchar (*newlim)])
+ ++newlim;
+ while (newlim < lim && !blanks[to_uchar (*newlim)])
+ ++newlim;
+ lim = newlim;
+ }
+#endif
+
+ /* If we're ignoring leading blanks when computing the End
+ of the field, don't start counting bytes until after skipping
+ past any leading blanks. */
+ if (key->skipeblanks)
+ while (ptr < lim && blanks[to_uchar (*ptr)])
+ ++ptr;
+
+ /* Advance PTR by ECHAR (if possible), but no further than LIM. */
+ remaining_bytes = lim - ptr;
+ if (echar < remaining_bytes)
+ ptr += echar;
+ else
+ ptr = lim;
+
+ return ptr;
+}
+
+#if HAVE_MBRTOWC
+static char *
+limfield_mb (const struct line *line, const struct keyfield *key)
+{
+ char *ptr = line->text, *lim = ptr + line->length - 1;
+ size_t eword = key->eword, echar = key->echar;
+ int i;
+ size_t mblength;
+ mbstate_t state;
+
+ memset (&state, '\0', sizeof(mbstate_t));
+
+ if (!tab_default)
+ while (ptr < lim && eword--)
+ {
+ while (ptr < lim && memcmp (ptr, tab, tab_length) != 0)
+ {
+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
+ ptr += mblength;
+ }
+ if (ptr < lim && (eword | echar))
+ {
+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
+ ptr += mblength;
+ }
+ }
+ else
+ while (ptr < lim && eword--)
+ {
+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
+ ptr += mblength;
+ if (ptr < lim)
+ {
+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
+ ptr += mblength;
+ }
+ while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength))
+ ptr += mblength;
+ }
+
+
+# ifdef POSIX_UNSPECIFIED
+ /* Make LIM point to the end of (one byte past) the current field. */
+ if (!tab_default)
+ {
+ char *newlim, *p;
+
+ newlim = NULL;
+ for (p = ptr; p < lim;)
+ {
+ if (memcmp (p, tab, tab_length) == 0)
+ {
+ newlim = p;
+ break;
+ }
+
+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
+ p += mblength;
+ }
+ }
+ else
+ {
+ char *newlim;
+ newlim = ptr;
+
+ while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength))
+ newlim += mblength;
+ if (ptr < lim)
+ {
+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
+ ptr += mblength;
+ }
+ while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength))
+ newlim += mblength;
+ lim = newlim;
+ }
+# endif
+
+ /* If we're skipping leading blanks, don't start counting characters
+ * until after skipping past any leading blanks. */
+ if (key->skipeblanks)
+ while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
+ ptr += mblength;
+
+ memset (&state, '\0', sizeof(mbstate_t));
+
+ /* Advance PTR by ECHAR (if possible), but no further than LIM. */
+ for (i = 0; i < echar; i++)
+ {
+ GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
+
+ if (ptr + mblength > lim)
+ break;
+ else
+ ptr += mblength;
+ }
+
+ return ptr;
+}
+#endif
+
+/* Fill BUF reading from FP, moving buf->left bytes from the end
+ of buf->buf to the beginning first. If EOF is reached and the
+ file wasn't terminated by a newline, supply one. Set up BUF's line
+ table too. FILE is the name of the file corresponding to FP.
+ Return true if some input was read. */
+
+static bool
+fillbuf (struct buffer *buf, register FILE *fp, char const *file)
+{
+ struct keyfield const *key = keylist;
+ char eol = eolchar;
+ size_t line_bytes = buf->line_bytes;
+ size_t mergesize = merge_buffer_size - MIN_MERGE_BUFFER_SIZE;
+
+ if (buf->eof)
+ return false;
+
+ if (buf->used != buf->left)
+ {
+ memmove (buf->buf, buf->buf + buf->used - buf->left, buf->left);
+ buf->used = buf->left;
+ buf->nlines = 0;
+ }
+
+ for (;;)
+ {
+ char *ptr = buf->buf + buf->used;
+ struct line *linelim = buffer_linelim (buf);
+ struct line *line = linelim - buf->nlines;
+ size_t avail = (char *) linelim - buf->nlines * line_bytes - ptr;
+ char *line_start = buf->nlines ? line->text + line->length : buf->buf;
+
+ while (line_bytes + 1 < avail)
+ {
+ /* Read as many bytes as possible, but do not read so many
+ bytes that there might not be enough room for the
+ corresponding line array. The worst case is when the
+ rest of the input file consists entirely of newlines,
+ except that the last byte is not a newline. */
+ size_t readsize = (avail - 1) / (line_bytes + 1);
+ size_t bytes_read = fread (ptr, 1, readsize, fp);
+ char *ptrlim = ptr + bytes_read;
+ char *p;
+ avail -= bytes_read;
+
+ if (bytes_read != readsize)
+ {
+ if (ferror (fp))
+ die (_("read failed"), file);
+ if (feof (fp))
+ {
+ buf->eof = true;
+ if (buf->buf == ptrlim)
+ return false;
+ if (ptrlim[-1] != eol)
+ *ptrlim++ = eol;
+ }
+ }
+
+ /* Find and record each line in the just-read input. */
+ while ((p = memchr (ptr, eol, ptrlim - ptr)))
+ {
+ ptr = p + 1;
+ line--;
+ line->text = line_start;
+ line->length = ptr - line_start;
+ mergesize = MAX (mergesize, line->length);
+ avail -= line_bytes;
+
+ if (key)
+ {
+ /* Precompute the position of the first key for
+ efficiency. */
+ line->keylim = (key->eword == SIZE_MAX
+ ? p
+ : limfield (line, key));
+
+ if (key->sword != SIZE_MAX)
+ line->keybeg = begfield (line, key);
+ else
+ {
+ if (key->skipsblanks)
+#if HAVE_MBRTOWC
+ {
+ if (MB_CUR_MAX > 1)
+ {
+ size_t mblength;
+
+ while (ismbblank (line_start, ptr - line_start, &mblength))
+ line_start += mblength;
+ }
+ else
+#endif
+ {
+ while (blanks[to_uchar (*line_start)])
+ line_start++;
+ }
+ }
+ line->keybeg = line_start;
+ }
+ }
+
+ line_start = ptr;
+ }
+
+ ptr = ptrlim;
+ if (buf->eof)
+ break;
+ }
+
+ buf->used = ptr - buf->buf;
+ buf->nlines = buffer_linelim (buf) - line;
+ if (buf->nlines != 0)
+ {
+ buf->left = ptr - line_start;
+ merge_buffer_size = mergesize + MIN_MERGE_BUFFER_SIZE;
+ return true;
+ }
+
+ /* The current input line is too long to fit in the buffer.
+ Double the buffer size and try again. */
+ buf->buf = x2nrealloc (buf->buf, &buf->alloc, sizeof *(buf->buf));
+ }
+}
+
+/* Compare strings A and B containing decimal fractions < 1. Each string
+ should begin with a decimal point followed immediately by the digits
+ of the fraction. Strings not of this form are considered to be zero. */
+
+/* The goal here, is to take two numbers a and b... compare these
+ in parallel. Instead of converting each, and then comparing the
+ outcome. Most likely stopping the comparison before the conversion
+ is complete. The algorithm used, in the old sort:
+
+ Algorithm: fraccompare
+ Action : compare two decimal fractions
+ accepts : char *a, char *b
+ returns : -1 if a<b, 0 if a=b, 1 if a>b.
+ implement:
+
+ if *a == decimal_point AND *b == decimal_point
+ find first character different in a and b.
+ if both are digits, return the difference *a - *b.
+ if *a is a digit
+ skip past zeros
+ if digit return 1, else 0
+ if *b is a digit
+ skip past zeros
+ if digit return -1, else 0
+ if *a is a decimal_point
+ skip past decimal_point and zeros
+ if digit return 1, else 0
+ if *b is a decimal_point
+ skip past decimal_point and zeros
+ if digit return -1, else 0
+ return 0 */
+
+static int
+fraccompare (register const char *a, register const char *b)
+{
+ if (*a == decimal_point && *b == decimal_point)
+ {
+ while (*++a == *++b)
+ if (! ISDIGIT (*a))
+ return 0;
+ if (ISDIGIT (*a) && ISDIGIT (*b))
+ return *a - *b;
+ if (ISDIGIT (*a))
+ goto a_trailing_nonzero;
+ if (ISDIGIT (*b))
+ goto b_trailing_nonzero;
+ return 0;
+ }
+ else if (*a++ == decimal_point)
+ {
+ a_trailing_nonzero:
+ while (*a == NUMERIC_ZERO)
+ a++;
+ return ISDIGIT (*a);
+ }
+ else if (*b++ == decimal_point)
+ {
+ b_trailing_nonzero:
+ while (*b == NUMERIC_ZERO)
+ b++;
+ return - ISDIGIT (*b);
+ }
+ return 0;
+}
+
+/* Compare strings A and B as numbers without explicitly converting them to
+ machine numbers. Comparatively slow for short strings, but asymptotically
+ hideously fast. */
+
+static int
+numcompare (register const char *a, register const char *b)
+{
+ char tmpa;
+ char tmpb;
+ int tmp;
+ size_t log_a;
+ size_t log_b;
+
+#if HAVE_MBRTOWC
+ if (MB_CUR_MAX > 1)
+ {
+ size_t mblength;
+ size_t alen = strnlen (a, MB_LEN_MAX);
+ size_t blen = strnlen (b, MB_LEN_MAX);
+
+ while (ismbblank (a, alen, &mblength))
+ a += mblength, alen -= mblength;
+ while (ismbblank (b, blen, &mblength))
+ b += mblength, blen -= mblength;
+
+ tmpa = *a;
+ tmpb = *b;
+ }
+ else
+#endif
+ {
+ tmpa = *a;
+ tmpb = *b;
+
+ while (blanks[to_uchar (tmpa)])
+ tmpa = *++a;
+ while (blanks[to_uchar (tmpb)])
+ tmpb = *++b;
+ }
+
+ if (tmpa == NEGATION_SIGN)
+ {
+ do
+ tmpa = *++a;
+ while (tmpa == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpa));
+ if (tmpb != NEGATION_SIGN)
+ {
+ if (tmpa == decimal_point)
+ do
+ tmpa = *++a;
+ while (tmpa == NUMERIC_ZERO);
+ if (ISDIGIT (tmpa))
+ return -1;
+ while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb))
+ tmpb = *++b;
+ if (tmpb == decimal_point)
+ do
+ tmpb = *++b;
+ while (tmpb == NUMERIC_ZERO);
+ if (ISDIGIT (tmpb))
+ return -1;
+ return 0;
+ }
+ do
+ tmpb = *++b;
+ while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb));
+
+ while (tmpa == tmpb && ISDIGIT (tmpa))
+ {
+ do
+ tmpa = *++a;
+ while (IS_THOUSANDS_SEP (tmpa));
+ do
+ tmpb = *++b;
+ while (IS_THOUSANDS_SEP (tmpb));
+ }
+
+ if ((tmpa == decimal_point && !ISDIGIT (tmpb))
+ || (tmpb == decimal_point && !ISDIGIT (tmpa)))
+ return -fraccompare (a, b);
+
+ tmp = tmpb - tmpa;
+
+ for (log_a = 0; ISDIGIT (tmpa); ++log_a)
+ do
+ tmpa = *++a;
+ while (IS_THOUSANDS_SEP (tmpa));
+
+ for (log_b = 0; ISDIGIT (tmpb); ++log_b)
+ do
+ tmpb = *++b;
+ while (IS_THOUSANDS_SEP (tmpb));
+
+ if (log_a != log_b)
+ return log_a < log_b ? 1 : -1;
+
+ if (!log_a)
+ return 0;
+
+ return tmp;
+ }
+ else if (tmpb == NEGATION_SIGN)
+ {
+ do
+ tmpb = *++b;
+ while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb));
+ if (tmpb == decimal_point)
+ do
+ tmpb = *++b;
+ while (tmpb == NUMERIC_ZERO);
+ if (ISDIGIT (tmpb))
+ return 1;
+ while (tmpa == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpa))
+ tmpa = *++a;
+ if (tmpa == decimal_point)
+ do
+ tmpa = *++a;
+ while (tmpa == NUMERIC_ZERO);
+ if (ISDIGIT (tmpa))
+ return 1;
+ return 0;
+ }
+ else
+ {
+ while (tmpa == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpa))
+ tmpa = *++a;
+ while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb))
+ tmpb = *++b;
+
+ while (tmpa == tmpb && ISDIGIT (tmpa))
+ {
+ do
+ tmpa = *++a;
+ while (IS_THOUSANDS_SEP (tmpa));
+ do
+ tmpb = *++b;
+ while (IS_THOUSANDS_SEP (tmpb));
+ }
+
+ if ((tmpa == decimal_point && !ISDIGIT (tmpb))
+ || (tmpb == decimal_point && !ISDIGIT (tmpa)))
+ return fraccompare (a, b);
+
+ tmp = tmpa - tmpb;
+
+ for (log_a = 0; ISDIGIT (tmpa); ++log_a)
+ do
+ tmpa = *++a;
+ while (IS_THOUSANDS_SEP (tmpa));
+
+ for (log_b = 0; ISDIGIT (tmpb); ++log_b)
+ do
+ tmpb = *++b;
+ while (IS_THOUSANDS_SEP (tmpb));
+
+ if (log_a != log_b)
+ return log_a < log_b ? -1 : 1;
+
+ if (!log_a)
+ return 0;
+
+ return tmp;
+ }
+}
+
+static int
+general_numcompare (const char *sa, const char *sb)
+{
+ /* FIXME: add option to warn about failed conversions. */
+ /* FIXME: maybe add option to try expensive FP conversion
+ only if A and B can't be compared more cheaply/accurately. */
+
+ char *bufa, *ea;
+ char *bufb, *eb;
+ double a;
+ double b;
+
+ char *p;
+ struct lconv *lconvp = localeconv ();
+ size_t thousands_sep_len = strlen (lconvp->thousands_sep);
+
+ bufa = (char *) xmalloc (strlen (sa) + 1);
+ bufb = (char *) xmalloc (strlen (sb) + 1);
+ strcpy (bufa, sa);
+ strcpy (bufb, sb);
+
+ if (force_general_numcompare)
+ {
+ while (1)
+ {
+ a = strtod (bufa, &ea);
+ if (memcmp (ea, lconvp->thousands_sep, thousands_sep_len) == 0)
+ {
+ for (p = ea; *(p + thousands_sep_len) != '\0'; p++)
+ *p = *(p + thousands_sep_len);
+ *p = '\0';
+ continue;
+ }
+ break;
+ }
+
+ while (1)
+ {
+ b = strtod (bufb, &eb);
+ if (memcmp (eb, lconvp->thousands_sep, thousands_sep_len) == 0)
+ {
+ for (p = eb; *(p + thousands_sep_len) != '\0'; p++)
+ *p = *(p + thousands_sep_len);
+ *p = '\0';
+ continue;
+ }
+ break;
+ }
+ }
+ else
+ {
+ a = strtod (bufa, &ea);
+ b = strtod (bufb, &eb);
+ }
+
+ /* Put conversion errors at the start of the collating sequence. */
+ free (bufa);
+ free (bufb);
+ if (bufa == ea)
+ return bufb == eb ? 0 : -1;
+ if (bufb == eb)
+ return 1;
+
+ /* Sort numbers in the usual way, where -0 == +0. Put NaNs after
+ conversion errors but before numbers; sort them by internal
+ bit-pattern, for lack of a more portable alternative. */
+ return (a < b ? -1
+ : a > b ? 1
+ : a == b ? 0
+ : b == b ? -1
+ : a == a ? 1
+ : memcmp ((char *) &a, (char *) &b, sizeof a));
+}
+
+/* Return an integer in 1..12 of the month name S with length LEN.
+ Return 0 if the name in S is not recognized. */
+
+static int
+getmonth_uni (const char *s, size_t len)
+{
+ char *month;
+ register size_t i;
+ register int lo = 0, hi = MONTHS_PER_YEAR, result;
+
+ while (len > 0 && blanks[to_uchar (*s)])
+ {
+ ++s;
+ --len;
+ }
+
+ if (len == 0)
+ return 0;
+
+ month = alloca (len + 1);
+ for (i = 0; i < len; ++i)
+ month[i] = fold_toupper[to_uchar (s[i])];
+ month[len] = '\0';
+
+ do
+ {
+ int ix = (lo + hi) / 2;
+
+ if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0)
+ hi = ix;
+ else
+ lo = ix;
+ }
+ while (hi - lo > 1);
+
+ result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name))
+ ? monthtab[lo].val : 0);
+
+ return result;
+}
+
+#if HAVE_MBRTOWC
+static int
+getmonth_mb (const char *s, size_t len)
+{
+ char *month;
+ register size_t i;
+ register int lo = 0, hi = MONTHS_PER_YEAR, result;
+ char *tmp;
+ size_t wclength, mblength;
+ const char **pp;
+ const wchar_t **wpp;
+ wchar_t *month_wcs;
+ mbstate_t state;
+
+ while (len > 0 && ismbblank (s, len, &mblength))
+ {
+ s += mblength;
+ len -= mblength;
+ }
+
+ if (len == 0)
+ return 0;
+
+ month = (char *) alloca (len + 1);
+
+ tmp = (char *) alloca (len + 1);
+ memcpy (tmp, s, len);
+ tmp[len] = '\0';
+ pp = (const char **)&tmp;
+ month_wcs = (wchar_t *) alloca ((len + 1) * sizeof (wchar_t));
+ memset (&state, '\0', sizeof(mbstate_t));
+
+ wclength = mbsrtowcs (month_wcs, pp, len + 1, &state);
+ assert (wclength != (size_t)-1 && *pp == NULL);
+
+ for (i = 0; i < wclength; i++)
+ month_wcs[i] = towupper(month_wcs[i]);
+ month_wcs[i] = L'\0';
+
+ wpp = (const wchar_t **)&month_wcs;
+
+ mblength = wcsrtombs (month, wpp, len + 1, &state);
+ assert (mblength != (-1) && *wpp == NULL);
+
+ do
+ {
+ int ix = (lo + hi) / 2;
+
+ if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0)
+ hi = ix;
+ else
+ lo = ix;
+ }
+ while (hi - lo > 1);
+
+ result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name))
+ ? monthtab[lo].val : 0);
+
+ return result;
+}
+#endif
+
+/* Compare two lines A and B trying every key in sequence until there
+ are no more keys or a difference is found. */
+
+static int
+keycompare_uni (const struct line *a, const struct line *b)
+{
+ struct keyfield const *key = keylist;
+
+ /* For the first iteration only, the key positions have been
+ precomputed for us. */
+ register char *texta = a->keybeg;
+ register char *textb = b->keybeg;
+ register char *lima = a->keylim;
+ register char *limb = b->keylim;
+
+ int diff;
+
+ for (;;)
+ {
+ register char const *translate = key->translate;
+ register bool const *ignore = key->ignore;
+
+ /* Find the lengths. */
+ size_t lena = lima <= texta ? 0 : lima - texta;
+ size_t lenb = limb <= textb ? 0 : limb - textb;
+
+ /* Actually compare the fields. */
+ if (key->numeric | key->general_numeric)
+ {
+ char savea = *lima, saveb = *limb;
+
+ *lima = *limb = '\0';
+ diff = ((key->numeric ? numcompare : general_numcompare)
+ (texta, textb));
+ *lima = savea, *limb = saveb;
+ }
+ else if (key->month)
+ diff = getmonth (texta, lena) - getmonth (textb, lenb);
+ /* Sorting like this may become slow, so in a simple locale the user
+ can select a faster sort that is similar to ascii sort */
+ else if (HAVE_SETLOCALE && hard_LC_COLLATE)
+ {
+ if (ignore || translate)
+ {
+ char *copy_a = alloca (lena + 1 + lenb + 1);
+ char *copy_b = copy_a + lena + 1;
+ size_t new_len_a, new_len_b, i;
+
+ /* Ignore and/or translate chars before comparing. */
+ for (new_len_a = new_len_b = i = 0; i < MAX (lena, lenb); i++)
+ {
+ if (i < lena)
+ {
+ copy_a[new_len_a] = (translate
+ ? translate[to_uchar (texta[i])]
+ : texta[i]);
+ if (!ignore || !ignore[to_uchar (texta[i])])
+ ++new_len_a;
+ }
+ if (i < lenb)
+ {
+ copy_b[new_len_b] = (translate
+ ? translate[to_uchar (textb[i])]
+ : textb [i]);
+ if (!ignore || !ignore[to_uchar (textb[i])])
+ ++new_len_b;
+ }
+ }
+
+ diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b);
+ }
+ else if (lena == 0)
+ diff = - NONZERO (lenb);
+ else if (lenb == 0)
+ goto greater;
+ else
+ diff = xmemcoll (texta, lena, textb, lenb);
+ }
+ else if (ignore)
+ {
+#define CMP_WITH_IGNORE(A, B) \
+ do \
+ { \
+ for (;;) \
+ { \
+ while (texta < lima && ignore[to_uchar (*texta)]) \
+ ++texta; \
+ while (textb < limb && ignore[to_uchar (*textb)]) \
+ ++textb; \
+ if (! (texta < lima && textb < limb)) \
+ break; \
+ diff = to_uchar (A) - to_uchar (B); \
+ if (diff) \
+ goto not_equal; \
+ ++texta; \
+ ++textb; \
+ } \
+ \
+ diff = (texta < lima) - (textb < limb); \
+ } \
+ while (0)
+
+ if (translate)
+ CMP_WITH_IGNORE (translate[to_uchar (*texta)],
+ translate[to_uchar (*textb)]);
+ else
+ CMP_WITH_IGNORE (*texta, *textb);
+ }
+ else if (lena == 0)
+ diff = - NONZERO (lenb);
+ else if (lenb == 0)
+ goto greater;
+ else
+ {
+ if (translate)
+ {
+ while (texta < lima && textb < limb)
+ {
+ diff = (to_uchar (translate[to_uchar (*texta++)])
+ - to_uchar (translate[to_uchar (*textb++)]));
+ if (diff)
+ goto not_equal;
+ }
+ }
+ else
+ {
+ diff = memcmp (texta, textb, MIN (lena, lenb));
+ if (diff)
+ goto not_equal;
+ }
+ diff = lena < lenb ? -1 : lena != lenb;
+ }
+
+ if (diff)
+ goto not_equal;
+
+ key = key->next;
+ if (! key)
+ break;
+
+ /* Find the beginning and limit of the next field. */
+ if (key->eword != SIZE_MAX)
+ lima = limfield (a, key), limb = limfield (b, key);
+ else
+ lima = a->text + a->length - 1, limb = b->text + b->length - 1;
+
+ if (key->sword != SIZE_MAX)
+ texta = begfield (a, key), textb = begfield (b, key);
+ else
+ {
+ texta = a->text, textb = b->text;
+ if (key->skipsblanks)
+ {
+ while (texta < lima && blanks[to_uchar (*texta)])
+ ++texta;
+ while (textb < limb && blanks[to_uchar (*textb)])
+ ++textb;
+ }
+ }
+ }
+
+ return 0;
+
+ greater:
+ diff = 1;
+ not_equal:
+ return key->reverse ? -diff : diff;
+}
+
+#if HAVE_MBRTOWC
+static int
+keycompare_mb (const struct line *a, const struct line *b)
+{
+ struct keyfield *key = keylist;
+
+ /* For the first iteration only, the key positions have been
+ precomputed for us. */
+ char *texta = a->keybeg;
+ char *textb = b->keybeg;
+ char *lima = a->keylim;
+ char *limb = b->keylim;
+
+ size_t mblength_a, mblength_b;
+ wchar_t wc_a, wc_b;
+ mbstate_t state_a, state_b;
+
+ int diff;
+
+ memset (&state_a, '\0', sizeof(mbstate_t));
+ memset (&state_b, '\0', sizeof(mbstate_t));
+
+ for (;;)
+ {
+ unsigned char *translate = (unsigned char *) key->translate;
+ bool const *ignore = key->ignore;
+
+ /* Find the lengths. */
+ size_t lena = lima <= texta ? 0 : lima - texta;
+ size_t lenb = limb <= textb ? 0 : limb - textb;
+
+ /* Actually compare the fields. */
+ if (key->numeric | key->general_numeric)
+ {
+ char savea = *lima, saveb = *limb;
+
+ *lima = *limb = '\0';
+ if (force_general_numcompare)
+ diff = general_numcompare (texta, textb);
+ else
+ diff = ((key->numeric ? numcompare : general_numcompare)
+ (texta, textb));
+ *lima = savea, *limb = saveb;
+ }
+ else if (key->month)
+ diff = getmonth (texta, lena) - getmonth (textb, lenb);
+ else
+ {
+ if (ignore || translate)
+ {
+ char *copy_a = (char *) alloca (lena + 1 + lenb + 1);
+ char *copy_b = copy_a + lena + 1;
+ size_t new_len_a, new_len_b;
+ size_t i, j;
+
+ /* Ignore and/or translate chars before comparing. */
+# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \
+ do \
+ { \
+ wchar_t uwc; \
+ char mbc[MB_LEN_MAX]; \
+ mbstate_t state_wc; \
+ \
+ for (NEW_LEN = i = 0; i < LEN;) \
+ { \
+ mbstate_t state_bak; \
+ \
+ state_bak = STATE; \
+ MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \
+ \
+ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \
+ || MBLENGTH == 0) \
+ { \
+ if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \
+ STATE = state_bak; \
+ if (!ignore) \
+ COPY[NEW_LEN++] = TEXT[i++]; \
+ continue; \
+ } \
+ \
+ if (ignore) \
+ { \
+ if ((ignore == nonprinting && !iswprint (WC)) \
+ || (ignore == nondictionary \
+ && !iswalnum (WC) && !iswblank (WC))) \
+ { \
+ i += MBLENGTH; \
+ continue; \
+ } \
+ } \
+ \
+ if (translate) \
+ { \
+ \
+ uwc = toupper(WC); \
+ if (WC == uwc) \
+ { \
+ memcpy (mbc, TEXT + i, MBLENGTH); \
+ i += MBLENGTH; \
+ } \
+ else \
+ { \
+ i += MBLENGTH; \
+ WC = uwc; \
+ memset (&state_wc, '\0', sizeof (mbstate_t)); \
+ \
+ MBLENGTH = wcrtomb (mbc, WC, &state_wc); \
+ assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \
+ } \
+ \
+ for (j = 0; j < MBLENGTH; j++) \
+ COPY[NEW_LEN++] = mbc[j]; \
+ } \
+ else \
+ for (j = 0; j < MBLENGTH; j++) \
+ COPY[NEW_LEN++] = TEXT[i++]; \
+ } \
+ COPY[NEW_LEN] = '\0'; \
+ } \
+ while (0)
+ IGNORE_CHARS (new_len_a, lena, texta, copy_a,
+ wc_a, mblength_a, state_a);
+ IGNORE_CHARS (new_len_b, lenb, textb, copy_b,
+ wc_b, mblength_b, state_b);
+ diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b);
+ }
+ else if (lena == 0)
+ diff = - NONZERO (lenb);
+ else if (lenb == 0)
+ goto greater;
+ else
+ diff = xmemcoll (texta, lena, textb, lenb);
+ }
+
+ if (diff)
+ goto not_equal;
+
+ key = key->next;
+ if (! key)
+ break;
+
+ /* Find the beginning and limit of the next field. */
+ if (key->eword != -1)
+ lima = limfield (a, key), limb = limfield (b, key);
+ else
+ lima = a->text + a->length - 1, limb = b->text + b->length - 1;
+
+ if (key->sword != -1)
+ texta = begfield (a, key), textb = begfield (b, key);
+ else
+ {
+ texta = a->text, textb = b->text;
+ if (key->skipsblanks)
+ {
+ while (texta < lima && ismbblank (texta, lima - texta, &mblength_a))
+ texta += mblength_a;
+ while (textb < limb && ismbblank (textb, limb - textb, &mblength_b))
+ textb += mblength_b;
+ }
+ }
+ }
+
+ return 0;
+
+greater:
+ diff = 1;
+not_equal:
+ return key->reverse ? -diff : diff;
+}
+#endif
+
+/* Compare two lines A and B, returning negative, zero, or positive
+ depending on whether A compares less than, equal to, or greater than B. */
+
+static int
+compare (register const struct line *a, register const struct line *b)
+{
+ int diff;
+ size_t alen, blen;
+
+ /* First try to compare on the specified keys (if any).
+ The only two cases with no key at all are unadorned sort,
+ and unadorned sort -r. */
+ if (keylist)
+ {
+ diff = keycompare (a, b);
+ alloca (0);
+ if (diff | unique | stable)
+ return diff;
+ }
+
+ /* If the keys all compare equal (or no keys were specified)
+ fall through to the default comparison. */
+ alen = a->length - 1, blen = b->length - 1;
+
+ if (alen == 0)
+ diff = - NONZERO (blen);
+ else if (blen == 0)
+ diff = 1;
+ else if (HAVE_SETLOCALE && hard_LC_COLLATE)
+ diff = xmemcoll (a->text, alen, b->text, blen);
+ else if (! (diff = memcmp (a->text, b->text, MIN (alen, blen))))
+ diff = alen < blen ? -1 : alen != blen;
+
+ return reverse ? -diff : diff;
+}
+
+/* Check that the lines read from FILE_NAME come in order. Print a
+ diagnostic (FILE_NAME, line number, contents of line) to stderr and return
+ false if they are not in order. Otherwise, print no diagnostic
+ and return true. */
+
+static bool
+check (char const *file_name)
+{
+ FILE *fp = xfopen (file_name, "r");
+ struct buffer buf; /* Input buffer. */
+ struct line temp; /* Copy of previous line. */
+ size_t alloc = 0;
+ uintmax_t line_number = 0;
+ struct keyfield const *key = keylist;
+ bool nonunique = ! unique;
+ bool ordered = true;
+
+ initbuf (&buf, sizeof (struct line),
+ MAX (merge_buffer_size, sort_size));
+ temp.text = NULL;
+
+ while (fillbuf (&buf, fp, file_name))
+ {
+ struct line const *line = buffer_linelim (&buf);
+ struct line const *linebase = line - buf.nlines;
+
+ /* Make sure the line saved from the old buffer contents is
+ less than or equal to the first line of the new buffer. */
+ if (alloc && nonunique <= compare (&temp, line - 1))
+ {
+ found_disorder:
+ {
+ struct line const *disorder_line = line - 1;
+ uintmax_t disorder_line_number =
+ buffer_linelim (&buf) - disorder_line + line_number;
+ char hr_buf[INT_BUFSIZE_BOUND (uintmax_t)];
+ fprintf (stderr, _("%s: %s:%s: disorder: "),
+ program_name, file_name,
+ umaxtostr (disorder_line_number, hr_buf));
+ write_bytes (disorder_line->text, disorder_line->length, stderr,
+ _("standard error"));
+ ordered = false;
+ break;
+ }
+ }
+
+ /* Compare each line in the buffer with its successor. */
+ while (linebase < --line)
+ if (nonunique <= compare (line, line - 1))
+ goto found_disorder;
+
+ line_number += buf.nlines;
+
+ /* Save the last line of the buffer. */
+ if (alloc < line->length)
+ {
+ do
+ {
+ alloc *= 2;
+ if (! alloc)
+ {
+ alloc = line->length;
+ break;
+ }
+ }
+ while (alloc < line->length);
+
+ temp.text = xrealloc (temp.text, alloc);
+ }
+ memcpy (temp.text, line->text, line->length);
+ temp.length = line->length;
+ if (key)
+ {
+ temp.keybeg = temp.text + (line->keybeg - line->text);
+ temp.keylim = temp.text + (line->keylim - line->text);
+ }
+ }
+
+ xfclose (fp, file_name);
+ free (buf.buf);
+ if (temp.text)
+ free (temp.text);
+ return ordered;
+}
+
+/* Merge lines from FILES onto OFP. NFILES cannot be greater than
+ NMERGE. Close input and output files before returning.
+ OUTPUT_FILE gives the name of the output file. If it is NULL,
+ the output file is standard output. If OFP is NULL, the output
+ file has not been opened yet (or written to, if standard output). */
+
+static void
+mergefps (char **files, register int nfiles,
+ FILE *ofp, const char *output_file)
+{
+ FILE *fps[NMERGE]; /* Input streams for each file. */
+ struct buffer buffer[NMERGE]; /* Input buffers for each file. */
+ struct line saved; /* Saved line storage for unique check. */
+ struct line const *savedline = NULL;
+ /* &saved if there is a saved line. */
+ size_t savealloc = 0; /* Size allocated for the saved line. */
+ struct line const *cur[NMERGE]; /* Current line in each line table. */
+ struct line const *base[NMERGE]; /* Base of each line table. */
+ int ord[NMERGE]; /* Table representing a permutation of fps,
+ such that cur[ord[0]] is the smallest line
+ and will be next output. */
+ register int i, j, t;
+ struct keyfield const *key = keylist;
+ saved.text = NULL;
+
+ /* Read initial lines from each input file. */
+ for (i = 0; i < nfiles; )
+ {
+ fps[i] = xfopen (files[i], "r");
+ initbuf (&buffer[i], sizeof (struct line),
+ MAX (merge_buffer_size, sort_size / nfiles));
+ if (fillbuf (&buffer[i], fps[i], files[i]))
+ {
+ struct line const *linelim = buffer_linelim (&buffer[i]);
+ cur[i] = linelim - 1;
+ base[i] = linelim - buffer[i].nlines;
+ i++;
+ }
+ else
+ {
+ /* fps[i] is empty; eliminate it from future consideration. */
+ xfclose (fps[i], files[i]);
+ zaptemp (files[i]);
+ free (buffer[i].buf);
+ --nfiles;
+ for (j = i; j < nfiles; ++j)
+ files[j] = files[j + 1];
+ }
+ }
+
+ if (! ofp)
+ ofp = xfopen (output_file, "w");
+
+ /* Set up the ord table according to comparisons among input lines.
+ Since this only reorders two items if one is strictly greater than
+ the other, it is stable. */
+ for (i = 0; i < nfiles; ++i)
+ ord[i] = i;
+ for (i = 1; i < nfiles; ++i)
+ if (0 < compare (cur[ord[i - 1]], cur[ord[i]]))
+ t = ord[i - 1], ord[i - 1] = ord[i], ord[i] = t, i = 0;
+
+ /* Repeatedly output the smallest line until no input remains. */
+ while (nfiles)
+ {
+ struct line const *smallest = cur[ord[0]];
+
+ /* If uniquified output is turned on, output only the first of
+ an identical series of lines. */
+ if (unique)
+ {
+ if (savedline && compare (savedline, smallest))
+ {
+ savedline = 0;
+ write_bytes (saved.text, saved.length, ofp, output_file);
+ }
+ if (!savedline)
+ {
+ savedline = &saved;
+ if (savealloc < smallest->length)
+ {
+ do
+ if (! savealloc)
+ {
+ savealloc = smallest->length;
+ break;
+ }
+ while ((savealloc *= 2) < smallest->length);
+
+ saved.text = xrealloc (saved.text, savealloc);
+ }
+ saved.length = smallest->length;
+ memcpy (saved.text, smallest->text, saved.length);
+ if (key)
+ {
+ saved.keybeg =
+ saved.text + (smallest->keybeg - smallest->text);
+ saved.keylim =
+ saved.text + (smallest->keylim - smallest->text);
+ }
+ }
+ }
+ else
+ write_bytes (smallest->text, smallest->length, ofp, output_file);
+
+ /* Check if we need to read more lines into core. */
+ if (base[ord[0]] < smallest)
+ cur[ord[0]] = smallest - 1;
+ else
+ {
+ if (fillbuf (&buffer[ord[0]], fps[ord[0]], files[ord[0]]))
+ {
+ struct line const *linelim = buffer_linelim (&buffer[ord[0]]);
+ cur[ord[0]] = linelim - 1;
+ base[ord[0]] = linelim - buffer[ord[0]].nlines;
+ }
+ else
+ {
+ /* We reached EOF on fps[ord[0]]. */
+ for (i = 1; i < nfiles; ++i)
+ if (ord[i] > ord[0])
+ --ord[i];
+ --nfiles;
+ xfclose (fps[ord[0]], files[ord[0]]);
+ zaptemp (files[ord[0]]);
+ free (buffer[ord[0]].buf);
+ for (i = ord[0]; i < nfiles; ++i)
+ {
+ fps[i] = fps[i + 1];
+ files[i] = files[i + 1];
+ buffer[i] = buffer[i + 1];
+ cur[i] = cur[i + 1];
+ base[i] = base[i + 1];
+ }
+ for (i = 0; i < nfiles; ++i)
+ ord[i] = ord[i + 1];
+ continue;
+ }
+ }
+
+ /* The new line just read in may be larger than other lines
+ already in core; push it back in the queue until we encounter
+ a line larger than it. */
+ for (i = 1; i < nfiles; ++i)
+ {
+ t = compare (cur[ord[0]], cur[ord[i]]);
+ if (!t)
+ t = ord[0] - ord[i];
+ if (t < 0)
+ break;
+ }
+ t = ord[0];
+ for (j = 1; j < i; ++j)
+ ord[j - 1] = ord[j];
+ ord[i - 1] = t;
+ }
+
+ if (unique && savedline)
+ {
+ write_bytes (saved.text, saved.length, ofp, output_file);
+ free (saved.text);
+ }
+
+ xfclose (ofp, output_file);
+}
+
+/* Merge into T the two sorted arrays of lines LO (with NLO members)
+ and HI (with NHI members). T, LO, and HI point just past their
+ respective arrays, and the arrays are in reverse order. NLO and
+ NHI must be positive, and HI - NHI must equal T - (NLO + NHI). */
+
+static inline void
+mergelines (struct line *t,
+ struct line const *lo, size_t nlo,
+ struct line const *hi, size_t nhi)
+{
+ for (;;)
+ if (compare (lo - 1, hi - 1) <= 0)
+ {
+ *--t = *--lo;
+ if (! --nlo)
+ {
+ /* HI - NHI equalled T - (NLO + NHI) when this function
+ began. Therefore HI must equal T now, and there is no
+ need to copy from HI to T. */
+ return;
+ }
+ }
+ else
+ {
+ *--t = *--hi;
+ if (! --nhi)
+ {
+ do
+ *--t = *--lo;
+ while (--nlo);
+
+ return;
+ }
+ }
+}
+
+/* Sort the array LINES with NLINES members, using TEMP for temporary space.
+ NLINES must be at least 2.
+ The input and output arrays are in reverse order, and LINES and
+ TEMP point just past the end of their respective arrays.
+
+ Use a recursive divide-and-conquer algorithm, in the style
+ suggested by Knuth volume 3 (2nd edition), exercise 5.2.4-23. Use
+ the optimization suggested by exercise 5.2.4-10; this requires room
+ for only 1.5*N lines, rather than the usual 2*N lines. Knuth
+ writes that this memory optimization was originally published by
+ D. A. Bell, Comp J. 1 (1958), 75. */
+
+static void
+sortlines (struct line *lines, size_t nlines, struct line *temp)
+{
+ if (nlines == 2)
+ {
+ if (0 < compare (&lines[-1], &lines[-2]))
+ {
+ struct line tmp = lines[-1];
+ lines[-1] = lines[-2];
+ lines[-2] = tmp;
+ }
+ }
+ else
+ {
+ size_t nlo = nlines / 2;
+ size_t nhi = nlines - nlo;
+ struct line *lo = lines;
+ struct line *hi = lines - nlo;
+ struct line *sorted_lo = temp;
+
+ sortlines (hi, nhi, temp);
+ if (1 < nlo)
+ sortlines_temp (lo, nlo, sorted_lo);
+ else
+ sorted_lo[-1] = lo[-1];
+
+ mergelines (lines, sorted_lo, nlo, hi, nhi);
+ }
+}
+
+/* Like sortlines (LINES, NLINES, TEMP), except output into TEMP
+ rather than sorting in place. */
+
+static void
+sortlines_temp (struct line *lines, size_t nlines, struct line *temp)
+{
+ if (nlines == 2)
+ {
+ bool swap = (0 < compare (&lines[-1], &lines[-2]));
+ temp[-1] = lines[-1 - swap];
+ temp[-2] = lines[-2 + swap];
+ }
+ else
+ {
+ size_t nlo = nlines / 2;
+ size_t nhi = nlines - nlo;
+ struct line *lo = lines;
+ struct line *hi = lines - nlo;
+ struct line *sorted_hi = temp - nlo;
+
+ sortlines_temp (hi, nhi, sorted_hi);
+ if (1 < nlo)
+ sortlines (lo, nlo, temp);
+
+ mergelines (temp, lo, nlo, sorted_hi, nhi);
+ }
+}
+
+/* Return the index of the first of NFILES FILES that is the same file
+ as OUTFILE. If none can be the same, return NFILES.
+
+ This test ensures that an otherwise-erroneous use like
+ "sort -m -o FILE ... FILE ..." copies FILE before writing to it.
+ It's not clear that POSIX requires this nicety.
+ Detect common error cases, but don't try to catch obscure cases like
+ "cat ... FILE ... | sort -m -o FILE"
+ where traditional "sort" doesn't copy the input and where
+ people should know that they're getting into trouble anyway.
+ Catching these obscure cases would slow down performance in
+ common cases. */
+
+static int
+first_same_file (char * const *files, int nfiles, char const *outfile)
+{
+ int i;
+ bool got_outstat = false;
+ struct stat instat, outstat;
+
+ for (i = 0; i < nfiles; i++)
+ {
+ bool standard_input = STREQ (files[i], "-");
+
+ if (outfile && STREQ (outfile, files[i]) && ! standard_input)
+ return i;
+
+ if (! got_outstat)
+ {
+ got_outstat = true;
+ if ((outfile
+ ? stat (outfile, &outstat)
+ : fstat (STDOUT_FILENO, &outstat))
+ != 0)
+ return nfiles;
+ }
+
+ if (((standard_input
+ ? fstat (STDIN_FILENO, &instat)
+ : stat (files[i], &instat))
+ == 0)
+ && SAME_INODE (instat, outstat))
+ return i;
+ }
+
+ return nfiles;
+}
+
+/* Merge NFILES FILES onto OUTPUT_FILE. However, merge at most
+ MAX_MERGE input files directly onto OUTPUT_FILE. MAX_MERGE cannot
+ exceed NMERGE. A null OUTPUT_FILE stands for standard output. */
+
+static void
+merge (char **files, int nfiles, int max_merge, char const *output_file)
+{
+ while (max_merge < nfiles)
+ {
+ FILE *tfp;
+ int i, t = 0;
+ char *temp;
+ for (i = 0; i < nfiles / NMERGE; ++i)
+ {
+ temp = create_temp_file (&tfp);
+ mergefps (&files[i * NMERGE], NMERGE, tfp, temp);
+ files[t++] = temp;
+ }
+ temp = create_temp_file (&tfp);
+ mergefps (&files[i * NMERGE], nfiles % NMERGE, tfp, temp);
+ files[t++] = temp;
+ nfiles = t;
+ if (nfiles == 1)
+ break;
+ }
+
+ mergefps (files, nfiles, NULL, output_file);
+}
+
+/* Sort NFILES FILES onto OUTPUT_FILE. */
+
+static void
+sort (char * const *files, int nfiles, char const *output_file)
+{
+ struct buffer buf;
+ int n_temp_files = 0;
+ bool output_file_created = false;
+
+ buf.alloc = 0;
+
+ while (nfiles)
+ {
+ char const *temp_output;
+ char const *file = *files;
+ FILE *fp = xfopen (file, "r");
+ FILE *tfp;
+ size_t bytes_per_line = (2 * sizeof (struct line)
+ - sizeof (struct line) / 2);
+
+ if (! buf.alloc)
+ initbuf (&buf, bytes_per_line,
+ sort_buffer_size (&fp, 1, files, nfiles, bytes_per_line));
+ buf.eof = false;
+ files++;
+ nfiles--;
+
+ while (fillbuf (&buf, fp, file))
+ {
+ struct line *line;
+ struct line *linebase;
+
+ if (buf.eof && nfiles
+ && (bytes_per_line + 1
+ < (buf.alloc - buf.used - bytes_per_line * buf.nlines)))
+ {
+ /* End of file, but there is more input and buffer room.
+ Concatenate the next input file; this is faster in
+ the usual case. */
+ buf.left = buf.used;
+ break;
+ }
+
+ line = buffer_linelim (&buf);
+ linebase = line - buf.nlines;
+ if (1 < buf.nlines)
+ sortlines (line, buf.nlines, linebase);
+ if (buf.eof && !nfiles && !n_temp_files && !buf.left)
+ {
+ xfclose (fp, file);
+ tfp = xfopen (output_file, "w");
+ temp_output = output_file;
+ output_file_created = true;
+ }
+ else
+ {
+ ++n_temp_files;
+ temp_output = create_temp_file (&tfp);
+ }
+
+ do
+ {
+ line--;
+ write_bytes (line->text, line->length, tfp, temp_output);
+ if (unique)
+ while (linebase < line && compare (line, line - 1) == 0)
+ line--;
+ }
+ while (linebase < line);
+
+ xfclose (tfp, temp_output);
+
+ if (output_file_created)
+ goto finish;
+ }
+ xfclose (fp, file);
+ }
+
+ finish:
+ free (buf.buf);
+
+ if (! output_file_created)
+ {
+ int i = n_temp_files;
+ struct tempnode *node;
+ char **tempfiles = xnmalloc (n_temp_files, sizeof *tempfiles);
+ for (node = temphead; i > 0; node = node->next)
+ tempfiles[--i] = node->name;
+ merge (tempfiles, n_temp_files, NMERGE, output_file);
+ free (tempfiles);
+ }
+}
+
+/* Insert key KEY at the end of the key list. */
+
+static void
+insertkey (struct keyfield *key)
+{
+ struct keyfield **p;
+
+ for (p = &keylist; *p; p = &(*p)->next)
+ continue;
+ *p = key;
+ key->next = NULL;
+}
+
+/* Report a bad field specification SPEC, with extra info MSGID. */
+
+static void badfieldspec (char const *, char const *)
+ ATTRIBUTE_NORETURN;
+static void
+badfieldspec (char const *spec, char const *msgid)
+{
+ error (SORT_FAILURE, 0, _("%s: invalid field specification `%s'"),
+ _(msgid), spec);
+ abort ();
+}
+
+/* Parse the leading integer in STRING and store the resulting value
+ (which must fit into size_t) into *VAL. Return the address of the
+ suffix after the integer. If MSGID is NULL, return NULL after
+ failure; otherwise, report MSGID and exit on failure. */
+
+static char const *
+parse_field_count (char const *string, size_t *val, char const *msgid)
+{
+ char *suffix;
+ uintmax_t n;
+
+ switch (xstrtoumax (string, &suffix, 10, &n, ""))
+ {
+ case LONGINT_OK:
+ case LONGINT_INVALID_SUFFIX_CHAR:
+ *val = n;
+ if (*val == n)
+ break;
+ /* Fall through. */
+ case LONGINT_OVERFLOW:
+ case LONGINT_OVERFLOW | LONGINT_INVALID_SUFFIX_CHAR:
+ if (msgid)
+ error (SORT_FAILURE, 0, _("%s: count `%.*s' too large"),
+ _(msgid), (int) (suffix - string), string);
+ return NULL;
+
+ case LONGINT_INVALID:
+ if (msgid)
+ error (SORT_FAILURE, 0, _("%s: invalid count at start of `%s'"),
+ _(msgid), string);
+ return NULL;
+ }
+
+ return suffix;
+}
+
+/* Handle interrupts and hangups. */
+
+static void
+sighandler (int sig)
+{
+#ifndef SA_NOCLDSTOP
+ signal (sig, SIG_IGN);
+#endif
+
+ cleanup ();
+
+ signal (sig, SIG_DFL);
+ raise (sig);
+}
+
+/* Set the ordering options for KEY specified in S.
+ Return the address of the first character in S that
+ is not a valid ordering option.
+ BLANKTYPE is the kind of blanks that 'b' should skip. */
+
+static char *
+set_ordering (register const char *s, struct keyfield *key,
+ enum blanktype blanktype)
+{
+ while (*s)
+ {
+ switch (*s)
+ {
+ case 'b':
+ if (blanktype == bl_start || blanktype == bl_both)
+ key->skipsblanks = true;
+ if (blanktype == bl_end || blanktype == bl_both)
+ key->skipeblanks = true;
+ break;
+ case 'd':
+ key->ignore = nondictionary;
+ break;
+ case 'f':
+ key->translate = fold_toupper;
+ break;
+ case 'g':
+ key->general_numeric = true;
+ break;
+ case 'i':
+ /* Option order should not matter, so don't let -i override
+ -d. -d implies -i, but -i does not imply -d. */
+ if (! key->ignore)
+ key->ignore = nonprinting;
+ break;
+ case 'M':
+ key->month = true;
+ break;
+ case 'n':
+ key->numeric = true;
+ break;
+ case 'r':
+ key->reverse = true;
+ break;
+ default:
+ return (char *) s;
+ }
+ ++s;
+ }
+ return (char *) s;
+}
+
+static struct keyfield *
+new_key (void)
+{
+ struct keyfield *key = xzalloc (sizeof *key);
+ key->eword = SIZE_MAX;
+ return key;
+}
+
+int
+main (int argc, char **argv)
+{
+ struct keyfield *key;
+ struct keyfield gkey;
+ char const *s;
+ int c = 0;
+ bool checkonly = false;
+ bool mergeonly = false;
+ int nfiles = 0;
+ bool posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
+ bool obsolete_usage = (posix2_version () < 200112);
+ char const *short_options = (obsolete_usage
+ ? COMMON_SHORT_OPTIONS "y::"
+ : COMMON_SHORT_OPTIONS "y:");
+ char *minus = "-", **files;
+ char const *outfile = NULL;
+
+ initialize_main (&argc, &argv);
+ program_name = argv[0];
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
+ atexit (cleanup);
+
+ initialize_exit_failure (SORT_FAILURE);
+ atexit (close_stdout);
+
+ hard_LC_COLLATE = hard_locale (LC_COLLATE);
+#if HAVE_NL_LANGINFO
+ hard_LC_TIME = hard_locale (LC_TIME);
+#endif
+
+#if HAVE_SETLOCALE
+ /* Let's get locale's representation of the decimal point */
+ {
+ struct lconv const *lconvp = localeconv ();
+
+ decimal_point = *lconvp->decimal_point;
+ if (! decimal_point || lconvp->decimal_point[1])
+ {
+ decimal_point = C_DECIMAL_POINT;
+ if (lconvp->decimal_point[0] && lconvp->decimal_point[1])
+ force_general_numcompare = 1;
+ }
+
+ /* We don't support multibyte thousands separators yet. */
+ th_sep = *lconvp->thousands_sep;
+ if (! th_sep || lconvp->thousands_sep[1])
+ {
+ th_sep = CHAR_MAX + 1;
+ if (lconvp->thousands_sep[0] && lconvp->thousands_sep[1])
+ force_general_numcompare = 1;
+ }
+ }
+#endif
+
+#if HAVE_MBRTOWC
+ if (MB_CUR_MAX > 1)
+ {
+ inittables = inittables_mb;
+ begfield = begfield_mb;
+ limfield = limfield_mb;
+ getmonth = getmonth_mb;
+ keycompare = keycompare_mb;
+ }
+ else
+#endif
+ {
+ inittables = inittables_uni;
+ begfield = begfield_uni;
+ limfield = limfield_uni;
+ keycompare = keycompare_uni;
+ getmonth = getmonth_uni;
+ }
+
+ have_read_stdin = false;
+ inittables ();
+
+ {
+ int i;
+ static int const sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM };
+ enum { nsigs = sizeof sig / sizeof sig[0] };
+
+#ifdef SA_NOCLDSTOP
+ struct sigaction act;
+
+ sigemptyset (&caught_signals);
+ for (i = 0; i < nsigs; i++)
+ {
+ sigaction (sig[i], NULL, &act);
+ if (act.sa_handler != SIG_IGN)
+ sigaddset (&caught_signals, sig[i]);
+ }
+
+ act.sa_handler = sighandler;
+ act.sa_mask = caught_signals;
+ act.sa_flags = 0;
+
+ for (i = 0; i < nsigs; i++)
+ if (sigismember (&caught_signals, sig[i]))
+ sigaction (sig[i], &act, NULL);
+#else
+ for (i = 0; i < nsigs; i++)
+ if (signal (sig[i], SIG_IGN) != SIG_IGN)
+ signal (sig[i], sighandler);
+#endif
+ }
+
+ gkey.sword = gkey.eword = SIZE_MAX;
+ gkey.ignore = NULL;
+ gkey.translate = NULL;
+ gkey.numeric = gkey.general_numeric = gkey.month = gkey.reverse = false;
+ gkey.skipsblanks = gkey.skipeblanks = false;
+
+ files = xnmalloc (argc, sizeof *files);
+
+ for (;;)
+ {
+ /* Parse an operand as a file after "--" was seen; or if
+ pedantic and a file was seen, unless the POSIX version
+ predates 1003.1-2001 and -c was not seen and the operand is
+ "-o FILE" or "-oFILE". */
+
+ if (c == -1
+ || (posixly_correct && nfiles != 0
+ && ! (obsolete_usage
+ && ! checkonly
+ && optind != argc
+ && argv[optind][0] == '-' && argv[optind][1] == 'o'
+ && (argv[optind][2] || optind + 1 != argc)))
+ || ((c = getopt_long (argc, argv, short_options,
+ long_options, NULL))
+ == -1))
+ {
+ if (argc <= optind)
+ break;
+ files[nfiles++] = argv[optind++];
+ }
+ else switch (c)
+ {
+ case 1:
+ key = NULL;
+ if (obsolete_usage && optarg[0] == '+')
+ {
+ /* Treat +POS1 [-POS2] as a key if possible; but silently
+ treat an operand as a file if it is not a valid +POS1. */
+ key = new_key ();
+ s = parse_field_count (optarg + 1, &key->sword, NULL);
+ if (s && *s == '.')
+ s = parse_field_count (s + 1, &key->schar, NULL);
+ if (! (key->sword | key->schar))
+ key->sword = SIZE_MAX;
+ if (! s || *set_ordering (s, key, bl_start))
+ {
+ free (key);
+ key = NULL;
+ }
+ else
+ {
+ if (optind != argc && argv[optind][0] == '-'
+ && ISDIGIT (argv[optind][1]))
+ {
+ char const *optarg1 = argv[optind++];
+ s = parse_field_count (optarg1 + 1, &key->eword,
+ N_("invalid number after `-'"));
+ if (*s == '.')
+ s = parse_field_count (s + 1, &key->echar,
+ N_("invalid number after `.'"));
+ if (*set_ordering (s, key, bl_end))
+ badfieldspec (optarg1,
+ N_("stray character in field spec"));
+ }
+ insertkey (key);
+ }
+ }
+ if (! key)
+ files[nfiles++] = optarg;
+ break;
+
+ case 'b':
+ case 'd':
+ case 'f':
+ case 'g':
+ case 'i':
+ case 'M':
+ case 'n':
+ case 'r':
+ {
+ char str[2];
+ str[0] = c;
+ str[1] = '\0';
+ set_ordering (str, &gkey, bl_both);
+ }
+ break;
+
+ case 'c':
+ checkonly = true;
+ break;
+
+ case 'k':
+ key = new_key ();
+
+ /* Get POS1. */
+ s = parse_field_count (optarg, &key->sword,
+ N_("invalid number at field start"));
+ if (! key->sword--)
+ {
+ /* Provoke with `sort -k0' */
+ badfieldspec (optarg, N_("field number is zero"));
+ }
+ if (*s == '.')
+ {
+ s = parse_field_count (s + 1, &key->schar,
+ N_("invalid number after `.'"));
+ if (! key->schar--)
+ {
+ /* Provoke with `sort -k1.0' */
+ badfieldspec (optarg, N_("character offset is zero"));
+ }
+ }
+ if (! (key->sword | key->schar))
+ key->sword = SIZE_MAX;
+ s = set_ordering (s, key, bl_start);
+ if (*s != ',')
+ {
+ key->eword = SIZE_MAX;
+ key->echar = 0;
+ }
+ else
+ {
+ /* Get POS2. */
+ s = parse_field_count (s + 1, &key->eword,
+ N_("invalid number after `,'"));
+ if (! key->eword--)
+ {
+ /* Provoke with `sort -k1,0' */
+ badfieldspec (optarg, N_("field number is zero"));
+ }
+ if (*s == '.')
+ s = parse_field_count (s + 1, &key->echar,
+ N_("invalid number after `.'"));
+ else
+ {
+ /* `-k 2,3' is equivalent to `+1 -3'. */
+ key->eword++;
+ }
+ s = set_ordering (s, key, bl_end);
+ }
+ if (*s)
+ badfieldspec (optarg, N_("stray character in field spec"));
+ insertkey (key);
+ break;
+
+ case 'm':
+ mergeonly = true;
+ break;
+
+ case 'o':
+ if (outfile && !STREQ (outfile, optarg))
+ error (SORT_FAILURE, 0, _("multiple output files specified"));
+ outfile = optarg;
+ break;
+
+ case 's':
+ stable = true;
+ break;
+
+ case 'S':
+ specify_sort_size (optarg);
+ break;
+
+ case 't':
+ {
+ char newtab[MB_LEN_MAX + 1];
+ size_t newtab_length = 1;
+ strncpy (newtab, optarg, MB_LEN_MAX);
+ if (! newtab[0])
+ error (SORT_FAILURE, 0, _("empty tab"));
+#if HAVE_MBRTOWC
+ if (MB_CUR_MAX > 1)
+ {
+ wchar_t wc;
+ mbstate_t state;
+ size_t i;
+
+ memset (&state, '\0', sizeof (mbstate_t));
+ newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, MB_LEN_MAX), &state);
+ switch (newtab_length)
+ {
+ case (size_t) -1:
+ case (size_t) -2:
+ case 0:
+ newtab_length = 1;
+ }
+
+ if (optarg[newtab_length])
+ {
+ /* Provoke with `sort -txx'. Complain about
+ "multi-character tab" instead of "multibyte tab", so
+ that the diagnostic's wording does not need to be
+ changed once multibyte characters are supported. */
+ error (SORT_FAILURE, 0, _("multi-character tab `%s'"),
+ optarg);
+ }
+ }
+ else
+#endif
+
+ if (optarg[1])
+ {
+ if (STREQ (optarg, "\\0"))
+ newtab[0] = '\0';
+ else
+ {
+ /* Provoke with `sort -txx'. Complain about
+ "multi-character tab" instead of "multibyte tab", so
+ that the diagnostic's wording does not need to be
+ changed once multibyte characters are supported. */
+ error (SORT_FAILURE, 0, _("multi-character tab `%s'"),
+ optarg);
+ }
+ }
+ if (!tab_default && (tab_length != newtab_length
+ || memcmp(tab, newtab, tab_length) != 0))
+ error (SORT_FAILURE, 0, _("incompatible tabs"));
+ memcpy(tab, newtab, newtab_length);
+ tab_length = newtab_length;
+ tab_default = false;
+ }
+ break;
+
+ case 'T':
+ add_temp_dir (optarg);
+ break;
+
+ case 'u':
+ unique = true;
+ break;
+
+ case 'y':
+ /* Accept and ignore e.g. -y0 for compatibility with Solaris
+ 2.x through Solaris 7. -y is marked as obsolete starting
+ with Solaris 8. */
+ break;
+
+ case 'z':
+ eolchar = 0;
+ break;
+
+ case_GETOPT_HELP_CHAR;
+
+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+
+ default:
+ usage (SORT_FAILURE);
+ }
+ }
+
+ /* Inheritance of global options to individual keys. */
+ for (key = keylist; key; key = key->next)
+ if (! (key->ignore || key->translate
+ || (key->skipsblanks | key->reverse
+ | key->skipeblanks | key->month | key->numeric
+ | key->general_numeric)))
+ {
+ key->ignore = gkey.ignore;
+ key->translate = gkey.translate;
+ key->skipsblanks = gkey.skipsblanks;
+ key->skipeblanks = gkey.skipeblanks;
+ key->month = gkey.month;
+ key->numeric = gkey.numeric;
+ key->general_numeric = gkey.general_numeric;
+ key->reverse = gkey.reverse;
+ }
+
+ if (!keylist && (gkey.ignore || gkey.translate
+ || (gkey.skipsblanks | gkey.skipeblanks | gkey.month
+ | gkey.numeric | gkey.general_numeric)))
+ insertkey (&gkey);
+ reverse = gkey.reverse;
+
+ if (temp_dir_count == 0)
+ {
+ char const *tmp_dir = getenv ("TMPDIR");
+ add_temp_dir (tmp_dir ? tmp_dir : DEFAULT_TMPDIR);
+ }
+
+ if (nfiles == 0)
+ {
+ nfiles = 1;
+ files = &minus;
+ }
+
+ if (checkonly)
+ {
+ if (nfiles > 1)
+ {
+ error (0, 0, _("extra operand %s not allowed with -c"),
+ quote (files[1]));
+ usage (SORT_FAILURE);
+ }
+
+ /* POSIX requires that sort return 1 IFF invoked with -c and the
+ input is not properly sorted. */
+ exit (check (files[0]) ? EXIT_SUCCESS : SORT_OUT_OF_ORDER);
+ }
+
+ if (mergeonly)
+ {
+ int max_merge = first_same_file (files, MIN (nfiles, NMERGE), outfile);
+ merge (files, nfiles, max_merge, outfile);
+ }
+ else
+ sort (files, nfiles, outfile);
+
+ if (have_read_stdin && fclose (stdin) == EOF)
+ die (_("close failed"), "-");
+
+ exit (EXIT_SUCCESS);
+}
diff --git a/contrib/gnu-sort/src/system.h b/contrib/gnu-sort/src/system.h
new file mode 100644
index 0000000..3497969
--- /dev/null
+++ b/contrib/gnu-sort/src/system.h
@@ -0,0 +1,831 @@
+/* system-dependent definitions for fileutils, textutils, and sh-utils packages.
+ Copyright (C) 1989, 1991-2004 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <alloca.h>
+
+/* Include sys/types.h before this file. */
+
+#if 2 <= __GLIBC__ && 2 <= __GLIBC_MINOR__
+# if ! defined _SYS_TYPES_H
+you must include <sys/types.h> before including this file
+# endif
+#endif
+
+#include <sys/stat.h>
+
+#if !defined HAVE_MKFIFO
+# define mkfifo(path, mode) (mknod ((path), (mode) | S_IFIFO, 0))
+#endif
+
+#if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+
+/* <unistd.h> should be included before any preprocessor test
+ of _POSIX_VERSION. */
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
+
+/* limits.h must come before pathmax.h because limits.h on some systems
+ undefs PATH_MAX, whereas pathmax.h sets PATH_MAX. */
+#include <limits.h>
+
+#include "pathmax.h"
+#include "localedir.h"
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+/* Since major is a function on SVR4, we can't use `ifndef major'. */
+#if MAJOR_IN_MKDEV
+# include <sys/mkdev.h>
+# define HAVE_MAJOR
+#endif
+#if MAJOR_IN_SYSMACROS
+# include <sys/sysmacros.h>
+# define HAVE_MAJOR
+#endif
+#ifdef major /* Might be defined in sys/types.h. */
+# define HAVE_MAJOR
+#endif
+
+#ifndef HAVE_MAJOR
+# define major(dev) (((dev) >> 8) & 0xff)
+# define minor(dev) ((dev) & 0xff)
+# define makedev(maj, min) (((maj) << 8) | (min))
+#endif
+#undef HAVE_MAJOR
+
+#if ! defined makedev && defined mkdev
+# define makedev(maj, min) mkdev (maj, min)
+#endif
+
+#if HAVE_UTIME_H
+# include <utime.h>
+#endif
+
+/* Some systems (even some that do have <utime.h>) don't declare this
+ structure anywhere. */
+#ifndef HAVE_STRUCT_UTIMBUF
+struct utimbuf
+{
+ long actime;
+ long modtime;
+};
+#endif
+
+/* Don't use bcopy! Use memmove if source and destination may overlap,
+ memcpy otherwise. */
+
+#include <string.h>
+#if ! HAVE_DECL_MEMRCHR
+void *memrchr (const void *, int, size_t);
+#endif
+
+#include <errno.h>
+
+/* Some systems don't define the following symbols. */
+#ifndef ENOSYS
+# define ENOSYS (-1)
+#endif
+#ifndef EISDIR
+# define EISDIR (-1)
+#endif
+
+#include <stdbool.h>
+
+#define getopt system_getopt
+#include <stdlib.h>
+#undef getopt
+
+/* The following test is to work around the gross typo in
+ systems like Sony NEWS-OS Release 4.0C, whereby EXIT_FAILURE
+ is defined to 0, not 1. */
+#if !EXIT_FAILURE
+# undef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#endif
+
+#ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+#endif
+
+/* Exit statuses for programs like 'env' that exec other programs.
+ EXIT_FAILURE might not be 1, so use EXIT_FAIL in such programs. */
+enum
+{
+ EXIT_FAIL = 1,
+ EXIT_CANNOT_INVOKE = 126,
+ EXIT_ENOENT = 127
+};
+
+#include "exitfail.h"
+
+/* Set exit_failure to STATUS if that's not the default already. */
+static inline void
+initialize_exit_failure (int status)
+{
+ if (status != EXIT_FAILURE)
+ exit_failure = status;
+}
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#else
+# include <sys/file.h>
+#endif
+
+#if !defined SEEK_SET
+# define SEEK_SET 0
+# define SEEK_CUR 1
+# define SEEK_END 2
+#endif
+#ifndef F_OK
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+/* For systems that distinguish between text and binary I/O.
+ O_BINARY is usually declared in fcntl.h */
+#if !defined O_BINARY && defined _O_BINARY
+ /* For MSC-compatible compilers. */
+# define O_BINARY _O_BINARY
+# define O_TEXT _O_TEXT
+#endif
+
+#if !defined O_DIRECT
+# define O_DIRECT 0
+#endif
+
+#if !defined O_DSYNC
+# define O_DSYNC 0
+#endif
+
+#if !defined O_NDELAY
+# define O_NDELAY 0
+#endif
+
+#if !defined O_NONBLOCK
+# define O_NONBLOCK O_NDELAY
+#endif
+
+#if !defined O_NOCTTY
+# define O_NOCTTY 0
+#endif
+
+#if !defined O_NOFOLLOW
+# define O_NOFOLLOW 0
+#endif
+
+#if !defined O_RSYNC
+# define O_RSYNC 0
+#endif
+
+#if !defined O_SYNC
+# define O_SYNC 0
+#endif
+
+#ifdef __BEOS__
+ /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */
+# undef O_BINARY
+# undef O_TEXT
+#endif
+
+#if O_BINARY
+# ifndef __DJGPP__
+# define setmode _setmode
+# define fileno(_fp) _fileno (_fp)
+# endif /* not DJGPP */
+# define SET_MODE(_f, _m) setmode (_f, _m)
+# define SET_BINARY(_f) do {if (!isatty(_f)) setmode (_f, O_BINARY);} while (0)
+# define SET_BINARY2(_f1, _f2) \
+ do { \
+ if (!isatty (_f1)) \
+ { \
+ setmode (_f1, O_BINARY); \
+ if (!isatty (_f2)) \
+ setmode (_f2, O_BINARY); \
+ } \
+ } while(0)
+#else
+# define SET_MODE(_f, _m) (void)0
+# define SET_BINARY(f) (void)0
+# define SET_BINARY2(f1,f2) (void)0
+# ifndef O_BINARY
+# define O_BINARY 0
+# endif
+# define O_TEXT 0
+#endif /* O_BINARY */
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NLENGTH(direct) (strlen((direct)->d_name))
+#else /* not HAVE_DIRENT_H */
+# define dirent direct
+# define NLENGTH(direct) ((direct)->d_namlen)
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif /* HAVE_SYS_NDIR_H */
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif /* HAVE_SYS_DIR_H */
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif /* HAVE_NDIR_H */
+#endif /* HAVE_DIRENT_H */
+
+#if CLOSEDIR_VOID
+/* Fake a return value. */
+# define CLOSEDIR(d) (closedir (d), 0)
+#else
+# define CLOSEDIR(d) closedir (d)
+#endif
+
+/* Get or fake the disk device blocksize.
+ Usually defined by sys/param.h (if at all). */
+#if !defined DEV_BSIZE && defined BSIZE
+# define DEV_BSIZE BSIZE
+#endif
+#if !defined DEV_BSIZE && defined BBSIZE /* SGI */
+# define DEV_BSIZE BBSIZE
+#endif
+#ifndef DEV_BSIZE
+# define DEV_BSIZE 4096
+#endif
+
+/* Extract or fake data from a `struct stat'.
+ ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
+ ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
+ ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
+#ifndef HAVE_STRUCT_STAT_ST_BLOCKS
+# define ST_BLKSIZE(statbuf) DEV_BSIZE
+# if defined _POSIX_SOURCE || !defined BSIZE /* fileblocks.c uses BSIZE. */
+# define ST_NBLOCKS(statbuf) \
+ ((statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0))
+# else /* !_POSIX_SOURCE && BSIZE */
+# define ST_NBLOCKS(statbuf) \
+ (S_ISREG ((statbuf).st_mode) \
+ || S_ISDIR ((statbuf).st_mode) \
+ ? st_blocks ((statbuf).st_size) : 0)
+# endif /* !_POSIX_SOURCE && BSIZE */
+#else /* HAVE_STRUCT_STAT_ST_BLOCKS */
+/* Some systems, like Sequents, return st_blksize of 0 on pipes.
+ Also, when running `rsh hpux11-system cat any-file', cat would
+ determine that the output stream had an st_blksize of 2147421096.
+ So here we arbitrarily limit the `optimal' block size to 4MB.
+ If anyone knows of a system for which the legitimate value for
+ st_blksize can exceed 4MB, please report it as a bug in this code. */
+# define ST_BLKSIZE(statbuf) ((0 < (statbuf).st_blksize \
+ && (statbuf).st_blksize <= (1 << 22)) /* 4MB */ \
+ ? (statbuf).st_blksize : DEV_BSIZE)
+# if defined hpux || defined __hpux__ || defined __hpux
+/* HP-UX counts st_blocks in 1024-byte units.
+ This loses when mixing HP-UX and BSD file systems with NFS. */
+# define ST_NBLOCKSIZE 1024
+# else /* !hpux */
+# if defined _AIX && defined _I386
+/* AIX PS/2 counts st_blocks in 4K units. */
+# define ST_NBLOCKSIZE (4 * 1024)
+# else /* not AIX PS/2 */
+# if defined _CRAY
+# define ST_NBLOCKS(statbuf) \
+ (S_ISREG ((statbuf).st_mode) \
+ || S_ISDIR ((statbuf).st_mode) \
+ ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
+# endif /* _CRAY */
+# endif /* not AIX PS/2 */
+# endif /* !hpux */
+#endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
+
+#ifndef ST_NBLOCKS
+# define ST_NBLOCKS(statbuf) ((statbuf).st_blocks)
+#endif
+
+#ifndef ST_NBLOCKSIZE
+# define ST_NBLOCKSIZE 512
+#endif
+
+/* Redirection and wildcarding when done by the utility itself.
+ Generally a noop, but used in particular for native VMS. */
+#ifndef initialize_main
+# define initialize_main(ac, av)
+#endif
+
+#include "stat-macros.h"
+
+#include "timespec.h"
+
+#ifndef RETSIGTYPE
+# define RETSIGTYPE void
+#endif
+
+#ifdef __DJGPP__
+ /* We need the declaration of setmode. */
+# include <io.h>
+ /* We need the declaration of __djgpp_set_ctrl_c. */
+# include <sys/exceptn.h>
+#endif
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#if ULONG_MAX < ULLONG_MAX
+# define LONGEST_MODIFIER "ll"
+#else
+# define LONGEST_MODIFIER "l"
+#endif
+#if PRI_MACROS_BROKEN
+# undef PRIdMAX
+# undef PRIoMAX
+# undef PRIuMAX
+# undef PRIxMAX
+#endif
+#ifndef PRIdMAX
+# define PRIdMAX LONGEST_MODIFIER "d"
+#endif
+#ifndef PRIoMAX
+# define PRIoMAX LONGEST_MODIFIER "o"
+#endif
+#ifndef PRIuMAX
+# define PRIuMAX LONGEST_MODIFIER "u"
+#endif
+#ifndef PRIxMAX
+# define PRIxMAX LONGEST_MODIFIER "x"
+#endif
+
+#include <ctype.h>
+
+/* Jim Meyering writes:
+
+ "... Some ctype macros are valid only for character codes that
+ isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
+ using /bin/cc or gcc but without giving an ansi option). So, all
+ ctype uses should be through macros like ISPRINT... If
+ STDC_HEADERS is defined, then autoconf has verified that the ctype
+ macros don't need to be guarded with references to isascii. ...
+ Defining isascii to 1 should let any compiler worth its salt
+ eliminate the && through constant folding."
+
+ Bruno Haible adds:
+
+ "... Furthermore, isupper(c) etc. have an undefined result if c is
+ outside the range -1 <= c <= 255. One is tempted to write isupper(c)
+ with c being of type `char', but this is wrong if c is an 8-bit
+ character >= 128 which gets sign-extended to a negative value.
+ The macro ISUPPER protects against this as well." */
+
+#if STDC_HEADERS || (!defined (isascii) && !HAVE_ISASCII)
+# define IN_CTYPE_DOMAIN(c) 1
+#else
+# define IN_CTYPE_DOMAIN(c) isascii(c)
+#endif
+
+#ifdef isblank
+# define ISBLANK(c) (IN_CTYPE_DOMAIN (c) && isblank (c))
+#else
+# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+#ifdef isgraph
+# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isgraph (c))
+#else
+# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isprint (c) && !isspace (c))
+#endif
+
+/* This is defined in <sys/euc.h> on at least Solaris2.6 systems. */
+#undef ISPRINT
+
+#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
+#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
+#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
+#define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl (c))
+#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
+#define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct (c))
+#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
+#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
+#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
+#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
+
+#if STDC_HEADERS
+# define TOLOWER(Ch) tolower (Ch)
+# define TOUPPER(Ch) toupper (Ch)
+#else
+# define TOLOWER(Ch) (ISUPPER (Ch) ? tolower (Ch) : (Ch))
+# define TOUPPER(Ch) (ISLOWER (Ch) ? toupper (Ch) : (Ch))
+#endif
+
+/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
+ - Its arg may be any int or unsigned int; it need not be an unsigned char.
+ - It's guaranteed to evaluate its argument exactly once.
+ - It's typically faster.
+ POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
+ ISDIGIT_LOCALE unless it's important to use the locale's definition
+ of `digit' even when the host does not conform to POSIX. */
+#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
+
+/* Convert a possibly-signed character to an unsigned character. This is
+ a bit safer than casting to unsigned char, since it catches some type
+ errors that the cast doesn't. */
+static inline unsigned char to_uchar (char ch) { return ch; }
+
+/* Take care of NLS matters. */
+
+#if HAVE_LOCALE_H
+# include <locale.h>
+#else
+# define setlocale(Category, Locale) /* empty */
+#endif
+
+#include "gettext.h"
+#if ! ENABLE_NLS
+# undef textdomain
+# define textdomain(Domainname) /* empty */
+# undef bindtextdomain
+# define bindtextdomain(Domainname, Dirname) /* empty */
+#endif
+
+#define _(msgid) gettext (msgid)
+#define N_(msgid) msgid
+
+#ifndef HAVE_SETLOCALE
+# define HAVE_SETLOCALE 0
+#endif
+
+#define STREQ(a, b) (strcmp ((a), (b)) == 0)
+
+#if !HAVE_DECL_FREE
+void free ();
+#endif
+
+#if !HAVE_DECL_MALLOC
+char *malloc ();
+#endif
+
+#if !HAVE_DECL_MEMCHR
+char *memchr ();
+#endif
+
+#if !HAVE_DECL_REALLOC
+char *realloc ();
+#endif
+
+#if !HAVE_DECL_STPCPY
+# ifndef stpcpy
+char *stpcpy ();
+# endif
+#endif
+
+#if !HAVE_DECL_STRNDUP
+char *strndup ();
+#endif
+
+#if !HAVE_DECL_STRSTR
+char *strstr ();
+#endif
+
+#if !HAVE_DECL_GETENV
+char *getenv ();
+#endif
+
+#if !HAVE_DECL_LSEEK
+off_t lseek ();
+#endif
+
+/* This is needed on some AIX systems. */
+#if !HAVE_DECL_STRTOUL
+unsigned long strtoul ();
+#endif
+
+#if !HAVE_DECL_GETLOGIN
+char *getlogin ();
+#endif
+
+#if !HAVE_DECL_TTYNAME
+char *ttyname ();
+#endif
+
+#if !HAVE_DECL_GETEUID
+uid_t geteuid ();
+#endif
+
+#if !HAVE_DECL_GETPWUID
+struct passwd *getpwuid ();
+#endif
+
+#if !HAVE_DECL_GETGRGID
+struct group *getgrgid ();
+#endif
+
+#if !HAVE_DECL_GETUID
+uid_t getuid ();
+#endif
+
+#include "xalloc.h"
+
+#if ! defined HAVE_MEMPCPY && ! defined mempcpy
+/* Be CAREFUL that there are no side effects in N. */
+# define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
+#endif
+
+/* Include automatically-generated macros for unlocked I/O. */
+#include "unlocked-io.h"
+
+#define SAME_INODE(Stat_buf_1, Stat_buf_2) \
+ ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \
+ && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
+
+#define DOT_OR_DOTDOT(Basename) \
+ (Basename[0] == '.' && (Basename[1] == '\0' \
+ || (Basename[1] == '.' && Basename[2] == '\0')))
+
+/* A wrapper for readdir so that callers don't see entries for `.' or `..'. */
+static inline struct dirent const *
+readdir_ignoring_dot_and_dotdot (DIR *dirp)
+{
+ while (1)
+ {
+ struct dirent const *dp = readdir (dirp);
+ if (dp == NULL || ! DOT_OR_DOTDOT (dp->d_name))
+ return dp;
+ }
+}
+
+#if SETVBUF_REVERSED
+# define SETVBUF(Stream, Buffer, Type, Size) \
+ setvbuf (Stream, Type, Buffer, Size)
+#else
+# define SETVBUF(Stream, Buffer, Type, Size) \
+ setvbuf (Stream, Buffer, Type, Size)
+#endif
+
+/* Factor out some of the common --help and --version processing code. */
+
+/* These enum values cannot possibly conflict with the option values
+ ordinarily used by commands, including CHAR_MAX + 1, etc. Avoid
+ CHAR_MIN - 1, as it may equal -1, the getopt end-of-options value. */
+enum
+{
+ GETOPT_HELP_CHAR = (CHAR_MIN - 2),
+ GETOPT_VERSION_CHAR = (CHAR_MIN - 3)
+};
+
+#define GETOPT_HELP_OPTION_DECL \
+ "help", no_argument, 0, GETOPT_HELP_CHAR
+#define GETOPT_VERSION_OPTION_DECL \
+ "version", no_argument, 0, GETOPT_VERSION_CHAR
+
+#define case_GETOPT_HELP_CHAR \
+ case GETOPT_HELP_CHAR: \
+ usage (EXIT_SUCCESS); \
+ break;
+
+#define HELP_OPTION_DESCRIPTION \
+ _(" --help display this help and exit\n")
+#define VERSION_OPTION_DESCRIPTION \
+ _(" --version output version information and exit\n")
+
+#include "closeout.h"
+#include "version-etc.h"
+
+#define case_GETOPT_VERSION_CHAR(Program_name, Authors) \
+ case GETOPT_VERSION_CHAR: \
+ version_etc (stdout, Program_name, GNU_PACKAGE, VERSION, Authors, \
+ (char *) NULL); \
+ exit (EXIT_SUCCESS); \
+ break;
+
+#ifndef MAX
+# define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef MIN
+# define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+/* The extra casts work around common compiler bugs. */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
+ It is necessary at least when t == time_t. */
+#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
+ ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
+#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
+
+/* Upper bound on the string length of an integer converted to string.
+ 302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit;
+ add 1 for integer division truncation; add 1 more for a minus sign. */
+#define INT_STRLEN_BOUND(t) ((sizeof (t) * CHAR_BIT - 1) * 302 / 1000 + 2)
+
+#ifndef CHAR_MIN
+# define CHAR_MIN TYPE_MINIMUM (char)
+#endif
+
+#ifndef CHAR_MAX
+# define CHAR_MAX TYPE_MAXIMUM (char)
+#endif
+
+#ifndef SCHAR_MIN
+# define SCHAR_MIN (-1 - SCHAR_MAX)
+#endif
+
+#ifndef SCHAR_MAX
+# define SCHAR_MAX (CHAR_MAX == UCHAR_MAX ? CHAR_MAX / 2 : CHAR_MAX)
+#endif
+
+#ifndef UCHAR_MAX
+# define UCHAR_MAX TYPE_MAXIMUM (unsigned char)
+#endif
+
+#ifndef SHRT_MIN
+# define SHRT_MIN TYPE_MINIMUM (short int)
+#endif
+
+#ifndef SHRT_MAX
+# define SHRT_MAX TYPE_MAXIMUM (short int)
+#endif
+
+#ifndef INT_MAX
+# define INT_MAX TYPE_MAXIMUM (int)
+#endif
+
+#ifndef INT_MIN
+# define INT_MIN TYPE_MINIMUM (int)
+#endif
+
+#ifndef INTMAX_MAX
+# define INTMAX_MAX TYPE_MAXIMUM (intmax_t)
+#endif
+
+#ifndef INTMAX_MIN
+# define INTMAX_MIN TYPE_MINIMUM (intmax_t)
+#endif
+
+#ifndef UINT_MAX
+# define UINT_MAX TYPE_MAXIMUM (unsigned int)
+#endif
+
+#ifndef LONG_MAX
+# define LONG_MAX TYPE_MAXIMUM (long int)
+#endif
+
+#ifndef ULONG_MAX
+# define ULONG_MAX TYPE_MAXIMUM (unsigned long int)
+#endif
+
+#ifndef SIZE_MAX
+# define SIZE_MAX TYPE_MAXIMUM (size_t)
+#endif
+
+#ifndef SSIZE_MAX
+# define SSIZE_MAX TYPE_MAXIMUM (ssize_t)
+#endif
+
+#ifndef UINTMAX_MAX
+# define UINTMAX_MAX TYPE_MAXIMUM (uintmax_t)
+#endif
+
+#ifndef OFF_T_MIN
+# define OFF_T_MIN TYPE_MINIMUM (off_t)
+#endif
+
+#ifndef OFF_T_MAX
+# define OFF_T_MAX TYPE_MAXIMUM (off_t)
+#endif
+
+#ifndef UID_T_MAX
+# define UID_T_MAX TYPE_MAXIMUM (uid_t)
+#endif
+
+#ifndef GID_T_MAX
+# define GID_T_MAX TYPE_MAXIMUM (gid_t)
+#endif
+
+#ifndef PID_T_MAX
+# define PID_T_MAX TYPE_MAXIMUM (pid_t)
+#endif
+
+/* Use this to suppress gcc's `...may be used before initialized' warnings. */
+#ifdef lint
+# define IF_LINT(Code) Code
+#else
+# define IF_LINT(Code) /* empty */
+#endif
+
+#ifndef __attribute__
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
+# define __attribute__(x)
+# endif
+#endif
+
+#ifndef ATTRIBUTE_NORETURN
+# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
+#endif
+
+#ifndef ATTRIBUTE_UNUSED
+# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#endif
+
+#if defined strdupa
+# define ASSIGN_STRDUPA(DEST, S) \
+ do { DEST = strdupa (S); } while (0)
+#else
+# define ASSIGN_STRDUPA(DEST, S) \
+ do \
+ { \
+ const char *s_ = (S); \
+ size_t len_ = strlen (s_) + 1; \
+ char *tmp_dest_ = alloca (len_); \
+ DEST = memcpy (tmp_dest_, (s_), len_); \
+ } \
+ while (0)
+#endif
+
+#ifndef EOVERFLOW
+# define EOVERFLOW EINVAL
+#endif
+
+#if ! HAVE_FSEEKO && ! defined fseeko
+# define fseeko(s, o, w) ((o) == (long int) (o) \
+ ? fseek (s, o, w) \
+ : (errno = EOVERFLOW, -1))
+#endif
+
+/* Compute the greatest common divisor of U and V using Euclid's
+ algorithm. U and V must be nonzero. */
+
+static inline size_t
+gcd (size_t u, size_t v)
+{
+ do
+ {
+ size_t t = u % v;
+ u = v;
+ v = t;
+ }
+ while (v);
+
+ return u;
+}
+
+/* Compute the least common multiple of U and V. U and V must be
+ nonzero. There is no overflow checking, so callers should not
+ specify outlandish sizes. */
+
+static inline size_t
+lcm (size_t u, size_t v)
+{
+ return u * (v / gcd (u, v));
+}
+
+/* Return PTR, aligned upward to the next multiple of ALIGNMENT.
+ ALIGNMENT must be nonzero. The caller must arrange for ((char *)
+ PTR) through ((char *) PTR + ALIGNMENT - 1) to be addressable
+ locations. */
+
+static inline void *
+ptr_align (void *ptr, size_t alignment)
+{
+ char *p0 = ptr;
+ char *p1 = p0 + alignment - 1;
+ return p1 - (size_t) p1 % alignment;
+}
diff --git a/crypto/openssl/fips/Makefile b/crypto/openssl/fips/Makefile
new file mode 100644
index 0000000..546b54b
--- /dev/null
+++ b/crypto/openssl/fips/Makefile
@@ -0,0 +1,230 @@
+#
+# OpenSSL/crypto/Makefile
+#
+
+DIR= fips
+TOP= ..
+CC= cc
+INCLUDE= -I. -I$(TOP) -I../include
+# INCLUDES targets sudbirs!
+INCLUDES= -I.. -I../.. -I../../include
+CFLAG= -g
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile
+RM= rm -f
+AR= ar r
+ARD= ar d
+TEST= fips_test_suite.c
+FIPS_TVDIR= testvectors
+FIPS_TVOK= $$HOME/fips/tv.ok
+
+FIPSCANLOC= $(FIPSLIBDIR)fipscanister.o
+
+RECURSIVE_MAKE= [ -n "$(FDIRS)" ] && for i in $(FDIRS) ; do \
+ (cd $$i && echo "making $$target in $(DIR)/$$i..." && \
+ $(MAKE) -e TOP=../.. DIR=$$i INCLUDES='${INCLUDES}' $$target ) || exit 1; \
+ done;
+
+PEX_LIBS=
+EX_LIBS=
+
+CFLAGS= $(INCLUDE) $(CFLAG) -DHMAC_EXT=\"$${HMAC_EXT:-sha1}\"
+ASFLAGS= $(INCLUDE) $(ASFLAG)
+AFLAGS=$(ASFLAGS)
+
+LIBS=
+
+FDIRS=sha rand des aes dsa rsa dh hmac
+
+GENERAL=Makefile README fips-lib.com install.com
+
+LIB= $(TOP)/libcrypto.a
+SHARED_LIB= $(FIPSCANLIB)$(SHLIB_EXT)
+LIBSRC=fips.c
+LIBOBJ=fips.o
+
+FIPS_OBJ_LISTS=sha/lib hmac/lib rand/lib des/lib aes/lib dsa/lib rsa/lib dh/lib
+
+SRC= $(LIBSRC)
+
+EXHEADER=fips.h
+HEADER=$(EXHEADER) fips_utl.h fips_locl.h
+EXE=fipsld
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ @(cd ..; $(MAKE) DIRS=$(DIR) all)
+
+testapps:
+ @if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
+
+all:
+ @if [ -z "$(FIPSLIBDIR)" ]; then \
+ $(MAKE) -e subdirs lib fips_premain_dso$(EXE_EXT); \
+ else \
+ $(MAKE) -e lib fips_premain_dso$(EXE_EXT) fips_standalone_sha1$(EXE_EXT); \
+ fi
+
+# Idea behind fipscanister.o is to "seize" the sequestered code between
+# known symbols for fingerprinting purposes, which would be commonly
+# done with ld -r start.o ... end.o. The latter however presents a minor
+# challenge on multi-ABI platforms. As just implied, we'd rather use ld,
+# but the trouble is that we don't generally know how ABI-selection
+# compiler flag is translated to corresponding linker flag. All compiler
+# drivers seem to recognize -r flag and pass it down to linker, but some
+# of them, including gcc, erroneously add -lc, as well as run-time
+# components, such as crt1.o and alike. Fortunately among those vendor
+# compilers which were observed to misinterpret -r flag multi-ABI ones
+# are equipped with smart linkers, which don't require any ABI-selection
+# flag and simply assume that all objects are of the same type as first
+# one in command line. So the idea is to identify gcc and deficient
+# vendor compiler drivers...
+
+fipscanister.o: fips_start.o $(LIBOBJ) $(FIPS_OBJ_LISTS) fips_end.o
+ FIPS_ASM=""; \
+ list="$(BN_ASM)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/bn/$$i" ; done; \
+ list="$(AES_ASM_OBJ)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/aes/$$i" ; done; \
+ list="$(DES_ENC)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/des/$$i" ; done; \
+ list="$(SHA1_ASM_OBJ)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/sha/$$i" ; done; \
+ if [ -n "$(CPUID_OBJ)" ]; then \
+ CPUID=../crypto/$(CPUID_OBJ) ; \
+ else \
+ CPUID="" ; \
+ fi ; \
+ objs="fips_start.o $(LIBOBJ) $(FIPS_EX_OBJ) $$CPUID $$FIPS_ASM"; \
+ for i in $(FIPS_OBJ_LISTS); do \
+ dir=`dirname $$i`; script="s|^|$$dir/|;s| | $$dir/|g"; \
+ objs="$$objs `sed "$$script" $$i`"; \
+ done; \
+ objs="$$objs fips_end.o" ; \
+ os="`(uname -s) 2>/dev/null`"; cflags="$(CFLAGS)"; \
+ [ "$$os" = "AIX" ] && cflags="$$cflags -Wl,-bnoobjreorder"; \
+ if [ -n "${FIPS_SITE_LD}" ]; then \
+ set -x; ${FIPS_SITE_LD} -r -o $@ $$objs; \
+ elif $(CC) -dumpversion >/dev/null 2>&1; then \
+ set -x; $(CC) $$cflags -r -nostdlib -o $@ $$objs ; \
+ else case "$$os" in \
+ HP-UX|OSF1|SunOS) set -x; /usr/ccs/bin/ld -r -o $@ $$objs ;; \
+ *) set -x; $(CC) $$cflags -r -o $@ $$objs ;; \
+ esac fi
+ ./fips_standalone_sha1$(EXE_EXT) fipscanister.o > fipscanister.o.sha1
+
+# If another exception is immediately required, assign approprite
+# site-specific ld command to FIPS_SITE_LD environment variable.
+
+fips_start.o: fips_canister.c
+ $(CC) $(CFLAGS) -DFIPS_START -c -o $@ fips_canister.c
+fips_end.o: fips_canister.c
+ $(CC) $(CFLAGS) -DFIPS_END -c -o $@ fips_canister.c
+fips_premain_dso$(EXE_EXT): fips_premain.c
+ $(CC) $(CFLAGS) -DFINGERPRINT_PREMAIN_DSO_LOAD -o $@ fips_premain.c \
+ $(FIPSLIBDIR)fipscanister.o ../libcrypto.a $(EX_LIBS)
+# this is executed only when linking with external fipscanister.o
+fips_standalone_sha1$(EXE_EXT): sha/fips_standalone_sha1.c
+ if [ -z "$(HOSTCC)" ] ; then \
+ $(CC) $(CFLAGS) -DFIPSCANISTER_O -o $@ sha/fips_standalone_sha1.c $(FIPSLIBDIR)fipscanister.o $(EX_LIBS) ; \
+ else \
+ $(HOSTCC) $(HOSTCFLAGS) -o $ $@ -I../include -I../crypto sha/fips_standalone_sha1.c ../crypto/sha/sha1dgst.c ; \
+ fi
+
+subdirs:
+ @target=all; $(RECURSIVE_MAKE)
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+ @target=files; $(RECURSIVE_MAKE)
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl ../include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl ../test $(TEST)
+ @target=links; $(RECURSIVE_MAKE)
+
+# lib: and $(LIB): are splitted to avoid end-less loop
+lib: $(LIB)
+ if [ "$(FIPSCANISTERINTERNAL)" = "n" -a -n "$(FIPSCANLOC)" ]; then $(AR) ../$(FIPSCANLIB).a $(FIPSCANLOC); fi
+ @touch lib
+
+$(LIB): $(FIPSLIBDIR)fipscanister.o
+ $(AR) $(LIB) $(FIPSLIBDIR)fipscanister.o
+ $(RANLIB) $(LIB) || echo Never mind.
+
+$(FIPSCANLIB): $(FIPSCANLOC)
+ $(AR) ../$(FIPSCANLIB).a $(FIPSCANLOC)
+ if [ "$(FIPSCANLIB)" = "libfips" ]; then \
+ $(AR) $(LIB) $(FIPSCANLOC) ; \
+ $(RANLIB) $(LIB) || echo Never Mind. ; \
+ fi
+ $(RANLIB) ../$(FIPSCANLIB).a || echo Never mind.
+ @touch lib
+
+shared: lib subdirs fips_premain_dso$(EXE_EXT)
+
+libs:
+ @target=lib; $(RECURSIVE_MAKE)
+
+fips_test: top
+ @target=fips_test; $(RECURSIVE_MAKE)
+
+fips_test_diff:
+ @if diff -b -B -I '^\#' -cr -X fips-nodiff.txt $(FIPS_TVDIR) $(FIPS_TVOK) ; then \
+ echo "FIPS diff OK" ; \
+ else \
+ echo "***FIPS DIFF ERROR***" ; exit 1 ; \
+ fi
+
+
+install:
+ @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+ @headerlist="$(EXHEADER)"; for i in $$headerlist ;\
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done;
+ @target=install; $(RECURSIVE_MAKE)
+ for i in $(EXE) ; \
+ do \
+ echo "installing $$i"; \
+ cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+ chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i; \
+ done
+ cp -p -f $(FIPSLIBDIR)fipscanister.o $(FIPSLIBDIR)fipscanister.o.sha1 \
+ $(FIPSLIBDIR)fips_premain.c $(FIPSLIBDIR)fips_premain.c.sha1 \
+ $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/; \
+ chmod 0444 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/fips*
+
+lint:
+ @target=lint; $(RECURSIVE_MAKE)
+
+depend:
+ @[ -z "$(THIS)" ] || $(MAKEDEPEND) -- $(CFLAG) $(INCLUDE) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+ @[ -z "$(THIS)" ] || (set -e; target=depend; $(RECURSIVE_MAKE) )
+ @if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
+
+clean:
+ rm -f fipscanister.o.sha1 fips_premain_dso$(EXE_EXT) fips_standalone_sha1$(EXE_EXT) \
+ *.s *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+ @target=clean; $(RECURSIVE_MAKE)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+ @target=dclean; $(RECURSIVE_MAKE)
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+fips.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+fips.o: ../include/openssl/crypto.h ../include/openssl/des.h
+fips.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
+fips.o: ../include/openssl/err.h ../include/openssl/evp.h
+fips.o: ../include/openssl/fips.h ../include/openssl/fips_rand.h
+fips.o: ../include/openssl/hmac.h ../include/openssl/lhash.h
+fips.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+fips.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+fips.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
+fips.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+fips.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+fips.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h fips.c
+fips.o: fips_locl.h
diff --git a/crypto/openssl/fips/aes/Makefile b/crypto/openssl/fips/aes/Makefile
new file mode 100644
index 0000000..7b8b3a2
--- /dev/null
+++ b/crypto/openssl/fips/aes/Makefile
@@ -0,0 +1,111 @@
+#
+# OpenSSL/fips/aes/Makefile
+#
+
+DIR= aes
+TOP= ../..
+CC= cc
+INCLUDES=
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile
+AR= ar r
+
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=fips_aesavs.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=fips_aes_selftest.c
+LIBOBJ=fips_aes_selftest.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=
+HEADER=
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ @echo $(LIBOBJ) > lib
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
+
+install:
+ @headerlist="$(EXHEADER)"; for i in $$headerlist; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+fips_test:
+ -find ../testvectors/aes/req -name '*.req' > testlist
+ -rm -rf ../testvectors/aes/rsp
+ mkdir ../testvectors/aes/rsp
+ if [ -s testlist ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_aesavs -d testlist; fi
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) \
+ $(SRC) $(TEST)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff testlist
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+fips_aes_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_aes_selftest.o: ../../include/openssl/crypto.h
+fips_aes_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_aes_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_aes_selftest.o: ../../include/openssl/lhash.h
+fips_aes_selftest.o: ../../include/openssl/obj_mac.h
+fips_aes_selftest.o: ../../include/openssl/objects.h
+fips_aes_selftest.o: ../../include/openssl/opensslconf.h
+fips_aes_selftest.o: ../../include/openssl/opensslv.h
+fips_aes_selftest.o: ../../include/openssl/ossl_typ.h
+fips_aes_selftest.o: ../../include/openssl/safestack.h
+fips_aes_selftest.o: ../../include/openssl/stack.h
+fips_aes_selftest.o: ../../include/openssl/symhacks.h fips_aes_selftest.c
+fips_aesavs.o: ../../e_os.h ../../include/openssl/aes.h
+fips_aesavs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_aesavs.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_aesavs.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_aesavs.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_aesavs.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_aesavs.o: ../../include/openssl/objects.h
+fips_aesavs.o: ../../include/openssl/opensslconf.h
+fips_aesavs.o: ../../include/openssl/opensslv.h
+fips_aesavs.o: ../../include/openssl/ossl_typ.h
+fips_aesavs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_aesavs.o: ../../include/openssl/symhacks.h ../fips_utl.h fips_aesavs.c
diff --git a/crypto/openssl/fips/aes/fips_aes_selftest.c b/crypto/openssl/fips/aes/fips_aes_selftest.c
new file mode 100644
index 0000000..441bbc1
--- /dev/null
+++ b/crypto/openssl/fips/aes/fips_aes_selftest.c
@@ -0,0 +1,101 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+#include <openssl/evp.h>
+
+#ifdef OPENSSL_FIPS
+static struct
+ {
+ unsigned char key[16];
+ unsigned char plaintext[16];
+ unsigned char ciphertext[16];
+ } tests[]=
+ {
+ {
+ { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F },
+ { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
+ 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF },
+ { 0x69,0xC4,0xE0,0xD8,0x6A,0x7B,0x04,0x30,
+ 0xD8,0xCD,0xB7,0x80,0x70,0xB4,0xC5,0x5A },
+ },
+ };
+
+void FIPS_corrupt_aes()
+ {
+ tests[0].key[0]++;
+ }
+
+int FIPS_selftest_aes()
+ {
+ int n;
+ int ret = 0;
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+
+ for(n=0 ; n < 1 ; ++n)
+ {
+ if (fips_cipher_test(&ctx, EVP_aes_128_ecb(),
+ tests[n].key, NULL,
+ tests[n].plaintext,
+ tests[n].ciphertext,
+ 16) <= 0)
+ goto err;
+ }
+ ret = 1;
+ err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ if (ret == 0)
+ FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED);
+ return ret;
+ }
+#endif
diff --git a/crypto/openssl/fips/aes/fips_aesavs.c b/crypto/openssl/fips/aes/fips_aesavs.c
new file mode 100644
index 0000000..a3c8b40
--- /dev/null
+++ b/crypto/openssl/fips/aes/fips_aesavs.c
@@ -0,0 +1,939 @@
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*---------------------------------------------
+ NIST AES Algorithm Validation Suite
+ Test Program
+
+ Donated to OpenSSL by:
+ V-ONE Corporation
+ 20250 Century Blvd, Suite 300
+ Germantown, MD 20874
+ U.S.A.
+ ----------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <ctype.h>
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+
+#include <openssl/err.h>
+#include "e_os.h"
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+ printf("No FIPS AES support\n");
+ return(0);
+}
+
+#else
+
+#include <openssl/fips.h>
+#include "fips_utl.h"
+
+#define AES_BLOCK_SIZE 16
+
+#define VERBOSE 0
+
+/*-----------------------------------------------*/
+
+static int AESTest(EVP_CIPHER_CTX *ctx,
+ char *amode, int akeysz, unsigned char *aKey,
+ unsigned char *iVec,
+ int dir, /* 0 = decrypt, 1 = encrypt */
+ unsigned char *plaintext, unsigned char *ciphertext, int len)
+ {
+ const EVP_CIPHER *cipher = NULL;
+
+ if (strcasecmp(amode, "CBC") == 0)
+ {
+ switch (akeysz)
+ {
+ case 128:
+ cipher = EVP_aes_128_cbc();
+ break;
+
+ case 192:
+ cipher = EVP_aes_192_cbc();
+ break;
+
+ case 256:
+ cipher = EVP_aes_256_cbc();
+ break;
+ }
+
+ }
+ else if (strcasecmp(amode, "ECB") == 0)
+ {
+ switch (akeysz)
+ {
+ case 128:
+ cipher = EVP_aes_128_ecb();
+ break;
+
+ case 192:
+ cipher = EVP_aes_192_ecb();
+ break;
+
+ case 256:
+ cipher = EVP_aes_256_ecb();
+ break;
+ }
+ }
+ else if (strcasecmp(amode, "CFB128") == 0)
+ {
+ switch (akeysz)
+ {
+ case 128:
+ cipher = EVP_aes_128_cfb128();
+ break;
+
+ case 192:
+ cipher = EVP_aes_192_cfb128();
+ break;
+
+ case 256:
+ cipher = EVP_aes_256_cfb128();
+ break;
+ }
+
+ }
+ else if (strncasecmp(amode, "OFB", 3) == 0)
+ {
+ switch (akeysz)
+ {
+ case 128:
+ cipher = EVP_aes_128_ofb();
+ break;
+
+ case 192:
+ cipher = EVP_aes_192_ofb();
+ break;
+
+ case 256:
+ cipher = EVP_aes_256_ofb();
+ break;
+ }
+ }
+ else if(!strcasecmp(amode,"CFB1"))
+ {
+ switch (akeysz)
+ {
+ case 128:
+ cipher = EVP_aes_128_cfb1();
+ break;
+
+ case 192:
+ cipher = EVP_aes_192_cfb1();
+ break;
+
+ case 256:
+ cipher = EVP_aes_256_cfb1();
+ break;
+ }
+ }
+ else if(!strcasecmp(amode,"CFB8"))
+ {
+ switch (akeysz)
+ {
+ case 128:
+ cipher = EVP_aes_128_cfb8();
+ break;
+
+ case 192:
+ cipher = EVP_aes_192_cfb8();
+ break;
+
+ case 256:
+ cipher = EVP_aes_256_cfb8();
+ break;
+ }
+ }
+ else
+ {
+ printf("Unknown mode: %s\n", amode);
+ return 0;
+ }
+ if (!cipher)
+ {
+ printf("Invalid key size: %d\n", akeysz);
+ return 0;
+ }
+ if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0)
+ return 0;
+ if(!strcasecmp(amode,"CFB1"))
+ M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS);
+ if (dir)
+ EVP_Cipher(ctx, ciphertext, plaintext, len);
+ else
+ EVP_Cipher(ctx, plaintext, ciphertext, len);
+ return 1;
+ }
+
+/*-----------------------------------------------*/
+char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"};
+char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB128"};
+enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB128};
+enum XCrypt {XDECRYPT, XENCRYPT};
+
+/*=============================*/
+/* Monte Carlo Tests */
+/*-----------------------------*/
+
+/*#define gb(a,b) (((a)[(b)/8] >> ((b)%8))&1)*/
+/*#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << ((b)%8)))|(!!(v) << ((b)%8)))*/
+
+#define gb(a,b) (((a)[(b)/8] >> (7-(b)%8))&1)
+#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << (7-(b)%8)))|(!!(v) << (7-(b)%8)))
+
+static int do_mct(char *amode,
+ int akeysz, unsigned char *aKey,unsigned char *iVec,
+ int dir, unsigned char *text, int len,
+ FILE *rfp)
+ {
+ int ret = 0;
+ unsigned char key[101][32];
+ unsigned char iv[101][AES_BLOCK_SIZE];
+ unsigned char ptext[1001][32];
+ unsigned char ctext[1001][32];
+ unsigned char ciphertext[64+4];
+ int i, j, n, n1, n2;
+ int imode = 0, nkeysz = akeysz/8;
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+
+ if (len > 32)
+ {
+ printf("\n>>>> Length exceeds 32 for %s %d <<<<\n\n",
+ amode, akeysz);
+ return -1;
+ }
+ for (imode = 0; imode < 6; ++imode)
+ if (strcmp(amode, t_mode[imode]) == 0)
+ break;
+ if (imode == 6)
+ {
+ printf("Unrecognized mode: %s\n", amode);
+ return -1;
+ }
+
+ memcpy(key[0], aKey, nkeysz);
+ if (iVec)
+ memcpy(iv[0], iVec, AES_BLOCK_SIZE);
+ if (dir == XENCRYPT)
+ memcpy(ptext[0], text, len);
+ else
+ memcpy(ctext[0], text, len);
+ for (i = 0; i < 100; ++i)
+ {
+ /* printf("Iteration %d\n", i); */
+ if (i > 0)
+ {
+ fprintf(rfp,"COUNT = %d\n",i);
+ OutputValue("KEY",key[i],nkeysz,rfp,0);
+ if (imode != ECB) /* ECB */
+ OutputValue("IV",iv[i],AES_BLOCK_SIZE,rfp,0);
+ /* Output Ciphertext | Plaintext */
+ OutputValue(t_tag[dir^1],dir ? ptext[0] : ctext[0],len,rfp,
+ imode == CFB1);
+ }
+ for (j = 0; j < 1000; ++j)
+ {
+ switch (imode)
+ {
+ case ECB:
+ if (j == 0)
+ { /* set up encryption */
+ ret = AESTest(&ctx, amode, akeysz, key[i], NULL,
+ dir, /* 0 = decrypt, 1 = encrypt */
+ ptext[j], ctext[j], len);
+ if (dir == XENCRYPT)
+ memcpy(ptext[j+1], ctext[j], len);
+ else
+ memcpy(ctext[j+1], ptext[j], len);
+ }
+ else
+ {
+ if (dir == XENCRYPT)
+ {
+ EVP_Cipher(&ctx, ctext[j], ptext[j], len);
+ memcpy(ptext[j+1], ctext[j], len);
+ }
+ else
+ {
+ EVP_Cipher(&ctx, ptext[j], ctext[j], len);
+ memcpy(ctext[j+1], ptext[j], len);
+ }
+ }
+ break;
+
+ case CBC:
+ case OFB:
+ case CFB128:
+ if (j == 0)
+ {
+ ret = AESTest(&ctx, amode, akeysz, key[i], iv[i],
+ dir, /* 0 = decrypt, 1 = encrypt */
+ ptext[j], ctext[j], len);
+ if (dir == XENCRYPT)
+ memcpy(ptext[j+1], iv[i], len);
+ else
+ memcpy(ctext[j+1], iv[i], len);
+ }
+ else
+ {
+ if (dir == XENCRYPT)
+ {
+ EVP_Cipher(&ctx, ctext[j], ptext[j], len);
+ memcpy(ptext[j+1], ctext[j-1], len);
+ }
+ else
+ {
+ EVP_Cipher(&ctx, ptext[j], ctext[j], len);
+ memcpy(ctext[j+1], ptext[j-1], len);
+ }
+ }
+ break;
+
+ case CFB8:
+ if (j == 0)
+ {
+ ret = AESTest(&ctx, amode, akeysz, key[i], iv[i],
+ dir, /* 0 = decrypt, 1 = encrypt */
+ ptext[j], ctext[j], len);
+ }
+ else
+ {
+ if (dir == XENCRYPT)
+ EVP_Cipher(&ctx, ctext[j], ptext[j], len);
+ else
+ EVP_Cipher(&ctx, ptext[j], ctext[j], len);
+ }
+ if (dir == XENCRYPT)
+ {
+ if (j < 16)
+ memcpy(ptext[j+1], &iv[i][j], len);
+ else
+ memcpy(ptext[j+1], ctext[j-16], len);
+ }
+ else
+ {
+ if (j < 16)
+ memcpy(ctext[j+1], &iv[i][j], len);
+ else
+ memcpy(ctext[j+1], ptext[j-16], len);
+ }
+ break;
+
+ case CFB1:
+ if(j == 0)
+ {
+#if 0
+ /* compensate for wrong endianness of input file */
+ if(i == 0)
+ ptext[0][0]<<=7;
+#endif
+ ret = AESTest(&ctx,amode,akeysz,key[i],iv[i],dir,
+ ptext[j], ctext[j], len);
+ }
+ else
+ {
+ if (dir == XENCRYPT)
+ EVP_Cipher(&ctx, ctext[j], ptext[j], len);
+ else
+ EVP_Cipher(&ctx, ptext[j], ctext[j], len);
+
+ }
+ if(dir == XENCRYPT)
+ {
+ if(j < 128)
+ sb(ptext[j+1],0,gb(iv[i],j));
+ else
+ sb(ptext[j+1],0,gb(ctext[j-128],0));
+ }
+ else
+ {
+ if(j < 128)
+ sb(ctext[j+1],0,gb(iv[i],j));
+ else
+ sb(ctext[j+1],0,gb(ptext[j-128],0));
+ }
+ break;
+ }
+ }
+ --j; /* reset to last of range */
+ /* Output Ciphertext | Plaintext */
+ OutputValue(t_tag[dir],dir ? ctext[j] : ptext[j],len,rfp,
+ imode == CFB1);
+ fprintf(rfp, "\n"); /* add separator */
+
+ /* Compute next KEY */
+ if (dir == XENCRYPT)
+ {
+ if (imode == CFB8)
+ { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */
+ for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2)
+ ciphertext[n1] = ctext[j-n2][0];
+ }
+ else if(imode == CFB1)
+ {
+ for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2)
+ sb(ciphertext,n1,gb(ctext[j-n2],0));
+ }
+ else
+ switch (akeysz)
+ {
+ case 128:
+ memcpy(ciphertext, ctext[j], 16);
+ break;
+ case 192:
+ memcpy(ciphertext, ctext[j-1]+8, 8);
+ memcpy(ciphertext+8, ctext[j], 16);
+ break;
+ case 256:
+ memcpy(ciphertext, ctext[j-1], 16);
+ memcpy(ciphertext+16, ctext[j], 16);
+ break;
+ }
+ }
+ else
+ {
+ if (imode == CFB8)
+ { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */
+ for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2)
+ ciphertext[n1] = ptext[j-n2][0];
+ }
+ else if(imode == CFB1)
+ {
+ for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2)
+ sb(ciphertext,n1,gb(ptext[j-n2],0));
+ }
+ else
+ switch (akeysz)
+ {
+ case 128:
+ memcpy(ciphertext, ptext[j], 16);
+ break;
+ case 192:
+ memcpy(ciphertext, ptext[j-1]+8, 8);
+ memcpy(ciphertext+8, ptext[j], 16);
+ break;
+ case 256:
+ memcpy(ciphertext, ptext[j-1], 16);
+ memcpy(ciphertext+16, ptext[j], 16);
+ break;
+ }
+ }
+ /* Compute next key: Key[i+1] = Key[i] xor ct */
+ for (n = 0; n < nkeysz; ++n)
+ key[i+1][n] = key[i][n] ^ ciphertext[n];
+
+ /* Compute next IV and text */
+ if (dir == XENCRYPT)
+ {
+ switch (imode)
+ {
+ case ECB:
+ memcpy(ptext[0], ctext[j], AES_BLOCK_SIZE);
+ break;
+ case CBC:
+ case OFB:
+ case CFB128:
+ memcpy(iv[i+1], ctext[j], AES_BLOCK_SIZE);
+ memcpy(ptext[0], ctext[j-1], AES_BLOCK_SIZE);
+ break;
+ case CFB8:
+ /* IV[i+1] = ct */
+ for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2)
+ iv[i+1][n1] = ctext[j-n2][0];
+ ptext[0][0] = ctext[j-16][0];
+ break;
+ case CFB1:
+ for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2)
+ sb(iv[i+1],n1,gb(ctext[j-n2],0));
+ ptext[0][0]=ctext[j-128][0]&0x80;
+ break;
+ }
+ }
+ else
+ {
+ switch (imode)
+ {
+ case ECB:
+ memcpy(ctext[0], ptext[j], AES_BLOCK_SIZE);
+ break;
+ case CBC:
+ case OFB:
+ case CFB128:
+ memcpy(iv[i+1], ptext[j], AES_BLOCK_SIZE);
+ memcpy(ctext[0], ptext[j-1], AES_BLOCK_SIZE);
+ break;
+ case CFB8:
+ for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2)
+ iv[i+1][n1] = ptext[j-n2][0];
+ ctext[0][0] = ptext[j-16][0];
+ break;
+ case CFB1:
+ for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2)
+ sb(iv[i+1],n1,gb(ptext[j-n2],0));
+ ctext[0][0]=ptext[j-128][0]&0x80;
+ break;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+/*================================================*/
+/*----------------------------
+ # Config info for v-one
+ # AESVS MMT test data for ECB
+ # State : Encrypt and Decrypt
+ # Key Length : 256
+ # Fri Aug 30 04:07:22 PM
+ ----------------------------*/
+
+static int proc_file(char *rqfile, char *rspfile)
+ {
+ char afn[256], rfn[256];
+ FILE *afp = NULL, *rfp = NULL;
+ char ibuf[2048];
+ char tbuf[2048];
+ int ilen, len, ret = 0;
+ char algo[8] = "";
+ char amode[8] = "";
+ char atest[8] = "";
+ int akeysz = 0;
+ unsigned char iVec[20], aKey[40];
+ int dir = -1, err = 0, step = 0;
+ unsigned char plaintext[2048];
+ unsigned char ciphertext[2048];
+ char *rp;
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+
+ if (!rqfile || !(*rqfile))
+ {
+ printf("No req file\n");
+ return -1;
+ }
+ strcpy(afn, rqfile);
+
+ if ((afp = fopen(afn, "r")) == NULL)
+ {
+ printf("Cannot open file: %s, %s\n",
+ afn, strerror(errno));
+ return -1;
+ }
+ if (!rspfile)
+ {
+ strcpy(rfn,afn);
+ rp=strstr(rfn,"req/");
+#ifdef OPENSSL_SYS_WIN32
+ if (!rp)
+ rp=strstr(rfn,"req\\");
+#endif
+ assert(rp);
+ memcpy(rp,"rsp",3);
+ rp = strstr(rfn, ".req");
+ memcpy(rp, ".rsp", 4);
+ rspfile = rfn;
+ }
+ if ((rfp = fopen(rspfile, "w")) == NULL)
+ {
+ printf("Cannot open file: %s, %s\n",
+ rfn, strerror(errno));
+ fclose(afp);
+ afp = NULL;
+ return -1;
+ }
+ while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL)
+ {
+ tidy_line(tbuf, ibuf);
+ ilen = strlen(ibuf);
+ /* printf("step=%d ibuf=%s",step,ibuf); */
+ switch (step)
+ {
+ case 0: /* read preamble */
+ if (ibuf[0] == '\n')
+ { /* end of preamble */
+ if ((*algo == '\0') ||
+ (*amode == '\0') ||
+ (akeysz == 0))
+ {
+ printf("Missing Algorithm, Mode or KeySize (%s/%s/%d)\n",
+ algo,amode,akeysz);
+ err = 1;
+ }
+ else
+ {
+ fputs(ibuf, rfp);
+ ++ step;
+ }
+ }
+ else if (ibuf[0] != '#')
+ {
+ printf("Invalid preamble item: %s\n", ibuf);
+ err = 1;
+ }
+ else
+ { /* process preamble */
+ char *xp, *pp = ibuf+2;
+ int n;
+ if (akeysz)
+ { /* insert current time & date */
+ time_t rtim = time(0);
+ fprintf(rfp, "# %s", ctime(&rtim));
+ }
+ else
+ {
+ fputs(ibuf, rfp);
+ if (strncmp(pp, "AESVS ", 6) == 0)
+ {
+ strcpy(algo, "AES");
+ /* get test type */
+ pp += 6;
+ xp = strchr(pp, ' ');
+ n = xp-pp;
+ strncpy(atest, pp, n);
+ atest[n] = '\0';
+ /* get mode */
+ xp = strrchr(pp, ' '); /* get mode" */
+ n = strlen(xp+1)-1;
+ strncpy(amode, xp+1, n);
+ amode[n] = '\0';
+ /* amode[3] = '\0'; */
+ if (VERBOSE)
+ printf("Test = %s, Mode = %s\n", atest, amode);
+ }
+ else if (strncasecmp(pp, "Key Length : ", 13) == 0)
+ {
+ akeysz = atoi(pp+13);
+ if (VERBOSE)
+ printf("Key size = %d\n", akeysz);
+ }
+ }
+ }
+ break;
+
+ case 1: /* [ENCRYPT] | [DECRYPT] */
+ if (ibuf[0] == '[')
+ {
+ fputs(ibuf, rfp);
+ ++step;
+ if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0)
+ dir = 1;
+ else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0)
+ dir = 0;
+ else
+ {
+ printf("Invalid keyword: %s\n", ibuf);
+ err = 1;
+ }
+ break;
+ }
+ else if (dir == -1)
+ {
+ err = 1;
+ printf("Missing ENCRYPT/DECRYPT keyword\n");
+ break;
+ }
+ else
+ step = 2;
+
+ case 2: /* KEY = xxxx */
+ fputs(ibuf, rfp);
+ if(*ibuf == '\n')
+ break;
+ if(!strncasecmp(ibuf,"COUNT = ",8))
+ break;
+
+ if (strncasecmp(ibuf, "KEY = ", 6) != 0)
+ {
+ printf("Missing KEY\n");
+ err = 1;
+ }
+ else
+ {
+ len = hex2bin((char*)ibuf+6, aKey);
+ if (len < 0)
+ {
+ printf("Invalid KEY\n");
+ err =1;
+ break;
+ }
+ PrintValue("KEY", aKey, len);
+ if (strcmp(amode, "ECB") == 0)
+ {
+ memset(iVec, 0, sizeof(iVec));
+ step = (dir)? 4: 5; /* no ivec for ECB */
+ }
+ else
+ ++step;
+ }
+ break;
+
+ case 3: /* IV = xxxx */
+ fputs(ibuf, rfp);
+ if (strncasecmp(ibuf, "IV = ", 5) != 0)
+ {
+ printf("Missing IV\n");
+ err = 1;
+ }
+ else
+ {
+ len = hex2bin((char*)ibuf+5, iVec);
+ if (len < 0)
+ {
+ printf("Invalid IV\n");
+ err =1;
+ break;
+ }
+ PrintValue("IV", iVec, len);
+ step = (dir)? 4: 5;
+ }
+ break;
+
+ case 4: /* PLAINTEXT = xxxx */
+ fputs(ibuf, rfp);
+ if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0)
+ {
+ printf("Missing PLAINTEXT\n");
+ err = 1;
+ }
+ else
+ {
+ int nn = strlen(ibuf+12);
+ if(!strcmp(amode,"CFB1"))
+ len=bint2bin(ibuf+12,nn-1,plaintext);
+ else
+ len=hex2bin(ibuf+12, plaintext);
+ if (len < 0)
+ {
+ printf("Invalid PLAINTEXT: %s", ibuf+12);
+ err =1;
+ break;
+ }
+ if (len >= (int)sizeof(plaintext))
+ {
+ printf("Buffer overflow\n");
+ }
+ PrintValue("PLAINTEXT", (unsigned char*)plaintext, len);
+ if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */
+ {
+ if(do_mct(amode, akeysz, aKey, iVec,
+ dir, (unsigned char*)plaintext, len,
+ rfp) < 0)
+ EXIT(1);
+ }
+ else
+ {
+ ret = AESTest(&ctx, amode, akeysz, aKey, iVec,
+ dir, /* 0 = decrypt, 1 = encrypt */
+ plaintext, ciphertext, len);
+ OutputValue("CIPHERTEXT",ciphertext,len,rfp,
+ !strcmp(amode,"CFB1"));
+ }
+ step = 6;
+ }
+ break;
+
+ case 5: /* CIPHERTEXT = xxxx */
+ fputs(ibuf, rfp);
+ if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0)
+ {
+ printf("Missing KEY\n");
+ err = 1;
+ }
+ else
+ {
+ if(!strcmp(amode,"CFB1"))
+ len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext);
+ else
+ len = hex2bin(ibuf+13,ciphertext);
+ if (len < 0)
+ {
+ printf("Invalid CIPHERTEXT\n");
+ err =1;
+ break;
+ }
+
+ PrintValue("CIPHERTEXT", ciphertext, len);
+ if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */
+ {
+ do_mct(amode, akeysz, aKey, iVec,
+ dir, ciphertext, len, rfp);
+ }
+ else
+ {
+ ret = AESTest(&ctx, amode, akeysz, aKey, iVec,
+ dir, /* 0 = decrypt, 1 = encrypt */
+ plaintext, ciphertext, len);
+ OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp,
+ !strcmp(amode,"CFB1"));
+ }
+ step = 6;
+ }
+ break;
+
+ case 6:
+ if (ibuf[0] != '\n')
+ {
+ err = 1;
+ printf("Missing terminator\n");
+ }
+ else if (strcmp(atest, "MCT") != 0)
+ { /* MCT already added terminating nl */
+ fputs(ibuf, rfp);
+ }
+ step = 1;
+ break;
+ }
+ }
+ if (rfp)
+ fclose(rfp);
+ if (afp)
+ fclose(afp);
+ return err;
+ }
+
+/*--------------------------------------------------
+ Processes either a single file or
+ a set of files whose names are passed in a file.
+ A single file is specified as:
+ aes_test -f xxx.req
+ A set of files is specified as:
+ aes_test -d xxxxx.xxx
+ The default is: -d req.txt
+--------------------------------------------------*/
+int main(int argc, char **argv)
+ {
+ char *rqlist = "req.txt", *rspfile = NULL;
+ FILE *fp = NULL;
+ char fn[250] = "", rfn[256] = "";
+ int f_opt = 0, d_opt = 1;
+
+#ifdef OPENSSL_FIPS
+ if(!FIPS_mode_set(1))
+ {
+ do_print_errors();
+ EXIT(1);
+ }
+#endif
+ if (argc > 1)
+ {
+ if (strcasecmp(argv[1], "-d") == 0)
+ {
+ d_opt = 1;
+ }
+ else if (strcasecmp(argv[1], "-f") == 0)
+ {
+ f_opt = 1;
+ d_opt = 0;
+ }
+ else
+ {
+ printf("Invalid parameter: %s\n", argv[1]);
+ return 0;
+ }
+ if (argc < 3)
+ {
+ printf("Missing parameter\n");
+ return 0;
+ }
+ if (d_opt)
+ rqlist = argv[2];
+ else
+ {
+ strcpy(fn, argv[2]);
+ rspfile = argv[3];
+ }
+ }
+ if (d_opt)
+ { /* list of files (directory) */
+ if (!(fp = fopen(rqlist, "r")))
+ {
+ printf("Cannot open req list file\n");
+ return -1;
+ }
+ while (fgets(fn, sizeof(fn), fp))
+ {
+ strtok(fn, "\r\n");
+ strcpy(rfn, fn);
+ if (VERBOSE)
+ printf("Processing: %s\n", rfn);
+ if (proc_file(rfn, rspfile))
+ {
+ printf(">>> Processing failed for: %s <<<\n", rfn);
+ EXIT(1);
+ }
+ }
+ fclose(fp);
+ }
+ else /* single file */
+ {
+ if (VERBOSE)
+ printf("Processing: %s\n", fn);
+ if (proc_file(fn, rspfile))
+ {
+ printf(">>> Processing failed for: %s <<<\n", fn);
+ }
+ }
+ EXIT(0);
+ return 0;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/des/Makefile b/crypto/openssl/fips/des/Makefile
new file mode 100644
index 0000000..ba1d095
--- /dev/null
+++ b/crypto/openssl/fips/des/Makefile
@@ -0,0 +1,111 @@
+#
+# OpenSSL/fips/des/Makefile
+#
+
+DIR= des
+TOP= ../..
+CC= cc
+INCLUDES=
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile
+AR= ar r
+
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST= fips_desmovs.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=fips_des_selftest.c
+LIBOBJ=fips_des_selftest.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=
+HEADER=
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ @echo $(LIBOBJ) > lib
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
+
+install:
+ @headerlist="$(EXHEADER)"; for i in $$headerlist; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+fips_test:
+ -find ../testvectors/tdes/req -name '*.req' > testlist
+ -rm -rf ../testvectors/tdes/rsp
+ mkdir ../testvectors/tdes/rsp
+ if [ -s testlist ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_desmovs -d testlist; fi
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) \
+ $(SRC) $(TEST)
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff testlist
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+fips_des_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_des_selftest.o: ../../include/openssl/crypto.h
+fips_des_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_des_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_des_selftest.o: ../../include/openssl/lhash.h
+fips_des_selftest.o: ../../include/openssl/obj_mac.h
+fips_des_selftest.o: ../../include/openssl/objects.h
+fips_des_selftest.o: ../../include/openssl/opensslconf.h
+fips_des_selftest.o: ../../include/openssl/opensslv.h
+fips_des_selftest.o: ../../include/openssl/ossl_typ.h
+fips_des_selftest.o: ../../include/openssl/safestack.h
+fips_des_selftest.o: ../../include/openssl/stack.h
+fips_des_selftest.o: ../../include/openssl/symhacks.h fips_des_selftest.c
+fips_desmovs.o: ../../e_os.h ../../include/openssl/asn1.h
+fips_desmovs.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_desmovs.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+fips_desmovs.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+fips_desmovs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_desmovs.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_desmovs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_desmovs.o: ../../include/openssl/opensslconf.h
+fips_desmovs.o: ../../include/openssl/opensslv.h
+fips_desmovs.o: ../../include/openssl/ossl_typ.h
+fips_desmovs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_desmovs.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+fips_desmovs.o: ../../include/openssl/ui_compat.h ../fips_utl.h fips_desmovs.c
diff --git a/crypto/openssl/fips/des/fips_des_selftest.c b/crypto/openssl/fips/des/fips_des_selftest.c
new file mode 100644
index 0000000..61c39ce
--- /dev/null
+++ b/crypto/openssl/fips/des/fips_des_selftest.c
@@ -0,0 +1,137 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+#include <openssl/evp.h>
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_FIPS
+
+static struct
+ {
+ unsigned char key[16];
+ unsigned char plaintext[8];
+ unsigned char ciphertext[8];
+ } tests2[]=
+ {
+ {
+ { 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec,
+ 0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 },
+ { 0x06,0xa7,0xd8,0x79,0xaa,0xce,0x69,0xef },
+ { 0x4c,0x11,0x17,0x55,0xbf,0xc4,0x4e,0xfd }
+ },
+ {
+ { 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34,
+ 0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 },
+ { 0x9c,0x50,0x09,0x0f,0x5e,0x7d,0x69,0x7e },
+ { 0xd2,0x0b,0x18,0xdf,0xd9,0x0d,0x9e,0xff },
+ }
+ };
+
+static struct
+ {
+ unsigned char key[24];
+ unsigned char plaintext[8];
+ unsigned char ciphertext[8];
+ } tests3[]=
+ {
+ {
+ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,
+ 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 },
+ { 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c },
+ { 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b },
+ },
+ {
+ { 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE,
+ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 },
+ { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF },
+ { 0x11,0x25,0xb0,0x35,0xbe,0xa0,0x82,0x86 },
+ },
+ };
+
+void FIPS_corrupt_des()
+ {
+ tests2[0].plaintext[0]++;
+ }
+
+int FIPS_selftest_des()
+ {
+ int n, ret = 0;
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+ /* Encrypt/decrypt with 2-key 3DES and compare to known answers */
+ for(n=0 ; n < 2 ; ++n)
+ {
+ if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(),
+ tests2[n].key, NULL,
+ tests2[n].plaintext, tests2[n].ciphertext, 8))
+ goto err;
+ }
+
+ /* Encrypt/decrypt with 3DES and compare to known answers */
+ for(n=0 ; n < 2 ; ++n)
+ {
+ if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(),
+ tests3[n].key, NULL,
+ tests3[n].plaintext, tests3[n].ciphertext, 8))
+ goto err;
+ }
+ ret = 1;
+ err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ if (ret == 0)
+ FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
+
+ return ret;
+ }
+#endif
diff --git a/crypto/openssl/fips/des/fips_desmovs.c b/crypto/openssl/fips/des/fips_desmovs.c
new file mode 100644
index 0000000..f96a5ca
--- /dev/null
+++ b/crypto/openssl/fips/des/fips_desmovs.c
@@ -0,0 +1,702 @@
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*---------------------------------------------
+ NIST DES Modes of Operation Validation System
+ Test Program
+
+ Based on the AES Validation Suite, which was:
+ Donated to OpenSSL by:
+ V-ONE Corporation
+ 20250 Century Blvd, Suite 300
+ Germantown, MD 20874
+ U.S.A.
+ ----------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <ctype.h>
+#include <openssl/des.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+
+#include <openssl/err.h>
+#include "e_os.h"
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+ printf("No FIPS DES support\n");
+ return(0);
+}
+
+#else
+
+#include <openssl/fips.h>
+#include "fips_utl.h"
+
+#define DES_BLOCK_SIZE 8
+
+#define VERBOSE 0
+
+static int DESTest(EVP_CIPHER_CTX *ctx,
+ char *amode, int akeysz, unsigned char *aKey,
+ unsigned char *iVec,
+ int dir, /* 0 = decrypt, 1 = encrypt */
+ unsigned char *out, unsigned char *in, int len)
+ {
+ const EVP_CIPHER *cipher = NULL;
+
+ if (akeysz != 192)
+ {
+ printf("Invalid key size: %d\n", akeysz);
+ EXIT(1);
+ }
+
+ if (strcasecmp(amode, "CBC") == 0)
+ cipher = EVP_des_ede3_cbc();
+ else if (strcasecmp(amode, "ECB") == 0)
+ cipher = EVP_des_ede3_ecb();
+ else if (strcasecmp(amode, "CFB64") == 0)
+ cipher = EVP_des_ede3_cfb64();
+ else if (strncasecmp(amode, "OFB", 3) == 0)
+ cipher = EVP_des_ede3_ofb();
+ else if(!strcasecmp(amode,"CFB8"))
+ cipher = EVP_des_ede3_cfb8();
+ else if(!strcasecmp(amode,"CFB1"))
+ cipher = EVP_des_ede3_cfb1();
+ else
+ {
+ printf("Unknown mode: %s\n", amode);
+ EXIT(1);
+ }
+
+ if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0)
+ return 0;
+ if(!strcasecmp(amode,"CFB1"))
+ M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS);
+ EVP_Cipher(ctx, out, in, len);
+
+ return 1;
+ }
+#if 0
+static void DebugValue(char *tag, unsigned char *val, int len)
+ {
+ char obuf[2048];
+ int olen;
+ olen = bin2hex(val, len, obuf);
+ printf("%s = %.*s\n", tag, olen, obuf);
+ }
+#endif
+static void shiftin(unsigned char *dst,unsigned char *src,int nbits)
+ {
+ int n;
+
+ /* move the bytes... */
+ memmove(dst,dst+nbits/8,3*8-nbits/8);
+ /* append new data */
+ memcpy(dst+3*8-nbits/8,src,(nbits+7)/8);
+ /* left shift the bits */
+ if(nbits%8)
+ for(n=0 ; n < 3*8 ; ++n)
+ dst[n]=(dst[n] << (nbits%8))|(dst[n+1] >> (8-nbits%8));
+ }
+
+/*-----------------------------------------------*/
+char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"};
+char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB64"};
+enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB64};
+int Sizes[6]={64,64,64,1,8,64};
+
+static void do_mct(char *amode,
+ int akeysz, int numkeys, unsigned char *akey,unsigned char *ivec,
+ int dir, unsigned char *text, int len,
+ FILE *rfp)
+ {
+ int i,imode;
+ unsigned char nk[4*8]; /* longest key+8 */
+ unsigned char text0[8];
+
+ for (imode=0 ; imode < 6 ; ++imode)
+ if(!strcmp(amode,t_mode[imode]))
+ break;
+ if (imode == 6)
+ {
+ printf("Unrecognized mode: %s\n", amode);
+ EXIT(1);
+ }
+
+ for(i=0 ; i < 400 ; ++i)
+ {
+ int j;
+ int n;
+ int kp=akeysz/64;
+ unsigned char old_iv[8];
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+
+ fprintf(rfp,"\nCOUNT = %d\n",i);
+ if(kp == 1)
+ OutputValue("KEY",akey,8,rfp,0);
+ else
+ for(n=0 ; n < kp ; ++n)
+ {
+ fprintf(rfp,"KEY%d",n+1);
+ OutputValue("",akey+n*8,8,rfp,0);
+ }
+
+ if(imode != ECB)
+ OutputValue("IV",ivec,8,rfp,0);
+ OutputValue(t_tag[dir^1],text,len,rfp,imode == CFB1);
+#if 0
+ /* compensate for endianness */
+ if(imode == CFB1)
+ text[0]<<=7;
+#endif
+ memcpy(text0,text,8);
+
+ for(j=0 ; j < 10000 ; ++j)
+ {
+ unsigned char old_text[8];
+
+ memcpy(old_text,text,8);
+ if(j == 0)
+ {
+ memcpy(old_iv,ivec,8);
+ DESTest(&ctx,amode,akeysz,akey,ivec,dir,text,text,len);
+ }
+ else
+ {
+ memcpy(old_iv,ctx.iv,8);
+ EVP_Cipher(&ctx,text,text,len);
+ }
+ if(j == 9999)
+ {
+ OutputValue(t_tag[dir],text,len,rfp,imode == CFB1);
+ /* memcpy(ivec,text,8); */
+ }
+ /* DebugValue("iv",ctx.iv,8); */
+ /* accumulate material for the next key */
+ shiftin(nk,text,Sizes[imode]);
+ /* DebugValue("nk",nk,24);*/
+ if((dir && (imode == CFB1 || imode == CFB8 || imode == CFB64
+ || imode == CBC)) || imode == OFB)
+ memcpy(text,old_iv,8);
+
+ if(!dir && (imode == CFB1 || imode == CFB8 || imode == CFB64))
+ {
+ /* the test specifies using the output of the raw DES operation
+ which we don't have, so reconstruct it... */
+ for(n=0 ; n < 8 ; ++n)
+ text[n]^=old_text[n];
+ }
+ }
+ for(n=0 ; n < 8 ; ++n)
+ akey[n]^=nk[16+n];
+ for(n=0 ; n < 8 ; ++n)
+ akey[8+n]^=nk[8+n];
+ for(n=0 ; n < 8 ; ++n)
+ akey[16+n]^=nk[n];
+ if(numkeys < 3)
+ memcpy(&akey[2*8],akey,8);
+ if(numkeys < 2)
+ memcpy(&akey[8],akey,8);
+ DES_set_odd_parity((DES_cblock *)akey);
+ DES_set_odd_parity((DES_cblock *)(akey+8));
+ DES_set_odd_parity((DES_cblock *)(akey+16));
+ memcpy(ivec,ctx.iv,8);
+
+ /* pointless exercise - the final text doesn't depend on the
+ initial text in OFB mode, so who cares what it is? (Who
+ designed these tests?) */
+ if(imode == OFB)
+ for(n=0 ; n < 8 ; ++n)
+ text[n]=text0[n]^old_iv[n];
+ }
+ }
+
+static int proc_file(char *rqfile, char *rspfile)
+ {
+ char afn[256], rfn[256];
+ FILE *afp = NULL, *rfp = NULL;
+ char ibuf[2048], tbuf[2048];
+ int ilen, len, ret = 0;
+ char amode[8] = "";
+ char atest[100] = "";
+ int akeysz=0;
+ unsigned char iVec[20], aKey[40];
+ int dir = -1, err = 0, step = 0;
+ unsigned char plaintext[2048];
+ unsigned char ciphertext[2048];
+ char *rp;
+ EVP_CIPHER_CTX ctx;
+ int numkeys=1;
+ EVP_CIPHER_CTX_init(&ctx);
+
+ if (!rqfile || !(*rqfile))
+ {
+ printf("No req file\n");
+ return -1;
+ }
+ strcpy(afn, rqfile);
+
+ if ((afp = fopen(afn, "r")) == NULL)
+ {
+ printf("Cannot open file: %s, %s\n",
+ afn, strerror(errno));
+ return -1;
+ }
+ if (!rspfile)
+ {
+ strcpy(rfn,afn);
+ rp=strstr(rfn,"req/");
+#ifdef OPENSSL_SYS_WIN32
+ if (!rp)
+ rp=strstr(rfn,"req\\");
+#endif
+ assert(rp);
+ memcpy(rp,"rsp",3);
+ rp = strstr(rfn, ".req");
+ memcpy(rp, ".rsp", 4);
+ rspfile = rfn;
+ }
+ if ((rfp = fopen(rspfile, "w")) == NULL)
+ {
+ printf("Cannot open file: %s, %s\n",
+ rfn, strerror(errno));
+ fclose(afp);
+ afp = NULL;
+ return -1;
+ }
+ while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL)
+ {
+ tidy_line(tbuf, ibuf);
+ ilen = strlen(ibuf);
+ /* printf("step=%d ibuf=%s",step,ibuf);*/
+ if(step == 3 && !strcmp(amode,"ECB"))
+ {
+ memset(iVec, 0, sizeof(iVec));
+ step = (dir)? 4: 5; /* no ivec for ECB */
+ }
+ switch (step)
+ {
+ case 0: /* read preamble */
+ if (ibuf[0] == '\n')
+ { /* end of preamble */
+ if (*amode == '\0')
+ {
+ printf("Missing Mode\n");
+ err = 1;
+ }
+ else
+ {
+ fputs(ibuf, rfp);
+ ++ step;
+ }
+ }
+ else if (ibuf[0] != '#')
+ {
+ printf("Invalid preamble item: %s\n", ibuf);
+ err = 1;
+ }
+ else
+ { /* process preamble */
+ char *xp, *pp = ibuf+2;
+ int n;
+ if(*amode)
+ { /* insert current time & date */
+ time_t rtim = time(0);
+ fprintf(rfp, "# %s", ctime(&rtim));
+ }
+ else
+ {
+ fputs(ibuf, rfp);
+ if(!strncmp(pp,"INVERSE ",8) || !strncmp(pp,"DES ",4)
+ || !strncmp(pp,"TDES ",5)
+ || !strncmp(pp,"PERMUTATION ",12)
+ || !strncmp(pp,"SUBSTITUTION ",13)
+ || !strncmp(pp,"VARIABLE ",9))
+ {
+ /* get test type */
+ if(!strncmp(pp,"DES ",4))
+ pp+=4;
+ else if(!strncmp(pp,"TDES ",5))
+ pp+=5;
+ xp = strchr(pp, ' ');
+ n = xp-pp;
+ strncpy(atest, pp, n);
+ atest[n] = '\0';
+ /* get mode */
+ xp = strrchr(pp, ' '); /* get mode" */
+ n = strlen(xp+1)-1;
+ strncpy(amode, xp+1, n);
+ amode[n] = '\0';
+ /* amode[3] = '\0'; */
+ if (VERBOSE)
+ printf("Test=%s, Mode=%s\n",atest,amode);
+ }
+ }
+ }
+ break;
+
+ case 1: /* [ENCRYPT] | [DECRYPT] */
+ if(ibuf[0] == '\n')
+ break;
+ if (ibuf[0] == '[')
+ {
+ fputs(ibuf, rfp);
+ ++step;
+ if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0)
+ dir = 1;
+ else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0)
+ dir = 0;
+ else
+ {
+ printf("Invalid keyword: %s\n", ibuf);
+ err = 1;
+ }
+ break;
+ }
+ else if (dir == -1)
+ {
+ err = 1;
+ printf("Missing ENCRYPT/DECRYPT keyword\n");
+ break;
+ }
+ else
+ step = 2;
+
+ case 2: /* KEY = xxxx */
+ if(*ibuf == '\n')
+ {
+ fputs(ibuf, rfp);
+ break;
+ }
+ if(!strncasecmp(ibuf,"COUNT = ",8))
+ {
+ fputs(ibuf, rfp);
+ break;
+ }
+ if(!strncasecmp(ibuf,"COUNT=",6))
+ {
+ fputs(ibuf, rfp);
+ break;
+ }
+ if(!strncasecmp(ibuf,"NumKeys = ",10))
+ {
+ numkeys=atoi(ibuf+10);
+ break;
+ }
+
+ fputs(ibuf, rfp);
+ if(!strncasecmp(ibuf,"KEY = ",6))
+ {
+ akeysz=64;
+ len = hex2bin((char*)ibuf+6, aKey);
+ if (len < 0)
+ {
+ printf("Invalid KEY\n");
+ err=1;
+ break;
+ }
+ PrintValue("KEY", aKey, len);
+ ++step;
+ }
+ else if(!strncasecmp(ibuf,"KEYs = ",7))
+ {
+ akeysz=64*3;
+ len=hex2bin(ibuf+7,aKey);
+ if(len != 8)
+ {
+ printf("Invalid KEY\n");
+ err=1;
+ break;
+ }
+ memcpy(aKey+8,aKey,8);
+ memcpy(aKey+16,aKey,8);
+ ibuf[4]='\0';
+ PrintValue("KEYs",aKey,len);
+ ++step;
+ }
+ else if(!strncasecmp(ibuf,"KEY",3))
+ {
+ int n=ibuf[3]-'1';
+
+ akeysz=64*3;
+ len=hex2bin(ibuf+7,aKey+n*8);
+ if(len != 8)
+ {
+ printf("Invalid KEY\n");
+ err=1;
+ break;
+ }
+ ibuf[4]='\0';
+ PrintValue(ibuf,aKey,len);
+ if(n == 2)
+ ++step;
+ }
+ else
+ {
+ printf("Missing KEY\n");
+ err = 1;
+ }
+ break;
+
+ case 3: /* IV = xxxx */
+ fputs(ibuf, rfp);
+ if (strncasecmp(ibuf, "IV = ", 5) != 0)
+ {
+ printf("Missing IV\n");
+ err = 1;
+ }
+ else
+ {
+ len = hex2bin((char*)ibuf+5, iVec);
+ if (len < 0)
+ {
+ printf("Invalid IV\n");
+ err =1;
+ break;
+ }
+ PrintValue("IV", iVec, len);
+ step = (dir)? 4: 5;
+ }
+ break;
+
+ case 4: /* PLAINTEXT = xxxx */
+ fputs(ibuf, rfp);
+ if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0)
+ {
+ printf("Missing PLAINTEXT\n");
+ err = 1;
+ }
+ else
+ {
+ int nn = strlen(ibuf+12);
+ if(!strcmp(amode,"CFB1"))
+ len=bint2bin(ibuf+12,nn-1,plaintext);
+ else
+ len=hex2bin(ibuf+12, plaintext);
+ if (len < 0)
+ {
+ printf("Invalid PLAINTEXT: %s", ibuf+12);
+ err =1;
+ break;
+ }
+ if (len >= (int)sizeof(plaintext))
+ {
+ printf("Buffer overflow\n");
+ }
+ PrintValue("PLAINTEXT", (unsigned char*)plaintext, len);
+ if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */
+ {
+ do_mct(amode,akeysz,numkeys,aKey,iVec,dir,plaintext,len,rfp);
+ }
+ else
+ {
+ assert(dir == 1);
+ ret = DESTest(&ctx, amode, akeysz, aKey, iVec,
+ dir, /* 0 = decrypt, 1 = encrypt */
+ ciphertext, plaintext, len);
+ OutputValue("CIPHERTEXT",ciphertext,len,rfp,
+ !strcmp(amode,"CFB1"));
+ }
+ step = 6;
+ }
+ break;
+
+ case 5: /* CIPHERTEXT = xxxx */
+ fputs(ibuf, rfp);
+ if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0)
+ {
+ printf("Missing KEY\n");
+ err = 1;
+ }
+ else
+ {
+ if(!strcmp(amode,"CFB1"))
+ len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext);
+ else
+ len = hex2bin(ibuf+13,ciphertext);
+ if (len < 0)
+ {
+ printf("Invalid CIPHERTEXT\n");
+ err =1;
+ break;
+ }
+
+ PrintValue("CIPHERTEXT", ciphertext, len);
+ if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */
+ {
+ do_mct(amode, akeysz, numkeys, aKey, iVec,
+ dir, ciphertext, len, rfp);
+ }
+ else
+ {
+ assert(dir == 0);
+ ret = DESTest(&ctx, amode, akeysz, aKey, iVec,
+ dir, /* 0 = decrypt, 1 = encrypt */
+ plaintext, ciphertext, len);
+ OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp,
+ !strcmp(amode,"CFB1"));
+ }
+ step = 6;
+ }
+ break;
+
+ case 6:
+ if (ibuf[0] != '\n')
+ {
+ err = 1;
+ printf("Missing terminator\n");
+ }
+ else if (strcmp(atest, "MCT") != 0)
+ { /* MCT already added terminating nl */
+ fputs(ibuf, rfp);
+ }
+ step = 1;
+ break;
+ }
+ }
+ if (rfp)
+ fclose(rfp);
+ if (afp)
+ fclose(afp);
+ return err;
+ }
+
+/*--------------------------------------------------
+ Processes either a single file or
+ a set of files whose names are passed in a file.
+ A single file is specified as:
+ aes_test -f xxx.req
+ A set of files is specified as:
+ aes_test -d xxxxx.xxx
+ The default is: -d req.txt
+--------------------------------------------------*/
+int main(int argc, char **argv)
+ {
+ char *rqlist = "req.txt", *rspfile = NULL;
+ FILE *fp = NULL;
+ char fn[250] = "", rfn[256] = "";
+ int f_opt = 0, d_opt = 1;
+
+#ifdef OPENSSL_FIPS
+ if(!FIPS_mode_set(1))
+ {
+ do_print_errors();
+ EXIT(1);
+ }
+#endif
+ if (argc > 1)
+ {
+ if (strcasecmp(argv[1], "-d") == 0)
+ {
+ d_opt = 1;
+ }
+ else if (strcasecmp(argv[1], "-f") == 0)
+ {
+ f_opt = 1;
+ d_opt = 0;
+ }
+ else
+ {
+ printf("Invalid parameter: %s\n", argv[1]);
+ return 0;
+ }
+ if (argc < 3)
+ {
+ printf("Missing parameter\n");
+ return 0;
+ }
+ if (d_opt)
+ rqlist = argv[2];
+ else
+ {
+ strcpy(fn, argv[2]);
+ rspfile = argv[3];
+ }
+ }
+ if (d_opt)
+ { /* list of files (directory) */
+ if (!(fp = fopen(rqlist, "r")))
+ {
+ printf("Cannot open req list file\n");
+ return -1;
+ }
+ while (fgets(fn, sizeof(fn), fp))
+ {
+ strtok(fn, "\r\n");
+ strcpy(rfn, fn);
+ printf("Processing: %s\n", rfn);
+ if (proc_file(rfn, rspfile))
+ {
+ printf(">>> Processing failed for: %s <<<\n", rfn);
+ EXIT(1);
+ }
+ }
+ fclose(fp);
+ }
+ else /* single file */
+ {
+ if (VERBOSE)
+ printf("Processing: %s\n", fn);
+ if (proc_file(fn, rspfile))
+ {
+ printf(">>> Processing failed for: %s <<<\n", fn);
+ }
+ }
+ EXIT(0);
+ return 0;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/dh/Makefile b/crypto/openssl/fips/dh/Makefile
new file mode 100644
index 0000000..2d3833a
--- /dev/null
+++ b/crypto/openssl/fips/dh/Makefile
@@ -0,0 +1,115 @@
+#
+# OpenSSL/fips/dh/Makefile
+#
+
+DIR= dh
+TOP= ../..
+CC= cc
+INCLUDES=
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile
+AR= ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=fips_dh_check.c fips_dh_gen.c fips_dh_key.c fips_dh_lib.c
+LIBOBJ=fips_dh_check.o fips_dh_gen.o fips_dh_key.o fips_dh_lib.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=
+HEADER= $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ @echo $(LIBOBJ) > lib
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
+
+install:
+ @headerlist="$(EXHEADER)"; for i in $$headerlist; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+fips_test:
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+fips_dh_check.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dh_check.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+fips_dh_check.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_dh_check.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_dh_check.o: ../../include/openssl/opensslconf.h
+fips_dh_check.o: ../../include/openssl/opensslv.h
+fips_dh_check.o: ../../include/openssl/ossl_typ.h
+fips_dh_check.o: ../../include/openssl/safestack.h
+fips_dh_check.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_dh_check.o: fips_dh_check.c
+fips_dh_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dh_gen.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+fips_dh_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_dh_gen.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_dh_gen.o: ../../include/openssl/opensslconf.h
+fips_dh_gen.o: ../../include/openssl/opensslv.h
+fips_dh_gen.o: ../../include/openssl/ossl_typ.h
+fips_dh_gen.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_dh_gen.o: ../../include/openssl/symhacks.h fips_dh_gen.c
+fips_dh_key.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dh_key.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+fips_dh_key.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_dh_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_dh_key.o: ../../include/openssl/opensslconf.h
+fips_dh_key.o: ../../include/openssl/opensslv.h
+fips_dh_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_dh_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_dh_key.o: ../../include/openssl/symhacks.h fips_dh_key.c
+fips_dh_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dh_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+fips_dh_lib.o: ../../include/openssl/e_os2.h
+fips_dh_lib.o: ../../include/openssl/opensslconf.h
+fips_dh_lib.o: ../../include/openssl/opensslv.h
+fips_dh_lib.o: ../../include/openssl/ossl_typ.h
+fips_dh_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_dh_lib.o: ../../include/openssl/symhacks.h fips_dh_lib.c
diff --git a/crypto/openssl/fips/dh/dh_gen.c b/crypto/openssl/fips/dh/dh_gen.c
new file mode 100644
index 0000000..999e1de
--- /dev/null
+++ b/crypto/openssl/fips/dh/dh_gen.c
@@ -0,0 +1,179 @@
+/* crypto/dh/dh_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* NB: These functions have been upgraded - the previous prototypes are in
+ * dh_depr.c as wrappers to these ones.
+ * - Geoff
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+#ifndef OPENSSL_FIPS
+
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb);
+
+int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb)
+ {
+ if(ret->meth->generate_params)
+ return ret->meth->generate_params(ret, prime_len, generator, cb);
+ return dh_builtin_genparams(ret, prime_len, generator, cb);
+ }
+
+/* We generate DH parameters as follows
+ * find a prime q which is prime_len/2 bits long.
+ * p=(2*q)+1 or (p-1)/2 = q
+ * For this case, g is a generator if
+ * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
+ * Since the factors of p-1 are q and 2, we just need to check
+ * g^2 mod p != 1 and g^q mod p != 1.
+ *
+ * Having said all that,
+ * there is another special case method for the generators 2, 3 and 5.
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5 <<<<< does not work for safe primes.
+ * for 5, p mod 10 == 3 or 7
+ *
+ * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
+ * special generators and for answering some of my questions.
+ *
+ * I've implemented the second simple method :-).
+ * Since DH should be using a safe prime (both p and q are prime),
+ * this generator function can take a very very long time to run.
+ */
+/* Actually there is no reason to insist that 'generator' be a generator.
+ * It's just as OK (and in some sense better) to use a generator of the
+ * order-q subgroup.
+ */
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb)
+ {
+ BIGNUM *t1,*t2;
+ int g,ok= -1;
+ BN_CTX *ctx=NULL;
+
+ ctx=BN_CTX_new();
+ if (ctx == NULL) goto err;
+ BN_CTX_start(ctx);
+ t1 = BN_CTX_get(ctx);
+ t2 = BN_CTX_get(ctx);
+ if (t1 == NULL || t2 == NULL) goto err;
+
+ /* Make sure 'ret' has the necessary elements */
+ if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err;
+ if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err;
+
+ if (generator <= 1)
+ {
+ DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
+ goto err;
+ }
+ if (generator == DH_GENERATOR_2)
+ {
+ if (!BN_set_word(t1,24)) goto err;
+ if (!BN_set_word(t2,11)) goto err;
+ g=2;
+ }
+#if 0 /* does not work for safe primes */
+ else if (generator == DH_GENERATOR_3)
+ {
+ if (!BN_set_word(t1,12)) goto err;
+ if (!BN_set_word(t2,5)) goto err;
+ g=3;
+ }
+#endif
+ else if (generator == DH_GENERATOR_5)
+ {
+ if (!BN_set_word(t1,10)) goto err;
+ if (!BN_set_word(t2,3)) goto err;
+ /* BN_set_word(t3,7); just have to miss
+ * out on these ones :-( */
+ g=5;
+ }
+ else
+ {
+ /* in the general case, don't worry if 'generator' is a
+ * generator or not: since we are using safe primes,
+ * it will generate either an order-q or an order-2q group,
+ * which both is OK */
+ if (!BN_set_word(t1,2)) goto err;
+ if (!BN_set_word(t2,1)) goto err;
+ g=generator;
+ }
+
+ if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err;
+ if(!BN_GENCB_call(cb, 3, 0)) goto err;
+ if (!BN_set_word(ret->g,g)) goto err;
+ ok=1;
+err:
+ if (ok == -1)
+ {
+ DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB);
+ ok=0;
+ }
+
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return ok;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/dh/fips_dh_check.c b/crypto/openssl/fips/dh/fips_dh_check.c
new file mode 100644
index 0000000..7333f7c
--- /dev/null
+++ b/crypto/openssl/fips/dh/fips_dh_check.c
@@ -0,0 +1,147 @@
+/* crypto/dh/dh_check.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+
+/* Check that p is a safe prime and
+ * if g is 2, 3 or 5, check that is is a suitable generator
+ * where
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5
+ * for 5, p mod 10 == 3 or 7
+ * should hold.
+ */
+
+#ifdef OPENSSL_FIPS
+
+int DH_check(const DH *dh, int *ret)
+ {
+ int ok=0;
+ BN_CTX *ctx=NULL;
+ BN_ULONG l;
+ BIGNUM *q=NULL;
+
+ *ret=0;
+ ctx=BN_CTX_new();
+ if (ctx == NULL) goto err;
+ q=BN_new();
+ if (q == NULL) goto err;
+
+ if (BN_is_word(dh->g,DH_GENERATOR_2))
+ {
+ l=BN_mod_word(dh->p,24);
+ if (l != 11) *ret|=DH_NOT_SUITABLE_GENERATOR;
+ }
+#if 0
+ else if (BN_is_word(dh->g,DH_GENERATOR_3))
+ {
+ l=BN_mod_word(dh->p,12);
+ if (l != 5) *ret|=DH_NOT_SUITABLE_GENERATOR;
+ }
+#endif
+ else if (BN_is_word(dh->g,DH_GENERATOR_5))
+ {
+ l=BN_mod_word(dh->p,10);
+ if ((l != 3) && (l != 7))
+ *ret|=DH_NOT_SUITABLE_GENERATOR;
+ }
+ else
+ *ret|=DH_UNABLE_TO_CHECK_GENERATOR;
+
+ if (!BN_is_prime_ex(dh->p,BN_prime_checks,ctx,NULL))
+ *ret|=DH_CHECK_P_NOT_PRIME;
+ else
+ {
+ if (!BN_rshift1(q,dh->p)) goto err;
+ if (!BN_is_prime_ex(q,BN_prime_checks,ctx,NULL))
+ *ret|=DH_CHECK_P_NOT_SAFE_PRIME;
+ }
+ ok=1;
+err:
+ if (ctx != NULL) BN_CTX_free(ctx);
+ if (q != NULL) BN_free(q);
+ return(ok);
+ }
+
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
+ {
+ int ok=0;
+ BIGNUM *q=NULL;
+
+ *ret=0;
+ q=BN_new();
+ if (q == NULL) goto err;
+ BN_set_word(q,1);
+ if (BN_cmp(pub_key,q) <= 0)
+ *ret|=DH_CHECK_PUBKEY_TOO_SMALL;
+ BN_copy(q,dh->p);
+ BN_sub_word(q,1);
+ if (BN_cmp(pub_key,q) >= 0)
+ *ret|=DH_CHECK_PUBKEY_TOO_LARGE;
+
+ ok = 1;
+err:
+ if (q != NULL) BN_free(q);
+ return(ok);
+ }
+
+#endif
diff --git a/crypto/openssl/fips/dh/fips_dh_gen.c b/crypto/openssl/fips/dh/fips_dh_gen.c
new file mode 100644
index 0000000..d115f9d
--- /dev/null
+++ b/crypto/openssl/fips/dh/fips_dh_gen.c
@@ -0,0 +1,192 @@
+/* crypto/dh/dh_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* NB: These functions have been upgraded - the previous prototypes are in
+ * dh_depr.c as wrappers to these ones.
+ * - Geoff
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+
+#ifdef OPENSSL_FIPS
+
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb);
+
+int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb)
+ {
+ if(ret->meth->generate_params)
+ return ret->meth->generate_params(ret, prime_len, generator, cb);
+ return dh_builtin_genparams(ret, prime_len, generator, cb);
+ }
+
+/* We generate DH parameters as follows
+ * find a prime q which is prime_len/2 bits long.
+ * p=(2*q)+1 or (p-1)/2 = q
+ * For this case, g is a generator if
+ * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
+ * Since the factors of p-1 are q and 2, we just need to check
+ * g^2 mod p != 1 and g^q mod p != 1.
+ *
+ * Having said all that,
+ * there is another special case method for the generators 2, 3 and 5.
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5 <<<<< does not work for safe primes.
+ * for 5, p mod 10 == 3 or 7
+ *
+ * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
+ * special generators and for answering some of my questions.
+ *
+ * I've implemented the second simple method :-).
+ * Since DH should be using a safe prime (both p and q are prime),
+ * this generator function can take a very very long time to run.
+ */
+/* Actually there is no reason to insist that 'generator' be a generator.
+ * It's just as OK (and in some sense better) to use a generator of the
+ * order-q subgroup.
+ */
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb)
+ {
+ BIGNUM *t1,*t2;
+ int g,ok= -1;
+ BN_CTX *ctx=NULL;
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_DH_BUILTIN_GENPARAMS,FIPS_R_FIPS_SELFTEST_FAILED);
+ return 0;
+ }
+
+ if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS))
+ {
+ DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL);
+ goto err;
+ }
+
+ ctx=BN_CTX_new();
+ if (ctx == NULL) goto err;
+ BN_CTX_start(ctx);
+ t1 = BN_CTX_get(ctx);
+ t2 = BN_CTX_get(ctx);
+ if (t1 == NULL || t2 == NULL) goto err;
+
+ /* Make sure 'ret' has the necessary elements */
+ if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err;
+ if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err;
+
+ if (generator <= 1)
+ {
+ DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
+ goto err;
+ }
+ if (generator == DH_GENERATOR_2)
+ {
+ if (!BN_set_word(t1,24)) goto err;
+ if (!BN_set_word(t2,11)) goto err;
+ g=2;
+ }
+#if 0 /* does not work for safe primes */
+ else if (generator == DH_GENERATOR_3)
+ {
+ if (!BN_set_word(t1,12)) goto err;
+ if (!BN_set_word(t2,5)) goto err;
+ g=3;
+ }
+#endif
+ else if (generator == DH_GENERATOR_5)
+ {
+ if (!BN_set_word(t1,10)) goto err;
+ if (!BN_set_word(t2,3)) goto err;
+ /* BN_set_word(t3,7); just have to miss
+ * out on these ones :-( */
+ g=5;
+ }
+ else
+ {
+ /* in the general case, don't worry if 'generator' is a
+ * generator or not: since we are using safe primes,
+ * it will generate either an order-q or an order-2q group,
+ * which both is OK */
+ if (!BN_set_word(t1,2)) goto err;
+ if (!BN_set_word(t2,1)) goto err;
+ g=generator;
+ }
+
+ if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err;
+ if(!BN_GENCB_call(cb, 3, 0)) goto err;
+ if (!BN_set_word(ret->g,g)) goto err;
+ ok=1;
+err:
+ if (ok == -1)
+ {
+ DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB);
+ ok=0;
+ }
+
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ return ok;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/dh/fips_dh_key.c b/crypto/openssl/fips/dh/fips_dh_key.c
new file mode 100644
index 0000000..d20fa91
--- /dev/null
+++ b/crypto/openssl/fips/dh/fips_dh_key.c
@@ -0,0 +1,276 @@
+/* crypto/dh/dh_key.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_RAND
+#include <openssl/rand.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#include <openssl/fips.h>
+
+#ifdef OPENSSL_FIPS
+
+static int generate_key(DH *dh);
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx);
+static int dh_init(DH *dh);
+static int dh_finish(DH *dh);
+
+int DH_generate_key(DH *dh)
+ {
+ return dh->meth->generate_key(dh);
+ }
+
+int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+ {
+ return dh->meth->compute_key(key, pub_key, dh);
+ }
+
+static const DH_METHOD dh_ossl = {
+"OpenSSL DH Method",
+generate_key,
+compute_key,
+dh_bn_mod_exp,
+dh_init,
+dh_finish,
+0,
+NULL
+};
+
+const DH_METHOD *DH_OpenSSL(void)
+{
+ return &dh_ossl;
+}
+
+static int generate_key(DH *dh)
+ {
+ int ok=0;
+ int generate_new_key=0;
+ unsigned l;
+ BN_CTX *ctx;
+ BN_MONT_CTX *mont=NULL;
+ BIGNUM *pub_key=NULL,*priv_key=NULL;
+
+ if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS))
+ {
+ DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
+ return 0;
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) goto err;
+
+ if (dh->priv_key == NULL)
+ {
+ priv_key=BN_new();
+ if (priv_key == NULL) goto err;
+ generate_new_key=1;
+ }
+ else
+ priv_key=dh->priv_key;
+
+ if (dh->pub_key == NULL)
+ {
+ pub_key=BN_new();
+ if (pub_key == NULL) goto err;
+ }
+ else
+ pub_key=dh->pub_key;
+
+ if (dh->flags & DH_FLAG_CACHE_MONT_P)
+ {
+ mont = BN_MONT_CTX_set_locked(
+ (BN_MONT_CTX **)&dh->method_mont_p,
+ CRYPTO_LOCK_DH, dh->p, ctx);
+ if (!mont)
+ goto err;
+ }
+
+ if (generate_new_key)
+ {
+ l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */
+ if (!BN_rand(priv_key, l, 0, 0)) goto err;
+ }
+
+ {
+ BIGNUM local_prk;
+ BIGNUM *prk;
+
+ if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
+ {
+ BN_init(&local_prk);
+ prk = &local_prk;
+ BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
+ }
+ else
+ prk = priv_key;
+
+ if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont))
+ goto err;
+ }
+
+ dh->pub_key=pub_key;
+ dh->priv_key=priv_key;
+ ok=1;
+err:
+ if (ok != 1)
+ DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB);
+
+ if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key);
+ if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
+ BN_CTX_free(ctx);
+ return(ok);
+ }
+
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+ {
+ BN_CTX *ctx;
+ BN_MONT_CTX *mont=NULL;
+ BIGNUM *tmp;
+ int ret= -1;
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) goto err;
+ BN_CTX_start(ctx);
+ tmp = BN_CTX_get(ctx);
+
+ if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS)
+ {
+ DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE);
+ goto err;
+ }
+
+ if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS))
+ {
+ DHerr(DH_F_COMPUTE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
+ goto err;
+ }
+
+ if (dh->priv_key == NULL)
+ {
+ DHerr(DH_F_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
+ goto err;
+ }
+
+ if (dh->flags & DH_FLAG_CACHE_MONT_P)
+ {
+ mont = BN_MONT_CTX_set_locked(
+ (BN_MONT_CTX **)&dh->method_mont_p,
+ CRYPTO_LOCK_DH, dh->p, ctx);
+ if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
+ {
+ /* XXX */
+ BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
+ }
+ if (!mont)
+ goto err;
+ }
+
+ if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
+ {
+ DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB);
+ goto err;
+ }
+
+ ret=BN_bn2bin(tmp,key);
+err:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return(ret);
+ }
+
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
+ const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx)
+ {
+ /* If a is only one word long and constant time is false, use the faster
+ * exponenentiation function.
+ */
+ if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0))
+ {
+ BN_ULONG A = a->d[0];
+ return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx);
+ }
+ else
+ return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx);
+ }
+
+
+static int dh_init(DH *dh)
+ {
+ FIPS_selftest_check();
+ dh->flags |= DH_FLAG_CACHE_MONT_P;
+ return(1);
+ }
+
+static int dh_finish(DH *dh)
+ {
+ if(dh->method_mont_p)
+ BN_MONT_CTX_free((BN_MONT_CTX *)dh->method_mont_p);
+ return(1);
+ }
+
+#endif
+#endif
diff --git a/crypto/openssl/fips/dh/fips_dh_lib.c b/crypto/openssl/fips/dh/fips_dh_lib.c
new file mode 100644
index 0000000..4a822cf
--- /dev/null
+++ b/crypto/openssl/fips/dh/fips_dh_lib.c
@@ -0,0 +1,95 @@
+/* fips_dh_lib.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+/* Minimal FIPS versions of FIPS_dh_new() and FIPS_dh_free(): to
+ * reduce external dependencies.
+ */
+
+DH *FIPS_dh_new(void)
+ {
+ DH *ret;
+ ret = OPENSSL_malloc(sizeof(DH));
+ if (!ret)
+ return NULL;
+ memset(ret, 0, sizeof(DH));
+ ret->meth = DH_OpenSSL();
+ if (ret->meth->init)
+ ret->meth->init(ret);
+ return ret;
+ }
+
+void FIPS_dh_free(DH *r)
+ {
+ if (!r)
+ return;
+ if (r->meth->finish)
+ r->meth->finish(r);
+ if (r->p != NULL) BN_clear_free(r->p);
+ if (r->g != NULL) BN_clear_free(r->g);
+ if (r->q != NULL) BN_clear_free(r->q);
+ if (r->j != NULL) BN_clear_free(r->j);
+ if (r->seed) OPENSSL_free(r->seed);
+ if (r->counter != NULL) BN_clear_free(r->counter);
+ if (r->pub_key != NULL) BN_clear_free(r->pub_key);
+ if (r->priv_key != NULL) BN_clear_free(r->priv_key);
+ OPENSSL_free(r);
+ }
diff --git a/crypto/openssl/fips/dsa/Makefile b/crypto/openssl/fips/dsa/Makefile
new file mode 100644
index 0000000..251615e
--- /dev/null
+++ b/crypto/openssl/fips/dsa/Makefile
@@ -0,0 +1,191 @@
+#
+# OpenSSL/fips/dsa/Makefile
+#
+
+DIR= dsa
+TOP= ../..
+CC= cc
+INCLUDES=
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile
+AR= ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=fips_dsatest.c fips_dssvs.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=fips_dsa_ossl.c fips_dsa_gen.c fips_dsa_selftest.c fips_dsa_key.c \
+ fips_dsa_lib.c fips_dsa_sign.c
+LIBOBJ=fips_dsa_ossl.o fips_dsa_gen.o fips_dsa_selftest.o fips_dsa_key.o \
+ fips_dsa_lib.o fips_dsa_sign.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=
+HEADER= $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ @echo $(LIBOBJ) > lib
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
+
+install:
+ @headerlist="$(EXHEADER)"; for i in $$headerlist; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+Q=../testvectors/dsa/req
+A=../testvectors/dsa/rsp
+
+fips_test:
+ -rm -rf $A
+ mkdir $A
+ if [ -f $(Q)/PQGGen.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs pqg < $(Q)/PQGGen.req > $(A)/PQGGen.rsp; fi
+ if [ -f $(Q)/KeyPair.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs keypair < $(Q)/KeyPair.req > $(A)/KeyPair.rsp; fi
+ if [ -f $(Q)/SigGen.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs siggen < $(Q)/SigGen.req > $(A)/SigGen.rsp; fi
+ if [ -f $(Q)/SigVer.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs sigver < $Q/SigVer.req > $A/SigVer.rsp; fi
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+fips_dsa_gen.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_dsa_gen.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_dsa_gen.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsa_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dsa_gen.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_dsa_gen.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_dsa_gen.o: ../../include/openssl/opensslconf.h
+fips_dsa_gen.o: ../../include/openssl/opensslv.h
+fips_dsa_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_dsa_gen.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+fips_dsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_dsa_gen.o: fips_dsa_gen.c
+fips_dsa_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_dsa_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_dsa_key.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsa_key.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dsa_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_dsa_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_dsa_key.o: ../../include/openssl/opensslconf.h
+fips_dsa_key.o: ../../include/openssl/opensslv.h
+fips_dsa_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_dsa_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_dsa_key.o: ../../include/openssl/symhacks.h ../fips_locl.h fips_dsa_key.c
+fips_dsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dsa_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+fips_dsa_lib.o: ../../include/openssl/e_os2.h
+fips_dsa_lib.o: ../../include/openssl/opensslconf.h
+fips_dsa_lib.o: ../../include/openssl/opensslv.h
+fips_dsa_lib.o: ../../include/openssl/ossl_typ.h
+fips_dsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_dsa_lib.o: ../../include/openssl/symhacks.h fips_dsa_lib.c
+fips_dsa_ossl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_dsa_ossl.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+fips_dsa_ossl.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+fips_dsa_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_dsa_ossl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+fips_dsa_ossl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+fips_dsa_ossl.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_dsa_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_dsa_ossl.o: ../../include/openssl/objects.h
+fips_dsa_ossl.o: ../../include/openssl/opensslconf.h
+fips_dsa_ossl.o: ../../include/openssl/opensslv.h
+fips_dsa_ossl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+fips_dsa_ossl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+fips_dsa_ossl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+fips_dsa_ossl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+fips_dsa_ossl.o: ../../include/openssl/x509_vfy.h fips_dsa_ossl.c
+fips_dsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_dsa_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_dsa_selftest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsa_selftest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dsa_selftest.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_dsa_selftest.o: ../../include/openssl/obj_mac.h
+fips_dsa_selftest.o: ../../include/openssl/objects.h
+fips_dsa_selftest.o: ../../include/openssl/opensslconf.h
+fips_dsa_selftest.o: ../../include/openssl/opensslv.h
+fips_dsa_selftest.o: ../../include/openssl/ossl_typ.h
+fips_dsa_selftest.o: ../../include/openssl/safestack.h
+fips_dsa_selftest.o: ../../include/openssl/stack.h
+fips_dsa_selftest.o: ../../include/openssl/symhacks.h fips_dsa_selftest.c
+fips_dsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_dsa_sign.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_dsa_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dsa_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_dsa_sign.o: ../../include/openssl/obj_mac.h
+fips_dsa_sign.o: ../../include/openssl/objects.h
+fips_dsa_sign.o: ../../include/openssl/opensslconf.h
+fips_dsa_sign.o: ../../include/openssl/opensslv.h
+fips_dsa_sign.o: ../../include/openssl/ossl_typ.h
+fips_dsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+fips_dsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_dsa_sign.o: fips_dsa_sign.c
+fips_dsatest.o: ../../e_os.h ../../include/openssl/asn1.h
+fips_dsatest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+fips_dsatest.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+fips_dsatest.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+fips_dsatest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dsatest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+fips_dsatest.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+fips_dsatest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dsatest.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_dsatest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_dsatest.o: ../../include/openssl/objects.h
+fips_dsatest.o: ../../include/openssl/opensslconf.h
+fips_dsatest.o: ../../include/openssl/opensslv.h
+fips_dsatest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+fips_dsatest.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+fips_dsatest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+fips_dsatest.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+fips_dsatest.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
+fips_dsatest.o: ../../include/openssl/x509_vfy.h ../fips_utl.h fips_dsatest.c
+fips_dssvs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_dssvs.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_dssvs.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_dssvs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_dssvs.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_dssvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_dssvs.o: ../../include/openssl/opensslconf.h
+fips_dssvs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips_dssvs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_dssvs.o: ../../include/openssl/symhacks.h ../fips_utl.h fips_dssvs.c
diff --git a/crypto/openssl/fips/dsa/fips_dsa_gen.c b/crypto/openssl/fips/dsa/fips_dsa_gen.c
new file mode 100644
index 0000000..0cecf34
--- /dev/null
+++ b/crypto/openssl/fips/dsa/fips_dsa_gen.c
@@ -0,0 +1,339 @@
+/* crypto/dsa/dsa_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#undef GENUINE_DSA
+
+#ifdef GENUINE_DSA
+/* Parameter generation follows the original release of FIPS PUB 186,
+ * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */
+#define HASH EVP_sha()
+#else
+/* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
+ * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in
+ * FIPS PUB 180-1) */
+#define HASH EVP_sha1()
+#endif
+
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_SHA is defined */
+
+#ifndef OPENSSL_NO_SHA
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+#include <openssl/err.h>
+
+#ifdef OPENSSL_FIPS
+
+static int dsa_builtin_paramgen(DSA *ret, int bits,
+ unsigned char *seed_in, int seed_len,
+ int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
+
+int DSA_generate_parameters_ex(DSA *ret, int bits,
+ unsigned char *seed_in, int seed_len,
+ int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
+ {
+ if(ret->meth->dsa_paramgen)
+ return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
+ counter_ret, h_ret, cb);
+ return dsa_builtin_paramgen(ret, bits, seed_in, seed_len,
+ counter_ret, h_ret, cb);
+ }
+
+static int dsa_builtin_paramgen(DSA *ret, int bits,
+ unsigned char *seed_in, int seed_len,
+ int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
+ {
+ int ok=0;
+ unsigned char seed[SHA_DIGEST_LENGTH];
+ unsigned char md[SHA_DIGEST_LENGTH];
+ unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH];
+ BIGNUM *r0,*W,*X,*c,*test;
+ BIGNUM *g=NULL,*q=NULL,*p=NULL;
+ BN_MONT_CTX *mont=NULL;
+ int k,n=0,i,b,m=0;
+ int counter=0;
+ int r=0;
+ BN_CTX *ctx=NULL;
+ unsigned int h=2;
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN,
+ FIPS_R_FIPS_SELFTEST_FAILED);
+ goto err;
+ }
+
+ if (FIPS_mode() && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
+ {
+ DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_TOO_SMALL);
+ goto err;
+ }
+
+ if (bits < 512) bits=512;
+ bits=(bits+63)/64*64;
+
+ /* NB: seed_len == 0 is special case: copy generated seed to
+ * seed_in if it is not NULL.
+ */
+ if (seed_len && (seed_len < 20))
+ seed_in = NULL; /* seed buffer too small -- ignore */
+ if (seed_len > 20)
+ seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
+ * but our internal buffers are restricted to 160 bits*/
+ if ((seed_in != NULL) && (seed_len == 20))
+ {
+ memcpy(seed,seed_in,seed_len);
+ /* set seed_in to NULL to avoid it being copied back */
+ seed_in = NULL;
+ }
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+ if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+
+ BN_CTX_start(ctx);
+ r0 = BN_CTX_get(ctx);
+ g = BN_CTX_get(ctx);
+ W = BN_CTX_get(ctx);
+ q = BN_CTX_get(ctx);
+ X = BN_CTX_get(ctx);
+ c = BN_CTX_get(ctx);
+ p = BN_CTX_get(ctx);
+ test = BN_CTX_get(ctx);
+
+ if (!BN_lshift(test,BN_value_one(),bits-1))
+ goto err;
+
+ for (;;)
+ {
+ for (;;) /* find q */
+ {
+ int seed_is_random;
+
+ /* step 1 */
+ if(!BN_GENCB_call(cb, 0, m++))
+ goto err;
+
+ if (!seed_len)
+ {
+ RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH);
+ seed_is_random = 1;
+ }
+ else
+ {
+ seed_is_random = 0;
+ seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/
+ }
+ memcpy(buf,seed,SHA_DIGEST_LENGTH);
+ memcpy(buf2,seed,SHA_DIGEST_LENGTH);
+ /* precompute "SEED + 1" for step 7: */
+ for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
+ {
+ buf[i]++;
+ if (buf[i] != 0) break;
+ }
+
+ /* step 2 */
+ EVP_Digest(seed,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);
+ EVP_Digest(buf,SHA_DIGEST_LENGTH,buf2,NULL,HASH, NULL);
+ for (i=0; i<SHA_DIGEST_LENGTH; i++)
+ md[i]^=buf2[i];
+
+ /* step 3 */
+ md[0]|=0x80;
+ md[SHA_DIGEST_LENGTH-1]|=0x01;
+ if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err;
+
+ /* step 4 */
+ r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
+ seed_is_random, cb);
+ if (r > 0)
+ break;
+ if (r != 0)
+ goto err;
+
+ /* do a callback call */
+ /* step 5 */
+ }
+
+ if(!BN_GENCB_call(cb, 2, 0)) goto err;
+ if(!BN_GENCB_call(cb, 3, 0)) goto err;
+
+ /* step 6 */
+ counter=0;
+ /* "offset = 2" */
+
+ n=(bits-1)/160;
+ b=(bits-1)-n*160;
+
+ for (;;)
+ {
+ if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
+ goto err;
+
+ /* step 7 */
+ BN_zero(W);
+ /* now 'buf' contains "SEED + offset - 1" */
+ for (k=0; k<=n; k++)
+ {
+ /* obtain "SEED + offset + k" by incrementing: */
+ for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
+ {
+ buf[i]++;
+ if (buf[i] != 0) break;
+ }
+
+ EVP_Digest(buf,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);
+
+ /* step 8 */
+ if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0))
+ goto err;
+ if (!BN_lshift(r0,r0,160*k)) goto err;
+ if (!BN_add(W,W,r0)) goto err;
+ }
+
+ /* more of step 8 */
+ if (!BN_mask_bits(W,bits-1)) goto err;
+ if (!BN_copy(X,W)) goto err;
+ if (!BN_add(X,X,test)) goto err;
+
+ /* step 9 */
+ if (!BN_lshift1(r0,q)) goto err;
+ if (!BN_mod(c,X,r0,ctx)) goto err;
+ if (!BN_sub(r0,c,BN_value_one())) goto err;
+ if (!BN_sub(p,X,r0)) goto err;
+
+ /* step 10 */
+ if (BN_cmp(p,test) >= 0)
+ {
+ /* step 11 */
+ r = BN_is_prime_fasttest_ex(p, DSS_prime_checks,
+ ctx, 1, cb);
+ if (r > 0)
+ goto end; /* found it */
+ if (r != 0)
+ goto err;
+ }
+
+ /* step 13 */
+ counter++;
+ /* "offset = offset + n + 1" */
+
+ /* step 14 */
+ if (counter >= 4096) break;
+ }
+ }
+end:
+ if(!BN_GENCB_call(cb, 2, 1))
+ goto err;
+
+ /* We now need to generate g */
+ /* Set r0=(p-1)/q */
+ if (!BN_sub(test,p,BN_value_one())) goto err;
+ if (!BN_div(r0,NULL,test,q,ctx)) goto err;
+
+ if (!BN_set_word(test,h)) goto err;
+ if (!BN_MONT_CTX_set(mont,p,ctx)) goto err;
+
+ for (;;)
+ {
+ /* g=test^r0%p */
+ if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err;
+ if (!BN_is_one(g)) break;
+ if (!BN_add(test,test,BN_value_one())) goto err;
+ h++;
+ }
+
+ if(!BN_GENCB_call(cb, 3, 1))
+ goto err;
+
+ ok=1;
+err:
+ if (ok)
+ {
+ if(ret->p) BN_free(ret->p);
+ if(ret->q) BN_free(ret->q);
+ if(ret->g) BN_free(ret->g);
+ ret->p=BN_dup(p);
+ ret->q=BN_dup(q);
+ ret->g=BN_dup(g);
+ if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
+ {
+ ok=0;
+ goto err;
+ }
+ if (seed_in != NULL) memcpy(seed_in,seed,20);
+ if (counter_ret != NULL) *counter_ret=counter;
+ if (h_ret != NULL) *h_ret=h;
+ }
+ if(ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (mont != NULL) BN_MONT_CTX_free(mont);
+ return ok;
+ }
+#endif
+#endif
diff --git a/crypto/openssl/fips/dsa/fips_dsa_key.c b/crypto/openssl/fips/dsa/fips_dsa_key.c
new file mode 100644
index 0000000..9f21033
--- /dev/null
+++ b/crypto/openssl/fips/dsa/fips_dsa_key.c
@@ -0,0 +1,169 @@
+/* crypto/dsa/dsa_key.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#ifndef OPENSSL_NO_SHA
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/fips.h>
+#include "fips_locl.h"
+
+#ifdef OPENSSL_FIPS
+
+static int fips_dsa_pairwise_fail = 0;
+
+void FIPS_corrupt_dsa_keygen(void)
+ {
+ fips_dsa_pairwise_fail = 1;
+ }
+
+static int dsa_builtin_keygen(DSA *dsa);
+
+static int fips_check_dsa(DSA *dsa)
+ {
+ EVP_PKEY pk;
+ unsigned char tbs[] = "DSA Pairwise Check Data";
+ pk.type = EVP_PKEY_DSA;
+ pk.pkey.dsa = dsa;
+
+ if (!fips_pkey_signature_test(&pk, tbs, -1,
+ NULL, 0, EVP_dss1(), 0, NULL))
+ {
+ FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED);
+ fips_set_selftest_fail();
+ return 0;
+ }
+ return 1;
+ }
+
+int DSA_generate_key(DSA *dsa)
+ {
+ if(dsa->meth->dsa_keygen)
+ return dsa->meth->dsa_keygen(dsa);
+ return dsa_builtin_keygen(dsa);
+ }
+
+static int dsa_builtin_keygen(DSA *dsa)
+ {
+ int ok=0;
+ BN_CTX *ctx=NULL;
+ BIGNUM *pub_key=NULL,*priv_key=NULL;
+
+ if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
+ {
+ DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL);
+ goto err;
+ }
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+ if (dsa->priv_key == NULL)
+ {
+ if ((priv_key=BN_new()) == NULL) goto err;
+ }
+ else
+ priv_key=dsa->priv_key;
+
+ do
+ if (!BN_rand_range(priv_key,dsa->q)) goto err;
+ while (BN_is_zero(priv_key));
+
+ if (dsa->pub_key == NULL)
+ {
+ if ((pub_key=BN_new()) == NULL) goto err;
+ }
+ else
+ pub_key=dsa->pub_key;
+
+ {
+ BIGNUM local_prk;
+ BIGNUM *prk;
+
+ if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
+ {
+ BN_init(&local_prk);
+ prk = &local_prk;
+ BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
+ }
+ else
+ prk = priv_key;
+
+ if (!BN_mod_exp(pub_key,dsa->g,prk,dsa->p,ctx)) goto err;
+ }
+
+ dsa->priv_key=priv_key;
+ dsa->pub_key=pub_key;
+ if (fips_dsa_pairwise_fail)
+ BN_add_word(dsa->pub_key, 1);
+ if(!fips_check_dsa(dsa))
+ goto err;
+ ok=1;
+
+err:
+ if ((pub_key != NULL) && (dsa->pub_key == NULL)) BN_free(pub_key);
+ if ((priv_key != NULL) && (dsa->priv_key == NULL)) BN_free(priv_key);
+ if (ctx != NULL) BN_CTX_free(ctx);
+ return(ok);
+ }
+#endif
+
+#endif
diff --git a/crypto/openssl/fips/dsa/fips_dsa_lib.c b/crypto/openssl/fips/dsa/fips_dsa_lib.c
new file mode 100644
index 0000000..2545966
--- /dev/null
+++ b/crypto/openssl/fips/dsa/fips_dsa_lib.c
@@ -0,0 +1,95 @@
+/* fips_dsa_lib.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include <openssl/dsa.h>
+#include <openssl/bn.h>
+
+/* Minimal FIPS versions of FIPS_dsa_new() and FIPS_dsa_free: to
+ * reduce external dependencies.
+ */
+
+DSA *FIPS_dsa_new(void)
+ {
+ DSA *ret;
+ ret = OPENSSL_malloc(sizeof(DSA));
+ if (!ret)
+ return NULL;
+ memset(ret, 0, sizeof(DSA));
+ ret->meth = DSA_OpenSSL();
+ if (ret->meth->init)
+ ret->meth->init(ret);
+ return ret;
+ }
+
+void FIPS_dsa_free(DSA *r)
+ {
+ if (!r)
+ return;
+ if (r->meth->finish)
+ r->meth->finish(r);
+ if (r->p != NULL) BN_clear_free(r->p);
+ if (r->q != NULL) BN_clear_free(r->q);
+ if (r->g != NULL) BN_clear_free(r->g);
+ if (r->pub_key != NULL) BN_clear_free(r->pub_key);
+ if (r->priv_key != NULL) BN_clear_free(r->priv_key);
+ if (r->kinv != NULL) BN_clear_free(r->kinv);
+ if (r->r != NULL) BN_clear_free(r->r);
+ OPENSSL_free(r);
+ }
+
diff --git a/crypto/openssl/fips/dsa/fips_dsa_ossl.c b/crypto/openssl/fips/dsa/fips_dsa_ossl.c
new file mode 100644
index 0000000..50a6c13
--- /dev/null
+++ b/crypto/openssl/fips/dsa/fips_dsa_ossl.c
@@ -0,0 +1,435 @@
+/* crypto/dsa/dsa_ossl.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/rand.h>
+#include <openssl/asn1.h>
+#include <openssl/err.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include <openssl/fips.h>
+
+#ifdef OPENSSL_FIPS
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA *dsa);
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
+static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DSA_SIG *sig,
+ DSA *dsa);
+static int dsa_init(DSA *dsa);
+static int dsa_finish(DSA *dsa);
+static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+ BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *in_mont);
+static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx);
+
+static const DSA_METHOD openssl_dsa_meth = {
+"OpenSSL FIPS DSA method",
+dsa_do_sign,
+dsa_sign_setup,
+dsa_do_verify,
+dsa_mod_exp,
+dsa_bn_mod_exp,
+dsa_init,
+dsa_finish,
+DSA_FLAG_FIPS_METHOD,
+NULL
+};
+#if 0
+int FIPS_dsa_check(struct dsa_st *dsa)
+ {
+ if(dsa->meth != &openssl_dsa_meth || dsa->meth->dsa_do_sign != dsa_do_sign
+ || dsa->meth->dsa_sign_setup != dsa_sign_setup
+ || dsa->meth->dsa_mod_exp != dsa_mod_exp
+ || dsa->meth->bn_mod_exp != dsa_bn_mod_exp
+ || dsa->meth->init != dsa_init
+ || dsa->meth->finish != dsa_finish)
+ {
+ FIPSerr(FIPS_F_FIPS_DSA_CHECK,FIPS_R_NON_FIPS_METHOD);
+ return 0;
+ }
+ return 1;
+ }
+#endif
+
+const DSA_METHOD *DSA_OpenSSL(void)
+{
+ return &openssl_dsa_meth;
+}
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA *dsa)
+ {
+ BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
+ BIGNUM m;
+ BIGNUM xr;
+ BN_CTX *ctx=NULL;
+ int i,reason=ERR_R_BN_LIB;
+ DSA_SIG *ret=NULL;
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED);
+ return NULL;
+ }
+
+ if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
+ {
+ DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL);
+ return NULL;
+ }
+
+ BN_init(&m);
+ BN_init(&xr);
+
+ if (!dsa->p || !dsa->q || !dsa->g)
+ {
+ reason=DSA_R_MISSING_PARAMETERS;
+ goto err;
+ }
+
+ s=BN_new();
+ if (s == NULL) goto err;
+
+ i=BN_num_bytes(dsa->q); /* should be 20 */
+ if ((dlen > i) || (dlen > 50))
+ {
+ reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
+ goto err;
+ }
+
+ ctx=BN_CTX_new();
+ if (ctx == NULL) goto err;
+
+ if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r)) goto err;
+
+ if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err;
+
+ /* Compute s = inv(k) (m + xr) mod q */
+ if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
+ if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */
+ if (BN_cmp(s,dsa->q) > 0)
+ BN_sub(s,s,dsa->q);
+ if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
+
+ ret= DSA_SIG_new();
+ if (ret == NULL) goto err;
+ ret->r = r;
+ ret->s = s;
+
+err:
+ if (!ret)
+ {
+ DSAerr(DSA_F_DSA_DO_SIGN,reason);
+ BN_free(r);
+ BN_free(s);
+ }
+ if (ctx != NULL) BN_CTX_free(ctx);
+ BN_clear_free(&m);
+ BN_clear_free(&xr);
+ if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
+ BN_clear_free(kinv);
+ return(ret);
+ }
+
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+ {
+ BN_CTX *ctx;
+ BIGNUM k,kq,*K,*kinv=NULL,*r=NULL;
+ int ret=0;
+
+ if (!dsa->p || !dsa->q || !dsa->g)
+ {
+ DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
+ return 0;
+ }
+
+ BN_init(&k);
+ BN_init(&kq);
+
+ if (ctx_in == NULL)
+ {
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+ }
+ else
+ ctx=ctx_in;
+
+ if ((r=BN_new()) == NULL) goto err;
+
+ /* Get random k */
+ do
+ if (!BN_rand_range(&k, dsa->q)) goto err;
+ while (BN_is_zero(&k));
+ if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
+ {
+ BN_set_flags(&k, BN_FLG_CONSTTIME);
+ }
+
+ if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
+ {
+ if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
+ CRYPTO_LOCK_DSA,
+ dsa->p, ctx))
+ goto err;
+ }
+
+ /* Compute r = (g^k mod p) mod q */
+
+ if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
+ {
+ if (!BN_copy(&kq, &k)) goto err;
+
+ /* We do not want timing information to leak the length of k,
+ * so we compute g^k using an equivalent exponent of fixed length.
+ *
+ * (This is a kludge that we need because the BN_mod_exp_mont()
+ * does not let us specify the desired timing behaviour.) */
+
+ if (!BN_add(&kq, &kq, dsa->q)) goto err;
+ if (BN_num_bits(&kq) <= BN_num_bits(dsa->q))
+ {
+ if (!BN_add(&kq, &kq, dsa->q)) goto err;
+ }
+
+ K = &kq;
+ }
+ else
+ {
+ K = &k;
+ }
+ if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,K,dsa->p,ctx,
+ (BN_MONT_CTX *)dsa->method_mont_p)) goto err;
+ if (!BN_mod(r,r,dsa->q,ctx)) goto err;
+
+ /* Compute part of 's = inv(k) (m + xr) mod q' */
+ if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;
+
+ if (*kinvp != NULL) BN_clear_free(*kinvp);
+ *kinvp=kinv;
+ kinv=NULL;
+ if (*rp != NULL) BN_clear_free(*rp);
+ *rp=r;
+ ret=1;
+err:
+ if (!ret)
+ {
+ DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
+ if (kinv != NULL) BN_clear_free(kinv);
+ if (r != NULL) BN_clear_free(r);
+ }
+ if (ctx_in == NULL) BN_CTX_free(ctx);
+ if (kinv != NULL) BN_clear_free(kinv);
+ BN_clear_free(&k);
+ BN_clear_free(&kq);
+ return(ret);
+ }
+
+static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DSA_SIG *sig,
+ DSA *dsa)
+ {
+ BN_CTX *ctx;
+ BIGNUM u1,u2,t1;
+ BN_MONT_CTX *mont=NULL;
+ int ret = -1;
+
+ if (!dsa->p || !dsa->q || !dsa->g)
+ {
+ DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
+ return -1;
+ }
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED);
+ return -1;
+ }
+
+ if (BN_num_bits(dsa->q) != 160)
+ {
+ DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
+ return -1;
+ }
+
+ if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS)
+ {
+ DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
+ return -1;
+ }
+
+ if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
+ {
+ DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL);
+ return -1;
+ }
+
+ BN_init(&u1);
+ BN_init(&u2);
+ BN_init(&t1);
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+
+ if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
+ {
+ ret = 0;
+ goto err;
+ }
+ if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
+ {
+ ret = 0;
+ goto err;
+ }
+
+ /* Calculate W = inv(S) mod Q
+ * save W in u2 */
+ if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
+
+ /* save M in u1 */
+ if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
+
+ /* u1 = M * w mod q */
+ if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;
+
+ /* u2 = r * w mod q */
+ if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
+
+
+ if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
+ {
+ mont = BN_MONT_CTX_set_locked(
+ (BN_MONT_CTX **)&dsa->method_mont_p,
+ CRYPTO_LOCK_DSA, dsa->p, ctx);
+ if (!mont)
+ goto err;
+ }
+
+#if 0
+ {
+ BIGNUM t2;
+
+ BN_init(&t2);
+ /* v = ( g^u1 * y^u2 mod p ) mod q */
+ /* let t1 = g ^ u1 mod p */
+ if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err;
+ /* let t2 = y ^ u2 mod p */
+ if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err;
+ /* let u1 = t1 * t2 mod p */
+ if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn;
+ BN_free(&t2);
+ }
+ /* let u1 = u1 mod q */
+ if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err;
+#else
+ {
+ if (!dsa->meth->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2,
+ dsa->p,ctx,mont)) goto err;
+ /* BN_copy(&u1,&t1); */
+ /* let u1 = u1 mod q */
+ if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
+ }
+#endif
+ /* V is now in u1. If the signature is correct, it will be
+ * equal to R. */
+ ret=(BN_ucmp(&u1, sig->r) == 0);
+
+ err:
+ if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
+ if (ctx != NULL) BN_CTX_free(ctx);
+ BN_free(&u1);
+ BN_free(&u2);
+ BN_free(&t1);
+ return(ret);
+ }
+
+static int dsa_init(DSA *dsa)
+{
+ FIPS_selftest_check();
+ dsa->flags|=DSA_FLAG_CACHE_MONT_P;
+ return(1);
+}
+
+static int dsa_finish(DSA *dsa)
+{
+ if(dsa->method_mont_p)
+ BN_MONT_CTX_free((BN_MONT_CTX *)dsa->method_mont_p);
+ return(1);
+}
+
+static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+ BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *in_mont)
+{
+ return BN_mod_exp2_mont(rr, a1, p1, a2, p2, m, ctx, in_mont);
+}
+
+static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx)
+{
+ return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
+}
+
+#else /* ndef OPENSSL_FIPS */
+
+static void *dummy=&dummy;
+
+#endif /* ndef OPENSSL_FIPS */
diff --git a/crypto/openssl/fips/dsa/fips_dsa_selftest.c b/crypto/openssl/fips/dsa/fips_dsa_selftest.c
new file mode 100644
index 0000000..6880760
--- /dev/null
+++ b/crypto/openssl/fips/dsa/fips_dsa_selftest.c
@@ -0,0 +1,180 @@
+/* crypto/dsa/dsatest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+
+#ifdef OPENSSL_FIPS
+
+/* seed, out_p, out_q, out_g are taken the NIST test vectors */
+
+static unsigned char seed[20] = {
+ 0x77, 0x8f, 0x40, 0x74, 0x6f, 0x66, 0xbe, 0x33, 0xce, 0xbe, 0x99, 0x34,
+ 0x4c, 0xfc, 0xf3, 0x28, 0xaa, 0x70, 0x2d, 0x3a
+ };
+
+static unsigned char out_p[] = {
+ 0xf7, 0x7c, 0x1b, 0x83, 0xd8, 0xe8, 0x5c, 0x7f, 0x85, 0x30, 0x17, 0x57,
+ 0x21, 0x95, 0xfe, 0x26, 0x04, 0xeb, 0x47, 0x4c, 0x3a, 0x4a, 0x81, 0x4b,
+ 0x71, 0x2e, 0xed, 0x6e, 0x4f, 0x3d, 0x11, 0x0f, 0x7c, 0xfe, 0x36, 0x43,
+ 0x51, 0xd9, 0x81, 0x39, 0x17, 0xdf, 0x62, 0xf6, 0x9c, 0x01, 0xa8, 0x69,
+ 0x71, 0xdd, 0x29, 0x7f, 0x47, 0xe6, 0x65, 0xa6, 0x22, 0xe8, 0x6a, 0x12,
+ 0x2b, 0xc2, 0x81, 0xff, 0x32, 0x70, 0x2f, 0x9e, 0xca, 0x53, 0x26, 0x47,
+ 0x0f, 0x59, 0xd7, 0x9e, 0x2c, 0xa5, 0x07, 0xc4, 0x49, 0x52, 0xa3, 0xe4,
+ 0x6b, 0x04, 0x00, 0x25, 0x49, 0xe2, 0xe6, 0x7f, 0x28, 0x78, 0x97, 0xb8,
+ 0x3a, 0x32, 0x14, 0x38, 0xa2, 0x51, 0x33, 0x22, 0x44, 0x7e, 0xd7, 0xef,
+ 0x45, 0xdb, 0x06, 0x4a, 0xd2, 0x82, 0x4a, 0x82, 0x2c, 0xb1, 0xd7, 0xd8,
+ 0xb6, 0x73, 0x00, 0x4d, 0x94, 0x77, 0x94, 0xef
+ };
+
+static unsigned char out_q[] = {
+ 0xd4, 0x0a, 0xac, 0x9f, 0xbd, 0x8c, 0x80, 0xc2, 0x38, 0x7e, 0x2e, 0x0c,
+ 0x52, 0x5c, 0xea, 0x34, 0xa1, 0x83, 0x32, 0xf3
+ };
+
+static unsigned char out_g[] = {
+ 0x34, 0x73, 0x8b, 0x57, 0x84, 0x8e, 0x55, 0xbf, 0x57, 0xcc, 0x41, 0xbb,
+ 0x5e, 0x2b, 0xd5, 0x42, 0xdd, 0x24, 0x22, 0x2a, 0x09, 0xea, 0x26, 0x1e,
+ 0x17, 0x65, 0xcb, 0x1a, 0xb3, 0x12, 0x44, 0xa3, 0x9e, 0x99, 0xe9, 0x63,
+ 0xeb, 0x30, 0xb1, 0x78, 0x7b, 0x09, 0x40, 0x30, 0xfa, 0x83, 0xc2, 0x35,
+ 0xe1, 0xc4, 0x2d, 0x74, 0x1a, 0xb1, 0x83, 0x54, 0xd8, 0x29, 0xf4, 0xcf,
+ 0x7f, 0x6f, 0x67, 0x1c, 0x36, 0x49, 0xee, 0x6c, 0xa2, 0x3c, 0x2d, 0x6a,
+ 0xe9, 0xd3, 0x9a, 0xf6, 0x57, 0x78, 0x6f, 0xfd, 0x33, 0xcd, 0x3c, 0xed,
+ 0xfd, 0xd4, 0x41, 0xe6, 0x5c, 0x8b, 0xe0, 0x68, 0x31, 0x47, 0x47, 0xaf,
+ 0x12, 0xa7, 0xf9, 0x32, 0x0d, 0x94, 0x15, 0x48, 0xd0, 0x54, 0x85, 0xb2,
+ 0x04, 0xb5, 0x4d, 0xd4, 0x9d, 0x05, 0x22, 0x25, 0xd9, 0xfd, 0x6c, 0x36,
+ 0xef, 0xbe, 0x69, 0x6c, 0x55, 0xf4, 0xee, 0xec
+ };
+
+static const unsigned char str1[]="12345678901234567890";
+
+void FIPS_corrupt_dsa()
+ {
+ ++seed[0];
+ }
+
+int FIPS_selftest_dsa()
+ {
+ DSA *dsa=NULL;
+ int counter,i,j, ret = 0;
+ unsigned int slen;
+ unsigned char buf[256];
+ unsigned long h;
+ EVP_MD_CTX mctx;
+ EVP_PKEY pk;
+
+ EVP_MD_CTX_init(&mctx);
+
+ dsa = FIPS_dsa_new();
+
+ if(dsa == NULL)
+ goto err;
+ if(!DSA_generate_parameters_ex(dsa, 1024,seed,20,&counter,&h,NULL))
+ goto err;
+ if (counter != 378)
+ goto err;
+ if (h != 2)
+ goto err;
+ i=BN_bn2bin(dsa->q,buf);
+ j=sizeof(out_q);
+ if (i != j || memcmp(buf,out_q,i) != 0)
+ goto err;
+
+ i=BN_bn2bin(dsa->p,buf);
+ j=sizeof(out_p);
+ if (i != j || memcmp(buf,out_p,i) != 0)
+ goto err;
+
+ i=BN_bn2bin(dsa->g,buf);
+ j=sizeof(out_g);
+ if (i != j || memcmp(buf,out_g,i) != 0)
+ goto err;
+ DSA_generate_key(dsa);
+ pk.type = EVP_PKEY_DSA;
+ pk.pkey.dsa = dsa;
+
+ if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
+ goto err;
+ if (!EVP_SignUpdate(&mctx, str1, 20))
+ goto err;
+ if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
+ goto err;
+
+ if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
+ goto err;
+ if (!EVP_VerifyUpdate(&mctx, str1, 20))
+ goto err;
+ if (EVP_VerifyFinal(&mctx, buf, slen, &pk) != 1)
+ goto err;
+
+ ret = 1;
+
+ err:
+ EVP_MD_CTX_cleanup(&mctx);
+ if (dsa)
+ FIPS_dsa_free(dsa);
+ if (ret == 0)
+ FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
+ return ret;
+ }
+#endif
diff --git a/crypto/openssl/fips/dsa/fips_dsa_sign.c b/crypto/openssl/fips/dsa/fips_dsa_sign.c
new file mode 100644
index 0000000..7a4d51d
--- /dev/null
+++ b/crypto/openssl/fips/dsa/fips_dsa_sign.c
@@ -0,0 +1,258 @@
+/* fips_dsa_sign.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/dsa.h>
+#include <openssl/err.h>
+#include <openssl/sha.h>
+#include <openssl/bn.h>
+
+#ifdef OPENSSL_FIPS
+
+/* FIPS versions of DSA_sign() and DSA_verify().
+ * These include a tiny ASN1 encoder/decoder to handle the specific
+ * case of a DSA signature.
+ */
+
+#if 0
+int FIPS_dsa_size(DSA *r)
+ {
+ int ilen;
+ ilen = BN_num_bytes(r->q);
+ if (ilen > 20)
+ return -1;
+ /* If MSB set need padding byte */
+ ilen ++;
+ /* Also need 2 bytes INTEGER header for r and s plus
+ * 2 bytes SEQUENCE header making 6 in total.
+ */
+ return ilen * 2 + 6;
+ }
+#endif
+
+/* Tiny ASN1 encoder for DSA_SIG structure. We can assume r, s smaller than
+ * 0x80 octets as by the DSA standards they will be less than 2^160
+ */
+
+int FIPS_dsa_sig_encode(unsigned char *out, DSA_SIG *sig)
+ {
+ int rlen, slen, rpad, spad, seqlen;
+ rlen = BN_num_bytes(sig->r);
+ if (rlen > 20)
+ return -1;
+ if (BN_num_bits(sig->r) & 0x7)
+ rpad = 0;
+ else
+ rpad = 1;
+ slen = BN_num_bytes(sig->s);
+ if (slen > 20)
+ return -1;
+ if (BN_num_bits(sig->s) & 0x7)
+ spad = 0;
+ else
+ spad = 1;
+ /* Length of SEQUENCE, (1 tag + 1 len octet) * 2 + content octets */
+ seqlen = rlen + rpad + slen + spad + 4;
+ /* Actual encoded length: include SEQUENCE header */
+ if (!out)
+ return seqlen + 2;
+
+ /* Output SEQUENCE header */
+ *out++ = V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED;
+ *out++ = (unsigned char)seqlen;
+
+ /* Output r */
+ *out++ = V_ASN1_INTEGER;
+ *out++ = (unsigned char)(rlen + rpad);
+ if (rpad)
+ *out++ = 0;
+ BN_bn2bin(sig->r, out);
+ out += rlen;
+
+ /* Output s */
+ *out++ = V_ASN1_INTEGER;
+ *out++ = (unsigned char)(slen + spad);
+ if (spad)
+ *out++ = 0;
+ BN_bn2bin(sig->s, out);
+ return seqlen + 2;
+ }
+
+/* Companion DSA_SIG decoder */
+
+int FIPS_dsa_sig_decode(DSA_SIG *sig, const unsigned char *in, int inlen)
+ {
+ int seqlen, rlen, slen;
+ const unsigned char *rbin;
+ /* Sanity check */
+
+ /* Need SEQUENCE tag */
+ if (*in++ != (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
+ return 0;
+ /* Get length octet */
+ seqlen = *in++;
+ /* Check sensible length value */
+ if (seqlen < 4 || seqlen > 0x7F)
+ return 0;
+ /* Check INTEGER tag */
+ if (*in++ != V_ASN1_INTEGER)
+ return 0;
+ rlen = *in++;
+ seqlen -= 2 + rlen;
+ /* Check sensible seqlen value */
+ if (seqlen < 2)
+ return 0;
+ rbin = in;
+ in += rlen;
+ /* Check INTEGER tag */
+ if (*in++ != V_ASN1_INTEGER)
+ return 0;
+ slen = *in++;
+ /* Remaining bytes of SEQUENCE should exactly match
+ * encoding of s
+ */
+ if (seqlen != (slen + 2))
+ return 0;
+ if (!sig->r && !(sig->r = BN_new()))
+ return 0;
+ if (!sig->s && !(sig->s = BN_new()))
+ return 0;
+ if (!BN_bin2bn(rbin, rlen, sig->r))
+ return 0;
+ if (!BN_bin2bn(in, slen, sig->s))
+ return 0;
+ return 1;
+ }
+
+static int fips_dsa_sign(int type, const unsigned char *x, int y,
+ unsigned char *sig, unsigned int *siglen, EVP_MD_SVCTX *sv)
+ {
+ DSA *dsa = sv->key;
+ unsigned char dig[EVP_MAX_MD_SIZE];
+ unsigned int dlen;
+ DSA_SIG *s;
+ EVP_DigestFinal_ex(sv->mctx, dig, &dlen);
+ s=dsa->meth->dsa_do_sign(dig,dlen,dsa);
+ OPENSSL_cleanse(dig, dlen);
+ if (s == NULL)
+ {
+ *siglen=0;
+ return 0;
+ }
+ *siglen= FIPS_dsa_sig_encode(sig, s);
+ DSA_SIG_free(s);
+ if (*siglen < 0)
+ return 0;
+ return 1;
+ }
+
+static int fips_dsa_verify(int type, const unsigned char *x, int y,
+ const unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv)
+ {
+ DSA *dsa = sv->key;
+ DSA_SIG *s;
+ int ret=-1;
+ unsigned char dig[EVP_MAX_MD_SIZE];
+ unsigned int dlen;
+
+ s = DSA_SIG_new();
+ if (s == NULL)
+ return ret;
+ if (!FIPS_dsa_sig_decode(s,sigbuf,siglen))
+ goto err;
+ EVP_DigestFinal_ex(sv->mctx, dig, &dlen);
+ ret=dsa->meth->dsa_do_verify(dig,dlen,s,dsa);
+ OPENSSL_cleanse(dig, dlen);
+err:
+ DSA_SIG_free(s);
+ return ret;
+ }
+
+static int init(EVP_MD_CTX *ctx)
+ { return SHA1_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+ { return SHA1_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+ { return SHA1_Final(md,ctx->md_data); }
+
+static const EVP_MD dss1_md=
+ {
+ NID_dsa,
+ NID_dsaWithSHA1,
+ SHA_DIGEST_LENGTH,
+ EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ (evp_sign_method *)fips_dsa_sign,
+ (evp_verify_method *)fips_dsa_verify,
+ {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, EVP_PKEY_DSA4,0},
+ SHA_CBLOCK,
+ sizeof(EVP_MD *)+sizeof(SHA_CTX),
+ };
+
+const EVP_MD *EVP_dss1(void)
+ {
+ return(&dss1_md);
+ }
+#endif
diff --git a/crypto/openssl/fips/dsa/fips_dsatest.c b/crypto/openssl/fips/dsa/fips_dsatest.c
new file mode 100644
index 0000000..1aec089
--- /dev/null
+++ b/crypto/openssl/fips/dsa/fips_dsatest.c
@@ -0,0 +1,271 @@
+/* crypto/dsa/dsatest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "e_os.h"
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+
+#if defined(OPENSSL_NO_DSA) || !defined(OPENSSL_FIPS)
+int main(int argc, char *argv[])
+{
+ printf("No FIPS DSA support\n");
+ return(0);
+}
+#else
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
+#include <openssl/dsa.h>
+
+#ifdef OPENSSL_SYS_WIN16
+#define MS_CALLBACK _far _loadds
+#else
+#define MS_CALLBACK
+#endif
+
+#include "fips_utl.h"
+
+static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb);
+
+/* seed, out_p, out_q, out_g are taken from the earlier validation test
+ * vectors.
+ */
+
+static unsigned char seed[20] = {
+ 0x1c, 0xfb, 0xa9, 0x6c, 0xf7, 0x95, 0xb3, 0x2e, 0x01, 0x01, 0x3c, 0x8d,
+ 0x7f, 0x6e, 0xf4, 0x59, 0xcc, 0x2f, 0x19, 0x59
+ };
+
+static unsigned char out_p[] = {
+ 0xc2, 0x3c, 0x48, 0x31, 0x7e, 0x3b, 0x4e, 0x5d, 0x3c, 0x93, 0x78, 0x60,
+ 0x5c, 0xf2, 0x60, 0xbb, 0x5a, 0xfa, 0x7f, 0x17, 0xf9, 0x26, 0x69, 0x46,
+ 0xe7, 0x07, 0xbb, 0x3b, 0x2e, 0xc4, 0xb5, 0x66, 0xf7, 0x4d, 0xae, 0x9b,
+ 0x8f, 0xf0, 0x42, 0xea, 0xb3, 0xa0, 0x7e, 0x81, 0x85, 0x89, 0xe6, 0xb0,
+ 0x29, 0x03, 0x6b, 0xcc, 0xfb, 0x8e, 0x46, 0x15, 0x4d, 0xc1, 0x69, 0xd8,
+ 0x2f, 0xef, 0x5c, 0x8b, 0x29, 0x32, 0x41, 0xbd, 0x13, 0x72, 0x3d, 0xac,
+ 0x81, 0xcc, 0x86, 0x6c, 0x06, 0x5d, 0x51, 0xa1, 0xa5, 0x07, 0x0c, 0x3e,
+ 0xbe, 0xdd, 0xf4, 0x6e, 0xa8, 0xed, 0xb4, 0x2f, 0xbd, 0x3e, 0x64, 0xea,
+ 0xee, 0x92, 0xec, 0x51, 0xe1, 0x0d, 0xab, 0x25, 0x45, 0xae, 0x55, 0x21,
+ 0x4d, 0xd6, 0x96, 0x6f, 0xe6, 0xaa, 0xd3, 0xca, 0x87, 0x92, 0xb1, 0x1c,
+ 0x3c, 0xaf, 0x29, 0x09, 0x8b, 0xc6, 0xed, 0xe1
+ };
+
+static unsigned char out_q[] = {
+ 0xae, 0x0a, 0x8c, 0xfb, 0x80, 0xe1, 0xc6, 0xd1, 0x09, 0x0f, 0x26, 0xde,
+ 0x91, 0x53, 0xc2, 0x8b, 0x2b, 0x0f, 0xde, 0x7f
+ };
+
+static unsigned char out_g[] = {
+ 0x0d, 0x7d, 0x92, 0x74, 0x10, 0xf6, 0xa4, 0x43, 0x86, 0x9a, 0xd1, 0xd9,
+ 0x56, 0x00, 0xbc, 0x18, 0x97, 0x99, 0x4e, 0x9a, 0x93, 0xfb, 0x00, 0x3d,
+ 0x6c, 0xa0, 0x1b, 0x95, 0x6b, 0xbd, 0xf7, 0x7a, 0xbc, 0x36, 0x3f, 0x3d,
+ 0xb9, 0xbf, 0xf9, 0x91, 0x37, 0x68, 0xd1, 0xb9, 0x1e, 0xfe, 0x7f, 0x10,
+ 0xc0, 0x6a, 0xcd, 0x5f, 0xc1, 0x65, 0x1a, 0xb8, 0xe7, 0xab, 0xb5, 0xc6,
+ 0x8d, 0xb7, 0x86, 0xad, 0x3a, 0xbf, 0x6b, 0x7b, 0x0a, 0x66, 0xbe, 0xd5,
+ 0x58, 0x23, 0x16, 0x48, 0x83, 0x29, 0xb6, 0xa7, 0x64, 0xc7, 0x08, 0xbe,
+ 0x55, 0x4c, 0x6f, 0xcb, 0x34, 0xc1, 0x73, 0xb0, 0x39, 0x68, 0x52, 0xdf,
+ 0x27, 0x7f, 0x32, 0xbc, 0x2b, 0x0d, 0x63, 0xed, 0x75, 0x3e, 0xb5, 0x54,
+ 0xac, 0xc8, 0x20, 0x2a, 0x73, 0xe8, 0x29, 0x51, 0x03, 0x77, 0xe8, 0xc9,
+ 0x61, 0x32, 0x25, 0xaf, 0x21, 0x5b, 0x6e, 0xda
+ };
+
+
+static const unsigned char str1[]="12345678901234567890";
+
+static const char rnd_seed[] = "string to make the random number generator think it has entropy";
+
+int main(int argc, char **argv)
+ {
+ DSA *dsa=NULL;
+ EVP_PKEY pk;
+ int counter,ret=0,i,j;
+ unsigned int slen;
+ unsigned char buf[256];
+ unsigned long h;
+ BN_GENCB cb;
+ EVP_MD_CTX mctx;
+ BN_GENCB_set(&cb, dsa_cb, stderr);
+ EVP_MD_CTX_init(&mctx);
+
+ if(!FIPS_mode_set(1))
+ {
+ do_print_errors();
+ EXIT(1);
+ }
+
+ fprintf(stderr,"test generation of DSA parameters\n");
+
+ dsa = FIPS_dsa_new();
+ DSA_generate_parameters_ex(dsa, 1024,seed,20,&counter,&h,&cb);
+
+ fprintf(stderr,"seed\n");
+ for (i=0; i<20; i+=4)
+ {
+ fprintf(stderr,"%02X%02X%02X%02X ",
+ seed[i],seed[i+1],seed[i+2],seed[i+3]);
+ }
+ fprintf(stderr,"\ncounter=%d h=%ld\n",counter,h);
+
+ if (dsa == NULL) goto end;
+ if (counter != 16)
+ {
+ fprintf(stderr,"counter should be 105\n");
+ goto end;
+ }
+ if (h != 2)
+ {
+ fprintf(stderr,"h should be 2\n");
+ goto end;
+ }
+
+ i=BN_bn2bin(dsa->q,buf);
+ j=sizeof(out_q);
+ if ((i != j) || (memcmp(buf,out_q,i) != 0))
+ {
+ fprintf(stderr,"q value is wrong\n");
+ goto end;
+ }
+
+ i=BN_bn2bin(dsa->p,buf);
+ j=sizeof(out_p);
+ if ((i != j) || (memcmp(buf,out_p,i) != 0))
+ {
+ fprintf(stderr,"p value is wrong\n");
+ goto end;
+ }
+
+ i=BN_bn2bin(dsa->g,buf);
+ j=sizeof(out_g);
+ if ((i != j) || (memcmp(buf,out_g,i) != 0))
+ {
+ fprintf(stderr,"g value is wrong\n");
+ goto end;
+ }
+ DSA_generate_key(dsa);
+ pk.type = EVP_PKEY_DSA;
+ pk.pkey.dsa = dsa;
+
+ if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
+ goto end;
+ if (!EVP_SignUpdate(&mctx, str1, 20))
+ goto end;
+ if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
+ goto end;
+
+ if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
+ goto end;
+ if (!EVP_VerifyUpdate(&mctx, str1, 20))
+ goto end;
+ if (EVP_VerifyFinal(&mctx, buf, slen, &pk) != 1)
+ goto end;
+
+ ret = 1;
+
+end:
+ if (!ret)
+ do_print_errors();
+ if (dsa != NULL) FIPS_dsa_free(dsa);
+ EVP_MD_CTX_cleanup(&mctx);
+#if 0
+ CRYPTO_mem_leaks(bio_err);
+#endif
+ EXIT(!ret);
+ return(!ret);
+ }
+
+static int cb_exit(int ec)
+ {
+ EXIT(ec);
+ return(0); /* To keep some compilers quiet */
+ }
+
+static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb)
+ {
+ char c='*';
+ static int ok=0,num=0;
+
+ if (p == 0) { c='.'; num++; };
+ if (p == 1) c='+';
+ if (p == 2) { c='*'; ok++; }
+ if (p == 3) c='\n';
+ fwrite(&c,1, 1, cb->arg);
+ fflush(cb->arg);
+
+ if (!ok && (p == 0) && (num > 1))
+ {
+ fprintf(cb->arg,"error in dsatest\n");
+ cb_exit(1);
+ }
+ return 1;
+ }
+#endif
diff --git a/crypto/openssl/fips/dsa/fips_dssvs.c b/crypto/openssl/fips/dsa/fips_dssvs.c
new file mode 100644
index 0000000..45f4e1c
--- /dev/null
+++ b/crypto/openssl/fips/dsa/fips_dssvs.c
@@ -0,0 +1,537 @@
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_FIPS
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ printf("No FIPS DSA support\n");
+ return(0);
+}
+#else
+
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "fips_utl.h"
+
+static void pbn(const char *name, BIGNUM *bn)
+ {
+ int len, i;
+ unsigned char *tmp;
+ len = BN_num_bytes(bn);
+ tmp = OPENSSL_malloc(len);
+ if (!tmp)
+ {
+ fprintf(stderr, "Memory allocation error\n");
+ return;
+ }
+ BN_bn2bin(bn, tmp);
+ printf("%s = ", name);
+ for (i = 0; i < len; i++)
+ printf("%02X", tmp[i]);
+ fputs("\n", stdout);
+ OPENSSL_free(tmp);
+ return;
+ }
+
+static void primes()
+ {
+ char buf[10240];
+ char lbuf[10240];
+ char *keyword, *value;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ fputs(buf,stdout);
+ if (!parse_line(&keyword, &value, lbuf, buf))
+ continue;
+ if(!strcmp(keyword,"Prime"))
+ {
+ BIGNUM *pp;
+
+ pp=BN_new();
+ do_hex2bn(&pp,value);
+ printf("result= %c\n",
+ BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
+ }
+ }
+ }
+
+static void pqg()
+ {
+ char buf[1024];
+ char lbuf[1024];
+ char *keyword, *value;
+ int nmod=0;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if (!parse_line(&keyword, &value, lbuf, buf))
+ {
+ fputs(buf,stdout);
+ continue;
+ }
+ if(!strcmp(keyword,"[mod"))
+ nmod=atoi(value);
+ else if(!strcmp(keyword,"N"))
+ {
+ int n=atoi(value);
+
+ printf("[mod = %d]\n\n",nmod);
+
+ while(n--)
+ {
+ unsigned char seed[20];
+ DSA *dsa;
+ int counter;
+ unsigned long h;
+ dsa = FIPS_dsa_new();
+
+ if (!DSA_generate_parameters_ex(dsa, nmod,seed,0,&counter,&h,NULL))
+ {
+ do_print_errors();
+ exit(1);
+ }
+ pbn("P",dsa->p);
+ pbn("Q",dsa->q);
+ pbn("G",dsa->g);
+ pv("Seed",seed,20);
+ printf("c = %d\n",counter);
+ printf("H = %lx\n",h);
+ putc('\n',stdout);
+ }
+ }
+ else
+ fputs(buf,stdout);
+ }
+ }
+
+static void pqgver()
+ {
+ char buf[1024];
+ char lbuf[1024];
+ char *keyword, *value;
+ BIGNUM *p = NULL, *q = NULL, *g = NULL;
+ int counter, counter2;
+ unsigned long h, h2;
+ DSA *dsa=NULL;
+ int nmod=0;
+ unsigned char seed[1024];
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if (!parse_line(&keyword, &value, lbuf, buf))
+ {
+ fputs(buf,stdout);
+ continue;
+ }
+ fputs(buf, stdout);
+ if(!strcmp(keyword,"[mod"))
+ nmod=atoi(value);
+ else if(!strcmp(keyword,"P"))
+ p=hex2bn(value);
+ else if(!strcmp(keyword,"Q"))
+ q=hex2bn(value);
+ else if(!strcmp(keyword,"G"))
+ g=hex2bn(value);
+ else if(!strcmp(keyword,"Seed"))
+ {
+ int slen = hex2bin(value, seed);
+ if (slen != 20)
+ {
+ fprintf(stderr, "Seed parse length error\n");
+ exit (1);
+ }
+ }
+ else if(!strcmp(keyword,"c"))
+ counter =atoi(buf+4);
+ else if(!strcmp(keyword,"H"))
+ {
+ h = atoi(value);
+ if (!p || !q || !g)
+ {
+ fprintf(stderr, "Parse Error\n");
+ exit (1);
+ }
+ dsa = FIPS_dsa_new();
+ if (!DSA_generate_parameters_ex(dsa, nmod,seed,20 ,&counter2,&h2,NULL))
+ {
+ do_print_errors();
+ exit(1);
+ }
+ if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g)
+ || (counter != counter2) || (h != h2))
+ printf("Result = F\n");
+ else
+ printf("Result = P\n");
+ BN_free(p);
+ BN_free(q);
+ BN_free(g);
+ p = NULL;
+ q = NULL;
+ g = NULL;
+ FIPS_dsa_free(dsa);
+ dsa = NULL;
+ }
+ }
+ }
+
+/* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
+ * algorithm tests. It is an additional test to perform sanity checks on the
+ * output of the KeyPair test.
+ */
+
+static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
+ BN_CTX *ctx)
+ {
+ BIGNUM *rem = NULL;
+ if (BN_num_bits(p) != nmod)
+ return 0;
+ if (BN_num_bits(q) != 160)
+ return 0;
+ if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
+ return 0;
+ if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
+ return 0;
+ rem = BN_new();
+ if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
+ || (BN_cmp(g, BN_value_one()) <= 0)
+ || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
+ {
+ BN_free(rem);
+ return 0;
+ }
+ /* Todo: check g */
+ BN_free(rem);
+ return 1;
+ }
+
+static void keyver()
+ {
+ char buf[1024];
+ char lbuf[1024];
+ char *keyword, *value;
+ BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
+ BIGNUM *Y2;
+ BN_CTX *ctx = NULL;
+ int nmod=0, paramcheck = 0;
+
+ ctx = BN_CTX_new();
+ Y2 = BN_new();
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if (!parse_line(&keyword, &value, lbuf, buf))
+ {
+ fputs(buf,stdout);
+ continue;
+ }
+ if(!strcmp(keyword,"[mod"))
+ {
+ if (p)
+ BN_free(p);
+ p = NULL;
+ if (q)
+ BN_free(q);
+ q = NULL;
+ if (g)
+ BN_free(g);
+ g = NULL;
+ paramcheck = 0;
+ nmod=atoi(value);
+ }
+ else if(!strcmp(keyword,"P"))
+ p=hex2bn(value);
+ else if(!strcmp(keyword,"Q"))
+ q=hex2bn(value);
+ else if(!strcmp(keyword,"G"))
+ g=hex2bn(value);
+ else if(!strcmp(keyword,"X"))
+ X=hex2bn(value);
+ else if(!strcmp(keyword,"Y"))
+ {
+ Y=hex2bn(value);
+ if (!p || !q || !g || !X || !Y)
+ {
+ fprintf(stderr, "Parse Error\n");
+ exit (1);
+ }
+ pbn("P",p);
+ pbn("Q",q);
+ pbn("G",g);
+ pbn("X",X);
+ pbn("Y",Y);
+ if (!paramcheck)
+ {
+ if (dss_paramcheck(nmod, p, q, g, ctx))
+ paramcheck = 1;
+ else
+ paramcheck = -1;
+ }
+ if (paramcheck != 1)
+ printf("Result = F\n");
+ else
+ {
+ if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
+ printf("Result = F\n");
+ else
+ printf("Result = P\n");
+ }
+ BN_free(X);
+ BN_free(Y);
+ X = NULL;
+ Y = NULL;
+ }
+ }
+ if (p)
+ BN_free(p);
+ if (q)
+ BN_free(q);
+ if (g)
+ BN_free(g);
+ if (Y2)
+ BN_free(Y2);
+ }
+
+static void keypair()
+ {
+ char buf[1024];
+ char lbuf[1024];
+ char *keyword, *value;
+ int nmod=0;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if (!parse_line(&keyword, &value, lbuf, buf))
+ {
+ fputs(buf,stdout);
+ continue;
+ }
+ if(!strcmp(keyword,"[mod"))
+ nmod=atoi(value);
+ else if(!strcmp(keyword,"N"))
+ {
+ DSA *dsa;
+ int n=atoi(value);
+
+ printf("[mod = %d]\n\n",nmod);
+ dsa = FIPS_dsa_new();
+ if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
+ {
+ do_print_errors();
+ exit(1);
+ }
+ pbn("P",dsa->p);
+ pbn("Q",dsa->q);
+ pbn("G",dsa->g);
+ putc('\n',stdout);
+
+ while(n--)
+ {
+ if (!DSA_generate_key(dsa))
+ {
+ do_print_errors();
+ exit(1);
+ }
+
+ pbn("X",dsa->priv_key);
+ pbn("Y",dsa->pub_key);
+ putc('\n',stdout);
+ }
+ }
+ }
+ }
+
+static void siggen()
+ {
+ char buf[1024];
+ char lbuf[1024];
+ char *keyword, *value;
+ int nmod=0;
+ DSA *dsa=NULL;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if (!parse_line(&keyword, &value, lbuf, buf))
+ {
+ fputs(buf,stdout);
+ continue;
+ }
+ if(!strcmp(keyword,"[mod"))
+ {
+ nmod=atoi(value);
+ printf("[mod = %d]\n\n",nmod);
+ if (dsa)
+ FIPS_dsa_free(dsa);
+ dsa = FIPS_dsa_new();
+ if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
+ {
+ do_print_errors();
+ exit(1);
+ }
+ pbn("P",dsa->p);
+ pbn("Q",dsa->q);
+ pbn("G",dsa->g);
+ putc('\n',stdout);
+ }
+ else if(!strcmp(keyword,"Msg"))
+ {
+ unsigned char msg[1024];
+ unsigned char sbuf[60];
+ unsigned int slen;
+ int n;
+ EVP_PKEY pk;
+ EVP_MD_CTX mctx;
+ DSA_SIG *sig;
+ EVP_MD_CTX_init(&mctx);
+
+ n=hex2bin(value,msg);
+ pv("Msg",msg,n);
+
+ if (!DSA_generate_key(dsa))
+ {
+ do_print_errors();
+ exit(1);
+ }
+ pk.type = EVP_PKEY_DSA;
+ pk.pkey.dsa = dsa;
+ pbn("Y",dsa->pub_key);
+
+ EVP_SignInit_ex(&mctx, EVP_dss1(), NULL);
+ EVP_SignUpdate(&mctx, msg, n);
+ EVP_SignFinal(&mctx, sbuf, &slen, &pk);
+
+ sig = DSA_SIG_new();
+ FIPS_dsa_sig_decode(sig, sbuf, slen);
+
+ pbn("R",sig->r);
+ pbn("S",sig->s);
+ putc('\n',stdout);
+ DSA_SIG_free(sig);
+ EVP_MD_CTX_cleanup(&mctx);
+ }
+ }
+ if (dsa)
+ FIPS_dsa_free(dsa);
+ }
+
+static void sigver()
+ {
+ DSA *dsa=NULL;
+ char buf[1024];
+ char lbuf[1024];
+ unsigned char msg[1024];
+ char *keyword, *value;
+ int nmod=0, n=0;
+ DSA_SIG sg, *sig = &sg;
+
+ sig->r = NULL;
+ sig->s = NULL;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if (!parse_line(&keyword, &value, lbuf, buf))
+ {
+ fputs(buf,stdout);
+ continue;
+ }
+ if(!strcmp(keyword,"[mod"))
+ {
+ nmod=atoi(value);
+ if(dsa)
+ FIPS_dsa_free(dsa);
+ dsa=FIPS_dsa_new();
+ }
+ else if(!strcmp(keyword,"P"))
+ dsa->p=hex2bn(value);
+ else if(!strcmp(keyword,"Q"))
+ dsa->q=hex2bn(value);
+ else if(!strcmp(keyword,"G"))
+ {
+ dsa->g=hex2bn(value);
+
+ printf("[mod = %d]\n\n",nmod);
+ pbn("P",dsa->p);
+ pbn("Q",dsa->q);
+ pbn("G",dsa->g);
+ putc('\n',stdout);
+ }
+ else if(!strcmp(keyword,"Msg"))
+ {
+ n=hex2bin(value,msg);
+ pv("Msg",msg,n);
+ }
+ else if(!strcmp(keyword,"Y"))
+ dsa->pub_key=hex2bn(value);
+ else if(!strcmp(keyword,"R"))
+ sig->r=hex2bn(value);
+ else if(!strcmp(keyword,"S"))
+ {
+ EVP_MD_CTX mctx;
+ EVP_PKEY pk;
+ unsigned char sigbuf[60];
+ unsigned int slen;
+ int r;
+ EVP_MD_CTX_init(&mctx);
+ pk.type = EVP_PKEY_DSA;
+ pk.pkey.dsa = dsa;
+ sig->s=hex2bn(value);
+
+ pbn("Y",dsa->pub_key);
+ pbn("R",sig->r);
+ pbn("S",sig->s);
+
+ slen = FIPS_dsa_sig_encode(sigbuf, sig);
+ EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL);
+ EVP_VerifyUpdate(&mctx, msg, n);
+ r = EVP_VerifyFinal(&mctx, sigbuf, slen, &pk);
+ EVP_MD_CTX_cleanup(&mctx);
+
+ printf("Result = %c\n", r == 1 ? 'P' : 'F');
+ putc('\n',stdout);
+ }
+ }
+ }
+
+int main(int argc,char **argv)
+ {
+ if(argc != 2)
+ {
+ fprintf(stderr,"%s [prime|pqg|pqgver|keypair|siggen|sigver]\n",argv[0]);
+ exit(1);
+ }
+ if(!FIPS_mode_set(1))
+ {
+ do_print_errors();
+ exit(1);
+ }
+ if(!strcmp(argv[1],"prime"))
+ primes();
+ else if(!strcmp(argv[1],"pqg"))
+ pqg();
+ else if(!strcmp(argv[1],"pqgver"))
+ pqgver();
+ else if(!strcmp(argv[1],"keypair"))
+ keypair();
+ else if(!strcmp(argv[1],"keyver"))
+ keyver();
+ else if(!strcmp(argv[1],"siggen"))
+ siggen();
+ else if(!strcmp(argv[1],"sigver"))
+ sigver();
+ else
+ {
+ fprintf(stderr,"Don't know how to %s.\n",argv[1]);
+ exit(1);
+ }
+
+ return 0;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/fips-nodiff.txt b/crypto/openssl/fips/fips-nodiff.txt
new file mode 100644
index 0000000..fb2944b
--- /dev/null
+++ b/crypto/openssl/fips/fips-nodiff.txt
@@ -0,0 +1,7 @@
+KeyPair.rsp
+PQGGen.rsp
+SigGen.rsp
+SigGen15.rsp
+SigGenPSS.rsp
+SigGenRSA.rsp
+SigGenPSS.rsp
diff --git a/crypto/openssl/fips/fips.c b/crypto/openssl/fips/fips.c
new file mode 100644
index 0000000..7dcc344
--- /dev/null
+++ b/crypto/openssl/fips/fips.c
@@ -0,0 +1,519 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#include <openssl/err.h>
+#include <openssl/bio.h>
+#include <openssl/hmac.h>
+#include <openssl/rsa.h>
+#include <string.h>
+#include <limits.h>
+#include "fips_locl.h"
+
+#ifdef OPENSSL_FIPS
+
+#include <openssl/fips.h>
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+static int fips_selftest_fail;
+static int fips_mode;
+static const void *fips_rand_check;
+
+static void fips_set_mode(int onoff)
+ {
+ int owning_thread = fips_is_owning_thread();
+
+ if (fips_is_started())
+ {
+ if (!owning_thread) fips_w_lock();
+ fips_mode = onoff;
+ if (!owning_thread) fips_w_unlock();
+ }
+ }
+
+static void fips_set_rand_check(const void *rand_check)
+ {
+ int owning_thread = fips_is_owning_thread();
+
+ if (fips_is_started())
+ {
+ if (!owning_thread) fips_w_lock();
+ fips_rand_check = rand_check;
+ if (!owning_thread) fips_w_unlock();
+ }
+ }
+
+int FIPS_mode(void)
+ {
+ int ret = 0;
+ int owning_thread = fips_is_owning_thread();
+
+ if (fips_is_started())
+ {
+ if (!owning_thread) fips_r_lock();
+ ret = fips_mode;
+ if (!owning_thread) fips_r_unlock();
+ }
+ return ret;
+ }
+
+const void *FIPS_rand_check(void)
+ {
+ const void *ret = 0;
+ int owning_thread = fips_is_owning_thread();
+
+ if (fips_is_started())
+ {
+ if (!owning_thread) fips_r_lock();
+ ret = fips_rand_check;
+ if (!owning_thread) fips_r_unlock();
+ }
+ return ret;
+ }
+
+int FIPS_selftest_failed(void)
+ {
+ int ret = 0;
+ if (fips_is_started())
+ {
+ int owning_thread = fips_is_owning_thread();
+
+ if (!owning_thread) fips_r_lock();
+ ret = fips_selftest_fail;
+ if (!owning_thread) fips_r_unlock();
+ }
+ return ret;
+ }
+
+/* Selftest failure fatal exit routine. This will be called
+ * during *any* cryptographic operation. It has the minimum
+ * overhead possible to avoid too big a performance hit.
+ */
+
+void FIPS_selftest_check(void)
+ {
+ if (fips_selftest_fail)
+ {
+ OpenSSLDie(__FILE__,__LINE__, "FATAL FIPS SELFTEST FAILURE");
+ }
+ }
+
+void fips_set_selftest_fail(void)
+ {
+ fips_selftest_fail = 1;
+ }
+
+int FIPS_selftest()
+ {
+
+ return FIPS_selftest_sha1()
+ && FIPS_selftest_hmac()
+ && FIPS_selftest_aes()
+ && FIPS_selftest_des()
+ && FIPS_selftest_rsa()
+ && FIPS_selftest_dsa();
+ }
+
+extern const void *FIPS_text_start(), *FIPS_text_end();
+extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[];
+unsigned char FIPS_signature [20] = { 0 };
+static const char FIPS_hmac_key[]="etaonrishdlcupfm";
+
+unsigned int FIPS_incore_fingerprint(unsigned char *sig,unsigned int len)
+ {
+ const unsigned char *p1 = FIPS_text_start();
+ const unsigned char *p2 = FIPS_text_end();
+ const unsigned char *p3 = FIPS_rodata_start;
+ const unsigned char *p4 = FIPS_rodata_end;
+ HMAC_CTX c;
+
+ HMAC_CTX_init(&c);
+ HMAC_Init(&c,FIPS_hmac_key,strlen(FIPS_hmac_key),EVP_sha1());
+
+ /* detect overlapping regions */
+ if (p1<=p3 && p2>=p3)
+ p3=p1, p4=p2>p4?p2:p4, p1=NULL, p2=NULL;
+ else if (p3<=p1 && p4>=p1)
+ p3=p3, p4=p2>p4?p2:p4, p1=NULL, p2=NULL;
+
+ if (p1)
+ HMAC_Update(&c,p1,(size_t)p2-(size_t)p1);
+
+ if (FIPS_signature>=p3 && FIPS_signature<p4)
+ {
+ /* "punch" hole */
+ HMAC_Update(&c,p3,(size_t)FIPS_signature-(size_t)p3);
+ p3 = FIPS_signature+sizeof(FIPS_signature);
+ if (p3<p4)
+ HMAC_Update(&c,p3,(size_t)p4-(size_t)p3);
+ }
+ else
+ HMAC_Update(&c,p3,(size_t)p4-(size_t)p3);
+
+ HMAC_Final(&c,sig,&len);
+ HMAC_CTX_cleanup(&c);
+
+ return len;
+ }
+
+int FIPS_check_incore_fingerprint(void)
+ {
+ unsigned char sig[EVP_MAX_MD_SIZE];
+ unsigned int len;
+#if defined(__sgi) && (defined(__mips) || defined(mips))
+ extern int __dso_displacement[];
+#else
+ extern int OPENSSL_NONPIC_relocated;
+#endif
+
+ if (FIPS_text_start()==NULL)
+ {
+ FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_UNSUPPORTED_PLATFORM);
+ return 0;
+ }
+
+ len=FIPS_incore_fingerprint (sig,sizeof(sig));
+
+ if (len!=sizeof(FIPS_signature) ||
+ memcmp(FIPS_signature,sig,sizeof(FIPS_signature)))
+ {
+ if (FIPS_signature>=FIPS_rodata_start && FIPS_signature<FIPS_rodata_end)
+ FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING);
+#if defined(__sgi) && (defined(__mips) || defined(mips))
+ else if (__dso_displacement!=NULL)
+#else
+ else if (OPENSSL_NONPIC_relocated)
+#endif
+ FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED);
+ else
+ FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH);
+ return 0;
+ }
+
+ return 1;
+ }
+
+int FIPS_mode_set(int onoff)
+ {
+ int fips_set_owning_thread();
+ int fips_clear_owning_thread();
+ int ret = 0;
+
+ fips_w_lock();
+ fips_set_started();
+ fips_set_owning_thread();
+
+ if(onoff)
+ {
+ unsigned char buf[48];
+
+ fips_selftest_fail = 0;
+
+ /* Don't go into FIPS mode twice, just so we can do automagic
+ seeding */
+ if(FIPS_mode())
+ {
+ FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_FIPS_MODE_ALREADY_SET);
+ fips_selftest_fail = 1;
+ ret = 0;
+ goto end;
+ }
+
+#ifdef OPENSSL_IA32_SSE2
+ if ((OPENSSL_ia32cap & (1<<25|1<<26)) != (1<<25|1<<26))
+ {
+ FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_UNSUPPORTED_PLATFORM);
+ fips_selftest_fail = 1;
+ ret = 0;
+ goto end;
+ }
+#endif
+
+ if(fips_signature_witness() != FIPS_signature)
+ {
+ FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_CONTRADICTING_EVIDENCE);
+ fips_selftest_fail = 1;
+ ret = 0;
+ goto end;
+ }
+
+ if(!FIPS_check_incore_fingerprint())
+ {
+ fips_selftest_fail = 1;
+ ret = 0;
+ goto end;
+ }
+
+ /* Perform RNG KAT before seeding */
+ if (!FIPS_selftest_rng())
+ {
+ fips_selftest_fail = 1;
+ ret = 0;
+ goto end;
+ }
+
+ /* automagically seed PRNG if not already seeded */
+ if(!FIPS_rand_status())
+ {
+ if(RAND_bytes(buf,sizeof buf) <= 0)
+ {
+ fips_selftest_fail = 1;
+ ret = 0;
+ goto end;
+ }
+ FIPS_rand_set_key(buf,32);
+ FIPS_rand_seed(buf+32,16);
+ }
+
+ /* now switch into FIPS mode */
+ fips_set_rand_check(FIPS_rand_method());
+ RAND_set_rand_method(FIPS_rand_method());
+ if(FIPS_selftest())
+ fips_set_mode(1);
+ else
+ {
+ fips_selftest_fail = 1;
+ ret = 0;
+ goto end;
+ }
+ ret = 1;
+ goto end;
+ }
+ fips_set_mode(0);
+ fips_selftest_fail = 0;
+ ret = 1;
+end:
+ fips_clear_owning_thread();
+ fips_w_unlock();
+ return ret;
+ }
+
+void fips_w_lock(void) { CRYPTO_w_lock(CRYPTO_LOCK_FIPS); }
+void fips_w_unlock(void) { CRYPTO_w_unlock(CRYPTO_LOCK_FIPS); }
+void fips_r_lock(void) { CRYPTO_r_lock(CRYPTO_LOCK_FIPS); }
+void fips_r_unlock(void) { CRYPTO_r_unlock(CRYPTO_LOCK_FIPS); }
+
+static int fips_started = 0;
+static unsigned long fips_thread = 0;
+
+void fips_set_started(void)
+ {
+ fips_started = 1;
+ }
+
+int fips_is_started(void)
+ {
+ return fips_started;
+ }
+
+int fips_is_owning_thread(void)
+ {
+ int ret = 0;
+
+ if (fips_is_started())
+ {
+ CRYPTO_r_lock(CRYPTO_LOCK_FIPS2);
+ if (fips_thread != 0 && fips_thread == CRYPTO_thread_id())
+ ret = 1;
+ CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2);
+ }
+ return ret;
+ }
+
+int fips_set_owning_thread(void)
+ {
+ int ret = 0;
+
+ if (fips_is_started())
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
+ if (fips_thread == 0)
+ {
+ fips_thread = CRYPTO_thread_id();
+ ret = 1;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
+ }
+ return ret;
+ }
+
+int fips_clear_owning_thread(void)
+ {
+ int ret = 0;
+
+ if (fips_is_started())
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
+ if (fips_thread == CRYPTO_thread_id())
+ {
+ fips_thread = 0;
+ ret = 1;
+ }
+ CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
+ }
+ return ret;
+ }
+
+unsigned char *fips_signature_witness(void)
+ {
+ extern unsigned char FIPS_signature[];
+ return FIPS_signature;
+ }
+
+/* Generalized public key test routine. Signs and verifies the data
+ * supplied in tbs using mesage digest md and setting option digest
+ * flags md_flags. If the 'kat' parameter is not NULL it will
+ * additionally check the signature matches it: a known answer test
+ * The string "fail_str" is used for identification purposes in case
+ * of failure.
+ */
+
+int fips_pkey_signature_test(EVP_PKEY *pkey,
+ const unsigned char *tbs, int tbslen,
+ const unsigned char *kat, unsigned int katlen,
+ const EVP_MD *digest, unsigned int md_flags,
+ const char *fail_str)
+ {
+ int ret = 0;
+ unsigned char sigtmp[256], *sig = sigtmp;
+ unsigned int siglen;
+ EVP_MD_CTX mctx;
+ EVP_MD_CTX_init(&mctx);
+
+ if ((pkey->type == EVP_PKEY_RSA)
+ && (RSA_size(pkey->pkey.rsa) > sizeof(sigtmp)))
+ {
+ sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa));
+ if (!sig)
+ {
+ FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+
+ if (tbslen == -1)
+ tbslen = strlen((char *)tbs);
+
+ if (md_flags)
+ M_EVP_MD_CTX_set_flags(&mctx, md_flags);
+
+ if (!EVP_SignInit_ex(&mctx, digest, NULL))
+ goto error;
+ if (!EVP_SignUpdate(&mctx, tbs, tbslen))
+ goto error;
+ if (!EVP_SignFinal(&mctx, sig, &siglen, pkey))
+ goto error;
+
+ if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen)))
+ goto error;
+
+ if (!EVP_VerifyInit_ex(&mctx, digest, NULL))
+ goto error;
+ if (!EVP_VerifyUpdate(&mctx, tbs, tbslen))
+ goto error;
+ ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey);
+
+ error:
+ if (sig != sigtmp)
+ OPENSSL_free(sig);
+ EVP_MD_CTX_cleanup(&mctx);
+ if (ret != 1)
+ {
+ FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE);
+ if (fail_str)
+ ERR_add_error_data(2, "Type=", fail_str);
+ return 0;
+ }
+ return 1;
+ }
+
+/* Generalized symmetric cipher test routine. Encrypt data, verify result
+ * against known answer, decrypt and compare with original plaintext.
+ */
+
+int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+ const unsigned char *key,
+ const unsigned char *iv,
+ const unsigned char *plaintext,
+ const unsigned char *ciphertext,
+ int len)
+ {
+ unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE];
+ unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE];
+ OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE);
+ if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0)
+ return 0;
+ EVP_Cipher(ctx, citmp, plaintext, len);
+ if (memcmp(citmp, ciphertext, len))
+ return 0;
+ if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0)
+ return 0;
+ EVP_Cipher(ctx, pltmp, citmp, len);
+ if (memcmp(pltmp, plaintext, len))
+ return 0;
+ return 1;
+ }
+
+#if 0
+/* The purpose of this is to ensure the error code exists and the function
+ * name is to keep the error checking script quiet
+ */
+void hash_final(void)
+ {
+ FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD);
+ }
+#endif
+
+
+#endif
diff --git a/crypto/openssl/fips/fips.h b/crypto/openssl/fips/fips.h
new file mode 100644
index 0000000..42bdcf2
--- /dev/null
+++ b/crypto/openssl/fips/fips.h
@@ -0,0 +1,163 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_FIPS
+#error FIPS is disabled.
+#endif
+
+#ifdef OPENSSL_FIPS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dsa_st;
+struct evp_pkey_st;
+struct env_md_st;
+struct evp_cipher_st;
+struct evp_cipher_ctx_st;
+
+int FIPS_mode_set(int onoff);
+int FIPS_mode(void);
+const void *FIPS_rand_check(void);
+int FIPS_selftest_failed(void);
+void FIPS_selftest_check(void);
+void FIPS_corrupt_sha1(void);
+int FIPS_selftest_sha1(void);
+void FIPS_corrupt_aes(void);
+int FIPS_selftest_aes(void);
+void FIPS_corrupt_des(void);
+int FIPS_selftest_des(void);
+void FIPS_corrupt_rsa(void);
+void FIPS_corrupt_rsa_keygen(void);
+int FIPS_selftest_rsa(void);
+void FIPS_corrupt_dsa(void);
+void FIPS_corrupt_dsa_keygen(void);
+int FIPS_selftest_dsa(void);
+void FIPS_corrupt_rng(void);
+void FIPS_rng_stick(void);
+int FIPS_selftest_rng(void);
+int FIPS_selftest_hmac(void);
+
+int fips_pkey_signature_test(struct evp_pkey_st *pkey,
+ const unsigned char *tbs, int tbslen,
+ const unsigned char *kat, unsigned int katlen,
+ const struct env_md_st *digest, unsigned int md_flags,
+ const char *fail_str);
+
+int fips_cipher_test(struct evp_cipher_ctx_st *ctx,
+ const struct evp_cipher_st *cipher,
+ const unsigned char *key,
+ const unsigned char *iv,
+ const unsigned char *plaintext,
+ const unsigned char *ciphertext,
+ int len);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_FIPS_strings(void);
+
+/* Error codes for the FIPS functions. */
+
+/* Function codes. */
+#define FIPS_F_DH_BUILTIN_GENPARAMS 100
+#define FIPS_F_DSA_BUILTIN_PARAMGEN 101
+#define FIPS_F_DSA_DO_SIGN 102
+#define FIPS_F_DSA_DO_VERIFY 103
+#define FIPS_F_EVP_CIPHERINIT_EX 124
+#define FIPS_F_EVP_DIGESTINIT_EX 125
+#define FIPS_F_FIPS_CHECK_DSA 104
+#define FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT 105
+#define FIPS_F_FIPS_CHECK_RSA 106
+#define FIPS_F_FIPS_DSA_CHECK 107
+#define FIPS_F_FIPS_MODE_SET 108
+#define FIPS_F_FIPS_PKEY_SIGNATURE_TEST 109
+#define FIPS_F_FIPS_SELFTEST_AES 110
+#define FIPS_F_FIPS_SELFTEST_DES 111
+#define FIPS_F_FIPS_SELFTEST_DSA 112
+#define FIPS_F_FIPS_SELFTEST_HMAC 113
+#define FIPS_F_FIPS_SELFTEST_RNG 114
+#define FIPS_F_FIPS_SELFTEST_SHA1 115
+#define FIPS_F_HASH_FINAL 123
+#define FIPS_F_RSA_BUILTIN_KEYGEN 116
+#define FIPS_F_RSA_EAY_PRIVATE_DECRYPT 117
+#define FIPS_F_RSA_EAY_PRIVATE_ENCRYPT 118
+#define FIPS_F_RSA_EAY_PUBLIC_DECRYPT 119
+#define FIPS_F_RSA_EAY_PUBLIC_ENCRYPT 120
+#define FIPS_F_RSA_X931_GENERATE_KEY_EX 121
+#define FIPS_F_SSLEAY_RAND_BYTES 122
+
+/* Reason codes. */
+#define FIPS_R_CANNOT_READ_EXE 103
+#define FIPS_R_CANNOT_READ_EXE_DIGEST 104
+#define FIPS_R_CONTRADICTING_EVIDENCE 114
+#define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH 105
+#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH 110
+#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED 111
+#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING 112
+#define FIPS_R_FIPS_MODE_ALREADY_SET 102
+#define FIPS_R_FIPS_SELFTEST_FAILED 106
+#define FIPS_R_INVALID_KEY_LENGTH 109
+#define FIPS_R_KEY_TOO_SHORT 108
+#define FIPS_R_NON_FIPS_METHOD 100
+#define FIPS_R_PAIRWISE_TEST_FAILED 107
+#define FIPS_R_RSA_DECRYPT_ERROR 115
+#define FIPS_R_RSA_ENCRYPT_ERROR 116
+#define FIPS_R_SELFTEST_FAILED 101
+#define FIPS_R_TEST_FAILURE 117
+#define FIPS_R_UNSUPPORTED_PLATFORM 113
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/crypto/openssl/fips/fips_canister.c b/crypto/openssl/fips/fips_canister.c
new file mode 100644
index 0000000..17446618
--- /dev/null
+++ b/crypto/openssl/fips/fips_canister.c
@@ -0,0 +1,187 @@
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
+ * and usage in source and binary forms are granted according to the
+ * OpenSSL license.
+ */
+
+#include <stdio.h>
+#if defined(__DECC)
+# include <c_asm.h>
+# pragma __nostandard
+#endif
+
+#include "e_os.h"
+
+#if !defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
+# if (defined(__sun) && (defined(__sparc) || defined(__sparcv9))) || \
+ (defined(__sgi) && (defined(__mips) || defined(mips))) || \
+ (defined(__osf__) && defined(__alpha)) || \
+ (defined(__linux) && (defined(__arm) || defined(__arm__))) || \
+ (defined(__i386) || defined(__i386__)) || \
+ (defined(__x86_64) || defined(__x86_64__)) || \
+ defined(__ANDROID__) || \
+ (defined(vax) || defined(__vax__))
+# define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION
+# endif
+#endif
+
+#if defined(__xlC__) && __xlC__>=0x600 && (defined(_POWER) || defined(_ARCH_PPC))
+static void *instruction_pointer_xlc(void);
+# pragma mc_func instruction_pointer_xlc {\
+ "7c0802a6" /* mflr r0 */ \
+ "48000005" /* bl $+4 */ \
+ "7c6802a6" /* mflr r3 */ \
+ "7c0803a6" /* mtlr r0 */ }
+# pragma reg_killed_by instruction_pointer_xlc gr0 gr3
+# define INSTRUCTION_POINTER_IMPLEMENTED(ret) (ret=instruction_pointer_xlc());
+#endif
+
+#ifdef FIPS_START
+#define FIPS_ref_point FIPS_text_start
+/* Some compilers put string literals into a separate segment. As we
+ * are mostly interested to hash AES tables in .rodata, we declare
+ * reference points accordingly. In case you wonder, the values are
+ * big-endian encoded variable names, just to prevent these arrays
+ * from being merged by linker. */
+const unsigned int FIPS_rodata_start[]=
+ { 0x46495053, 0x5f726f64, 0x6174615f, 0x73746172 };
+#else
+#define FIPS_ref_point FIPS_text_end
+const unsigned int FIPS_rodata_end[]=
+ { 0x46495053, 0x5f726f64, 0x6174615f, 0x656e645b };
+#endif
+
+/*
+ * I declare reference function as static in order to avoid certain
+ * pitfalls in -dynamic linker behaviour...
+ */
+static void *instruction_pointer(void)
+{ void *ret=NULL;
+/* These are ABI-neutral CPU-specific snippets. ABI-neutrality means
+ * that they are designed to work under any OS running on particular
+ * CPU, which is why you don't find any #ifdef THIS_OR_THAT_OS in
+ * this function. */
+#if defined(INSTRUCTION_POINTER_IMPLEMENTED)
+ INSTRUCTION_POINTER_IMPLEMENTED(ret);
+#elif defined(__GNUC__) && __GNUC__>=2
+# if defined(__alpha) || defined(__alpha__)
+# define INSTRUCTION_POINTER_IMPLEMENTED
+ __asm __volatile ( "br %0,1f\n1:" : "=r"(ret) );
+# elif defined(__i386) || defined(__i386__)
+# define INSTRUCTION_POINTER_IMPLEMENTED
+ __asm __volatile ( "call 1f\n1: popl %0" : "=r"(ret) );
+ ret = (void *)((size_t)ret&~3UL); /* align for better performance */
+# elif defined(__ia64) || defined(__ia64__)
+# define INSTRUCTION_POINTER_IMPLEMENTED
+ __asm __volatile ( "mov %0=ip" : "=r"(ret) );
+# elif defined(__hppa) || defined(__hppa__) || defined(__pa_risc)
+# define INSTRUCTION_POINTER_IMPLEMENTED
+ __asm __volatile ( "blr %%r0,%0\n\tnop" : "=r"(ret) );
+ ret = (void *)((size_t)ret&~3UL); /* mask privilege level */
+# elif defined(__mips) || defined(__mips__)
+# define INSTRUCTION_POINTER_IMPLEMENTED
+ void *scratch;
+ __asm __volatile ( "move %1,$31\n\t" /* save ra */
+ "bal .+8; nop\n\t"
+ "move %0,$31\n\t"
+ "move $31,%1" /* restore ra */
+ : "=r"(ret),"=r"(scratch) );
+# elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \
+ defined(__POWERPC__) || defined(_POWER) || defined(__PPC__) || \
+ defined(__PPC64__) || defined(__powerpc64__)
+# define INSTRUCTION_POINTER_IMPLEMENTED
+ void *scratch;
+ __asm __volatile ( "mfspr %1,8\n\t" /* save lr */
+ "bl $+4\n\t"
+ "mfspr %0,8\n\t" /* mflr ret */
+ "mtspr 8,%1" /* restore lr */
+ : "=r"(ret),"=r"(scratch) );
+# elif defined(__s390__) || defined(__s390x__)
+# define INSTRUCTION_POINTER_IMPLEMENTED
+ __asm __volatile ( "bras %0,1f\n1:" : "=r"(ret) );
+ ret = (void *)((size_t)ret&~3UL);
+# elif defined(__sparc) || defined(__sparc__) || defined(__sparcv9)
+# define INSTRUCTION_POINTER_IMPLEMENTED
+ void *scratch;
+ __asm __volatile ( "mov %%o7,%1\n\t"
+ "call .+8; nop\n\t"
+ "mov %%o7,%0\n\t"
+ "mov %1,%%o7"
+ : "=r"(ret),"=r"(scratch) );
+# elif defined(__x86_64) || defined(__x86_64__)
+# define INSTRUCTION_POINTER_IMPLEMENTED
+ __asm __volatile ( "leaq 0(%%rip),%0" : "=r"(ret) );
+ ret = (void *)((size_t)ret&~3UL); /* align for better performance */
+# endif
+#elif defined(__DECC) && defined(__alpha)
+# define INSTRUCTION_POINTER_IMPLEMENTED
+ ret = (void *)(size_t)asm("br %v0,1f\n1:");
+#elif defined(_MSC_VER) && defined(_M_IX86)
+# define INSTRUCTION_POINTER_IMPLEMENTED
+ void *scratch;
+ _asm {
+ call self
+ self: pop eax
+ mov scratch,eax
+ }
+ ret = (void *)((size_t)scratch&~3UL);
+#endif
+ return ret;
+}
+
+/*
+ * This function returns pointer to an instruction in the vicinity of
+ * its entry point, but not outside this object module. This guarantees
+ * that sequestered code is covered...
+ */
+void *FIPS_ref_point()
+{
+#if defined(INSTRUCTION_POINTER_IMPLEMENTED)
+ return instruction_pointer();
+/* Below we essentially cover vendor compilers which do not support
+ * inline assembler... */
+#elif defined(_AIX)
+ struct { void *ip,*gp,*env; } *p = (void *)instruction_pointer;
+ return p->ip;
+#elif defined(_HPUX_SOURCE)
+# if defined(__hppa) || defined(__hppa__)
+ struct { void *i[4]; } *p = (void *)FIPS_ref_point;
+
+ if (sizeof(p) == 8) /* 64-bit */
+ return p->i[2];
+ else if ((size_t)p & 2)
+ { p = (void *)((size_t)p&~3UL);
+ return p->i[0];
+ }
+ else
+ return (void *)p;
+# elif defined(__ia64) || defined(__ia64__)
+ struct { unsigned long long ip,gp; } *p=(void *)instruction_pointer;
+ return (void *)(size_t)p->ip;
+# endif
+#elif (defined(__VMS) || defined(VMS)) && !(defined(vax) || defined(__vax__))
+ /* applies to both alpha and ia64 */
+ struct { unsigned __int64 opaque,ip; } *p=(void *)instruction_pointer;
+ return (void *)(size_t)p->ip;
+#elif defined(__VOS__)
+ /* applies to both pa-risc and ia32 */
+ struct { void *dp,*ip,*gp; } *p = (void *)instruction_pointer;
+ return p->ip;
+#elif defined(_WIN32)
+# if defined(_WIN64) && defined(_M_IA64)
+ struct { void *ip,*gp; } *p = (void *)FIPS_ref_point;
+ return p->ip;
+# else
+ return (void *)FIPS_ref_point;
+# endif
+/*
+ * In case you wonder why there is no #ifdef __linux. All Linux targets
+ * are GCC-based and therefore are covered by instruction_pointer above
+ * [well, some are covered by by the one below]...
+ */
+#elif defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
+ return (void *)instruction_pointer;
+#else
+ return NULL;
+#endif
+}
diff --git a/crypto/openssl/fips/fips_locl.h b/crypto/openssl/fips/fips_locl.h
new file mode 100644
index 0000000..b3ea289
--- /dev/null
+++ b/crypto/openssl/fips/fips_locl.h
@@ -0,0 +1,74 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef OPENSSL_FIPS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void fips_w_lock(void);
+void fips_w_unlock(void);
+void fips_r_lock(void);
+void fips_r_unlock(void);
+int fips_is_started(void);
+void fips_set_started(void);
+int fips_is_owning_thread(void);
+int fips_set_owning_thread(void);
+void fips_set_selftest_fail(void);
+int fips_clear_owning_thread(void);
+unsigned char *fips_signature_witness(void);
+int fips_check_rsa(RSA *rsa);
+
+#define FIPS_MAX_CIPHER_TEST_SIZE 16
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/crypto/openssl/fips/fips_premain.c b/crypto/openssl/fips/fips_premain.c
new file mode 100644
index 0000000..165d2c5
--- /dev/null
+++ b/crypto/openssl/fips/fips_premain.c
@@ -0,0 +1,176 @@
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
+ * and usage in source and binary forms are granted according to the
+ * OpenSSL license.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(__unix) || defined(__unix__)
+#include <unistd.h>
+#endif
+
+#ifndef FINGERPRINT_PREMAIN_DSO_LOAD
+
+#if defined(__GNUC__) && __GNUC__>=2
+ void FINGERPRINT_premain(void) __attribute__((constructor));
+ /* Most commonly this results in pointer to premain to be dropped
+ * to .ctors segment, which is traversed by GCC crtbegin.o upon
+ * program startup. Except on a.out OpenBSD where it results in
+ * _GLOBAL_$I$premain() {premain();} being auto-generated by
+ * compiler... But one way or another this is believed to cover
+ * *all* GCC targets. */
+#elif defined(_MSC_VER)
+# ifdef _WINDLL
+ __declspec(dllexport) /* this is essentially cosmetics... */
+# endif
+ void FINGERPRINT_premain(void);
+ static int premain_wrapper(void) { FINGERPRINT_premain(); return 0; }
+# ifdef _WIN64
+# pragma section(".CRT$XCU",read)
+ __declspec(allocate(".CRT$XCU"))
+# else
+# pragma data_seg(".CRT$XCU")
+# endif
+ static int (*p)(void) = premain_wrapper;
+ /* This results in pointer to premain to appear in .CRT segment,
+ * which is traversed by Visual C run-time initialization code.
+ * This applies to both Win32 and [all flavors of] Win64. */
+# pragma data_seg()
+#elif defined(__SUNPRO_C)
+ void FINGERPRINT_premain(void);
+# pragma init(FINGERPRINT_premain)
+ /* This results in a call to premain to appear in .init segment. */
+#elif defined(__DECC) && (defined(__VMS) || defined(VMS))
+ void FINGERPRINT_premain(void);
+# pragma __nostandard
+ globaldef { "LIB$INITIALIZ" } readonly _align (LONGWORD)
+ int spare[8] = {0};
+ globaldef { "LIB$INITIALIZE" } readonly _align (LONGWORD)
+ void (*x_FINGERPRINT_premain)(void) = FINGERPRINT_premain;
+ /* Refer to LIB$INITIALIZE to ensure it exists in the image. */
+ int lib$initialize();
+ globaldef int (*lib_init_ref)() = lib$initialize;
+# pragma __standard
+#elif 0
+ The rest has to be taken care of through command line:
+
+ -Wl,-init,FINGERPRINT_premain on OSF1 and IRIX
+ -Wl,+init,FINGERPRINT_premain on HP-UX
+ -Wl,-binitfini:FINGERPRINT_premain on AIX
+
+ On ELF platforms this results in a call to premain to appear in
+ .init segment...
+#endif
+
+#ifndef HMAC_SHA1_SIG
+#define HMAC_SHA1_SIG "?have to make sure this string is unique"
+#endif
+
+static const unsigned char FINGERPRINT_ascii_value[40] = HMAC_SHA1_SIG;
+
+#define atox(c) ((c)>='a'?((c)-'a'+10):((c)>='A'?(c)-'A'+10:(c)-'0'))
+
+extern const void *FIPS_text_start(), *FIPS_text_end();
+extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[];
+extern unsigned char FIPS_signature[20];
+extern unsigned int FIPS_incore_fingerprint(unsigned char *,unsigned int);
+
+/*
+ * As name suggests this code is executed prior main(). We use this
+ * opportunity to fingerprint sequestered code in virtual address
+ * space of target application.
+ */
+void FINGERPRINT_premain(void)
+{ unsigned char sig[sizeof(FIPS_signature)];
+ const unsigned char * volatile p=FINGERPRINT_ascii_value;
+ unsigned int len=sizeof(sig),i;
+
+ /* "volatilization" is done to disengage unwanted optimization... */
+ if (*((volatile unsigned char *)p)=='?')
+ { if (FIPS_text_start()==NULL)
+ { fprintf(stderr,"FIPS_text_start() returns NULL\n");
+ _exit(1);
+ }
+#if defined(DEBUG_FINGERPRINT_PREMAIN)
+ fprintf(stderr,".text:%p+%d=%p\n",FIPS_text_start(),
+ (int)((size_t)FIPS_text_end()-(size_t)FIPS_text_start()),
+ FIPS_text_end());
+ fprintf(stderr,".rodata:%p+%d=%p\n",FIPS_rodata_start,
+ (int)((size_t)FIPS_rodata_end-(size_t)FIPS_rodata_start),
+ FIPS_rodata_end);
+#endif
+
+ len=FIPS_incore_fingerprint(sig,sizeof(sig));
+
+ if (len!=sizeof(sig))
+ { fprintf(stderr,"fingerprint length mismatch: %u\n",len);
+ _exit(1);
+ }
+
+ for (i=0;i<len;i++) printf("%02x",sig[i]);
+ printf("\n");
+ fflush(stdout);
+ _exit(0);
+ }
+ else if (FIPS_signature[0]=='\0') do
+ { for (i=0;i<sizeof(FIPS_signature);i++,p+=2)
+ FIPS_signature[i] = (atox(p[0])<<4)|atox(p[1]);
+
+#if defined(DEBUG_FINGERPRINT_PREMAIN)
+ if (getenv("OPENSSL_FIPS")==NULL) break;
+
+ len=FIPS_incore_fingerprint(sig,sizeof(sig));
+
+ if (memcmp(FIPS_signature,sig,sizeof(FIPS_signature)))
+ { fprintf(stderr,"FINGERPRINT_premain: FIPS_signature mismatch\n");
+ _exit(1);
+ }
+#endif
+ } while(0);
+}
+
+#else
+
+#include <openssl/bio.h>
+#include <openssl/dso.h>
+#include <openssl/err.h>
+
+int main(int argc,char *argv[])
+{ DSO *dso;
+ DSO_FUNC_TYPE func;
+ BIO *bio_err;
+
+ if (argc < 2)
+ { fprintf (stderr,"usage: %s libcrypto.dso\n",argv[0]);
+ return 1;
+ }
+
+ if ((bio_err=BIO_new(BIO_s_file())) == NULL)
+ { fprintf (stderr,"unable to allocate BIO\n");
+ return 1;
+ }
+ BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+ ERR_load_crypto_strings();
+
+ dso = DSO_load(NULL,argv[1],NULL,DSO_FLAG_NO_NAME_TRANSLATION);
+ if (dso == NULL)
+ { ERR_print_errors(bio_err);
+ return 1;
+ }
+
+ /* This is not normally reached, because FINGERPRINT_premain should
+ * have executed and terminated application already upon DSO_load... */
+ func = DSO_bind_func(dso,"FINGERPRINT_premain");
+ if (func == NULL)
+ { ERR_print_errors(bio_err);
+ return 1;
+ }
+
+ (*func)();
+
+ return 0;
+}
+
+#endif
diff --git a/crypto/openssl/fips/fips_premain.c.sha1 b/crypto/openssl/fips/fips_premain.c.sha1
new file mode 100644
index 0000000..c16f964
--- /dev/null
+++ b/crypto/openssl/fips/fips_premain.c.sha1
@@ -0,0 +1 @@
+HMAC-SHA1(fips_premain.c)= 9e5ddba185ac446e0cf36fcf8e1b3acffe5d0b2c
diff --git a/crypto/openssl/fips/fips_test_suite.c b/crypto/openssl/fips/fips_test_suite.c
new file mode 100644
index 0000000..2bc0ba9
--- /dev/null
+++ b/crypto/openssl/fips/fips_test_suite.c
@@ -0,0 +1,579 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
+ *
+ *
+ * This command is intended as a test driver for the FIPS-140 testing
+ * lab performing FIPS-140 validation. It demonstrates the use of the
+ * OpenSSL library ito perform a variety of common cryptographic
+ * functions. A power-up self test is demonstrated by deliberately
+ * pointing to an invalid executable hash
+ *
+ * Contributed by Steve Marquess.
+ *
+ */
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/aes.h>
+#include <openssl/des.h>
+#include <openssl/hmac.h>
+#include <openssl/err.h>
+
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+
+#ifndef OPENSSL_FIPS
+int main(int argc, char *argv[])
+ {
+ printf("No FIPS support\n");
+ return(0);
+ }
+#else
+
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+
+#include <openssl/fips.h>
+#include "fips_utl.h"
+
+/* AES: encrypt and decrypt known plaintext, verify result matches original plaintext
+*/
+static int FIPS_aes_test(void)
+ {
+ int ret = 0;
+ unsigned char pltmp[16];
+ unsigned char citmp[16];
+ unsigned char key[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
+ unsigned char plaintext[16] = "etaonrishdlcu";
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+ if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 1) <= 0)
+ goto err;
+ EVP_Cipher(&ctx, citmp, plaintext, 16);
+ if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 0) <= 0)
+ goto err;
+ EVP_Cipher(&ctx, pltmp, citmp, 16);
+ if (memcmp(pltmp, plaintext, 16))
+ goto err;
+ ret = 1;
+ err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return ret;
+ }
+
+static int FIPS_des3_test(void)
+ {
+ int ret = 0;
+ unsigned char pltmp[8];
+ unsigned char citmp[8];
+ unsigned char key[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
+ 19,20,21,22,23,24};
+ unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' };
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+ if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 1) <= 0)
+ goto err;
+ EVP_Cipher(&ctx, citmp, plaintext, 8);
+ if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 0) <= 0)
+ goto err;
+ EVP_Cipher(&ctx, pltmp, citmp, 8);
+ if (memcmp(pltmp, plaintext, 8))
+ goto err;
+ ret = 1;
+ err:
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return ret;
+ }
+
+/*
+ * DSA: generate keys and sign, verify input plaintext.
+ */
+static int FIPS_dsa_test(int bad)
+ {
+ DSA *dsa = NULL;
+ EVP_PKEY pk;
+ unsigned char dgst[] = "etaonrishdlc";
+ unsigned char buf[60];
+ unsigned int slen;
+ int r = 0;
+ EVP_MD_CTX mctx;
+
+ ERR_clear_error();
+ EVP_MD_CTX_init(&mctx);
+ dsa = FIPS_dsa_new();
+ if (!dsa)
+ goto end;
+ if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL))
+ goto end;
+ if (!DSA_generate_key(dsa))
+ goto end;
+ if (bad)
+ BN_add_word(dsa->pub_key, 1);
+
+ pk.type = EVP_PKEY_DSA;
+ pk.pkey.dsa = dsa;
+
+ if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
+ goto end;
+ if (!EVP_SignUpdate(&mctx, dgst, sizeof(dgst) - 1))
+ goto end;
+ if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
+ goto end;
+
+ if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
+ goto end;
+ if (!EVP_VerifyUpdate(&mctx, dgst, sizeof(dgst) - 1))
+ goto end;
+ r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
+ end:
+ EVP_MD_CTX_cleanup(&mctx);
+ if (dsa)
+ FIPS_dsa_free(dsa);
+ if (r != 1)
+ return 0;
+ return 1;
+ }
+
+/*
+ * RSA: generate keys and sign, verify input plaintext.
+ */
+static int FIPS_rsa_test(int bad)
+ {
+ RSA *key;
+ unsigned char input_ptext[] = "etaonrishdlc";
+ unsigned char buf[256];
+ unsigned int slen;
+ BIGNUM *bn;
+ EVP_MD_CTX mctx;
+ EVP_PKEY pk;
+ int r = 0;
+
+ ERR_clear_error();
+ EVP_MD_CTX_init(&mctx);
+ key = FIPS_rsa_new();
+ bn = BN_new();
+ if (!key || !bn)
+ return 0;
+ BN_set_word(bn, 65537);
+ if (!RSA_generate_key_ex(key, 1024,bn,NULL))
+ return 0;
+ BN_free(bn);
+ if (bad)
+ BN_add_word(key->n, 1);
+
+ pk.type = EVP_PKEY_RSA;
+ pk.pkey.rsa = key;
+
+ if (!EVP_SignInit_ex(&mctx, EVP_sha1(), NULL))
+ goto end;
+ if (!EVP_SignUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
+ goto end;
+ if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
+ goto end;
+
+ if (!EVP_VerifyInit_ex(&mctx, EVP_sha1(), NULL))
+ goto end;
+ if (!EVP_VerifyUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
+ goto end;
+ r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
+ end:
+ EVP_MD_CTX_cleanup(&mctx);
+ if (key)
+ FIPS_rsa_free(key);
+ if (r != 1)
+ return 0;
+ return 1;
+ }
+
+/* SHA1: generate hash of known digest value and compare to known
+ precomputed correct hash
+*/
+static int FIPS_sha1_test()
+ {
+ unsigned char digest[SHA_DIGEST_LENGTH] =
+ { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, 0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 };
+ unsigned char str[] = "etaonrishd";
+
+ unsigned char md[SHA_DIGEST_LENGTH];
+
+ ERR_clear_error();
+ if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha1(), NULL)) return 0;
+ if (memcmp(md,digest,sizeof(md)))
+ return 0;
+ return 1;
+ }
+
+/* SHA256: generate hash of known digest value and compare to known
+ precomputed correct hash
+*/
+static int FIPS_sha256_test()
+ {
+ unsigned char digest[SHA256_DIGEST_LENGTH] =
+ {0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9, 0x68, 0xc0, 0xea, 0x40, 0x91,
+ 0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6, 0x50, 0x4f, 0x47, 0x57};
+ unsigned char str[] = "etaonrishd";
+
+ unsigned char md[SHA256_DIGEST_LENGTH];
+
+ ERR_clear_error();
+ if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha256(), NULL)) return 0;
+ if (memcmp(md,digest,sizeof(md)))
+ return 0;
+ return 1;
+ }
+
+/* SHA512: generate hash of known digest value and compare to known
+ precomputed correct hash
+*/
+static int FIPS_sha512_test()
+ {
+ unsigned char digest[SHA512_DIGEST_LENGTH] =
+ {0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f, 0x94, 0x71, 0x64, 0x28, 0xca,
+ 0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2, 0xd0, 0xe7, 0x0b, 0x94, 0x4a,
+ 0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f, 0x24, 0xb1, 0xd9, 0x40, 0x22,
+ 0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6, 0xeb, 0x2d, 0x42, 0x1d, 0xa3};
+ unsigned char str[] = "etaonrishd";
+
+ unsigned char md[SHA512_DIGEST_LENGTH];
+
+ ERR_clear_error();
+ if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha512(), NULL)) return 0;
+ if (memcmp(md,digest,sizeof(md)))
+ return 0;
+ return 1;
+ }
+
+/* HMAC-SHA1: generate hash of known digest value and compare to known
+ precomputed correct hash
+*/
+static int FIPS_hmac_sha1_test()
+ {
+ unsigned char key[] = "etaonrishd";
+ unsigned char iv[] = "Sample text";
+ unsigned char kaval[EVP_MAX_MD_SIZE] =
+ {0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea, 0x56, 0x1b, 0x61, 0x2e, 0x70,
+ 0xb2, 0xfb, 0xec, 0xc6};
+
+ unsigned char out[EVP_MAX_MD_SIZE];
+ unsigned int outlen;
+
+ ERR_clear_error();
+ if (!HMAC(EVP_sha1(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
+ if (memcmp(out,kaval,outlen))
+ return 0;
+ return 1;
+ }
+
+/* HMAC-SHA224: generate hash of known digest value and compare to known
+ precomputed correct hash
+*/
+static int FIPS_hmac_sha224_test()
+ {
+ unsigned char key[] = "etaonrishd";
+ unsigned char iv[] = "Sample text";
+ unsigned char kaval[EVP_MAX_MD_SIZE] =
+ {0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe, 0x1c, 0xb2, 0xf0, 0x20, 0x35,
+ 0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19};
+
+ unsigned char out[EVP_MAX_MD_SIZE];
+ unsigned int outlen;
+
+ ERR_clear_error();
+ if (!HMAC(EVP_sha224(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
+ if (memcmp(out,kaval,outlen))
+ return 0;
+ return 1;
+ }
+
+/* HMAC-SHA256: generate hash of known digest value and compare to known
+ precomputed correct hash
+*/
+static int FIPS_hmac_sha256_test()
+ {
+ unsigned char key[] = "etaonrishd";
+ unsigned char iv[] = "Sample text";
+ unsigned char kaval[EVP_MAX_MD_SIZE] =
+ {0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36, 0x02, 0xf5, 0x72, 0x33, 0x87,
+ 0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee, 0x51, 0xff, 0xda, 0x24, 0xf4};
+
+ unsigned char out[EVP_MAX_MD_SIZE];
+ unsigned int outlen;
+
+ ERR_clear_error();
+ if (!HMAC(EVP_sha256(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
+ if (memcmp(out,kaval,outlen))
+ return 0;
+ return 1;
+ }
+
+/* HMAC-SHA384: generate hash of known digest value and compare to known
+ precomputed correct hash
+*/
+static int FIPS_hmac_sha384_test()
+ {
+ unsigned char key[] = "etaonrishd";
+ unsigned char iv[] = "Sample text";
+ unsigned char kaval[EVP_MAX_MD_SIZE] =
+ {0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08, 0x26, 0x99, 0xef, 0x3b, 0x10,
+ 0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b, 0xac, 0xb0, 0x07, 0x39, 0x08,
+ 0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3, 0xf3, 0xb8, 0x9b, 0x88, 0x1c};
+
+ unsigned char out[EVP_MAX_MD_SIZE];
+ unsigned int outlen;
+
+ ERR_clear_error();
+ if (!HMAC(EVP_sha384(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
+ if (memcmp(out,kaval,outlen))
+ return 0;
+ return 1;
+ }
+
+/* HMAC-SHA512: generate hash of known digest value and compare to known
+ precomputed correct hash
+*/
+static int FIPS_hmac_sha512_test()
+ {
+ unsigned char key[] = "etaonrishd";
+ unsigned char iv[] = "Sample text";
+ unsigned char kaval[EVP_MAX_MD_SIZE] =
+ {0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3, 0x77, 0x59, 0x85, 0xa9, 0xe6,
+ 0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1, 0xad, 0x7e, 0x24, 0xca, 0xb1,
+ 0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52, 0x6b, 0x61, 0x7f, 0xeb, 0x9c,
+ 0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96, 0x3d, 0xa6, 0xd9, 0x2a, 0x53};
+
+ unsigned char out[EVP_MAX_MD_SIZE];
+ unsigned int outlen;
+
+ ERR_clear_error();
+ if (!HMAC(EVP_sha512(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
+ if (memcmp(out,kaval,outlen))
+ return 0;
+ return 1;
+ }
+
+
+/* DH: generate shared parameters
+*/
+static int dh_test()
+ {
+ DH *dh;
+ ERR_clear_error();
+ dh = FIPS_dh_new();
+ if (!dh)
+ return 0;
+ if (!DH_generate_parameters_ex(dh, 1024, 2, NULL))
+ return 0;
+ FIPS_dh_free(dh);
+ return 1;
+ }
+
+/* Zeroize
+*/
+static int Zeroize()
+ {
+ RSA *key;
+ BIGNUM *bn;
+ unsigned char userkey[16] =
+ { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 };
+ size_t i;
+ int n;
+
+ key = FIPS_rsa_new();
+ bn = BN_new();
+ if (!key || !bn)
+ return 0;
+ BN_set_word(bn, 65537);
+ if (!RSA_generate_key_ex(key, 1024,bn,NULL))
+ return 0;
+ BN_free(bn);
+
+ n = BN_num_bytes(key->d);
+ printf(" Generated %d byte RSA private key\n", n);
+ printf("\tBN key before overwriting:\n");
+ do_bn_print(stdout, key->d);
+ BN_rand(key->d,n*8,-1,0);
+ printf("\tBN key after overwriting:\n");
+ do_bn_print(stdout, key->d);
+
+ printf("\tchar buffer key before overwriting: \n\t\t");
+ for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
+ printf("\n");
+ RAND_bytes(userkey, sizeof userkey);
+ printf("\tchar buffer key after overwriting: \n\t\t");
+ for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
+ printf("\n");
+
+ return 1;
+ }
+
+static int Error;
+static const char * Fail(const char *msg)
+ {
+ do_print_errors();
+ Error++;
+ return msg;
+ }
+
+static void test_msg(const char *msg, int result)
+ {
+ printf("%s...%s\n", msg, result ? "successful" : Fail("Failed!"));
+ }
+
+int main(int argc,char **argv)
+ {
+
+ int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0;
+ int bad_rsa = 0, bad_dsa = 0;
+ int do_rng_stick = 0;
+ int no_exit = 0;
+
+ printf("\tFIPS-mode test application\n\n");
+
+ /* Load entropy from external file, if any */
+ RAND_load_file(".rnd", 1024);
+
+ if (argv[1]) {
+ /* Corrupted KAT tests */
+ if (!strcmp(argv[1], "aes")) {
+ FIPS_corrupt_aes();
+ printf("AES encryption/decryption with corrupted KAT...\n");
+ } else if (!strcmp(argv[1], "des")) {
+ FIPS_corrupt_des();
+ printf("DES3-ECB encryption/decryption with corrupted KAT...\n");
+ } else if (!strcmp(argv[1], "dsa")) {
+ FIPS_corrupt_dsa();
+ printf("DSA key generation and signature validation with corrupted KAT...\n");
+ } else if (!strcmp(argv[1], "rsa")) {
+ FIPS_corrupt_rsa();
+ printf("RSA key generation and signature validation with corrupted KAT...\n");
+ } else if (!strcmp(argv[1], "rsakey")) {
+ printf("RSA key generation and signature validation with corrupted key...\n");
+ bad_rsa = 1;
+ no_exit = 1;
+ } else if (!strcmp(argv[1], "rsakeygen")) {
+ do_corrupt_rsa_keygen = 1;
+ no_exit = 1;
+ printf("RSA key generation and signature validation with corrupted keygen...\n");
+ } else if (!strcmp(argv[1], "dsakey")) {
+ printf("DSA key generation and signature validation with corrupted key...\n");
+ bad_dsa = 1;
+ no_exit = 1;
+ } else if (!strcmp(argv[1], "dsakeygen")) {
+ do_corrupt_dsa_keygen = 1;
+ no_exit = 1;
+ printf("DSA key generation and signature validation with corrupted keygen...\n");
+ } else if (!strcmp(argv[1], "sha1")) {
+ FIPS_corrupt_sha1();
+ printf("SHA-1 hash with corrupted KAT...\n");
+ } else if (!strcmp(argv[1], "rng")) {
+ FIPS_corrupt_rng();
+ } else if (!strcmp(argv[1], "rngstick")) {
+ do_rng_stick = 1;
+ no_exit = 1;
+ printf("RNG test with stuck continuous test...\n");
+ } else {
+ printf("Bad argument \"%s\"\n", argv[1]);
+ exit(1);
+ }
+ if (!no_exit) {
+ if (!FIPS_mode_set(1)) {
+ do_print_errors();
+ printf("Power-up self test failed\n");
+ exit(1);
+ }
+ printf("Power-up self test successful\n");
+ exit(0);
+ }
+ }
+
+ /* Non-Approved cryptographic operation
+ */
+ printf("1. Non-Approved cryptographic operation test...\n");
+ test_msg("\ta. Included algorithm (D-H)...", dh_test());
+
+ /* Power-up self test
+ */
+ ERR_clear_error();
+ test_msg("2. Automatic power-up self test", FIPS_mode_set(1));
+ if (!FIPS_mode())
+ exit(1);
+ if (do_corrupt_dsa_keygen)
+ FIPS_corrupt_dsa_keygen();
+ if (do_corrupt_rsa_keygen)
+ FIPS_corrupt_rsa_keygen();
+ if (do_rng_stick)
+ FIPS_rng_stick();
+
+ /* AES encryption/decryption
+ */
+ test_msg("3. AES encryption/decryption", FIPS_aes_test());
+
+ /* RSA key generation and encryption/decryption
+ */
+ test_msg("4. RSA key generation and encryption/decryption",
+ FIPS_rsa_test(bad_rsa));
+
+ /* DES-CBC encryption/decryption
+ */
+ test_msg("5. DES-ECB encryption/decryption", FIPS_des3_test());
+
+ /* DSA key generation and signature validation
+ */
+ test_msg("6. DSA key generation and signature validation",
+ FIPS_dsa_test(bad_dsa));
+
+ /* SHA-1 hash
+ */
+ test_msg("7a. SHA-1 hash", FIPS_sha1_test());
+
+ /* SHA-256 hash
+ */
+ test_msg("7b. SHA-256 hash", FIPS_sha256_test());
+
+ /* SHA-512 hash
+ */
+ test_msg("7c. SHA-512 hash", FIPS_sha512_test());
+
+ /* HMAC-SHA-1 hash
+ */
+ test_msg("7d. HMAC-SHA-1 hash", FIPS_hmac_sha1_test());
+
+ /* HMAC-SHA-224 hash
+ */
+ test_msg("7e. HMAC-SHA-224 hash", FIPS_hmac_sha224_test());
+
+ /* HMAC-SHA-256 hash
+ */
+ test_msg("7f. HMAC-SHA-256 hash", FIPS_hmac_sha256_test());
+
+ /* HMAC-SHA-384 hash
+ */
+ test_msg("7g. HMAC-SHA-384 hash", FIPS_hmac_sha384_test());
+
+ /* HMAC-SHA-512 hash
+ */
+ test_msg("7h. HMAC-SHA-512 hash", FIPS_hmac_sha512_test());
+
+ /* Non-Approved cryptographic operation
+ */
+ printf("8. Non-Approved cryptographic operation test...\n");
+ printf("\ta. Included algorithm (D-H)...%s\n",
+ dh_test() ? "successful as expected"
+ : Fail("failed INCORRECTLY!") );
+
+ /* Zeroization
+ */
+ printf("9. Zero-ization...\n\t%s\n",
+ Zeroize() ? "successful as expected"
+ : Fail("failed INCORRECTLY!") );
+
+ printf("\nAll tests completed with %d errors\n", Error);
+ return Error ? 1 : 0;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/fips_utl.h b/crypto/openssl/fips/fips_utl.h
new file mode 100644
index 0000000..85d9e12
--- /dev/null
+++ b/crypto/openssl/fips/fips_utl.h
@@ -0,0 +1,359 @@
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+void do_print_errors(void);
+int hex2bin(const char *in, unsigned char *out);
+unsigned char *hex2bin_m(const char *in, long *plen);
+int do_hex2bn(BIGNUM **pr, const char *in);
+int do_bn_print(FILE *out, BIGNUM *bn);
+int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn);
+int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf);
+BIGNUM *hex2bn(const char *in);
+int bin2hex(const unsigned char *in,int len,char *out);
+void pv(const char *tag,const unsigned char *val,int len);
+int tidy_line(char *linebuf, char *olinebuf);
+int bint2bin(const char *in, int len, unsigned char *out);
+int bin2bint(const unsigned char *in,int len,char *out);
+void PrintValue(char *tag, unsigned char *val, int len);
+void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode);
+
+void do_print_errors(void)
+ {
+ const char *file, *data;
+ int line, flags;
+ unsigned long l;
+ while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)))
+ {
+ fprintf(stderr, "ERROR:%lx:lib=%d,func=%d,reason=%d"
+ ":file=%s:line=%d:%s\n",
+ l, ERR_GET_LIB(l), ERR_GET_FUNC(l), ERR_GET_REASON(l),
+ file, line, flags & ERR_TXT_STRING ? data : "");
+ }
+ }
+
+int hex2bin(const char *in, unsigned char *out)
+ {
+ int n1, n2;
+ unsigned char ch;
+
+ for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; )
+ { /* first byte */
+ if ((in[n1] >= '0') && (in[n1] <= '9'))
+ ch = in[n1++] - '0';
+ else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
+ ch = in[n1++] - 'A' + 10;
+ else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
+ ch = in[n1++] - 'a' + 10;
+ else
+ return -1;
+ if(!in[n1])
+ {
+ out[n2++]=ch;
+ break;
+ }
+ out[n2] = ch << 4;
+ /* second byte */
+ if ((in[n1] >= '0') && (in[n1] <= '9'))
+ ch = in[n1++] - '0';
+ else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
+ ch = in[n1++] - 'A' + 10;
+ else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
+ ch = in[n1++] - 'a' + 10;
+ else
+ return -1;
+ out[n2++] |= ch;
+ }
+ return n2;
+ }
+
+unsigned char *hex2bin_m(const char *in, long *plen)
+ {
+ unsigned char *p;
+ p = OPENSSL_malloc((strlen(in) + 1)/2);
+ *plen = hex2bin(in, p);
+ return p;
+ }
+
+int do_hex2bn(BIGNUM **pr, const char *in)
+ {
+ unsigned char *p;
+ long plen;
+ int r = 0;
+ p = hex2bin_m(in, &plen);
+ if (!p)
+ return 0;
+ if (!*pr)
+ *pr = BN_new();
+ if (!*pr)
+ return 0;
+ if (BN_bin2bn(p, plen, *pr))
+ r = 1;
+ OPENSSL_free(p);
+ return r;
+ }
+
+int do_bn_print(FILE *out, BIGNUM *bn)
+ {
+ int len, i;
+ unsigned char *tmp;
+ len = BN_num_bytes(bn);
+ if (len == 0)
+ {
+ fputs("00", out);
+ return 1;
+ }
+
+ tmp = OPENSSL_malloc(len);
+ if (!tmp)
+ {
+ fprintf(stderr, "Memory allocation error\n");
+ return 0;
+ }
+ BN_bn2bin(bn, tmp);
+ for (i = 0; i < len; i++)
+ fprintf(out, "%02x", tmp[i]);
+ OPENSSL_free(tmp);
+ return 1;
+ }
+
+int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn)
+ {
+ int r;
+ fprintf(out, "%s = ", name);
+ r = do_bn_print(out, bn);
+ if (!r)
+ return 0;
+ fputs("\n", out);
+ return 1;
+ }
+
+int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf)
+ {
+ char *keyword, *value, *p, *q;
+ strcpy(linebuf, olinebuf);
+ keyword = linebuf;
+ /* Skip leading space */
+ while (isspace((unsigned char)*keyword))
+ keyword++;
+
+ /* Look for = sign */
+ p = strchr(linebuf, '=');
+
+ /* If no '=' exit */
+ if (!p)
+ return 0;
+
+ q = p - 1;
+
+ /* Remove trailing space */
+ while (isspace((unsigned char)*q))
+ *q-- = 0;
+
+ *p = 0;
+ value = p + 1;
+
+ /* Remove leading space from value */
+ while (isspace((unsigned char)*value))
+ value++;
+
+ /* Remove trailing space from value */
+ p = value + strlen(value) - 1;
+
+ while (*p == '\n' || isspace((unsigned char)*p))
+ *p-- = 0;
+
+ *pkw = keyword;
+ *pval = value;
+ return 1;
+ }
+
+BIGNUM *hex2bn(const char *in)
+ {
+ BIGNUM *p=NULL;
+
+ if (!do_hex2bn(&p, in))
+ return NULL;
+
+ return p;
+ }
+
+int bin2hex(const unsigned char *in,int len,char *out)
+ {
+ int n1, n2;
+ unsigned char ch;
+
+ for (n1=0,n2=0 ; n1 < len ; ++n1)
+ {
+ ch=in[n1] >> 4;
+ if (ch <= 0x09)
+ out[n2++]=ch+'0';
+ else
+ out[n2++]=ch-10+'a';
+ ch=in[n1] & 0x0f;
+ if(ch <= 0x09)
+ out[n2++]=ch+'0';
+ else
+ out[n2++]=ch-10+'a';
+ }
+ out[n2]='\0';
+ return n2;
+ }
+
+void pv(const char *tag,const unsigned char *val,int len)
+ {
+ char obuf[2048];
+
+ bin2hex(val,len,obuf);
+ printf("%s = %s\n",tag,obuf);
+ }
+
+/* To avoid extensive changes to test program at this stage just convert
+ * the input line into an acceptable form. Keyword lines converted to form
+ * "keyword = value\n" no matter what white space present, all other lines
+ * just have leading and trailing space removed.
+ */
+
+int tidy_line(char *linebuf, char *olinebuf)
+ {
+ char *keyword, *value, *p, *q;
+ strcpy(linebuf, olinebuf);
+ keyword = linebuf;
+ /* Skip leading space */
+ while (isspace((unsigned char)*keyword))
+ keyword++;
+ /* Look for = sign */
+ p = strchr(linebuf, '=');
+
+ /* If no '=' just chop leading, trailing ws */
+ if (!p)
+ {
+ p = keyword + strlen(keyword) - 1;
+ while (*p == '\n' || isspace((unsigned char)*p))
+ *p-- = 0;
+ strcpy(olinebuf, keyword);
+ strcat(olinebuf, "\n");
+ return 1;
+ }
+
+ q = p - 1;
+
+ /* Remove trailing space */
+ while (isspace((unsigned char)*q))
+ *q-- = 0;
+
+ *p = 0;
+ value = p + 1;
+
+ /* Remove leading space from value */
+ while (isspace((unsigned char)*value))
+ value++;
+
+ /* Remove trailing space from value */
+ p = value + strlen(value) - 1;
+
+ while (*p == '\n' || isspace((unsigned char)*p))
+ *p-- = 0;
+
+ strcpy(olinebuf, keyword);
+ strcat(olinebuf, " = ");
+ strcat(olinebuf, value);
+ strcat(olinebuf, "\n");
+
+ return 1;
+ }
+
+/* NB: this return the number of _bits_ read */
+int bint2bin(const char *in, int len, unsigned char *out)
+ {
+ int n;
+
+ memset(out,0,len);
+ for(n=0 ; n < len ; ++n)
+ if(in[n] == '1')
+ out[n/8]|=(0x80 >> (n%8));
+ return len;
+ }
+
+int bin2bint(const unsigned char *in,int len,char *out)
+ {
+ int n;
+
+ for(n=0 ; n < len ; ++n)
+ out[n]=(in[n/8]&(0x80 >> (n%8))) ? '1' : '0';
+ return n;
+ }
+
+/*-----------------------------------------------*/
+
+void PrintValue(char *tag, unsigned char *val, int len)
+{
+#if VERBOSE
+ char obuf[2048];
+ int olen;
+ olen = bin2hex(val, len, obuf);
+ printf("%s = %.*s\n", tag, olen, obuf);
+#endif
+}
+
+void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode)
+ {
+ char obuf[2048];
+ int olen;
+
+ if(bitmode)
+ olen=bin2bint(val,len,obuf);
+ else
+ olen=bin2hex(val,len,obuf);
+
+ fprintf(rfp, "%s = %.*s\n", tag, olen, obuf);
+#if VERBOSE
+ printf("%s = %.*s\n", tag, olen, obuf);
+#endif
+ }
+
diff --git a/crypto/openssl/fips/fipsalgtest.pl b/crypto/openssl/fips/fipsalgtest.pl
new file mode 100755
index 0000000..851cc98
--- /dev/null
+++ b/crypto/openssl/fips/fipsalgtest.pl
@@ -0,0 +1,887 @@
+#!/usr/bin/perl -w
+# Perl utility to run or verify FIPS 140-2 CMVP algorithm tests based on the
+# pathnames of input algorithm test files actually present (the unqualified
+# file names are consistent but the pathnames are not).
+#
+
+# FIPS test definitions
+# List of all the unqualified file names we expect and command lines to run
+
+# DSA tests
+my @fips_dsa_test_list = (
+
+ "DSA",
+
+ [ "PQGGen", "fips_dssvs pqg" ],
+ [ "KeyPair", "fips_dssvs keypair" ],
+ [ "SigGen", "fips_dssvs siggen" ],
+ [ "SigVer", "fips_dssvs sigver" ]
+
+);
+
+my @fips_dsa_pqgver_test_list = (
+
+ [ "PQGVer", "fips_dssvs pqgver" ]
+
+);
+
+# RSA tests
+
+my @fips_rsa_test_list = (
+
+ "RSA",
+
+ [ "SigGen15", "fips_rsastest" ],
+ [ "SigVer15", "fips_rsavtest" ],
+ [ "SigVerRSA", "fips_rsavtest -x931" ],
+ [ "KeyGenRSA", "fips_rsagtest" ],
+ [ "SigGenRSA", "fips_rsastest -x931" ]
+
+);
+
+# Special cases for PSS. The filename itself is
+# not sufficient to determine the test. Addditionally we
+# need to examine the file contents to determine the salt length
+# In these cases the test filename has (saltlen) appended.
+
+# RSA PSS salt length 0 tests
+
+my @fips_rsa_pss0_test_list = (
+
+ [ "SigGenPSS(0)", "fips_rsastest -saltlen 0" ],
+ [ "SigVerPSS(0)", "fips_rsavtest -saltlen 0" ]
+
+);
+
+# RSA PSS salt length 62 tests
+
+my @fips_rsa_pss62_test_list = (
+ [ "SigGenPSS(62)", "fips_rsastest -saltlen 62" ],
+ [ "SigVerPSS(62)", "fips_rsavtest -saltlen 62" ]
+
+);
+
+# SHA tests
+
+my @fips_sha_test_list = (
+
+ "SHA",
+
+ [ "SHA1LongMsg", "fips_shatest" ],
+ [ "SHA1Monte", "fips_shatest" ],
+ [ "SHA1ShortMsg", "fips_shatest" ],
+ [ "SHA224LongMsg", "fips_shatest" ],
+ [ "SHA224Monte", "fips_shatest" ],
+ [ "SHA224ShortMsg", "fips_shatest" ],
+ [ "SHA256LongMsg", "fips_shatest" ],
+ [ "SHA256Monte", "fips_shatest" ],
+ [ "SHA256ShortMsg", "fips_shatest" ],
+ [ "SHA384LongMsg", "fips_shatest" ],
+ [ "SHA384Monte", "fips_shatest" ],
+ [ "SHA384ShortMsg", "fips_shatest" ],
+ [ "SHA512LongMsg", "fips_shatest" ],
+ [ "SHA512Monte", "fips_shatest" ],
+ [ "SHA512ShortMsg", "fips_shatest" ]
+
+);
+
+# HMAC
+
+my @fips_hmac_test_list = (
+
+ "HMAC",
+
+ [ "HMAC", "fips_hmactest" ]
+
+);
+
+# RAND tests, AES version
+
+my @fips_rand_aes_test_list = (
+
+ "RAND (AES)",
+
+ [ "ANSI931_AES128MCT", "fips_rngvs mct" ],
+ [ "ANSI931_AES192MCT", "fips_rngvs mct" ],
+ [ "ANSI931_AES256MCT", "fips_rngvs mct" ],
+ [ "ANSI931_AES128VST", "fips_rngvs vst" ],
+ [ "ANSI931_AES192VST", "fips_rngvs vst" ],
+ [ "ANSI931_AES256VST", "fips_rngvs vst" ]
+
+);
+
+# RAND tests, DES2 version
+
+my @fips_rand_des2_test_list = (
+
+ "RAND (DES2)",
+
+ [ "ANSI931_TDES2MCT", "fips_rngvs mct" ],
+ [ "ANSI931_TDES2VST", "fips_rngvs vst" ]
+
+);
+
+# AES tests
+
+my @fips_aes_test_list = (
+
+ "AES",
+
+ [ "CBCGFSbox128", "fips_aesavs -f" ],
+ [ "CBCGFSbox192", "fips_aesavs -f" ],
+ [ "CBCGFSbox256", "fips_aesavs -f" ],
+ [ "CBCKeySbox128", "fips_aesavs -f" ],
+ [ "CBCKeySbox192", "fips_aesavs -f" ],
+ [ "CBCKeySbox256", "fips_aesavs -f" ],
+ [ "CBCMCT128", "fips_aesavs -f" ],
+ [ "CBCMCT192", "fips_aesavs -f" ],
+ [ "CBCMCT256", "fips_aesavs -f" ],
+ [ "CBCMMT128", "fips_aesavs -f" ],
+ [ "CBCMMT192", "fips_aesavs -f" ],
+ [ "CBCMMT256", "fips_aesavs -f" ],
+ [ "CBCVarKey128", "fips_aesavs -f" ],
+ [ "CBCVarKey192", "fips_aesavs -f" ],
+ [ "CBCVarKey256", "fips_aesavs -f" ],
+ [ "CBCVarTxt128", "fips_aesavs -f" ],
+ [ "CBCVarTxt192", "fips_aesavs -f" ],
+ [ "CBCVarTxt256", "fips_aesavs -f" ],
+ [ "CFB128GFSbox128", "fips_aesavs -f" ],
+ [ "CFB128GFSbox192", "fips_aesavs -f" ],
+ [ "CFB128GFSbox256", "fips_aesavs -f" ],
+ [ "CFB128KeySbox128", "fips_aesavs -f" ],
+ [ "CFB128KeySbox192", "fips_aesavs -f" ],
+ [ "CFB128KeySbox256", "fips_aesavs -f" ],
+ [ "CFB128MCT128", "fips_aesavs -f" ],
+ [ "CFB128MCT192", "fips_aesavs -f" ],
+ [ "CFB128MCT256", "fips_aesavs -f" ],
+ [ "CFB128MMT128", "fips_aesavs -f" ],
+ [ "CFB128MMT192", "fips_aesavs -f" ],
+ [ "CFB128MMT256", "fips_aesavs -f" ],
+ [ "CFB128VarKey128", "fips_aesavs -f" ],
+ [ "CFB128VarKey192", "fips_aesavs -f" ],
+ [ "CFB128VarKey256", "fips_aesavs -f" ],
+ [ "CFB128VarTxt128", "fips_aesavs -f" ],
+ [ "CFB128VarTxt192", "fips_aesavs -f" ],
+ [ "CFB128VarTxt256", "fips_aesavs -f" ],
+ [ "CFB8GFSbox128", "fips_aesavs -f" ],
+ [ "CFB8GFSbox192", "fips_aesavs -f" ],
+ [ "CFB8GFSbox256", "fips_aesavs -f" ],
+ [ "CFB8KeySbox128", "fips_aesavs -f" ],
+ [ "CFB8KeySbox192", "fips_aesavs -f" ],
+ [ "CFB8KeySbox256", "fips_aesavs -f" ],
+ [ "CFB8MCT128", "fips_aesavs -f" ],
+ [ "CFB8MCT192", "fips_aesavs -f" ],
+ [ "CFB8MCT256", "fips_aesavs -f" ],
+ [ "CFB8MMT128", "fips_aesavs -f" ],
+ [ "CFB8MMT192", "fips_aesavs -f" ],
+ [ "CFB8MMT256", "fips_aesavs -f" ],
+ [ "CFB8VarKey128", "fips_aesavs -f" ],
+ [ "CFB8VarKey192", "fips_aesavs -f" ],
+ [ "CFB8VarKey256", "fips_aesavs -f" ],
+ [ "CFB8VarTxt128", "fips_aesavs -f" ],
+ [ "CFB8VarTxt192", "fips_aesavs -f" ],
+ [ "CFB8VarTxt256", "fips_aesavs -f" ],
+
+ [ "ECBGFSbox128", "fips_aesavs -f" ],
+ [ "ECBGFSbox192", "fips_aesavs -f" ],
+ [ "ECBGFSbox256", "fips_aesavs -f" ],
+ [ "ECBKeySbox128", "fips_aesavs -f" ],
+ [ "ECBKeySbox192", "fips_aesavs -f" ],
+ [ "ECBKeySbox256", "fips_aesavs -f" ],
+ [ "ECBMCT128", "fips_aesavs -f" ],
+ [ "ECBMCT192", "fips_aesavs -f" ],
+ [ "ECBMCT256", "fips_aesavs -f" ],
+ [ "ECBMMT128", "fips_aesavs -f" ],
+ [ "ECBMMT192", "fips_aesavs -f" ],
+ [ "ECBMMT256", "fips_aesavs -f" ],
+ [ "ECBVarKey128", "fips_aesavs -f" ],
+ [ "ECBVarKey192", "fips_aesavs -f" ],
+ [ "ECBVarKey256", "fips_aesavs -f" ],
+ [ "ECBVarTxt128", "fips_aesavs -f" ],
+ [ "ECBVarTxt192", "fips_aesavs -f" ],
+ [ "ECBVarTxt256", "fips_aesavs -f" ],
+ [ "OFBGFSbox128", "fips_aesavs -f" ],
+ [ "OFBGFSbox192", "fips_aesavs -f" ],
+ [ "OFBGFSbox256", "fips_aesavs -f" ],
+ [ "OFBKeySbox128", "fips_aesavs -f" ],
+ [ "OFBKeySbox192", "fips_aesavs -f" ],
+ [ "OFBKeySbox256", "fips_aesavs -f" ],
+ [ "OFBMCT128", "fips_aesavs -f" ],
+ [ "OFBMCT192", "fips_aesavs -f" ],
+ [ "OFBMCT256", "fips_aesavs -f" ],
+ [ "OFBMMT128", "fips_aesavs -f" ],
+ [ "OFBMMT192", "fips_aesavs -f" ],
+ [ "OFBMMT256", "fips_aesavs -f" ],
+ [ "OFBVarKey128", "fips_aesavs -f" ],
+ [ "OFBVarKey192", "fips_aesavs -f" ],
+ [ "OFBVarKey256", "fips_aesavs -f" ],
+ [ "OFBVarTxt128", "fips_aesavs -f" ],
+ [ "OFBVarTxt192", "fips_aesavs -f" ],
+ [ "OFBVarTxt256", "fips_aesavs -f" ]
+
+);
+
+my @fips_aes_cfb1_test_list = (
+
+ # AES CFB1 tests
+
+ [ "CFB1GFSbox128", "fips_aesavs -f" ],
+ [ "CFB1GFSbox192", "fips_aesavs -f" ],
+ [ "CFB1GFSbox256", "fips_aesavs -f" ],
+ [ "CFB1KeySbox128", "fips_aesavs -f" ],
+ [ "CFB1KeySbox192", "fips_aesavs -f" ],
+ [ "CFB1KeySbox256", "fips_aesavs -f" ],
+ [ "CFB1MCT128", "fips_aesavs -f" ],
+ [ "CFB1MCT192", "fips_aesavs -f" ],
+ [ "CFB1MCT256", "fips_aesavs -f" ],
+ [ "CFB1MMT128", "fips_aesavs -f" ],
+ [ "CFB1MMT192", "fips_aesavs -f" ],
+ [ "CFB1MMT256", "fips_aesavs -f" ],
+ [ "CFB1VarKey128", "fips_aesavs -f" ],
+ [ "CFB1VarKey192", "fips_aesavs -f" ],
+ [ "CFB1VarKey256", "fips_aesavs -f" ],
+ [ "CFB1VarTxt128", "fips_aesavs -f" ],
+ [ "CFB1VarTxt192", "fips_aesavs -f" ],
+ [ "CFB1VarTxt256", "fips_aesavs -f" ]
+
+);
+
+# Triple DES tests
+
+my @fips_des3_test_list = (
+
+ "Triple DES",
+
+ [ "TCBCinvperm", "fips_desmovs -f" ],
+ [ "TCBCMMT1", "fips_desmovs -f" ],
+ [ "TCBCMMT2", "fips_desmovs -f" ],
+ [ "TCBCMMT3", "fips_desmovs -f" ],
+ [ "TCBCMonte1", "fips_desmovs -f" ],
+ [ "TCBCMonte2", "fips_desmovs -f" ],
+ [ "TCBCMonte3", "fips_desmovs -f" ],
+ [ "TCBCpermop", "fips_desmovs -f" ],
+ [ "TCBCsubtab", "fips_desmovs -f" ],
+ [ "TCBCvarkey", "fips_desmovs -f" ],
+ [ "TCBCvartext", "fips_desmovs -f" ],
+ [ "TCFB64invperm", "fips_desmovs -f" ],
+ [ "TCFB64MMT1", "fips_desmovs -f" ],
+ [ "TCFB64MMT2", "fips_desmovs -f" ],
+ [ "TCFB64MMT3", "fips_desmovs -f" ],
+ [ "TCFB64Monte1", "fips_desmovs -f" ],
+ [ "TCFB64Monte2", "fips_desmovs -f" ],
+ [ "TCFB64Monte3", "fips_desmovs -f" ],
+ [ "TCFB64permop", "fips_desmovs -f" ],
+ [ "TCFB64subtab", "fips_desmovs -f" ],
+ [ "TCFB64varkey", "fips_desmovs -f" ],
+ [ "TCFB64vartext", "fips_desmovs -f" ],
+ [ "TCFB8invperm", "fips_desmovs -f" ],
+ [ "TCFB8MMT1", "fips_desmovs -f" ],
+ [ "TCFB8MMT2", "fips_desmovs -f" ],
+ [ "TCFB8MMT3", "fips_desmovs -f" ],
+ [ "TCFB8Monte1", "fips_desmovs -f" ],
+ [ "TCFB8Monte2", "fips_desmovs -f" ],
+ [ "TCFB8Monte3", "fips_desmovs -f" ],
+ [ "TCFB8permop", "fips_desmovs -f" ],
+ [ "TCFB8subtab", "fips_desmovs -f" ],
+ [ "TCFB8varkey", "fips_desmovs -f" ],
+ [ "TCFB8vartext", "fips_desmovs -f" ],
+ [ "TECBinvperm", "fips_desmovs -f" ],
+ [ "TECBMMT1", "fips_desmovs -f" ],
+ [ "TECBMMT2", "fips_desmovs -f" ],
+ [ "TECBMMT3", "fips_desmovs -f" ],
+ [ "TECBMonte1", "fips_desmovs -f" ],
+ [ "TECBMonte2", "fips_desmovs -f" ],
+ [ "TECBMonte3", "fips_desmovs -f" ],
+ [ "TECBpermop", "fips_desmovs -f" ],
+ [ "TECBsubtab", "fips_desmovs -f" ],
+ [ "TECBvarkey", "fips_desmovs -f" ],
+ [ "TECBvartext", "fips_desmovs -f" ],
+ [ "TOFBinvperm", "fips_desmovs -f" ],
+ [ "TOFBMMT1", "fips_desmovs -f" ],
+ [ "TOFBMMT2", "fips_desmovs -f" ],
+ [ "TOFBMMT3", "fips_desmovs -f" ],
+ [ "TOFBMonte1", "fips_desmovs -f" ],
+ [ "TOFBMonte2", "fips_desmovs -f" ],
+ [ "TOFBMonte3", "fips_desmovs -f" ],
+ [ "TOFBpermop", "fips_desmovs -f" ],
+ [ "TOFBsubtab", "fips_desmovs -f" ],
+ [ "TOFBvarkey", "fips_desmovs -f" ],
+ [ "TOFBvartext", "fips_desmovs -f" ]
+
+);
+
+my @fips_des3_cfb1_test_list = (
+
+ # DES3 CFB1 tests
+
+ [ "TCFB1invperm", "fips_desmovs -f" ],
+ [ "TCFB1MMT1", "fips_desmovs -f" ],
+ [ "TCFB1MMT2", "fips_desmovs -f" ],
+ [ "TCFB1MMT3", "fips_desmovs -f" ],
+ [ "TCFB1Monte1", "fips_desmovs -f" ],
+ [ "TCFB1Monte2", "fips_desmovs -f" ],
+ [ "TCFB1Monte3", "fips_desmovs -f" ],
+ [ "TCFB1permop", "fips_desmovs -f" ],
+ [ "TCFB1subtab", "fips_desmovs -f" ],
+ [ "TCFB1varkey", "fips_desmovs -f" ],
+ [ "TCFB1vartext", "fips_desmovs -f" ],
+
+);
+
+# Verification special cases.
+# In most cases the output of a test is deterministic and
+# it can be compared to a known good result. A few involve
+# the genration and use of random keys and the output will
+# be different each time. In thoses cases we perform special tests
+# to simply check their consistency. For example signature generation
+# output will be run through signature verification to see if all outputs
+# show as valid.
+#
+
+my %verify_special = (
+ "PQGGen" => "fips_dssvs pqgver",
+ "KeyPair" => "fips_dssvs keyver",
+ "SigGen" => "fips_dssvs sigver",
+ "SigGen15" => "fips_rsavtest",
+ "SigGenRSA" => "fips_rsavtest -x931",
+ "SigGenPSS(0)" => "fips_rsavtest -saltlen 0",
+ "SigGenPSS(62)" => "fips_rsavtest -saltlen 62",
+);
+
+my $win32 = $^O =~ m/mswin/i;
+my $onedir = 0;
+my $filter = "";
+my $tvdir;
+my $tprefix;
+my $shwrap_prefix;
+my $debug = 0;
+my $quiet = 0;
+my $notest = 0;
+my $verify = 1;
+my $rspdir = "rsp";
+my $ignore_missing = 0;
+my $ignore_bogus = 0;
+my $bufout = '';
+my $list_tests = 0;
+
+my %fips_enabled = (
+ dsa => 1,
+ "dsa-pqgver" => 0,
+ rsa => 1,
+ "rsa-pss0" => 0,
+ "rsa-pss62" => 1,
+ sha => 1,
+ hmac => 1,
+ "rand-aes" => 1,
+ "rand-des2" => 0,
+ aes => 1,
+ "aes-cfb1" => 0,
+ des3 => 1,
+ "des3-cfb1" => 0
+);
+
+foreach (@ARGV) {
+ if ( $_ eq "--win32" ) {
+ $win32 = 1;
+ }
+ elsif ( $_ eq "--onedir" ) {
+ $onedir = 1;
+ }
+ elsif ( $_ eq "--debug" ) {
+ $debug = 1;
+ }
+ elsif ( $_ eq "--ignore-missing" ) {
+ $ignore_missing = 1;
+ }
+ elsif ( $_ eq "--ignore-bogus" ) {
+ $ignore_bogus = 1;
+ }
+ elsif ( $_ eq "--generate" ) {
+ $verify = 0;
+ }
+ elsif ( $_ eq "--notest" ) {
+ $notest = 1;
+ }
+ elsif ( $_ eq "--quiet" ) {
+ $quiet = 1;
+ }
+ elsif (/--dir=(.*)$/) {
+ $tvdir = $1;
+ }
+ elsif (/--rspdir=(.*)$/) {
+ $rspdir = $1;
+ }
+ elsif (/--tprefix=(.*)$/) {
+ $tprefix = $1;
+ }
+ elsif (/--shwrap_prefix=(.*)$/) {
+ $shwrap_prefix = $1;
+ }
+ elsif (/^--(enable|disable)-(.*)$/) {
+ if ( !exists $fips_enabled{$2} ) {
+ print STDERR "Unknown test $2\n";
+ }
+ if ( $1 eq "enable" ) {
+ $fips_enabled{$2} = 1;
+ }
+ else {
+ $fips_enabled{$2} = 0;
+ }
+ }
+ elsif (/--filter=(.*)$/) {
+ $filter = $1;
+ }
+ elsif (/^--list-tests$/) {
+ $list_tests = 1;
+ }
+ else {
+ Help();
+ exit(1);
+ }
+}
+
+my @fips_test_list;
+
+push @fips_test_list, @fips_dsa_test_list if $fips_enabled{"dsa"};
+push @fips_test_list, @fips_dsa_pqgver_test_list if $fips_enabled{"dsa-pqgver"};
+push @fips_test_list, @fips_rsa_test_list if $fips_enabled{"rsa"};
+push @fips_test_list, @fips_rsa_pss0_test_list if $fips_enabled{"rsa-pss0"};
+push @fips_test_list, @fips_rsa_pss62_test_list if $fips_enabled{"rsa-pss62"};
+push @fips_test_list, @fips_sha_test_list if $fips_enabled{"sha"};
+push @fips_test_list, @fips_hmac_test_list if $fips_enabled{"hmac"};
+push @fips_test_list, @fips_rand_aes_test_list if $fips_enabled{"rand-aes"};
+push @fips_test_list, @fips_rand_des2_test_list if $fips_enabled{"rand-des2"};
+push @fips_test_list, @fips_aes_test_list if $fips_enabled{"aes"};
+push @fips_test_list, @fips_aes_cfb1_test_list if $fips_enabled{"aes-cfb1"};
+push @fips_test_list, @fips_des3_test_list if $fips_enabled{"des3"};
+push @fips_test_list, @fips_des3_cfb1_test_list if $fips_enabled{"des3-cfb1"};
+
+if ($list_tests) {
+ my ( $test, $en );
+ print "=====TEST LIST=====\n";
+ foreach $test ( sort keys %fips_enabled ) {
+ $en = $fips_enabled{$test};
+ $test =~ tr/[a-z]/[A-Z]/;
+ printf "%-10s %s\n", $test, $en ? "enabled" : "disabled";
+ }
+ exit(0);
+}
+
+foreach (@fips_test_list) {
+ next unless ref($_);
+ my $nm = $_->[0];
+ $_->[2] = "";
+ $_->[3] = "";
+ print STDERR "Duplicate test $nm\n" if exists $fips_tests{$nm};
+ $fips_tests{$nm} = $_;
+}
+
+$tvdir = "." unless defined $tvdir;
+
+if ($win32) {
+ if ( !defined $tprefix ) {
+ if ($onedir) {
+ $tprefix = ".\\";
+ }
+ else {
+ $tprefix = "..\\out32dll\\";
+ }
+ }
+}
+else {
+ if ($onedir) {
+ $tprefix = "./" unless defined $tprefix;
+ $shwrap_prefix = "./" unless defined $shwrap_prefix;
+ }
+ else {
+ $tprefix = "../test/" unless defined $tprefix;
+ $shwrap_prefix = "../util/" unless defined $shwrap_prefix;
+ }
+}
+
+sanity_check_exe( $win32, $tprefix, $shwrap_prefix );
+
+my $cmd_prefix = $win32 ? "" : "${shwrap_prefix}shlib_wrap.sh ";
+
+find_files( $filter, $tvdir );
+
+sanity_check_files();
+
+my ( $runerr, $cmperr, $cmpok, $scheckrunerr, $scheckerr, $scheckok, $skipcnt )
+ = ( 0, 0, 0, 0, 0, 0, 0 );
+
+exit(0) if $notest;
+
+run_tests( $verify, $win32, $tprefix, $filter, $tvdir );
+
+if ($verify) {
+ print "ALGORITHM TEST VERIFY SUMMARY REPORT:\n";
+ print "Tests skipped due to missing files: $skipcnt\n";
+ print "Algorithm test program execution failures: $runerr\n";
+ print "Test comparisons successful: $cmpok\n";
+ print "Test comparisons failed: $cmperr\n";
+ print "Test sanity checks successful: $scheckok\n";
+ print "Test sanity checks failed: $scheckerr\n";
+ print "Sanity check program execution failures: $scheckrunerr\n";
+
+ if ( $runerr || $cmperr || $scheckrunerr || $scheckerr ) {
+ print "***TEST FAILURE***\n";
+ }
+ else {
+ print "***ALL TESTS SUCCESSFUL***\n";
+ }
+}
+else {
+ print "ALGORITHM TEST SUMMARY REPORT:\n";
+ print "Tests skipped due to missing files: $skipcnt\n";
+ print "Algorithm test program execution failures: $runerr\n";
+
+ if ($runerr) {
+ print "***TEST FAILURE***\n";
+ }
+ else {
+ print "***ALL TESTS SUCCESSFUL***\n";
+ }
+}
+
+#--------------------------------
+sub Help {
+ ( my $cmd ) = ( $0 =~ m#([^/]+)$# );
+ print <<EOF;
+$cmd: generate run CMVP algorithm tests
+ --debug Enable debug output
+ --dir=<dirname> Optional root for *.req file search
+ --filter=<regexp>
+ --onedir <dirname> Assume all components in current directory
+ --rspdir=<dirname> Name of subdirectories containing *.rsp files, default "rsp"
+ --shwrap_prefix=<prefix>
+ --tprefix=<prefix>
+ --ignore-bogus Ignore duplicate or bogus files
+ --ignore-missing Ignore missing test files
+ --quiet Shhh....
+ --generate Generate algorithm test output
+ --win32 Win32 environment
+ --enable-<alg> Enable algorithm set <alg>.
+ --disable-<alg> Disable algorithm set <alg>.
+ Where <alg> can be one of:
+EOF
+
+while (my ($key, $value) = each %fips_enabled)
+ {
+ printf "\t\t%-20s(%s by default)\n", $key ,
+ $value ? "enabled" : "disabled";
+ }
+}
+
+# Sanity check to see if all necessary executables exist
+
+sub sanity_check_exe {
+ my ( $win32, $tprefix, $shwrap_prefix ) = @_;
+ my %exe_list;
+ my $bad = 0;
+ $exe_list{ $shwrap_prefix . "shlib_wrap.sh" } = 1 unless $win32;
+ foreach (@fips_test_list) {
+ next unless ref($_);
+ my $cmd = $_->[1];
+ $cmd =~ s/ .*$//;
+ $cmd = $tprefix . $cmd;
+ $cmd .= ".exe" if $win32;
+ $exe_list{$cmd} = 1;
+ }
+
+ foreach ( sort keys %exe_list ) {
+ if ( !-f $_ ) {
+ print STDERR "ERROR: can't find executable $_\n";
+ $bad = 1;
+ }
+ }
+ if ($bad) {
+ print STDERR "FATAL ERROR: executables missing\n";
+ exit(1);
+ }
+ elsif ($debug) {
+ print STDERR "Executable sanity check passed OK\n";
+ }
+}
+
+# Search for all request and response files
+
+sub find_files {
+ my ( $filter, $dir ) = @_;
+ my ( $dirh, $testname );
+ opendir( $dirh, $dir );
+ while ( $_ = readdir($dirh) ) {
+ next if ( $_ eq "." || $_ eq ".." );
+ $_ = "$dir/$_";
+ if ( -f "$_" ) {
+ if (/\/([^\/]*)\.rsp$/) {
+ $testname = fix_pss( $1, $_ );
+ if ( exists $fips_tests{$testname} ) {
+ if ( $fips_tests{$testname}->[3] eq "" ) {
+ $fips_tests{$testname}->[3] = $_;
+ }
+ else {
+ print STDERR
+"WARNING: duplicate response file $_ for test $testname\n";
+ $nbogus++;
+ }
+ }
+ else {
+ print STDERR "WARNING: bogus file $_\n";
+ $nbogus++;
+ }
+ }
+ next unless /$filter.*\.req$/i;
+ if (/\/([^\/]*)\.req$/) {
+ $testname = fix_pss( $1, $_ );
+ if ( exists $fips_tests{$testname} ) {
+ if ( $fips_tests{$testname}->[2] eq "" ) {
+ $fips_tests{$testname}->[2] = $_;
+ }
+ else {
+ print STDERR
+"WARNING: duplicate request file $_ for test $testname\n";
+ $nbogus++;
+ }
+
+ }
+ elsif ( !/SHAmix\.req$/ ) {
+ print STDERR "WARNING: unrecognized filename $_\n";
+ $nbogus++;
+ }
+ }
+ }
+ elsif ( -d "$_" ) {
+ find_files( $filter, $_ );
+ }
+ }
+ closedir($dirh);
+}
+
+sub fix_pss {
+ my ( $test, $path ) = @_;
+ my $sl = "";
+ local $_;
+ if ( $test =~ /PSS/ ) {
+ open( IN, $path ) || die "Can't Open File $path";
+ while (<IN>) {
+ if (/^\s*#\s*salt\s+len:\s+(\d+)\s*$/i) {
+ $sl = $1;
+ last;
+ }
+ }
+ close IN;
+ if ( $sl eq "" ) {
+ print STDERR "WARNING: No Salt length detected for file $path\n";
+ }
+ else {
+ return $test . "($sl)";
+ }
+ }
+ return $test;
+}
+
+sub sanity_check_files {
+ my $bad = 0;
+ foreach (@fips_test_list) {
+ next unless ref($_);
+ my ( $tst, $cmd, $req, $resp ) = @$_;
+
+ #print STDERR "FILES $tst, $cmd, $req, $resp\n";
+ if ( $req eq "" ) {
+ print STDERR "WARNING: missing request file for $tst\n";
+ $bad = 1;
+ next;
+ }
+ if ( $verify && $resp eq "" ) {
+ print STDERR "WARNING: no response file for test $tst\n";
+ $bad = 1;
+ }
+ elsif ( !$verify && $resp ne "" ) {
+ print STDERR "WARNING: response file $resp will be overwritten\n";
+ }
+ }
+ if ($bad) {
+ print STDERR "ERROR: test vector file set not complete\n";
+ exit(1) unless $ignore_missing;
+ }
+ if ($nbogus) {
+ print STDERR
+ "ERROR: $nbogus bogus or duplicate request and response files\n";
+ exit(1) unless $ignore_bogus;
+ }
+ if ( $debug && !$nbogus && !$bad ) {
+ print STDERR "test vector file set complete\n";
+ }
+}
+
+sub run_tests {
+ my ( $verify, $win32, $tprefix, $filter, $tvdir ) = @_;
+ my ( $tname, $tref );
+ my $bad = 0;
+ foreach (@fips_test_list) {
+ if ( !ref($_) ) {
+ print "Running $_ tests\n" unless $quiet;
+ next;
+ }
+ my ( $tname, $tcmd, $req, $rsp ) = @$_;
+ my $out = $rsp;
+ if ($verify) {
+ $out =~ s/\.rsp$/.tst/;
+ }
+ if ( $req eq "" ) {
+ print STDERR
+ "WARNING: Request file for $tname missing: test skipped\n";
+ $skipcnt++;
+ next;
+ }
+ if ( $verify && $rsp eq "" ) {
+ print STDERR
+ "WARNING: Response file for $tname missing: test skipped\n";
+ $skipcnt++;
+ next;
+ }
+ elsif ( !$verify ) {
+ if ( $rsp ne "" ) {
+ print STDERR "WARNING: Response file for $tname deleted\n";
+ unlink $rsp;
+ }
+ $out = $req;
+ $out =~ s|/req/(\S+)\.req|/$rspdir/$1.rsp|;
+ my $outdir = $out;
+ $outdir =~ s|/[^/]*$||;
+ if ( !-d $outdir ) {
+ print STDERR "DEBUG: Creating directory $outdir\n" if $debug;
+ mkdir($outdir) || die "Can't create directory $outdir";
+ }
+ }
+ my $cmd = "$cmd_prefix$tprefix$tcmd ";
+ if ( $tcmd =~ /-f$/ ) {
+ $cmd .= "\"$req\" \"$out\"";
+ }
+ else {
+ $cmd .= "<\"$req\" >\"$out\"";
+ }
+ print STDERR "DEBUG: running test $tname\n" if ( $debug && !$verify );
+ system($cmd);
+ if ( $? != 0 ) {
+ print STDERR
+ "WARNING: error executing test $tname for command: $cmd\n";
+ $runerr++;
+ next;
+ }
+ if ($verify) {
+ if ( exists $verify_special{$tname} ) {
+ my $vout = $rsp;
+ $vout =~ s/\.rsp$/.ver/;
+ $tcmd = $verify_special{$tname};
+ $cmd = "$cmd_prefix$tprefix$tcmd ";
+ $cmd .= "<\"$out\" >\"$vout\"";
+ system($cmd);
+ if ( $? != 0 ) {
+ print STDERR
+ "WARNING: error executing verify test $tname $cmd\n";
+ $scheckrunerr++;
+ next;
+ }
+ my ( $fcount, $pcount ) = ( 0, 0 );
+ open VER, "$vout";
+ while (<VER>) {
+ if (/^Result\s*=\s*(\S*)\s*$/i)
+
+ {
+ if ( $1 eq "F" ) {
+ $fcount++;
+ }
+ else {
+ $pcount++;
+ }
+ }
+ }
+ close VER;
+
+ unlink $vout;
+ if ( $fcount || $debug ) {
+ print STDERR "DEBUG: $tname, Pass=$pcount, Fail=$fcount\n";
+ }
+ if ( $fcount || !$pcount ) {
+ $scheckerr++;
+ }
+ else {
+ $scheckok++;
+ }
+
+ }
+ elsif ( !cmp_file( $tname, $rsp, $out ) ) {
+ $cmperr++;
+ }
+ else {
+ $cmpok++;
+ }
+ unlink $out;
+ }
+ }
+}
+
+sub cmp_file {
+ my ( $tname, $rsp, $tst ) = @_;
+ my ( $rspf, $tstf );
+ my ( $rspline, $tstline );
+ if ( !open( $rspf, $rsp ) ) {
+ print STDERR "ERROR: can't open request file $rsp\n";
+ return 0;
+ }
+ if ( !open( $tstf, $tst ) ) {
+ print STDERR "ERROR: can't open output file $tst\n";
+ return 0;
+ }
+ for ( ; ; ) {
+ $rspline = next_line($rspf);
+ $tstline = next_line($tstf);
+ if ( !defined($rspline) && !defined($tstline) ) {
+ print STDERR "DEBUG: $tname file comparison OK\n" if $debug;
+ return 1;
+ }
+ if ( !defined($rspline) ) {
+ print STDERR "ERROR: $tname EOF on $rsp\n";
+ return 0;
+ }
+ if ( !defined($tstline) ) {
+ print STDERR "ERROR: $tname EOF on $tst\n";
+ return 0;
+ }
+
+ # Workaround for bug in RAND des2 test output */
+ if ( $tstline =~ /^Key2 =/ && $rspline =~ /^Key1 =/ ) {
+ $rspline =~ s/^Key1/Key2/;
+ }
+
+ if ( $tstline ne $rspline ) {
+ print STDERR "ERROR: $tname mismatch:\n";
+ print STDERR "\t \"$tstline\" != \"$rspline\"\n";
+ return 0;
+ }
+ }
+ return 1;
+}
+
+sub next_line {
+ my ($in) = @_;
+
+ while (<$in>) {
+ chomp;
+
+ # Delete comments
+ s/#.*$//;
+
+ # Ignore blank lines
+ next if (/^\s*$/);
+
+ # Translate multiple space into one
+ s/\s+/ /g;
+ # Delete trailing whitespace
+ s/\s+$//;
+ return $_;
+ }
+ return undef;
+}
diff --git a/crypto/openssl/fips/fipsld b/crypto/openssl/fips/fipsld
new file mode 100755
index 0000000..8c26c85
--- /dev/null
+++ b/crypto/openssl/fips/fipsld
@@ -0,0 +1,178 @@
+#!/bin/sh -e
+#
+# Copyright (c) 2005-2007 The OpenSSL Project.
+#
+# Depending on output file name, the script either embeds fingerprint
+# into libcrypto.so or static application. "Static" refers to static
+# libcrypto.a, not [necessarily] application per se.
+#
+# Even though this script is called fipsld, it expects C compiler
+# command line syntax and $FIPSLD_CC or $CC environment variable set
+# and can even be used to compile source files.
+
+#set -x
+
+CC=${FIPSLD_CC:-${CC}}
+[ -n "${CC}" ] || { echo '$CC is not defined'; exit 1; }
+
+# Initially -c wasn't intended to be interpreted here, but it might
+# make life easier for those who want to build FIPS-ified applications
+# with minimal [if any] modifications to their Makefiles...
+( while [ "x$1" != "x" -a "x$1" != "x-c" -a "x$1" != "x-E" ]; do shift; done;
+ [ $# -ge 1 ]
+) && exec ${CC} "$@"
+
+TARGET=`(while [ "x$1" != "x" -a "x$1" != "x-o" ]; do shift; done; echo $2)`
+
+# If using an auto-tooled (autoconf/automake/libtool) project,
+# configure will fail when testing the compiler or even performing
+# simple checks. Pass-through to compiler directly if application is
+# is not being linked with libcrypto, allowing auto-tooled applications
+# to utilize fipsld (e.g. CC=/usr/local/ssl/bin/fipsld FIPSLD_CC=gcc
+# ./configure && make). But keep in mind[!] that if certified code
+# resides in a shared library, then fipsld *may not* be used and
+# end-developer should not modify application configuration and build
+# procedures. This is because in-core fingerprint and associated
+# procedures are already embedded into and executed in shared library
+# context.
+case `basename "${TARGET}"` in
+libcrypto*|libfips*|*.dll) ;;
+*) case "$*" in
+ *libcrypto.a*|*-lcrypto*|*fipscanister.o*) ;;
+ *) exec ${CC} "$@" ;;
+ esac
+esac
+
+[ -n "${TARGET}" ] || { echo 'no -o specified'; exit 1; }
+
+# Turn on debugging output?
+( while [ "x$1" != "x" -a "x$1" != "x-DDEBUG_FINGERPRINT_PREMAIN" ]; do shift; done;
+ [ $# -ge 1 ]
+) && set -x
+
+THERE="`echo $0 | sed -e 's|[^/]*$||'`"..
+
+# fipscanister.o can appear in command line
+CANISTER_O=`(while [ "x$1" != "x" ]; do case "$1" in *fipscanister.o) echo $1; exit;; esac; shift; done)`
+if [ -z "${CANISTER_O}" ]; then
+ # If set, FIPSLIBDIR is location of installed validated FIPS module
+ if [ -n "${FIPSLIBDIR}" ]; then
+ CANISTER_O="${FIPSLIBDIR}/fipscanister.o"
+ elif [ -f "${THERE}/fips/fipscanister.o" ]; then
+ CANISTER_O="${THERE}/fips/fipscanister.o"
+ elif [ -f "${THERE}/lib/fipscanister.o" ]; then
+ CANISTER_O="${THERE}/lib/fipscanister.o"
+ fi
+ CANISTER_O_CMD="${CANISTER_O}"
+fi
+[ -f ${CANISTER_O} ] || { echo "unable to find ${CANISTER_O}"; exit 1; }
+
+PREMAIN_C=`dirname "${CANISTER_O}"`/fips_premain.c
+
+HMAC_KEY="etaonrishdlcupfm"
+
+case "`(uname -s) 2>/dev/null`" in
+OSF1|IRIX*) _WL_PREMAIN="-Wl,-init,FINGERPRINT_premain" ;;
+HP-UX) _WL_PREMAIN="-Wl,+init,FINGERPRINT_premain" ;;
+AIX) _WL_PREMAIN="-Wl,-binitfini:FINGERPRINT_premain,-bnoobjreorder";;
+Darwin) ( while [ "x$1" != "x" -a "x$1" != "x-dynamiclib" ]; do shift; done;
+ [ $# -ge 1 ]
+ ) && _WL_PREMAIN="-Wl,-init,_FINGERPRINT_premain" ;;
+esac
+
+case "${TARGET}" in
+[!/]*) TARGET=./${TARGET} ;;
+esac
+
+case `basename "${TARGET}"` in
+lib*|*.dll) # must be linking a shared lib...
+ # Shared lib creation can be taking place in the source
+ # directory only, but fipscanister.o can reside elsewhere...
+ FINGERTYPE="${THERE}/fips/fips_standalone_sha1"
+
+ # verify fipspremain.c against its detached signature...
+ ${FINGERTYPE} "${PREMAIN_C}" | sed "s/(.*\//(/" | \
+ diff -w "${PREMAIN_C}.sha1" - || \
+ { echo "${PREMAIN_C} fingerprint mismatch"; exit 1; }
+ # verify fipscanister.o against its detached signature...
+ ${FINGERTYPE} "${CANISTER_O}" | sed "s/(.*\//(/" | \
+ diff -w "${CANISTER_O}.sha1" - || \
+ { echo "${CANISTER_O} fingerprint mismatch"; exit 1; }
+
+ # Temporarily remove fipscanister.o from libcrypto.a!
+ # We are required to use the standalone copy...
+ if [ -f "${THERE}/libcrypto.a" ]; then
+ if ar d "${THERE}/libcrypto.a" fipscanister.o; then
+ (ranlib "${THERE}/libcrypto.a") 2>/dev/null || :
+ trap 'ar r "${THERE}/libcrypto.a" "${CANISTER_O}";
+ (ranlib "${THERE}/libcrypto.a") 2>/dev/null || :;
+ sleep 1;
+ touch -c "${TARGET}"' 0
+ fi
+ fi
+
+ /bin/rm -f "${TARGET}"
+ ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
+ "${PREMAIN_C}" \
+ ${_WL_PREMAIN} "$@"
+
+ # generate signature...
+ if [ -z "${FIPS_SIG}" ]; then
+ SIG=`"${THERE}/fips/fips_premain_dso" "${TARGET}"`
+ else
+ SIG=`"${FIPS_SIG}" -dso "${TARGET}"`
+ fi
+ /bin/rm -f "${TARGET}"
+ if [ -z "${SIG}" ]; then
+ echo "unable to collect signature"; exit 1
+ fi
+
+ # recompile with signature...
+ ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
+ -DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \
+ ${_WL_PREMAIN} "$@"
+ ;;
+
+*) # must be linking statically...
+ # Static linking can be taking place either in the source
+ # directory or off the installed binary target destination.
+ if [ -x "${THERE}/fips/fips_standalone_sha1" ]; then
+ FINGERTYPE="${THERE}/fips/fips_standalone_sha1"
+ else # Installed tree is expected to contain
+ # lib/fipscanister.o, lib/fipscanister.o.sha1 and
+ # lib/fips_premain.c [not to mention bin/openssl].
+ FINGERTYPE="${THERE}/bin/openssl sha1 -hmac ${HMAC_KEY}"
+ fi
+
+ # verify fipscanister.o against its detached signature...
+ ${FINGERTYPE} "${CANISTER_O}" | sed "s/(.*\//(/" | \
+ diff -w "${CANISTER_O}.sha1" - || \
+ { echo "${CANISTER_O} fingerprint mismatch"; exit 1; }
+
+ # verify fips_premain.c against its detached signature...
+ ${FINGERTYPE} "${PREMAIN_C}" | sed "s/(.*\//(/" | \
+ diff -w "${PREMAIN_C}.sha1" - || \
+ { echo "${PREMAIN_C} fingerprint mismatch"; exit 1; }
+
+ /bin/rm -f "${TARGET}"
+ ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
+ "${PREMAIN_C}" \
+ ${_WL_PREMAIN} "$@"
+
+ # generate signature...
+ if [ -z "${FIPS_SIG}" ]; then
+ SIG=`"${TARGET}"`
+ else
+ SIG=`"${FIPS_SIG}" -exe "${TARGET}"`
+ fi
+ /bin/rm -f "${TARGET}"
+ if [ -z "${SIG}" ]; then
+ echo "unable to collect signature"; exit 1
+ fi
+
+ # recompile with signature...
+ ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
+ -DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \
+ ${_WL_PREMAIN} "$@"
+ ;;
+esac
diff --git a/crypto/openssl/fips/fipstests.sh b/crypto/openssl/fips/fipstests.sh
new file mode 100755
index 0000000..a351446
--- /dev/null
+++ b/crypto/openssl/fips/fipstests.sh
@@ -0,0 +1,400 @@
+#!/bin/sh
+
+# Test vector run script
+# Auto generated by mkfipsscr.pl script
+# Do not edit
+
+
+echo Running tests in "./testvectors/AES/req"
+rm -rf "./testvectors/AES/rsp"
+mkdir "./testvectors/AES/rsp"
+
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCGFSbox128.req" "./testvectors/AES/rsp/CBCGFSbox128.rsp" || { echo "./testvectors/AES/req/CBCGFSbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCGFSbox192.req" "./testvectors/AES/rsp/CBCGFSbox192.rsp" || { echo "./testvectors/AES/req/CBCGFSbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCGFSbox256.req" "./testvectors/AES/rsp/CBCGFSbox256.rsp" || { echo "./testvectors/AES/req/CBCGFSbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCKeySbox128.req" "./testvectors/AES/rsp/CBCKeySbox128.rsp" || { echo "./testvectors/AES/req/CBCKeySbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCKeySbox192.req" "./testvectors/AES/rsp/CBCKeySbox192.rsp" || { echo "./testvectors/AES/req/CBCKeySbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCKeySbox256.req" "./testvectors/AES/rsp/CBCKeySbox256.rsp" || { echo "./testvectors/AES/req/CBCKeySbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMCT128.req" "./testvectors/AES/rsp/CBCMCT128.rsp" || { echo "./testvectors/AES/req/CBCMCT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMCT192.req" "./testvectors/AES/rsp/CBCMCT192.rsp" || { echo "./testvectors/AES/req/CBCMCT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMCT256.req" "./testvectors/AES/rsp/CBCMCT256.rsp" || { echo "./testvectors/AES/req/CBCMCT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMMT128.req" "./testvectors/AES/rsp/CBCMMT128.rsp" || { echo "./testvectors/AES/req/CBCMMT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMMT192.req" "./testvectors/AES/rsp/CBCMMT192.rsp" || { echo "./testvectors/AES/req/CBCMMT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMMT256.req" "./testvectors/AES/rsp/CBCMMT256.rsp" || { echo "./testvectors/AES/req/CBCMMT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarKey128.req" "./testvectors/AES/rsp/CBCVarKey128.rsp" || { echo "./testvectors/AES/req/CBCVarKey128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarKey192.req" "./testvectors/AES/rsp/CBCVarKey192.rsp" || { echo "./testvectors/AES/req/CBCVarKey192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarKey256.req" "./testvectors/AES/rsp/CBCVarKey256.rsp" || { echo "./testvectors/AES/req/CBCVarKey256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarTxt128.req" "./testvectors/AES/rsp/CBCVarTxt128.rsp" || { echo "./testvectors/AES/req/CBCVarTxt128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarTxt192.req" "./testvectors/AES/rsp/CBCVarTxt192.rsp" || { echo "./testvectors/AES/req/CBCVarTxt192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarTxt256.req" "./testvectors/AES/rsp/CBCVarTxt256.rsp" || { echo "./testvectors/AES/req/CBCVarTxt256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128GFSbox128.req" "./testvectors/AES/rsp/CFB128GFSbox128.rsp" || { echo "./testvectors/AES/req/CFB128GFSbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128GFSbox192.req" "./testvectors/AES/rsp/CFB128GFSbox192.rsp" || { echo "./testvectors/AES/req/CFB128GFSbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128GFSbox256.req" "./testvectors/AES/rsp/CFB128GFSbox256.rsp" || { echo "./testvectors/AES/req/CFB128GFSbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128KeySbox128.req" "./testvectors/AES/rsp/CFB128KeySbox128.rsp" || { echo "./testvectors/AES/req/CFB128KeySbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128KeySbox192.req" "./testvectors/AES/rsp/CFB128KeySbox192.rsp" || { echo "./testvectors/AES/req/CFB128KeySbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128KeySbox256.req" "./testvectors/AES/rsp/CFB128KeySbox256.rsp" || { echo "./testvectors/AES/req/CFB128KeySbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MCT128.req" "./testvectors/AES/rsp/CFB128MCT128.rsp" || { echo "./testvectors/AES/req/CFB128MCT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MCT192.req" "./testvectors/AES/rsp/CFB128MCT192.rsp" || { echo "./testvectors/AES/req/CFB128MCT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MCT256.req" "./testvectors/AES/rsp/CFB128MCT256.rsp" || { echo "./testvectors/AES/req/CFB128MCT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MMT128.req" "./testvectors/AES/rsp/CFB128MMT128.rsp" || { echo "./testvectors/AES/req/CFB128MMT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MMT192.req" "./testvectors/AES/rsp/CFB128MMT192.rsp" || { echo "./testvectors/AES/req/CFB128MMT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MMT256.req" "./testvectors/AES/rsp/CFB128MMT256.rsp" || { echo "./testvectors/AES/req/CFB128MMT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarKey128.req" "./testvectors/AES/rsp/CFB128VarKey128.rsp" || { echo "./testvectors/AES/req/CFB128VarKey128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarKey192.req" "./testvectors/AES/rsp/CFB128VarKey192.rsp" || { echo "./testvectors/AES/req/CFB128VarKey192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarKey256.req" "./testvectors/AES/rsp/CFB128VarKey256.rsp" || { echo "./testvectors/AES/req/CFB128VarKey256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarTxt128.req" "./testvectors/AES/rsp/CFB128VarTxt128.rsp" || { echo "./testvectors/AES/req/CFB128VarTxt128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarTxt192.req" "./testvectors/AES/rsp/CFB128VarTxt192.rsp" || { echo "./testvectors/AES/req/CFB128VarTxt192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarTxt256.req" "./testvectors/AES/rsp/CFB128VarTxt256.rsp" || { echo "./testvectors/AES/req/CFB128VarTxt256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1GFSbox128.req" "./testvectors/AES/rsp/CFB1GFSbox128.rsp" || { echo "./testvectors/AES/req/CFB1GFSbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1GFSbox192.req" "./testvectors/AES/rsp/CFB1GFSbox192.rsp" || { echo "./testvectors/AES/req/CFB1GFSbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1GFSbox256.req" "./testvectors/AES/rsp/CFB1GFSbox256.rsp" || { echo "./testvectors/AES/req/CFB1GFSbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1KeySbox128.req" "./testvectors/AES/rsp/CFB1KeySbox128.rsp" || { echo "./testvectors/AES/req/CFB1KeySbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1KeySbox192.req" "./testvectors/AES/rsp/CFB1KeySbox192.rsp" || { echo "./testvectors/AES/req/CFB1KeySbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1KeySbox256.req" "./testvectors/AES/rsp/CFB1KeySbox256.rsp" || { echo "./testvectors/AES/req/CFB1KeySbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MCT128.req" "./testvectors/AES/rsp/CFB1MCT128.rsp" || { echo "./testvectors/AES/req/CFB1MCT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MCT192.req" "./testvectors/AES/rsp/CFB1MCT192.rsp" || { echo "./testvectors/AES/req/CFB1MCT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MCT256.req" "./testvectors/AES/rsp/CFB1MCT256.rsp" || { echo "./testvectors/AES/req/CFB1MCT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MMT128.req" "./testvectors/AES/rsp/CFB1MMT128.rsp" || { echo "./testvectors/AES/req/CFB1MMT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MMT192.req" "./testvectors/AES/rsp/CFB1MMT192.rsp" || { echo "./testvectors/AES/req/CFB1MMT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MMT256.req" "./testvectors/AES/rsp/CFB1MMT256.rsp" || { echo "./testvectors/AES/req/CFB1MMT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarKey128.req" "./testvectors/AES/rsp/CFB1VarKey128.rsp" || { echo "./testvectors/AES/req/CFB1VarKey128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarKey192.req" "./testvectors/AES/rsp/CFB1VarKey192.rsp" || { echo "./testvectors/AES/req/CFB1VarKey192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarKey256.req" "./testvectors/AES/rsp/CFB1VarKey256.rsp" || { echo "./testvectors/AES/req/CFB1VarKey256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarTxt128.req" "./testvectors/AES/rsp/CFB1VarTxt128.rsp" || { echo "./testvectors/AES/req/CFB1VarTxt128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarTxt192.req" "./testvectors/AES/rsp/CFB1VarTxt192.rsp" || { echo "./testvectors/AES/req/CFB1VarTxt192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarTxt256.req" "./testvectors/AES/rsp/CFB1VarTxt256.rsp" || { echo "./testvectors/AES/req/CFB1VarTxt256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8GFSbox128.req" "./testvectors/AES/rsp/CFB8GFSbox128.rsp" || { echo "./testvectors/AES/req/CFB8GFSbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8GFSbox192.req" "./testvectors/AES/rsp/CFB8GFSbox192.rsp" || { echo "./testvectors/AES/req/CFB8GFSbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8GFSbox256.req" "./testvectors/AES/rsp/CFB8GFSbox256.rsp" || { echo "./testvectors/AES/req/CFB8GFSbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8KeySbox128.req" "./testvectors/AES/rsp/CFB8KeySbox128.rsp" || { echo "./testvectors/AES/req/CFB8KeySbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8KeySbox192.req" "./testvectors/AES/rsp/CFB8KeySbox192.rsp" || { echo "./testvectors/AES/req/CFB8KeySbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8KeySbox256.req" "./testvectors/AES/rsp/CFB8KeySbox256.rsp" || { echo "./testvectors/AES/req/CFB8KeySbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MCT128.req" "./testvectors/AES/rsp/CFB8MCT128.rsp" || { echo "./testvectors/AES/req/CFB8MCT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MCT192.req" "./testvectors/AES/rsp/CFB8MCT192.rsp" || { echo "./testvectors/AES/req/CFB8MCT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MCT256.req" "./testvectors/AES/rsp/CFB8MCT256.rsp" || { echo "./testvectors/AES/req/CFB8MCT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MMT128.req" "./testvectors/AES/rsp/CFB8MMT128.rsp" || { echo "./testvectors/AES/req/CFB8MMT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MMT192.req" "./testvectors/AES/rsp/CFB8MMT192.rsp" || { echo "./testvectors/AES/req/CFB8MMT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MMT256.req" "./testvectors/AES/rsp/CFB8MMT256.rsp" || { echo "./testvectors/AES/req/CFB8MMT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarKey128.req" "./testvectors/AES/rsp/CFB8VarKey128.rsp" || { echo "./testvectors/AES/req/CFB8VarKey128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarKey192.req" "./testvectors/AES/rsp/CFB8VarKey192.rsp" || { echo "./testvectors/AES/req/CFB8VarKey192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarKey256.req" "./testvectors/AES/rsp/CFB8VarKey256.rsp" || { echo "./testvectors/AES/req/CFB8VarKey256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarTxt128.req" "./testvectors/AES/rsp/CFB8VarTxt128.rsp" || { echo "./testvectors/AES/req/CFB8VarTxt128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarTxt192.req" "./testvectors/AES/rsp/CFB8VarTxt192.rsp" || { echo "./testvectors/AES/req/CFB8VarTxt192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarTxt256.req" "./testvectors/AES/rsp/CFB8VarTxt256.rsp" || { echo "./testvectors/AES/req/CFB8VarTxt256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBGFSbox128.req" "./testvectors/AES/rsp/ECBGFSbox128.rsp" || { echo "./testvectors/AES/req/ECBGFSbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBGFSbox192.req" "./testvectors/AES/rsp/ECBGFSbox192.rsp" || { echo "./testvectors/AES/req/ECBGFSbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBGFSbox256.req" "./testvectors/AES/rsp/ECBGFSbox256.rsp" || { echo "./testvectors/AES/req/ECBGFSbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBKeySbox128.req" "./testvectors/AES/rsp/ECBKeySbox128.rsp" || { echo "./testvectors/AES/req/ECBKeySbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBKeySbox192.req" "./testvectors/AES/rsp/ECBKeySbox192.rsp" || { echo "./testvectors/AES/req/ECBKeySbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBKeySbox256.req" "./testvectors/AES/rsp/ECBKeySbox256.rsp" || { echo "./testvectors/AES/req/ECBKeySbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMCT128.req" "./testvectors/AES/rsp/ECBMCT128.rsp" || { echo "./testvectors/AES/req/ECBMCT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMCT192.req" "./testvectors/AES/rsp/ECBMCT192.rsp" || { echo "./testvectors/AES/req/ECBMCT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMCT256.req" "./testvectors/AES/rsp/ECBMCT256.rsp" || { echo "./testvectors/AES/req/ECBMCT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMMT128.req" "./testvectors/AES/rsp/ECBMMT128.rsp" || { echo "./testvectors/AES/req/ECBMMT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMMT192.req" "./testvectors/AES/rsp/ECBMMT192.rsp" || { echo "./testvectors/AES/req/ECBMMT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMMT256.req" "./testvectors/AES/rsp/ECBMMT256.rsp" || { echo "./testvectors/AES/req/ECBMMT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarKey128.req" "./testvectors/AES/rsp/ECBVarKey128.rsp" || { echo "./testvectors/AES/req/ECBVarKey128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarKey192.req" "./testvectors/AES/rsp/ECBVarKey192.rsp" || { echo "./testvectors/AES/req/ECBVarKey192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarKey256.req" "./testvectors/AES/rsp/ECBVarKey256.rsp" || { echo "./testvectors/AES/req/ECBVarKey256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarTxt128.req" "./testvectors/AES/rsp/ECBVarTxt128.rsp" || { echo "./testvectors/AES/req/ECBVarTxt128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarTxt192.req" "./testvectors/AES/rsp/ECBVarTxt192.rsp" || { echo "./testvectors/AES/req/ECBVarTxt192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarTxt256.req" "./testvectors/AES/rsp/ECBVarTxt256.rsp" || { echo "./testvectors/AES/req/ECBVarTxt256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBGFSbox128.req" "./testvectors/AES/rsp/OFBGFSbox128.rsp" || { echo "./testvectors/AES/req/OFBGFSbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBGFSbox192.req" "./testvectors/AES/rsp/OFBGFSbox192.rsp" || { echo "./testvectors/AES/req/OFBGFSbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBGFSbox256.req" "./testvectors/AES/rsp/OFBGFSbox256.rsp" || { echo "./testvectors/AES/req/OFBGFSbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBKeySbox128.req" "./testvectors/AES/rsp/OFBKeySbox128.rsp" || { echo "./testvectors/AES/req/OFBKeySbox128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBKeySbox192.req" "./testvectors/AES/rsp/OFBKeySbox192.rsp" || { echo "./testvectors/AES/req/OFBKeySbox192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBKeySbox256.req" "./testvectors/AES/rsp/OFBKeySbox256.rsp" || { echo "./testvectors/AES/req/OFBKeySbox256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMCT128.req" "./testvectors/AES/rsp/OFBMCT128.rsp" || { echo "./testvectors/AES/req/OFBMCT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMCT192.req" "./testvectors/AES/rsp/OFBMCT192.rsp" || { echo "./testvectors/AES/req/OFBMCT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMCT256.req" "./testvectors/AES/rsp/OFBMCT256.rsp" || { echo "./testvectors/AES/req/OFBMCT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMMT128.req" "./testvectors/AES/rsp/OFBMMT128.rsp" || { echo "./testvectors/AES/req/OFBMMT128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMMT192.req" "./testvectors/AES/rsp/OFBMMT192.rsp" || { echo "./testvectors/AES/req/OFBMMT192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMMT256.req" "./testvectors/AES/rsp/OFBMMT256.rsp" || { echo "./testvectors/AES/req/OFBMMT256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarKey128.req" "./testvectors/AES/rsp/OFBVarKey128.rsp" || { echo "./testvectors/AES/req/OFBVarKey128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarKey192.req" "./testvectors/AES/rsp/OFBVarKey192.rsp" || { echo "./testvectors/AES/req/OFBVarKey192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarKey256.req" "./testvectors/AES/rsp/OFBVarKey256.rsp" || { echo "./testvectors/AES/req/OFBVarKey256.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarTxt128.req" "./testvectors/AES/rsp/OFBVarTxt128.rsp" || { echo "./testvectors/AES/req/OFBVarTxt128.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarTxt192.req" "./testvectors/AES/rsp/OFBVarTxt192.rsp" || { echo "./testvectors/AES/req/OFBVarTxt192.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarTxt256.req" "./testvectors/AES/rsp/OFBVarTxt256.rsp" || { echo "./testvectors/AES/req/OFBVarTxt256.req failure" ; exit 1
+}
+
+echo Running tests in "./testvectors/DSA/req"
+rm -rf "./testvectors/DSA/rsp"
+mkdir "./testvectors/DSA/rsp"
+
+../util/shlib_wrap.sh ../test/fips_dssvs keypair < "./testvectors/DSA/req/KeyPair.req" > "./testvectors/DSA/rsp/KeyPair.rsp" || { echo "./testvectors/DSA/req/KeyPair.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_dssvs pqg < "./testvectors/DSA/req/PQGGen.req" > "./testvectors/DSA/rsp/PQGGen.rsp" || { echo "./testvectors/DSA/req/PQGGen.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_dssvs siggen < "./testvectors/DSA/req/SigGen.req" > "./testvectors/DSA/rsp/SigGen.rsp" || { echo "./testvectors/DSA/req/SigGen.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_dssvs sigver < "./testvectors/DSA/req/SigVer.req" > "./testvectors/DSA/rsp/SigVer.rsp" || { echo "./testvectors/DSA/req/SigVer.req failure" ; exit 1; }
+
+echo Running tests in "./testvectors/HMAC/req"
+rm -rf "./testvectors/HMAC/rsp"
+mkdir "./testvectors/HMAC/rsp"
+
+../util/shlib_wrap.sh ../test/fips_hmactest < "./testvectors/HMAC/req/HMAC.req" > "./testvectors/HMAC/rsp/HMAC.rsp" || { echo "./testvectors/HMAC/req/HMAC.req failure" ; exit 1; }
+
+echo Running tests in "./testvectors/RNG/req"
+rm -rf "./testvectors/RNG/rsp"
+mkdir "./testvectors/RNG/rsp"
+
+../util/shlib_wrap.sh ../test/fips_rngvs mct < "./testvectors/RNG/req/ANSI931_AES128MCT.req" > "./testvectors/RNG/rsp/ANSI931_AES128MCT.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES128MCT.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_rngvs vst < "./testvectors/RNG/req/ANSI931_AES128VST.req" > "./testvectors/RNG/rsp/ANSI931_AES128VST.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES128VST.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_rngvs mct < "./testvectors/RNG/req/ANSI931_AES192MCT.req" > "./testvectors/RNG/rsp/ANSI931_AES192MCT.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES192MCT.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_rngvs vst < "./testvectors/RNG/req/ANSI931_AES192VST.req" > "./testvectors/RNG/rsp/ANSI931_AES192VST.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES192VST.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_rngvs mct < "./testvectors/RNG/req/ANSI931_AES256MCT.req" > "./testvectors/RNG/rsp/ANSI931_AES256MCT.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES256MCT.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_rngvs vst < "./testvectors/RNG/req/ANSI931_AES256VST.req" > "./testvectors/RNG/rsp/ANSI931_AES256VST.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES256VST.req failure" ; exit 1; }
+
+echo Running tests in "./testvectors/RSA/req"
+rm -rf "./testvectors/RSA/rsp"
+mkdir "./testvectors/RSA/rsp"
+
+../util/shlib_wrap.sh ../test/fips_rsagtest < "./testvectors/RSA/req/KeyGenRSA.req" > "./testvectors/RSA/rsp/KeyGenRSA.rsp" || { echo "./testvectors/RSA/req/KeyGenRSA.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_rsastest < "./testvectors/RSA/req/SigGen15.req" > "./testvectors/RSA/rsp/SigGen15.rsp" || { echo "./testvectors/RSA/req/SigGen15.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_rsastest -saltlen 0 < "./testvectors/RSA/req/SigGenPSS.req" > "./testvectors/RSA/rsp/SigGenPSS.rsp" || { echo "./testvectors/RSA/req/SigGenPSS.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_rsastest -x931 < "./testvectors/RSA/req/SigGenRSA.req" > "./testvectors/RSA/rsp/SigGenRSA.rsp" || { echo "./testvectors/RSA/req/SigGenRSA.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_rsavtest < "./testvectors/RSA/req/SigVer15.req" > "./testvectors/RSA/rsp/SigVer15.rsp" || { echo "./testvectors/RSA/req/SigVer15.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_rsavtest -saltlen 0 < "./testvectors/RSA/req/SigVerPSS.req" > "./testvectors/RSA/rsp/SigVerPSS.rsp" || { echo "./testvectors/RSA/req/SigVerPSS.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_rsavtest -x931 < "./testvectors/RSA/req/SigVerRSA.req" > "./testvectors/RSA/rsp/SigVerRSA.rsp" || { echo "./testvectors/RSA/req/SigVerRSA.req failure" ; exit 1; }
+
+echo Running tests in "./testvectors/SHA/req"
+rm -rf "./testvectors/SHA/rsp"
+mkdir "./testvectors/SHA/rsp"
+
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA1LongMsg.req" > "./testvectors/SHA/rsp/SHA1LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA1LongMsg.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA1Monte.req" > "./testvectors/SHA/rsp/SHA1Monte.rsp" || { echo "./testvectors/SHA/req/SHA1Monte.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA1ShortMsg.req" > "./testvectors/SHA/rsp/SHA1ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA1ShortMsg.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA224LongMsg.req" > "./testvectors/SHA/rsp/SHA224LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA224LongMsg.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA224Monte.req" > "./testvectors/SHA/rsp/SHA224Monte.rsp" || { echo "./testvectors/SHA/req/SHA224Monte.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA224ShortMsg.req" > "./testvectors/SHA/rsp/SHA224ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA224ShortMsg.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA256LongMsg.req" > "./testvectors/SHA/rsp/SHA256LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA256LongMsg.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA256Monte.req" > "./testvectors/SHA/rsp/SHA256Monte.rsp" || { echo "./testvectors/SHA/req/SHA256Monte.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA256ShortMsg.req" > "./testvectors/SHA/rsp/SHA256ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA256ShortMsg.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA384LongMsg.req" > "./testvectors/SHA/rsp/SHA384LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA384LongMsg.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA384Monte.req" > "./testvectors/SHA/rsp/SHA384Monte.rsp" || { echo "./testvectors/SHA/req/SHA384Monte.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA384ShortMsg.req" > "./testvectors/SHA/rsp/SHA384ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA384ShortMsg.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA512LongMsg.req" > "./testvectors/SHA/rsp/SHA512LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA512LongMsg.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA512Monte.req" > "./testvectors/SHA/rsp/SHA512Monte.rsp" || { echo "./testvectors/SHA/req/SHA512Monte.req failure" ; exit 1; }
+../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA512ShortMsg.req" > "./testvectors/SHA/rsp/SHA512ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA512ShortMsg.req failure" ; exit 1; }
+
+echo Running tests in "./testvectors/TDES/req"
+rm -rf "./testvectors/TDES/rsp"
+mkdir "./testvectors/TDES/rsp"
+
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCinvperm.req" "./testvectors/TDES/rsp/TCBCinvperm.rsp" || { echo "./testvectors/TDES/req/TCBCinvperm.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMMT1.req" "./testvectors/TDES/rsp/TCBCMMT1.rsp" || { echo "./testvectors/TDES/req/TCBCMMT1.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMMT2.req" "./testvectors/TDES/rsp/TCBCMMT2.rsp" || { echo "./testvectors/TDES/req/TCBCMMT2.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMMT3.req" "./testvectors/TDES/rsp/TCBCMMT3.rsp" || { echo "./testvectors/TDES/req/TCBCMMT3.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMonte1.req" "./testvectors/TDES/rsp/TCBCMonte1.rsp" || { echo "./testvectors/TDES/req/TCBCMonte1.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMonte2.req" "./testvectors/TDES/rsp/TCBCMonte2.rsp" || { echo "./testvectors/TDES/req/TCBCMonte2.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMonte3.req" "./testvectors/TDES/rsp/TCBCMonte3.rsp" || { echo "./testvectors/TDES/req/TCBCMonte3.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCpermop.req" "./testvectors/TDES/rsp/TCBCpermop.rsp" || { echo "./testvectors/TDES/req/TCBCpermop.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCsubtab.req" "./testvectors/TDES/rsp/TCBCsubtab.rsp" || { echo "./testvectors/TDES/req/TCBCsubtab.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCvarkey.req" "./testvectors/TDES/rsp/TCBCvarkey.rsp" || { echo "./testvectors/TDES/req/TCBCvarkey.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCvartext.req" "./testvectors/TDES/rsp/TCBCvartext.rsp" || { echo "./testvectors/TDES/req/TCBCvartext.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64invperm.req" "./testvectors/TDES/rsp/TCFB64invperm.rsp" || { echo "./testvectors/TDES/req/TCFB64invperm.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64MMT1.req" "./testvectors/TDES/rsp/TCFB64MMT1.rsp" || { echo "./testvectors/TDES/req/TCFB64MMT1.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64MMT2.req" "./testvectors/TDES/rsp/TCFB64MMT2.rsp" || { echo "./testvectors/TDES/req/TCFB64MMT2.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64MMT3.req" "./testvectors/TDES/rsp/TCFB64MMT3.rsp" || { echo "./testvectors/TDES/req/TCFB64MMT3.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64Monte1.req" "./testvectors/TDES/rsp/TCFB64Monte1.rsp" || { echo "./testvectors/TDES/req/TCFB64Monte1.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64Monte2.req" "./testvectors/TDES/rsp/TCFB64Monte2.rsp" || { echo "./testvectors/TDES/req/TCFB64Monte2.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64Monte3.req" "./testvectors/TDES/rsp/TCFB64Monte3.rsp" || { echo "./testvectors/TDES/req/TCFB64Monte3.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64permop.req" "./testvectors/TDES/rsp/TCFB64permop.rsp" || { echo "./testvectors/TDES/req/TCFB64permop.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64subtab.req" "./testvectors/TDES/rsp/TCFB64subtab.rsp" || { echo "./testvectors/TDES/req/TCFB64subtab.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64varkey.req" "./testvectors/TDES/rsp/TCFB64varkey.rsp" || { echo "./testvectors/TDES/req/TCFB64varkey.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64vartext.req" "./testvectors/TDES/rsp/TCFB64vartext.rsp" || { echo "./testvectors/TDES/req/TCFB64vartext.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8invperm.req" "./testvectors/TDES/rsp/TCFB8invperm.rsp" || { echo "./testvectors/TDES/req/TCFB8invperm.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8MMT1.req" "./testvectors/TDES/rsp/TCFB8MMT1.rsp" || { echo "./testvectors/TDES/req/TCFB8MMT1.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8MMT2.req" "./testvectors/TDES/rsp/TCFB8MMT2.rsp" || { echo "./testvectors/TDES/req/TCFB8MMT2.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8MMT3.req" "./testvectors/TDES/rsp/TCFB8MMT3.rsp" || { echo "./testvectors/TDES/req/TCFB8MMT3.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8Monte1.req" "./testvectors/TDES/rsp/TCFB8Monte1.rsp" || { echo "./testvectors/TDES/req/TCFB8Monte1.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8Monte2.req" "./testvectors/TDES/rsp/TCFB8Monte2.rsp" || { echo "./testvectors/TDES/req/TCFB8Monte2.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8Monte3.req" "./testvectors/TDES/rsp/TCFB8Monte3.rsp" || { echo "./testvectors/TDES/req/TCFB8Monte3.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8permop.req" "./testvectors/TDES/rsp/TCFB8permop.rsp" || { echo "./testvectors/TDES/req/TCFB8permop.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8subtab.req" "./testvectors/TDES/rsp/TCFB8subtab.rsp" || { echo "./testvectors/TDES/req/TCFB8subtab.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8varkey.req" "./testvectors/TDES/rsp/TCFB8varkey.rsp" || { echo "./testvectors/TDES/req/TCFB8varkey.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8vartext.req" "./testvectors/TDES/rsp/TCFB8vartext.rsp" || { echo "./testvectors/TDES/req/TCFB8vartext.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBinvperm.req" "./testvectors/TDES/rsp/TECBinvperm.rsp" || { echo "./testvectors/TDES/req/TECBinvperm.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMMT1.req" "./testvectors/TDES/rsp/TECBMMT1.rsp" || { echo "./testvectors/TDES/req/TECBMMT1.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMMT2.req" "./testvectors/TDES/rsp/TECBMMT2.rsp" || { echo "./testvectors/TDES/req/TECBMMT2.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMMT3.req" "./testvectors/TDES/rsp/TECBMMT3.rsp" || { echo "./testvectors/TDES/req/TECBMMT3.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMonte1.req" "./testvectors/TDES/rsp/TECBMonte1.rsp" || { echo "./testvectors/TDES/req/TECBMonte1.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMonte2.req" "./testvectors/TDES/rsp/TECBMonte2.rsp" || { echo "./testvectors/TDES/req/TECBMonte2.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMonte3.req" "./testvectors/TDES/rsp/TECBMonte3.rsp" || { echo "./testvectors/TDES/req/TECBMonte3.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBpermop.req" "./testvectors/TDES/rsp/TECBpermop.rsp" || { echo "./testvectors/TDES/req/TECBpermop.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBsubtab.req" "./testvectors/TDES/rsp/TECBsubtab.rsp" || { echo "./testvectors/TDES/req/TECBsubtab.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBvarkey.req" "./testvectors/TDES/rsp/TECBvarkey.rsp" || { echo "./testvectors/TDES/req/TECBvarkey.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBvartext.req" "./testvectors/TDES/rsp/TECBvartext.rsp" || { echo "./testvectors/TDES/req/TECBvartext.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBinvperm.req" "./testvectors/TDES/rsp/TOFBinvperm.rsp" || { echo "./testvectors/TDES/req/TOFBinvperm.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMMT1.req" "./testvectors/TDES/rsp/TOFBMMT1.rsp" || { echo "./testvectors/TDES/req/TOFBMMT1.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMMT2.req" "./testvectors/TDES/rsp/TOFBMMT2.rsp" || { echo "./testvectors/TDES/req/TOFBMMT2.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMMT3.req" "./testvectors/TDES/rsp/TOFBMMT3.rsp" || { echo "./testvectors/TDES/req/TOFBMMT3.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMonte1.req" "./testvectors/TDES/rsp/TOFBMonte1.rsp" || { echo "./testvectors/TDES/req/TOFBMonte1.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMonte2.req" "./testvectors/TDES/rsp/TOFBMonte2.rsp" || { echo "./testvectors/TDES/req/TOFBMonte2.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMonte3.req" "./testvectors/TDES/rsp/TOFBMonte3.rsp" || { echo "./testvectors/TDES/req/TOFBMonte3.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBpermop.req" "./testvectors/TDES/rsp/TOFBpermop.rsp" || { echo "./testvectors/TDES/req/TOFBpermop.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBsubtab.req" "./testvectors/TDES/rsp/TOFBsubtab.rsp" || { echo "./testvectors/TDES/req/TOFBsubtab.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBvarkey.req" "./testvectors/TDES/rsp/TOFBvarkey.rsp" || { echo "./testvectors/TDES/req/TOFBvarkey.req failure" ; exit 1
+}
+../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBvartext.req" "./testvectors/TDES/rsp/TOFBvartext.rsp" || { echo "./testvectors/TDES/req/TOFBvartext.req failure" ; exit 1
+}
diff --git a/crypto/openssl/fips/hmac/Makefile b/crypto/openssl/fips/hmac/Makefile
new file mode 100644
index 0000000..be230ad
--- /dev/null
+++ b/crypto/openssl/fips/hmac/Makefile
@@ -0,0 +1,123 @@
+#
+# OpenSSL/fips/hmac/Makefile
+#
+
+DIR= hmac
+TOP= ../..
+CC= cc
+INCLUDES=
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile
+AR= ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=fips_hmactest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=fips_hmac.c fips_hmac_selftest.c
+LIBOBJ=fips_hmac.o fips_hmac_selftest.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=
+HEADER= $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ @echo $(LIBOBJ) > lib
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
+
+install:
+ @headerlist="$(EXHEADER)"; for i in $$headerlist; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+Q=../testvectors/hmac/req
+A=../testvectors/hmac/rsp
+
+fips_test:
+ -rm -rf $(A)
+ mkdir $(A)
+ if [ -f $(Q)/HMAC.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_hmactest < $(Q)/HMAC.req > $(A)/HMAC.rsp; fi
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+fips_hmac.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_hmac.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_hmac.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_hmac.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h
+fips_hmac.o: ../../include/openssl/objects.h
+fips_hmac.o: ../../include/openssl/opensslconf.h
+fips_hmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips_hmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_hmac.o: ../../include/openssl/symhacks.h fips_hmac.c
+fips_hmac_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_hmac_selftest.o: ../../include/openssl/crypto.h
+fips_hmac_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_hmac_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_hmac_selftest.o: ../../include/openssl/hmac.h
+fips_hmac_selftest.o: ../../include/openssl/lhash.h
+fips_hmac_selftest.o: ../../include/openssl/obj_mac.h
+fips_hmac_selftest.o: ../../include/openssl/objects.h
+fips_hmac_selftest.o: ../../include/openssl/opensslconf.h
+fips_hmac_selftest.o: ../../include/openssl/opensslv.h
+fips_hmac_selftest.o: ../../include/openssl/ossl_typ.h
+fips_hmac_selftest.o: ../../include/openssl/safestack.h
+fips_hmac_selftest.o: ../../include/openssl/stack.h
+fips_hmac_selftest.o: ../../include/openssl/symhacks.h fips_hmac_selftest.c
+fips_hmactest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_hmactest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+fips_hmactest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+fips_hmactest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_hmactest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+fips_hmactest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_hmactest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h
+fips_hmactest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_hmactest.o: ../../include/openssl/objects.h
+fips_hmactest.o: ../../include/openssl/opensslconf.h
+fips_hmactest.o: ../../include/openssl/opensslv.h
+fips_hmactest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+fips_hmactest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+fips_hmactest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_hmactest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+fips_hmactest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_hmactest.c
diff --git a/crypto/openssl/fips/hmac/fips_hmac.c b/crypto/openssl/fips/hmac/fips_hmac.c
new file mode 100644
index 0000000..69a10da
--- /dev/null
+++ b/crypto/openssl/fips/hmac/fips_hmac.c
@@ -0,0 +1,191 @@
+/* crypto/hmac/hmac.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/hmac.h>
+#include <openssl/fips.h>
+
+#ifdef OPENSSL_FIPS
+
+void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+ const EVP_MD *md, ENGINE *impl)
+ {
+ int i,j,reset=0;
+ unsigned char pad[HMAC_MAX_MD_CBLOCK];
+
+ if (md != NULL)
+ {
+ reset=1;
+ ctx->md=md;
+ }
+ else
+ md=ctx->md;
+
+ if (key != NULL)
+ {
+ if (FIPS_mode() && !(md->flags & EVP_MD_FLAG_FIPS)
+ && (!(ctx->md_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
+ || !(ctx->i_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
+ || !(ctx->o_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)))
+ OpenSSLDie(__FILE__,__LINE__,
+ "HMAC: digest not allowed in FIPS mode");
+
+ reset=1;
+ j=M_EVP_MD_block_size(md);
+ OPENSSL_assert(j <= (int)sizeof ctx->key);
+ if (j < len)
+ {
+ EVP_DigestInit_ex(&ctx->md_ctx,md, impl);
+ EVP_DigestUpdate(&ctx->md_ctx,key,len);
+ EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key,
+ &ctx->key_length);
+ }
+ else
+ {
+ OPENSSL_assert(len <= (int)sizeof ctx->key);
+ memcpy(ctx->key,key,len);
+ ctx->key_length=len;
+ }
+ if(ctx->key_length != HMAC_MAX_MD_CBLOCK)
+ memset(&ctx->key[ctx->key_length], 0,
+ HMAC_MAX_MD_CBLOCK - ctx->key_length);
+ }
+
+ if (reset)
+ {
+ for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
+ pad[i]=0x36^ctx->key[i];
+ EVP_DigestInit_ex(&ctx->i_ctx,md, impl);
+ EVP_DigestUpdate(&ctx->i_ctx,pad,M_EVP_MD_block_size(md));
+
+ for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
+ pad[i]=0x5c^ctx->key[i];
+ EVP_DigestInit_ex(&ctx->o_ctx,md, impl);
+ EVP_DigestUpdate(&ctx->o_ctx,pad,M_EVP_MD_block_size(md));
+ }
+ EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx);
+ }
+
+void HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
+ const EVP_MD *md)
+ {
+ if(key && md)
+ HMAC_CTX_init(ctx);
+ HMAC_Init_ex(ctx,key,len,md, NULL);
+ }
+
+void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
+ {
+ EVP_DigestUpdate(&ctx->md_ctx,data,len);
+ }
+
+void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
+ {
+ int j;
+ unsigned int i;
+ unsigned char buf[EVP_MAX_MD_SIZE];
+
+ j=M_EVP_MD_block_size(ctx->md);
+
+ EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i);
+ EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx);
+ EVP_DigestUpdate(&ctx->md_ctx,buf,i);
+ EVP_DigestFinal_ex(&ctx->md_ctx,md,len);
+ }
+
+void HMAC_CTX_init(HMAC_CTX *ctx)
+ {
+ EVP_MD_CTX_init(&ctx->i_ctx);
+ EVP_MD_CTX_init(&ctx->o_ctx);
+ EVP_MD_CTX_init(&ctx->md_ctx);
+ }
+
+void HMAC_CTX_cleanup(HMAC_CTX *ctx)
+ {
+ EVP_MD_CTX_cleanup(&ctx->i_ctx);
+ EVP_MD_CTX_cleanup(&ctx->o_ctx);
+ EVP_MD_CTX_cleanup(&ctx->md_ctx);
+ memset(ctx,0,sizeof *ctx);
+ }
+
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+ const unsigned char *d, size_t n, unsigned char *md,
+ unsigned int *md_len)
+ {
+ HMAC_CTX c;
+ static unsigned char m[EVP_MAX_MD_SIZE];
+
+ if (md == NULL) md=m;
+ HMAC_CTX_init(&c);
+ HMAC_Init(&c,key,key_len,evp_md);
+ HMAC_Update(&c,d,n);
+ HMAC_Final(&c,md,md_len);
+ HMAC_CTX_cleanup(&c);
+ return(md);
+ }
+
+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
+ {
+ M_EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
+ M_EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
+ M_EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
+ }
+
+#endif
+
diff --git a/crypto/openssl/fips/hmac/fips_hmac_selftest.c b/crypto/openssl/fips/hmac/fips_hmac_selftest.c
new file mode 100644
index 0000000..73455ff
--- /dev/null
+++ b/crypto/openssl/fips/hmac/fips_hmac_selftest.c
@@ -0,0 +1,135 @@
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+#include <openssl/hmac.h>
+
+#ifdef OPENSSL_FIPS
+typedef struct {
+ const EVP_MD *(*alg)(void);
+ const char *key, *iv;
+ unsigned char kaval[EVP_MAX_MD_SIZE];
+} HMAC_KAT;
+
+static const HMAC_KAT vector[] = {
+ { EVP_sha1,
+ /* from http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf */
+ "0123456789:;<=>?@ABC",
+ "Sample #2",
+ { 0x09,0x22,0xd3,0x40,0x5f,0xaa,0x3d,0x19,
+ 0x4f,0x82,0xa4,0x58,0x30,0x73,0x7d,0x5c,
+ 0xc6,0xc7,0x5d,0x24 }
+ },
+ { EVP_sha224,
+ /* just keep extending the above... */
+ "0123456789:;<=>?@ABC",
+ "Sample #2",
+ { 0xdd,0xef,0x0a,0x40,0xcb,0x7d,0x50,0xfb,
+ 0x6e,0xe6,0xce,0xa1,0x20,0xba,0x26,0xaa,
+ 0x08,0xf3,0x07,0x75,0x87,0xb8,0xad,0x1b,
+ 0x8c,0x8d,0x12,0xc7 }
+ },
+ { EVP_sha256,
+ "0123456789:;<=>?@ABC",
+ "Sample #2",
+ { 0xb8,0xf2,0x0d,0xb5,0x41,0xea,0x43,0x09,
+ 0xca,0x4e,0xa9,0x38,0x0c,0xd0,0xe8,0x34,
+ 0xf7,0x1f,0xbe,0x91,0x74,0xa2,0x61,0x38,
+ 0x0d,0xc1,0x7e,0xae,0x6a,0x34,0x51,0xd9 }
+ },
+ { EVP_sha384,
+ "0123456789:;<=>?@ABC",
+ "Sample #2",
+ { 0x08,0xbc,0xb0,0xda,0x49,0x1e,0x87,0xad,
+ 0x9a,0x1d,0x6a,0xce,0x23,0xc5,0x0b,0xf6,
+ 0xb7,0x18,0x06,0xa5,0x77,0xcd,0x49,0x04,
+ 0x89,0xf1,0xe6,0x23,0x44,0x51,0x51,0x9f,
+ 0x85,0x56,0x80,0x79,0x0c,0xbd,0x4d,0x50,
+ 0xa4,0x5f,0x29,0xe3,0x93,0xf0,0xe8,0x7f }
+ },
+ { EVP_sha512,
+ "0123456789:;<=>?@ABC",
+ "Sample #2",
+ { 0x80,0x9d,0x44,0x05,0x7c,0x5b,0x95,0x41,
+ 0x05,0xbd,0x04,0x13,0x16,0xdb,0x0f,0xac,
+ 0x44,0xd5,0xa4,0xd5,0xd0,0x89,0x2b,0xd0,
+ 0x4e,0x86,0x64,0x12,0xc0,0x90,0x77,0x68,
+ 0xf1,0x87,0xb7,0x7c,0x4f,0xae,0x2c,0x2f,
+ 0x21,0xa5,0xb5,0x65,0x9a,0x4f,0x4b,0xa7,
+ 0x47,0x02,0xa3,0xde,0x9b,0x51,0xf1,0x45,
+ 0xbd,0x4f,0x25,0x27,0x42,0x98,0x99,0x05 }
+ },
+};
+
+int FIPS_selftest_hmac()
+ {
+ size_t n;
+ unsigned int outlen;
+ unsigned char out[EVP_MAX_MD_SIZE];
+ const EVP_MD *md;
+ const HMAC_KAT *t;
+
+ for(n=0,t=vector; n<sizeof(vector)/sizeof(vector[0]); n++,t++)
+ {
+ md = (*t->alg)();
+ HMAC(md,t->key,strlen(t->key),
+ (const unsigned char *)t->iv,strlen(t->iv),
+ out,&outlen);
+
+ if(memcmp(out,t->kaval,outlen))
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_HMAC,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+ }
+ return 1;
+ }
+#endif
diff --git a/crypto/openssl/fips/hmac/fips_hmactest.c b/crypto/openssl/fips/hmac/fips_hmactest.c
new file mode 100644
index 0000000..69ebf68
--- /dev/null
+++ b/crypto/openssl/fips/hmac/fips_hmactest.c
@@ -0,0 +1,328 @@
+/* fips_hmactest.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+ printf("No FIPS HMAC support\n");
+ return(0);
+}
+
+#else
+
+#include <openssl/fips.h>
+#include "fips_utl.h"
+
+static int hmac_test(const EVP_MD *md, FILE *out, FILE *in);
+static int print_hmac(const EVP_MD *md, FILE *out,
+ unsigned char *Key, int Klen,
+ unsigned char *Msg, int Msglen, int Tlen);
+
+int main(int argc, char **argv)
+ {
+ FILE *in = NULL, *out = NULL;
+
+ int ret = 1;
+
+ if(!FIPS_mode_set(1))
+ {
+ do_print_errors();
+ goto end;
+ }
+
+ if (argc == 1)
+ in = stdin;
+ else
+ in = fopen(argv[1], "r");
+
+ if (argc < 2)
+ out = stdout;
+ else
+ out = fopen(argv[2], "w");
+
+ if (!in)
+ {
+ fprintf(stderr, "FATAL input initialization error\n");
+ goto end;
+ }
+
+ if (!out)
+ {
+ fprintf(stderr, "FATAL output initialization error\n");
+ goto end;
+ }
+
+ if (!hmac_test(EVP_sha1(), out, in))
+ {
+ fprintf(stderr, "FATAL hmac file processing error\n");
+ goto end;
+ }
+ else
+ ret = 0;
+
+ end:
+
+ if (ret)
+ do_print_errors();
+
+ if (in && (in != stdin))
+ fclose(in);
+ if (out && (out != stdout))
+ fclose(out);
+
+ return ret;
+
+ }
+
+#define HMAC_TEST_MAXLINELEN 1024
+
+int hmac_test(const EVP_MD *md, FILE *out, FILE *in)
+ {
+ char *linebuf, *olinebuf, *p, *q;
+ char *keyword, *value;
+ unsigned char *Key = NULL, *Msg = NULL;
+ int Count, Klen, Tlen;
+ long Keylen, Msglen;
+ int ret = 0;
+ int lnum = 0;
+
+ olinebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
+ linebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
+
+ if (!linebuf || !olinebuf)
+ goto error;
+
+ Count = -1;
+ Klen = -1;
+ Tlen = -1;
+
+ while (fgets(olinebuf, HMAC_TEST_MAXLINELEN, in))
+ {
+ lnum++;
+ strcpy(linebuf, olinebuf);
+ keyword = linebuf;
+ /* Skip leading space */
+ while (isspace((unsigned char)*keyword))
+ keyword++;
+
+ /* Look for = sign */
+ p = strchr(linebuf, '=');
+
+ /* If no = or starts with [ (for [L=20] line) just copy */
+ if (!p)
+ {
+ if (fputs(olinebuf, out) < 0)
+ goto error;
+ continue;
+ }
+
+ q = p - 1;
+
+ /* Remove trailing space */
+ while (isspace((unsigned char)*q))
+ *q-- = 0;
+
+ *p = 0;
+ value = p + 1;
+
+ /* Remove leading space from value */
+ while (isspace((unsigned char)*value))
+ value++;
+
+ /* Remove trailing space from value */
+ p = value + strlen(value) - 1;
+
+ while (*p == '\n' || isspace((unsigned char)*p))
+ *p-- = 0;
+
+ if (!strcmp(keyword,"[L") && *p==']')
+ {
+ switch (atoi(value))
+ {
+ case 20: md=EVP_sha1(); break;
+ case 28: md=EVP_sha224(); break;
+ case 32: md=EVP_sha256(); break;
+ case 48: md=EVP_sha384(); break;
+ case 64: md=EVP_sha512(); break;
+ default: goto parse_error;
+ }
+ }
+ else if (!strcmp(keyword, "Count"))
+ {
+ if (Count != -1)
+ goto parse_error;
+ Count = atoi(value);
+ if (Count < 0)
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "Klen"))
+ {
+ if (Klen != -1)
+ goto parse_error;
+ Klen = atoi(value);
+ if (Klen < 0)
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "Tlen"))
+ {
+ if (Tlen != -1)
+ goto parse_error;
+ Tlen = atoi(value);
+ if (Tlen < 0)
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "Msg"))
+ {
+ if (Msg)
+ goto parse_error;
+ Msg = hex2bin_m(value, &Msglen);
+ if (!Msg)
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "Key"))
+ {
+ if (Key)
+ goto parse_error;
+ Key = hex2bin_m(value, &Keylen);
+ if (!Key)
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "Mac"))
+ continue;
+ else
+ goto parse_error;
+
+ fputs(olinebuf, out);
+
+ if (Key && Msg && (Tlen > 0) && (Klen > 0))
+ {
+ if (!print_hmac(md, out, Key, Klen, Msg, Msglen, Tlen))
+ goto error;
+ OPENSSL_free(Key);
+ Key = NULL;
+ OPENSSL_free(Msg);
+ Msg = NULL;
+ Klen = -1;
+ Tlen = -1;
+ Count = -1;
+ }
+
+ }
+
+
+ ret = 1;
+
+
+ error:
+
+ if (olinebuf)
+ OPENSSL_free(olinebuf);
+ if (linebuf)
+ OPENSSL_free(linebuf);
+ if (Key)
+ OPENSSL_free(Key);
+ if (Msg)
+ OPENSSL_free(Msg);
+
+ return ret;
+
+ parse_error:
+
+ fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
+
+ goto error;
+
+ }
+
+static int print_hmac(const EVP_MD *emd, FILE *out,
+ unsigned char *Key, int Klen,
+ unsigned char *Msg, int Msglen, int Tlen)
+ {
+ int i, mdlen;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ if (!HMAC(emd, Key, Klen, Msg, Msglen, md,
+ (unsigned int *)&mdlen))
+ {
+ fputs("Error calculating HMAC\n", stderr);
+ return 0;
+ }
+ if (Tlen > mdlen)
+ {
+ fputs("Parameter error, Tlen > HMAC length\n", stderr);
+ return 0;
+ }
+ fputs("Mac = ", out);
+ for (i = 0; i < Tlen; i++)
+ fprintf(out, "%02x", md[i]);
+ fputs("\n", out);
+ return 1;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/mkfipsscr.pl b/crypto/openssl/fips/mkfipsscr.pl
new file mode 100755
index 0000000..361641d
--- /dev/null
+++ b/crypto/openssl/fips/mkfipsscr.pl
@@ -0,0 +1,657 @@
+#!/usr/local/bin/perl -w
+# Quick & dirty utility to generate a script for executing the
+# FIPS 140-2 CMVP algorithm tests based on the pathnames of
+# input algorithm test files actually present (the unqualified
+# file names are consistent but the pathnames are not).
+#
+
+# List of all the unqualified file names we expect.
+my %fips_tests = (
+
+# FIPS test definitions
+
+# DSA tests
+
+"PQGGen" => "fips_dssvs pqg",
+"KeyPair" => "fips_dssvs keypair",
+"SigGen" => "fips_dssvs siggen",
+"SigVer" => "fips_dssvs sigver",
+
+# SHA tests
+
+"SHA1LongMsg" => "fips_shatest",
+"SHA1Monte" => "fips_shatest",
+"SHA1ShortMsg" => "fips_shatest",
+"SHA224LongMsg" => "fips_shatest",
+"SHA224Monte" => "fips_shatest",
+"SHA224ShortMsg" => "fips_shatest",
+"SHA256LongMsg" => "fips_shatest",
+"SHA256Monte" => "fips_shatest",
+"SHA256ShortMsg" => "fips_shatest",
+"SHA384LongMsg" => "fips_shatest",
+"SHA384Monte" => "fips_shatest",
+"SHA384ShortMsg" => "fips_shatest",
+"SHA512LongMsg" => "fips_shatest",
+"SHA512Monte" => "fips_shatest",
+"SHA512ShortMsg" => "fips_shatest",
+
+# HMAC
+
+"HMAC" => "fips_hmactest",
+
+# RAND tests
+
+"ANSI931_AES128MCT" => "fips_rngvs mct",
+"ANSI931_AES192MCT" => "fips_rngvs mct",
+"ANSI931_AES256MCT" => "fips_rngvs mct",
+"ANSI931_AES128VST" => "fips_rngvs vst",
+"ANSI931_AES192VST" => "fips_rngvs vst",
+"ANSI931_AES256VST" => "fips_rngvs vst",
+
+# RSA tests
+
+"SigGen15" => "fips_rsastest",
+"SigVer15" => "fips_rsavtest",
+"SigGenPSS" => "fips_rsastest -saltlen SALT",
+"SigVerPSS" => "fips_rsavtest -saltlen SALT",
+"SigGenRSA" => "fips_rsastest -x931",
+"SigVerRSA" => "fips_rsavtest -x931",
+"KeyGenRSA" => "fips_rsagtest",
+
+# AES tests
+
+"CBCGFSbox128" => "fips_aesavs -f",
+"CBCGFSbox192" => "fips_aesavs -f",
+"CBCGFSbox256" => "fips_aesavs -f",
+"CBCKeySbox128" => "fips_aesavs -f",
+"CBCKeySbox192" => "fips_aesavs -f",
+"CBCKeySbox256" => "fips_aesavs -f",
+"CBCMCT128" => "fips_aesavs -f",
+"CBCMCT192" => "fips_aesavs -f",
+"CBCMCT256" => "fips_aesavs -f",
+"CBCMMT128" => "fips_aesavs -f",
+"CBCMMT192" => "fips_aesavs -f",
+"CBCMMT256" => "fips_aesavs -f",
+"CBCVarKey128" => "fips_aesavs -f",
+"CBCVarKey192" => "fips_aesavs -f",
+"CBCVarKey256" => "fips_aesavs -f",
+"CBCVarTxt128" => "fips_aesavs -f",
+"CBCVarTxt192" => "fips_aesavs -f",
+"CBCVarTxt256" => "fips_aesavs -f",
+"CFB128GFSbox128" => "fips_aesavs -f",
+"CFB128GFSbox192" => "fips_aesavs -f",
+"CFB128GFSbox256" => "fips_aesavs -f",
+"CFB128KeySbox128" => "fips_aesavs -f",
+"CFB128KeySbox192" => "fips_aesavs -f",
+"CFB128KeySbox256" => "fips_aesavs -f",
+"CFB128MCT128" => "fips_aesavs -f",
+"CFB128MCT192" => "fips_aesavs -f",
+"CFB128MCT256" => "fips_aesavs -f",
+"CFB128MMT128" => "fips_aesavs -f",
+"CFB128MMT192" => "fips_aesavs -f",
+"CFB128MMT256" => "fips_aesavs -f",
+"CFB128VarKey128" => "fips_aesavs -f",
+"CFB128VarKey192" => "fips_aesavs -f",
+"CFB128VarKey256" => "fips_aesavs -f",
+"CFB128VarTxt128" => "fips_aesavs -f",
+"CFB128VarTxt192" => "fips_aesavs -f",
+"CFB128VarTxt256" => "fips_aesavs -f",
+"CFB8GFSbox128" => "fips_aesavs -f",
+"CFB8GFSbox192" => "fips_aesavs -f",
+"CFB8GFSbox256" => "fips_aesavs -f",
+"CFB8KeySbox128" => "fips_aesavs -f",
+"CFB8KeySbox192" => "fips_aesavs -f",
+"CFB8KeySbox256" => "fips_aesavs -f",
+"CFB8MCT128" => "fips_aesavs -f",
+"CFB8MCT192" => "fips_aesavs -f",
+"CFB8MCT256" => "fips_aesavs -f",
+"CFB8MMT128" => "fips_aesavs -f",
+"CFB8MMT192" => "fips_aesavs -f",
+"CFB8MMT256" => "fips_aesavs -f",
+"CFB8VarKey128" => "fips_aesavs -f",
+"CFB8VarKey192" => "fips_aesavs -f",
+"CFB8VarKey256" => "fips_aesavs -f",
+"CFB8VarTxt128" => "fips_aesavs -f",
+"CFB8VarTxt192" => "fips_aesavs -f",
+"CFB8VarTxt256" => "fips_aesavs -f",
+#"CFB1GFSbox128" => "fips_aesavs -f",
+#"CFB1GFSbox192" => "fips_aesavs -f",
+#"CFB1GFSbox256" => "fips_aesavs -f",
+#"CFB1KeySbox128" => "fips_aesavs -f",
+#"CFB1KeySbox192" => "fips_aesavs -f",
+#"CFB1KeySbox256" => "fips_aesavs -f",
+#"CFB1MCT128" => "fips_aesavs -f",
+#"CFB1MCT192" => "fips_aesavs -f",
+#"CFB1MCT256" => "fips_aesavs -f",
+#"CFB1MMT128" => "fips_aesavs -f",
+#"CFB1MMT192" => "fips_aesavs -f",
+#"CFB1MMT256" => "fips_aesavs -f",
+#"CFB1VarKey128" => "fips_aesavs -f",
+#"CFB1VarKey192" => "fips_aesavs -f",
+#"CFB1VarKey256" => "fips_aesavs -f",
+#"CFB1VarTxt128" => "fips_aesavs -f",
+#"CFB1VarTxt192" => "fips_aesavs -f",
+#"CFB1VarTxt256" => "fips_aesavs -f",
+"ECBGFSbox128" => "fips_aesavs -f",
+"ECBGFSbox192" => "fips_aesavs -f",
+"ECBGFSbox256" => "fips_aesavs -f",
+"ECBKeySbox128" => "fips_aesavs -f",
+"ECBKeySbox192" => "fips_aesavs -f",
+"ECBKeySbox256" => "fips_aesavs -f",
+"ECBMCT128" => "fips_aesavs -f",
+"ECBMCT192" => "fips_aesavs -f",
+"ECBMCT256" => "fips_aesavs -f",
+"ECBMMT128" => "fips_aesavs -f",
+"ECBMMT192" => "fips_aesavs -f",
+"ECBMMT256" => "fips_aesavs -f",
+"ECBVarKey128" => "fips_aesavs -f",
+"ECBVarKey192" => "fips_aesavs -f",
+"ECBVarKey256" => "fips_aesavs -f",
+"ECBVarTxt128" => "fips_aesavs -f",
+"ECBVarTxt192" => "fips_aesavs -f",
+"ECBVarTxt256" => "fips_aesavs -f",
+"OFBGFSbox128" => "fips_aesavs -f",
+"OFBGFSbox192" => "fips_aesavs -f",
+"OFBGFSbox256" => "fips_aesavs -f",
+"OFBKeySbox128" => "fips_aesavs -f",
+"OFBKeySbox192" => "fips_aesavs -f",
+"OFBKeySbox256" => "fips_aesavs -f",
+"OFBMCT128" => "fips_aesavs -f",
+"OFBMCT192" => "fips_aesavs -f",
+"OFBMCT256" => "fips_aesavs -f",
+"OFBMMT128" => "fips_aesavs -f",
+"OFBMMT192" => "fips_aesavs -f",
+"OFBMMT256" => "fips_aesavs -f",
+"OFBVarKey128" => "fips_aesavs -f",
+"OFBVarKey192" => "fips_aesavs -f",
+"OFBVarKey256" => "fips_aesavs -f",
+"OFBVarTxt128" => "fips_aesavs -f",
+"OFBVarTxt192" => "fips_aesavs -f",
+"OFBVarTxt256" => "fips_aesavs -f",
+
+# Triple DES tests
+
+"TCBCinvperm" => "fips_desmovs -f",
+"TCBCMMT1" => "fips_desmovs -f",
+"TCBCMMT2" => "fips_desmovs -f",
+"TCBCMMT3" => "fips_desmovs -f",
+"TCBCMonte1" => "fips_desmovs -f",
+"TCBCMonte2" => "fips_desmovs -f",
+"TCBCMonte3" => "fips_desmovs -f",
+"TCBCpermop" => "fips_desmovs -f",
+"TCBCsubtab" => "fips_desmovs -f",
+"TCBCvarkey" => "fips_desmovs -f",
+"TCBCvartext" => "fips_desmovs -f",
+"TCFB64invperm" => "fips_desmovs -f",
+"TCFB64MMT1" => "fips_desmovs -f",
+"TCFB64MMT2" => "fips_desmovs -f",
+"TCFB64MMT3" => "fips_desmovs -f",
+"TCFB64Monte1" => "fips_desmovs -f",
+"TCFB64Monte2" => "fips_desmovs -f",
+"TCFB64Monte3" => "fips_desmovs -f",
+"TCFB64permop" => "fips_desmovs -f",
+"TCFB64subtab" => "fips_desmovs -f",
+"TCFB64varkey" => "fips_desmovs -f",
+"TCFB64vartext" => "fips_desmovs -f",
+"TCFB8invperm" => "fips_desmovs -f",
+"TCFB8MMT1" => "fips_desmovs -f",
+"TCFB8MMT2" => "fips_desmovs -f",
+"TCFB8MMT3" => "fips_desmovs -f",
+"TCFB8Monte1" => "fips_desmovs -f",
+"TCFB8Monte2" => "fips_desmovs -f",
+"TCFB8Monte3" => "fips_desmovs -f",
+"TCFB8permop" => "fips_desmovs -f",
+"TCFB8subtab" => "fips_desmovs -f",
+"TCFB8varkey" => "fips_desmovs -f",
+"TCFB8vartext" => "fips_desmovs -f",
+"TECBinvperm" => "fips_desmovs -f",
+"TECBMMT1" => "fips_desmovs -f",
+"TECBMMT2" => "fips_desmovs -f",
+"TECBMMT3" => "fips_desmovs -f",
+"TECBMonte1" => "fips_desmovs -f",
+"TECBMonte2" => "fips_desmovs -f",
+"TECBMonte3" => "fips_desmovs -f",
+"TECBpermop" => "fips_desmovs -f",
+"TECBsubtab" => "fips_desmovs -f",
+"TECBvarkey" => "fips_desmovs -f",
+"TECBvartext" => "fips_desmovs -f",
+"TOFBinvperm" => "fips_desmovs -f",
+"TOFBMMT1" => "fips_desmovs -f",
+"TOFBMMT2" => "fips_desmovs -f",
+"TOFBMMT3" => "fips_desmovs -f",
+"TOFBMonte1" => "fips_desmovs -f",
+"TOFBMonte2" => "fips_desmovs -f",
+"TOFBMonte3" => "fips_desmovs -f",
+"TOFBpermop" => "fips_desmovs -f",
+"TOFBsubtab" => "fips_desmovs -f",
+"TOFBvarkey" => "fips_desmovs -f",
+"TOFBvartext" => "fips_desmovs -f",
+"TCBCinvperm" => "fips_desmovs -f",
+"TCBCMMT1" => "fips_desmovs -f",
+"TCBCMMT2" => "fips_desmovs -f",
+"TCBCMMT3" => "fips_desmovs -f",
+"TCBCMonte1" => "fips_desmovs -f",
+"TCBCMonte2" => "fips_desmovs -f",
+"TCBCMonte3" => "fips_desmovs -f",
+"TCBCpermop" => "fips_desmovs -f",
+"TCBCsubtab" => "fips_desmovs -f",
+"TCBCvarkey" => "fips_desmovs -f",
+"TCBCvartext" => "fips_desmovs -f",
+"TCFB64invperm" => "fips_desmovs -f",
+"TCFB64MMT1" => "fips_desmovs -f",
+"TCFB64MMT2" => "fips_desmovs -f",
+"TCFB64MMT3" => "fips_desmovs -f",
+"TCFB64Monte1" => "fips_desmovs -f",
+"TCFB64Monte2" => "fips_desmovs -f",
+"TCFB64Monte3" => "fips_desmovs -f",
+"TCFB64permop" => "fips_desmovs -f",
+"TCFB64subtab" => "fips_desmovs -f",
+"TCFB64varkey" => "fips_desmovs -f",
+"TCFB64vartext" => "fips_desmovs -f",
+"TCFB8invperm" => "fips_desmovs -f",
+"TCFB8MMT1" => "fips_desmovs -f",
+"TCFB8MMT2" => "fips_desmovs -f",
+"TCFB8MMT3" => "fips_desmovs -f",
+"TCFB8Monte1" => "fips_desmovs -f",
+"TCFB8Monte2" => "fips_desmovs -f",
+"TCFB8Monte3" => "fips_desmovs -f",
+"TCFB8permop" => "fips_desmovs -f",
+"TCFB8subtab" => "fips_desmovs -f",
+"TCFB8varkey" => "fips_desmovs -f",
+"TCFB8vartext" => "fips_desmovs -f",
+"TECBinvperm" => "fips_desmovs -f",
+"TECBMMT1" => "fips_desmovs -f",
+"TECBMMT2" => "fips_desmovs -f",
+"TECBMMT3" => "fips_desmovs -f",
+"TECBMonte1" => "fips_desmovs -f",
+"TECBMonte2" => "fips_desmovs -f",
+"TECBMonte3" => "fips_desmovs -f",
+"TECBpermop" => "fips_desmovs -f",
+"TECBsubtab" => "fips_desmovs -f",
+"TECBvarkey" => "fips_desmovs -f",
+"TECBvartext" => "fips_desmovs -f",
+"TOFBinvperm" => "fips_desmovs -f",
+"TOFBMMT1" => "fips_desmovs -f",
+"TOFBMMT2" => "fips_desmovs -f",
+"TOFBMMT3" => "fips_desmovs -f",
+"TOFBMonte1" => "fips_desmovs -f",
+"TOFBMonte2" => "fips_desmovs -f",
+"TOFBMonte3" => "fips_desmovs -f",
+"TOFBpermop" => "fips_desmovs -f",
+"TOFBsubtab" => "fips_desmovs -f",
+"TOFBvarkey" => "fips_desmovs -f",
+"TOFBvartext" => "fips_desmovs -f"
+
+);
+my %salt_names = (
+"SigVerPSS (salt 0)" => "SigVerPSS",
+"SigVerPSS (salt 62)" => "SigVerPSS",
+"SigGenPSS (salt 0)" => "SigGenPSS",
+"SigGenPSS (salt 62)" => "SigGenPSS",
+);
+
+
+my $win32 = $^O =~ m/mswin/i;
+my $onedir = 0;
+my $filter = "";
+my $tvdir;
+my $tprefix;
+my $shwrap_prefix;
+my $shwrap;
+my $rmcmd = "rm -rf";
+my $mkcmd = "mkdir";
+my $debug = 0;
+my $quiet = 0;
+my $rspdir = "rsp";
+my $rspignore = 0;
+my @bogus = (); # list of unmatched *.rsp files
+my $bufout = '';
+my $bufdir = '';
+my %_programs = (); # list of external programs to check
+
+foreach (@ARGV)
+ {
+ if ($_ eq "--win32")
+ {
+ $win32 = 1;
+ }
+ elsif ($_ eq "--onedir")
+ {
+ $onedir = 1;
+ }
+ elsif ($_ eq "--debug")
+ {
+ $debug = 1;
+ }
+ elsif ($_ eq "--quiet")
+ {
+ $quiet = 1;
+ }
+ elsif (/--dir=(.*)$/)
+ {
+ $tvdir = $1;
+ }
+ elsif (/--rspdir=(.*)$/)
+ {
+ $rspdir = $1;
+ }
+ elsif (/--noshwrap$/)
+ {
+ $shwrap = "";
+ }
+ elsif (/--rspignore$/)
+ {
+ $rspignore = 1;
+ }
+ elsif (/--tprefix=(.*)$/)
+ {
+ $tprefix = $1;
+ }
+ elsif (/--shwrap_prefix=(.*)$/)
+ {
+ $shwrap_prefix = $1;
+ }
+ elsif (/--filter=(.*)$/)
+ {
+ $filter = $1;
+ }
+ elsif (/--mkdir=(.*)$/)
+ {
+ $mkcmd = $1;
+ }
+ elsif (/--rm=(.*)$/)
+ {
+ $rmcmd = $1;
+ }
+ elsif (/--outfile=(.*)$/)
+ {
+ $outfile = $1;
+ }
+ else
+ {
+ &Help();
+ exit(1);
+ }
+ }
+
+$tvdir = "." unless defined $tvdir;
+
+if ($win32)
+ {
+ if (!defined $tprefix)
+ {
+ if ($onedir)
+ {
+ $tprefix = ".\\";
+ }
+ else
+ {
+ $tprefix = "..\\out32dll\\";
+ }
+ }
+
+ $bufinit .= <<END;
+\@echo off
+rem Test vector run script
+rem Auto generated by mkfipsscr.pl script
+rem Do not edit
+
+END
+
+ }
+else
+ {
+ if ($onedir)
+ {
+ $tprefix = "./" unless defined $tprefix;
+ $shwrap_prefix = "./" unless defined $shwrap_prefix;
+ }
+ else
+ {
+ $tprefix = "../test/" unless defined $tprefix;
+ $shwrap_prefix = "../util/" unless defined $shwrap_prefix;
+ }
+
+ $shwrap = "${shwrap_prefix}shlib_wrap.sh " unless defined $shwrap;
+
+ $bufinit .= <<END;
+#!/bin/sh
+
+# Test vector run script
+# Auto generated by mkfipsscr.pl script
+# Do not edit
+
+RM="$rmcmd"
+MKDIR="$mkcmd"
+TPREFIX=$tprefix
+END
+
+ }
+my %fips_found;
+foreach (keys %fips_tests)
+ {
+ $fips_found{$_} = 0;
+ }
+my %saltPSS;
+for (keys %salt_names)
+ {
+ $salt_found{$_} = 0;
+ }
+
+recurse_test($win32, $tprefix, $filter, $tvdir);
+
+while (($key, $value) = each %salt_found)
+ {
+ &countentry($key, $value);
+ delete $fips_found{$salt_names{$key}};
+ }
+while (($key, $value) = each %fips_found)
+ {
+ &countentry($key, $value);
+ }
+
+# If no fatal errors write out the script file
+ $outfile = "fipstests.sh" unless defined $outfile;
+ open(OUT, ">$outfile") || die "Error opening $outfile: $!";
+ print OUT $bufinit;
+ if (!$rspignore && @bogus)
+ {
+ print STDERR "ERROR: please remove bogus *.rsp files\n";
+ print OUT <<EOF;
+echo $outfile generation failed due to presence of bogus *.rsp files
+EOF
+ }
+ else
+ {
+ print OUT $bufout;
+ }
+ close OUT;
+
+# Check for external programs
+ for (keys %_programs)
+ {
+ s/ .*$//;
+ -x $_ || print STDERR "WARNING: program $_ not found\n";
+ }
+
+#--------------------------------
+sub Help {
+(my $cmd) = ($0 =~ m#([^/]+)$#);
+ print <<EOF;
+$cmd: generate script for CMVP algorithm tests
+ --debug Enable debug output
+ --dir=<dirname> Optional root for *.req file search
+ --filter=<regexp>
+ --onedir <dirname> Assume all components in current directory
+ --outfile=<filename> Optional name of output script, default fipstests.{sh|bat}
+ --rspdir=<dirname> Name of subdirectories containing *.rsp files, default "resp"
+ --rspignore Ignore any bogus *.rsp files
+ --shwrap_prefix=<prefix>
+ --tprefix=<prefix>
+ --quiet Shhh....
+ --win32 Generate script for Win32 environment
+EOF
+}
+
+#--------------------------------
+sub countentry {
+ my ($key,$value) = @_;
+ if ($value == 0)
+ {
+ print STDERR "WARNING: test file $key not found\n" unless $quiet;
+ }
+ elsif ($value > 1)
+ {
+ print STDERR "WARNING: test file $key found $value times\n" unless $quiet;
+ }
+ else
+ {
+ print STDERR "Found test file $key\n" if $debug;
+ }
+ }
+
+#--------------------------------
+sub recurse_test
+ {
+ my ($win32, $tprefix, $filter, $dir) = @_;
+ my $dirh;
+ opendir($dirh, $dir);
+ while ($_ = readdir($dirh))
+ {
+ next if ($_ eq "." || $_ eq "..");
+ $_ = "$dir/$_";
+ if (-f "$_")
+ {
+ if (/\/([^\/]*)\.rsp$/)
+ {
+ if (exists $fips_tests{$1})
+ {
+ $debug && print "DEBUG: $1 found, will be overwritten\n";
+ }
+ else
+ {
+ print STDERR "ERROR: bogus file $_\n";
+ push @bogus, $_;
+ }
+ }
+ next unless /$filter.*\.req$/i;
+ if (/\/([^\/]*)\.req$/ && exists $fips_tests{$1})
+ {
+ $fips_found{$1}++;
+ test_line($win32, $_, $tprefix, $1);
+ }
+ elsif (! /SHAmix\.req$/)
+ {
+ print STDERR "WARNING: unrecognized filename $_\n";
+ }
+ }
+ elsif (-d "$_")
+ {
+ if (/$filter.*req$/i)
+ {
+ test_dir($win32, $_);
+ }
+ recurse_test($win32, $tprefix, $filter, $_);
+ }
+ }
+ closedir($dirh);
+ }
+
+#--------------------------------
+sub test_dir
+ {
+ my ($win32, $req) = @_;
+ my $rsp = $req;
+ $rsp =~ s/req$/$rspdir/;
+ if ($win32)
+ {
+ $rsp =~ tr|/|\\|;
+ $req =~ tr|/|\\|;
+ $bufdir = <<END;
+
+echo Running tests in $req
+if exist "$rsp" rd /s /q "$rsp"
+md "$rsp"
+END
+ }
+ else
+ {
+ $bufdir = <<END;
+
+echo Running tests in "$req"
+\$RM "$rsp"
+\$MKDIR "$rsp"
+
+END
+ }
+ }
+
+#--------------------------------
+sub test_line
+ {
+ my ($win32, $req, $tprefix, $tnam) = @_;
+ my $rsp = $req;
+ my $tcmd = $fips_tests{$tnam};
+
+ $bufout .= $bufdir;
+ $bufdir = "";
+
+ $rsp =~ s/req\/([^\/]*).req$/$rspdir\/$1.rsp/;
+ if ($tcmd =~ /-f$/)
+ {
+ if ($win32)
+ {
+ $req =~ tr|/|\\|;
+ $rsp =~ tr|/|\\|;
+ $bufout .= "$tprefix$tcmd \"$req\" \"$rsp\"\n";
+ $_programs{"$tprefix$tcmd.exe"} = 1;
+ }
+ else
+ {
+ $bufout .= <<END;
+${shwrap}\${TPREFIX}$tcmd "$req" "$rsp" || { echo "$req failure" ; exit 1
+}
+END
+ $_programs{"${shwrap_prefix}shlib_wrap.sh"} = 1;
+ $_programs{"$tprefix$tcmd"} = 1;
+ }
+ return;
+ }
+ if ($tcmd =~ /SALT$/)
+ {
+ open (IN, $req) || die "Can't Open File $req";
+ my $saltlen;
+ while (<IN>)
+ {
+ if (/^\s*#\s*salt\s+len:\s+(\d+)\s*$/i)
+ {
+ my $sl = $1;
+ print STDERR "$req salt length $sl\n" if $debug;
+ $tcmd =~ s/SALT$/$sl/;
+ $salt_found{"$tnam (salt $sl)"}++;
+ last;
+ }
+ }
+ close IN;
+ if ($tcmd =~ /SALT$/)
+ {
+ die "Can't detect salt length for $req";
+ }
+ }
+
+ if ($win32)
+ {
+ $req =~ tr|/|\\|;
+ $rsp =~ tr|/|\\|;
+ $bufout .= "$tprefix$tcmd < \"$req\" > \"$rsp\"\n";
+ $_programs{"$tprefix$tcmd.exe"} = 1;
+ }
+ else
+ {
+ $bufout .= <<END;
+${shwrap}\${TPREFIX}$tcmd < "$req" > "$rsp" || { echo "$req failure" ; exit 1; }
+END
+ $_programs{"$tprefix$tcmd"} = 1;
+ }
+ }
+
diff --git a/crypto/openssl/fips/openssl_fips_fingerprint b/crypto/openssl/fips/openssl_fips_fingerprint
new file mode 100755
index 0000000..f59a67d
--- /dev/null
+++ b/crypto/openssl/fips/openssl_fips_fingerprint
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# Check the library fingerprint and generate an executable fingerprint, or
+# return an error
+
+lib=$1
+exe=$2
+ext=${HMAC_EXT:-sha1}
+
+# deal with the case where we're run from within the build and OpenSSL is
+# not yet installed. Also, make sure LD_LIBRARY_PATH is properly set in
+# case shared libraries are built.
+if [ "X$TOP" != "X" ]
+then
+ if test "$OSTYPE" = msdosdjgpp; then
+ PATH="$TOP/apps;$TOP;$PATH"
+ else
+ PATH="$TOP/apps:$TOP:$PATH"
+ fi
+ LD_LIBRARY_PATH=$TOP; export LD_LIBRARY_PATH
+else
+ LD_LIBRARY_PATH=.; export LD_LIBRARY_PATH
+fi
+
+echo "Checking library fingerprint for $lib"
+openssl sha1 -hmac etaonrishdlcupfm $lib | sed "s/(.*\//(/" | diff -w $lib.sha1 - || { echo "$libs fingerprint mismatch"; exit 1; }
+
+[ -x $exe.exe ] && exe=$exe.exe
+
+echo "Making fingerprint for $exe"
+openssl sha1 -hmac etaonrishdlcupfm -binary $exe > $exe.$ext || rm $exe.$ext
diff --git a/crypto/openssl/fips/rand/Makefile b/crypto/openssl/fips/rand/Makefile
new file mode 100644
index 0000000..20303c8
--- /dev/null
+++ b/crypto/openssl/fips/rand/Makefile
@@ -0,0 +1,149 @@
+#
+# OpenSSL/fips/rand/Makefile
+#
+
+DIR= rand
+TOP= ../..
+CC= cc
+INCLUDES=
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile
+AR= ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST= fips_randtest.c fips_rngvs.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=fips_rand.c fips_rand_selftest.c
+LIBOBJ=fips_rand.o fips_rand_selftest.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= fips_rand.h
+HEADER= $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd $(TOP); $(MAKE) DIRS=fips SDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ @echo $(LIBOBJ) > lib
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
+
+install:
+ @headerlist="$(EXHEADER)"; for i in $$headerlist; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+Q=../testvectors/rng/req
+A=../testvectors/rng/rsp
+
+fips_test:
+ -rm -rf $(A)
+ mkdir $(A)
+ if [ -f $(Q)/ANSI931_AES128MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES128MCT.req > $(A)/ANSI931_AES128MCT.rsp; fi
+ if [ -f $(Q)/ANSI931_AES192MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES192MCT.req > $(A)/ANSI931_AES192MCT.rsp; fi
+ if [ -f $(Q)/ANSI931_AES256MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES256MCT.req > $(A)/ANSI931_AES256MCT.rsp; fi
+ if [ -f $(Q)/ANSI931_AES128VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES128VST.req > $(A)/ANSI931_AES128VST.rsp; fi
+ if [ -f $(Q)/ANSI931_AES192VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES192VST.req > $(A)/ANSI931_AES192VST.rsp; fi
+ if [ -f $(Q)/ANSI931_AES256VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES256VST.req > $(A)/ANSI931_AES256VST.rsp; fi
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+fips_rand.o: ../../e_os.h ../../include/openssl/aes.h
+fips_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_rand.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+fips_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rand.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_rand.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+fips_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+fips_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rand.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+fips_rand.o: ../fips_locl.h fips_rand.c
+fips_rand_selftest.o: ../../include/openssl/bio.h
+fips_rand_selftest.o: ../../include/openssl/crypto.h
+fips_rand_selftest.o: ../../include/openssl/des.h
+fips_rand_selftest.o: ../../include/openssl/des_old.h
+fips_rand_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rand_selftest.o: ../../include/openssl/fips.h
+fips_rand_selftest.o: ../../include/openssl/fips_rand.h
+fips_rand_selftest.o: ../../include/openssl/lhash.h
+fips_rand_selftest.o: ../../include/openssl/opensslconf.h
+fips_rand_selftest.o: ../../include/openssl/opensslv.h
+fips_rand_selftest.o: ../../include/openssl/ossl_typ.h
+fips_rand_selftest.o: ../../include/openssl/rand.h
+fips_rand_selftest.o: ../../include/openssl/safestack.h
+fips_rand_selftest.o: ../../include/openssl/stack.h
+fips_rand_selftest.o: ../../include/openssl/symhacks.h
+fips_rand_selftest.o: ../../include/openssl/ui.h
+fips_rand_selftest.o: ../../include/openssl/ui_compat.h fips_rand_selftest.c
+fips_randtest.o: ../../e_os.h ../../include/openssl/bio.h
+fips_randtest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_randtest.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+fips_randtest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_randtest.o: ../../include/openssl/fips_rand.h
+fips_randtest.o: ../../include/openssl/lhash.h
+fips_randtest.o: ../../include/openssl/opensslconf.h
+fips_randtest.o: ../../include/openssl/opensslv.h
+fips_randtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_randtest.o: ../../include/openssl/safestack.h
+fips_randtest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_randtest.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+fips_randtest.o: ../fips_utl.h fips_randtest.c
+fips_rngvs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rngvs.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+fips_rngvs.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+fips_rngvs.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+fips_rngvs.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_rngvs.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+fips_rngvs.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+fips_rngvs.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rngvs.o: ../../include/openssl/fips_rand.h ../../include/openssl/lhash.h
+fips_rngvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_rngvs.o: ../../include/openssl/opensslconf.h
+fips_rngvs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips_rngvs.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+fips_rngvs.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+fips_rngvs.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rngvs.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+fips_rngvs.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+fips_rngvs.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rngvs.c
diff --git a/crypto/openssl/fips/rand/fips_rand.c b/crypto/openssl/fips/rand/fips_rand.c
new file mode 100644
index 0000000..9492b15
--- /dev/null
+++ b/crypto/openssl/fips/rand/fips_rand.c
@@ -0,0 +1,410 @@
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * This is a FIPS approved AES PRNG based on ANSI X9.31 A.2.4.
+ */
+
+#include "e_os.h"
+
+/* If we don't define _XOPEN_SOURCE_EXTENDED, struct timeval won't
+ be defined and gettimeofday() won't be declared with strict compilers
+ like DEC C in ANSI C mode. */
+#ifndef _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_SOURCE_EXTENDED 1
+#endif
+
+#include <openssl/rand.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include <openssl/fips_rand.h>
+#ifndef OPENSSL_SYS_WIN32
+#include <sys/time.h>
+#endif
+#include <assert.h>
+#ifndef OPENSSL_SYS_WIN32
+# ifdef OPENSSL_UNISTD
+# include OPENSSL_UNISTD
+# else
+# include <unistd.h>
+# endif
+#endif
+#include <string.h>
+#include <openssl/fips.h>
+#include "fips_locl.h"
+
+#ifdef OPENSSL_FIPS
+
+void *OPENSSL_stderr(void);
+
+#define AES_BLOCK_LENGTH 16
+
+
+/* AES FIPS PRNG implementation */
+
+typedef struct
+ {
+ int seeded;
+ int keyed;
+ int test_mode;
+ int second;
+ int error;
+ unsigned long counter;
+ AES_KEY ks;
+ int vpos;
+ /* Temporary storage for key if it equals seed length */
+ unsigned char tmp_key[AES_BLOCK_LENGTH];
+ unsigned char V[AES_BLOCK_LENGTH];
+ unsigned char DT[AES_BLOCK_LENGTH];
+ unsigned char last[AES_BLOCK_LENGTH];
+ } FIPS_PRNG_CTX;
+
+static FIPS_PRNG_CTX sctx;
+
+static int fips_prng_fail = 0;
+
+void FIPS_rng_stick(void)
+ {
+ fips_prng_fail = 1;
+ }
+
+static void fips_rand_prng_reset(FIPS_PRNG_CTX *ctx)
+ {
+ ctx->seeded = 0;
+ ctx->keyed = 0;
+ ctx->test_mode = 0;
+ ctx->counter = 0;
+ ctx->second = 0;
+ ctx->error = 0;
+ ctx->vpos = 0;
+ OPENSSL_cleanse(ctx->V, AES_BLOCK_LENGTH);
+ OPENSSL_cleanse(&ctx->ks, sizeof(AES_KEY));
+ }
+
+
+static int fips_set_prng_key(FIPS_PRNG_CTX *ctx,
+ const unsigned char *key, FIPS_RAND_SIZE_T keylen)
+ {
+ FIPS_selftest_check();
+ if (keylen != 16 && keylen != 24 && keylen != 32)
+ {
+ /* error: invalid key size */
+ return 0;
+ }
+ AES_set_encrypt_key(key, keylen << 3, &ctx->ks);
+ if (keylen == 16)
+ {
+ memcpy(ctx->tmp_key, key, 16);
+ ctx->keyed = 2;
+ }
+ else
+ ctx->keyed = 1;
+ ctx->seeded = 0;
+ ctx->second = 0;
+ return 1;
+ }
+
+static int fips_set_prng_seed(FIPS_PRNG_CTX *ctx,
+ const unsigned char *seed, FIPS_RAND_SIZE_T seedlen)
+ {
+ int i;
+ if (!ctx->keyed)
+ return 0;
+ /* In test mode seed is just supplied data */
+ if (ctx->test_mode)
+ {
+ if (seedlen != AES_BLOCK_LENGTH)
+ return 0;
+ memcpy(ctx->V, seed, AES_BLOCK_LENGTH);
+ ctx->seeded = 1;
+ return 1;
+ }
+ /* Outside test mode XOR supplied data with existing seed */
+ for (i = 0; i < seedlen; i++)
+ {
+ ctx->V[ctx->vpos++] ^= seed[i];
+ if (ctx->vpos == AES_BLOCK_LENGTH)
+ {
+ ctx->vpos = 0;
+ /* Special case if first seed and key length equals
+ * block size check key and seed do not match.
+ */
+ if (ctx->keyed == 2)
+ {
+ if (!memcmp(ctx->tmp_key, ctx->V, 16))
+ {
+ RANDerr(RAND_F_FIPS_SET_PRNG_SEED,
+ RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY);
+ return 0;
+ }
+ OPENSSL_cleanse(ctx->tmp_key, 16);
+ ctx->keyed = 1;
+ }
+ ctx->seeded = 1;
+ }
+ }
+ return 1;
+ }
+
+static int fips_set_test_mode(FIPS_PRNG_CTX *ctx)
+ {
+ if (ctx->keyed)
+ {
+ RANDerr(RAND_F_FIPS_SET_TEST_MODE,RAND_R_PRNG_KEYED);
+ return 0;
+ }
+ ctx->test_mode = 1;
+ return 1;
+ }
+
+int FIPS_rand_test_mode(void)
+ {
+ return fips_set_test_mode(&sctx);
+ }
+
+int FIPS_rand_set_dt(unsigned char *dt)
+ {
+ if (!sctx.test_mode)
+ {
+ RANDerr(RAND_F_FIPS_RAND_SET_DT,RAND_R_NOT_IN_TEST_MODE);
+ return 0;
+ }
+ memcpy(sctx.DT, dt, AES_BLOCK_LENGTH);
+ return 1;
+ }
+
+static void fips_get_dt(FIPS_PRNG_CTX *ctx)
+ {
+#ifdef OPENSSL_SYS_WIN32
+ FILETIME ft;
+#else
+ struct timeval tv;
+#endif
+ unsigned char *buf = ctx->DT;
+
+#ifndef GETPID_IS_MEANINGLESS
+ unsigned long pid;
+#endif
+
+#ifdef OPENSSL_SYS_WIN32
+ GetSystemTimeAsFileTime(&ft);
+ buf[0] = (unsigned char) (ft.dwHighDateTime & 0xff);
+ buf[1] = (unsigned char) ((ft.dwHighDateTime >> 8) & 0xff);
+ buf[2] = (unsigned char) ((ft.dwHighDateTime >> 16) & 0xff);
+ buf[3] = (unsigned char) ((ft.dwHighDateTime >> 24) & 0xff);
+ buf[4] = (unsigned char) (ft.dwLowDateTime & 0xff);
+ buf[5] = (unsigned char) ((ft.dwLowDateTime >> 8) & 0xff);
+ buf[6] = (unsigned char) ((ft.dwLowDateTime >> 16) & 0xff);
+ buf[7] = (unsigned char) ((ft.dwLowDateTime >> 24) & 0xff);
+#else
+ gettimeofday(&tv,NULL);
+ buf[0] = (unsigned char) (tv.tv_sec & 0xff);
+ buf[1] = (unsigned char) ((tv.tv_sec >> 8) & 0xff);
+ buf[2] = (unsigned char) ((tv.tv_sec >> 16) & 0xff);
+ buf[3] = (unsigned char) ((tv.tv_sec >> 24) & 0xff);
+ buf[4] = (unsigned char) (tv.tv_usec & 0xff);
+ buf[5] = (unsigned char) ((tv.tv_usec >> 8) & 0xff);
+ buf[6] = (unsigned char) ((tv.tv_usec >> 16) & 0xff);
+ buf[7] = (unsigned char) ((tv.tv_usec >> 24) & 0xff);
+#endif
+ buf[8] = (unsigned char) (ctx->counter & 0xff);
+ buf[9] = (unsigned char) ((ctx->counter >> 8) & 0xff);
+ buf[10] = (unsigned char) ((ctx->counter >> 16) & 0xff);
+ buf[11] = (unsigned char) ((ctx->counter >> 24) & 0xff);
+
+ ctx->counter++;
+
+
+#ifndef GETPID_IS_MEANINGLESS
+ pid=(unsigned long)getpid();
+ buf[12] = (unsigned char) (pid & 0xff);
+ buf[13] = (unsigned char) ((pid >> 8) & 0xff);
+ buf[14] = (unsigned char) ((pid >> 16) & 0xff);
+ buf[15] = (unsigned char) ((pid >> 24) & 0xff);
+#endif
+ }
+
+static int fips_rand(FIPS_PRNG_CTX *ctx,
+ unsigned char *out, FIPS_RAND_SIZE_T outlen)
+ {
+ unsigned char R[AES_BLOCK_LENGTH], I[AES_BLOCK_LENGTH];
+ unsigned char tmp[AES_BLOCK_LENGTH];
+ int i;
+ if (ctx->error)
+ {
+ RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_ERROR);
+ return 0;
+ }
+ if (!ctx->keyed)
+ {
+ RANDerr(RAND_F_FIPS_RAND,RAND_R_NO_KEY_SET);
+ return 0;
+ }
+ if (!ctx->seeded)
+ {
+ RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_NOT_SEEDED);
+ return 0;
+ }
+ for (;;)
+ {
+ if (!ctx->test_mode)
+ fips_get_dt(ctx);
+ AES_encrypt(ctx->DT, I, &ctx->ks);
+ for (i = 0; i < AES_BLOCK_LENGTH; i++)
+ tmp[i] = I[i] ^ ctx->V[i];
+ AES_encrypt(tmp, R, &ctx->ks);
+ for (i = 0; i < AES_BLOCK_LENGTH; i++)
+ tmp[i] = R[i] ^ I[i];
+ AES_encrypt(tmp, ctx->V, &ctx->ks);
+ /* Continuous PRNG test */
+ if (ctx->second)
+ {
+ if (fips_prng_fail)
+ memcpy(ctx->last, R, AES_BLOCK_LENGTH);
+ if (!memcmp(R, ctx->last, AES_BLOCK_LENGTH))
+ {
+ RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_STUCK);
+ ctx->error = 1;
+ fips_set_selftest_fail();
+ return 0;
+ }
+ }
+ memcpy(ctx->last, R, AES_BLOCK_LENGTH);
+ if (!ctx->second)
+ {
+ ctx->second = 1;
+ if (!ctx->test_mode)
+ continue;
+ }
+
+ if (outlen <= AES_BLOCK_LENGTH)
+ {
+ memcpy(out, R, outlen);
+ break;
+ }
+
+ memcpy(out, R, AES_BLOCK_LENGTH);
+ out += AES_BLOCK_LENGTH;
+ outlen -= AES_BLOCK_LENGTH;
+ }
+ return 1;
+ }
+
+
+int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen)
+ {
+ int ret;
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ ret = fips_set_prng_key(&sctx, key, keylen);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ return ret;
+ }
+
+int FIPS_rand_seed(const void *seed, FIPS_RAND_SIZE_T seedlen)
+ {
+ int ret;
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ ret = fips_set_prng_seed(&sctx, seed, seedlen);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ return ret;
+ }
+
+
+int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T count)
+ {
+ int ret;
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ ret = fips_rand(&sctx, out, count);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ return ret;
+ }
+
+int FIPS_rand_status(void)
+ {
+ int ret;
+ CRYPTO_r_lock(CRYPTO_LOCK_RAND);
+ ret = sctx.seeded;
+ CRYPTO_r_unlock(CRYPTO_LOCK_RAND);
+ return ret;
+ }
+
+void FIPS_rand_reset(void)
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ fips_rand_prng_reset(&sctx);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ }
+
+static void fips_do_rand_seed(const void *seed, FIPS_RAND_SIZE_T seedlen)
+ {
+ FIPS_rand_seed(seed, seedlen);
+ }
+
+static void fips_do_rand_add(const void *seed, FIPS_RAND_SIZE_T seedlen,
+ double add_entropy)
+ {
+ FIPS_rand_seed(seed, seedlen);
+ }
+
+static const RAND_METHOD rand_fips_meth=
+ {
+ fips_do_rand_seed,
+ FIPS_rand_bytes,
+ FIPS_rand_reset,
+ fips_do_rand_add,
+ FIPS_rand_bytes,
+ FIPS_rand_status
+ };
+
+const RAND_METHOD *FIPS_rand_method(void)
+{
+ return &rand_fips_meth;
+}
+
+#endif
diff --git a/crypto/openssl/fips/rand/fips_rand.h b/crypto/openssl/fips/rand/fips_rand.h
new file mode 100644
index 0000000..a175aaf
--- /dev/null
+++ b/crypto/openssl/fips/rand/fips_rand.h
@@ -0,0 +1,77 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef HEADER_FIPS_RAND_H
+#define HEADER_FIPS_RAND_H
+
+#include "des.h"
+
+#ifdef OPENSSL_FIPS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen);
+int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num);
+int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T outlen);
+
+int FIPS_rand_test_mode(void);
+void FIPS_rand_reset(void);
+int FIPS_rand_set_dt(unsigned char *dt);
+
+int FIPS_rand_status(void);
+
+const RAND_METHOD *FIPS_rand_method(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
diff --git a/crypto/openssl/fips/rand/fips_rand_selftest.c b/crypto/openssl/fips/rand/fips_rand_selftest.c
new file mode 100644
index 0000000..2194a76
--- /dev/null
+++ b/crypto/openssl/fips/rand/fips_rand_selftest.c
@@ -0,0 +1,371 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+
+#ifdef OPENSSL_FIPS
+
+
+
+typedef struct
+ {
+ unsigned char DT[16];
+ unsigned char V[16];
+ unsigned char R[16];
+ } AES_PRNG_TV;
+
+/* The following test vectors are taken directly from the RGNVS spec */
+
+static unsigned char aes_128_key[16] =
+ {0xf3,0xb1,0x66,0x6d,0x13,0x60,0x72,0x42,
+ 0xed,0x06,0x1c,0xab,0xb8,0xd4,0x62,0x02};
+
+static AES_PRNG_TV aes_128_tv[] = {
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xf9},
+ /* V */
+ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x59,0x53,0x1e,0xd1,0x3b,0xb0,0xc0,0x55,
+ 0x84,0x79,0x66,0x85,0xc1,0x2f,0x76,0x41}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfa},
+ /* V */
+ {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x7c,0x22,0x2c,0xf4,0xca,0x8f,0xa2,0x4c,
+ 0x1c,0x9c,0xb6,0x41,0xa9,0xf3,0x22,0x0d}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfb},
+ /* V */
+ {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x8a,0xaa,0x00,0x39,0x66,0x67,0x5b,0xe5,
+ 0x29,0x14,0x28,0x81,0xa9,0x4d,0x4e,0xc7}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfc},
+ /* V */
+ {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x88,0xdd,0xa4,0x56,0x30,0x24,0x23,0xe5,
+ 0xf6,0x9d,0xa5,0x7e,0x7b,0x95,0xc7,0x3a}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfd},
+ /* V */
+ {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x05,0x25,0x92,0x46,0x61,0x79,0xd2,0xcb,
+ 0x78,0xc4,0x0b,0x14,0x0a,0x5a,0x9a,0xc8}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x77},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
+ /* R */
+ {0x0d,0xd5,0xa0,0x36,0x7a,0x59,0x26,0xbc,
+ 0x48,0xd9,0x38,0xbf,0xf0,0x85,0x8f,0xea}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x78},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+ /* R */
+ {0xae,0x53,0x87,0xee,0x8c,0xd9,0x12,0xf5,
+ 0x73,0x53,0xae,0x03,0xf9,0xd5,0x13,0x33}
+ },
+};
+
+static unsigned char aes_192_key[24] =
+ {0x15,0xd8,0x78,0x0d,0x62,0xd3,0x25,0x6e,
+ 0x44,0x64,0x10,0x13,0x60,0x2b,0xa9,0xbc,
+ 0x4a,0xfb,0xca,0xeb,0x4c,0x8b,0x99,0x3b};
+
+static AES_PRNG_TV aes_192_tv[] = {
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4b},
+ /* V */
+ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x17,0x07,0xd5,0x28,0x19,0x79,0x1e,0xef,
+ 0xa5,0x0c,0xbf,0x25,0xe5,0x56,0xb4,0x93}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4c},
+ /* V */
+ {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x92,0x8d,0xbe,0x07,0xdd,0xc7,0x58,0xc0,
+ 0x6f,0x35,0x41,0x9b,0x17,0xc9,0xbd,0x9b}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4d},
+ /* V */
+ {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0xd5,0xde,0xf4,0x50,0xf3,0xb7,0x10,0x4e,
+ 0xb8,0xc6,0xf8,0xcf,0xe2,0xb1,0xca,0xa2}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4e},
+ /* V */
+ {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0xce,0x29,0x08,0x43,0xfc,0x34,0x41,0xe7,
+ 0x47,0x8f,0xb3,0x66,0x2b,0x46,0xb1,0xbb}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4f},
+ /* V */
+ {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0xb3,0x26,0x0f,0xf5,0xd6,0xca,0xa8,0xbf,
+ 0x89,0xb8,0x5e,0x2f,0x22,0x56,0x92,0x2f}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xc9},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
+ /* R */
+ {0x05,0xeb,0x18,0x52,0x34,0x43,0x00,0x43,
+ 0x6e,0x5a,0xa5,0xfe,0x7b,0x32,0xc4,0x2d}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xca},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+ /* R */
+ {0x15,0x3c,0xe8,0xd1,0x04,0xc7,0xad,0x50,
+ 0x0b,0xf0,0x07,0x16,0xe7,0x56,0x7a,0xea}
+ },
+};
+
+static unsigned char aes_256_key[32] =
+ {0x6d,0x14,0x06,0x6c,0xb6,0xd8,0x21,0x2d,
+ 0x82,0x8d,0xfa,0xf2,0x7a,0x03,0xb7,0x9f,
+ 0x0c,0xc7,0x3e,0xcd,0x76,0xeb,0xee,0xb5,
+ 0x21,0x05,0x8c,0x4f,0x31,0x7a,0x80,0xbb};
+
+static AES_PRNG_TV aes_256_tv[] = {
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x88},
+ /* V */
+ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x35,0xc7,0xef,0xa7,0x78,0x4d,0x29,0xbc,
+ 0x82,0x79,0x99,0xfb,0xd0,0xb3,0x3b,0x72}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x89},
+ /* V */
+ {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x6c,0xf4,0x42,0x5d,0xc7,0x04,0x1a,0x41,
+ 0x28,0x2a,0x78,0xa9,0xb0,0x12,0xc4,0x95}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8a},
+ /* V */
+ {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x16,0x90,0xa4,0xff,0x7b,0x7e,0xb9,0x30,
+ 0xdb,0x67,0x4b,0xac,0x2d,0xe1,0xd1,0x75}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8b},
+ /* V */
+ {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x14,0x6f,0xf5,0x95,0xa1,0x46,0x65,0x30,
+ 0xbc,0x57,0xe2,0x4a,0xf7,0x45,0x62,0x05}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8c},
+ /* V */
+ {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x96,0xe2,0xb4,0x1e,0x66,0x5e,0x0f,0xa4,
+ 0xc5,0xcd,0xa2,0x07,0xcc,0xb7,0x94,0x40}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x06},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
+ /* R */
+ {0x61,0xce,0x1d,0x6a,0x48,0x75,0x97,0x28,
+ 0x4b,0x41,0xde,0x18,0x44,0x4f,0x56,0xec}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x07},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+ /* R */
+ {0x52,0x89,0x59,0x79,0x2d,0xaa,0x28,0xb3,
+ 0xb0,0x8a,0x3e,0x70,0xfa,0x71,0x59,0x84}
+ },
+};
+
+
+void FIPS_corrupt_rng()
+ {
+ aes_192_tv[0].V[0]++;
+ }
+
+#define fips_rand_test(key, tv) \
+ do_rand_test(key, sizeof key, tv, sizeof(tv)/sizeof(AES_PRNG_TV))
+
+static int do_rand_test(unsigned char *key, int keylen,
+ AES_PRNG_TV *tv, int ntv)
+ {
+ unsigned char R[16];
+ int i;
+ if (!FIPS_rand_set_key(key, keylen))
+ return 0;
+ for (i = 0; i < ntv; i++)
+ {
+ FIPS_rand_seed(tv[i].V, 16);
+ FIPS_rand_set_dt(tv[i].DT);
+ FIPS_rand_bytes(R, 16);
+ if (memcmp(R, tv[i].R, 16))
+ return 0;
+ }
+ return 1;
+ }
+
+
+int FIPS_selftest_rng()
+ {
+ FIPS_rand_reset();
+ if (!FIPS_rand_test_mode())
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+ if (!fips_rand_test(aes_128_key,aes_128_tv)
+ || !fips_rand_test(aes_192_key, aes_192_tv)
+ || !fips_rand_test(aes_256_key, aes_256_tv))
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+ FIPS_rand_reset();
+ return 1;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/rand/fips_randtest.c b/crypto/openssl/fips/rand/fips_randtest.c
new file mode 100644
index 0000000..5582941
--- /dev/null
+++ b/crypto/openssl/fips/rand/fips_randtest.c
@@ -0,0 +1,248 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+#include "e_os.h"
+
+#ifndef OPENSSL_FIPS
+int main(int argc, char *argv[])
+{
+ printf("No FIPS RAND support\n");
+ return(0);
+}
+
+#else
+
+#include "fips_utl.h"
+
+typedef struct
+ {
+ unsigned char DT[16];
+ unsigned char V[16];
+ unsigned char R[16];
+ } AES_PRNG_MCT;
+
+static unsigned char aes_128_mct_key[16] =
+ {0x9f,0x5b,0x51,0x20,0x0b,0xf3,0x34,0xb5,
+ 0xd8,0x2b,0xe8,0xc3,0x72,0x55,0xc8,0x48};
+
+static AES_PRNG_MCT aes_128_mct_tv = {
+ /* DT */
+ {0x63,0x76,0xbb,0xe5,0x29,0x02,0xba,0x3b,
+ 0x67,0xc9,0x25,0xfa,0x70,0x1f,0x11,0xac},
+ /* V */
+ {0x57,0x2c,0x8e,0x76,0x87,0x26,0x47,0x97,
+ 0x7e,0x74,0xfb,0xdd,0xc4,0x95,0x01,0xd1},
+ /* R */
+ {0x48,0xe9,0xbd,0x0d,0x06,0xee,0x18,0xfb,
+ 0xe4,0x57,0x90,0xd5,0xc3,0xfc,0x9b,0x73}
+};
+
+static unsigned char aes_192_mct_key[24] =
+ {0xb7,0x6c,0x34,0xd1,0x09,0x67,0xab,0x73,
+ 0x4d,0x5a,0xd5,0x34,0x98,0x16,0x0b,0x91,
+ 0xbc,0x35,0x51,0x16,0x6b,0xae,0x93,0x8a};
+
+static AES_PRNG_MCT aes_192_mct_tv = {
+ /* DT */
+ {0x84,0xce,0x22,0x7d,0x91,0x5a,0xa3,0xc9,
+ 0x84,0x3c,0x0a,0xb3,0xa9,0x63,0x15,0x52},
+ /* V */
+ {0xb6,0xaf,0xe6,0x8f,0x99,0x9e,0x90,0x64,
+ 0xdd,0xc7,0x7a,0xc1,0xbb,0x90,0x3a,0x6d},
+ /* R */
+ {0xfc,0x85,0x60,0x9a,0x29,0x6f,0xef,0x21,
+ 0xdd,0x86,0x20,0x32,0x8a,0x29,0x6f,0x47}
+};
+
+static unsigned char aes_256_mct_key[32] =
+ {0x9b,0x05,0xc8,0x68,0xff,0x47,0xf8,0x3a,
+ 0xa6,0x3a,0xa8,0xcb,0x4e,0x71,0xb2,0xe0,
+ 0xb8,0x7e,0xf1,0x37,0xb6,0xb4,0xf6,0x6d,
+ 0x86,0x32,0xfc,0x1f,0x5e,0x1d,0x1e,0x50};
+
+static AES_PRNG_MCT aes_256_mct_tv = {
+ /* DT */
+ {0x31,0x6e,0x35,0x9a,0xb1,0x44,0xf0,0xee,
+ 0x62,0x6d,0x04,0x46,0xe0,0xa3,0x92,0x4c},
+ /* V */
+ {0x4f,0xcd,0xc1,0x87,0x82,0x1f,0x4d,0xa1,
+ 0x3e,0x0e,0x56,0x44,0x59,0xe8,0x83,0xca},
+ /* R */
+ {0xc8,0x87,0xc2,0x61,0x5b,0xd0,0xb9,0xe1,
+ 0xe7,0xf3,0x8b,0xd7,0x5b,0xd5,0xf1,0x8d}
+};
+
+static void dump(const unsigned char *b,int n)
+ {
+ while(n-- > 0)
+ {
+ printf(" %02x",*b++);
+ }
+ }
+
+static void compare(const unsigned char *result,const unsigned char *expected,
+ int n)
+ {
+ int i;
+
+ for(i=0 ; i < n ; ++i)
+ if(result[i] != expected[i])
+ {
+ puts("Random test failed, got:");
+ dump(result,n);
+ puts("\n expected:");
+ dump(expected,n);
+ putchar('\n');
+ EXIT(1);
+ }
+ }
+
+
+static void run_test(unsigned char *key, int keylen, AES_PRNG_MCT *tv)
+ {
+ unsigned char buf[16], dt[16];
+ int i, j;
+ FIPS_rand_reset();
+ FIPS_rand_test_mode();
+ FIPS_rand_set_key(key, keylen);
+ FIPS_rand_seed(tv->V, 16);
+ memcpy(dt, tv->DT, 16);
+ for (i = 0; i < 10000; i++)
+ {
+ FIPS_rand_set_dt(dt);
+ FIPS_rand_bytes(buf, 16);
+ /* Increment DT */
+ for (j = 15; j >= 0; j--)
+ {
+ dt[j]++;
+ if (dt[j])
+ break;
+ }
+ }
+
+ compare(buf,tv->R, 16);
+ }
+
+int main()
+ {
+ run_test(aes_128_mct_key, 16, &aes_128_mct_tv);
+ printf("FIPS PRNG test 1 done\n");
+ run_test(aes_192_mct_key, 24, &aes_192_mct_tv);
+ printf("FIPS PRNG test 2 done\n");
+ run_test(aes_256_mct_key, 32, &aes_256_mct_tv);
+ printf("FIPS PRNG test 3 done\n");
+ return 0;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/rand/fips_rngvs.c b/crypto/openssl/fips/rand/fips_rngvs.c
new file mode 100644
index 0000000..80a8017
--- /dev/null
+++ b/crypto/openssl/fips/rand/fips_rngvs.c
@@ -0,0 +1,230 @@
+/*
+ * Crude test driver for processing the VST and MCT testvector files
+ * generated by the CMVP RNGVS product.
+ *
+ * Note the input files are assumed to have a _very_ specific format
+ * as described in the NIST document "The Random Number Generator
+ * Validation System (RNGVS)", May 25, 2004.
+ *
+ */
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_FIPS
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ printf("No FIPS RNG support\n");
+ return 0;
+}
+#else
+
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#include <openssl/x509v3.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "fips_utl.h"
+
+static void vst()
+ {
+ unsigned char *key = NULL;
+ unsigned char *v = NULL;
+ unsigned char *dt = NULL;
+ unsigned char ret[16];
+ char buf[1024];
+ char lbuf[1024];
+ char *keyword, *value;
+ long i, keylen;
+
+ keylen = 0;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ fputs(buf,stdout);
+ if(!strncmp(buf,"[AES 128-Key]", 13))
+ keylen = 16;
+ else if(!strncmp(buf,"[AES 192-Key]", 13))
+ keylen = 24;
+ else if(!strncmp(buf,"[AES 256-Key]", 13))
+ keylen = 32;
+ if (!parse_line(&keyword, &value, lbuf, buf))
+ continue;
+ if(!strcmp(keyword,"Key"))
+ {
+ key=hex2bin_m(value,&i);
+ if (i != keylen)
+ {
+ fprintf(stderr, "Invalid key length, expecting %ld\n", keylen);
+ return;
+ }
+ }
+ else if(!strcmp(keyword,"DT"))
+ {
+ dt=hex2bin_m(value,&i);
+ if (i != 16)
+ {
+ fprintf(stderr, "Invalid DT length\n");
+ return;
+ }
+ }
+ else if(!strcmp(keyword,"V"))
+ {
+ v=hex2bin_m(value,&i);
+ if (i != 16)
+ {
+ fprintf(stderr, "Invalid V length\n");
+ return;
+ }
+
+ if (!key || !dt)
+ {
+ fprintf(stderr, "Missing key or DT\n");
+ return;
+ }
+
+ FIPS_rand_set_key(key, keylen);
+ FIPS_rand_seed(v,16);
+ FIPS_rand_set_dt(dt);
+ if (FIPS_rand_bytes(ret,16) <= 0)
+ {
+ fprintf(stderr, "Error getting PRNG value\n");
+ return;
+ }
+
+ pv("R",ret,16);
+ OPENSSL_free(key);
+ key = NULL;
+ OPENSSL_free(dt);
+ dt = NULL;
+ OPENSSL_free(v);
+ v = NULL;
+ }
+ }
+ }
+
+static void mct()
+ {
+ unsigned char *key = NULL;
+ unsigned char *v = NULL;
+ unsigned char *dt = NULL;
+ unsigned char ret[16];
+ char buf[1024];
+ char lbuf[1024];
+ char *keyword, *value;
+ long i, keylen;
+ int j;
+
+ keylen = 0;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ fputs(buf,stdout);
+ if(!strncmp(buf,"[AES 128-Key]", 13))
+ keylen = 16;
+ else if(!strncmp(buf,"[AES 192-Key]", 13))
+ keylen = 24;
+ else if(!strncmp(buf,"[AES 256-Key]", 13))
+ keylen = 32;
+ if (!parse_line(&keyword, &value, lbuf, buf))
+ continue;
+ if(!strcmp(keyword,"Key"))
+ {
+ key=hex2bin_m(value,&i);
+ if (i != keylen)
+ {
+ fprintf(stderr, "Invalid key length, expecting %ld\n", keylen);
+ return;
+ }
+ }
+ else if(!strcmp(keyword,"DT"))
+ {
+ dt=hex2bin_m(value,&i);
+ if (i != 16)
+ {
+ fprintf(stderr, "Invalid DT length\n");
+ return;
+ }
+ }
+ else if(!strcmp(keyword,"V"))
+ {
+ v=hex2bin_m(value,&i);
+ if (i != 16)
+ {
+ fprintf(stderr, "Invalid V length\n");
+ return;
+ }
+
+ if (!key || !dt)
+ {
+ fprintf(stderr, "Missing key or DT\n");
+ return;
+ }
+
+ FIPS_rand_set_key(key, keylen);
+ FIPS_rand_seed(v,16);
+ for (i = 0; i < 10000; i++)
+ {
+ FIPS_rand_set_dt(dt);
+ if (FIPS_rand_bytes(ret,16) <= 0)
+ {
+ fprintf(stderr, "Error getting PRNG value\n");
+ return;
+ }
+ /* Increment DT */
+ for (j = 15; j >= 0; j--)
+ {
+ dt[j]++;
+ if (dt[j])
+ break;
+ }
+ }
+
+ pv("R",ret,16);
+ OPENSSL_free(key);
+ key = NULL;
+ OPENSSL_free(dt);
+ dt = NULL;
+ OPENSSL_free(v);
+ v = NULL;
+ }
+ }
+ }
+
+int main(int argc,char **argv)
+ {
+ if(argc != 2)
+ {
+ fprintf(stderr,"%s [mct|vst]\n",argv[0]);
+ exit(1);
+ }
+ if(!FIPS_mode_set(1))
+ {
+ do_print_errors();
+ exit(1);
+ }
+ FIPS_rand_reset();
+ if (!FIPS_rand_test_mode())
+ {
+ fprintf(stderr, "Error setting PRNG test mode\n");
+ do_print_errors();
+ exit(1);
+ }
+ if(!strcmp(argv[1],"mct"))
+ mct();
+ else if(!strcmp(argv[1],"vst"))
+ vst();
+ else
+ {
+ fprintf(stderr,"Don't know how to %s.\n",argv[1]);
+ exit(1);
+ }
+
+ return 0;
+ }
+#endif
diff --git a/crypto/openssl/fips/rsa/Makefile b/crypto/openssl/fips/rsa/Makefile
new file mode 100644
index 0000000..da28c13
--- /dev/null
+++ b/crypto/openssl/fips/rsa/Makefile
@@ -0,0 +1,215 @@
+#
+# OpenSSL/fips/rsa/Makefile
+#
+
+DIR= rsa
+TOP= ../..
+CC= cc
+INCLUDES=
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile
+AR= ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST= fips_rsavtest.c fips_rsastest.c fips_rsagtest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=fips_rsa_eay.c fips_rsa_gen.c fips_rsa_selftest.c fips_rsa_x931g.c \
+ fips_rsa_sign.c fips_rsa_lib.c
+LIBOBJ=fips_rsa_eay.o fips_rsa_gen.o fips_rsa_selftest.o fips_rsa_x931g.o \
+ fips_rsa_sign.o fips_rsa_lib.o
+
+SRC= $(LIBSRC)
+
+EXHEADER=
+HEADER= $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ @echo $(LIBOBJ) > lib
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
+
+install:
+ @headerlist="$(EXHEADER)"; for i in $$headerlist; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+Q=../testvectors/rsa/req
+A=../testvectors/rsa/rsp
+Q62=../testvectors/rsa_salt_62/req
+A62=../testvectors/rsa_salt_62/rsp
+
+fips_test:
+ -rm -rf $(A) $(A62)
+ mkdir $(A) $(A62)
+ if [ -f $(Q)/SigGen15.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest < $(Q)/SigGen15.req > $(A)/SigGen15.rsp; fi
+ if [ -f $(Q)/SigVer15.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest < $(Q)/SigVer15.req > $(A)/SigVer15.rsp; fi
+ if [ -f $(Q)/SigGenPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -saltlen 0 < $(Q)/SigGenPSS.req > $(A)/SigGenPSS.rsp; fi
+ if [ -f $(Q)/SigVerPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -saltlen 0 < $(Q)/SigVerPSS.req > $(A)/SigVerPSS.rsp; fi
+ if [ -f $(Q)/SigGenRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -x931 < $(Q)/SigGenRSA.req > $(A)/SigGenRSA.rsp; fi
+ if [ -f $(Q)/SigVerRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -x931 < $(Q)/SigVerRSA.req > $(A)/SigVerRSA.rsp; fi
+ if [ -f $(Q62)/SigGenPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -saltlen 62 < $(Q62)/SigGenPSS.req >$(A62)/SigGenPSS.rsp; fi
+ if [ -f $(Q62)/SigVerPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -saltlen 62 <$(Q62)/SigVerPSS.req >$(A62)/SigVerPSS.rsp; fi
+ if [ -f $(Q)/KeyGenRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsagtest < $(Q)/KeyGenRSA.req > $(A)/KeyGenRSA.rsp; fi
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+fips_rsa_eay.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsa_eay.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_rsa_eay.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rsa_eay.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_rsa_eay.o: ../../include/openssl/opensslconf.h
+fips_rsa_eay.o: ../../include/openssl/opensslv.h
+fips_rsa_eay.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_rsa_eay.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+fips_rsa_eay.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rsa_eay.o: fips_rsa_eay.c
+fips_rsa_gen.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsa_gen.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_rsa_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rsa_gen.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_rsa_gen.o: ../../include/openssl/objects.h
+fips_rsa_gen.o: ../../include/openssl/opensslconf.h
+fips_rsa_gen.o: ../../include/openssl/opensslv.h
+fips_rsa_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+fips_rsa_gen.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_rsa_gen.o: ../../include/openssl/symhacks.h ../fips_locl.h fips_rsa_gen.c
+fips_rsa_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsa_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_rsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rsa_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_rsa_lib.o: ../../include/openssl/objects.h
+fips_rsa_lib.o: ../../include/openssl/opensslconf.h
+fips_rsa_lib.o: ../../include/openssl/opensslv.h
+fips_rsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+fips_rsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+fips_rsa_lib.o: ../../include/openssl/symhacks.h fips_rsa_lib.c
+fips_rsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsa_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_rsa_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rsa_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rsa_selftest.o: ../../include/openssl/lhash.h
+fips_rsa_selftest.o: ../../include/openssl/obj_mac.h
+fips_rsa_selftest.o: ../../include/openssl/objects.h
+fips_rsa_selftest.o: ../../include/openssl/opensslconf.h
+fips_rsa_selftest.o: ../../include/openssl/opensslv.h
+fips_rsa_selftest.o: ../../include/openssl/ossl_typ.h
+fips_rsa_selftest.o: ../../include/openssl/rsa.h
+fips_rsa_selftest.o: ../../include/openssl/safestack.h
+fips_rsa_selftest.o: ../../include/openssl/stack.h
+fips_rsa_selftest.o: ../../include/openssl/symhacks.h fips_rsa_selftest.c
+fips_rsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsa_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+fips_rsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_rsa_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_rsa_sign.o: ../../include/openssl/obj_mac.h
+fips_rsa_sign.o: ../../include/openssl/objects.h
+fips_rsa_sign.o: ../../include/openssl/opensslconf.h
+fips_rsa_sign.o: ../../include/openssl/opensslv.h
+fips_rsa_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+fips_rsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+fips_rsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rsa_sign.o: fips_rsa_sign.c
+fips_rsa_x931g.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsa_x931g.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_rsa_x931g.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rsa_x931g.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_rsa_x931g.o: ../../include/openssl/opensslconf.h
+fips_rsa_x931g.o: ../../include/openssl/opensslv.h
+fips_rsa_x931g.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+fips_rsa_x931g.o: ../../include/openssl/safestack.h
+fips_rsa_x931g.o: ../../include/openssl/stack.h
+fips_rsa_x931g.o: ../../include/openssl/symhacks.h fips_rsa_x931g.c
+fips_rsagtest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsagtest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+fips_rsagtest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+fips_rsagtest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_rsagtest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+fips_rsagtest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_rsagtest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h
+fips_rsagtest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_rsagtest.o: ../../include/openssl/objects.h
+fips_rsagtest.o: ../../include/openssl/opensslconf.h
+fips_rsagtest.o: ../../include/openssl/opensslv.h
+fips_rsagtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+fips_rsagtest.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+fips_rsagtest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+fips_rsagtest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+fips_rsagtest.o: ../../include/openssl/x509_vfy.h
+fips_rsagtest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsagtest.c
+fips_rsastest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsastest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+fips_rsastest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+fips_rsastest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_rsastest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+fips_rsastest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_rsastest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h
+fips_rsastest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_rsastest.o: ../../include/openssl/objects.h
+fips_rsastest.o: ../../include/openssl/opensslconf.h
+fips_rsastest.o: ../../include/openssl/opensslv.h
+fips_rsastest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+fips_rsastest.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+fips_rsastest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+fips_rsastest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+fips_rsastest.o: ../../include/openssl/x509_vfy.h
+fips_rsastest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsastest.c
+fips_rsavtest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rsavtest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+fips_rsavtest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+fips_rsavtest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_rsavtest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+fips_rsavtest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_rsavtest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h
+fips_rsavtest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+fips_rsavtest.o: ../../include/openssl/objects.h
+fips_rsavtest.o: ../../include/openssl/opensslconf.h
+fips_rsavtest.o: ../../include/openssl/opensslv.h
+fips_rsavtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+fips_rsavtest.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+fips_rsavtest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+fips_rsavtest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+fips_rsavtest.o: ../../include/openssl/x509_vfy.h
+fips_rsavtest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsavtest.c
diff --git a/crypto/openssl/fips/rsa/fips_rsa_eay.c b/crypto/openssl/fips/rsa/fips_rsa_eay.c
new file mode 100644
index 0000000..937a14e
--- /dev/null
+++ b/crypto/openssl/fips/rsa/fips_rsa_eay.c
@@ -0,0 +1,934 @@
+/* crypto/rsa/rsa_eay.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+
+#if !defined(RSA_NULL) && defined(OPENSSL_FIPS)
+
+static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa,int padding);
+static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx);
+static int RSA_eay_init(RSA *rsa);
+static int RSA_eay_finish(RSA *rsa);
+static RSA_METHOD rsa_pkcs1_eay_meth={
+ "Eric Young's PKCS#1 RSA",
+ RSA_eay_public_encrypt,
+ RSA_eay_public_decrypt, /* signature verification */
+ RSA_eay_private_encrypt, /* signing */
+ RSA_eay_private_decrypt,
+ RSA_eay_mod_exp,
+ BN_mod_exp_mont, /* XXX probably we should not use Montgomery if e == 3 */
+ RSA_eay_init,
+ RSA_eay_finish,
+ RSA_FLAG_FIPS_METHOD, /* flags */
+ NULL,
+ 0, /* rsa_sign */
+ 0, /* rsa_verify */
+ NULL /* rsa_keygen */
+ };
+
+const RSA_METHOD *RSA_PKCS1_SSLeay(void)
+ {
+ return(&rsa_pkcs1_eay_meth);
+ }
+
+/* Usage example;
+ * MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
+ */
+#define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \
+ if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \
+ !BN_MONT_CTX_set_locked(&((rsa)->_method_mod_##m), \
+ CRYPTO_LOCK_RSA, \
+ (rsa)->m, (ctx))) \
+ err_instr
+
+static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+ {
+ BIGNUM *f,*ret;
+ int i,j,k,num=0,r= -1;
+ unsigned char *buf=NULL;
+ BN_CTX *ctx=NULL;
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
+ goto err;
+ }
+
+ if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
+ return -1;
+ }
+
+ if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
+ return -1;
+ }
+
+ if (BN_ucmp(rsa->n, rsa->e) <= 0)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+ return -1;
+ }
+
+ /* for large moduli, enforce exponent limit */
+ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
+ {
+ if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+ return -1;
+ }
+ }
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
+ num=BN_num_bytes(rsa->n);
+ buf = OPENSSL_malloc(num);
+ if (!f || !ret || !buf)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ switch (padding)
+ {
+ case RSA_PKCS1_PADDING:
+ i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
+ break;
+#ifndef OPENSSL_NO_SHA
+ case RSA_PKCS1_OAEP_PADDING:
+ i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
+ break;
+#endif
+ case RSA_SSLV23_PADDING:
+ i=RSA_padding_add_SSLv23(buf,num,from,flen);
+ break;
+ case RSA_NO_PADDING:
+ i=RSA_padding_add_none(buf,num,from,flen);
+ break;
+ default:
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+ goto err;
+ }
+ if (i <= 0) goto err;
+
+ if (BN_bin2bn(buf,num,f) == NULL) goto err;
+
+ if (BN_ucmp(f, rsa->n) >= 0)
+ {
+ /* usually the padding functions would catch this */
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ goto err;
+ }
+
+ MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+
+ if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
+ rsa->_method_mod_n)) goto err;
+
+ /* put in leading 0 bytes if the number is less than the
+ * length of the modulus */
+ j=BN_num_bytes(ret);
+ i=BN_bn2bin(ret,&(to[num-j]));
+ for (k=0; k<(num-i); k++)
+ to[k]=0;
+
+ r=num;
+err:
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (buf != NULL)
+ {
+ OPENSSL_cleanse(buf,num);
+ OPENSSL_free(buf);
+ }
+ return(r);
+ }
+
+static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
+{
+ BN_BLINDING *ret;
+ int got_write_lock = 0;
+
+ CRYPTO_r_lock(CRYPTO_LOCK_RSA);
+
+ if (rsa->blinding == NULL)
+ {
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+ got_write_lock = 1;
+
+ if (rsa->blinding == NULL)
+ rsa->blinding = RSA_setup_blinding(rsa, ctx);
+ }
+
+ ret = rsa->blinding;
+ if (ret == NULL)
+ goto err;
+
+ if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id())
+ {
+ /* rsa->blinding is ours! */
+
+ *local = 1;
+ }
+ else
+ {
+ /* resort to rsa->mt_blinding instead */
+
+ *local = 0; /* instructs rsa_blinding_convert(), rsa_blinding_invert()
+ * that the BN_BLINDING is shared, meaning that accesses
+ * require locks, and that the blinding factor must be
+ * stored outside the BN_BLINDING
+ */
+
+ if (rsa->mt_blinding == NULL)
+ {
+ if (!got_write_lock)
+ {
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+ got_write_lock = 1;
+ }
+
+ if (rsa->mt_blinding == NULL)
+ rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
+ }
+ ret = rsa->mt_blinding;
+ }
+
+ err:
+ if (got_write_lock)
+ CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
+ else
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+ return ret;
+}
+
+static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f,
+ BIGNUM *r, BN_CTX *ctx)
+{
+ if (local)
+ return BN_BLINDING_convert_ex(f, NULL, b, ctx);
+ else
+ {
+ int ret;
+ CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING);
+ ret = BN_BLINDING_convert_ex(f, r, b, ctx);
+ CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING);
+ return ret;
+ }
+}
+
+static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f,
+ BIGNUM *r, BN_CTX *ctx)
+{
+ if (local)
+ return BN_BLINDING_invert_ex(f, NULL, b, ctx);
+ else
+ {
+ int ret;
+ CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
+ ret = BN_BLINDING_invert_ex(f, r, b, ctx);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
+ return ret;
+ }
+}
+
+/* signing */
+static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+ {
+ BIGNUM *f, *ret, *br, *res;
+ int i,j,k,num=0,r= -1;
+ unsigned char *buf=NULL;
+ BN_CTX *ctx=NULL;
+ int local_blinding = 0;
+ BN_BLINDING *blinding = NULL;
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
+ goto err;
+ }
+
+ if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
+ {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
+ return -1;
+ }
+
+ if ((ctx=BN_CTX_new()) == NULL) goto err;
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ br = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
+ num = BN_num_bytes(rsa->n);
+ buf = OPENSSL_malloc(num);
+ if(!f || !ret || !buf)
+ {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ switch (padding)
+ {
+ case RSA_PKCS1_PADDING:
+ i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
+ break;
+ case RSA_X931_PADDING:
+ i=RSA_padding_add_X931(buf,num,from,flen);
+ break;
+ case RSA_NO_PADDING:
+ i=RSA_padding_add_none(buf,num,from,flen);
+ break;
+ case RSA_SSLV23_PADDING:
+ default:
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+ goto err;
+ }
+ if (i <= 0) goto err;
+
+ if (BN_bin2bn(buf,num,f) == NULL) goto err;
+
+ if (BN_ucmp(f, rsa->n) >= 0)
+ {
+ /* usually the padding functions would catch this */
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ goto err;
+ }
+
+ if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
+ {
+ blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
+ if (blinding == NULL)
+ {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ if (blinding != NULL)
+ if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+ goto err;
+
+ if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
+ ((rsa->p != NULL) &&
+ (rsa->q != NULL) &&
+ (rsa->dmp1 != NULL) &&
+ (rsa->dmq1 != NULL) &&
+ (rsa->iqmp != NULL)) )
+ {
+ if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
+ }
+ else
+ {
+ BIGNUM local_d;
+ BIGNUM *d = NULL;
+
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ BN_init(&local_d);
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+ }
+ else
+ d = rsa->d;
+
+ MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+
+ if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
+ rsa->_method_mod_n)) goto err;
+ }
+
+ if (blinding)
+ if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
+ goto err;
+
+ if (padding == RSA_X931_PADDING)
+ {
+ BN_sub(f, rsa->n, ret);
+ if (BN_cmp(ret, f))
+ res = f;
+ else
+ res = ret;
+ }
+ else
+ res = ret;
+
+ /* put in leading 0 bytes if the number is less than the
+ * length of the modulus */
+ j=BN_num_bytes(res);
+ i=BN_bn2bin(res,&(to[num-j]));
+ for (k=0; k<(num-i); k++)
+ to[k]=0;
+
+ r=num;
+err:
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (buf != NULL)
+ {
+ OPENSSL_cleanse(buf,num);
+ OPENSSL_free(buf);
+ }
+ return(r);
+ }
+
+static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+ {
+ BIGNUM *f, *ret, *br;
+ int j,num=0,r= -1;
+ unsigned char *p;
+ unsigned char *buf=NULL;
+ BN_CTX *ctx=NULL;
+ int local_blinding = 0;
+ BN_BLINDING *blinding = NULL;
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_RSA_EAY_PRIVATE_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
+ goto err;
+ }
+
+ if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
+ {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
+ return -1;
+ }
+
+ if((ctx = BN_CTX_new()) == NULL) goto err;
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ br = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
+ num = BN_num_bytes(rsa->n);
+ buf = OPENSSL_malloc(num);
+ if(!f || !ret || !buf)
+ {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* This check was for equality but PGP does evil things
+ * and chops off the top '0' bytes */
+ if (flen > num)
+ {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
+ goto err;
+ }
+
+ /* make data into a big number */
+ if (BN_bin2bn(from,(int)flen,f) == NULL) goto err;
+
+ if (BN_ucmp(f, rsa->n) >= 0)
+ {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ goto err;
+ }
+
+ if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
+ {
+ blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
+ if (blinding == NULL)
+ {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ if (blinding != NULL)
+ if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
+ goto err;
+
+ /* do the decrypt */
+ if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
+ ((rsa->p != NULL) &&
+ (rsa->q != NULL) &&
+ (rsa->dmp1 != NULL) &&
+ (rsa->dmq1 != NULL) &&
+ (rsa->iqmp != NULL)) )
+ {
+ if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
+ }
+ else
+ {
+ BIGNUM local_d;
+ BIGNUM *d = NULL;
+
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+ }
+ else
+ d = rsa->d;
+
+ MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+ if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
+ rsa->_method_mod_n))
+ goto err;
+ }
+
+ if (blinding)
+ if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
+ goto err;
+
+ p=buf;
+ j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */
+
+ switch (padding)
+ {
+ case RSA_PKCS1_PADDING:
+ r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
+ break;
+#ifndef OPENSSL_NO_SHA
+ case RSA_PKCS1_OAEP_PADDING:
+ r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
+ break;
+#endif
+ case RSA_SSLV23_PADDING:
+ r=RSA_padding_check_SSLv23(to,num,buf,j,num);
+ break;
+ case RSA_NO_PADDING:
+ r=RSA_padding_check_none(to,num,buf,j,num);
+ break;
+ default:
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+ goto err;
+ }
+ if (r < 0)
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
+
+err:
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (buf != NULL)
+ {
+ OPENSSL_cleanse(buf,num);
+ OPENSSL_free(buf);
+ }
+ return(r);
+ }
+
+/* signature verification */
+static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
+ unsigned char *to, RSA *rsa, int padding)
+ {
+ BIGNUM *f,*ret;
+ int i,num=0,r= -1;
+ unsigned char *p;
+ unsigned char *buf=NULL;
+ BN_CTX *ctx=NULL;
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_RSA_EAY_PUBLIC_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
+ goto err;
+ }
+
+ if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
+ return -1;
+ }
+
+ if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
+ return -1;
+ }
+
+ if (BN_ucmp(rsa->n, rsa->e) <= 0)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
+ return -1;
+ }
+
+ /* for large moduli, enforce exponent limit */
+ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
+ {
+ if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
+ return -1;
+ }
+ }
+
+ if((ctx = BN_CTX_new()) == NULL) goto err;
+ BN_CTX_start(ctx);
+ f = BN_CTX_get(ctx);
+ ret = BN_CTX_get(ctx);
+ num=BN_num_bytes(rsa->n);
+ buf = OPENSSL_malloc(num);
+ if(!f || !ret || !buf)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* This check was for equality but PGP does evil things
+ * and chops off the top '0' bytes */
+ if (flen > num)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
+ goto err;
+ }
+
+ if (BN_bin2bn(from,flen,f) == NULL) goto err;
+
+ if (BN_ucmp(f, rsa->n) >= 0)
+ {
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ goto err;
+ }
+
+ MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+
+ if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
+ rsa->_method_mod_n)) goto err;
+
+ if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12))
+ BN_sub(ret, rsa->n, ret);
+
+ p=buf;
+ i=BN_bn2bin(ret,p);
+
+ switch (padding)
+ {
+ case RSA_PKCS1_PADDING:
+ r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
+ break;
+ case RSA_X931_PADDING:
+ r=RSA_padding_check_X931(to,num,buf,i,num);
+ break;
+ case RSA_NO_PADDING:
+ r=RSA_padding_check_none(to,num,buf,i,num);
+ break;
+ default:
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
+ goto err;
+ }
+ if (r < 0)
+ RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
+
+err:
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (buf != NULL)
+ {
+ OPENSSL_cleanse(buf,num);
+ OPENSSL_free(buf);
+ }
+ return(r);
+ }
+
+static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+ {
+ BIGNUM *r1,*m1,*vrfy;
+ BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
+ BIGNUM *dmp1,*dmq1,*c,*pr1;
+ int bn_flags;
+ int ret=0;
+
+ BN_CTX_start(ctx);
+ r1 = BN_CTX_get(ctx);
+ m1 = BN_CTX_get(ctx);
+ vrfy = BN_CTX_get(ctx);
+
+ /* Make sure mod_inverse in montgomerey intialization use correct
+ * BN_FLG_CONSTTIME flag.
+ */
+ bn_flags = rsa->p->flags;
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ rsa->p->flags |= BN_FLG_CONSTTIME;
+ }
+ MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
+ /* We restore bn_flags back */
+ rsa->p->flags = bn_flags;
+
+ /* Make sure mod_inverse in montgomerey intialization use correct
+ * BN_FLG_CONSTTIME flag.
+ */
+ bn_flags = rsa->q->flags;
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ rsa->q->flags |= BN_FLG_CONSTTIME;
+ }
+ MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
+ /* We restore bn_flags back */
+ rsa->q->flags = bn_flags;
+
+ MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+
+ /* compute I mod q */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ c = &local_c;
+ BN_with_flags(c, I, BN_FLG_CONSTTIME);
+ if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
+ }
+
+ /* compute r1^dmq1 mod q */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ dmq1 = &local_dmq1;
+ BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
+ }
+ else
+ dmq1 = rsa->dmq1;
+ if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
+ rsa->_method_mod_q)) goto err;
+
+ /* compute I mod p */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ c = &local_c;
+ BN_with_flags(c, I, BN_FLG_CONSTTIME);
+ if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
+ }
+
+ /* compute r1^dmp1 mod p */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ dmp1 = &local_dmp1;
+ BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
+ }
+ else
+ dmp1 = rsa->dmp1;
+ if (!rsa->meth->bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
+ rsa->_method_mod_p)) goto err;
+
+ if (!BN_sub(r0,r0,m1)) goto err;
+ /* This will help stop the size of r0 increasing, which does
+ * affect the multiply if it optimised for a power of 2 size */
+ if (BN_is_negative(r0))
+ if (!BN_add(r0,r0,rsa->p)) goto err;
+
+ if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
+
+ /* Turn BN_FLG_CONSTTIME flag on before division operation */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ pr1 = &local_r1;
+ BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
+ }
+ else
+ pr1 = r1;
+ if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
+
+ /* If p < q it is occasionally possible for the correction of
+ * adding 'p' if r0 is negative above to leave the result still
+ * negative. This can break the private key operations: the following
+ * second correction should *always* correct this rare occurrence.
+ * This will *never* happen with OpenSSL generated keys because
+ * they ensure p > q [steve]
+ */
+ if (BN_is_negative(r0))
+ if (!BN_add(r0,r0,rsa->p)) goto err;
+ if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
+ if (!BN_add(r0,r1,m1)) goto err;
+
+ if (rsa->e && rsa->n)
+ {
+ if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err;
+ /* If 'I' was greater than (or equal to) rsa->n, the operation
+ * will be equivalent to using 'I mod n'. However, the result of
+ * the verify will *always* be less than 'n' so we don't check
+ * for absolute equality, just congruency. */
+ if (!BN_sub(vrfy, vrfy, I)) goto err;
+ if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
+ if (BN_is_negative(vrfy))
+ if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
+ if (!BN_is_zero(vrfy))
+ {
+ /* 'I' and 'vrfy' aren't congruent mod n. Don't leak
+ * miscalculated CRT output, just do a raw (slower)
+ * mod_exp and return that instead. */
+
+ BIGNUM local_d;
+ BIGNUM *d = NULL;
+
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+ }
+ else
+ d = rsa->d;
+ if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx,
+ rsa->_method_mod_n)) goto err;
+ }
+ }
+ ret=1;
+err:
+ BN_CTX_end(ctx);
+ return(ret);
+ }
+
+static int RSA_eay_init(RSA *rsa)
+ {
+ FIPS_selftest_check();
+ rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
+ return(1);
+ }
+
+static int RSA_eay_finish(RSA *rsa)
+ {
+ if (rsa->_method_mod_n != NULL)
+ BN_MONT_CTX_free(rsa->_method_mod_n);
+ if (rsa->_method_mod_p != NULL)
+ BN_MONT_CTX_free(rsa->_method_mod_p);
+ if (rsa->_method_mod_q != NULL)
+ BN_MONT_CTX_free(rsa->_method_mod_q);
+ return(1);
+ }
+
+#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsa_gen.c b/crypto/openssl/fips/rsa/fips_rsa_gen.c
new file mode 100644
index 0000000..90aaa2f
--- /dev/null
+++ b/crypto/openssl/fips/rsa/fips_rsa_gen.c
@@ -0,0 +1,310 @@
+/* crypto/rsa/rsa_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+
+/* NB: these functions have been "upgraded", the deprecated versions (which are
+ * compatibility wrappers using these functions) are in rsa_depr.c.
+ * - Geoff
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/fips.h>
+#include "fips_locl.h"
+
+#ifdef OPENSSL_FIPS
+
+static int fips_rsa_pairwise_fail = 0;
+
+void FIPS_corrupt_rsa_keygen(void)
+ {
+ fips_rsa_pairwise_fail = 1;
+ }
+
+int fips_check_rsa(RSA *rsa)
+ {
+ const unsigned char tbs[] = "RSA Pairwise Check Data";
+ unsigned char *ctbuf = NULL, *ptbuf = NULL;
+ int len, ret = 0;
+ EVP_PKEY pk;
+ pk.type = EVP_PKEY_RSA;
+ pk.pkey.rsa = rsa;
+
+ /* Perform pairwise consistency signature test */
+ if (!fips_pkey_signature_test(&pk, tbs, -1,
+ NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1, NULL)
+ || !fips_pkey_signature_test(&pk, tbs, -1,
+ NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931, NULL)
+ || !fips_pkey_signature_test(&pk, tbs, -1,
+ NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS, NULL))
+ goto err;
+ /* Now perform pairwise consistency encrypt/decrypt test */
+ ctbuf = OPENSSL_malloc(RSA_size(rsa));
+ if (!ctbuf)
+ goto err;
+
+ len = RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa, RSA_PKCS1_PADDING);
+ if (len <= 0)
+ goto err;
+ /* Check ciphertext doesn't match plaintext */
+ if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len))
+ goto err;
+ ptbuf = OPENSSL_malloc(RSA_size(rsa));
+
+ if (!ptbuf)
+ goto err;
+ len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING);
+ if (len != (sizeof(tbs) - 1))
+ goto err;
+ if (memcmp(ptbuf, tbs, len))
+ goto err;
+
+ ret = 1;
+
+ if (!ptbuf)
+ goto err;
+
+ err:
+ if (ret == 0)
+ {
+ fips_set_selftest_fail();
+ FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
+ }
+
+ if (ctbuf)
+ OPENSSL_free(ctbuf);
+ if (ptbuf)
+ OPENSSL_free(ptbuf);
+
+ return ret;
+ }
+
+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
+
+/* NB: this wrapper would normally be placed in rsa_lib.c and the static
+ * implementation would probably be in rsa_eay.c. Nonetheless, is kept here so
+ * that we don't introduce a new linker dependency. Eg. any application that
+ * wasn't previously linking object code related to key-generation won't have to
+ * now just because key-generation is part of RSA_METHOD. */
+int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
+ {
+ if(rsa->meth->rsa_keygen)
+ return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
+ return rsa_builtin_keygen(rsa, bits, e_value, cb);
+ }
+
+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
+ {
+ BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
+ BIGNUM local_r0,local_d,local_p;
+ BIGNUM *pr0,*d,*p;
+ int bitsp,bitsq,ok= -1,n=0;
+ BN_CTX *ctx=NULL;
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_FIPS_SELFTEST_FAILED);
+ return 0;
+ }
+
+ if (FIPS_mode() && (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
+ {
+ FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT);
+ return 0;
+ }
+
+ ctx=BN_CTX_new();
+ if (ctx == NULL) goto err;
+ BN_CTX_start(ctx);
+ r0 = BN_CTX_get(ctx);
+ r1 = BN_CTX_get(ctx);
+ r2 = BN_CTX_get(ctx);
+ r3 = BN_CTX_get(ctx);
+ if (r3 == NULL) goto err;
+
+ bitsp=(bits+1)/2;
+ bitsq=bits-bitsp;
+
+ /* We need the RSA components non-NULL */
+ if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err;
+ if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err;
+ if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err;
+ if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err;
+ if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err;
+ if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
+ if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
+ if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;
+
+ BN_copy(rsa->e, e_value);
+
+ /* generate p and q */
+ for (;;)
+ {
+ if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
+ goto err;
+ if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
+ if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
+ if (BN_is_one(r1)) break;
+ if(!BN_GENCB_call(cb, 2, n++))
+ goto err;
+ }
+ if(!BN_GENCB_call(cb, 3, 0))
+ goto err;
+ for (;;)
+ {
+ /* When generating ridiculously small keys, we can get stuck
+ * continually regenerating the same prime values. Check for
+ * this and bail if it happens 3 times. */
+ unsigned int degenerate = 0;
+ do
+ {
+ if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
+ goto err;
+ } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
+ if(degenerate == 3)
+ {
+ ok = 0; /* we set our own err */
+ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL);
+ goto err;
+ }
+ if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
+ if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
+ if (BN_is_one(r1))
+ break;
+ if(!BN_GENCB_call(cb, 2, n++))
+ goto err;
+ }
+ if(!BN_GENCB_call(cb, 3, 1))
+ goto err;
+ if (BN_cmp(rsa->p,rsa->q) < 0)
+ {
+ tmp=rsa->p;
+ rsa->p=rsa->q;
+ rsa->q=tmp;
+ }
+
+ /* calculate n */
+ if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;
+
+ /* calculate d */
+ if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */
+ if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */
+ if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ pr0 = &local_r0;
+ BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
+ }
+ else
+ pr0 = r0;
+ if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */
+
+ /* set up d for correct BN_FLG_CONSTTIME flag */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ d = &local_d;
+ BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+ }
+ else
+ d = rsa->d;
+
+ /* calculate d mod (p-1) */
+ if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;
+
+ /* calculate d mod (q-1) */
+ if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;
+
+ /* calculate inverse of q mod p */
+ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
+ {
+ p = &local_p;
+ BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
+ }
+ else
+ p = rsa->p;
+ if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
+
+ if (fips_rsa_pairwise_fail)
+ BN_add_word(rsa->n, 1);
+
+ if(!fips_check_rsa(rsa))
+ goto err;
+
+ ok=1;
+err:
+ if (ok == -1)
+ {
+ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
+ ok=0;
+ }
+ if (ctx != NULL)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+
+ return ok;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsa_lib.c b/crypto/openssl/fips/rsa/fips_rsa_lib.c
new file mode 100644
index 0000000..a37ad3e
--- /dev/null
+++ b/crypto/openssl/fips/rsa/fips_rsa_lib.c
@@ -0,0 +1,101 @@
+/* fips_rsa_sign.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#include <openssl/err.h>
+
+/* Minimal FIPS versions of FIPS_rsa_new() and FIPS_rsa_free: to
+ * reduce external dependencies.
+ */
+
+RSA *FIPS_rsa_new(void)
+ {
+ RSA *ret;
+ ret = OPENSSL_malloc(sizeof(RSA));
+ if (!ret)
+ return NULL;
+ memset(ret, 0, sizeof(RSA));
+ ret->meth = RSA_PKCS1_SSLeay();
+ if (ret->meth->init)
+ ret->meth->init(ret);
+ return ret;
+ }
+
+void FIPS_rsa_free(RSA *r)
+ {
+ if (!r)
+ return;
+ if (r->meth->finish)
+ r->meth->finish(r);
+ if (r->n != NULL) BN_clear_free(r->n);
+ if (r->e != NULL) BN_clear_free(r->e);
+ if (r->d != NULL) BN_clear_free(r->d);
+ if (r->p != NULL) BN_clear_free(r->p);
+ if (r->q != NULL) BN_clear_free(r->q);
+ if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
+ if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
+ if (r->iqmp != NULL) BN_clear_free(r->iqmp);
+ if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
+ if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
+ if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data);
+ OPENSSL_free(r);
+ }
+
diff --git a/crypto/openssl/fips/rsa/fips_rsa_selftest.c b/crypto/openssl/fips/rsa/fips_rsa_selftest.c
new file mode 100644
index 0000000..bead61f
--- /dev/null
+++ b/crypto/openssl/fips/rsa/fips_rsa_selftest.c
@@ -0,0 +1,432 @@
+/* ====================================================================
+ * Copyright (c) 2003-2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_FIPS
+
+static unsigned char n[] =
+"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
+"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
+"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD"
+"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80"
+"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25"
+"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39"
+"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68"
+"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD"
+"\xCB";
+
+
+static int setrsakey(RSA *key)
+ {
+ static const unsigned char e[] = "\x11";
+
+ static const unsigned char d[] =
+"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD"
+"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41"
+"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69"
+"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA"
+"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94"
+"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
+"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
+"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
+"\xC1";
+
+ static const unsigned char p[] =
+"\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60"
+"\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6"
+"\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A"
+"\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65"
+"\x99";
+
+ static const unsigned char q[] =
+"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
+"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
+"\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
+"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15"
+"\x03";
+
+ static const unsigned char dmp1[] =
+"\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A"
+"\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E"
+"\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E"
+"\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81";
+
+ static const unsigned char dmq1[] =
+"\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9"
+"\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7"
+"\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D"
+"\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D";
+
+ static const unsigned char iqmp[] =
+"\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23"
+"\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11"
+"\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E"
+"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
+"\xF7";
+
+ key->n = BN_bin2bn(n, sizeof(n)-1, key->n);
+ key->e = BN_bin2bn(e, sizeof(e)-1, key->e);
+ key->d = BN_bin2bn(d, sizeof(d)-1, key->d);
+ key->p = BN_bin2bn(p, sizeof(p)-1, key->p);
+ key->q = BN_bin2bn(q, sizeof(q)-1, key->q);
+ key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1);
+ key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1);
+ key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp);
+ return 1;
+ }
+
+void FIPS_corrupt_rsa()
+ {
+ n[0]++;
+ }
+
+/* Known Answer Test (KAT) data for the above RSA private key signing
+ * kat_tbs.
+ */
+
+static const unsigned char kat_tbs[] = "OpenSSL FIPS 140-2 Public Key RSA KAT";
+
+static const unsigned char kat_RSA_PSS_SHA1[] = {
+ 0x2D, 0xAF, 0x6E, 0xC2, 0x98, 0xFB, 0x8A, 0xA1, 0xB9, 0x46, 0xDA, 0x0F,
+ 0x01, 0x1E, 0x37, 0x93, 0xC2, 0x55, 0x27, 0xE4, 0x1D, 0xD2, 0x90, 0xBB,
+ 0xF4, 0xBF, 0x4A, 0x74, 0x39, 0x51, 0xBB, 0xE8, 0x0C, 0xB7, 0xF8, 0xD3,
+ 0xD1, 0xDF, 0xE7, 0xBE, 0x80, 0x05, 0xC3, 0xB5, 0xC7, 0x83, 0xD5, 0x4C,
+ 0x7F, 0x49, 0xFB, 0x3F, 0x29, 0x9B, 0xE1, 0x12, 0x51, 0x60, 0xD0, 0xA7,
+ 0x0D, 0xA9, 0x28, 0x56, 0x73, 0xD9, 0x07, 0xE3, 0x5E, 0x3F, 0x9B, 0xF5,
+ 0xB6, 0xF3, 0xF2, 0x5E, 0x74, 0xC9, 0x83, 0x81, 0x47, 0xF0, 0xC5, 0x45,
+ 0x0A, 0xE9, 0x8E, 0x38, 0xD7, 0x18, 0xC6, 0x2A, 0x0F, 0xF8, 0xB7, 0x31,
+ 0xD6, 0x55, 0xE4, 0x66, 0x78, 0x81, 0xD4, 0xE6, 0xDB, 0x9F, 0xBA, 0xE8,
+ 0x23, 0xB5, 0x7F, 0xDC, 0x08, 0xEA, 0xD5, 0x26, 0x1E, 0x20, 0x25, 0x84,
+ 0x26, 0xC6, 0x79, 0xC9, 0x9B, 0x3D, 0x7E, 0xA9
+};
+
+static const unsigned char kat_RSA_PSS_SHA224[] = {
+ 0x39, 0x4A, 0x6A, 0x20, 0xBC, 0xE9, 0x33, 0xED, 0xEF, 0xC5, 0x58, 0xA7,
+ 0xFE, 0x81, 0xC4, 0x36, 0x50, 0x9A, 0x2C, 0x82, 0x98, 0x08, 0x95, 0xFA,
+ 0xB1, 0x9E, 0xD2, 0x55, 0x61, 0x87, 0x21, 0x59, 0x87, 0x7B, 0x1F, 0x57,
+ 0x30, 0x9D, 0x0D, 0x4A, 0x06, 0xEB, 0x52, 0x37, 0x55, 0x54, 0x1C, 0x89,
+ 0x83, 0x75, 0x59, 0x65, 0x64, 0x90, 0x2E, 0x16, 0xCC, 0x86, 0x05, 0xEE,
+ 0xB1, 0xE6, 0x7B, 0xBA, 0x16, 0x75, 0x0D, 0x0C, 0x64, 0x0B, 0xAB, 0x22,
+ 0x15, 0x78, 0x6B, 0x6F, 0xA4, 0xFB, 0x77, 0x40, 0x64, 0x62, 0xD1, 0xB5,
+ 0x37, 0x1E, 0xE0, 0x3D, 0xA8, 0xF9, 0xD2, 0xBD, 0xAA, 0x38, 0x24, 0x49,
+ 0x58, 0xD2, 0x74, 0x85, 0xF4, 0xB5, 0x93, 0x8E, 0xF5, 0x03, 0xEA, 0x2D,
+ 0xC8, 0x52, 0xFA, 0xCF, 0x7E, 0x35, 0xB0, 0x6A, 0xAF, 0x95, 0xC0, 0x00,
+ 0x54, 0x76, 0x3D, 0x0C, 0x9C, 0xB2, 0xEE, 0xC0
+};
+
+static const unsigned char kat_RSA_PSS_SHA256[] = {
+ 0x6D, 0x3D, 0xBE, 0x8F, 0x60, 0x6D, 0x25, 0x14, 0xF0, 0x31, 0xE3, 0x89,
+ 0x00, 0x97, 0xFA, 0x99, 0x71, 0x28, 0xE5, 0x10, 0x25, 0x9A, 0xF3, 0x8F,
+ 0x7B, 0xC5, 0xA8, 0x4A, 0x74, 0x51, 0x36, 0xE2, 0x8D, 0x7D, 0x73, 0x28,
+ 0xC1, 0x77, 0xC6, 0x27, 0x97, 0x00, 0x8B, 0x00, 0xA3, 0x96, 0x73, 0x4E,
+ 0x7D, 0x2E, 0x2C, 0x34, 0x68, 0x8C, 0x8E, 0xDF, 0x9D, 0x49, 0x47, 0x05,
+ 0xAB, 0xF5, 0x01, 0xD6, 0x81, 0x47, 0x70, 0xF5, 0x1D, 0x6D, 0x26, 0xBA,
+ 0x2F, 0x7A, 0x54, 0x53, 0x4E, 0xED, 0x71, 0xD9, 0x5A, 0xF3, 0xDA, 0xB6,
+ 0x0B, 0x47, 0x34, 0xAF, 0x90, 0xDC, 0xC8, 0xD9, 0x6F, 0x56, 0xCD, 0x9F,
+ 0x21, 0xB7, 0x7E, 0xAD, 0x7C, 0x2F, 0x75, 0x50, 0x47, 0x12, 0xE4, 0x6D,
+ 0x5F, 0xB7, 0x01, 0xDF, 0xC3, 0x11, 0x6C, 0xA9, 0x9E, 0x49, 0xB9, 0xF6,
+ 0x72, 0xF4, 0xF6, 0xEF, 0x88, 0x1E, 0x2D, 0x1C
+};
+
+static const unsigned char kat_RSA_PSS_SHA384[] = {
+ 0x40, 0xFB, 0xA1, 0x21, 0xF4, 0xB2, 0x40, 0x9A, 0xB4, 0x31, 0xA8, 0xF2,
+ 0xEC, 0x1C, 0xC4, 0xC8, 0x7C, 0x22, 0x65, 0x9C, 0x57, 0x45, 0xCD, 0x5E,
+ 0x86, 0x00, 0xF7, 0x25, 0x78, 0xDE, 0xDC, 0x7A, 0x71, 0x44, 0x9A, 0xCD,
+ 0xAA, 0x25, 0xF4, 0xB2, 0xFC, 0xF0, 0x75, 0xD9, 0x2F, 0x78, 0x23, 0x7F,
+ 0x6F, 0x02, 0xEF, 0xC1, 0xAF, 0xA6, 0x28, 0x16, 0x31, 0xDC, 0x42, 0x6C,
+ 0xB2, 0x44, 0xE5, 0x4D, 0x66, 0xA2, 0xE6, 0x71, 0xF3, 0xAC, 0x4F, 0xFB,
+ 0x91, 0xCA, 0xF5, 0x70, 0xEF, 0x6B, 0x9D, 0xA4, 0xEF, 0xD9, 0x3D, 0x2F,
+ 0x3A, 0xBE, 0x89, 0x38, 0x59, 0x01, 0xBA, 0xDA, 0x32, 0xAD, 0x42, 0x89,
+ 0x98, 0x8B, 0x39, 0x44, 0xF0, 0xFC, 0x38, 0xAC, 0x87, 0x1F, 0xCA, 0x6F,
+ 0x48, 0xF6, 0xAE, 0xD7, 0x45, 0xEE, 0xAE, 0x88, 0x0E, 0x60, 0xF4, 0x55,
+ 0x48, 0x44, 0xEE, 0x1F, 0x90, 0x18, 0x4B, 0xF1
+};
+
+static const unsigned char kat_RSA_PSS_SHA512[] = {
+ 0x07, 0x1E, 0xD8, 0xD5, 0x05, 0xE8, 0xE6, 0xE6, 0x57, 0xAE, 0x63, 0x8C,
+ 0xC6, 0x83, 0xB7, 0xA0, 0x59, 0xBB, 0xF2, 0xC6, 0x8F, 0x12, 0x53, 0x9A,
+ 0x9B, 0x54, 0x9E, 0xB3, 0xC1, 0x1D, 0x23, 0x4D, 0x51, 0xED, 0x9E, 0xDD,
+ 0x4B, 0xF3, 0x46, 0x9B, 0x6B, 0xF6, 0x7C, 0x24, 0x60, 0x79, 0x23, 0x39,
+ 0x01, 0x1C, 0x51, 0xCB, 0xD8, 0xE9, 0x9A, 0x01, 0x67, 0x5F, 0xFE, 0xD7,
+ 0x7C, 0xE3, 0x7F, 0xED, 0xDB, 0x87, 0xBB, 0xF0, 0x3D, 0x78, 0x55, 0x61,
+ 0x57, 0xE3, 0x0F, 0xE3, 0xD2, 0x9D, 0x0C, 0x2A, 0x20, 0xB0, 0x85, 0x13,
+ 0xC5, 0x47, 0x34, 0x0D, 0x32, 0x15, 0xC8, 0xAE, 0x9A, 0x6A, 0x39, 0x63,
+ 0x2D, 0x60, 0xF5, 0x4C, 0xDF, 0x8A, 0x48, 0x4B, 0xBF, 0xF4, 0xA8, 0xFE,
+ 0x76, 0xF2, 0x32, 0x1B, 0x9C, 0x7C, 0xCA, 0xFE, 0x7F, 0x80, 0xC2, 0x88,
+ 0x5C, 0x97, 0x70, 0xB4, 0x26, 0xC9, 0x14, 0x8B
+};
+
+static const unsigned char kat_RSA_SHA1[] = {
+ 0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C,
+ 0x4A, 0xFD, 0x1A, 0x05, 0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B,
+ 0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51, 0x55, 0x77, 0x90, 0xCF,
+ 0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8,
+ 0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1,
+ 0x20, 0x22, 0xBE, 0x59, 0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA,
+ 0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF, 0x4E, 0xCA, 0x2E, 0x4E,
+ 0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F,
+ 0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F,
+ 0x72, 0x05, 0xDE, 0xE6, 0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95,
+ 0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4
+};
+
+static const unsigned char kat_RSA_SHA224[] = {
+ 0x62, 0xAA, 0x79, 0xA9, 0x18, 0x0E, 0x5F, 0x8C, 0xBB, 0xB7, 0x15, 0xF9,
+ 0x25, 0xBB, 0xFA, 0xD4, 0x3A, 0x34, 0xED, 0x9E, 0xA0, 0xA9, 0x18, 0x8D,
+ 0x5B, 0x55, 0x9A, 0x7E, 0x1E, 0x08, 0x08, 0x60, 0xC5, 0x1A, 0xC5, 0x89,
+ 0x08, 0xE2, 0x1B, 0xBD, 0x62, 0x50, 0x17, 0x76, 0x30, 0x2C, 0x9E, 0xCD,
+ 0xA4, 0x02, 0xAD, 0xB1, 0x6D, 0x44, 0x6D, 0xD5, 0xC6, 0x45, 0x41, 0xE5,
+ 0xEE, 0x1F, 0x8D, 0x7E, 0x08, 0x16, 0xA6, 0xE1, 0x5E, 0x0B, 0xA9, 0xCC,
+ 0xDB, 0x59, 0x55, 0x87, 0x09, 0x25, 0x70, 0x86, 0x84, 0x02, 0xC6, 0x3B,
+ 0x0B, 0x44, 0x4C, 0x46, 0x95, 0xF4, 0xF8, 0x5A, 0x91, 0x28, 0x3E, 0xB2,
+ 0x58, 0x2E, 0x06, 0x45, 0x49, 0xE0, 0x92, 0xE2, 0xC0, 0x66, 0xE6, 0x35,
+ 0xD9, 0x79, 0x7F, 0x17, 0x5E, 0x02, 0x73, 0x04, 0x77, 0x82, 0xE6, 0xDC,
+ 0x40, 0x21, 0x89, 0x8B, 0x37, 0x3E, 0x1E, 0x8D
+};
+
+static const unsigned char kat_RSA_SHA256[] = {
+ 0x0D, 0x55, 0xE2, 0xAA, 0x81, 0xDB, 0x8E, 0x82, 0x05, 0x17, 0xA5, 0x23,
+ 0xE7, 0x3B, 0x1D, 0xAF, 0xFB, 0x8C, 0xD0, 0x81, 0x20, 0x7B, 0xAA, 0x23,
+ 0x92, 0x87, 0x8C, 0xD1, 0x53, 0x85, 0x16, 0xDC, 0xBE, 0xAD, 0x6F, 0x35,
+ 0x98, 0x2D, 0x69, 0x84, 0xBF, 0xD9, 0x8A, 0x01, 0x17, 0x58, 0xB2, 0x6E,
+ 0x2C, 0x44, 0x9B, 0x90, 0xF1, 0xFB, 0x51, 0xE8, 0x6A, 0x90, 0x2D, 0x18,
+ 0x0E, 0xC0, 0x90, 0x10, 0x24, 0xA9, 0x1D, 0xB3, 0x58, 0x7A, 0x91, 0x30,
+ 0xBE, 0x22, 0xC7, 0xD3, 0xEC, 0xC3, 0x09, 0x5D, 0xBF, 0xE2, 0x80, 0x3A,
+ 0x7C, 0x85, 0xB4, 0xBC, 0xD1, 0xE9, 0xF0, 0x5C, 0xDE, 0x81, 0xA6, 0x38,
+ 0xB8, 0x42, 0xBB, 0x86, 0xC5, 0x9D, 0xCE, 0x7C, 0x2C, 0xEE, 0xD1, 0xDA,
+ 0x27, 0x48, 0x2B, 0xF5, 0xAB, 0xB9, 0xF7, 0x80, 0xD1, 0x90, 0x27, 0x90,
+ 0xBD, 0x44, 0x97, 0x60, 0xCD, 0x57, 0xC0, 0x7A
+};
+
+static const unsigned char kat_RSA_SHA384[] = {
+ 0x1D, 0xE3, 0x6A, 0xDD, 0x27, 0x4C, 0xC0, 0xA5, 0x27, 0xEF, 0xE6, 0x1F,
+ 0xD2, 0x91, 0x68, 0x59, 0x04, 0xAE, 0xBD, 0x99, 0x63, 0x56, 0x47, 0xC7,
+ 0x6F, 0x22, 0x16, 0x48, 0xD0, 0xF9, 0x18, 0xA9, 0xCA, 0xFA, 0x5D, 0x5C,
+ 0xA7, 0x65, 0x52, 0x8A, 0xC8, 0x44, 0x7E, 0x86, 0x5D, 0xA9, 0xA6, 0x55,
+ 0x65, 0x3E, 0xD9, 0x2D, 0x02, 0x38, 0xA8, 0x79, 0x28, 0x7F, 0xB6, 0xCF,
+ 0x82, 0xDD, 0x7E, 0x55, 0xE1, 0xB1, 0xBC, 0xE2, 0x19, 0x2B, 0x30, 0xC2,
+ 0x1B, 0x2B, 0xB0, 0x82, 0x46, 0xAC, 0x4B, 0xD1, 0xE2, 0x7D, 0xEB, 0x8C,
+ 0xFF, 0x95, 0xE9, 0x6A, 0x1C, 0x3D, 0x4D, 0xBF, 0x8F, 0x8B, 0x9C, 0xCD,
+ 0xEA, 0x85, 0xEE, 0x00, 0xDC, 0x1C, 0xA7, 0xEB, 0xD0, 0x8F, 0x99, 0xF1,
+ 0x16, 0x28, 0x24, 0x64, 0x04, 0x39, 0x2D, 0x58, 0x1E, 0x37, 0xDC, 0x04,
+ 0xBD, 0x31, 0xA2, 0x2F, 0xB3, 0x35, 0x56, 0xBF
+};
+
+static const unsigned char kat_RSA_SHA512[] = {
+ 0x69, 0x52, 0x1B, 0x51, 0x5E, 0x06, 0xCA, 0x9B, 0x16, 0x51, 0x5D, 0xCF,
+ 0x49, 0x25, 0x4A, 0xA1, 0x6A, 0x77, 0x4C, 0x36, 0x40, 0xF8, 0xB2, 0x9A,
+ 0x15, 0xEA, 0x5C, 0xE5, 0xE6, 0x82, 0xE0, 0x86, 0x82, 0x6B, 0x32, 0xF1,
+ 0x04, 0xC1, 0x5A, 0x1A, 0xED, 0x1E, 0x9A, 0xB6, 0x4C, 0x54, 0x9F, 0xD8,
+ 0x8D, 0xCC, 0xAC, 0x8A, 0xBB, 0x9C, 0x82, 0x3F, 0xA6, 0x53, 0x62, 0xB5,
+ 0x80, 0xE2, 0xBC, 0xDD, 0x67, 0x2B, 0xD9, 0x3F, 0xE4, 0x75, 0x92, 0x6B,
+ 0xAF, 0x62, 0x7C, 0x52, 0xF0, 0xEE, 0x33, 0xDF, 0x1B, 0x1D, 0x47, 0xE6,
+ 0x59, 0x56, 0xA5, 0xB9, 0x5C, 0xE6, 0x77, 0x78, 0x16, 0x63, 0x84, 0x05,
+ 0x6F, 0x0E, 0x2B, 0x31, 0x9D, 0xF7, 0x7F, 0xB2, 0x64, 0x71, 0xE0, 0x2D,
+ 0x3E, 0x62, 0xCE, 0xB5, 0x3F, 0x88, 0xDF, 0x2D, 0xAB, 0x98, 0x65, 0x91,
+ 0xDF, 0x70, 0x14, 0xA5, 0x3F, 0x36, 0xAB, 0x84
+};
+
+static const unsigned char kat_RSA_X931_SHA1[] = {
+ 0x86, 0xB4, 0x18, 0xBA, 0xD1, 0x80, 0xB6, 0x7C, 0x42, 0x45, 0x4D, 0xDF,
+ 0xE9, 0x2D, 0xE1, 0x83, 0x5F, 0xB5, 0x2F, 0xC9, 0xCD, 0xC4, 0xB2, 0x75,
+ 0x80, 0xA4, 0xF1, 0x4A, 0xE7, 0x83, 0x12, 0x1E, 0x1E, 0x14, 0xB8, 0xAC,
+ 0x35, 0xE2, 0xAA, 0x0B, 0x5C, 0xF8, 0x38, 0x4D, 0x04, 0xEE, 0xA9, 0x97,
+ 0x70, 0xFB, 0x5E, 0xE7, 0xB7, 0xE3, 0x62, 0x23, 0x4B, 0x38, 0xBE, 0xD6,
+ 0x53, 0x15, 0xF7, 0xDF, 0x87, 0xB4, 0x0E, 0xCC, 0xB1, 0x1A, 0x11, 0x19,
+ 0xEE, 0x51, 0xCC, 0x92, 0xDD, 0xBC, 0x63, 0x29, 0x63, 0x0C, 0x59, 0xD7,
+ 0x6F, 0x4C, 0x3C, 0x37, 0x5B, 0x37, 0x03, 0x61, 0x7D, 0x24, 0x1C, 0x99,
+ 0x48, 0xAF, 0x82, 0xFE, 0x32, 0x41, 0x9B, 0xB2, 0xDB, 0xEA, 0xED, 0x76,
+ 0x8E, 0x6E, 0xCA, 0x7E, 0x4E, 0x14, 0xBA, 0x30, 0x84, 0x1C, 0xB3, 0x67,
+ 0xA3, 0x29, 0x80, 0x70, 0x54, 0x68, 0x7D, 0x49
+};
+
+static const unsigned char kat_RSA_X931_SHA256[] = {
+ 0x7E, 0xA2, 0x77, 0xFE, 0xB8, 0x54, 0x8A, 0xC7, 0x7F, 0x64, 0x54, 0x89,
+ 0xE5, 0x52, 0x15, 0x8E, 0x52, 0x96, 0x4E, 0xA6, 0x58, 0x92, 0x1C, 0xDD,
+ 0xEA, 0xA2, 0x2D, 0x5C, 0xD1, 0x62, 0x00, 0x49, 0x05, 0x95, 0x73, 0xCF,
+ 0x16, 0x76, 0x68, 0xF6, 0xC6, 0x5E, 0x80, 0xB8, 0xB8, 0x7B, 0xC8, 0x9B,
+ 0xC6, 0x53, 0x88, 0x26, 0x20, 0x88, 0x73, 0xB6, 0x13, 0xB8, 0xF0, 0x4B,
+ 0x00, 0x85, 0xF3, 0xDD, 0x07, 0x50, 0xEB, 0x20, 0xC4, 0x38, 0x0E, 0x98,
+ 0xAD, 0x4E, 0x49, 0x2C, 0xD7, 0x65, 0xA5, 0x19, 0x0E, 0x59, 0x01, 0xEC,
+ 0x7E, 0x75, 0x89, 0x69, 0x2E, 0x63, 0x76, 0x85, 0x46, 0x8D, 0xA0, 0x8C,
+ 0x33, 0x1D, 0x82, 0x8C, 0x03, 0xEA, 0x69, 0x88, 0x35, 0xA1, 0x42, 0xBD,
+ 0x21, 0xED, 0x8D, 0xBC, 0xBC, 0xDB, 0x30, 0xFF, 0x86, 0xF0, 0x5B, 0xDC,
+ 0xE3, 0xE2, 0xE8, 0x0A, 0x0A, 0x29, 0x94, 0x80
+};
+
+static const unsigned char kat_RSA_X931_SHA384[] = {
+ 0x5C, 0x7D, 0x96, 0x35, 0xEC, 0x7E, 0x11, 0x38, 0xBB, 0x7B, 0xEC, 0x7B,
+ 0xF2, 0x82, 0x8E, 0x99, 0xBD, 0xEF, 0xD8, 0xAE, 0xD7, 0x39, 0x37, 0xCB,
+ 0xE6, 0x4F, 0x5E, 0x0A, 0x13, 0xE4, 0x2E, 0x40, 0xB9, 0xBE, 0x2E, 0xE3,
+ 0xEF, 0x78, 0x83, 0x18, 0x44, 0x35, 0x9C, 0x8E, 0xD7, 0x4A, 0x63, 0xF6,
+ 0x57, 0xC2, 0xB0, 0x08, 0x51, 0x73, 0xCF, 0xCA, 0x99, 0x66, 0xEE, 0x31,
+ 0xD8, 0x69, 0xE9, 0xAB, 0x13, 0x27, 0x7B, 0x41, 0x1E, 0x6D, 0x8D, 0xF1,
+ 0x3E, 0x9C, 0x35, 0x95, 0x58, 0xDD, 0x2B, 0xD5, 0xA0, 0x60, 0x41, 0x79,
+ 0x24, 0x22, 0xE4, 0xB7, 0xBF, 0x47, 0x53, 0xF6, 0x34, 0xD5, 0x7C, 0xFF,
+ 0x0E, 0x09, 0xEE, 0x2E, 0xE2, 0x37, 0xB9, 0xDE, 0xC5, 0x12, 0x44, 0x35,
+ 0xEF, 0x01, 0xE6, 0x5E, 0x39, 0x31, 0x2D, 0x71, 0xA5, 0xDC, 0xC6, 0x6D,
+ 0xE2, 0xCD, 0x85, 0xDB, 0x73, 0x82, 0x65, 0x28
+};
+
+static const unsigned char kat_RSA_X931_SHA512[] = {
+ 0xA6, 0x65, 0xA2, 0x77, 0x4F, 0xB3, 0x86, 0xCB, 0x64, 0x3A, 0xC1, 0x63,
+ 0xFC, 0xA1, 0xAA, 0xCB, 0x9B, 0x79, 0xDD, 0x4B, 0xE1, 0xD9, 0xDA, 0xAC,
+ 0xE7, 0x47, 0x09, 0xB2, 0x11, 0x4B, 0x8A, 0xAA, 0x05, 0x9E, 0x77, 0xD7,
+ 0x3A, 0xBD, 0x5E, 0x53, 0x09, 0x4A, 0xE6, 0x0F, 0x5E, 0xF9, 0x14, 0x28,
+ 0xA0, 0x99, 0x74, 0x64, 0x70, 0x4E, 0xF2, 0xE3, 0xFA, 0xC7, 0xF8, 0xC5,
+ 0x6E, 0x2B, 0x79, 0x96, 0x0D, 0x0C, 0xC8, 0x10, 0x34, 0x53, 0xD2, 0xAF,
+ 0x17, 0x0E, 0xE0, 0xBF, 0x79, 0xF6, 0x04, 0x72, 0x10, 0xE0, 0xF6, 0xD0,
+ 0xCE, 0x8A, 0x6F, 0xA1, 0x95, 0x89, 0xBF, 0x58, 0x8F, 0x46, 0x5F, 0x09,
+ 0x9F, 0x09, 0xCA, 0x84, 0x15, 0x85, 0xE0, 0xED, 0x04, 0x2D, 0xFB, 0x7C,
+ 0x36, 0x35, 0x21, 0x31, 0xC3, 0xFD, 0x92, 0x42, 0x11, 0x30, 0x71, 0x1B,
+ 0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3
+};
+
+
+int FIPS_selftest_rsa()
+ {
+ int ret = 0;
+ RSA *key = NULL;
+ EVP_PKEY pk;
+ key=FIPS_rsa_new();
+ setrsakey(key);
+ pk.type = EVP_PKEY_RSA;
+ pk.pkey.rsa = key;
+
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_SHA1, sizeof(kat_RSA_SHA1),
+ EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+ "RSA SHA1 PKCS#1"))
+ goto err;
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_SHA224, sizeof(kat_RSA_SHA224),
+ EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+ "RSA SHA224 PKCS#1"))
+ goto err;
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_SHA256, sizeof(kat_RSA_SHA256),
+ EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+ "RSA SHA256 PKCS#1"))
+ goto err;
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_SHA384, sizeof(kat_RSA_SHA384),
+ EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+ "RSA SHA384 PKCS#1"))
+ goto err;
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_SHA512, sizeof(kat_RSA_SHA512),
+ EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PKCS1,
+ "RSA SHA512 PKCS#1"))
+ goto err;
+
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_PSS_SHA1, sizeof(kat_RSA_PSS_SHA1),
+ EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS,
+ "RSA SHA1 PSS"))
+ goto err;
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_PSS_SHA224, sizeof(kat_RSA_PSS_SHA224),
+ EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PSS,
+ "RSA SHA224 PSS"))
+ goto err;
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_PSS_SHA256, sizeof(kat_RSA_PSS_SHA256),
+ EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PSS,
+ "RSA SHA256 PSS"))
+ goto err;
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_PSS_SHA384, sizeof(kat_RSA_PSS_SHA384),
+ EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PSS,
+ "RSA SHA384 PSS"))
+ goto err;
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_PSS_SHA512, sizeof(kat_RSA_PSS_SHA512),
+ EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PSS,
+ "RSA SHA512 PSS"))
+ goto err;
+
+
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_X931_SHA1, sizeof(kat_RSA_X931_SHA1),
+ EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931,
+ "RSA SHA1 X931"))
+ goto err;
+ /* NB: SHA224 not supported in X9.31 */
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_X931_SHA256, sizeof(kat_RSA_X931_SHA256),
+ EVP_sha256(), EVP_MD_CTX_FLAG_PAD_X931,
+ "RSA SHA256 X931"))
+ goto err;
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_X931_SHA384, sizeof(kat_RSA_X931_SHA384),
+ EVP_sha384(), EVP_MD_CTX_FLAG_PAD_X931,
+ "RSA SHA384 X931"))
+ goto err;
+ if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
+ kat_RSA_X931_SHA512, sizeof(kat_RSA_X931_SHA512),
+ EVP_sha512(), EVP_MD_CTX_FLAG_PAD_X931,
+ "RSA SHA512 X931"))
+ goto err;
+
+
+ ret = 1;
+
+ err:
+ FIPS_rsa_free(key);
+ return ret;
+ }
+
+#endif /* def OPENSSL_FIPS */
diff --git a/crypto/openssl/fips/rsa/fips_rsa_sign.c b/crypto/openssl/fips/rsa/fips_rsa_sign.c
new file mode 100644
index 0000000..3736462
--- /dev/null
+++ b/crypto/openssl/fips/rsa/fips_rsa_sign.c
@@ -0,0 +1,554 @@
+/* fips_rsa_sign.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/err.h>
+#include <openssl/sha.h>
+
+#ifdef OPENSSL_FIPS
+
+/* FIPS versions of RSA_sign() and RSA_verify().
+ * These will only have to deal with SHA* signatures and by including
+ * pregenerated encodings all ASN1 dependencies can be avoided
+ */
+
+/* Standard encodings including NULL parameter */
+
+static const unsigned char sha1_bin[] = {
+ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
+ 0x00, 0x04, 0x14
+};
+
+static const unsigned char sha224_bin[] = {
+ 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+ 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c
+};
+
+static const unsigned char sha256_bin[] = {
+ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+ 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+};
+
+static const unsigned char sha384_bin[] = {
+ 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+ 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30
+};
+
+static const unsigned char sha512_bin[] = {
+ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+ 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
+};
+
+/* Alternate encodings with absent parameters. We don't generate signature
+ * using this format but do tolerate received signatures of this form.
+ */
+
+static unsigned char sha1_nn_bin[] = {
+ 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04,
+ 0x14
+};
+
+static unsigned char sha224_nn_bin[] = {
+ 0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+ 0x04, 0x02, 0x04, 0x04, 0x1c
+};
+
+static unsigned char sha256_nn_bin[] = {
+ 0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+ 0x04, 0x02, 0x01, 0x04, 0x20
+};
+
+static unsigned char sha384_nn_bin[] = {
+ 0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+ 0x04, 0x02, 0x02, 0x04, 0x30
+};
+
+static unsigned char sha512_nn_bin[] = {
+ 0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+ 0x04, 0x02, 0x03, 0x04, 0x40
+};
+
+
+static const unsigned char *fips_digestinfo_encoding(int nid, unsigned int *len)
+ {
+ switch (nid)
+ {
+
+ case NID_sha1:
+ *len = sizeof(sha1_bin);
+ return sha1_bin;
+
+ case NID_sha224:
+ *len = sizeof(sha224_bin);
+ return sha224_bin;
+
+ case NID_sha256:
+ *len = sizeof(sha256_bin);
+ return sha256_bin;
+
+ case NID_sha384:
+ *len = sizeof(sha384_bin);
+ return sha384_bin;
+
+ case NID_sha512:
+ *len = sizeof(sha512_bin);
+ return sha512_bin;
+
+ default:
+ return NULL;
+
+ }
+ }
+
+static const unsigned char *fips_digestinfo_nn_encoding(int nid, unsigned int *len)
+ {
+ switch (nid)
+ {
+
+ case NID_sha1:
+ *len = sizeof(sha1_nn_bin);
+ return sha1_nn_bin;
+
+ case NID_sha224:
+ *len = sizeof(sha224_nn_bin);
+ return sha224_nn_bin;
+
+ case NID_sha256:
+ *len = sizeof(sha256_nn_bin);
+ return sha256_nn_bin;
+
+ case NID_sha384:
+ *len = sizeof(sha384_nn_bin);
+ return sha384_nn_bin;
+
+ case NID_sha512:
+ *len = sizeof(sha512_nn_bin);
+ return sha512_nn_bin;
+
+ default:
+ return NULL;
+
+ }
+ }
+
+static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y,
+ unsigned char *sigret, unsigned int *siglen, EVP_MD_SVCTX *sv)
+ {
+ int i=0,j,ret=0;
+ unsigned int dlen;
+ const unsigned char *der;
+ unsigned int m_len;
+ int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;
+ int rsa_pad_mode = 0;
+ RSA *rsa = sv->key;
+ /* Largest DigestInfo: 19 (max encoding) + max MD */
+ unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE];
+ unsigned char md[EVP_MAX_MD_SIZE + 1];
+
+ EVP_DigestFinal_ex(sv->mctx, md, &m_len);
+
+ if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign)
+ {
+ ret = rsa->meth->rsa_sign(type, md, m_len,
+ sigret, siglen, rsa);
+ goto done;
+ }
+
+ if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
+ {
+ int hash_id;
+ memcpy(tmpdinfo, md, m_len);
+ hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
+ if (hash_id == -1)
+ {
+ RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
+ return 0;
+ }
+ tmpdinfo[m_len] = (unsigned char)hash_id;
+ i = m_len + 1;
+ rsa_pad_mode = RSA_X931_PADDING;
+ }
+ else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)
+ {
+
+ der = fips_digestinfo_encoding(type, &dlen);
+
+ if (!der)
+ {
+ RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
+ return 0;
+ }
+ memcpy(tmpdinfo, der, dlen);
+ memcpy(tmpdinfo + dlen, md, m_len);
+
+ i = dlen + m_len;
+ rsa_pad_mode = RSA_PKCS1_PADDING;
+
+ }
+ else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)
+ {
+ unsigned char *sbuf;
+ int saltlen;
+ i = RSA_size(rsa);
+ sbuf = OPENSSL_malloc(RSA_size(rsa));
+ saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);
+ if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
+ saltlen = -1;
+ else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
+ saltlen = -2;
+ if (!sbuf)
+ {
+ RSAerr(RSA_F_FIPS_RSA_SIGN,ERR_R_MALLOC_FAILURE);
+ goto psserr;
+ }
+ if (!RSA_padding_add_PKCS1_PSS(rsa, sbuf, md,
+ M_EVP_MD_CTX_md(sv->mctx), saltlen))
+ goto psserr;
+ j=rsa->meth->rsa_priv_enc(i,sbuf,sigret,rsa,RSA_NO_PADDING);
+ if (j > 0)
+ {
+ ret=1;
+ *siglen=j;
+ }
+ psserr:
+ OPENSSL_cleanse(md,m_len);
+ OPENSSL_cleanse(sbuf, i);
+ OPENSSL_free(sbuf);
+ return ret;
+ }
+
+ j=RSA_size(rsa);
+ if (i > (j-RSA_PKCS1_PADDING_SIZE))
+ {
+ RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+ goto done;
+ }
+ /* NB: call underlying method directly to avoid FIPS blocking */
+ j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,rsa_pad_mode);
+ if (j > 0)
+ {
+ ret=1;
+ *siglen=j;
+ }
+
+ done:
+ OPENSSL_cleanse(tmpdinfo,i);
+ OPENSSL_cleanse(md,m_len);
+ return ret;
+ }
+
+static int fips_rsa_verify(int dtype,
+ const unsigned char *x, unsigned int y,
+ unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv)
+ {
+ int i,ret=0;
+ unsigned int dlen, diglen;
+ int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;
+ int rsa_pad_mode = 0;
+ unsigned char *s;
+ const unsigned char *der;
+ unsigned char dig[EVP_MAX_MD_SIZE];
+ RSA *rsa = sv->key;
+
+ if (siglen != (unsigned int)RSA_size(sv->key))
+ {
+ RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
+ return(0);
+ }
+
+ EVP_DigestFinal_ex(sv->mctx, dig, &diglen);
+
+ if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
+ {
+ return rsa->meth->rsa_verify(dtype, dig, diglen,
+ sigbuf, siglen, rsa);
+ }
+
+
+ s= OPENSSL_malloc((unsigned int)siglen);
+ if (s == NULL)
+ {
+ RSAerr(RSA_F_FIPS_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
+ rsa_pad_mode = RSA_X931_PADDING;
+ else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)
+ rsa_pad_mode = RSA_PKCS1_PADDING;
+ else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)
+ rsa_pad_mode = RSA_NO_PADDING;
+
+ /* NB: call underlying method directly to avoid FIPS blocking */
+ i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s, rsa, rsa_pad_mode);
+
+ if (i <= 0) goto err;
+
+ if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
+ {
+ int hash_id;
+ if (i != (int)(diglen + 1))
+ {
+ RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+ goto err;
+ }
+ hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
+ if (hash_id == -1)
+ {
+ RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE);
+ goto err;
+ }
+ if (s[diglen] != (unsigned char)hash_id)
+ {
+ RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+ goto err;
+ }
+ if (memcmp(s, dig, diglen))
+ {
+ RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+ goto err;
+ }
+ ret = 1;
+ }
+ else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)
+ {
+
+ der = fips_digestinfo_encoding(dtype, &dlen);
+
+ if (!der)
+ {
+ RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE);
+ return(0);
+ }
+
+ /* Compare, DigestInfo length, DigestInfo header and finally
+ * digest value itself
+ */
+
+ /* If length mismatch try alternate encoding */
+ if (i != (int)(dlen + diglen))
+ der = fips_digestinfo_nn_encoding(dtype, &dlen);
+
+ if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen)
+ || memcmp(s + dlen, dig, diglen))
+ {
+ RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
+ goto err;
+ }
+ ret = 1;
+
+ }
+ else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)
+ {
+ int saltlen;
+ saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);
+ if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
+ saltlen = -1;
+ else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
+ saltlen = -2;
+ ret = RSA_verify_PKCS1_PSS(rsa, dig, M_EVP_MD_CTX_md(sv->mctx),
+ s, saltlen);
+ if (ret < 0)
+ ret = 0;
+ }
+err:
+ if (s != NULL)
+ {
+ OPENSSL_cleanse(s, siglen);
+ OPENSSL_free(s);
+ }
+ return(ret);
+ }
+
+#define EVP_PKEY_RSA_fips_method \
+ (evp_sign_method *)fips_rsa_sign, \
+ (evp_verify_method *)fips_rsa_verify, \
+ {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+
+static int init(EVP_MD_CTX *ctx)
+ { return SHA1_Init(ctx->md_data); }
+
+static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
+ { return SHA1_Update(ctx->md_data,data,count); }
+
+static int final(EVP_MD_CTX *ctx,unsigned char *md)
+ { return SHA1_Final(md,ctx->md_data); }
+
+static const EVP_MD sha1_md=
+ {
+ NID_sha1,
+ NID_sha1WithRSAEncryption,
+ SHA_DIGEST_LENGTH,
+ EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
+ init,
+ update,
+ final,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_fips_method,
+ SHA_CBLOCK,
+ sizeof(EVP_MD *)+sizeof(SHA_CTX),
+ };
+
+const EVP_MD *EVP_sha1(void)
+ {
+ return(&sha1_md);
+ }
+
+static int init224(EVP_MD_CTX *ctx)
+ { return SHA224_Init(ctx->md_data); }
+static int init256(EVP_MD_CTX *ctx)
+ { return SHA256_Init(ctx->md_data); }
+/*
+ * Even though there're separate SHA224_[Update|Final], we call
+ * SHA256 functions even in SHA224 context. This is what happens
+ * there anyway, so we can spare few CPU cycles:-)
+ */
+static int update256(EVP_MD_CTX *ctx,const void *data,size_t count)
+ { return SHA256_Update(ctx->md_data,data,count); }
+static int final256(EVP_MD_CTX *ctx,unsigned char *md)
+ { return SHA256_Final(md,ctx->md_data); }
+
+static const EVP_MD sha224_md=
+ {
+ NID_sha224,
+ NID_sha224WithRSAEncryption,
+ SHA224_DIGEST_LENGTH,
+ EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
+ init224,
+ update256,
+ final256,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_fips_method,
+ SHA256_CBLOCK,
+ sizeof(EVP_MD *)+sizeof(SHA256_CTX),
+ };
+
+const EVP_MD *EVP_sha224(void)
+ { return(&sha224_md); }
+
+static const EVP_MD sha256_md=
+ {
+ NID_sha256,
+ NID_sha256WithRSAEncryption,
+ SHA256_DIGEST_LENGTH,
+ EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
+ init256,
+ update256,
+ final256,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_fips_method,
+ SHA256_CBLOCK,
+ sizeof(EVP_MD *)+sizeof(SHA256_CTX),
+ };
+
+const EVP_MD *EVP_sha256(void)
+ { return(&sha256_md); }
+
+static int init384(EVP_MD_CTX *ctx)
+ { return SHA384_Init(ctx->md_data); }
+static int init512(EVP_MD_CTX *ctx)
+ { return SHA512_Init(ctx->md_data); }
+/* See comment in SHA224/256 section */
+static int update512(EVP_MD_CTX *ctx,const void *data,size_t count)
+ { return SHA512_Update(ctx->md_data,data,count); }
+static int final512(EVP_MD_CTX *ctx,unsigned char *md)
+ { return SHA512_Final(md,ctx->md_data); }
+
+static const EVP_MD sha384_md=
+ {
+ NID_sha384,
+ NID_sha384WithRSAEncryption,
+ SHA384_DIGEST_LENGTH,
+ EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
+ init384,
+ update512,
+ final512,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_fips_method,
+ SHA512_CBLOCK,
+ sizeof(EVP_MD *)+sizeof(SHA512_CTX),
+ };
+
+const EVP_MD *EVP_sha384(void)
+ { return(&sha384_md); }
+
+static const EVP_MD sha512_md=
+ {
+ NID_sha512,
+ NID_sha512WithRSAEncryption,
+ SHA512_DIGEST_LENGTH,
+ EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
+ init512,
+ update512,
+ final512,
+ NULL,
+ NULL,
+ EVP_PKEY_RSA_fips_method,
+ SHA512_CBLOCK,
+ sizeof(EVP_MD *)+sizeof(SHA512_CTX),
+ };
+
+const EVP_MD *EVP_sha512(void)
+ { return(&sha512_md); }
+
+#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsa_x931g.c b/crypto/openssl/fips/rsa/fips_rsa_x931g.c
new file mode 100644
index 0000000..d9f9a81
--- /dev/null
+++ b/crypto/openssl/fips/rsa/fips_rsa_x931g.c
@@ -0,0 +1,280 @@
+/* crypto/rsa/rsa_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/fips.h>
+
+#ifdef OPENSSL_FIPS
+
+extern int fips_check_rsa(RSA *rsa);
+
+
+/* X9.31 RSA key derivation and generation */
+
+int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2,
+ const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp,
+ const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq,
+ const BIGNUM *e, BN_GENCB *cb)
+ {
+ BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL;
+ BN_CTX *ctx=NULL,*ctx2=NULL;
+
+ if (!rsa)
+ goto err;
+
+ ctx = BN_CTX_new();
+ BN_CTX_start(ctx);
+ if (!ctx)
+ goto err;
+
+ r0 = BN_CTX_get(ctx);
+ r1 = BN_CTX_get(ctx);
+ r2 = BN_CTX_get(ctx);
+ r3 = BN_CTX_get(ctx);
+
+ if (r3 == NULL)
+ goto err;
+ if (!rsa->e)
+ {
+ rsa->e = BN_dup(e);
+ if (!rsa->e)
+ goto err;
+ }
+ else
+ e = rsa->e;
+
+ /* If not all parameters present only calculate what we can.
+ * This allows test programs to output selective parameters.
+ */
+
+ if (Xp && !rsa->p)
+ {
+ rsa->p = BN_new();
+ if (!rsa->p)
+ goto err;
+
+ if (!BN_X931_derive_prime_ex(rsa->p, p1, p2,
+ Xp, Xp1, Xp2, e, ctx, cb))
+ goto err;
+ }
+
+ if (Xq && !rsa->q)
+ {
+ rsa->q = BN_new();
+ if (!rsa->q)
+ goto err;
+ if (!BN_X931_derive_prime_ex(rsa->q, q1, q2,
+ Xq, Xq1, Xq2, e, ctx, cb))
+ goto err;
+ }
+
+ if (!rsa->p || !rsa->q)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return 2;
+ }
+
+ /* Since both primes are set we can now calculate all remaining
+ * components.
+ */
+
+ /* calculate n */
+ rsa->n=BN_new();
+ if (rsa->n == NULL)
+ goto err;
+ if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx))
+ goto err;
+
+ /* calculate d */
+ if (!BN_sub(r1,rsa->p,BN_value_one()))
+ goto err; /* p-1 */
+ if (!BN_sub(r2,rsa->q,BN_value_one()))
+ goto err; /* q-1 */
+ if (!BN_mul(r0,r1,r2,ctx))
+ goto err; /* (p-1)(q-1) */
+
+ if (!BN_gcd(r3, r1, r2, ctx))
+ goto err;
+
+ if (!BN_div(r0, NULL, r0, r3, ctx))
+ goto err; /* LCM((p-1)(q-1)) */
+
+ ctx2 = BN_CTX_new();
+ if (!ctx2)
+ goto err;
+
+ rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */
+ if (rsa->d == NULL)
+ goto err;
+
+ /* calculate d mod (p-1) */
+ rsa->dmp1=BN_new();
+ if (rsa->dmp1 == NULL)
+ goto err;
+ if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx))
+ goto err;
+
+ /* calculate d mod (q-1) */
+ rsa->dmq1=BN_new();
+ if (rsa->dmq1 == NULL)
+ goto err;
+ if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx))
+ goto err;
+
+ /* calculate inverse of q mod p */
+ rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2);
+
+ err:
+ if (ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (ctx2)
+ BN_CTX_free(ctx2);
+ /* If this is set all calls successful */
+ if (rsa->iqmp != NULL)
+ return 1;
+
+ return 0;
+
+ }
+
+int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb)
+ {
+ int ok = 0;
+ BIGNUM *Xp = NULL, *Xq = NULL;
+ BN_CTX *ctx = NULL;
+
+ if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)
+ {
+ FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_KEY_TOO_SHORT);
+ return 0;
+ }
+
+ if (bits & 0xff)
+ {
+ FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+
+ if(FIPS_selftest_failed())
+ {
+ FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_FIPS_SELFTEST_FAILED);
+ return 0;
+ }
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ goto error;
+
+ BN_CTX_start(ctx);
+ Xp = BN_CTX_get(ctx);
+ Xq = BN_CTX_get(ctx);
+ if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx))
+ goto error;
+
+ rsa->p = BN_new();
+ rsa->q = BN_new();
+ if (!rsa->p || !rsa->q)
+ goto error;
+
+ /* Generate two primes from Xp, Xq */
+
+ if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp,
+ e, ctx, cb))
+ goto error;
+
+ if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq,
+ e, ctx, cb))
+ goto error;
+
+ /* Since rsa->p and rsa->q are valid this call will just derive
+ * remaining RSA components.
+ */
+
+ if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, e, cb))
+ goto error;
+
+ if(!fips_check_rsa(rsa))
+ goto error;
+
+ ok = 1;
+
+ error:
+ if (ctx)
+ {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+
+ if (ok)
+ return 1;
+
+ return 0;
+
+ }
+
+#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsagtest.c b/crypto/openssl/fips/rsa/fips_rsagtest.c
new file mode 100644
index 0000000..657e1b6
--- /dev/null
+++ b/crypto/openssl/fips/rsa/fips_rsagtest.c
@@ -0,0 +1,390 @@
+/* fips_rsagtest.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005,2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+ printf("No FIPS RSA support\n");
+ return(0);
+}
+
+#else
+
+#include <openssl/rsa.h>
+#include "fips_utl.h"
+
+int rsa_test(FILE *out, FILE *in);
+static int rsa_printkey1(FILE *out, RSA *rsa,
+ BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp,
+ BIGNUM *e);
+static int rsa_printkey2(FILE *out, RSA *rsa,
+ BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq);
+
+int main(int argc, char **argv)
+ {
+ FILE *in = NULL, *out = NULL;
+
+ int ret = 1;
+
+ if(!FIPS_mode_set(1))
+ {
+ do_print_errors();
+ goto end;
+ }
+
+ if (argc == 1)
+ in = stdin;
+ else
+ in = fopen(argv[1], "r");
+
+ if (argc < 2)
+ out = stdout;
+ else
+ out = fopen(argv[2], "w");
+
+ if (!in)
+ {
+ fprintf(stderr, "FATAL input initialization error\n");
+ goto end;
+ }
+
+ if (!out)
+ {
+ fprintf(stderr, "FATAL output initialization error\n");
+ goto end;
+ }
+
+ if (!rsa_test(out, in))
+ {
+ fprintf(stderr, "FATAL RSAGTEST file processing error\n");
+ goto end;
+ }
+ else
+ ret = 0;
+
+ end:
+
+ if (ret)
+ do_print_errors();
+
+ if (in && (in != stdin))
+ fclose(in);
+ if (out && (out != stdout))
+ fclose(out);
+
+ return ret;
+
+ }
+
+#define RSA_TEST_MAXLINELEN 10240
+
+int rsa_test(FILE *out, FILE *in)
+ {
+ char *linebuf, *olinebuf, *p, *q;
+ char *keyword, *value;
+ RSA *rsa = NULL;
+ BIGNUM *Xp1 = NULL, *Xp2 = NULL, *Xp = NULL;
+ BIGNUM *Xq1 = NULL, *Xq2 = NULL, *Xq = NULL;
+ BIGNUM *e = NULL;
+ int ret = 0;
+ int lnum = 0;
+
+ olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
+ linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
+
+ if (!linebuf || !olinebuf)
+ goto error;
+
+ while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
+ {
+ lnum++;
+ strcpy(linebuf, olinebuf);
+ keyword = linebuf;
+ /* Skip leading space */
+ while (isspace((unsigned char)*keyword))
+ keyword++;
+
+ /* Look for = sign */
+ p = strchr(linebuf, '=');
+
+ /* If no = or starts with [ (for [foo = bar] line) just copy */
+ if (!p || *keyword=='[')
+ {
+ if (fputs(olinebuf, out) < 0)
+ goto error;
+ continue;
+ }
+
+ q = p - 1;
+
+ /* Remove trailing space */
+ while (isspace((unsigned char)*q))
+ *q-- = 0;
+
+ *p = 0;
+ value = p + 1;
+
+ /* Remove leading space from value */
+ while (isspace((unsigned char)*value))
+ value++;
+
+ /* Remove trailing space from value */
+ p = value + strlen(value) - 1;
+
+ while (*p == '\n' || isspace((unsigned char)*p))
+ *p-- = 0;
+
+ if (!strcmp(keyword, "xp1"))
+ {
+ if (Xp1 || !do_hex2bn(&Xp1,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "xp2"))
+ {
+ if (Xp2 || !do_hex2bn(&Xp2,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "Xp"))
+ {
+ if (Xp || !do_hex2bn(&Xp,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "xq1"))
+ {
+ if (Xq1 || !do_hex2bn(&Xq1,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "xq2"))
+ {
+ if (Xq2 || !do_hex2bn(&Xq2,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "Xq"))
+ {
+ if (Xq || !do_hex2bn(&Xq,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "e"))
+ {
+ if (e || !do_hex2bn(&e,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "p1"))
+ continue;
+ else if (!strcmp(keyword, "p2"))
+ continue;
+ else if (!strcmp(keyword, "p"))
+ continue;
+ else if (!strcmp(keyword, "q1"))
+ continue;
+ else if (!strcmp(keyword, "q2"))
+ continue;
+ else if (!strcmp(keyword, "q"))
+ continue;
+ else if (!strcmp(keyword, "n"))
+ continue;
+ else if (!strcmp(keyword, "d"))
+ continue;
+ else
+ goto parse_error;
+
+ fputs(olinebuf, out);
+
+ if (e && Xp1 && Xp2 && Xp)
+ {
+ rsa = FIPS_rsa_new();
+ if (!rsa)
+ goto error;
+ if (!rsa_printkey1(out, rsa, Xp1, Xp2, Xp, e))
+ goto error;
+ BN_free(Xp1);
+ Xp1 = NULL;
+ BN_free(Xp2);
+ Xp2 = NULL;
+ BN_free(Xp);
+ Xp = NULL;
+ BN_free(e);
+ e = NULL;
+ }
+
+ if (rsa && Xq1 && Xq2 && Xq)
+ {
+ if (!rsa_printkey2(out, rsa, Xq1, Xq2, Xq))
+ goto error;
+ BN_free(Xq1);
+ Xq1 = NULL;
+ BN_free(Xq2);
+ Xq2 = NULL;
+ BN_free(Xq);
+ Xq = NULL;
+ FIPS_rsa_free(rsa);
+ rsa = NULL;
+ }
+ }
+
+ ret = 1;
+
+ error:
+
+ if (olinebuf)
+ OPENSSL_free(olinebuf);
+ if (linebuf)
+ OPENSSL_free(linebuf);
+
+ if (Xp1)
+ BN_free(Xp1);
+ if (Xp2)
+ BN_free(Xp2);
+ if (Xp)
+ BN_free(Xp);
+ if (Xq1)
+ BN_free(Xq1);
+ if (Xq1)
+ BN_free(Xq1);
+ if (Xq2)
+ BN_free(Xq2);
+ if (Xq)
+ BN_free(Xq);
+ if (e)
+ BN_free(e);
+ if (rsa)
+ FIPS_rsa_free(rsa);
+
+ return ret;
+
+ parse_error:
+
+ fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
+
+ goto error;
+
+ }
+
+static int rsa_printkey1(FILE *out, RSA *rsa,
+ BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp,
+ BIGNUM *e)
+ {
+ int ret = 0;
+ BIGNUM *p1 = NULL, *p2 = NULL;
+ p1 = BN_new();
+ p2 = BN_new();
+ if (!p1 || !p2)
+ goto error;
+
+ if (!RSA_X931_derive_ex(rsa, p1, p2, NULL, NULL, Xp1, Xp2, Xp,
+ NULL, NULL, NULL, e, NULL))
+ goto error;
+
+ do_bn_print_name(out, "p1", p1);
+ do_bn_print_name(out, "p2", p2);
+ do_bn_print_name(out, "p", rsa->p);
+
+ ret = 1;
+
+ error:
+ if (p1)
+ BN_free(p1);
+ if (p2)
+ BN_free(p2);
+
+ return ret;
+ }
+
+static int rsa_printkey2(FILE *out, RSA *rsa,
+ BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq)
+ {
+ int ret = 0;
+ BIGNUM *q1 = NULL, *q2 = NULL;
+ q1 = BN_new();
+ q2 = BN_new();
+ if (!q1 || !q2)
+ goto error;
+
+ if (!RSA_X931_derive_ex(rsa, NULL, NULL, q1, q2, NULL, NULL, NULL,
+ Xq1, Xq2, Xq, NULL, NULL))
+ goto error;
+
+ do_bn_print_name(out, "q1", q1);
+ do_bn_print_name(out, "q2", q2);
+ do_bn_print_name(out, "q", rsa->q);
+ do_bn_print_name(out, "n", rsa->n);
+ do_bn_print_name(out, "d", rsa->d);
+
+ ret = 1;
+
+ error:
+ if (q1)
+ BN_free(q1);
+ if (q2)
+ BN_free(q2);
+
+ return ret;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsastest.c b/crypto/openssl/fips/rsa/fips_rsastest.c
new file mode 100644
index 0000000..452084f
--- /dev/null
+++ b/crypto/openssl/fips/rsa/fips_rsastest.c
@@ -0,0 +1,370 @@
+/* fips_rsastest.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+ printf("No FIPS RSA support\n");
+ return(0);
+}
+
+#else
+
+#include <openssl/rsa.h>
+#include "fips_utl.h"
+
+static int rsa_stest(FILE *out, FILE *in, int Saltlen);
+static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst,
+ unsigned char *Msg, long Msglen, int Saltlen);
+
+int main(int argc, char **argv)
+ {
+ FILE *in = NULL, *out = NULL;
+
+ int ret = 1, Saltlen = -1;
+
+ if(!FIPS_mode_set(1))
+ {
+ do_print_errors();
+ goto end;
+ }
+
+ if ((argc > 2) && !strcmp("-saltlen", argv[1]))
+ {
+ Saltlen = atoi(argv[2]);
+ if (Saltlen < 0)
+ {
+ fprintf(stderr, "FATAL: Invalid salt length\n");
+ goto end;
+ }
+ argc -= 2;
+ argv += 2;
+ }
+ else if ((argc > 1) && !strcmp("-x931", argv[1]))
+ {
+ Saltlen = -2;
+ argc--;
+ argv++;
+ }
+
+ if (argc == 1)
+ in = stdin;
+ else
+ in = fopen(argv[1], "r");
+
+ if (argc < 2)
+ out = stdout;
+ else
+ out = fopen(argv[2], "w");
+
+ if (!in)
+ {
+ fprintf(stderr, "FATAL input initialization error\n");
+ goto end;
+ }
+
+ if (!out)
+ {
+ fprintf(stderr, "FATAL output initialization error\n");
+ goto end;
+ }
+
+ if (!rsa_stest(out, in, Saltlen))
+ {
+ fprintf(stderr, "FATAL RSASTEST file processing error\n");
+ goto end;
+ }
+ else
+ ret = 0;
+
+ end:
+
+ if (ret)
+ do_print_errors();
+
+ if (in && (in != stdin))
+ fclose(in);
+ if (out && (out != stdout))
+ fclose(out);
+
+ return ret;
+
+ }
+
+#define RSA_TEST_MAXLINELEN 10240
+
+int rsa_stest(FILE *out, FILE *in, int Saltlen)
+ {
+ char *linebuf, *olinebuf, *p, *q;
+ char *keyword, *value;
+ RSA *rsa = NULL;
+ const EVP_MD *dgst = NULL;
+ unsigned char *Msg = NULL;
+ long Msglen = -1;
+ int keylen = -1, current_keylen = -1;
+ int ret = 0;
+ int lnum = 0;
+
+ olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
+ linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
+
+ if (!linebuf || !olinebuf)
+ goto error;
+
+ while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
+ {
+ lnum++;
+ strcpy(linebuf, olinebuf);
+ keyword = linebuf;
+ /* Skip leading space */
+ while (isspace((unsigned char)*keyword))
+ keyword++;
+
+ /* Look for = sign */
+ p = strchr(linebuf, '=');
+
+ /* If no = just copy */
+ if (!p)
+ {
+ if (fputs(olinebuf, out) < 0)
+ goto error;
+ continue;
+ }
+
+ q = p - 1;
+
+ /* Remove trailing space */
+ while (isspace((unsigned char)*q))
+ *q-- = 0;
+
+ *p = 0;
+ value = p + 1;
+
+ /* Remove leading space from value */
+ while (isspace((unsigned char)*value))
+ value++;
+
+ /* Remove trailing space from value */
+ p = value + strlen(value) - 1;
+
+ while (*p == '\n' || isspace((unsigned char)*p))
+ *p-- = 0;
+
+ /* Look for [mod = XXX] for key length */
+
+ if (!strcmp(keyword, "[mod"))
+ {
+ p = value + strlen(value) - 1;
+ if (*p != ']')
+ goto parse_error;
+ *p = 0;
+ keylen = atoi(value);
+ if (keylen < 0)
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "SHAAlg"))
+ {
+ if (!strcmp(value, "SHA1"))
+ dgst = EVP_sha1();
+ else if (!strcmp(value, "SHA224"))
+ dgst = EVP_sha224();
+ else if (!strcmp(value, "SHA256"))
+ dgst = EVP_sha256();
+ else if (!strcmp(value, "SHA384"))
+ dgst = EVP_sha384();
+ else if (!strcmp(value, "SHA512"))
+ dgst = EVP_sha512();
+ else
+ {
+ fprintf(stderr,
+ "FATAL: unsupported algorithm \"%s\"\n",
+ value);
+ goto parse_error;
+ }
+ }
+ else if (!strcmp(keyword, "Msg"))
+ {
+ if (Msg)
+ goto parse_error;
+ if (strlen(value) & 1)
+ *(--value) = '0';
+ Msg = hex2bin_m(value, &Msglen);
+ if (!Msg)
+ goto parse_error;
+ }
+
+ fputs(olinebuf, out);
+
+ /* If key length has changed, generate and output public
+ * key components of new RSA private key.
+ */
+
+ if (keylen != current_keylen)
+ {
+ BIGNUM *bn_e;
+ if (rsa)
+ FIPS_rsa_free(rsa);
+ rsa = FIPS_rsa_new();
+ if (!rsa)
+ goto error;
+ bn_e = BN_new();
+ if (!bn_e || !BN_set_word(bn_e, 0x1001))
+ goto error;
+ if (!RSA_X931_generate_key_ex(rsa, keylen, bn_e, NULL))
+ goto error;
+ BN_free(bn_e);
+ fputs("n = ", out);
+ do_bn_print(out, rsa->n);
+ fputs("\ne = ", out);
+ do_bn_print(out, rsa->e);
+ fputs("\n", out);
+ current_keylen = keylen;
+ }
+
+ if (Msg && dgst)
+ {
+ if (!rsa_printsig(out, rsa, dgst, Msg, Msglen,
+ Saltlen))
+ goto error;
+ OPENSSL_free(Msg);
+ Msg = NULL;
+ }
+
+ }
+
+ ret = 1;
+
+ error:
+
+ if (olinebuf)
+ OPENSSL_free(olinebuf);
+ if (linebuf)
+ OPENSSL_free(linebuf);
+ if (rsa)
+ FIPS_rsa_free(rsa);
+
+ return ret;
+
+ parse_error:
+
+ fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
+
+ goto error;
+
+ }
+
+static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst,
+ unsigned char *Msg, long Msglen, int Saltlen)
+ {
+ int ret = 0;
+ unsigned char *sigbuf = NULL;
+ int i, siglen;
+ /* EVP_PKEY structure */
+ EVP_PKEY pk;
+ EVP_MD_CTX ctx;
+ pk.type = EVP_PKEY_RSA;
+ pk.pkey.rsa = rsa;
+
+ siglen = RSA_size(rsa);
+ sigbuf = OPENSSL_malloc(siglen);
+ if (!sigbuf)
+ goto error;
+
+ EVP_MD_CTX_init(&ctx);
+
+ if (Saltlen >= 0)
+ {
+ M_EVP_MD_CTX_set_flags(&ctx,
+ EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16));
+ }
+ else if (Saltlen == -2)
+ M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931);
+ if (!EVP_SignInit_ex(&ctx, dgst, NULL))
+ goto error;
+ if (!EVP_SignUpdate(&ctx, Msg, Msglen))
+ goto error;
+ if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, &pk))
+ goto error;
+
+ EVP_MD_CTX_cleanup(&ctx);
+
+ fputs("S = ", out);
+
+ for (i = 0; i < siglen; i++)
+ fprintf(out, "%02X", sigbuf[i]);
+
+ fputs("\n", out);
+
+ ret = 1;
+
+ error:
+
+ return ret;
+ }
+#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsavtest.c b/crypto/openssl/fips/rsa/fips_rsavtest.c
new file mode 100644
index 0000000..aadab27
--- /dev/null
+++ b/crypto/openssl/fips/rsa/fips_rsavtest.c
@@ -0,0 +1,378 @@
+/* fips_rsavtest.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+ printf("No FIPS RSA support\n");
+ return(0);
+}
+
+#else
+
+#include <openssl/rsa.h>
+
+#include "fips_utl.h"
+
+int rsa_test(FILE *out, FILE *in, int saltlen);
+static int rsa_printver(FILE *out,
+ BIGNUM *n, BIGNUM *e,
+ const EVP_MD *dgst,
+ unsigned char *Msg, long Msglen,
+ unsigned char *S, long Slen, int Saltlen);
+
+int main(int argc, char **argv)
+ {
+ FILE *in = NULL, *out = NULL;
+
+ int ret = 1;
+ int Saltlen = -1;
+
+ if(!FIPS_mode_set(1))
+ {
+ do_print_errors();
+ goto end;
+ }
+
+ if ((argc > 2) && !strcmp("-saltlen", argv[1]))
+ {
+ Saltlen = atoi(argv[2]);
+ if (Saltlen < 0)
+ {
+ fprintf(stderr, "FATAL: Invalid salt length\n");
+ goto end;
+ }
+ argc -= 2;
+ argv += 2;
+ }
+ else if ((argc > 1) && !strcmp("-x931", argv[1]))
+ {
+ Saltlen = -2;
+ argc--;
+ argv++;
+ }
+
+ if (argc == 1)
+ in = stdin;
+ else
+ in = fopen(argv[1], "r");
+
+ if (argc < 2)
+ out = stdout;
+ else
+ out = fopen(argv[2], "w");
+
+ if (!in)
+ {
+ fprintf(stderr, "FATAL input initialization error\n");
+ goto end;
+ }
+
+ if (!out)
+ {
+ fprintf(stderr, "FATAL output initialization error\n");
+ goto end;
+ }
+
+ if (!rsa_test(out, in, Saltlen))
+ {
+ fprintf(stderr, "FATAL RSAVTEST file processing error\n");
+ goto end;
+ }
+ else
+ ret = 0;
+
+ end:
+
+ if (ret)
+ do_print_errors();
+
+ if (in && (in != stdin))
+ fclose(in);
+ if (out && (out != stdout))
+ fclose(out);
+
+ return ret;
+
+ }
+
+#define RSA_TEST_MAXLINELEN 10240
+
+int rsa_test(FILE *out, FILE *in, int Saltlen)
+ {
+ char *linebuf, *olinebuf, *p, *q;
+ char *keyword, *value;
+ const EVP_MD *dgst = NULL;
+ BIGNUM *n = NULL, *e = NULL;
+ unsigned char *Msg = NULL, *S = NULL;
+ long Msglen, Slen;
+ int ret = 0;
+ int lnum = 0;
+
+ olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
+ linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
+
+ if (!linebuf || !olinebuf)
+ goto error;
+
+ while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
+ {
+ lnum++;
+ strcpy(linebuf, olinebuf);
+ keyword = linebuf;
+ /* Skip leading space */
+ while (isspace((unsigned char)*keyword))
+ keyword++;
+
+ /* Look for = sign */
+ p = strchr(linebuf, '=');
+
+ /* If no = or starts with [ (for [foo = bar] line) just copy */
+ if (!p || *keyword=='[')
+ {
+ if (fputs(olinebuf, out) < 0)
+ goto error;
+ continue;
+ }
+
+ q = p - 1;
+
+ /* Remove trailing space */
+ while (isspace((unsigned char)*q))
+ *q-- = 0;
+
+ *p = 0;
+ value = p + 1;
+
+ /* Remove leading space from value */
+ while (isspace((unsigned char)*value))
+ value++;
+
+ /* Remove trailing space from value */
+ p = value + strlen(value) - 1;
+
+ while (*p == '\n' || isspace((unsigned char)*p))
+ *p-- = 0;
+
+ if (!strcmp(keyword, "n"))
+ {
+ if (!do_hex2bn(&n,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "e"))
+ {
+ if (!do_hex2bn(&e,value))
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "SHAAlg"))
+ {
+ if (!strcmp(value, "SHA1"))
+ dgst = EVP_sha1();
+ else if (!strcmp(value, "SHA224"))
+ dgst = EVP_sha224();
+ else if (!strcmp(value, "SHA256"))
+ dgst = EVP_sha256();
+ else if (!strcmp(value, "SHA384"))
+ dgst = EVP_sha384();
+ else if (!strcmp(value, "SHA512"))
+ dgst = EVP_sha512();
+ else
+ {
+ fprintf(stderr,
+ "FATAL: unsupported algorithm \"%s\"\n",
+ value);
+ goto parse_error;
+ }
+ }
+ else if (!strcmp(keyword, "Msg"))
+ {
+ if (Msg)
+ goto parse_error;
+ if (strlen(value) & 1)
+ *(--value) = '0';
+ Msg = hex2bin_m(value, &Msglen);
+ if (!Msg)
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "S"))
+ {
+ if (S)
+ goto parse_error;
+ if (strlen(value) & 1)
+ *(--value) = '0';
+ S = hex2bin_m(value, &Slen);
+ if (!S)
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "Result"))
+ continue;
+ else
+ goto parse_error;
+
+ fputs(olinebuf, out);
+
+ if (n && e && Msg && S && dgst)
+ {
+ if (!rsa_printver(out, n, e, dgst,
+ Msg, Msglen, S, Slen, Saltlen))
+ goto error;
+ OPENSSL_free(Msg);
+ Msg = NULL;
+ OPENSSL_free(S);
+ S = NULL;
+ }
+
+ }
+
+
+ ret = 1;
+
+
+ error:
+
+ if (olinebuf)
+ OPENSSL_free(olinebuf);
+ if (linebuf)
+ OPENSSL_free(linebuf);
+ if (n)
+ BN_free(n);
+ if (e)
+ BN_free(e);
+
+ return ret;
+
+ parse_error:
+
+ fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
+
+ goto error;
+
+ }
+
+static int rsa_printver(FILE *out,
+ BIGNUM *n, BIGNUM *e,
+ const EVP_MD *dgst,
+ unsigned char *Msg, long Msglen,
+ unsigned char *S, long Slen, int Saltlen)
+ {
+ int ret = 0, r;
+ /* Setup RSA and EVP_PKEY structures */
+ RSA *rsa_pubkey = NULL;
+ EVP_PKEY pk;
+ EVP_MD_CTX ctx;
+ unsigned char *buf = NULL;
+ rsa_pubkey = FIPS_rsa_new();
+ if (!rsa_pubkey)
+ goto error;
+ rsa_pubkey->n = BN_dup(n);
+ rsa_pubkey->e = BN_dup(e);
+ if (!rsa_pubkey->n || !rsa_pubkey->e)
+ goto error;
+ pk.type = EVP_PKEY_RSA;
+ pk.pkey.rsa = rsa_pubkey;
+
+ EVP_MD_CTX_init(&ctx);
+
+ if (Saltlen >= 0)
+ {
+ M_EVP_MD_CTX_set_flags(&ctx,
+ EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16));
+ }
+ else if (Saltlen == -2)
+ M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931);
+ if (!EVP_VerifyInit_ex(&ctx, dgst, NULL))
+ goto error;
+ if (!EVP_VerifyUpdate(&ctx, Msg, Msglen))
+ goto error;
+
+ r = EVP_VerifyFinal(&ctx, S, Slen, &pk);
+
+
+ EVP_MD_CTX_cleanup(&ctx);
+
+ if (r < 0)
+ goto error;
+ ERR_clear_error();
+
+ if (r == 0)
+ fputs("Result = F\n", out);
+ else
+ fputs("Result = P\n", out);
+
+ ret = 1;
+
+ error:
+ if (rsa_pubkey)
+ FIPS_rsa_free(rsa_pubkey);
+ if (buf)
+ OPENSSL_free(buf);
+
+ return ret;
+ }
+#endif
diff --git a/crypto/openssl/fips/sha/Makefile b/crypto/openssl/fips/sha/Makefile
new file mode 100644
index 0000000..0f8cca9
--- /dev/null
+++ b/crypto/openssl/fips/sha/Makefile
@@ -0,0 +1,162 @@
+#
+# OpenSSL/fips/sha/Makefile
+#
+
+DIR= sha
+TOP= ../..
+CC= cc
+INCLUDES=
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile
+AR= ar r
+EXE_EXT=
+
+ASFLAGS= $(INCLUDES) $(ASFLAG)
+AFLAGS= $(ASFLAGS)
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST= fips_shatest.c
+APPS=
+EXE= fips_standalone_sha1$(EXE_EXT)
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=fips_sha1_selftest.c
+LIBOBJ=fips_sha1_selftest.o
+
+SRC= $(LIBSRC) fips_standalone_sha1.c
+
+EXHEADER=
+HEADER=
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd $(TOP); $(MAKE) DIRS=fips SDIRS=$(DIR) sub_all)
+
+all: ../fips_standalone_sha1$(EXE_EXT) lib
+
+lib: $(LIBOBJ)
+ @echo $(LIBOBJ) > lib
+
+../fips_standalone_sha1$(EXE_EXT): fips_standalone_sha1.o
+ if [ -z "$(HOSTCC)" ] ; then \
+ FIPS_SHA_ASM=""; for i in $(SHA1_ASM_OBJ) sha1dgst.o ; do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../../crypto/sha/$$i" ; done; \
+ $(CC) -o $@ $(CFLAGS) fips_standalone_sha1.o $$FIPS_SHA_ASM ; \
+ else \
+ $(HOSTCC) $(HOSTCFLAGS) -o $ $@ -I../../include -I../../crypto fips_standalone_sha1.c ../../crypto/sha/sha1dgst.c ; \
+ fi
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
+
+install:
+ @headerlist="$(EXHEADER)"; for i in $$headerlist; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+Q=../testvectors/sha/req
+A=../testvectors/sha/rsp
+
+VECTORS = SHA1LongMsg \
+ SHA1Monte \
+ SHA1ShortMsg \
+ SHA224LongMsg \
+ SHA224Monte \
+ SHA224ShortMsg \
+ SHA256LongMsg \
+ SHA256Monte \
+ SHA256ShortMsg \
+ SHA384LongMsg \
+ SHA384Monte \
+ SHA384ShortMsg \
+ SHA512LongMsg \
+ SHA512Monte \
+ SHA512ShortMsg
+
+fips_test:
+ -rm -rf $(A)
+ mkdir $(A)
+ for file in $(VECTORS); do \
+ if [ -f $(Q)/$$file.req ]; then \
+ $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_shatest $(Q)/$$file.req $(A)/$$file.rsp; \
+ fi; \
+ done
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff $(EXE)
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+fips_sha1_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_sha1_selftest.o: ../../include/openssl/crypto.h
+fips_sha1_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_sha1_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_sha1_selftest.o: ../../include/openssl/lhash.h
+fips_sha1_selftest.o: ../../include/openssl/obj_mac.h
+fips_sha1_selftest.o: ../../include/openssl/objects.h
+fips_sha1_selftest.o: ../../include/openssl/opensslconf.h
+fips_sha1_selftest.o: ../../include/openssl/opensslv.h
+fips_sha1_selftest.o: ../../include/openssl/ossl_typ.h
+fips_sha1_selftest.o: ../../include/openssl/safestack.h
+fips_sha1_selftest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+fips_sha1_selftest.o: ../../include/openssl/symhacks.h fips_sha1_selftest.c
+fips_shatest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_shatest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+fips_shatest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+fips_shatest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+fips_shatest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+fips_shatest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+fips_shatest.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+fips_shatest.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_shatest.o: ../../include/openssl/opensslconf.h
+fips_shatest.o: ../../include/openssl/opensslv.h
+fips_shatest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+fips_shatest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+fips_shatest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_shatest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+fips_shatest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_shatest.c
+fips_standalone_sha1.o: ../../include/openssl/asn1.h
+fips_standalone_sha1.o: ../../include/openssl/bio.h
+fips_standalone_sha1.o: ../../include/openssl/crypto.h
+fips_standalone_sha1.o: ../../include/openssl/e_os2.h
+fips_standalone_sha1.o: ../../include/openssl/evp.h
+fips_standalone_sha1.o: ../../include/openssl/fips.h
+fips_standalone_sha1.o: ../../include/openssl/hmac.h
+fips_standalone_sha1.o: ../../include/openssl/obj_mac.h
+fips_standalone_sha1.o: ../../include/openssl/objects.h
+fips_standalone_sha1.o: ../../include/openssl/opensslconf.h
+fips_standalone_sha1.o: ../../include/openssl/opensslv.h
+fips_standalone_sha1.o: ../../include/openssl/ossl_typ.h
+fips_standalone_sha1.o: ../../include/openssl/safestack.h
+fips_standalone_sha1.o: ../../include/openssl/sha.h
+fips_standalone_sha1.o: ../../include/openssl/stack.h
+fips_standalone_sha1.o: ../../include/openssl/symhacks.h fips_standalone_sha1.c
diff --git a/crypto/openssl/fips/sha/fips_sha1_selftest.c b/crypto/openssl/fips/sha/fips_sha1_selftest.c
new file mode 100644
index 0000000..4c0d463
--- /dev/null
+++ b/crypto/openssl/fips/sha/fips_sha1_selftest.c
@@ -0,0 +1,97 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#ifdef OPENSSL_FIPS
+static char test[][60]=
+ {
+ "",
+ "abc",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ };
+
+static const unsigned char ret[][SHA_DIGEST_LENGTH]=
+ {
+ { 0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55,
+ 0xbf,0xef,0x95,0x60,0x18,0x90,0xaf,0xd8,0x07,0x09 },
+ { 0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e,
+ 0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d },
+ { 0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae,
+ 0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1 },
+ };
+
+void FIPS_corrupt_sha1()
+ {
+ test[2][0]++;
+ }
+
+int FIPS_selftest_sha1()
+ {
+ size_t n;
+
+ for(n=0 ; n<sizeof(test)/sizeof(test[0]) ; ++n)
+ {
+ unsigned char md[SHA_DIGEST_LENGTH];
+
+ EVP_Digest(test[n],strlen(test[n]),md, NULL, EVP_sha1(), NULL);
+ if(memcmp(md,ret[n],sizeof md))
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_SHA1,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/sha/fips_shatest.c b/crypto/openssl/fips/sha/fips_shatest.c
new file mode 100644
index 0000000..ae5ecdd
--- /dev/null
+++ b/crypto/openssl/fips/sha/fips_shatest.c
@@ -0,0 +1,388 @@
+/* fips_shatest.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_FIPS
+
+int main(int argc, char *argv[])
+{
+ printf("No FIPS SHAXXX support\n");
+ return(0);
+}
+
+#else
+
+#include "fips_utl.h"
+
+static int dgst_test(FILE *out, FILE *in);
+static int print_dgst(const EVP_MD *md, FILE *out,
+ unsigned char *Msg, int Msglen);
+static int print_monte(const EVP_MD *md, FILE *out,
+ unsigned char *Seed, int SeedLen);
+
+int main(int argc, char **argv)
+ {
+ FILE *in = NULL, *out = NULL;
+
+ int ret = 1;
+
+ if(!FIPS_mode_set(1))
+ {
+ do_print_errors();
+ goto end;
+ }
+
+ if (argc == 1)
+ in = stdin;
+ else
+ in = fopen(argv[1], "r");
+
+ if (argc < 2)
+ out = stdout;
+ else
+ out = fopen(argv[2], "w");
+
+ if (!in)
+ {
+ fprintf(stderr, "FATAL input initialization error\n");
+ goto end;
+ }
+
+ if (!out)
+ {
+ fprintf(stderr, "FATAL output initialization error\n");
+ goto end;
+ }
+
+ if (!dgst_test(out, in))
+ {
+ fprintf(stderr, "FATAL digest file processing error\n");
+ goto end;
+ }
+ else
+ ret = 0;
+
+ end:
+
+ if (ret)
+ do_print_errors();
+
+ if (in && (in != stdin))
+ fclose(in);
+ if (out && (out != stdout))
+ fclose(out);
+
+ return ret;
+
+ }
+
+#define SHA_TEST_MAX_BITS 102400
+#define SHA_TEST_MAXLINELEN (((SHA_TEST_MAX_BITS >> 3) * 2) + 100)
+
+int dgst_test(FILE *out, FILE *in)
+ {
+ const EVP_MD *md = NULL;
+ char *linebuf, *olinebuf, *p, *q;
+ char *keyword, *value;
+ unsigned char *Msg = NULL, *Seed = NULL;
+ long MsgLen = -1, Len = -1, SeedLen = -1;
+ int ret = 0;
+ int lnum = 0;
+
+ olinebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN);
+ linebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN);
+
+ if (!linebuf || !olinebuf)
+ goto error;
+
+
+ while (fgets(olinebuf, SHA_TEST_MAXLINELEN, in))
+ {
+ lnum++;
+ strcpy(linebuf, olinebuf);
+ keyword = linebuf;
+ /* Skip leading space */
+ while (isspace((unsigned char)*keyword))
+ keyword++;
+
+ /* Look for = sign */
+ p = strchr(linebuf, '=');
+
+ /* If no = or starts with [ (for [L=20] line) just copy */
+ if (!p)
+ {
+ fputs(olinebuf, out);
+ continue;
+ }
+
+ q = p - 1;
+
+ /* Remove trailing space */
+ while (isspace((unsigned char)*q))
+ *q-- = 0;
+
+ *p = 0;
+ value = p + 1;
+
+ /* Remove leading space from value */
+ while (isspace((unsigned char)*value))
+ value++;
+
+ /* Remove trailing space from value */
+ p = value + strlen(value) - 1;
+ while (*p == '\n' || isspace((unsigned char)*p))
+ *p-- = 0;
+
+ if (!strcmp(keyword,"[L") && *p==']')
+ {
+ switch (atoi(value))
+ {
+ case 20: md=EVP_sha1(); break;
+ case 28: md=EVP_sha224(); break;
+ case 32: md=EVP_sha256(); break;
+ case 48: md=EVP_sha384(); break;
+ case 64: md=EVP_sha512(); break;
+ default: goto parse_error;
+ }
+ }
+ else if (!strcmp(keyword, "Len"))
+ {
+ if (Len != -1)
+ goto parse_error;
+ Len = atoi(value);
+ if (Len < 0)
+ goto parse_error;
+ /* Only handle multiples of 8 bits */
+ if (Len & 0x7)
+ goto parse_error;
+ if (Len > SHA_TEST_MAX_BITS)
+ goto parse_error;
+ MsgLen = Len >> 3;
+ }
+
+ else if (!strcmp(keyword, "Msg"))
+ {
+ long tmplen;
+ if (strlen(value) & 1)
+ *(--value) = '0';
+ if (Msg)
+ goto parse_error;
+ Msg = hex2bin_m(value, &tmplen);
+ if (!Msg)
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "Seed"))
+ {
+ if (strlen(value) & 1)
+ *(--value) = '0';
+ if (Seed)
+ goto parse_error;
+ Seed = hex2bin_m(value, &SeedLen);
+ if (!Seed)
+ goto parse_error;
+ }
+ else if (!strcmp(keyword, "MD"))
+ continue;
+ else
+ goto parse_error;
+
+ fputs(olinebuf, out);
+
+ if (md && Msg && (MsgLen >= 0))
+ {
+ if (!print_dgst(md, out, Msg, MsgLen))
+ goto error;
+ OPENSSL_free(Msg);
+ Msg = NULL;
+ MsgLen = -1;
+ Len = -1;
+ }
+ else if (md && Seed && (SeedLen > 0))
+ {
+ if (!print_monte(md, out, Seed, SeedLen))
+ goto error;
+ OPENSSL_free(Seed);
+ Seed = NULL;
+ SeedLen = -1;
+ }
+
+
+ }
+
+
+ ret = 1;
+
+
+ error:
+
+ if (olinebuf)
+ OPENSSL_free(olinebuf);
+ if (linebuf)
+ OPENSSL_free(linebuf);
+ if (Msg)
+ OPENSSL_free(Msg);
+ if (Seed)
+ OPENSSL_free(Seed);
+
+ return ret;
+
+ parse_error:
+
+ fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
+
+ goto error;
+
+ }
+
+static int print_dgst(const EVP_MD *emd, FILE *out,
+ unsigned char *Msg, int Msglen)
+ {
+ int i, mdlen;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ if (!EVP_Digest(Msg, Msglen, md, (unsigned int *)&mdlen, emd, NULL))
+ {
+ fputs("Error calculating HASH\n", stderr);
+ return 0;
+ }
+ fputs("MD = ", out);
+ for (i = 0; i < mdlen; i++)
+ fprintf(out, "%02x", md[i]);
+ fputs("\n", out);
+ return 1;
+ }
+
+static int print_monte(const EVP_MD *md, FILE *out,
+ unsigned char *Seed, int SeedLen)
+ {
+ unsigned int i, j, k;
+ int ret = 0;
+ EVP_MD_CTX ctx;
+ unsigned char *m1, *m2, *m3, *p;
+ unsigned int mlen, m1len, m2len, m3len;
+
+ EVP_MD_CTX_init(&ctx);
+
+ if (SeedLen > EVP_MAX_MD_SIZE)
+ mlen = SeedLen;
+ else
+ mlen = EVP_MAX_MD_SIZE;
+
+ m1 = OPENSSL_malloc(mlen);
+ m2 = OPENSSL_malloc(mlen);
+ m3 = OPENSSL_malloc(mlen);
+
+ if (!m1 || !m2 || !m3)
+ goto mc_error;
+
+ m1len = m2len = m3len = SeedLen;
+ memcpy(m1, Seed, SeedLen);
+ memcpy(m2, Seed, SeedLen);
+ memcpy(m3, Seed, SeedLen);
+
+ fputs("\n", out);
+
+ for (j = 0; j < 100; j++)
+ {
+ for (i = 0; i < 1000; i++)
+ {
+ EVP_DigestInit_ex(&ctx, md, NULL);
+ EVP_DigestUpdate(&ctx, m1, m1len);
+ EVP_DigestUpdate(&ctx, m2, m2len);
+ EVP_DigestUpdate(&ctx, m3, m3len);
+ p = m1;
+ m1 = m2;
+ m1len = m2len;
+ m2 = m3;
+ m2len = m3len;
+ m3 = p;
+ EVP_DigestFinal_ex(&ctx, m3, &m3len);
+ }
+ fprintf(out, "COUNT = %d\n", j);
+ fputs("MD = ", out);
+ for (k = 0; k < m3len; k++)
+ fprintf(out, "%02x", m3[k]);
+ fputs("\n\n", out);
+ memcpy(m1, m3, m3len);
+ memcpy(m2, m3, m3len);
+ m1len = m2len = m3len;
+ }
+
+ ret = 1;
+
+ mc_error:
+ if (m1)
+ OPENSSL_free(m1);
+ if (m2)
+ OPENSSL_free(m2);
+ if (m3)
+ OPENSSL_free(m3);
+
+ EVP_MD_CTX_cleanup(&ctx);
+
+ return ret;
+ }
+
+#endif
diff --git a/crypto/openssl/fips/sha/fips_standalone_sha1.c b/crypto/openssl/fips/sha/fips_standalone_sha1.c
new file mode 100644
index 0000000..eec65dc
--- /dev/null
+++ b/crypto/openssl/fips/sha/fips_standalone_sha1.c
@@ -0,0 +1,173 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/opensslconf.h>
+#include <openssl/sha.h>
+#include <openssl/hmac.h>
+
+#ifndef FIPSCANISTER_O
+int FIPS_selftest_failed() { return 0; }
+void FIPS_selftest_check() {}
+void OPENSSL_cleanse(void *p,size_t len) {}
+#endif
+
+#ifdef OPENSSL_FIPS
+
+static void hmac_init(SHA_CTX *md_ctx,SHA_CTX *o_ctx,
+ const char *key)
+ {
+ size_t len=strlen(key);
+ int i;
+ unsigned char keymd[HMAC_MAX_MD_CBLOCK];
+ unsigned char pad[HMAC_MAX_MD_CBLOCK];
+
+ if (len > SHA_CBLOCK)
+ {
+ SHA1_Init(md_ctx);
+ SHA1_Update(md_ctx,key,len);
+ SHA1_Final(keymd,md_ctx);
+ len=20;
+ }
+ else
+ memcpy(keymd,key,len);
+ memset(&keymd[len],'\0',HMAC_MAX_MD_CBLOCK-len);
+
+ for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++)
+ pad[i]=0x36^keymd[i];
+ SHA1_Init(md_ctx);
+ SHA1_Update(md_ctx,pad,SHA_CBLOCK);
+
+ for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++)
+ pad[i]=0x5c^keymd[i];
+ SHA1_Init(o_ctx);
+ SHA1_Update(o_ctx,pad,SHA_CBLOCK);
+ }
+
+static void hmac_final(unsigned char *md,SHA_CTX *md_ctx,SHA_CTX *o_ctx)
+ {
+ unsigned char buf[20];
+
+ SHA1_Final(buf,md_ctx);
+ SHA1_Update(o_ctx,buf,sizeof buf);
+ SHA1_Final(md,o_ctx);
+ }
+
+#endif
+
+int main(int argc,char **argv)
+ {
+#ifdef OPENSSL_FIPS
+ static char key[]="etaonrishdlcupfm";
+ int n,binary=0;
+
+ if(argc < 2)
+ {
+ fprintf(stderr,"%s [<file>]+\n",argv[0]);
+ exit(1);
+ }
+
+ n=1;
+ if (!strcmp(argv[n],"-binary"))
+ {
+ n++;
+ binary=1; /* emit binary fingerprint... */
+ }
+
+ for(; n < argc ; ++n)
+ {
+ FILE *f=fopen(argv[n],"rb");
+ SHA_CTX md_ctx,o_ctx;
+ unsigned char md[20];
+ int i;
+
+ if(!f)
+ {
+ perror(argv[n]);
+ exit(2);
+ }
+
+ hmac_init(&md_ctx,&o_ctx,key);
+ for( ; ; )
+ {
+ char buf[1024];
+ size_t l=fread(buf,1,sizeof buf,f);
+
+ if(l == 0)
+ {
+ if(ferror(f))
+ {
+ perror(argv[n]);
+ exit(3);
+ }
+ else
+ break;
+ }
+ SHA1_Update(&md_ctx,buf,l);
+ }
+ hmac_final(md,&md_ctx,&o_ctx);
+
+ if (binary)
+ {
+ fwrite(md,20,1,stdout);
+ break; /* ... for single(!) file */
+ }
+
+ printf("HMAC-SHA1(%s)= ",argv[n]);
+ for(i=0 ; i < 20 ; ++i)
+ printf("%02x",md[i]);
+ printf("\n");
+ }
+#endif
+ return 0;
+ }
+
+
diff --git a/external/Makefile b/external/Makefile
new file mode 100644
index 0000000..ce42389
--- /dev/null
+++ b/external/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= bsd
+
+.include <bsd.subdir.mk>
diff --git a/external/bsd/Makefile b/external/bsd/Makefile
new file mode 100644
index 0000000..5148309
--- /dev/null
+++ b/external/bsd/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= bmake
+
+.include <bsd.subdir.mk>
diff --git a/external/bsd/bmake/Makefile b/external/bsd/bmake/Makefile
new file mode 100644
index 0000000..ce166ab
--- /dev/null
+++ b/external/bsd/bmake/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= usr.bin
+
+.include <bsd.subdir.mk>
diff --git a/external/bsd/bmake/dist/ChangeLog b/external/bsd/bmake/dist/ChangeLog
new file mode 100644
index 0000000..3f82c8d
--- /dev/null
+++ b/external/bsd/bmake/dist/ChangeLog
@@ -0,0 +1,1383 @@
+2012-07-04 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120704
+ Merge with NetBSD make, pick up
+ o Job_ParseShell should call Shell_Init if it has been
+ previously called.
+ * Makefile.in: set USE_META based on configure result.
+ also .PARSEDIR is safer indicator of bmake.
+
+2012-06-26 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in: bump version to 20120626
+ ensure CPPFLAGS is in CFLAGS
+ * meta.c: avoid nested externs
+ * bsd.after-import.mk: avoid ${.CURDIR}/Makefile as target
+
+2012-06-20 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120620
+ Merge with NetBSD make, pick up
+ o make_malloc.c: avoid including make_malloc.h again
+
+ * Makefile.in: avoid bmake only syntax or protect with
+ .if defined(.MAKE.LEVEL)
+ * bsd.after-import.mk: replace .-include with .sinclude
+ ensure? SRCTOP gets a value
+ * configure.in: look for filemon.h in /usr/include/dev/filemon first.
+
+2012-06-19 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120612
+ Merge with NetBSD make, pick up
+ o use MAKE_ATTR_* rather than those defined by cdefs.h or compiler
+ for greater portability.
+ o unit-tests/forloop: check that .for works as expected wrt
+ number of times and with "quoted strings".
+
+2012-06-06 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120606
+ Merge with NetBSD make, pick up
+ o compat.c: use kill(2) rather than raise(3).
+ * configure.in: look for sys/dev/filemon
+ * bsd.after-import.mk: add a .-include "Makefile.inc" to Makefile
+ and pass BOOTSTRAP_XTRAS to boot-strap.
+
+2012-06-04 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120604
+ Merge with NetBSD make, pick up
+ o util.c and var.c share same var for tracking if environ
+ has been reallocated.
+ o util.c provide getenv with setenv.
+ * Add MAKE_LEVEL_SAFE as an alternate means of passing MAKE_LEVEL
+ when the shell actively strips .MAKE.* from the environment.
+ We still refer to the variable always as .MAKE.LEVEL
+ * util.c fix bug in findenv() was finding prefix of name.
+ * compat.c: re-raising SIGINT etc after running .INTERRUPT
+ results in more reliable termination of all activity on many
+ platforms.
+
+2012-06-02 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120602
+ Merge with NetBSD make, pick up
+ o for.c: handle quoted items in .for list
+
+2012-05-30 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120530
+ Merge with NetBSD make, pick up
+ o compat.c: ignore empty command.
+
+2012-05-24 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120524
+ * FILES: add bsd.after-import.mk:
+ A simple means of integrating bmake into a BSD build system.
+
+2012-05-20 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120520
+ Merge with NetBSD make, pick up
+ o increased limit for nested conditionals.
+
+2012-05-18 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120518
+ Merge with NetBSD make, pick up
+ o use _exit(2) in signal hanlder
+ o Don't use the [dir] cache when building nodes that might have
+ changed since the last exec.
+ o Avoid nested extern declaration warnings.
+
+2012-04-27 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * meta.c (fgetLine): avoid %z - not portable.
+ * parse.c: Since we moved include of sys/mman.h
+ and def's of MAP_COPY etc. we got dups from a merge.
+
+2012-04-24 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120420
+ Merge with NetBSD make, pick up
+ o restore duplicate supression in .MAKE.MAKEFILES
+ runtime saving can be significant.
+ o Var_Subst() uses Buf_DestroyCompact() to reduce memory
+ consumption up to 20%.
+
+2012-04-20 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120420
+ Merge with NetBSD make, pick up
+ o remove duplicate supression in .MAKE.MAKEFILES
+ o improved dir cache behavior
+ o gmake'ish export command
+
+2012-03-25 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120325
+ Merge with NetBSD make, pick up
+ o fix parsing of :[#] in conditionals.
+
+2012-02-10 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in: replace use of .Nx in bmake.1 with NetBSD
+ since some systems cannot cope with .Nx <version>
+
+2011-11-14 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20111111
+ Merge with NetBSD make, pick up
+ o debug output for .PARSEDIR and .PARSEFILE
+
+2011-10-10 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20111010
+
+2011-10-09 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * boot-strap: check for an expected file in the dirs we look for.
+ * make-bootstrap.sh: pass on LDSTATIC
+
+2011-10-01 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20111001
+ Merge with NetBSD make, pick up
+ o ensure .PREFIX is set for .PHONY
+ and .TARGET set for .PHONY run via .END
+ o __dead used consistently
+
+2011-09-10 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): 20110909 is a better number ;-)
+
+2011-09-05 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110905
+ Merge with NetBSD make, pick up
+ o meta_oodate: ignore makeDependfile
+
+2011-08-28 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110828
+ Merge with NetBSD make, pick up
+ o silent=yes in .MAKE.MODE causes meta mode to mark targets
+ as SILENT if a .meta file is created
+
+2011-08-18 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110818
+ Merge with NetBSD make, pick up
+ o in meta mode, if target flagged .META a missing .meta file
+ means target is out-of-date
+ o fixes for gcc 4.5 warnings
+ o simplify job printing code
+
+2011-08-09 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110808
+ Merge with NetBSD make, pick up
+ o do not touch OP_SPECIAL targets when doing make -t
+
+2011-06-22 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110622
+ Merge with NetBSD make, pick up
+ o meta_oodate detect corrupted .meta file and declare oodate.
+ * configure.in: add check for setsid
+
+2011-06-07 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Merge with NetBSD make, pick up
+ o unit-tests/modts now works on MirBSD
+
+2011-06-04 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110606
+ Merge with NetBSD make, pick up
+ o ApplyModifiers: when we parse a variable which is not
+ the entire modifier string, or not followed by ':', do not
+ consider it as containing modifiers.
+ o loadfile: ensure newline at end of mapped file.
+
+2011-05-05 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110505
+ Merge with NetBSD make, pick up
+ o .MAKE.META.BAILIWICK - list of prefixes which define the scope
+ of make's control. In meta mode, any generated file within
+ said bailiwick, which is found to be missing, causes current
+ target to be out-of-date.
+
+2011-04-11 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110411
+ Merge with NetBSD make, pick up
+ o when long modifiers fail to match, check sysV style.
+ - add a test case
+
+2011-04-10 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110410
+ Merge with NetBSD make, pick up
+ o :hash - cheap 32bit hash of value
+ o :localtime, :gmtime - use value as format string for strftime.
+
+2011-03-30 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110330
+ mostly because its a cooler version.
+ Merge with NetBSD make, pick up
+ o NetBSD tags for meta.[ch]
+ o job.c call meta_job_finish() after meta_job_error().
+ o meta_job_error() should call meta_job_finish() to ensure
+ .meta file is closed, and safe to copy - if .ERROR target wants.
+ meta_job_finish() is safe to call repeatedly.
+
+2011-03-29 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * unit-tests/modts: use printf if it is a builtin,
+ to save us from MirBSD
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110329
+ Merge with NetBSD make, pick up
+ o fix for use after free() in CondDoExists().
+ o meta_oodate() report extra commands and return earlier.
+
+2011-03-27 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110327
+ Merge with NetBSD make, pick up
+ o meta.c, if .MAKE.MODE contains curdirOk=yes
+ allow creating .meta files in .CURDIR
+ * boot-strap (TOOL_DIFF): aparently at least on linux distro
+ formats the output of 'type' differently - so eat any "()"
+
+2011-03-06 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110306
+ Merge with NetBSD make, pick up
+ o meta.c, only do getcwd() once
+
+2011-03-05 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110305
+ Merge with NetBSD make, pick up
+ o correct sysV substitution handling of empty lhs and variable
+ o correct exists() check for dir with trailing /
+ o correct handling of modifiers for non-existant variables
+ during evaluation of conditionals.
+ o ensure MAP_FILE is defined.
+ o meta.c use curdir[] now exported by main.c
+
+2011-02-25 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110225
+ Merge with NetBSD make, pick up
+ o fix for incorrect .PARSEDIR when .OBJDIR is re-computed after
+ makefiles have been read.
+ o fix example of :? modifier in man page.
+
+2011-02-13 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110214
+ Merge with NetBSD make, pick up
+ o meta.c handle realpath() failing when generating meta file
+ name.
+
+ * sigcompat.c: convert to ansi so we can use higher warning levels.
+
+
+2011-02-07 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110207
+ Merge with NetBSD make, pick up
+ o fix for bug in meta mode.
+
+2011-01-03 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * parse.c: SunOS 5.8 at least does not have MAP_FILE
+
+2011-01-01 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110101
+ Merge with NetBSD make, pick up
+ o use mmap(2) if available, for reading makefiles
+
+2010-12-15 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20101215
+ Merge with NetBSD make, pick up
+ o ensure meta_job_error() does not report a previous .meta file
+ as being culprit.
+
+2010-12-10 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20101210
+ Merge with NetBSD make, pick up
+ o meta_oodate: track cwd per process, and only consider target
+ out-of-date if missing file is outside make's CWD.
+ Ignore files in /tmp/ etc.
+ o to ensure unit-tests results match, need to control LC_ALL
+ as well as LANG.
+ o fix for parsing bug in var.c
+
+2010-11-26 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20101126
+ Merge with NetBSD make, pick up
+ o if stale dependency is an IMPSRC, search via .PATH
+ o meta_oodate: if a referenced file is missing, target is
+ out-of-date.
+ o meta_oodate: if a target uses .OODATE in its commands,
+ it (.OODATE) needs to be recomputed.
+ o keep a pointer to youngest child node, rather than just its
+ mtime.
+
+2010-11-02 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20101101
+
+2010-10-16 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * machine.sh: like os.sh,
+ allow for uname -p producing useless drivel
+
+2010-09-13 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * boot-strap: document configure knobs for meta and filemon.
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100911
+ Merge with NetBSD make, pick up
+ o meta.c - meta mode
+
+ * make-bootstrap.sh.in: handle meta.c
+ * configure.in: add knobs for use_meta and filemon_h
+ also, look for dirname, str[e]sep and strlcpy
+ * util.c: add simple err[x] and warn[x]
+
+2010-08-08 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * boot-strap (TOOL_DIFF): set this to ensure tests use
+ the same version of diff that configure tested
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100808
+ Merge with NetBSD make, pick up
+ o in jobs mode, when we discover we cannot make something,
+ call PrintOnError before exit.
+
+2010-08-06 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100806
+ Merge with NetBSD make, pick up
+ o formatting fixes for ignored errors
+ o ensure jobs are cleaned up regardless of where wait() was called.
+
+2010-06-28 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100618
+ * os.sh (MACHINE_ARCH): watch out for drivel from uname -p
+
+2010-06-16 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100616
+ Merge with NetBSD make, pick up
+ o man page update
+ o call PrintOnError from JobFinish when we detect an error we
+ are not ignoring.
+
+2010-06-06 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100606
+ Merge with NetBSD make, pick up
+ o man page update
+
+2010-06-05 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100605
+ Merge with NetBSD make, pick up
+ o use bmake_signal() which is a wrapper around sigaction()
+ in place of signal()
+ o add .export-env to allow exporting variables to environment
+ without tracking (so no re-export when the internal value is
+ changed).
+
+2010-05-24 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100524
+ Merge with NetBSD make, pick up
+ o fix for .info et al being greedy.
+
+2010-05-23 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100520
+ Merge with NetBSD make, pick up
+ o back to using realpath on argv[0]
+ but only if contains '/' and does not start with '/'.
+
+2010-05-10 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * boot-strap: use absolute path for bmake when running tests.
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100510
+ Merge with NetBSD make, pick up
+ o revert use of realpath on argv[0]
+ too many corner cases.
+ o print MAKE_PRINT_VAR_ON_ERROR before running .ERROR target.
+
+2010-05-05 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100505
+ Merge with NetBSD make, pick up
+ o fix for missed SIGCHLD when compiled with SunPRO
+ actually for bmake, defining FORCE_POSIX_SIGNALS would have
+ done the job.
+
+2010-04-30 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100430
+ Merge with NetBSD make, pick up
+ o fflush stdout before writing to stdout
+
+2010-04-23 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100423
+ Merge with NetBSD make, pick up
+ o updated unit tests for Haiku (this time for sure).
+ * boot-strap: based on patch from joerg
+ honor --with-default-sys-path better.
+ * boot-strap: remove mention of --with-prefix-sys-path
+
+2010-04-22 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100422
+ * Merge with NetBSD make, pick up
+ o fix for vfork() on Darwin.
+ o fix for bogus $TMPDIR.
+ o set .MAKE.MODE=compat for -B
+ o set .MAKE.JOBS=max_jobs for -j max_jobs
+ o allow unit-tests to run without any *.mk
+ o unit-tests/modmisc be more conservative in dirs presumed to exist.
+ * boot-strap: ignore /usr/share/mk except on NetBSD.
+ * unit-tests/Makefile.in: set LANG=C when running unit-tests to
+ ensure sort(1) behaves as expected.
+
+2010-04-21 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * boot-strap: add FindHereOrAbove so we can use -m .../mk
+
+2010-04-20 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100420
+ * Merge with NetBSD make, pick up
+ o fix for variable realpath() behavior.
+ we have to stat(2) the result to be sure.
+ o fix for .export (all) when nested vars use :sh
+
+2010-04-14 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100414
+ * Merge with NetBSD make, pick up
+ o use realpath to resolve argv[0] (for .MAKE) if needed.
+ o add realpath from libc.
+ o add :tA to resolve variable via realpath(3) if possible.
+
+2010-04-08 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100408
+ * Merge with NetBSD make, pick up
+ o unit tests for .ERROR, .error
+ o fix for .ERROR to ensure it cannot be default target.
+
+2010-04-06 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100406
+ * Merge with NetBSD make, pick up
+ o fix for compat mode "Error code" going to debug_file.
+ o fix for .ALLSRC being populated twice.
+ o support for .info, .warning and .error directives
+ o .MAKE.MODE to control make's operational mode
+ o .MAKE.MAKEFILE_PREFERENCE to control the preferred makefile
+ name(s).
+ o .MAKE.DEPENDFILE to control the name of the depend file
+ o .ERROR target - run on failure.
+
+2010-03-18 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * make-bootstrap.sh.in: extract MAKE_VERSION from Makefile
+
+ * os.sh,arch.c: patch for Haiku from joerg at netbsd
+
+2010-03-17 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100222
+ * Merge with NetBSD make, pick up
+ o better error msg for .for with mutiple inter vars
+
+ * boot-strap:
+ o use make-bootstrap.sh from joerg at netbsd
+ to avoid the need for a native make when bootstrapping.
+ o add "" everywhere ;-)
+ o if /usr/share/tmac/andoc.tmac exists install nroff bmake.1
+ otherwise the pre-formated version.
+
+2010-01-04 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20100102
+ * Merge with NetBSD make, pick up:
+ o fix for -m .../
+
+2009-11-18 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20091118
+ * Merge with NetBSD make, pick up:
+ o .unexport
+ o report lines that start with '.' and should have ':'
+ (catch typo's of .el*if).
+
+2009-10-30 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * configure.in: Ensure that srcdir and mksrc are absolute paths.
+
+2009-10-09 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): fix version to 20091007
+
+2009-10-07 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 200910007
+ * Merge with NetBSD make, pick up:
+ o fix for parsing of :S;...;...; applied to .for loop iterator
+ appearing in a dependency line.
+
+2009-09-09 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20090909
+ * Merge with NetBSD make, pick up:
+ o fix for -C, .CURDIR and .OBJDIR
+ * boot-strap:
+ o allow share_dir to be set independent of prefix.
+ o select default share_dir better when prefix ends in $HOST_TARGET
+ o if FORCE_BSD_MK etc were set, include them in the suggested
+ install-mk command.
+
+2009-09-08 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20090908
+ * Merge with NetBSD make, pick up:
+ o .MAKE.LEVEL for recursion tracking
+ o fix for :M scanning \:
+
+2009-09-03 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * configure.in: Don't -D__EXTENSIONS__ if
+ AC_USE_SYSTEM_EXTENSIONS says "no".
+
+2009-08-26 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20090826
+ Simplify MAKE_VERSION to just the bare date.
+ * Merge with NetBSD make, pick up:
+ o -C directory support.
+ o support for SIGINFO
+ o use $TMPDIR for temp files.
+ o child of vfork should be careful about modifying parent's state.
+
+
+2009-03-26 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Appy some patches for MiNT from David Brownlee
+
+2009-02-26 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20090222
+ * Merge with NetBSD make, pick up:
+ o Possible null pointer de-ref in Var_Set.
+
+2009-02-08 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20090204
+ * Merge with NetBSD make, pick up:
+ o bmake_malloc et al moved to their own .c
+ o Count both () and {} when looking for the end of a :M pattern
+ o Change 'Buffer' so that it is the actual struct, not a pointer to it.
+ o strlist.c - functions for processing extendable arrays of pointers to strings.
+ o ClientData replaced with void *, so const void * can be used.
+ o New debug flag C for DEBUG_CWD
+
+2008-11-11 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20081111
+ Apply patch from Joerg Sonnenberge to
+ configure.in:
+ o remove some redundant checks
+ o check for emlloc etc only in libutil and require the whole family.
+ util.c:
+ o remove [v]asprintf which is no longer used.
+
+2008-11-04 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20081101
+ * Merge with NetBSD make, pick up:
+ o util.c: avoid use of putenv() - christos
+
+2008-10-30 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20081030
+ pick up man page tweaks.
+
+2008-10-29 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in: move processing of LIBOBJS to after is definition!
+ thus we'll have getenv.c in SRCS only if needed.
+
+ * make.1: add examples of how to use :?
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20081029
+ * Merge with NetBSD make, pick up:
+ o fix for .END processing with -j
+ o segfault from Parse_Error when no makefile is open
+ o handle numeric expressions in any variable expansion
+ o debug output now defaults to stderr, -dF to change it - apb
+ o make now uses bmake_malloc etc so that it can build natively
+ on A/UX - wasn't an issue for bmake, but we want to keep in sync.
+
+2008-09-27 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20080808
+ * Merge with NetBSD make, pick up:
+ o fix for PR/38840: Pierre Pronchery: make crashes while parsing
+ long lines in Makefiles
+ o optimizations for VarQuote by joerg
+ o fix for PR/38756: dominik: make dumps core on invalid makefile
+
+2008-05-15 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20080515
+ * Merge with NetBSD make, pick up:
+ o fix skip setting vars in VAR_GLOBAL context, to handle
+ cases where VAR_CMD is used for other than command line vars.
+
+2008-05-14 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * boot-strap (make_version): we may need to look in
+ $prefix/share/mk for sys.mk
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20080514
+ * Merge with NetBSD make, pick up:
+ o skip setting vars in VAR_GLOBAL context, when already set in
+ VAR_CMD which takes precedence.
+
+2008-03-30 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20080330
+ * Merge with NetBSD make, pick up:
+ o fix for ?= when LHS contains variable reference.
+
+2008-02-15 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * merge some patches from NetBSD pkgsrc.
+
+ * makefile.boot.in (BOOTSTRAP_SYS_PATH): Allow better control of
+ the MAKSYSPATH used during bootstrap.
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20080215
+ * Merge with NetBSD make, pick up:
+ o warn if non-space chars follow 'empty' in a conditional.
+
+2008-01-18 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20080118
+ * Merge with NetBSD make, pick up:
+ o consider dependencies read from .depend as optional - dsl
+ o remember when buffer for reading makefile grows - dsl
+ o add -dl (aka LOUD) - David O'Brien
+
+2007-10-22 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20071022
+ * Merge with NetBSD make, pick up:
+ o Allow .PATH<suffix> to be used for .include ""
+
+ * boot-strap: source default settings from .bmake-boot-strap.rc
+
+2007-10-16 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in: fix maninstall on various systems
+ provided that our man.mk is used.
+ For non-BSD systems we install the preformatted page
+ into $MANDIR/cat1
+
+2007-10-15 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * boot-strap: make bmake.1 too, so maninstall works.
+
+2007-10-14 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20071014
+ * Merge with NetBSD make, pick up:
+ o revamped handling of defshell - configure no longer needs to
+ know the content of the shells array - apb
+ o stop Var_Subst modifying its input - apb
+ o avoid calling ParseTrackInput too often - dsl
+
+2007-10-11 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20071011
+ * Merge with NetBSD make, pick up:
+ o fix Shell_Init for case that _BASENAME_DEFSHELL is absolute path.
+
+ * sigcompat.c: some tweaks for HP-UX 11.x based on
+ patch from Tobias Nygren
+
+ * configure.in: update handling of --with-defshell to match
+ new make behavior. --with-defshell=/usr/xpg4/bin/sh
+ will now do what one might hope - provided the chosen shell
+ behaves enough like sh.
+
+2007-10-08 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20071008
+ * Merge with NetBSD make, pick up:
+ o .MAKE.JOB.PREFIX - control the token output before jobs - sjg
+ o .export/.MAKE.EXPORTED - export of variables - sjg
+ o .MAKE.MAKEFILES - track all makefiles read - sjg
+ o performance improvements - dsl
+ o revamp parallel job scheduling - dsl
+
+2006-07-28 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20060728
+ * Merge with NetBSD make, pick up:
+ o extra debug info during variable and cond processing - sjg
+ o shell definition now covers newline - rillig
+ o minor mem leak in PrintOnError - sjg
+
+2006-05-11 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20060511
+ * Merge with NetBSD make, pick up:
+ o more memory leaks - coverity
+ o possible overflow in ArchFindMember - coverity
+ o extract variable modifier code out of Var_Parse()
+ so it can be called recursively - sjg
+ o unit-tests/moderrs - sjg
+
+2006-04-12 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20060412
+ * Merge with NetBSD make, pick up:
+ o fixes for some memory leaks - coverity
+ o only read first sys.mk etc when searching sysIncPath - sjg
+
+ * main.c (ReadMakefile): remove hack for __INTERIX that prevented
+ setting ${MAKEFILE} - OBATA Akio
+
+2006-03-18 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20060318
+ * Merge with NetBSD make, pick up:
+ o cleanup of job.c to remove remote handling, distcc is more
+ useful and this code was likely bit-rotting - dsl
+ o fix for :P modifier - sjg
+ * boot-strap: set default prefix to something reasonable
+ (for me anyway).
+
+2006-03-01 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20060301
+ * Merge with NetBSD make, pick up:
+ o make .WAIT apply recursively, document and test case - apb
+ o allow variable modifiers in a variable appear anywhere in
+ modifier list, document and test case - sjg
+
+2006-02-22 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20060222
+ * Merge with NetBSD make, pick up:
+ o improved job token handling - dsl
+ o SIG_DFL the correct signal before exec - dsl
+ o more debug info during parsing - dsl
+ o allow variable modifiers to be specified via variable - sjg
+ * boot-strap: explain why we died if no mksrc
+
+2005-11-05 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20051105
+ * configure.in: always set default_sys_path
+ default is ${prefix}/share/mk
+ - remove prefix_sys_path, anyone wanting more than above
+ needs to set it manually.
+
+2005-11-04 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * boot-strap: make this a bit easier for pkgsrc folk.
+ bootstrap still fails on IRIX64 since MACHINE_ARCH gets set to
+ 'mips' while pkgsrc wants 'mipseb' or 'mipsel'
+
+2005-11-02 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20051102
+ * job.c (JobFinish): fix likely ancient merge lossage
+ fix from Todd Vierling.
+ * boot-strap (srcdir): allow setting mksrc=none
+
+2005-10-31 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20051031
+ * ranlib.h: skip on OSF too.
+ (NetBSD PR 31864)
+
+2005-10-10 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20051002
+ fix a silly typo
+
+2005-10-09 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20051001
+ support for UnixWare and some other systems,
+ based on patches from pkgsrc/bootstrap
+
+2005-09-03 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20050901
+ * Merge with NetBSD make, pick up:
+ o possible parse error causing us to wander off.
+
+2005-06-06 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20050606
+ * Merge with NetBSD make, pick up:
+ o :0x modifier for randomizing a list
+ o fixes for a number of -Wuninitialized issues.
+
+2005-05-30 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20050530
+ * Merge with NetBSD make, pick up:
+ o Handle dependencies for .BEGIN, .END and .INTERRUPT
+
+ * README: was seriously out of date.
+
+2005-03-22 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Important to use .MAKE rather than MAKE.
+
+2005-03-15 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20050315
+ * Merge with NetBSD make, pick up:
+ o don't mistake .elsefoo for .else
+ o use suffix-specific search path correctly
+ o bunch of style nits
+
+2004-05-11 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * boot-strap:
+ o ensure that args to --src and --with-mksrc
+ are resolved before giving them to configure.
+ o add -o "objdir" so that builder can control it,
+ default is $OS as determined by os.sh
+ o add -q to suppress all the install instructions.
+
+2004-05-08 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Remove __IDSTRING()
+
+ * Makefile.in (BMAKE_VERSION): bump to 20040508
+ * Merge with NetBSD make, pick up:
+ o posix fixes
+ - remove '-e' from compat mode
+ - add support for '+' command-line prefix.
+ o fix for handling '--' on command-line.
+ o fix include in lst.lib/lstInt.h to simplify '-I's
+ o we also picked up replacement of MAKE_BOOTSTRAP
+ with !MAKE_NATIVE which is a noop, but possibly confusing.
+
+2004-04-14 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20040414
+ * Merge with NetBSD make, pick up:
+ o allow quoted strings on lhs of conditionals
+ o issue warning when extra .else is seen
+ o print line numer when errors encountered during parsing from
+ string.
+
+2004-02-20 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20040220
+ * Merge with NetBSD make, pick up:
+ o fix for old :M parsing bug.
+ o re-jigged unit-tests
+
+2004-02-15 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (accept test): use ${.MAKE:S,^./,${.CURDIR}/,}
+ so that './bmake -f Makefile test' works.
+
+2004-02-14 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in: (BMAKE_VERSION): bump to 20040214
+ * Merge with NetBSD make, pick up:
+ o search upwards for *.mk
+ o fix for double free of var substitution buffers
+ o use of getopt replaced with custom code, since the usage
+ (re-scanning) isn't posix compatible.
+
+2004-02-12 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * arch.c: don't include ranlib.h on ELF systems
+ (thanks to Chuck Cranor <chuck@ece.cmu.edu>).
+
+2004-01-18 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump to 20040118
+
+ * boot-strap (while): export vars we assign to on cmdline
+ * unit-test/Makefile.in: ternary is .PHONY
+
+2004-01-08 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20040108
+ * Merge with NetBSD make, pick up:
+ o fix for ternary modifier
+
+2004-01-06 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20040105
+ * Merge with NetBSD make, pick up:
+ o fix for cond.c to handle compound expressions better
+ o variable expansion within sysV style replacements
+
+2003-12-22 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Make portable snprintf safer - output to /dev/null first to
+ check space needed.
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20031222
+ * Merge with NetBSD make, pick up:
+ o -dg3 to show input graph when things go wrong.
+ o explicitly look for makefiles in objdir if not found in curdir so
+ that errors in .depend etc will be reported accurarely.
+ o avoid use of -e in shell scripts in jobs mode, use '|| exit $?'
+ instead as it more accurately reflects the expected behavior and
+ is more consistently implemented.
+ o avoid use of asprintf.
+
+2003-09-28 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * util.c: Add asprintf and vasprintf.
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20030928
+ * Merge with NetBSD make, pick up:
+ :[] modifier - allows picking words from a variable.
+ :tW modifier - allows treating value as one big word.
+ W flag for :C and :S - allows treating value as one big word.
+
+2003-09-12 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Merge with NetBSD make
+ pick up -de flag to enable printing failed command.
+ don't skip 1st two dir entries (normally . and ..) since
+ coda does not have them.
+
+2003-09-09 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20030909
+ * Merge with NetBSD make, pick up:
+ - changes for -V '${VAR}' to print fully expanded value
+ cf. -V VAR
+ - CompatRunCommand now prints the command that failed.
+ - several files got updated 3 clause Berkeley license.
+
+2003-08-02 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * boot-strap: Allow setting configure args on command line.
+
+2003-07-31 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * configure.in: add --with-defshell to allow sh or ksh
+ to be selected as default shell.
+
+ * Makefile.in: bump version to 20030731
+
+ * Merge with NetBSD make
+ Pick up .SHELL spec for ksh and associate man page changes.
+ Also compat mode now uses the same shell specs.
+
+2003-07-29 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * var.c (Var_Parse): ensure delim is initialized.
+
+ * unit-tests/Makefile.in: use single quotes to avoid problems from
+ some shells.
+
+ * makefile.boot.in:
+ Run the unit-tests as part of the bootstrap procedure.
+
+2003-07-28 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * unit-tests/Makefile.in: always force complaints from
+ ${TEST_MAKE} to be from 'make'.
+
+ * configure.in: add check for 'diff -u'
+ also fix some old autoconf'isms
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20030728.
+ if using GCC add -Wno-cast-qual to CFLAGS for var.o
+
+ * Merge with NetBSD make
+ Pick up fix for :ts parsing error in some cases.
+ Pick unit-tests.
+
+2003-07-23 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in (BMAKE_VERSION): bump version to 20030723.
+
+ * var.c (Var_Parse): fix bug in :ts modifier, after const
+ correctness fixes, must pass nstr to VarModify.
+
+2003-07-14 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Makefile.in: BMAKE_VERSION switch to a date based version.
+ We'll generally use the date of last import from NetBSD.
+
+ * Merge with NetBSD make
+ Pick up fixes for const-correctness, now passes WARNS=3 on
+ NetBSD.
+ Pick up :ts modifier, allows controlling the separator used
+ between words in variable expansion.
+
+2003-07-11 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * FILES: include boot-strap and os.sh
+
+ * Makefile.in: only set WARNS if we are NetBSD, the effect on
+ FreeBSD is known to be bad.
+
+ * makefile.boot.in (bootstrap): make this the default target.
+
+ * Makefile.in: bump version to 3.1.19
+
+ * machine.sh: avoid A-Z with tr as it is bound to lose.
+
+2003-07-10 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Merge with NetBSD make
+ Pick up fix for PR/19781 - unhelpful error msg on unclosed ${var:foo
+ Plus some doc fixes.
+
+2003-04-27 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Merge with NetBSD make
+ Pick up fix for PR/1523 - don't count a library as built, if there
+ is no way to build it
+
+ * Bump version to 3.1.18
+
+2003-03-23 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Merge with NetBSD make
+ Pick up fix for ParseDoSpecialSrc - we only use it if .WAIT
+ appears in src list.
+
+2003-03-21 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Merge with NetBSD make (mmm 10th anniversary!)
+ pick up fix for .WAIT in srcs that refer to $@ or $* (PR#20828)
+ pick up -X which tells us to not export VAR=val via setenv if
+ we are already doing so via MAKEFLAGS. This saves valuable env
+ space on systems like Darwin.
+ set MAKE_VERSION to 3.1.17
+
+ * parse.c: pix up fix for suffix rules
+
+2003-03-06 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Merge with NetBSD make.
+ pick up fix for propagating -B via MAKEFLAGS.
+ set MAKE_VERSION to 3.1.16
+
+ * Apply some patches from pkgsrc-bootstrap/bmake
+ Originally by Grant Beattie <grant@netbsd.org>
+ I may have missed some - since they are based on bmake-3.1.12
+
+2002-12-03 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * makefile.boot.in (bmake): update install targets for those that
+ use them, also clear MAKEFLAGS when invoking bmake.boot to avoid
+ havoc from gmake -w. Thanks to Harlan Stenn <hstenn@cisco.com>.
+
+ * bmake.cat1: update the pre-formatted man page!
+
+2002-11-30 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Merge with NetBSD make.
+ pick up fix for premature free of pointer used in call
+ to Dir_InitCur().
+ set MAKE_VERSION to 3.1.15
+
+2002-11-26 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * configure.in: determine suitable value for MKSRC.
+ override using --with-mksrc=PATH.
+
+ * machine.sh: use `uname -p` for MACHINE_ARCH on modern SunOS systems.
+ configs(8) will use 'sun4' as an alias for 'sparc'.
+
+2002-11-25 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * Merge with NetBSD make.
+ pick up ${.PATH}
+ pick up fix for finding ../cat.c via .PATH when .CURDIR=..
+ set MAKE_VERSION to 3.1.14
+ add configure checks for killpg and sys/socket.h
+
+2002-09-16 Simon J. Gerraty <sjg@void.crufty.net>
+
+ * tag bmake-3-1-13
+
+ * makefile.boot.in (bmake): use install-mk
+ Also setup ./mk before trying to invoke bmake.boot incase we
+ needed install-mk to create a sys.mk for us.
+
+ * configure.in: If we need to add -I${srcdir}/missing, make it an
+ absolute path so that it works for lst.lib too.
+
+ * make.h: always include sys/cdefs.h since we provide one if the
+ host does not.
+
+ * Makefile.in (install-mk):
+ use MKSRC/install-mk which will do the right thing.
+ use uname -p for ARCH if possible.
+ since install-mk will setup links bsd.prog.mk -> prog.mk if
+ needed, just .include bsd.prog.mk
+
+ * Merge with NetBSD make (NetBSD-1.6)
+ Code is ansi-C only now.
+ Bug in handling of dotLast is fixed.
+ Can now assign .OBJDIR and make will reset its notions of life.
+ New modifiers :tu :tl for toUpper and toLower.
+
+Tue Oct 16 12:18:42 2001 Simon J. Gerraty <sjg@zen.crufty.net>
+
+ * Merge with NetBSD make
+ pick up fix for .END failure in compat mode.
+ pick up fix for extra va_end() in ParseVErrorInternal.
+
+Thu Oct 11 13:20:06 2001 Simon J. Gerraty <sjg@zen.crufty.net>
+
+ * configure.in: for systems that have sys/cdefs.h check if it is
+ compatible. If not, include the one under missing, but tell it to
+ include the native one too - necessary on Linux.
+
+ * missing/sys/cdefs.h: if NEED_HOST_CDEFS_H is defined, use
+ include_next (for gcc) to get the native sys/cdefs.h
+
+Tue Aug 21 02:29:34 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * job.c (JobFinish): Fix an earlier merge bug that resulted in
+ leaking descriptors when using -jN.
+
+ * job.c (JobPrintCommand): See if "curdir" exists before
+ attempting to chdir(). Doing the chdir directly in make (when in
+ compat mode) fails silently, so let the -jN version do the same.
+ This can happen when building kernels in an object tree and
+ playing clever games to reset .CURDIR.
+
+ * Merged with NetBSD make
+ pick up .USEBEFORE
+
+Tue Jun 26 23:45:11 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * makefile.boot.in: Give bmake.boot a MAKESYSPATH that might work.
+
+Tue Jun 12 16:48:57 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * var.c (Var_Set): Add 4th (flags) arg so VarLoopExpand can tell
+ us not to export the iterator variable when using VAR_CMD context.
+
+Sun Jun 10 21:55:21 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * job.c (Job_CatchChildren): don't call Job_CatchOutput() here,
+ its the wrong "fix".
+
+Sat Jun 9 00:11:24 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * Redesigned export of VAR_CMD's via MAKEFLAGS.
+ We now simply append the variable names to .MAKEOVERRIDES, and
+ handle duplicate suppression and quoting in ExportMAKEFLAGS using:
+ ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}
+ Apart from fixing quoting bugs in previous version, this allows us
+ to export vars to the environment by simply doing:
+ .MAKEOVERRIDES+= PATH
+ Merged again with NetBSD make, but the above is the only change.
+
+ * configure.in: added
+ --disable-pwd-override disable $PWD overriding getcwd()
+ --disable-check-make-chdir disable make trying to guess
+ when it should automatically cd ${.CURDIR}
+
+ * Merge with NetBSD make, changes include:
+ parse.c (ParseDoDependency): Spot that the syntax error is
+ caused by an unresolved cvs/rcs conflict and say so.
+ var.c: most of Var* functions now take a ctxt as 1st arg.
+ now does variable substituion on rhs of sysv style modifiers.
+
+ * var.c (Var_Set): exporting of command line variables (VAR_CMD)
+ is now done here. We append the name='value' to .MAKEOVERRIDES
+ rather than directly into MAKEFLAGS as this allows a Makefile to
+ use .MAKEOVERRIDES= to disable this behaviour. GNU make uses a
+ very similar mechanism. Note that in adding name='value' to
+ .MAKEOVERRIDES we do the moral equivalent of:
+ .MAKEOVERRIDES:= ${.MAKEOVERRIDES:Nname=*} name='val'
+
+Fri Jun 1 14:08:02 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * make-conf.h (USE_IOVEC): make it conditional on HAVE_SYS_UIO_H
+
+ * Merged with NetBSD make
+ make -dx can now be used to run commands via sh -x
+ better error messages on exec failures.
+
+Thu May 31 01:44:54 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * Makefile.in (main.o): depends on ${SRCS} ${MAKEFILE} so that
+ MAKE_VERSION gets updated. Also don't use ?= for MAKE_VERSION,
+ MACHINE etc otherwise they propagate from the previous bmake.
+
+ * configure.in (machine): allow --with-machine=generic to make
+ configure use machine.sh to set MACHINE.
+
+ * job.c (JobInterrupt): convert to using WAIT_T and friends.
+
+ * Makefile.in: mention in bmake.1 that we use autoconf.
+
+ * make.1: mention MAKE_PRINT_VAR_ON_ERROR.
+
+Wed May 30 23:17:18 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * main.c (ReadMakefile): don't set MAKEFILE if reading ".depend"
+ as that rather defeats the usefulness of ${MAKEFILE}.
+
+ * main.c (MainParseArgs): append command line variable assignments
+ to MAKEFLAGS so that they get propagated to child make's.
+ Apparently this is required POSIX behaviour? Its useful anyway.
+
+Tue May 29 02:20:07 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * compat.c (CompatRunCommand): don't use perror() since stdio may
+ cause problems in child of vfork().
+
+ * compat.c, main.c: Call PrintOnError() when we are going to bail.
+ This routine prints out the .curdir where we stopped and will also
+ display any vars listed in ${MAKE_PRINT_VAR_ON_ERROR}.
+
+ * main.c: add ${.newline} to hold a "\n" - sometimes handy in
+ :@ expansion.
+
+ * var.c: VarLoopExpand: ignore addSpace if a \n is present.
+
+ * Added RCSid's for the files we've touched.
+
+Thu May 24 15:41:37 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * configure.in: Thanks to some clues from mdb@juniper.net,
+ added autoconf magic to control setting of MACHINE, MACHINE_ARCH
+ as well as what ends up in _PATH_DEFSYSPATH. We now have:
+
+ --with-machine=MACHINE explicitly set MACHINE
+ --with-force-machine=MACHINE set FORCE_MACHINE
+ --with-machine_arch=MACHINE_ARCH explicitly set MACHINE_ARCH
+ --with-default-sys-path=PATH:DIR:LIST use an explicit _PATH_DEFSYSPATH
+ --with-prefix-sys-path=PATH:DIR:LIST prefix _PATH_PREFIX_SYSPATH
+ --with-path-objdirprefix=PATH override _PATH_OBJDIRPREFIX
+
+ If _PATH_OBJDIRPREFIX is set to "no" we won't define it.
+
+ * makefile: added a pathetically simple makefile to drive
+ bootstrapping. Running configure by hand is more useful.
+
+ * Makefile.in: added MAKE_VERSION, and reworked things to be less
+ dependent on NetBSD bsd.*.mk
+
+ * pathnames.h: allow NO_PATH_OBJDIRPREFIX to stop us defining
+ _PATH_OBJDIRPREFIX for those that don't want a default.
+ construct _PATH_DEFSYSPATH from the info we get from configure.
+
+ * main.c: allow for no _PATH_OBJDIRPREFIX, set ${MAKE_VERSION}
+ if MAKE_VERSION is defined.
+
+ * compat.c: when we bail, print out the .CURDIR we were in.
+
+Sat May 12 00:34:12 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * Merged with NetBSD make
+
+ * var.c: fixed a bug in the handling of the modifier :P
+ if the node as found but the path was null, we segfault trying to
+ duplicate it.
+
+Mon Mar 5 16:20:33 2001 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * Merged with NetBSD make
+
+ * make.c: Make_OODate's test for a library out of date was using
+ cmtime where it should have used mtime (my bug).
+
+ * compat.c: Use perror() to tell us what really went wrong when we
+ cannot exec a command.
+
+Fri Dec 15 10:11:08 2000 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * Merged with NetBSD make
+
+Sat Jun 10 10:11:08 2000 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * Merged with NetBSD make
+
+Thu Jun 1 10:11:08 2000 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * Merged with NetBSD make
+
+Tue May 30 10:11:08 2000 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * Merged with NetBSD make
+
+Thu Apr 27 00:07:47 2000 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * util.c: don't provide signal() since we use sigcompat.c
+
+ * Makefile.in: added a build target.
+
+ * var.c (Var_Parse): added ODE modifiers :U, :D, :L, :P, :@ and :!
+ These allow some quite clever magic.
+
+ * main.c (main): added support for getenv(MAKESYSPATH).
+
+Mon Apr 2 16:25:13 2000 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * Disable $PWD overriding getcwd() if MAKEOBJDIRPREFIX is set.
+ This avoids objdir having a different value depending on how a
+ directory was reached (via command line, or subdir.mk).
+
+ * If FORCE_MACHINE is defined, ignore getenv("MACHINE").
+
+Mon Apr 2 23:15:31 2000 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * Do a chdir(${.CURDIR}) before invoking ${.MAKE} or ${.MAKE:T} if
+ MAKEOBJDIRPREFIX is set and NOCHECKMAKECHDIR is not.
+ I've been testing this in NetBSD's make for some weeks.
+
+ * Turn Makefile into Makefile.in and make it useful.
+
+Tue Feb 29 22:08:00 2000 Simon J. Gerraty <sjg@zen.quick.com.au>
+
+ * Imported NetBSD's -current make(1) and resolve conflicts.
+
+ * Applied autoconf patches from bmake v2
+
+ * Imported clean code base from NetBSD-1.0
diff --git a/external/bsd/bmake/dist/FILES b/external/bsd/bmake/dist/FILES
new file mode 100644
index 0000000..397d3a2
--- /dev/null
+++ b/external/bsd/bmake/dist/FILES
@@ -0,0 +1,121 @@
+FILES
+ChangeLog
+bmake.cat1
+boot-strap
+bsd.after-import.mk
+os.sh
+Makefile.in
+PSD.doc/Makefile
+PSD.doc/tutorial.ms
+README
+arch.c
+buf.c
+buf.h
+compat.c
+cond.c
+make-conf.h
+make_malloc.c
+make_malloc.h
+config.h.in
+configure
+aclocal.m4
+configure.in
+dir.c
+dir.h
+find_lib.sh
+for.c
+getopt.c
+hash.c
+hash.h
+install-sh
+job.c
+job.h
+meta.c
+meta.h
+dirname.c
+realpath.c
+strlcpy.c
+strlist.c
+strlist.h
+stresep.c
+trace.c
+trace.h
+lst.h
+lst.lib/Makefile
+lst.lib/lstAppend.c
+lst.lib/lstAtEnd.c
+lst.lib/lstAtFront.c
+lst.lib/lstClose.c
+lst.lib/lstConcat.c
+lst.lib/lstDatum.c
+lst.lib/lstDeQueue.c
+lst.lib/lstDestroy.c
+lst.lib/lstDupl.c
+lst.lib/lstEnQueue.c
+lst.lib/lstFind.c
+lst.lib/lstFindFrom.c
+lst.lib/lstFirst.c
+lst.lib/lstForEach.c
+lst.lib/lstForEachFrom.c
+lst.lib/lstInit.c
+lst.lib/lstInsert.c
+lst.lib/lstInt.h
+lst.lib/lstIsAtEnd.c
+lst.lib/lstIsEmpty.c
+lst.lib/lstLast.c
+lst.lib/lstMember.c
+lst.lib/lstNext.c
+lst.lib/lstOpen.c
+lst.lib/lstPrev.c
+lst.lib/lstRemove.c
+lst.lib/lstReplace.c
+lst.lib/lstSucc.c
+machine.sh
+main.c
+make.1
+bmake.1
+make.c
+make.h
+make-bootstrap.sh.in
+missing/sys/cdefs.h
+mkdeps.sh
+nonints.h
+parse.c
+pathnames.h
+ranlib.h
+setenv.c
+sigcompat.c
+sprite.h
+str.c
+suff.c
+targ.c
+util.c
+var.c
+wait.h
+unit-tests/Makefile.in
+unit-tests/comment
+unit-tests/cond1
+unit-tests/doterror
+unit-tests/dotwait
+unit-tests/error
+unit-tests/export
+unit-tests/export-all
+unit-tests/forloop
+unit-tests/forsubst
+unit-tests/hash
+unit-tests/misc
+unit-tests/moderrs
+unit-tests/modmatch
+unit-tests/modmisc
+unit-tests/modorder
+unit-tests/modts
+unit-tests/modword
+unit-tests/phony-end
+unit-tests/posix
+unit-tests/qequals
+unit-tests/sysv
+unit-tests/ternary
+unit-tests/test.exp
+unit-tests/unexport
+unit-tests/unexport-env
+unit-tests/varcmd
diff --git a/external/bsd/bmake/dist/Makefile.in b/external/bsd/bmake/dist/Makefile.in
new file mode 100644
index 0000000..5a1f004
--- /dev/null
+++ b/external/bsd/bmake/dist/Makefile.in
@@ -0,0 +1,187 @@
+# $NetBSD: Makefile,v 1.56 2012/05/30 21:54:23 sjg Exp $
+# @(#)Makefile 5.2 (Berkeley) 12/28/90
+
+# $Id: Makefile.in,v 1.168 2012/07/05 04:10:23 sjg Exp $
+
+PROG= bmake
+SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \
+ make.c parse.c str.c suff.c targ.c trace.c var.c util.c
+SRCS+= strlist.c
+SRCS+= make_malloc.c
+SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \
+ lstDatum.c lstDeQueue.c lstDestroy.c lstDupl.c lstEnQueue.c \
+ lstFind.c lstFindFrom.c lstFirst.c lstForEach.c lstForEachFrom.c \
+ lstInit.c lstInsert.c lstIsAtEnd.c lstIsEmpty.c lstLast.c \
+ lstMember.c lstNext.c lstOpen.c lstRemove.c lstReplace.c lstSucc.c
+SRCS += lstPrev.c
+
+# you can use this Makefile if you have an earlier version of bmake.
+prefix= @prefix@
+srcdir= @srcdir@
+CC?= @CC@
+
+# Base version on src date
+MAKE_VERSION= 20120704
+MACHINE=@machine@
+MACHINE_ARCH=@machine_arch@
+DEFAULT_SYS_PATH = @default_sys_path@
+
+CPPFLAGS+= @CPPFLAGS@
+CFLAGS+= ${CPPFLAGS}
+CFLAGS+= -D_PATH_DEFSYSPATH=\"${DEFAULT_SYS_PATH}\"
+CFLAGS+= -I. -I${srcdir} @DEFS@ ${XDEFS} -DMAKE_NATIVE
+CFLAGS+= ${CFLAGS_${.TARGET:T}}
+CFLAGS+= ${COPTS.${.ALLSRC:M*.c:T:u}}
+COPTS.main.c+= "-DMAKE_VERSION=\"${MAKE_VERSION}\""
+LDFLAGS= @LDFLAGS@
+LIBOBJS= @LIBOBJS@
+LDADD= @LIBS@
+
+.if !empty(LIBOBJS)
+SRCS+= ${LIBOBJS:T:.o=.c}
+.endif
+
+USE_META = @use_meta@
+.if ${USE_META} != "no"
+SRCS+= meta.c
+CPPFLAGS+= -DUSE_META
+FILEMON_H ?= @filemon_h@
+.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
+COPTS.meta.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
+.endif
+.endif
+
+.PATH: ${srcdir}
+.PATH: ${srcdir}/lst.lib
+
+OS!= uname -s
+ARCH!= uname -p 2>/dev/null || uname -m
+
+# list of OS's which are derrived from BSD4.4
+isBSD44= NetBSD FreeBSD OpenBSD DragonFly
+
+.if ${OS} == "NetBSD"
+# Don't set these for anyone else since we don't know what the effect may be.
+# On FreeBSD WARNS=2 sets a bunch of -W flags that make does not handle.
+WFORMAT= 1
+WARNS=4
+.NOPATH: bmake.cat1
+.if make(install) && exists(${DESTDIR}/usr/share/doc)
+SUBDIR= PSD.doc
+.endif
+.endif
+
+.if empty(isBSD44:M${OS})
+# XXX not sure if we still want this given that configure
+# lets us force or not the definition of MACHINE.
+CFLAGS_main.o+= "-DFORCE_MACHINE=\"${MACHINE}\""
+MANTARGET=cat
+INSTALL?=${srcdir}/install-sh
+.if (${MACHINE} == "sun386")
+# even I don't have one of these anymore :-)
+CFLAGS+= -DPORTAR
+.elif (${MACHINE} != "sunos")
+SRCS+= sigcompat.c
+CFLAGS+= -DSIGNAL_FLAGS=SA_RESTART
+.endif
+.endif
+.if defined(.PARSEDIR)
+.if make(obj) || make(clean)
+SUBDIR+= unit-tests
+.endif
+.endif
+
+# many systems use gcc these days
+CC_IS_GCC=@GCC@
+.if ${CC_IS_GCC} == "yes"
+# problem with gcc3
+CFLAGS_var.o+= -Wno-cast-qual
+.endif
+
+CFLAGS_main.o+= "-D@force_machine@MACHINE=\"${MACHINE}\"" "-DMACHINE_ARCH=\"${MACHINE_ARCH}\""
+
+EXTRACT_MAN=no
+
+MAN=${PROG}.1
+.if (${PROG} != "make")
+${MAN}: make.1
+ @echo making ${PROG}.1
+ @sed -e 's/^.Nx/NetBSD/' -e '/^.Nm/s/make/${PROG}/' -e '/^.Sh HISTORY/,$$d' ${srcdir}/make.1 > $@
+ @(echo ".Sh HISTORY"; \
+ echo ".Nm"; \
+ echo "is derived from NetBSD"; \
+ echo ".Xr make 1 ."; \
+ echo It uses autoconf to facilitate portability to other platforms.) >> $@
+
+.endif
+
+.if !empty(isBSD44:M${OS})
+.if "${OS}" != "NetBSD"
+MAN1=${MAN}
+.endif
+MANTARGET?=man
+.endif
+
+MANTARGET?= cat
+MANDEST?= ${MANDIR}/${MANTARGET}1
+
+.if ${MANTARGET} == "cat"
+_mfromdir=${srcdir}
+.endif
+
+.if exists(${srcdir}/../Makefile.inc)
+.include "${srcdir}/../Makefile.inc"
+.endif
+.-include <bsd.prog.mk>
+# sigh, FreeBSD at least includes bsd.subdir.mk via bsd.obj.mk
+# so the inclusion below, results in complaints about re-defined
+# targets. For NetBSD though we need to explicitly include it.
+.if defined(.PARSEDIR)
+.if defined(SUBDIR) && !target(${SUBDIR:[1]})
+.-include <bsd.subdir.mk>
+.endif
+.endif
+
+CPPFLAGS+= -DMAKE_NATIVE
+COPTS.var.c += -Wno-cast-qual
+COPTS.job.c += -Wno-format-nonliteral
+COPTS.parse.c += -Wno-format-nonliteral
+COPTS.var.c += -Wno-format-nonliteral
+
+# Force these
+BINDIR= ${prefix}/bin
+MANDIR= ${prefix}/man
+
+arch.o: config.h
+# make sure that MAKE_VERSION gets updated.
+main.o: ${SRCS} ${MAKEFILE}
+
+MK?=${prefix}/share/mk
+MKSRC?=@mksrc@
+INSTALL?=${srcdir}/install-sh
+
+beforeinstall:
+ test -d ${DESTDIR}${BINDIR} || ${INSTALL} -m 775 -d ${DESTDIR}${BINDIR}
+ test -d ${DESTDIR}${MANDEST} || ${INSTALL} -m 775 -d ${DESTDIR}${MANDEST}
+
+# latest version of *.mk includes an installer.
+# you should not need to set USE_OS
+install-mk:
+.if exists(${MKSRC}/install-mk)
+ test -d ${DESTDIR}${MK} || ${INSTALL} -m 775 -d ${DESTDIR}${MK}
+ ${MKSRC}/install-mk -v -m 644 ${DESTDIR}${MK} ${USE_OS}
+.else
+ @echo need to unpack mk.tar.gz under ${srcdir} or set MKSRC; false
+.endif
+
+.ifdef TOOLDIR
+# this is a native netbsd build,
+# use libutil rather than the local emalloc etc.
+CPPFLAGS+= -DUSE_EMALLOC
+LDADD+=-lutil
+DPADD+=${LIBUTIL}
+.endif
+
+# A simple unit-test driver to help catch regressions
+accept test:
+ cd ${.CURDIR}/unit-tests && MAKEFLAGS= ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
diff --git a/external/bsd/bmake/dist/PSD.doc/Makefile b/external/bsd/bmake/dist/PSD.doc/Makefile
new file mode 100644
index 0000000..8e1f1fa
--- /dev/null
+++ b/external/bsd/bmake/dist/PSD.doc/Makefile
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile,v 1.2 1995/06/14 15:20:23 christos Exp $
+# @(#)Makefile 8.1 (Berkeley) 8/14/93
+
+DIR= psd/12.make
+SRCS= tutorial.ms
+MACROS= -ms
+
+.include <bsd.doc.mk>
diff --git a/external/bsd/bmake/dist/PSD.doc/tutorial.ms b/external/bsd/bmake/dist/PSD.doc/tutorial.ms
new file mode 100644
index 0000000..c1a6444
--- /dev/null
+++ b/external/bsd/bmake/dist/PSD.doc/tutorial.ms
@@ -0,0 +1,3773 @@
+.\" $NetBSD: tutorial.ms,v 1.11 2011/08/18 15:19:30 sjg Exp $
+.\" Copyright (c) 1988, 1989, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Adam de Boor.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" Copyright (c) 1988, 1989 by Adam de Boor
+.\" Copyright (c) 1989 by Berkeley Softworks
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Adam de Boor.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)tutorial.ms 8.1 (Berkeley) 8/18/93
+.\"
+.EH 'PSD:12-%''PMake \*- A Tutorial'
+.OH 'PMake \*- A Tutorial''PSD:12-%'
+.\" xH is a macro to provide numbered headers that are automatically stuffed
+.\" into a table-of-contents, properly indented, etc. If the first argument
+.\" is numeric, it is taken as the depth for numbering (as for .NH), else
+.\" the default (1) is assumed.
+.\"
+.\" @P The initial paragraph distance.
+.\" @Q The piece of section number to increment (or 0 if none given)
+.\" @R Section header.
+.\" @S Indent for toc entry
+.\" @T Argument to NH (can't use @Q b/c giving 0 to NH resets the counter)
+.de xH
+.NH \\$1
+\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
+.nr PD .1v
+.XS \\n%
+.ta 0.6i
+\\*(SN \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
+.XE
+.nr PD .3v
+..
+.\" CW is used to place a string in fixed-width or switch to a
+.\" fixed-width font.
+.\" C is a typewriter font for a laserwriter. Use something else if
+.\" you don't have one...
+.de CW
+.ie !\\n(.$ .ft C
+.el \&\\$3\fC\\$1\fP\\$2
+..
+.\" Anything I put in a display I want to be in fixed-width
+.am DS
+.CW
+..
+.\" The stuff in .No produces a little stop sign in the left margin
+.\" that says NOTE in it. Unfortunately, it does cause a break, but
+.\" hey. Can't have everything. In case you're wondering how I came
+.\" up with such weird commands, they came from running grn on a
+.\" gremlin file...
+.de No
+.br
+.ne 0.5i
+.po -0.5i
+.br
+.mk
+.nr g3 \\n(.f
+.nr g4 \\n(.s
+.sp -1
+.\" .st cf
+\D't 5u'
+.sp -1
+\h'50u'
+.sp -1
+\D't 3u'
+.sp -1
+.sp 7u
+\h'53u'
+\d\D'p -0.19i 0.0i 0.0i -0.13i 0.30i 0.0i 0.0i 0.13i'
+.sp -1
+.ft R
+.ps 6
+.nr g8 \\n(.d
+.ds g9 "NOTE
+.sp 74u
+\h'85u'\v'0.85n'\h-\w\\*(g9u/2u\&\\*(g9
+.sp |\\n(g8u
+.sp 166u
+\D't 3u'
+.br
+.po
+.rt
+.ft \\n(g3
+.ps \\n(g4
+..
+.de Bp
+.ie !\\n(.$ .IP \(bu 2
+.el .IP "\&" 2
+..
+.po +.3i
+.TL
+PMake \*- A Tutorial
+.AU
+Adam de Boor
+.AI
+Berkeley Softworks
+2150 Shattuck Ave, Penthouse
+Berkeley, CA 94704
+adam@bsw.uu.net
+\&...!uunet!bsw!adam
+.FS
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appears in all copies.
+The University of California, Berkeley Softworks, and Adam de Boor make no
+representations about the suitability of this software for any
+purpose. It is provided "as is" without express or implied warranty.
+.FE
+.PP
+.xH 1 Introduction
+.LP
+PMake is a program for creating other programs, or anything else you
+can think of for it to do. The basic idea behind PMake is that, for
+any given system, be it a program or a document or whatever, there
+will be some files that depend on the state of other files (on when
+they were last modified). PMake takes these dependencies, which you
+must specify, and uses them to build whatever it is you want it to
+build.
+.LP
+PMake is almost fully-compatible with Make, with which you may already
+be familiar. PMake's most important feature is its ability to run
+several different jobs at once, making the creation of systems
+considerably faster. It also has a great deal more functionality than
+Make. Throughout the text, whenever something is mentioned that is an
+important difference between PMake and Make (i.e. something that will
+cause a makefile to fail if you don't do something about it), or is
+simply important, it will be flagged with a little sign in the left
+margin, like this:
+.No
+.LP
+This tutorial is divided into three main sections corresponding to basic,
+intermediate and advanced PMake usage. If you already know Make well,
+you will only need to skim chapter 2 (there are some aspects of
+PMake that I consider basic to its use that didn't exist in Make).
+Things in chapter 3 make life much easier, while those in chapter 4
+are strictly for those who know what they are doing. Chapter 5 has
+definitions for the jargon I use and chapter 6 contains possible
+solutions to the problems presented throughout the tutorial.
+.xH 1 The Basics of PMake
+.LP
+PMake takes as input a file that tells a) which files depend on which
+other files to be complete and b) what to do about files that are
+``out-of-date.'' This file is known as a ``makefile'' and is usually
+.Ix 0 def makefile
+kept in the top-most directory of the system to be built. While you
+can call the makefile anything you want, PMake will look for
+.CW Makefile
+and
+.CW makefile
+(in that order) in the current directory if you don't tell it
+otherwise.
+.Ix 0 def makefile default
+To specify a different makefile, use the
+.B \-f
+flag (e.g.
+.CW "pmake -f program.mk" ''). ``
+.Ix 0 ref flags -f
+.Ix 0 ref makefile other
+.LP
+A makefile has four different types of lines in it:
+.RS
+.IP \(bu 2
+File dependency specifications
+.IP \(bu 2
+Creation commands
+.IP \(bu 2
+Variable assignments
+.IP \(bu 2
+Comments, include statements and conditional directives
+.RE
+.LP
+Any line may be continued over multiple lines by ending it with a
+backslash.
+.Ix 0 def "continuation line"
+The backslash, following newline and any initial whitespace
+on the following line are compressed into a single space before the
+input line is examined by PMake.
+.xH 2 Dependency Lines
+.LP
+As mentioned in the introduction, in any system, there are
+dependencies between the files that make up the system. For instance,
+in a program made up of several C source files and one header file,
+the C files will need to be re-compiled should the header file be
+changed. For a document of several chapters and one macro file, the
+chapters will need to be reprocessed if any of the macros changes.
+.Ix 0 def "dependency"
+These are dependencies and are specified by means of dependency lines in
+the makefile.
+.LP
+.Ix 0 def "dependency line"
+On a dependency line, there are targets and sources, separated by a
+one- or two-character operator.
+The targets ``depend'' on the sources and are usually created from
+them.
+.Ix 0 def target
+.Ix 0 def source
+.Ix 0 ref operator
+Any number of targets and sources may be specified on a dependency line.
+All the targets in the line are made to depend on all the sources.
+Targets and sources need not be actual files, but every source must be
+either an actual file or another target in the makefile.
+If you run out of room, use a backslash at the end of the line to continue onto
+the next one.
+.LP
+Any file may be a target and any file may be a source, but the
+relationship between the two (or however many) is determined by the
+``operator'' that separates them.
+.Ix 0 def operator
+Three types of operators exist: one specifies that the datedness of a
+target is determined by the state of its sources, while another
+specifies other files (the sources) that need to be dealt with before
+the target can be re-created. The third operator is very similar to
+the first, with the additional condition that the target is
+out-of-date if it has no sources. These operations are represented by
+the colon, the exclamation point and the double-colon, respectively, and are
+mutually exclusive. Their exact semantics are as follows:
+.IP ":"
+.Ix 0 def operator colon
+.Ix 0 def :
+If a colon is used, a target on the line is considered to be
+``out-of-date'' (and in need of creation) if
+.RS
+.IP \(bu 2
+any of the sources has been modified more recently than the target, or
+.IP \(bu 2
+the target doesn't exist.
+.RE
+.Ix 0 def out-of-date
+.IP "\&"
+Under this operation, steps will be taken to re-create the target only
+if it is found to be out-of-date by using these two rules.
+.IP "!"
+.Ix 0 def operator force
+.Ix 0 def !
+If an exclamation point is used, the target will always be re-created,
+but this will not happen until all of its sources have been examined
+and re-created, if necessary.
+.IP "::"
+.Ix 0 def operator double-colon
+.Ix 0 def ::
+If a double-colon is used, a target is out-of-date if:
+.RS
+.IP \(bu 2
+any of the sources has been modified more recently than the target, or
+.IP \(bu 2
+the target doesn't exist, or
+.IP \(bu 2
+the target has no sources.
+.RE
+.IP "\&"
+If the target is out-of-date according to these rules, it will be re-created.
+This operator also does something else to the targets, but I'll go
+into that in the next section (``Shell Commands'').
+.LP
+Enough words, now for an example. Take that C program I mentioned
+earlier. Say there are three C files
+.CW a.c , (
+.CW b.c
+and
+.CW c.c )
+each of which
+includes the file
+.CW defs.h .
+The dependencies between the files could then be expressed as follows:
+.DS
+program : a.o b.o c.o
+a.o b.o c.o : defs.h
+a.o : a.c
+b.o : b.c
+c.o : c.c
+.DE
+.LP
+You may be wondering at this point, where
+.CW a.o ,
+.CW b.o
+and
+.CW c.o
+came in and why
+.I they
+depend on
+.CW defs.h
+and the C files don't. The reason is quite simple:
+.CW program
+cannot be made by linking together .c files \*- it must be
+made from .o files. Likewise, if you change
+.CW defs.h ,
+it isn't the .c files that need to be re-created, it's the .o files.
+If you think of dependencies in these terms \*- which files (targets)
+need to be created from which files (sources) \*- you should have no problems.
+.LP
+An important thing to notice about the above example, is that all the
+\&.o files appear as targets on more than one line. This is perfectly
+all right: the target is made to depend on all the sources mentioned
+on all the dependency lines. E.g.
+.CW a.o
+depends on both
+.CW defs.h
+and
+.CW a.c .
+.Ix 0 ref dependency
+.No
+.LP
+The order of the dependency lines in the makefile is
+important: the first target on the first dependency line in the
+makefile will be the one that gets made if you don't say otherwise.
+That's why
+.CW program
+comes first in the example makefile, above.
+.LP
+Both targets and sources may contain the standard C-Shell wildcard
+characters
+.CW { , (
+.CW } ,
+.CW * ,
+.CW ? ,
+.CW [ ,
+and
+.CW ] ),
+but the non-curly-brace ones may only appear in the final component
+(the file portion) of the target or source. The characters mean the
+following things:
+.IP \fB{}\fP
+These enclose a comma-separated list of options and cause the pattern
+to be expanded once for each element of the list. Each expansion
+contains a different element. For example,
+.CW src/{whiffle,beep,fish}.c
+expands to the three words
+.CW src/whiffle.c ,
+.CW src/beep.c ,
+and
+.CW src/fish.c .
+These braces may be nested and, unlike the other wildcard characters,
+the resulting words need not be actual files. All other wildcard
+characters are expanded using the files that exist when PMake is
+started.
+.IP \fB*\fP
+This matches zero or more characters of any sort.
+.CW src/*.c
+will expand to the same three words as above as long as
+.CW src
+contains those three files (and no other files that end in
+.CW .c ).
+.IP \fB?\fP
+Matches any single character.
+.IP \fB[]\fP
+This is known as a character class and contains either a list of
+single characters, or a series of character ranges
+.CW a-z , (
+for example means all characters between a and z), or both. It matches
+any single character contained in the list. E.g.
+.CW [A-Za-z]
+will match all letters, while
+.CW [0123456789]
+will match all numbers.
+.xH 2 Shell Commands
+.LP
+``Isn't that nice,'' you say to yourself, ``but how are files
+actually `re-created,' as he likes to spell it?''
+The re-creation is accomplished by commands you place in the makefile.
+These commands are passed to the Bourne shell (better known as
+``/bin/sh'') to be executed and are
+.Ix 0 ref shell
+.Ix 0 ref re-creation
+.Ix 0 ref update
+expected to do what's necessary to update the target file (PMake
+doesn't actually check to see if the target was created. It just
+assumes it's there).
+.Ix 0 ref target
+.LP
+Shell commands in a makefile look a lot like shell commands you would
+type at a terminal, with one important exception: each command in a
+makefile
+.I must
+be preceded by at least one tab.
+.LP
+Each target has associated with it a shell script made up of
+one or more of these shell commands. The creation script for a target
+should immediately follow the dependency line for that target. While
+any given target may appear on more than one dependency line, only one
+of these dependency lines may be followed by a creation script, unless
+the `::' operator was used on the dependency line.
+.Ix 0 ref operator double-colon
+.Ix 0 ref ::
+.No
+.LP
+If the double-colon was used, each dependency line for the target
+may be followed by a shell script. That script will only be executed
+if the target on the associated dependency line is out-of-date with
+respect to the sources on that line, according to the rules I gave
+earlier.
+I'll give you a good example of this later on.
+.LP
+To expand on the earlier makefile, you might add commands as follows:
+.DS
+program : a.o b.o c.o
+ cc a.o b.o c.o \-o program
+a.o b.o c.o : defs.h
+a.o : a.c
+ cc \-c a.c
+b.o : b.c
+ cc \-c b.c
+c.o : c.c
+ cc \-c c.c
+.DE
+.LP
+Something you should remember when writing a makefile is, the
+commands will be executed if the
+.I target
+on the dependency line is out-of-date, not the sources.
+.Ix 0 ref target
+.Ix 0 ref source
+.Ix 0 ref out-of-date
+In this example, the command
+.CW "cc \-c a.c" '' ``
+will be executed if
+.CW a.o
+is out-of-date. Because of the `:' operator,
+.Ix 0 ref :
+.Ix 0 ref operator colon
+this means that should
+.CW a.c
+.I or
+.CW defs.h
+have been modified more recently than
+.CW a.o ,
+the command will be executed
+.CW a.o "\&" (
+will be considered out-of-date).
+.Ix 0 ref out-of-date
+.LP
+Remember how I said the only difference between a makefile shell
+command and a regular shell command was the leading tab? I lied. There
+is another way in which makefile commands differ from regular ones.
+The first two characters after the initial whitespace are treated
+specially.
+If they are any combination of `@' and `\-', they cause PMake to do
+different things.
+.LP
+In most cases, shell commands are printed before they're
+actually executed. This is to keep you informed of what's going on. If
+an `@' appears, however, this echoing is suppressed. In the case of an
+.CW echo
+command, say
+.CW "echo Linking index" ,'' ``
+it would be
+rather silly to see
+.DS
+echo Linking index
+Linking index
+.DE
+.LP
+so PMake allows you to place an `@' before the command
+.CW "@echo Linking index" '') (``
+to prevent the command from being printed.
+.LP
+The other special character is the `\-'. In case you didn't know,
+shell commands finish with a certain ``exit status.'' This status is
+made available by the operating system to whatever program invoked the
+command. Normally this status will be 0 if everything went ok and
+non-zero if something went wrong. For this reason, PMake will consider
+an error to have occurred if one of the shells it invokes returns a non-zero
+status. When it detects an error, PMake's usual action is to abort
+whatever it's doing and exit with a non-zero status itself (any other
+targets that were being created will continue being made, but nothing
+new will be started. PMake will exit after the last job finishes).
+This behavior can be altered, however, by placing a `\-' at the front
+of a command
+.CW "\-mv index index.old" ''), (``
+certain command-line arguments,
+or doing other things, to be detailed later. In such
+a case, the non-zero status is simply ignored and PMake keeps chugging
+along.
+.No
+.LP
+Because all the commands are given to a single shell to execute, such
+things as setting shell variables, changing directories, etc., last
+beyond the command in which they are found. This also allows shell
+compound commands (like
+.CW for
+loops) to be entered in a natural manner.
+Since this could cause problems for some makefiles that depend on
+each command being executed by a single shell, PMake has a
+.B \-B
+.Ix 0 ref compatibility
+.Ix 0 ref flags -B
+flag (it stands for backwards-compatible) that forces each command to
+be given to a separate shell. It also does several other things, all
+of which I discourage since they are now old-fashioned.\|.\|.\|.
+.No
+.LP
+A target's shell script is fed to the shell on its (the shell's) input stream.
+This means that any commands, such as
+.CW ci
+that need to get input from the terminal won't work right \*- they'll
+get the shell's input, something they probably won't find to their
+liking. A simple way around this is to give a command like this:
+.DS
+ci $(SRCS) < /dev/tty
+.DE
+This would force the program's input to come from the terminal. If you
+can't do this for some reason, your only other alternative is to use
+PMake in its fullest compatibility mode. See
+.B Compatibility
+in chapter 4.
+.Ix 0 ref compatibility
+.LP
+.xH 2 Variables
+.LP
+PMake, like Make before it, has the ability to save text in variables
+to be recalled later at your convenience. Variables in PMake are used
+much like variables in the shell and, by tradition, consist of
+all upper-case letters (you don't
+.I have
+to use all upper-case letters.
+In fact there's nothing to stop you from calling a variable
+.CW @^&$%$ .
+Just tradition). Variables are assigned-to using lines of the form
+.Ix 0 def variable assignment
+.DS
+VARIABLE = value
+.DE
+.Ix 0 def variable assignment
+appended-to by
+.DS
+VARIABLE += value
+.DE
+.Ix 0 def variable appending
+.Ix 0 def variable assignment appended
+.Ix 0 def +=
+conditionally assigned-to (if the variable isn't already defined) by
+.DS
+VARIABLE ?= value
+.DE
+.Ix 0 def variable assignment conditional
+.Ix 0 def ?=
+and assigned-to with expansion (i.e. the value is expanded (see below)
+before being assigned to the variable\*-useful for placing a value at
+the beginning of a variable, or other things) by
+.DS
+VARIABLE := value
+.DE
+.Ix 0 def variable assignment expanded
+.Ix 0 def :=
+.LP
+Any whitespace before
+.I value
+is stripped off. When appending, a space is placed between the old
+value and the stuff being appended.
+.LP
+The final way a variable may be assigned to is using
+.DS
+VARIABLE != shell-command
+.DE
+.Ix 0 def variable assignment shell-output
+.Ix 0 def !=
+In this case,
+.I shell-command
+has all its variables expanded (see below) and is passed off to a
+shell to execute. The output of the shell is then placed in the
+variable. Any newlines (other than the final one) are replaced by
+spaces before the assignment is made. This is typically used to find
+the current directory via a line like:
+.DS
+CWD != pwd
+.DE
+.LP
+.B Note:
+this is intended to be used to execute commands that produce small amounts
+of output (e.g. ``pwd''). The implementation is less than intelligent and will
+likely freeze if you execute something that produces thousands of
+bytes of output (8 Kb is the limit on many UNIX systems).
+.LP
+The value of a variable may be retrieved by enclosing the variable
+name in parentheses or curly braces and preceding the whole thing
+with a dollar sign.
+.LP
+For example, to set the variable CFLAGS to the string
+.CW "\-I/sprite/src/lib/libc \-O" ,'' ``
+you would place a line
+.DS
+CFLAGS = \-I/sprite/src/lib/libc \-O
+.DE
+in the makefile and use the word
+.CW "$(CFLAGS)"
+wherever you would like the string
+.CW "\-I/sprite/src/lib/libc \-O"
+to appear. This is called variable expansion.
+.Ix 0 def variable expansion
+.No
+.LP
+Unlike Make, PMake will not expand a variable unless it knows
+the variable exists. E.g. if you have a
+.CW "${i}"
+in a shell command and you have not assigned a value to the variable
+.CW i
+(the empty string is considered a value, by the way), where Make would have
+substituted the empty string, PMake will leave the
+.CW "${i}"
+alone.
+To keep PMake from substituting for a variable it knows, precede the
+dollar sign with another dollar sign.
+(e.g. to pass
+.CW "${HOME}"
+to the shell, use
+.CW "$${HOME}" ).
+This causes PMake, in effect, to expand the
+.CW $
+macro, which expands to a single
+.CW $ .
+For compatibility, Make's style of variable expansion will be used
+if you invoke PMake with any of the compatibility flags (\c
+.B \-V ,
+.B \-B
+or
+.B \-M .
+The
+.B \-V
+flag alters just the variable expansion).
+.Ix 0 ref flags -V
+.Ix 0 ref flags -B
+.Ix 0 ref flags -M
+.Ix 0 ref compatibility
+.LP
+.Ix 0 ref variable expansion
+There are two different times at which variable expansion occurs:
+When parsing a dependency line, the expansion occurs immediately
+upon reading the line. If any variable used on a dependency line is
+undefined, PMake will print a message and exit.
+Variables in shell commands are expanded when the command is
+executed.
+Variables used inside another variable are expanded whenever the outer
+variable is expanded (the expansion of an inner variable has no effect
+on the outer variable. I.e. if the outer variable is used on a dependency
+line and in a shell command, and the inner variable changes value
+between when the dependency line is read and the shell command is
+executed, two different values will be substituted for the outer
+variable).
+.Ix 0 def variable types
+.LP
+Variables come in four flavors, though they are all expanded the same
+and all look about the same. They are (in order of expanding scope):
+.RS
+.IP \(bu 2
+Local variables.
+.Ix 0 ref variable local
+.IP \(bu 2
+Command-line variables.
+.Ix 0 ref variable command-line
+.IP \(bu 2
+Global variables.
+.Ix 0 ref variable global
+.IP \(bu 2
+Environment variables.
+.Ix 0 ref variable environment
+.RE
+.LP
+The classification of variables doesn't matter much, except that the
+classes are searched from the top (local) to the bottom (environment)
+when looking up a variable. The first one found wins.
+.xH 3 Local Variables
+.LP
+.Ix 0 def variable local
+Each target can have as many as seven local variables. These are
+variables that are only ``visible'' within that target's shell script
+and contain such things as the target's name, all of its sources (from
+all its dependency lines), those sources that were out-of-date, etc.
+Four local variables are defined for all targets. They are:
+.RS
+.IP ".TARGET"
+.Ix 0 def variable local .TARGET
+.Ix 0 def .TARGET
+The name of the target.
+.IP ".OODATE"
+.Ix 0 def variable local .OODATE
+.Ix 0 def .OODATE
+The list of the sources for the target that were considered out-of-date.
+The order in the list is not guaranteed to be the same as the order in
+which the dependencies were given.
+.IP ".ALLSRC"
+.Ix 0 def variable local .ALLSRC
+.Ix 0 def .ALLSRC
+The list of all sources for this target in the order in which they
+were given.
+.IP ".PREFIX"
+.Ix 0 def variable local .PREFIX
+.Ix 0 def .PREFIX
+The target without its suffix and without any leading path. E.g. for
+the target
+.CW ../../lib/compat/fsRead.c ,
+this variable would contain
+.CW fsRead .
+.RE
+.LP
+Three other local variables are set only for certain targets under
+special circumstances. These are the ``.IMPSRC,''
+.Ix 0 ref variable local .IMPSRC
+.Ix 0 ref .IMPSRC
+``.ARCHIVE,''
+.Ix 0 ref variable local .ARCHIVE
+.Ix 0 ref .ARCHIVE
+and ``.MEMBER''
+.Ix 0 ref variable local .MEMBER
+.Ix 0 ref .MEMBER
+variables. When they are set and how they are used is described later.
+.LP
+Four of these variables may be used in sources as well as in shell
+scripts.
+.Ix 0 def "dynamic source"
+.Ix 0 def source dynamic
+These are ``.TARGET'', ``.PREFIX'', ``.ARCHIVE'' and ``.MEMBER''. The
+variables in the sources are expanded once for each target on the
+dependency line, providing what is known as a ``dynamic source,''
+.Rd 0
+allowing you to specify several dependency lines at once. For example,
+.DS
+$(OBJS) : $(.PREFIX).c
+.DE
+will create a dependency between each object file and its
+corresponding C source file.
+.xH 3 Command-line Variables
+.LP
+.Ix 0 def variable command-line
+Command-line variables are set when PMake is first invoked by giving a
+variable assignment as one of the arguments. For example,
+.DS
+pmake "CFLAGS = -I/sprite/src/lib/libc -O"
+.DE
+would make
+.CW CFLAGS
+be a command-line variable with the given value. Any assignments to
+.CW CFLAGS
+in the makefile will have no effect, because once it
+is set, there is (almost) nothing you can do to change a command-line
+variable (the search order, you see). Command-line variables may be
+set using any of the four assignment operators, though only
+.CW =
+and
+.CW ?=
+behave as you would expect them to, mostly because assignments to
+command-line variables are performed before the makefile is read, thus
+the values set in the makefile are unavailable at the time.
+.CW +=
+.Ix 0 ref +=
+.Ix 0 ref variable assignment appended
+is the same as
+.CW = ,
+because the old value of the variable is sought only in the scope in
+which the assignment is taking place (for reasons of efficiency that I
+won't get into here).
+.CW :=
+and
+.CW ?=
+.Ix 0 ref :=
+.Ix 0 ref ?=
+.Ix 0 ref variable assignment expanded
+.Ix 0 ref variable assignment conditional
+will work if the only variables used are in the environment.
+.CW !=
+is sort of pointless to use from the command line, since the same
+effect can no doubt be accomplished using the shell's own command
+substitution mechanisms (backquotes and all that).
+.xH 3 Global Variables
+.LP
+.Ix 0 def variable global
+Global variables are those set or appended-to in the makefile.
+There are two classes of global variables: those you set and those PMake sets.
+As I said before, the ones you set can have any name you want them to have,
+except they may not contain a colon or an exclamation point.
+The variables PMake sets (almost) always begin with a
+period and always contain upper-case letters, only. The variables are
+as follows:
+.RS
+.IP .PMAKE
+.Ix 0 def variable global .PMAKE
+.Ix 0 def .PMAKE
+.Ix 0 def variable global MAKE
+.Ix 0 def MAKE
+The name by which PMake was invoked is stored in this variable. For
+compatibility, the name is also stored in the MAKE variable.
+.IP .MAKEFLAGS
+.Ix 0 def variable global .MAKEFLAGS
+.Ix 0 def .MAKEFLAGS variable
+.Ix 0 def variable global MFLAGS
+.Ix 0 def MFLAGS
+All the relevant flags with which PMake was invoked. This does not
+include such things as
+.B \-f
+or variable assignments. Again for compatibility, this value is stored
+in the MFLAGS variable as well.
+.RE
+.LP
+Two other variables, ``.INCLUDES'' and ``.LIBS,'' are covered in the
+section on special targets in chapter 3.
+.Ix 0 ref variable global .INCLUDES
+.Ix 0 ref variable global .LIBS
+.LP
+Global variables may be deleted using lines of the form:
+.Ix 0 def #undef
+.Ix 0 def variable deletion
+.DS
+#undef \fIvariable\fP
+.DE
+The
+.CW # ' `
+must be the first character on the line. Note that this may only be
+done on global variables.
+.xH 3 Environment Variables
+.LP
+.Ix 0 def variable environment
+Environment variables are passed by the shell that invoked PMake and
+are given by PMake to each shell it invokes. They are expanded like
+any other variable, but they cannot be altered in any way.
+.LP
+One special environment variable,
+.CW PMAKE ,
+.Ix 0 def variable environment PMAKE
+is examined by PMake for command-line flags, variable assignments,
+etc., it should always use. This variable is examined before the
+actual arguments to PMake are. In addition, all flags given to PMake,
+either through the
+.CW PMAKE
+variable or on the command line, are placed in this environment
+variable and exported to each shell PMake executes. Thus recursive
+invocations of PMake automatically receive the same flags as the
+top-most one.
+.LP
+Using all these variables, you can compress the sample makefile even more:
+.DS
+OBJS = a.o b.o c.o
+program : $(OBJS)
+ cc $(.ALLSRC) \-o $(.TARGET)
+$(OBJS) : defs.h
+a.o : a.c
+ cc \-c a.c
+b.o : b.c
+ cc \-c b.c
+c.o : c.c
+ cc \-c c.c
+.DE
+.Ix 0 ref variable local .ALLSRC
+.Ix 0 ref .ALLSRC
+.Ix 0 ref variable local .TARGET
+.Ix 0 ref .TARGET
+.Rd 3
+.xH 2 Comments
+.LP
+.Ix 0 def comments
+Comments in a makefile start with a `#' character and extend to the
+end of the line. They may appear
+anywhere you want them, except in a shell command (though the shell
+will treat it as a comment, too). If, for some reason, you need to use the `#'
+in a variable or on a dependency line, put a backslash in front of it.
+PMake will compress the two into a single `#' (Note: this isn't true
+if PMake is operating in full-compatibility mode).
+.Ix 0 ref flags -M
+.Ix 0 ref compatibility
+.xH 2 Parallelism
+.No
+.LP
+PMake was specifically designed to re-create several targets at once,
+when possible. You do not have to do anything special to cause this to
+happen (unless PMake was configured to not act in parallel, in which
+case you will have to make use of the
+.B \-L
+and
+.B \-J
+flags (see below)),
+.Ix 0 ref flags -L
+.Ix 0 ref flags -J
+but you do have to be careful at times.
+.LP
+There are several problems you are likely to encounter. One is
+that some makefiles (and programs) are written in such a way that it is
+impossible for two targets to be made at once. The program
+.CW xstr ,
+for example,
+always modifies the files
+.CW strings
+and
+.CW x.c .
+There is no way to change it. Thus you cannot run two of them at once
+without something being trashed. Similarly, if you have commands
+in the makefile that always send output to the same file, you will not
+be able to make more than one target at once unless you change the
+file you use. You can, for instance, add a
+.CW $$$$
+to the end of the file name to tack on the process ID of the shell
+executing the command (each
+.CW $$
+expands to a single
+.CW $ ,
+thus giving you the shell variable
+.CW $$ ).
+Since only one shell is used for all the
+commands, you'll get the same file name for each command in the
+script.
+.LP
+The other problem comes from improperly-specified dependencies that
+worked in Make because of its sequential, depth-first way of examining
+them. While I don't want to go into depth on how PMake
+works (look in chapter 4 if you're interested), I will warn you that
+files in two different ``levels'' of the dependency tree may be
+examined in a different order in PMake than they were in Make. For
+example, given the makefile
+.DS
+a : b c
+b : d
+.DE
+PMake will examine the targets in the order
+.CW c ,
+.CW d ,
+.CW b ,
+.CW a .
+If the makefile's author expected PMake to abort before making
+.CW c
+if an error occurred while making
+.CW b ,
+or if
+.CW b
+needed to exist before
+.CW c
+was made,
+s/he will be sorely disappointed. The dependencies are
+incomplete, since in both these cases,
+.CW c
+would depend on
+.CW b .
+So watch out.
+.LP
+Another problem you may face is that, while PMake is set up to handle the
+output from multiple jobs in a graceful fashion, the same is not so for input.
+It has no way to regulate input to different jobs,
+so if you use the redirection from
+.CW /dev/tty
+I mentioned earlier, you must be careful not to run two of the jobs at once.
+.xH 2 Writing and Debugging a Makefile
+.LP
+Now you know most of what's in a makefile, what do you do next? There
+are two choices: (1) use one of the uncommonly-available makefile
+generators or (2) write your own makefile (I leave out the third choice of
+ignoring PMake and doing everything by hand as being beyond the bounds
+of common sense).
+.LP
+When faced with the writing of a makefile, it is usually best to start
+from first principles: just what
+.I are
+you trying to do? What do you want the makefile finally to produce?
+.LP
+To begin with a somewhat traditional example, let's say you need to
+write a makefile to create a program,
+.CW expr ,
+that takes standard infix expressions and converts them to prefix form (for
+no readily apparent reason). You've got three source files, in C, that
+make up the program:
+.CW main.c ,
+.CW parse.c ,
+and
+.CW output.c .
+Harking back to my pithy advice about dependency lines, you write the
+first line of the file:
+.DS
+expr : main.o parse.o output.o
+.DE
+because you remember
+.CW expr
+is made from
+.CW .o
+files, not
+.CW .c
+files. Similarly for the
+.CW .o
+files you produce the lines:
+.DS
+main.o : main.c
+parse.o : parse.c
+output.o : output.c
+main.o parse.o output.o : defs.h
+.DE
+.LP
+Great. You've now got the dependencies specified. What you need now is
+commands. These commands, remember, must produce the target on the
+dependency line, usually by using the sources you've listed.
+You remember about local variables? Good, so it should come
+to you as no surprise when you write
+.DS
+expr : main.o parse.o output.o
+ cc -o $(.TARGET) $(.ALLSRC)
+.DE
+Why use the variables? If your program grows to produce postfix
+expressions too (which, of course, requires a name change or two), it
+is one fewer place you have to change the file. You cannot do this for
+the object files, however, because they depend on their corresponding
+source files
+.I and
+.CW defs.h ,
+thus if you said
+.DS
+ cc -c $(.ALLSRC)
+.DE
+you'd get (for
+.CW main.o ):
+.DS
+ cc -c main.c defs.h
+.DE
+which is wrong. So you round out the makefile with these lines:
+.DS
+main.o : main.c
+ cc -c main.c
+parse.o : parse.c
+ cc -c parse.c
+output.o : output.c
+ cc -c output.c
+.DE
+.LP
+The makefile is now complete and will, in fact, create the program you
+want it to without unnecessary compilations or excessive typing on
+your part. There are two things wrong with it, however (aside from it
+being altogether too long, something I'll address in chapter 3):
+.IP 1)
+The string
+.CW "main.o parse.o output.o" '' ``
+is repeated twice, necessitating two changes when you add postfix
+(you were planning on that, weren't you?). This is in direct violation
+of de Boor's First Rule of writing makefiles:
+.QP
+.I
+Anything that needs to be written more than once
+should be placed in a variable.
+.IP "\&"
+I cannot emphasize this enough as being very important to the
+maintenance of a makefile and its program.
+.IP 2)
+There is no way to alter the way compilations are performed short of
+editing the makefile and making the change in all places. This is evil
+and violates de Boor's Second Rule, which follows directly from the
+first:
+.QP
+.I
+Any flags or programs used inside a makefile should be placed in a variable so
+they may be changed, temporarily or permanently, with the greatest ease.
+.LP
+The makefile should more properly read:
+.DS
+OBJS = main.o parse.o output.o
+expr : $(OBJS)
+ $(CC) $(CFLAGS) -o $(.TARGET) $(.ALLSRC)
+main.o : main.c
+ $(CC) $(CFLAGS) -c main.c
+parse.o : parse.c
+ $(CC) $(CFLAGS) -c parse.c
+output.o : output.c
+ $(CC) $(CFLAGS) -c output.c
+$(OBJS) : defs.h
+.DE
+Alternatively, if you like the idea of dynamic sources mentioned in
+section 2.3.1,
+.Rm 0 2.3.1
+.Rd 4
+.Ix 0 ref "dynamic source"
+.Ix 0 ref source dynamic
+you could write it like this:
+.DS
+OBJS = main.o parse.o output.o
+expr : $(OBJS)
+ $(CC) $(CFLAGS) -o $(.TARGET) $(.ALLSRC)
+$(OBJS) : $(.PREFIX).c defs.h
+ $(CC) $(CFLAGS) -c $(.PREFIX).c
+.DE
+These two rules and examples lead to de Boor's First Corollary:
+.QP
+.I
+Variables are your friends.
+.LP
+Once you've written the makefile comes the sometimes-difficult task of
+.Ix 0 ref debugging
+making sure the darn thing works. Your most helpful tool to make sure
+the makefile is at least syntactically correct is the
+.B \-n
+.Ix 0 ref flags -n
+flag, which allows you to see if PMake will choke on the makefile. The
+second thing the
+.B \-n
+flag lets you do is see what PMake would do without it actually doing
+it, thus you can make sure the right commands would be executed were
+you to give PMake its head.
+.LP
+When you find your makefile isn't behaving as you hoped, the first
+question that comes to mind (after ``What time is it, anyway?'') is
+``Why not?'' In answering this, two flags will serve you well:
+.CW "-d m" '' ``
+.Ix 0 ref flags -d
+and
+.CW "-p 2" .'' ``
+.Ix 0 ref flags -p
+The first causes PMake to tell you as it examines each target in the
+makefile and indicate why it is deciding whatever it is deciding. You
+can then use the information printed for other targets to see where
+you went wrong. The
+.CW "-p 2" '' ``
+flag makes PMake print out its internal state when it is done,
+allowing you to see that you forgot to make that one chapter depend on
+that file of macros you just got a new version of. The output from
+.CW "-p 2" '' ``
+is intended to resemble closely a real makefile, but with additional
+information provided and with variables expanded in those commands
+PMake actually printed or executed.
+.LP
+Something to be especially careful about is circular dependencies.
+.Ix 0 def dependency circular
+E.g.
+.DS
+a : b
+b : c d
+d : a
+.DE
+In this case, because of how PMake works,
+.CW c
+is the only thing PMake will examine, because
+.CW d
+and
+.CW a
+will effectively fall off the edge of the universe, making it
+impossible to examine
+.CW b
+(or them, for that matter).
+PMake will tell you (if run in its normal mode) all the targets
+involved in any cycle it looked at (i.e. if you have two cycles in the
+graph (naughty, naughty), but only try to make a target in one of
+them, PMake will only tell you about that one. You'll have to try to
+make the other to find the second cycle). When run as Make, it will
+only print the first target in the cycle.
+.xH 2 Invoking PMake
+.LP
+.Ix 0 ref flags
+.Ix 0 ref arguments
+.Ix 0 ref usage
+PMake comes with a wide variety of flags to choose from.
+They may appear in any order, interspersed with command-line variable
+assignments and targets to create.
+The flags are as follows:
+.IP "\fB\-d\fP \fIwhat\fP"
+.Ix 0 def flags -d
+.Ix 0 ref debugging
+This causes PMake to spew out debugging information that
+may prove useful to you. If you can't
+figure out why PMake is doing what it's doing, you might try using
+this flag. The
+.I what
+parameter is a string of single characters that tell PMake what
+aspects you are interested in. Most of what I describe will make
+little sense to you, unless you've dealt with Make before. Just
+remember where this table is and come back to it as you read on.
+The characters and the information they produce are as follows:
+.RS
+.IP a
+Archive searching and caching.
+.IP c
+Conditional evaluation.
+.IP d
+The searching and caching of directories.
+.IP j
+Various snippets of information related to the running of the multiple
+shells. Not particularly interesting.
+.IP m
+The making of each target: what target is being examined; when it was
+last modified; whether it is out-of-date; etc.
+.IP p
+Makefile parsing.
+.IP r
+Remote execution.
+.IP s
+The application of suffix-transformation rules. (See chapter 3)
+.IP t
+The maintenance of the list of targets.
+.IP v
+Variable assignment.
+.RE
+.IP "\&"
+Of these all, the
+.CW m
+and
+.CW s
+letters will be most useful to you.
+If the
+.B \-d
+is the final argument or the argument from which it would get these
+key letters (see below for a note about which argument would be used)
+begins with a
+.B \- ,
+all of these debugging flags will be set, resulting in massive amounts
+of output.
+.IP "\fB\-f\fP \fImakefile\fP"
+.Ix 0 def flags -f
+Specify a makefile to read different from the standard makefiles
+.CW Makefile "\&" (
+or
+.CW makefile ).
+.Ix 0 ref makefile default
+.Ix 0 ref makefile other
+If
+.I makefile
+is ``\-'', PMake uses the standard input. This is useful for making
+quick and dirty makefiles.\|.\|.
+.Ix 0 ref makefile "quick and dirty"
+.IP \fB\-h\fP
+.Ix 0 def flags -h
+Prints out a summary of the various flags PMake accepts. It can also
+be used to find out what level of concurrency was compiled into the
+version of PMake you are using (look at
+.B \-J
+and
+.B \-L )
+and various other information on how PMake was configured.
+.Ix 0 ref configuration
+.Ix 0 ref makefile system
+.IP \fB\-i\fP
+.Ix 0 def flags -i
+If you give this flag, PMake will ignore non-zero status returned
+by any of its shells. It's like placing a `\-' before all the commands
+in the makefile.
+.IP \fB\-k\fP
+.Ix 0 def flags -k
+This is similar to
+.B \-i
+in that it allows PMake to continue when it sees an error, but unlike
+.B \-i ,
+where PMake continues blithely as if nothing went wrong,
+.B \-k
+causes it to recognize the error and only continue work on those
+things that don't depend on the target, either directly or indirectly (through
+depending on something that depends on it), whose creation returned the error.
+The `k' is for ``keep going''.\|.\|.
+.Ix 0 ref target
+.IP \fB\-l\fP
+.Ix 0 def flags -l
+PMake has the ability to lock a directory against other
+people executing it in the same directory (by means of a file called
+``LOCK.make'' that it creates and checks for in the directory). This
+is a Good Thing because two people doing the same thing in the same place
+can be disastrous for the final product (too many cooks and all that).
+Whether this locking is the default is up to your system
+administrator. If locking is on,
+.B \-l
+will turn it off, and vice versa. Note that this locking will not
+prevent \fIyou\fP from invoking PMake twice in the same place \*- if
+you own the lock file, PMake will warn you about it but continue to execute.
+.IP "\fB\-m\fP \fIdirectory\fP"
+.Ix 0 def flags -m
+Tells PMake another place to search for included makefiles via the <...>
+style. Several
+.B \-m
+options can be given to form a search path. If this construct is used the
+default system makefile search path is completely overridden.
+To be explained in chapter 3, section 3.2.
+.Rm 2 3.2
+.IP \fB\-n\fP
+.Ix 0 def flags -n
+This flag tells PMake not to execute the commands needed to update the
+out-of-date targets in the makefile. Rather, PMake will simply print
+the commands it would have executed and exit. This is particularly
+useful for checking the correctness of a makefile. If PMake doesn't do
+what you expect it to, it's a good chance the makefile is wrong.
+.IP "\fB\-p\fP \fInumber\fP"
+.Ix 0 def flags -p
+.Ix 0 ref debugging
+This causes PMake to print its input in a reasonable form, though
+not necessarily one that would make immediate sense to anyone but me. The
+.I number
+is a bitwise-or of 1 and 2 where 1 means it should print the input
+before doing any processing and 2 says it should print it after
+everything has been re-created. Thus
+.CW "\-p 3"
+would print it twice\*-once before processing and once after (you
+might find the difference between the two interesting). This is mostly
+useful to me, but you may find it informative in some bizarre circumstances.
+.IP \fB\-q\fP
+.Ix 0 def flags -q
+If you give PMake this flag, it will not try to re-create anything. It
+will just see if anything is out-of-date and exit non-zero if so.
+.IP \fB\-r\fP
+.Ix 0 def flags -r
+When PMake starts up, it reads a default makefile that tells it what
+sort of system it's on and gives it some idea of what to do if you
+don't tell it anything. I'll tell you about it in chapter 3. If you
+give this flag, PMake won't read the default makefile.
+.IP \fB\-s\fP
+.Ix 0 def flags -s
+This causes PMake to not print commands before they're executed. It
+is the equivalent of putting an `@' before every command in the
+makefile.
+.IP \fB\-t\fP
+.Ix 0 def flags -t
+Rather than try to re-create a target, PMake will simply ``touch'' it
+so as to make it appear up-to-date. If the target didn't exist before,
+it will when PMake finishes, but if the target did exist, it will
+appear to have been updated.
+.IP \fB\-v\fP
+.Ix 0 def flags -v
+This is a mixed-compatibility flag intended to mimic the System V
+version of Make. It is the same as giving
+.B \-B ,
+and
+.B \-V
+as well as turning off directory locking. Targets can still be created
+in parallel, however. This is the mode PMake will enter if it is
+invoked either as
+.CW smake '' ``
+or
+.CW vmake ''. ``
+.IP \fB\-x\fP
+.Ix 0 def flags -x
+This tells PMake it's ok to export jobs to other machines, if they're
+available. It is used when running in Make mode, as exporting in this
+mode tends to make things run slower than if the commands were just
+executed locally.
+.IP \fB\-B\fP
+.Ix 0 ref compatibility
+.Ix 0 def flags -B
+Forces PMake to be as backwards-compatible with Make as possible while
+still being itself.
+This includes:
+.RS
+.IP \(bu 2
+Executing one shell per shell command
+.IP \(bu 2
+Expanding anything that looks even vaguely like a variable, with the
+empty string replacing any variable PMake doesn't know.
+.IP \(bu 2
+Refusing to allow you to escape a `#' with a backslash.
+.IP \(bu 2
+Permitting undefined variables on dependency lines and conditionals
+(see below). Normally this causes PMake to abort.
+.RE
+.IP \fB\-C\fP
+.Ix 0 def flags -C
+This nullifies any and all compatibility mode flags you may have given
+or implied up to the time the
+.B \-C
+is encountered. It is useful mostly in a makefile that you wrote for PMake
+to avoid bad things happening when someone runs PMake as
+.CW make '' ``
+or has things set in the environment that tell it to be compatible.
+.B \-C
+is
+.I not
+placed in the
+.CW PMAKE
+environment variable or the
+.CW .MAKEFLAGS
+or
+.CW MFLAGS
+global variables.
+.Ix 0 ref variable environment PMAKE
+.Ix 0 ref variable global .MAKEFLAGS
+.Ix 0 ref variable global MFLAGS
+.Ix 0 ref .MAKEFLAGS variable
+.Ix 0 ref MFLAGS
+.IP "\fB\-D\fP \fIvariable\fP"
+.Ix 0 def flags -D
+Allows you to define a variable to have
+.CW 1 '' ``
+as its value. The variable is a global variable, not a command-line
+variable. This is useful mostly for people who are used to the C
+compiler arguments and those using conditionals, which I'll get into
+in section 4.3
+.Rm 1 4.3
+.IP "\fB\-I\fP \fIdirectory\fP"
+.Ix 0 def flags -I
+Tells PMake another place to search for included makefiles. Yet
+another thing to be explained in chapter 3 (section 3.2, to be
+precise).
+.Rm 2 3.2
+.IP "\fB\-J\fP \fInumber\fP"
+.Ix 0 def flags -J
+Gives the absolute maximum number of targets to create at once on both
+local and remote machines.
+.IP "\fB\-L\fP \fInumber\fP"
+.Ix 0 def flags -L
+This specifies the maximum number of targets to create on the local
+machine at once. This may be 0, though you should be wary of doing
+this, as PMake may hang until a remote machine becomes available, if
+one is not available when it is started.
+.IP \fB\-M\fP
+.Ix 0 ref compatibility
+.Ix 0 def flags -M
+This is the flag that provides absolute, complete, full compatibility
+with Make. It still allows you to use all but a few of the features of
+PMake, but it is non-parallel. This is the mode PMake enters if you
+call it
+.CW make .'' ``
+.IP \fB\-P\fP
+.Ix 0 def flags -P
+.Ix 0 ref "output control"
+When creating targets in parallel, several shells are executing at
+once, each wanting to write its own two cent's-worth to the screen.
+This output must be captured by PMake in some way in order to prevent
+the screen from being filled with garbage even more indecipherable
+than you usually see. PMake has two ways of doing this, one of which
+provides for much cleaner output and a clear separation between the
+output of different jobs, the other of which provides a more immediate
+response so one can tell what is really happening. The former is done
+by notifying you when the creation of a target starts, capturing the
+output and transferring it to the screen all at once when the job
+finishes. The latter is done by catching the output of the shell (and
+its children) and buffering it until an entire line is received, then
+printing that line preceded by an indication of which job produced
+the output. Since I prefer this second method, it is the one used by
+default. The first method will be used if you give the
+.B \-P
+flag to PMake.
+.IP \fB\-V\fP
+.Ix 0 def flags -V
+As mentioned before, the
+.B \-V
+flag tells PMake to use Make's style of expanding variables,
+substituting the empty string for any variable it doesn't know.
+.IP \fB\-W\fP
+.Ix 0 def flags -W
+There are several times when PMake will print a message at you that is
+only a warning, i.e. it can continue to work in spite of your having
+done something silly (such as forgotten a leading tab for a shell
+command). Sometimes you are well aware of silly things you have done
+and would like PMake to stop bothering you. This flag tells it to shut
+up about anything non-fatal.
+.IP \fB\-X\fP
+.Ix 0 def flags -X
+This flag causes PMake to not attempt to export any jobs to another
+machine.
+.LP
+Several flags may follow a single `\-'. Those flags that require
+arguments take them from successive parameters. E.g.
+.DS
+pmake -fDnI server.mk DEBUG /chip2/X/server/include
+.DE
+will cause PMake to read
+.CW server.mk
+as the input makefile, define the variable
+.CW DEBUG
+as a global variable and look for included makefiles in the directory
+.CW /chip2/X/server/include .
+.xH 2 Summary
+.LP
+A makefile is made of four types of lines:
+.RS
+.IP \(bu 2
+Dependency lines
+.IP \(bu 2
+Creation commands
+.IP \(bu 2
+Variable assignments
+.IP \(bu 2
+Comments, include statements and conditional directives
+.RE
+.LP
+A dependency line is a list of one or more targets, an operator
+.CW : ', (`
+.CW :: ', `
+or
+.CW ! '), `
+and a list of zero or more sources. Sources may contain wildcards and
+certain local variables.
+.LP
+A creation command is a regular shell command preceded by a tab. In
+addition, if the first two characters after the tab (and other
+whitespace) are a combination of
+.CW @ ' `
+or
+.CW - ', `
+PMake will cause the command to not be printed (if the character is
+.CW @ ') `
+or errors from it to be ignored (if
+.CW - '). `
+A blank line, dependency line or variable assignment terminates a
+creation script. There may be only one creation script for each target
+with a
+.CW : ' `
+or
+.CW ! ' `
+operator.
+.LP
+Variables are places to store text. They may be unconditionally
+assigned-to using the
+.CW = ' `
+.Ix 0 ref =
+.Ix 0 ref variable assignment
+operator, appended-to using the
+.CW += ' `
+.Ix 0 ref +=
+.Ix 0 ref variable assignment appended
+operator, conditionally (if the variable is undefined) assigned-to
+with the
+.CW ?= ' `
+.Ix 0 ref ?=
+.Ix 0 ref variable assignment conditional
+operator, and assigned-to with variable expansion with the
+.CW := ' `
+.Ix 0 ref :=
+.Ix 0 ref variable assignment expanded
+operator. The output of a shell command may be assigned to a variable
+using the
+.CW != ' `
+.Ix 0 ref !=
+.Ix 0 ref variable assignment shell-output
+operator. Variables may be expanded (their value inserted) by enclosing
+their name in parentheses or curly braces, preceded by a dollar sign.
+A dollar sign may be escaped with another dollar sign. Variables are
+not expanded if PMake doesn't know about them. There are seven local
+variables:
+.CW .TARGET ,
+.CW .ALLSRC ,
+.CW .OODATE ,
+.CW .PREFIX ,
+.CW .IMPSRC ,
+.CW .ARCHIVE ,
+and
+.CW .MEMBER .
+Four of them
+.CW .TARGET , (
+.CW .PREFIX ,
+.CW .ARCHIVE ,
+and
+.CW .MEMBER )
+may be used to specify ``dynamic sources.''
+.Ix 0 ref "dynamic source"
+.Ix 0 ref source dynamic
+Variables are good. Know them. Love them. Live them.
+.LP
+Debugging of makefiles is best accomplished using the
+.B \-n ,
+.B "\-d m" ,
+and
+.B "\-p 2"
+flags.
+.xH 2 Exercises
+.ce
+\s+4\fBTBA\fP\s0
+.xH 1 Short-cuts and Other Nice Things
+.LP
+Based on what I've told you so far, you may have gotten the impression
+that PMake is just a way of storing away commands and making sure you
+don't forget to compile something. Good. That's just what it is.
+However, the ways I've described have been inelegant, at best, and
+painful, at worst.
+This chapter contains things that make the
+writing of makefiles easier and the makefiles themselves shorter and
+easier to modify (and, occasionally, simpler). In this chapter, I
+assume you are somewhat more
+familiar with Sprite (or UNIX, if that's what you're using) than I did
+in chapter 2, just so you're on your toes.
+So without further ado...
+.xH 2 Transformation Rules
+.LP
+As you know, a file's name consists of two parts: a base name, which
+gives some hint as to the contents of the file, and a suffix, which
+usually indicates the format of the file.
+Over the years, as
+.UX
+has developed,
+naming conventions, with regard to suffixes, have also developed that have
+become almost as incontrovertible as Law. E.g. a file ending in
+.CW .c
+is assumed to contain C source code; one with a
+.CW .o
+suffix is assumed to be a compiled, relocatable object file that may
+be linked into any program; a file with a
+.CW .ms
+suffix is usually a text file to be processed by Troff with the \-ms
+macro package, and so on.
+One of the best aspects of both Make and PMake comes from their
+understanding of how the suffix of a file pertains to its contents and
+their ability to do things with a file based solely on its suffix. This
+ability comes from something known as a transformation rule. A
+transformation rule specifies how to change a file with one suffix
+into a file with another suffix.
+.LP
+A transformation rule looks much like a dependency line, except the
+target is made of two known suffixes stuck together. Suffixes are made
+known to PMake by placing them as sources on a dependency line whose
+target is the special target
+.CW .SUFFIXES .
+E.g.
+.DS
+\&.SUFFIXES : .o .c
+\&.c.o :
+ $(CC) $(CFLAGS) -c $(.IMPSRC)
+.DE
+The creation script attached to the target is used to transform a file with
+the first suffix (in this case,
+.CW .c )
+into a file with the second suffix (here,
+.CW .o ).
+In addition, the target inherits whatever attributes have been applied
+to the transformation rule.
+The simple rule given above says that to transform a C source file
+into an object file, you compile it using
+.CW cc
+with the
+.CW \-c
+flag.
+This rule is taken straight from the system makefile. Many
+transformation rules (and suffixes) are defined there, and I refer you
+to it for more examples (type
+.CW "pmake -h" '' ``
+to find out where it is).
+.LP
+There are several things to note about the transformation rule given
+above:
+.RS
+.IP 1)
+The
+.CW .IMPSRC
+variable.
+.Ix 0 def variable local .IMPSRC
+.Ix 0 def .IMPSRC
+This variable is set to the ``implied source'' (the file from which
+the target is being created; the one with the first suffix), which, in this
+case, is the .c file.
+.IP 2)
+The
+.CW CFLAGS
+variable. Almost all of the transformation rules in the system
+makefile are set up using variables that you can alter in your
+makefile to tailor the rule to your needs. In this case, if you want
+all your C files to be compiled with the
+.B \-g
+flag, to provide information for
+.CW dbx ,
+you would set the
+.CW CFLAGS
+variable to contain
+.CW -g
+.CW "CFLAGS = -g" '') (``
+and PMake would take care of the rest.
+.RE
+.LP
+To give you a quick example, the makefile in 2.3.4
+.Rm 3 2.3.4
+could be changed to this:
+.DS
+OBJS = a.o b.o c.o
+program : $(OBJS)
+ $(CC) -o $(.TARGET) $(.ALLSRC)
+$(OBJS) : defs.h
+.DE
+The transformation rule I gave above takes the place of the 6 lines\**
+.FS
+This is also somewhat cleaner, I think, than the dynamic source
+solution presented in 2.6
+.FE
+.Rm 4 2.6
+.DS
+a.o : a.c
+ cc -c a.c
+b.o : b.c
+ cc -c b.c
+c.o : c.c
+ cc -c c.c
+.DE
+.LP
+Now you may be wondering about the dependency between the
+.CW .o
+and
+.CW .c
+files \*- it's not mentioned anywhere in the new makefile. This is
+because it isn't needed: one of the effects of applying a
+transformation rule is the target comes to depend on the implied
+source. That's why it's called the implied
+.I source .
+.LP
+For a more detailed example. Say you have a makefile like this:
+.DS
+a.out : a.o b.o
+ $(CC) $(.ALLSRC)
+.DE
+and a directory set up like this:
+.DS
+total 4
+-rw-rw-r-- 1 deboor 34 Sep 7 00:43 Makefile
+-rw-rw-r-- 1 deboor 119 Oct 3 19:39 a.c
+-rw-rw-r-- 1 deboor 201 Sep 7 00:43 a.o
+-rw-rw-r-- 1 deboor 69 Sep 7 00:43 b.c
+.DE
+While just typing
+.CW pmake '' ``
+will do the right thing, it's much more informative to type
+.CW "pmake -d s" ''. ``
+This will show you what PMake is up to as it processes the files. In
+this case, PMake prints the following:
+.DS
+Suff_FindDeps (a.out)
+ using existing source a.o
+ applying .o -> .out to "a.o"
+Suff_FindDeps (a.o)
+ trying a.c...got it
+ applying .c -> .o to "a.c"
+Suff_FindDeps (b.o)
+ trying b.c...got it
+ applying .c -> .o to "b.c"
+Suff_FindDeps (a.c)
+ trying a.y...not there
+ trying a.l...not there
+ trying a.c,v...not there
+ trying a.y,v...not there
+ trying a.l,v...not there
+Suff_FindDeps (b.c)
+ trying b.y...not there
+ trying b.l...not there
+ trying b.c,v...not there
+ trying b.y,v...not there
+ trying b.l,v...not there
+--- a.o ---
+cc -c a.c
+--- b.o ---
+cc -c b.c
+--- a.out ---
+cc a.o b.o
+.DE
+.LP
+.CW Suff_FindDeps
+is the name of a function in PMake that is called to check for implied
+sources for a target using transformation rules.
+The transformations it tries are, naturally
+enough, limited to the ones that have been defined (a transformation
+may be defined multiple times, by the way, but only the most recent
+one will be used). You will notice, however, that there is a definite
+order to the suffixes that are tried. This order is set by the
+relative positions of the suffixes on the
+.CW .SUFFIXES
+line \*- the earlier a suffix appears, the earlier it is checked as
+the source of a transformation. Once a suffix has been defined, the
+only way to change its position in the pecking order is to remove all
+the suffixes (by having a
+.CW .SUFFIXES
+dependency line with no sources) and redefine them in the order you
+want. (Previously-defined transformation rules will be automatically
+redefined as the suffixes they involve are re-entered.)
+.LP
+Another way to affect the search order is to make the dependency
+explicit. In the above example,
+.CW a.out
+depends on
+.CW a.o
+and
+.CW b.o .
+Since a transformation exists from
+.CW .o
+to
+.CW .out ,
+PMake uses that, as indicated by the
+.CW "using existing source a.o" '' ``
+message.
+.LP
+The search for a transformation starts from the suffix of the target
+and continues through all the defined transformations, in the order
+dictated by the suffix ranking, until an existing file with the same
+base (the target name minus the suffix and any leading directories) is
+found. At that point, one or more transformation rules will have been
+found to change the one existing file into the target.
+.LP
+For example, ignoring what's in the system makefile for now, say you
+have a makefile like this:
+.DS
+\&.SUFFIXES : .out .o .c .y .l
+\&.l.c :
+ lex $(.IMPSRC)
+ mv lex.yy.c $(.TARGET)
+\&.y.c :
+ yacc $(.IMPSRC)
+ mv y.tab.c $(.TARGET)
+\&.c.o :
+ cc -c $(.IMPSRC)
+\&.o.out :
+ cc -o $(.TARGET) $(.IMPSRC)
+.DE
+and the single file
+.CW jive.l .
+If you were to type
+.CW "pmake -rd ms jive.out" ,'' ``
+you would get the following output for
+.CW jive.out :
+.DS
+Suff_FindDeps (jive.out)
+ trying jive.o...not there
+ trying jive.c...not there
+ trying jive.y...not there
+ trying jive.l...got it
+ applying .l -> .c to "jive.l"
+ applying .c -> .o to "jive.c"
+ applying .o -> .out to "jive.o"
+.DE
+and this is why: PMake starts with the target
+.CW jive.out ,
+figures out its suffix
+.CW .out ) (
+and looks for things it can transform to a
+.CW .out
+file. In this case, it only finds
+.CW .o ,
+so it looks for the file
+.CW jive.o .
+It fails to find it, so it looks for transformations into a
+.CW .o
+file. Again it has only one choice:
+.CW .c .
+So it looks for
+.CW jive.c
+and, as you know, fails to find it. At this point it has two choices:
+it can create the
+.CW .c
+file from either a
+.CW .y
+file or a
+.CW .l
+file. Since
+.CW .y
+came first on the
+.CW .SUFFIXES
+line, it checks for
+.CW jive.y
+first, but can't find it, so it looks for
+.CW jive.l
+and, lo and behold, there it is.
+At this point, it has defined a transformation path as follows:
+.CW .l
+\(->
+.CW .c
+\(->
+.CW .o
+\(->
+.CW .out
+and applies the transformation rules accordingly. For completeness,
+and to give you a better idea of what PMake actually did with this
+three-step transformation, this is what PMake printed for the rest of
+the process:
+.DS
+Suff_FindDeps (jive.o)
+ using existing source jive.c
+ applying .c -> .o to "jive.c"
+Suff_FindDeps (jive.c)
+ using existing source jive.l
+ applying .l -> .c to "jive.l"
+Suff_FindDeps (jive.l)
+Examining jive.l...modified 17:16:01 Oct 4, 1987...up-to-date
+Examining jive.c...non-existent...out-of-date
+--- jive.c ---
+lex jive.l
+\&.\|.\|. meaningless lex output deleted .\|.\|.
+mv lex.yy.c jive.c
+Examining jive.o...non-existent...out-of-date
+--- jive.o ---
+cc -c jive.c
+Examining jive.out...non-existent...out-of-date
+--- jive.out ---
+cc -o jive.out jive.o
+.DE
+.LP
+One final question remains: what does PMake do with targets that have
+no known suffix? PMake simply pretends it actually has a known suffix
+and searches for transformations accordingly.
+The suffix it chooses is the source for the
+.CW .NULL
+.Ix 0 ref .NULL
+target mentioned later. In the system makefile,
+.CW .out
+is chosen as the ``null suffix''
+.Ix 0 def suffix null
+.Ix 0 def "null suffix"
+because most people use PMake to create programs. You are, however,
+free and welcome to change it to a suffix of your own choosing.
+The null suffix is ignored, however, when PMake is in compatibility
+mode (see chapter 4).
+.xH 2 Including Other Makefiles
+.Ix 0 def makefile inclusion
+.Rd 2
+.LP
+Just as for programs, it is often useful to extract certain parts of a
+makefile into another file and just include it in other makefiles
+somehow. Many compilers allow you say something like
+.DS
+#include "defs.h"
+.DE
+to include the contents of
+.CW defs.h
+in the source file. PMake allows you to do the same thing for
+makefiles, with the added ability to use variables in the filenames.
+An include directive in a makefile looks either like this:
+.DS
+#include <file>
+.DE
+or this
+.DS
+#include "file"
+.DE
+The difference between the two is where PMake searches for the file:
+the first way, PMake will look for
+the file only in the system makefile directory (or directories)
+(to find out what that directory is, give PMake the
+.B \-h
+flag).
+.Ix 0 ref flags -h
+The system makefile directory search path can be overridden via the
+.B \-m
+option.
+.Ix 0 ref flags -m
+For files in double-quotes, the search is more complex:
+.RS
+.IP 1)
+The directory of the makefile that's including the file.
+.IP 2)
+The current directory (the one in which you invoked PMake).
+.IP 3)
+The directories given by you using
+.B \-I
+flags, in the order in which you gave them.
+.IP 4)
+Directories given by
+.CW .PATH
+dependency lines (see chapter 4).
+.IP 5)
+The system makefile directory.
+.RE
+.LP
+in that order.
+.LP
+You are free to use PMake variables in the filename\*-PMake will
+expand them before searching for the file. You must specify the
+searching method with either angle brackets or double-quotes
+.I outside
+of a variable expansion. I.e. the following
+.DS
+SYSTEM = <command.mk>
+
+#include $(SYSTEM)
+.DE
+won't work.
+.xH 2 Saving Commands
+.LP
+.Ix 0 def ...
+There may come a time when you will want to save certain commands to
+be executed when everything else is done. For instance: you're
+making several different libraries at one time and you want to create the
+members in parallel. Problem is,
+.CW ranlib
+is another one of those programs that can't be run more than once in
+the same directory at the same time (each one creates a file called
+.CW __.SYMDEF
+into which it stuffs information for the linker to use. Two of them
+running at once will overwrite each other's file and the result will
+be garbage for both parties). You might want a way to save the ranlib
+commands til the end so they can be run one after the other, thus
+keeping them from trashing each other's file. PMake allows you to do
+this by inserting an ellipsis (``.\|.\|.'') as a command between
+commands to be run at once and those to be run later.
+.LP
+So for the
+.CW ranlib
+case above, you might do this:
+.Rd 5
+.DS
+lib1.a : $(LIB1OBJS)
+ rm -f $(.TARGET)
+ ar cr $(.TARGET) $(.ALLSRC)
+ ...
+ ranlib $(.TARGET)
+
+lib2.a : $(LIB2OBJS)
+ rm -f $(.TARGET)
+ ar cr $(.TARGET) $(.ALLSRC)
+ ...
+ ranlib $(.TARGET)
+.DE
+.Ix 0 ref variable local .TARGET
+.Ix 0 ref variable local .ALLSRC
+This would save both
+.DS
+ranlib $(.TARGET)
+.DE
+commands until the end, when they would run one after the other
+(using the correct value for the
+.CW .TARGET
+variable, of course).
+.LP
+Commands saved in this manner are only executed if PMake manages to
+re-create everything without an error.
+.xH 2 Target Attributes
+.LP
+PMake allows you to give attributes to targets by means of special
+sources. Like everything else PMake uses, these sources begin with a
+period and are made up of all upper-case letters. There are various
+reasons for using them, and I will try to give examples for most of
+them. Others you'll have to find uses for yourself. Think of it as ``an
+exercise for the reader.'' By placing one (or more) of these as a source on a
+dependency line, you are ``marking the target(s) with that
+attribute.'' That's just the way I phrase it, so you know.
+.LP
+Any attributes given as sources for a transformation rule are applied
+to the target of the transformation rule when the rule is applied.
+.Ix 0 def attributes
+.Ix 0 ref source
+.Ix 0 ref target
+.nr pw 12
+.IP .DONTCARE \n(pw
+.Ix 0 def attributes .DONTCARE
+.Ix 0 def .DONTCARE
+If a target is marked with this attribute and PMake can't figure out
+how to create it, it will ignore this fact and assume the file isn't
+really needed or actually exists and PMake just can't find it. This may prove
+wrong, but the error will be noted later on, not when PMake tries to create
+the target so marked. This attribute also prevents PMake from
+attempting to touch the target if it is given the
+.B \-t
+flag.
+.Ix 0 ref flags -t
+.IP .EXEC \n(pw
+.Ix 0 def attributes .EXEC
+.Ix 0 def .EXEC
+This attribute causes its shell script to be executed while having no
+effect on targets that depend on it. This makes the target into a sort
+of subroutine. An example. Say you have some LISP files that need to
+be compiled and loaded into a LISP process. To do this, you echo LISP
+commands into a file and execute a LISP with this file as its input
+when everything's done. Say also that you have to load other files
+from another system before you can compile your files and further,
+that you don't want to go through the loading and dumping unless one
+of
+.I your
+files has changed. Your makefile might look a little bit
+like this (remember, this is an educational example, and don't worry
+about the
+.CW COMPILE
+rule, all will soon become clear, grasshopper):
+.DS
+system : init a.fasl b.fasl c.fasl
+ for i in $(.ALLSRC);
+ do
+ echo -n '(load "' >> input
+ echo -n ${i} >> input
+ echo '")' >> input
+ done
+ echo '(dump "$(.TARGET)")' >> input
+ lisp < input
+
+a.fasl : a.l init COMPILE
+b.fasl : b.l init COMPILE
+c.fasl : c.l init COMPILE
+COMPILE : .USE
+ echo '(compile "$(.ALLSRC)")' >> input
+init : .EXEC
+ echo '(load-system)' > input
+.DE
+.Ix 0 ref .USE
+.Ix 0 ref attributes .USE
+.Ix 0 ref variable local .ALLSRC
+.IP "\&"
+.CW .EXEC
+sources, don't appear in the local variables of targets that depend on
+them (nor are they touched if PMake is given the
+.B \-t
+flag).
+.Ix 0 ref flags -t
+Note that all the rules, not just that for
+.CW system ,
+include
+.CW init
+as a source. This is because none of the other targets can be made
+until
+.CW init
+has been made, thus they depend on it.
+.IP .EXPORT \n(pw
+.Ix 0 def attributes .EXPORT
+.Ix 0 def .EXPORT
+This is used to mark those targets whose creation should be sent to
+another machine if at all possible. This may be used by some
+exportation schemes if the exportation is expensive. You should ask
+your system administrator if it is necessary.
+.IP .EXPORTSAME \n(pw
+.Ix 0 def attributes .EXPORTSAME
+.Ix 0 def .EXPORTSAME
+Tells the export system that the job should be exported to a machine
+of the same architecture as the current one. Certain operations (e.g.
+running text through
+.CW nroff )
+can be performed the same on any architecture (CPU and
+operating system type), while others (e.g. compiling a program with
+.CW cc )
+must be performed on a machine with the same architecture. Not all
+export systems will support this attribute.
+.IP .IGNORE \n(pw
+.Ix 0 def attributes .IGNORE
+.Ix 0 def .IGNORE attribute
+Giving a target the
+.CW .IGNORE
+attribute causes PMake to ignore errors from any of the target's commands, as
+if they all had `\-' before them.
+.IP .INVISIBLE \n(pw
+.Ix 0 def attributes .INVISIBLE
+.Ix 0 def .INVISIBLE
+This allows you to specify one target as a source for another without
+the one affecting the other's local variables. Useful if, say, you
+have a makefile that creates two programs, one of which is used to
+create the other, so it must exist before the other is created. You
+could say
+.DS
+prog1 : $(PROG1OBJS) prog2 MAKEINSTALL
+prog2 : $(PROG2OBJS) .INVISIBLE MAKEINSTALL
+.DE
+where
+.CW MAKEINSTALL
+is some complex .USE rule (see below) that depends on the
+.Ix 0 ref .USE
+.CW .ALLSRC
+variable containing the right things. Without the
+.CW .INVISIBLE
+attribute for
+.CW prog2 ,
+the
+.CW MAKEINSTALL
+rule couldn't be applied. This is not as useful as it should be, and
+the semantics may change (or the whole thing go away) in the
+not-too-distant future.
+.IP .JOIN \n(pw
+.Ix 0 def attributes .JOIN
+.Ix 0 def .JOIN
+This is another way to avoid performing some operations in parallel
+while permitting everything else to be done so. Specifically it
+forces the target's shell script to be executed only if one or more of the
+sources was out-of-date. In addition, the target's name,
+in both its
+.CW .TARGET
+variable and all the local variables of any target that depends on it,
+is replaced by the value of its
+.CW .ALLSRC
+variable.
+As an example, suppose you have a program that has four libraries that
+compile in the same directory along with, and at the same time as, the
+program. You again have the problem with
+.CW ranlib
+that I mentioned earlier, only this time it's more severe: you
+can't just put the ranlib off to the end since the program
+will need those libraries before it can be re-created. You can do
+something like this:
+.DS
+program : $(OBJS) libraries
+ cc -o $(.TARGET) $(.ALLSRC)
+
+libraries : lib1.a lib2.a lib3.a lib4.a .JOIN
+ ranlib $(.OODATE)
+.DE
+.Ix 0 ref variable local .TARGET
+.Ix 0 ref variable local .ALLSRC
+.Ix 0 ref variable local .OODATE
+.Ix 0 ref .TARGET
+.Ix 0 ref .ALLSRC
+.Ix 0 ref .OODATE
+In this case, PMake will re-create the
+.CW $(OBJS)
+as necessary, along with
+.CW lib1.a ,
+.CW lib2.a ,
+.CW lib3.a
+and
+.CW lib4.a .
+It will then execute
+.CW ranlib
+on any library that was changed and set
+.CW program 's
+.CW .ALLSRC
+variable to contain what's in
+.CW $(OBJS)
+followed by
+.CW "lib1.a lib2.a lib3.a lib4.a" .'' ``
+In case you're wondering, it's called
+.CW .JOIN
+because it joins together different threads of the ``input graph'' at
+the target marked with the attribute.
+Another aspect of the .JOIN attribute is it keeps the target from
+being created if the
+.B \-t
+flag was given.
+.Ix 0 ref flags -t
+.IP .MAKE \n(pw
+.Ix 0 def attributes .MAKE
+.Ix 0 def .MAKE
+The
+.CW .MAKE
+attribute marks its target as being a recursive invocation of PMake.
+This forces PMake to execute the script associated with the target (if
+it's out-of-date) even if you gave the
+.B \-n
+or
+.B \-t
+flag. By doing this, you can start at the top of a system and type
+.DS
+pmake -n
+.DE
+and have it descend the directory tree (if your makefiles are set up
+correctly), printing what it would have executed if you hadn't
+included the
+.B \-n
+flag.
+.IP .NOEXPORT \n(pw
+.Ix 0 def attributes .NOEXPORT
+.Ix 0 def .NOEXPORT attribute
+If possible, PMake will attempt to export the creation of all targets to
+another machine (this depends on how PMake was configured). Sometimes,
+the creation is so simple, it is pointless to send it to another
+machine. If you give the target the
+.CW .NOEXPORT
+attribute, it will be run locally, even if you've given PMake the
+.B "\-L 0"
+flag.
+.IP .NOTMAIN \n(pw
+.Ix 0 def attributes .NOTMAIN
+.Ix 0 def .NOTMAIN
+Normally, if you do not specify a target to make in any other way,
+PMake will take the first target on the first dependency line of a
+makefile as the target to create. That target is known as the ``Main
+Target'' and is labeled as such if you print the dependencies out
+using the
+.B \-p
+flag.
+.Ix 0 ref flags -p
+Giving a target this attribute tells PMake that the target is
+definitely
+.I not
+the Main Target.
+This allows you to place targets in an included makefile and
+have PMake create something else by default.
+.IP .PRECIOUS \n(pw
+.Ix 0 def attributes .PRECIOUS
+.Ix 0 def .PRECIOUS attribute
+When PMake is interrupted (you type control-C at the keyboard), it
+will attempt to clean up after itself by removing any half-made
+targets. If a target has the
+.CW .PRECIOUS
+attribute, however, PMake will leave it alone. An additional side
+effect of the `::' operator is to mark the targets as
+.CW .PRECIOUS .
+.Ix 0 ref operator double-colon
+.Ix 0 ref ::
+.IP .SILENT \n(pw
+.Ix 0 def attributes .SILENT
+.Ix 0 def .SILENT attribute
+Marking a target with this attribute keeps its commands from being
+printed when they're executed, just as if they had an `@' in front of them.
+.IP .USE \n(pw
+.Ix 0 def attributes .USE
+.Ix 0 def .USE
+By giving a target this attribute, you turn it into PMake's equivalent
+of a macro. When the target is used as a source for another target,
+the other target acquires the commands, sources and attributes (except
+.CW .USE )
+of the source.
+If the target already has commands, the
+.CW .USE
+target's commands are added to the end. If more than one .USE-marked
+source is given to a target, the rules are applied sequentially.
+.IP "\&" \n(pw
+The typical .USE rule (as I call them) will use the sources of the
+target to which it is applied (as stored in the
+.CW .ALLSRC
+variable for the target) as its ``arguments,'' if you will.
+For example, you probably noticed that the commands for creating
+.CW lib1.a
+and
+.CW lib2.a
+in the example in section 3.3
+.Rm 5 3.3
+were exactly the same. You can use the
+.CW .USE
+attribute to eliminate the repetition, like so:
+.DS
+lib1.a : $(LIB1OBJS) MAKELIB
+lib2.a : $(LIB2OBJS) MAKELIB
+
+MAKELIB : .USE
+ rm -f $(.TARGET)
+ ar cr $(.TARGET) $(.ALLSRC)
+ ...
+ ranlib $(.TARGET)
+.DE
+.Ix 0 ref variable local .TARGET
+.Ix 0 ref variable local .ALLSRC
+.IP "\&" \n(pw
+Several system makefiles (not to be confused with The System Makefile)
+make use of these .USE rules to make your
+life easier (they're in the default, system makefile directory...take a look).
+Note that the .USE rule source itself
+.CW MAKELIB ) (
+does not appear in any of the targets's local variables.
+There is no limit to the number of times I could use the
+.CW MAKELIB
+rule. If there were more libraries, I could continue with
+.CW "lib3.a : $(LIB3OBJS) MAKELIB" '' ``
+and so on and so forth.
+.xH 2 Special Targets
+.LP
+As there were in Make, so there are certain targets that have special
+meaning to PMake. When you use one on a dependency line, it is the
+only target that may appear on the left-hand-side of the operator.
+.Ix 0 ref target
+.Ix 0 ref operator
+As for the attributes and variables, all the special targets
+begin with a period and consist of upper-case letters only.
+I won't describe them all in detail because some of them are rather
+complex and I'll describe them in more detail than you'll want in
+chapter 4.
+The targets are as follows:
+.nr pw 10
+.IP .BEGIN \n(pw
+.Ix 0 def .BEGIN
+Any commands attached to this target are executed before anything else
+is done. You can use it for any initialization that needs doing.
+.IP .DEFAULT \n(pw
+.Ix 0 def .DEFAULT
+This is sort of a .USE rule for any target (that was used only as a
+source) that PMake can't figure out any other way to create. It's only
+``sort of'' a .USE rule because only the shell script attached to the
+.CW .DEFAULT
+target is used. The
+.CW .IMPSRC
+variable of a target that inherits
+.CW .DEFAULT 's
+commands is set to the target's own name.
+.Ix 0 ref .IMPSRC
+.Ix 0 ref variable local .IMPSRC
+.IP .END \n(pw
+.Ix 0 def .END
+This serves a function similar to
+.CW .BEGIN ,
+in that commands attached to it are executed once everything has been
+re-created (so long as no errors occurred). It also serves the extra
+function of being a place on which PMake can hang commands you put off
+to the end. Thus the script for this target will be executed before
+any of the commands you save with the ``.\|.\|.''.
+.Ix 0 ref ...
+.IP .EXPORT \n(pw
+The sources for this target are passed to the exportation system compiled
+into PMake. Some systems will use these sources to configure
+themselves. You should ask your system administrator about this.
+.IP .IGNORE \n(pw
+.Ix 0 def .IGNORE target
+.Ix 0 ref .IGNORE attribute
+.Ix 0 ref attributes .IGNORE
+This target marks each of its sources with the
+.CW .IGNORE
+attribute. If you don't give it any sources, then it is like
+giving the
+.B \-i
+flag when you invoke PMake \*- errors are ignored for all commands.
+.Ix 0 ref flags -i
+.IP .INCLUDES \n(pw
+.Ix 0 def .INCLUDES target
+.Ix 0 def variable global .INCLUDES
+.Ix 0 def .INCLUDES variable
+The sources for this target are taken to be suffixes that indicate a
+file that can be included in a program source file.
+The suffix must have already been declared with
+.CW .SUFFIXES
+(see below).
+Any suffix so marked will have the directories on its search path
+(see
+.CW .PATH ,
+below) placed in the
+.CW .INCLUDES
+variable, each preceded by a
+.B \-I
+flag. This variable can then be used as an argument for the compiler
+in the normal fashion. The
+.CW .h
+suffix is already marked in this way in the system makefile.
+.Ix 0 ref makefile system
+E.g. if you have
+.DS
+\&.SUFFIXES : .bitmap
+\&.PATH.bitmap : /usr/local/X/lib/bitmaps
+\&.INCLUDES : .bitmap
+.DE
+PMake will place
+.CW "-I/usr/local/X/lib/bitmaps" '' ``
+in the
+.CW .INCLUDES
+variable and you can then say
+.DS
+cc $(.INCLUDES) -c xprogram.c
+.DE
+(Note: the
+.CW .INCLUDES
+variable is not actually filled in until the entire makefile has been read.)
+.IP .INTERRUPT \n(pw
+.Ix 0 def .INTERRUPT
+When PMake is interrupted,
+it will execute the commands in the script for this target, if it
+exists.
+.IP .LIBS \n(pw
+.Ix 0 def .LIBS target
+.Ix 0 def .LIBS variable
+.Ix 0 def variable global .LIBS
+This does for libraries what
+.CW .INCLUDES
+does for include files, except the flag used is
+.B \-L ,
+as required by those linkers that allow you to tell them where to find
+libraries. The variable used is
+.CW .LIBS .
+Be forewarned that PMake may not have been compiled to do this if the
+linker on your system doesn't accept the
+.B \-L
+flag, though the
+.CW .LIBS
+variable will always be defined once the makefile has been read.
+.IP .MAIN \n(pw
+.Ix 0 def .MAIN
+If you didn't give a target (or targets) to create when you invoked
+PMake, it will take the sources of this target as the targets to
+create.
+.IP .MAKEFLAGS \n(pw
+.Ix 0 def .MAKEFLAGS target
+This target provides a way for you to always specify flags for PMake
+when the makefile is used. The flags are just as they would be typed
+to the shell (except you can't use shell variables unless they're in
+the environment),
+though the
+.B \-f
+and
+.B \-r
+flags have no effect.
+.IP .NULL \n(pw
+.Ix 0 def .NULL
+.Ix 0 ref suffix null
+.Ix 0 ref "null suffix"
+This allows you to specify what suffix PMake should pretend a file has
+if, in fact, it has no known suffix. Only one suffix may be so
+designated. The last source on the dependency line is the suffix that
+is used (you should, however, only give one suffix.\|.\|.).
+.IP .PATH \n(pw
+.Ix 0 def .PATH
+If you give sources for this target, PMake will take them as
+directories in which to search for files it cannot find in the current
+directory. If you give no sources, it will clear out any directories
+added to the search path before. Since the effects of this all get
+very complex, I'll leave it til chapter four to give you a complete
+explanation.
+.IP .PATH\fIsuffix\fP \n(pw
+.Ix 0 ref .PATH
+This does a similar thing to
+.CW .PATH ,
+but it does it only for files with the given suffix. The suffix must
+have been defined already. Look at
+.B "Search Paths"
+(section 4.1)
+.Rm 6 4.1
+for more information.
+.IP .PRECIOUS \n(pw
+.Ix 0 def .PRECIOUS target
+.Ix 0 ref .PRECIOUS attribute
+.Ix 0 ref attributes .PRECIOUS
+Similar to
+.CW .IGNORE ,
+this gives the
+.CW .PRECIOUS
+attribute to each source on the dependency line, unless there are no
+sources, in which case the
+.CW .PRECIOUS
+attribute is given to every target in the file.
+.IP .RECURSIVE \n(pw
+.Ix 0 def .RECURSIVE
+.Ix 0 ref attributes .MAKE
+.Ix 0 ref .MAKE
+This target applies the
+.CW .MAKE
+attribute to all its sources. It does nothing if you don't give it any sources.
+.IP .SHELL \n(pw
+.Ix 0 def .SHELL
+PMake is not constrained to only using the Bourne shell to execute
+the commands you put in the makefile. You can tell it some other shell
+to use with this target. Check out
+.B "A Shell is a Shell is a Shell"
+(section 4.4)
+.Rm 7 4.4
+for more information.
+.IP .SILENT \n(pw
+.Ix 0 def .SILENT target
+.Ix 0 ref .SILENT attribute
+.Ix 0 ref attributes .SILENT
+When you use
+.CW .SILENT
+as a target, it applies the
+.CW .SILENT
+attribute to each of its sources. If there are no sources on the
+dependency line, then it is as if you gave PMake the
+.B \-s
+flag and no commands will be echoed.
+.IP .SUFFIXES \n(pw
+.Ix 0 def .SUFFIXES
+This is used to give new file suffixes for PMake to handle. Each
+source is a suffix PMake should recognize. If you give a
+.CW .SUFFIXES
+dependency line with no sources, PMake will forget about all the
+suffixes it knew (this also nukes the null suffix).
+For those targets that need to have suffixes defined, this is how you do it.
+.LP
+In addition to these targets, a line of the form
+.DS
+\fIattribute\fP : \fIsources\fP
+.DE
+applies the
+.I attribute
+to all the targets listed as
+.I sources .
+.xH 2 Modifying Variable Expansion
+.LP
+.Ix 0 def variable expansion modified
+.Ix 0 ref variable expansion
+.Ix 0 def variable modifiers
+Variables need not always be expanded verbatim. PMake defines several
+modifiers that may be applied to a variable's value before it is
+expanded. You apply a modifier by placing it after the variable name
+with a colon between the two, like so:
+.DS
+${\fIVARIABLE\fP:\fImodifier\fP}
+.DE
+Each modifier is a single character followed by something specific to
+the modifier itself.
+You may apply as many modifiers as you want \*- each one is applied to
+the result of the previous and is separated from the previous by
+another colon.
+.LP
+There are seven ways to modify a variable's expansion, most of which
+come from the C shell variable modification characters:
+.RS
+.IP "M\fIpattern\fP"
+.Ix 0 def :M
+.Ix 0 def modifier match
+This is used to select only those words (a word is a series of
+characters that are neither spaces nor tabs) that match the given
+.I pattern .
+The pattern is a wildcard pattern like that used by the shell, where
+.CW *
+means 0 or more characters of any sort;
+.CW ?
+is any single character;
+.CW [abcd]
+matches any single character that is either `a', `b', `c' or `d'
+(there may be any number of characters between the brackets);
+.CW [0-9]
+matches any single character that is between `0' and `9' (i.e. any
+digit. This form may be freely mixed with the other bracket form), and
+`\\' is used to escape any of the characters `*', `?', `[' or `:',
+leaving them as regular characters to match themselves in a word.
+For example, the system makefile
+.CW <makedepend.mk>
+uses
+.CW "$(CFLAGS:M-[ID]*)" '' ``
+to extract all the
+.CW \-I
+and
+.CW \-D
+flags that would be passed to the C compiler. This allows it to
+properly locate include files and generate the correct dependencies.
+.IP "N\fIpattern\fP"
+.Ix 0 def :N
+.Ix 0 def modifier nomatch
+This is identical to
+.CW :M
+except it substitutes all words that don't match the given pattern.
+.IP "S/\fIsearch-string\fP/\fIreplacement-string\fP/[g]"
+.Ix 0 def :S
+.Ix 0 def modifier substitute
+Causes the first occurrence of
+.I search-string
+in the variable to be replaced by
+.I replacement-string ,
+unless the
+.CW g
+flag is given at the end, in which case all occurrences of the string
+are replaced. The substitution is performed on each word in the
+variable in turn. If
+.I search-string
+begins with a
+.CW ^ ,
+the string must match starting at the beginning of the word. If
+.I search-string
+ends with a
+.CW $ ,
+the string must match to the end of the word (these two may be
+combined to force an exact match). If a backslash precedes these two
+characters, however, they lose their special meaning. Variable
+expansion also occurs in the normal fashion inside both the
+.I search-string
+and the
+.I replacement-string ,
+.B except
+that a backslash is used to prevent the expansion of a
+.CW $ ,
+not another dollar sign, as is usual.
+Note that
+.I search-string
+is just a string, not a pattern, so none of the usual
+regular-expression/wildcard characters have any special meaning save
+.CW ^
+and
+.CW $ .
+In the replacement string,
+the
+.CW &
+character is replaced by the
+.I search-string
+unless it is preceded by a backslash.
+You are allowed to use any character except
+colon or exclamation point to separate the two strings. This so-called
+delimiter character may be placed in either string by preceding it
+with a backslash.
+.IP T
+.Ix 0 def :T
+.Ix 0 def modifier tail
+Replaces each word in the variable expansion by its last
+component (its ``tail''). For example, given
+.DS
+OBJS = ../lib/a.o b /usr/lib/libm.a
+TAILS = $(OBJS:T)
+.DE
+the variable
+.CW TAILS
+would expand to
+.CW "a.o b libm.a" .'' ``
+.IP H
+.Ix 0 def :H
+.Ix 0 def modifier head
+This is similar to
+.CW :T ,
+except that every word is replaced by everything but the tail (the
+``head''). Using the same definition of
+.CW OBJS ,
+the string
+.CW "$(OBJS:H)" '' ``
+would expand to
+.CW "../lib /usr/lib" .'' ``
+Note that the final slash on the heads is removed and
+anything without a head is replaced by the empty string.
+.IP E
+.Ix 0 def :E
+.Ix 0 def modifier extension
+.Ix 0 def modifier suffix
+.Ix 0 ref suffix "variable modifier"
+.CW :E
+replaces each word by its suffix (``extension''). So
+.CW "$(OBJS:E)" '' ``
+would give you
+.CW ".o .a" .'' ``
+.IP R
+.Ix 0 def :R
+.Ix 0 def modifier root
+.Ix 0 def modifier base
+This replaces each word by everything but the suffix (the ``root'' of
+the word).
+.CW "$(OBJS:R)" '' ``
+expands to ``
+.CW "../lib/a b /usr/lib/libm" .''
+.RE
+.LP
+In addition, the System V style of substitution is also supported.
+This looks like:
+.DS
+$(\fIVARIABLE\fP:\fIsearch-string\fP=\fIreplacement\fP)
+.DE
+It must be the last modifier in the chain. The search is anchored at
+the end of each word, so only suffixes or whole words may be replaced.
+.xH 2 More on Debugging
+.xH 2 More Exercises
+.IP (3.1)
+You've got a set programs, each of which is created from its own
+assembly-language source file (suffix
+.CW .asm ).
+Each program can be assembled into two versions, one with error-checking
+code assembled in and one without. You could assemble them into files
+with different suffixes
+.CW .eobj \& (
+and
+.CW .obj ,
+for instance), but your linker only understands files that end in
+.CW .obj .
+To top it all off, the final executables
+.I must
+have the suffix
+.CW .exe .
+How can you still use transformation rules to make your life easier
+(Hint: assume the error-checking versions have
+.CW ec
+tacked onto their prefix)?
+.IP (3.2)
+Assume, for a moment or two, you want to perform a sort of
+``indirection'' by placing the name of a variable into another one,
+then you want to get the value of the first by expanding the second
+somehow. Unfortunately, PMake doesn't allow constructs like
+.DS I
+$($(FOO))
+.DE
+What do you do? Hint: no further variable expansion is performed after
+modifiers are applied, thus if you cause a $ to occur in the
+expansion, that's what will be in the result.
+.xH 1 PMake for Gods
+.LP
+This chapter is devoted to those facilities in PMake that allow you to
+do a great deal in a makefile with very little work, as well as do
+some things you couldn't do in Make without a great deal of work (and
+perhaps the use of other programs). The problem with these features,
+is they must be handled with care, or you will end up with a mess.
+.LP
+Once more, I assume a greater familiarity with
+.UX
+or Sprite than I did in the previous two chapters.
+.xH 2 Search Paths
+.Rd 6
+.LP
+PMake supports the dispersal of files into multiple directories by
+allowing you to specify places to look for sources with
+.CW .PATH
+targets in the makefile. The directories you give as sources for these
+targets make up a ``search path.'' Only those files used exclusively
+as sources are actually sought on a search path, the assumption being
+that anything listed as a target in the makefile can be created by the
+makefile and thus should be in the current directory.
+.LP
+There are two types of search paths
+in PMake: one is used for all types of files (including included
+makefiles) and is specified with a plain
+.CW .PATH
+target (e.g.
+.CW ".PATH : RCS" ''), ``
+while the other is specific to a certain type of file, as indicated by
+the file's suffix. A specific search path is indicated by immediately following
+the
+.CW .PATH
+with the suffix of the file. For instance
+.DS
+\&.PATH.h : /sprite/lib/include /sprite/att/lib/include
+.DE
+would tell PMake to look in the directories
+.CW /sprite/lib/include
+and
+.CW /sprite/att/lib/include
+for any files whose suffix is
+.CW .h .
+.LP
+The current directory is always consulted first to see if a file
+exists. Only if it cannot be found there are the directories in the
+specific search path, followed by those in the general search path,
+consulted.
+.LP
+A search path is also used when expanding wildcard characters. If the
+pattern has a recognizable suffix on it, the path for that suffix will
+be used for the expansion. Otherwise the default search path is employed.
+.LP
+When a file is found in some directory other than the current one, all
+local variables that would have contained the target's name
+.CW .ALLSRC , (
+and
+.CW .IMPSRC )
+will instead contain the path to the file, as found by PMake.
+Thus if you have a file
+.CW ../lib/mumble.c
+and a makefile
+.DS
+\&.PATH.c : ../lib
+mumble : mumble.c
+ $(CC) -o $(.TARGET) $(.ALLSRC)
+.DE
+the command executed to create
+.CW mumble
+would be
+.CW "cc -o mumble ../lib/mumble.c" .'' ``
+(As an aside, the command in this case isn't strictly necessary, since
+it will be found using transformation rules if it isn't given. This is because
+.CW .out
+is the null suffix by default and a transformation exists from
+.CW .c
+to
+.CW .out .
+Just thought I'd throw that in.)
+.LP
+If a file exists in two directories on the same search path, the file
+in the first directory on the path will be the one PMake uses. So if
+you have a large system spread over many directories, it would behoove
+you to follow a naming convention that avoids such conflicts.
+.LP
+Something you should know about the way search paths are implemented
+is that each directory is read, and its contents cached, exactly once
+\&\*- when it is first encountered \*- so any changes to the
+directories while PMake is running will not be noted when searching
+for implicit sources, nor will they be found when PMake attempts to
+discover when the file was last modified, unless the file was created in the
+current directory. While people have suggested that PMake should read
+the directories each time, my experience suggests that the caching seldom
+causes problems. In addition, not caching the directories slows things
+down enormously because of PMake's attempts to apply transformation
+rules through non-existent files \*- the number of extra file-system
+searches is truly staggering, especially if many files without
+suffixes are used and the null suffix isn't changed from
+.CW .out .
+.xH 2 Archives and Libraries
+.LP
+.UX
+and Sprite allow you to merge files into an archive using the
+.CW ar
+command. Further, if the files are relocatable object files, you can
+run
+.CW ranlib
+on the archive and get yourself a library that you can link into any
+program you want. The main problem with archives is they double the
+space you need to store the archived files, since there's one copy in
+the archive and one copy out by itself. The problem with libraries is
+you usually think of them as
+.CW -lm
+rather than
+.CW /usr/lib/libm.a
+and the linker thinks they're out-of-date if you so much as look at
+them.
+.LP
+PMake solves the problem with archives by allowing you to tell it to
+examine the files in the archives (so you can remove the individual
+files without having to regenerate them later). To handle the problem
+with libraries, PMake adds an additional way of deciding if a library
+is out-of-date:
+.IP \(bu 2
+If the table of contents is older than the library, or is missing, the
+library is out-of-date.
+.LP
+A library is any target that looks like
+.CW \-l name'' ``
+or that ends in a suffix that was marked as a library using the
+.CW .LIBS
+target.
+.CW .a
+is so marked in the system makefile.
+.LP
+Members of an archive are specified as
+``\fIarchive\fP(\fImember\fP[ \fImember\fP...])''.
+Thus
+.CW libdix.a(window.o) '' ``'
+specifies the file
+.CW window.o
+in the archive
+.CW libdix.a .
+You may also use wildcards to specify the members of the archive. Just
+remember that most the wildcard characters will only find
+.I existing
+files.
+.LP
+A file that is a member of an archive is treated specially. If the
+file doesn't exist, but it is in the archive, the modification time
+recorded in the archive is used for the file when determining if the
+file is out-of-date. When figuring out how to make an archived member target
+(not the file itself, but the file in the archive \*- the
+\fIarchive\fP(\fImember\fP) target), special care is
+taken with the transformation rules, as follows:
+.IP \(bu 2
+\&\fIarchive\fP(\fImember\fP) is made to depend on \fImember\fP.
+.IP \(bu 2
+The transformation from the \fImember\fP's suffix to the
+\fIarchive\fP's suffix is applied to the \fIarchive\fP(\fImember\fP) target.
+.IP \(bu 2
+The \fIarchive\fP(\fImember\fP)'s
+.CW .TARGET
+variable is set to the name of the \fImember\fP if \fImember\fP is
+actually a target, or the path to the member file if \fImember\fP is
+only a source.
+.IP \(bu 2
+The
+.CW .ARCHIVE
+variable for the \fIarchive\fP(\fImember\fP) target is set to the name
+of the \fIarchive\fP.
+.Ix 0 def variable local .ARCHIVE
+.Ix 0 def .ARCHIVE
+.IP \(bu 2
+The
+.CW .MEMBER
+variable is set to the actual string inside the parentheses. In most
+cases, this will be the same as the
+.CW .TARGET
+variable.
+.Ix 0 def variable local .MEMBER
+.Ix 0 def .MEMBER
+.IP \(bu 2
+The \fIarchive\fP(\fImember\fP)'s place in the local variables of the
+targets that depend on it is taken by the value of its
+.CW .TARGET
+variable.
+.LP
+Thus, a program library could be created with the following makefile:
+.DS
+\&.o.a :
+ ...
+ rm -f $(.TARGET:T)
+OBJS = obj1.o obj2.o obj3.o
+libprog.a : libprog.a($(OBJS))
+ ar cru $(.TARGET) $(.OODATE)
+ ranlib $(.TARGET)
+.DE
+This will cause the three object files to be compiled (if the
+corresponding source files were modified after the object file or, if
+that doesn't exist, the archived object file), the out-of-date ones
+archived in
+.CW libprog.a ,
+a table of contents placed in the archive and the newly-archived
+object files to be removed.
+.LP
+All this is used in the
+.CW makelib.mk
+system makefile to create a single library with ease. This makefile
+looks like this:
+.DS
+.SM
+#
+# Rules for making libraries. The object files that make up the library
+# are removed once they are archived.
+#
+# To make several libraries in parallel, you should define the variable
+# "many_libraries". This will serialize the invocations of ranlib.
+#
+# To use, do something like this:
+#
+# OBJECTS = <files in the library>
+#
+# fish.a: fish.a($(OBJECTS)) MAKELIB
+#
+#
+
+#ifndef _MAKELIB_MK
+_MAKELIB_MK =
+
+#include <po.mk>
+
+\&.po.a .o.a :
+ ...
+ rm -f $(.MEMBER)
+
+ARFLAGS ?= crl
+
+#
+# Re-archive the out-of-date members and recreate the library's table of
+# contents using ranlib. If many_libraries is defined, put the ranlib
+# off til the end so many libraries can be made at once.
+#
+MAKELIB : .USE .PRECIOUS
+ ar $(ARFLAGS) $(.TARGET) $(.OODATE)
+#ifndef no_ranlib
+# ifdef many_libraries
+ ...
+# endif /* many_libraries */
+ ranlib $(.TARGET)
+#endif /* no_ranlib */
+
+#endif /* _MAKELIB_MK */
+.DE
+.xH 2 On the Condition...
+.Rd 1
+.LP
+Like the C compiler before it, PMake allows you to configure the makefile,
+based on the current environment, using conditional statements. A
+conditional looks like this:
+.DS
+#if \fIboolean expression\fP
+\fIlines\fP
+#elif \fIanother boolean expression\fP
+\fImore lines\fP
+#else
+\fIstill more lines\fP
+#endif
+.DE
+They may be nested to a maximum depth of 30 and may occur anywhere
+(except in a comment, of course). The
+.CW # '' ``
+must the very first character on the line.
+.LP
+Each
+.I "boolean expression"
+is made up of terms that look like function calls, the standard C
+boolean operators
+.CW && ,
+.CW || ,
+and
+.CW ! ,
+and the standard relational operators
+.CW == ,
+.CW != ,
+.CW > ,
+.CW >= ,
+.CW < ,
+and
+.CW <= ,
+with
+.CW ==
+and
+.CW !=
+being overloaded to allow string comparisons as well.
+.CW &&
+represents logical AND;
+.CW ||
+is logical OR and
+.CW !
+is logical NOT. The arithmetic and string operators take precedence
+over all three of these operators, while NOT takes precedence over
+AND, which takes precedence over OR. This precedence may be
+overridden with parentheses, and an expression may be parenthesized to
+your heart's content. Each term looks like a call on one of four
+functions:
+.nr pw 9
+.Ix 0 def make
+.Ix 0 def conditional make
+.Ix 0 def if make
+.IP make \n(pw
+The syntax is
+.CW make( \fItarget\fP\c
+.CW )
+where
+.I target
+is a target in the makefile. This is true if the given target was
+specified on the command line, or as the source for a
+.CW .MAIN
+target (note that the sources for
+.CW .MAIN
+are only used if no targets were given on the command line).
+.IP defined \n(pw
+.Ix 0 def defined
+.Ix 0 def conditional defined
+.Ix 0 def if defined
+The syntax is
+.CW defined( \fIvariable\fP\c
+.CW )
+and is true if
+.I variable
+is defined. Certain variables are defined in the system makefile that
+identify the system on which PMake is being run.
+.IP exists \n(pw
+.Ix 0 def exists
+.Ix 0 def conditional exists
+.Ix 0 def if exists
+The syntax is
+.CW exists( \fIfile\fP\c
+.CW )
+and is true if the file can be found on the global search path
+(i.e. that defined by
+.CW .PATH
+targets, not by
+.CW .PATH \fIsuffix\fP
+targets).
+.IP empty \n(pw
+.Ix 0 def empty
+.Ix 0 def conditional empty
+.Ix 0 def if empty
+This syntax is much like the others, except the string inside the
+parentheses is of the same form as you would put between parentheses
+when expanding a variable, complete with modifiers and everything. The
+function returns true if the resulting string is empty (NOTE: an undefined
+variable in this context will cause at the very least a warning
+message about a malformed conditional, and at the worst will cause the
+process to stop once it has read the makefile. If you want to check
+for a variable being defined or empty, use the expression
+.CW !defined( \fIvar\fP\c ``
+.CW ") || empty(" \fIvar\fP\c
+.CW ) ''
+as the definition of
+.CW ||
+will prevent the
+.CW empty()
+from being evaluated and causing an error, if the variable is
+undefined). This can be used to see if a variable contains a given
+word, for example:
+.DS
+#if !empty(\fIvar\fP:M\fIword\fP)
+.DE
+.LP
+The arithmetic and string operators may only be used to test the value
+of a variable. The lefthand side must contain the variable expansion,
+while the righthand side contains either a string, enclosed in
+double-quotes, or a number. The standard C numeric conventions (except
+for specifying an octal number) apply to both sides. E.g.
+.DS
+#if $(OS) == 4.3
+
+#if $(MACHINE) == "sun3"
+
+#if $(LOAD_ADDR) < 0xc000
+.DE
+are all valid conditionals. In addition, the numeric value of a
+variable can be tested as a boolean as follows:
+.DS
+#if $(LOAD)
+.DE
+would see if
+.CW LOAD
+contains a non-zero value and
+.DS
+#if !$(LOAD)
+.DE
+would test if
+.CW LOAD
+contains a zero value.
+.LP
+In addition to the bare
+.CW #if ,'' ``
+there are other forms that apply one of the first two functions to each
+term. They are as follows:
+.DS
+ ifdef \fRdefined\fP
+ ifndef \fR!defined\fP
+ ifmake \fRmake\fP
+ ifnmake \fR!make\fP
+.DE
+There are also the ``else if'' forms:
+.CW elif ,
+.CW elifdef ,
+.CW elifndef ,
+.CW elifmake ,
+and
+.CW elifnmake .
+.LP
+For instance, if you wish to create two versions of a program, one of which
+is optimized (the production version) and the other of which is for debugging
+(has symbols for dbx), you have two choices: you can create two
+makefiles, one of which uses the
+.CW \-g
+flag for the compilation, while the other uses the
+.CW \-O
+flag, or you can use another target (call it
+.CW debug )
+to create the debug version. The construct below will take care of
+this for you. I have also made it so defining the variable
+.CW DEBUG
+(say with
+.CW "pmake -D DEBUG" )
+will also cause the debug version to be made.
+.DS
+#if defined(DEBUG) || make(debug)
+CFLAGS += -g
+#else
+CFLAGS += -O
+#endif
+.DE
+There are, of course, problems with this approach. The most glaring
+annoyance is that if you want to go from making a debug version to
+making a production version, you have to remove all the object files,
+or you will get some optimized and some debug versions in the same
+program. Another annoyance is you have to be careful not to make two
+targets that ``conflict'' because of some conditionals in the
+makefile. For instance
+.DS
+#if make(print)
+FORMATTER = ditroff -Plaser_printer
+#endif
+#if make(draft)
+FORMATTER = nroff -Pdot_matrix_printer
+#endif
+.DE
+would wreak havoc if you tried
+.CW "pmake draft print" '' ``
+since you would use the same formatter for each target. As I said,
+this all gets somewhat complicated.
+.xH 2 A Shell is a Shell is a Shell
+.Rd 7
+.LP
+In normal operation, the Bourne Shell (better known as
+.CW sh '') ``
+is used to execute the commands to re-create targets. PMake also allows you
+to specify a different shell for it to use when executing these
+commands. There are several things PMake must know about the shell you
+wish to use. These things are specified as the sources for the
+.CW .SHELL
+.Ix 0 ref .SHELL
+.Ix 0 ref target .SHELL
+target by keyword, as follows:
+.IP "\fBpath=\fP\fIpath\fP"
+PMake needs to know where the shell actually resides, so it can
+execute it. If you specify this and nothing else, PMake will use the
+last component of the path and look in its table of the shells it
+knows and use the specification it finds, if any. Use this if you just
+want to use a different version of the Bourne or C Shell (yes, PMake knows
+how to use the C Shell too).
+.IP "\fBname=\fP\fIname\fP"
+This is the name by which the shell is to be known. It is a single
+word and, if no other keywords are specified (other than
+.B path ),
+it is the name by which PMake attempts to find a specification for
+it (as mentioned above). You can use this if you would just rather use
+the C Shell than the Bourne Shell
+.CW ".SHELL: name=csh" '' (``
+will do it).
+.IP "\fBquiet=\fP\fIecho-off command\fP"
+As mentioned before, PMake actually controls whether commands are
+printed by introducing commands into the shell's input stream. This
+keyword, and the next two, control what those commands are. The
+.B quiet
+keyword is the command used to turn echoing off. Once it is turned
+off, echoing is expected to remain off until the echo-on command is given.
+.IP "\fBecho=\fP\fIecho-on command\fP"
+The command PMake should give to turn echoing back on again.
+.IP "\fBfilter=\fP\fIprinted echo-off command\fP"
+Many shells will echo the echo-off command when it is given. This
+keyword tells PMake in what format the shell actually prints the
+echo-off command. Wherever PMake sees this string in the shell's
+output, it will delete it and any following whitespace, up to and
+including the next newline. See the example at the end of this section
+for more details.
+.IP "\fBechoFlag=\fP\fIflag to turn echoing on\fP"
+Unless a target has been marked
+.CW .SILENT ,
+PMake wants to start the shell running with echoing on. To do this, it
+passes this flag to the shell as one of its arguments. If either this
+or the next flag begins with a `\-', the flags will be passed to the
+shell as separate arguments. Otherwise, the two will be concatenated
+(if they are used at the same time, of course).
+.IP "\fBerrFlag=\fP\fIflag to turn error checking on\fP"
+Likewise, unless a target is marked
+.CW .IGNORE ,
+PMake wishes error-checking to be on from the very start. To this end,
+it will pass this flag to the shell as an argument. The same rules for
+an initial `\-' apply as for the
+.B echoFlag .
+.IP "\fBcheck=\fP\fIcommand to turn error checking on\fP"
+Just as for echo-control, error-control is achieved by inserting
+commands into the shell's input stream. This is the command to make
+the shell check for errors. It also serves another purpose if the
+shell doesn't have error-control as commands, but I'll get into that
+in a minute. Again, once error checking has been turned on, it is
+expected to remain on until it is turned off again.
+.IP "\fBignore=\fP\fIcommand to turn error checking off\fP"
+This is the command PMake uses to turn error checking off. It has
+another use if the shell doesn't do error-control, but I'll tell you
+about that.\|.\|.\|now.
+.IP "\fBhasErrCtl=\fP\fIyes or no\fP"
+This takes a value that is either
+.B yes
+or
+.B no .
+Now you might think that the existence of the
+.B check
+and
+.B ignore
+keywords would be enough to tell PMake if the shell can do
+error-control, but you'd be wrong. If
+.B hasErrCtl
+is
+.B yes ,
+PMake uses the check and ignore commands in a straight-forward manner.
+If this is
+.B no ,
+however, their use is rather different. In this case, the check
+command is used as a template, in which the string
+.B %s
+is replaced by the command that's about to be executed, to produce a
+command for the shell that will echo the command to be executed. The
+ignore command is also used as a template, again with
+.B %s
+replaced by the command to be executed, to produce a command that will
+execute the command to be executed and ignore any error it returns.
+When these strings are used as templates, you must provide newline(s)
+.CW \en '') (``
+in the appropriate place(s).
+.LP
+The strings that follow these keywords may be enclosed in single or
+double quotes (the quotes will be stripped off) and may contain the
+usual C backslash-characters (\en is newline, \er is return, \eb is
+backspace, \e' escapes a single-quote inside single-quotes, \e"
+escapes a double-quote inside double-quotes). Now for an example.
+.LP
+This is actually the contents of the
+.CW <shx.mk>
+system makefile, and causes PMake to use the Bourne Shell in such a
+way that each command is printed as it is executed. That is, if more
+than one command is given on a line, each will be printed separately.
+Similarly, each time the body of a loop is executed, the commands
+within that loop will be printed, etc. The specification runs like
+this:
+.DS
+#
+# This is a shell specification to have the Bourne shell echo
+# the commands just before executing them, rather than when it reads
+# them. Useful if you want to see how variables are being expanded, etc.
+#
+\&.SHELL : path=/bin/sh \e
+ quiet="set -" \e
+ echo="set -x" \e
+ filter="+ set - " \e
+ echoFlag=x \e
+ errFlag=e \e
+ hasErrCtl=yes \e
+ check="set -e" \e
+ ignore="set +e"
+.DE
+.LP
+It tells PMake the following:
+.Bp
+The shell is located in the file
+.CW /bin/sh .
+It need not tell PMake that the name of the shell is
+.CW sh
+as PMake can figure that out for itself (it's the last component of
+the path).
+.Bp
+The command to stop echoing is
+.CW "set -" .
+.Bp
+The command to start echoing is
+.CW "set -x" .
+.Bp
+When the echo off command is executed, the shell will print
+.CW "+ set - "
+(The `+' comes from using the
+.CW \-x
+flag (rather than the
+.CW \-v
+flag PMake usually uses)). PMake will remove all occurrences of this
+string from the output, so you don't notice extra commands you didn't
+put there.
+.Bp
+The flag the Bourne Shell will take to start echoing in this way is
+the
+.CW \-x
+flag. The Bourne Shell will only take its flag arguments concatenated
+as its first argument, so neither this nor the
+.B errFlag
+specification begins with a \-.
+.Bp
+The flag to use to turn error-checking on from the start is
+.CW \-e .
+.Bp
+The shell can turn error-checking on and off, and the commands to do
+so are
+.CW "set +e"
+and
+.CW "set -e" ,
+respectively.
+.LP
+I should note that this specification is for Bourne Shells that are
+not part of Berkeley
+.UX ,
+as shells from Berkeley don't do error control. You can get a similar
+effect, however, by changing the last three lines to be:
+.DS
+ hasErrCtl=no \e
+ check="echo \e"+ %s\e"\en" \e
+ ignore="sh -c '%s || exit 0\en"
+.DE
+.LP
+This will cause PMake to execute the two commands
+.DS
+echo "+ \fIcmd\fP"
+sh -c '\fIcmd\fP || true'
+.DE
+for each command for which errors are to be ignored. (In case you are
+wondering, the thing for
+.CW ignore
+tells the shell to execute another shell without error checking on and
+always exit 0, since the
+.B ||
+causes the
+.CW "exit 0"
+to be executed only if the first command exited non-zero, and if the
+first command exited zero, the shell will also exit zero, since that's
+the last command it executed).
+.xH 2 Compatibility
+.Ix 0 ref compatibility
+.LP
+There are three (well, 3 \(12) levels of backwards-compatibility built
+into PMake. Most makefiles will need none at all. Some may need a
+little bit of work to operate correctly when run in parallel. Each
+level encompasses the previous levels (e.g.
+.B \-B
+(one shell per command) implies
+.B \-V )
+The three levels are described in the following three sections.
+.xH 3 DEFCON 3 \*- Variable Expansion
+.Ix 0 ref compatibility
+.LP
+As noted before, PMake will not expand a variable unless it knows of a
+value for it. This can cause problems for makefiles that expect to
+leave variables undefined except in special circumstances (e.g. if
+more flags need to be passed to the C compiler or the output from a
+text processor should be sent to a different printer). If the
+variables are enclosed in curly braces
+.CW ${PRINTER} ''), (``
+the shell will let them pass. If they are enclosed in parentheses,
+however, the shell will declare a syntax error and the make will come
+to a grinding halt.
+.LP
+You have two choices: change the makefile to define the variables
+(their values can be overridden on the command line, since that's
+where they would have been set if you used Make, anyway) or always give the
+.B \-V
+flag (this can be done with the
+.CW .MAKEFLAGS
+target, if you want).
+.xH 3 DEFCON 2 \*- The Number of the Beast
+.Ix 0 ref compatibility
+.LP
+Then there are the makefiles that expect certain commands, such as
+changing to a different directory, to not affect other commands in a
+target's creation script. You can solve this is either by going
+back to executing one shell per command (which is what the
+.B \-B
+flag forces PMake to do), which slows the process down a good bit and
+requires you to use semicolons and escaped newlines for shell constructs, or
+by changing the makefile to execute the offending command(s) in a subshell
+(by placing the line inside parentheses), like so:
+.DS
+install :: .MAKE
+ (cd src; $(.PMAKE) install)
+ (cd lib; $(.PMAKE) install)
+ (cd man; $(.PMAKE) install)
+.DE
+.Ix 0 ref operator double-colon
+.Ix 0 ref variable global .PMAKE
+.Ix 0 ref .PMAKE
+.Ix 0 ref .MAKE
+.Ix 0 ref attribute .MAKE
+This will always execute the three makes (even if the
+.B \-n
+flag was given) because of the combination of the ``::'' operator and
+the
+.CW .MAKE
+attribute. Each command will change to the proper directory to perform
+the install, leaving the main shell in the directory in which it started.
+.xH 3 "DEFCON 1 \*- Imitation is the Not the Highest Form of Flattery"
+.Ix 0 ref compatibility
+.LP
+The final category of makefile is the one where every command requires
+input, the dependencies are incompletely specified, or you simply
+cannot create more than one target at a time, as mentioned earlier. In
+addition, you may not have the time or desire to upgrade the makefile
+to run smoothly with PMake. If you are the conservative sort, this is
+the compatibility mode for you. It is entered either by giving PMake
+the
+.B \-M
+flag (for Make), or by executing PMake as
+.CW make .'' ``
+In either case, PMake performs things exactly like Make (while still
+supporting most of the nice new features PMake provides). This
+includes:
+.IP \(bu 2
+No parallel execution.
+.IP \(bu 2
+Targets are made in the exact order specified by the makefile. The
+sources for each target are made in strict left-to-right order, etc.
+.IP \(bu 2
+A single Bourne shell is used to execute each command, thus the
+shell's
+.CW $$
+variable is useless, changing directories doesn't work across command
+lines, etc.
+.IP \(bu 2
+If no special characters exist in a command line, PMake will break the
+command into words itself and execute the command directly, without
+executing a shell first. The characters that cause PMake to execute a
+shell are:
+.CW # ,
+.CW = ,
+.CW | ,
+.CW ^ ,
+.CW ( ,
+.CW ) ,
+.CW { ,
+.CW } ,
+.CW ; ,
+.CW & ,
+.CW < ,
+.CW > ,
+.CW * ,
+.CW ? ,
+.CW [ ,
+.CW ] ,
+.CW : ,
+.CW $ ,
+.CW ` ,
+and
+.CW \e .
+You should notice that these are all the characters that are given
+special meaning by the shell (except
+.CW '
+and
+.CW " ,
+which PMake deals with all by its lonesome).
+.IP \(bu 2
+The use of the null suffix is turned off.
+.Ix 0 ref "null suffix"
+.Ix 0 ref suffix null
+.xH 2 The Way Things Work
+.LP
+When PMake reads the makefile, it parses sources and targets into
+nodes in a graph. The graph is directed only in the sense that PMake
+knows which way is up. Each node contains not only links to all its
+parents and children (the nodes that depend on it and those on which
+it depends, respectively), but also a count of the number of its
+children that have already been processed.
+.LP
+The most important thing to know about how PMake uses this graph is
+that the traversal is breadth-first and occurs in two passes.
+.LP
+After PMake has parsed the makefile, it begins with the nodes the user
+has told it to make (either on the command line, or via a
+.CW .MAIN
+target, or by the target being the first in the file not labeled with
+the
+.CW .NOTMAIN
+attribute) placed in a queue. It continues to take the node off the
+front of the queue, mark it as something that needs to be made, pass
+the node to
+.CW Suff_FindDeps
+(mentioned earlier) to find any implicit sources for the node, and
+place all the node's children that have yet to be marked at the end of
+the queue. If any of the children is a
+.CW .USE
+rule, its attributes are applied to the parent, then its commands are
+appended to the parent's list of commands and its children are linked
+to its parent. The parent's unmade children counter is then decremented
+(since the
+.CW .USE
+node has been processed). You will note that this allows a
+.CW .USE
+node to have children that are
+.CW .USE
+nodes and the rules will be applied in sequence.
+If the node has no children, it is placed at the end of
+another queue to be examined in the second pass. This process
+continues until the first queue is empty.
+.LP
+At this point, all the leaves of the graph are in the examination
+queue. PMake removes the node at the head of the queue and sees if it
+is out-of-date. If it is, it is passed to a function that will execute
+the commands for the node asynchronously. When the commands have
+completed, all the node's parents have their unmade children counter
+decremented and, if the counter is then 0, they are placed on the
+examination queue. Likewise, if the node is up-to-date. Only those
+parents that were marked on the downward pass are processed in this
+way. Thus PMake traverses the graph back up to the nodes the user
+instructed it to create. When the examination queue is empty and no
+shells are running to create a target, PMake is finished.
+.LP
+Once all targets have been processed, PMake executes the commands
+attached to the
+.CW .END
+target, either explicitly or through the use of an ellipsis in a shell
+script. If there were no errors during the entire process but there
+are still some targets unmade (PMake keeps a running count of how many
+targets are left to be made), there is a cycle in the graph. PMake does
+a depth-first traversal of the graph to find all the targets that
+weren't made and prints them out one by one.
+.xH 1 Answers to Exercises
+.IP (3.1)
+This is something of a trick question, for which I apologize. The
+trick comes from the UNIX definition of a suffix, which PMake doesn't
+necessarily share. You will have noticed that all the suffixes used in
+this tutorial (and in UNIX in general) begin with a period
+.CW .ms , (
+.CW .c ,
+etc.). Now, PMake's idea of a suffix is more like English's: it's the
+characters at the end of a word. With this in mind, one possible
+.Ix 0 def suffix
+solution to this problem goes as follows:
+.DS I
+\&.SUFFIXES : ec.exe .exe ec.obj .obj .asm
+ec.objec.exe .obj.exe :
+ link -o $(.TARGET) $(.IMPSRC)
+\&.asmec.obj :
+ asm -o $(.TARGET) -DDO_ERROR_CHECKING $(.IMPSRC)
+\&.asm.obj :
+ asm -o $(.TARGET) $(.IMPSRC)
+.DE
+.IP (3.2)
+The trick to this one lies in the ``:='' variable-assignment operator
+and the ``:S'' variable-expansion modifier.
+.Ix 0 ref variable assignment expanded
+.Ix 0 ref variable expansion modified
+.Ix 0 ref modifier substitute
+.Ix 0 ref :S
+.Ix 0 ref :=
+Basically what you want is to take the pointer variable, so to speak,
+and transform it into an invocation of the variable at which it
+points. You might try something like
+.DS I
+$(PTR:S/^/\e$(/:S/$/))
+.DE
+which places
+.CW $( '' ``
+at the front of the variable name and
+.CW ) '' ``
+at the end, thus transforming
+.CW VAR ,'' ``
+for example, into
+.CW $(VAR) ,'' ``
+which is just what we want. Unfortunately (as you know if you've tried
+it), since, as it says in the hint, PMake does no further substitution
+on the result of a modified expansion, that's \fIall\fP you get. The
+solution is to make use of ``:='' to place that string into yet
+another variable, then invoke the other variable directly:
+.DS I
+*PTR := $(PTR:S/^/\e$(/:S/$/)/)
+.DE
+You can then use
+.CW $(*PTR) '' ``
+to your heart's content.
+.de Gp
+.XP
+\&\fB\\$1:\fP
+..
+.xH 1 Glossary of Jargon
+.Gp "attribute"
+A property given to a target that causes PMake to treat it differently.
+.Gp "command script"
+The lines immediately following a dependency line that specify
+commands to execute to create each of the targets on the dependency
+line. Each line in the command script must begin with a tab.
+.Gp "command-line variable"
+A variable defined in an argument when PMake is first executed.
+Overrides all assignments to the same variable name in the makefile.
+.Gp "conditional"
+A construct much like that used in C that allows a makefile to be
+configured on the fly based on the local environment, or on what is being
+made by that invocation of PMake.
+.Gp "creation script"
+Commands used to create a target. See ``command script.''
+.Gp "dependency"
+The relationship between a source and a target. This comes in three
+flavors, as indicated by the operator between the target and the
+source. `:' gives a straight time-wise dependency (if the target is
+older than the source, the target is out-of-date), while `!' provides
+simply an ordering and always considers the target out-of-date. `::'
+is much like `:', save it creates multiple instances of a target each
+of which depends on its own list of sources.
+.Gp "dynamic source"
+This refers to a source that has a local variable invocation in it. It
+allows a single dependency line to specify a different source for each
+target on the line.
+.Gp "global variable"
+Any variable defined in a makefile. Takes precedence over variables
+defined in the environment, but not over command-line or local variables.
+.Gp "input graph"
+What PMake constructs from a makefile. Consists of nodes made of the
+targets in the makefile, and the links between them (the
+dependencies). The links are directed (from source to target) and
+there may not be any cycles (loops) in the graph.
+.Gp "local variable"
+A variable defined by PMake visible only in a target's shell script.
+There are seven local variables, not all of which are defined for
+every target:
+.CW .TARGET ,
+.CW .ALLSRC ,
+.CW .OODATE ,
+.CW .PREFIX ,
+.CW .IMPSRC ,
+.CW .ARCHIVE ,
+and
+.CW .MEMBER .
+.CW .TARGET ,
+.CW .PREFIX ,
+.CW .ARCHIVE ,
+and
+.CW .MEMBER
+may be used on dependency lines to create ``dynamic sources.''
+.Gp "makefile"
+A file that describes how a system is built. If you don't know what it
+is after reading this tutorial.\|.\|.\|.
+.Gp "modifier"
+A letter, following a colon, used to alter how a variable is expanded.
+It has no effect on the variable itself.
+.Gp "operator"
+What separates a source from a target (on a dependency line) and specifies
+the relationship between the two. There are three:
+.CW : ', `
+.CW :: ', `
+and
+.CW ! '. `
+.Gp "search path"
+A list of directories in which a file should be sought. PMake's view
+of the contents of directories in a search path does not change once
+the makefile has been read. A file is sought on a search path only if
+it is exclusively a source.
+.Gp "shell"
+A program to which commands are passed in order to create targets.
+.Gp "source"
+Anything to the right of an operator on a dependency line. Targets on
+the dependency line are usually created from the sources.
+.Gp "special target"
+A target that causes PMake to do special things when it's encountered.
+.Gp "suffix"
+The tail end of a file name. Usually begins with a period,
+.CW .c
+or
+.CW .ms ,
+e.g.
+.Gp "target"
+A word to the left of the operator on a dependency line. More
+generally, any file that PMake might create. A file may be (and often
+is) both a target and a source (what it is depends on how PMake is
+looking at it at the time \*- sort of like the wave/particle duality
+of light, you know).
+.Gp "transformation rule"
+A special construct in a makefile that specifies how to create a file
+of one type from a file of another, as indicated by their suffixes.
+.Gp "variable expansion"
+The process of substituting the value of a variable for a reference to
+it. Expansion may be altered by means of modifiers.
+.Gp "variable"
+A place in which to store text that may be retrieved later. Also used
+to define the local environment. Conditionals exist that test whether
+a variable is defined or not.
+.bp
+.\" Output table of contents last, with an entry for the index, making
+.\" sure to save and restore the last real page number for the index...
+.nr @n \n(PN+1
+.\" We are not generating an index
+.\" .XS \n(@n
+.\" Index
+.\" .XE
+.nr %% \n%
+.PX
+.nr % \n(%%
diff --git a/external/bsd/bmake/dist/README b/external/bsd/bmake/dist/README
new file mode 100644
index 0000000..fb688a3
--- /dev/null
+++ b/external/bsd/bmake/dist/README
@@ -0,0 +1,47 @@
+ bmake
+
+This directory contains a port of the BSD make tool (from NetBSD)
+I have run it on SunOS,Solaris,HP-UX,AIX,IRIX,FreeBSD and Linux.
+
+Version 3 was re-worked from scratch to better facilitate
+importing newer make(1) versions from NetBSD. The original code base
+was NetBSD-1.0, so version 3 was built by doing a fresh import of the
+NetBSD-1.0 usr.bin/make, adding the autoconf and other portability
+patches to sync it with bmake v2, and then NetBSD's make
+of Feb 20, 2000 was imported and conflicts dealt with.
+NetBSD's make was again imported on June 6 and December 15, 2000.
+
+In 2003 bmake switched to a date based version (first was 20030714)
+which generally represents the date it was last merged with NetBSD's
+make. Since then, NetBSD's make is imported within a week of any
+interesting changes, so that bmake tracks it very closely.
+
+Building:
+
+The prefered way to bootstrap bmake is:
+
+./bmake/boot-strap
+
+there are a number of args - most of which get passed to configure,
+eg.
+
+./bmake/boot-strap --prefix=/opt
+
+see the boot-strap script for details.
+
+To make much use of bmake you will need the bsd.*.mk macros or my
+portable *.mk macros. See
+http://www.crufty.net/ftp/pub/sjg/mk.tar.gz
+which will be links to the latest versions.
+
+On a non-BSD system, you would want to unpack mk[-YYYYmmdd].tar.gz in
+the same directory as bmake (so ./mk and ./bmake exist), and
+./bmake/boot-strap will do the rest.
+
+If you want to do it all by hand then read boot-strap first to get the
+idea.
+
+Even if you have an earlier version of bmake installed, use boot-strap
+to ensure that all goes well.
+
+--sjg
diff --git a/external/bsd/bmake/dist/aclocal.m4 b/external/bsd/bmake/dist/aclocal.m4
new file mode 100644
index 0000000..2adafba
--- /dev/null
+++ b/external/bsd/bmake/dist/aclocal.m4
@@ -0,0 +1,77 @@
+dnl RCSid:
+dnl $Id: aclocal.m4,v 1.5 2003/03/06 21:21:30 sjg Exp $
+dnl
+
+dnl
+dnl AC_CHECK_HEADER_HAS(HEADER, PATTERN, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]))
+
+AC_DEFUN(AC_CHECK_HEADER_HAS,
+[dnl first check if header exists and if so, see if it contains PATTERN
+ac_has_hdr=`echo "ac_cv_header_$1" | sed 'y%./+-%__p_%'`
+ac_has_it=`echo "ac_cv_header_$1"_$2 | sed 'y%./+-%__p_%'`
+if eval "test \"`echo x'$'$ac_has_hdr`\" = x"; then
+ AC_CHECK_HEADER($1)
+fi
+if eval "test \"`echo '$'$ac_has_hdr`\" = yes"; then
+ ac_x=HAVE_`echo "$1" | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ AC_DEFINE_UNQUOTED($ac_x)
+ AC_MSG_CHECKING([if $1 has $2])
+ AC_CACHE_VAL($ac_has_it,
+ [eval $ac_has_it=no
+ AC_EGREP_HEADER($2, $1, eval "$ac_has_it=yes")])
+
+ if eval "test \"`echo '$'$ac_has_it`\" = yes"; then
+ AC_MSG_RESULT(yes)
+ ac_x=HAVE_`echo "$1"_$2 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ AC_DEFINE_UNQUOTED($ac_x)
+ ifelse([$3], , :, [$3])
+ else
+ AC_MSG_RESULT(no)
+ ifelse([$4], , , [$4
+])dnl
+ fi
+fi
+])
+
+dnl AC_EGREP(PATTERN, FILE, ACTION-IF-FOUND [,
+dnl ACTION-IF-NOT-FOUND])
+AC_DEFUN(AC_EGREP,
+[
+dnl Prevent m4 from eating character classes:
+changequote(, )dnl
+if egrep "$1" $2 >/dev/null 2>&1; then
+changequote([, ])dnl
+ ifelse([$3], , :, [$3])
+ifelse([$4], , , [else
+ $4
+])dnl
+fi
+])
+
+dnl
+dnl Test for __attribute__
+dnl
+
+AC_DEFUN(AC_C___ATTRIBUTE__, [
+AC_MSG_CHECKING(for __attribute__)
+AC_CACHE_VAL(ac_cv___attribute__, [
+AC_TRY_COMPILE([
+#include <stdlib.h>
+],
+[
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+ exit(1);
+}
+],
+ac_cv___attribute__=yes,
+ac_cv___attribute__=no)])
+if test "$ac_cv___attribute__" = "yes"; then
+ AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
+fi
+AC_MSG_RESULT($ac_cv___attribute__)
+])
+
diff --git a/external/bsd/bmake/dist/arch.c b/external/bsd/bmake/dist/arch.c
new file mode 100644
index 0000000..943f41e
--- /dev/null
+++ b/external/bsd/bmake/dist/arch.c
@@ -0,0 +1,1403 @@
+/* $NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94";
+#else
+__RCSID("$NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * arch.c --
+ * Functions to manipulate libraries, archives and their members.
+ *
+ * Once again, cacheing/hashing comes into play in the manipulation
+ * of archives. The first time an archive is referenced, all of its members'
+ * headers are read and hashed and the archive closed again. All hashed
+ * archives are kept on a list which is searched each time an archive member
+ * is referenced.
+ *
+ * The interface to this module is:
+ * Arch_ParseArchive Given an archive specification, return a list
+ * of GNode's, one for each member in the spec.
+ * FAILURE is returned if the specification is
+ * invalid for some reason.
+ *
+ * Arch_Touch Alter the modification time of the archive
+ * member described by the given node to be
+ * the current time.
+ *
+ * Arch_TouchLib Update the modification time of the library
+ * described by the given node. This is special
+ * because it also updates the modification time
+ * of the library's table of contents.
+ *
+ * Arch_MTime Find the modification time of a member of
+ * an archive *in the archive*. The time is also
+ * placed in the member's GNode. Returns the
+ * modification time.
+ *
+ * Arch_MemTime Find the modification time of a member of
+ * an archive. Called when the member doesn't
+ * already exist. Looks in the archive for the
+ * modification time. Returns the modification
+ * time.
+ *
+ * Arch_FindLib Search for a library along a path. The
+ * library name in the GNode should be in
+ * -l<name> format.
+ *
+ * Arch_LibOODate Special function to decide if a library node
+ * is out-of-date.
+ *
+ * Arch_Init Initialize this module.
+ *
+ * Arch_End Cleanup this module.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <ctype.h>
+#ifdef HAVE_AR_H
+#include <ar.h>
+#else
+struct ar_hdr {
+ char ar_name[16]; /* name */
+ char ar_date[12]; /* modification time */
+ char ar_uid[6]; /* user id */
+ char ar_gid[6]; /* group id */
+ char ar_mode[8]; /* octal file permissions */
+ char ar_size[10]; /* size in bytes */
+#ifndef ARFMAG
+#define ARFMAG "`\n"
+#endif
+ char ar_fmag[2]; /* consistency check */
+};
+#endif
+#if defined(HAVE_RANLIB_H) && !(defined(__ELF__) || defined(NO_RANLIB))
+#include <ranlib.h>
+#endif
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+
+#ifdef TARGET_MACHINE
+#undef MAKE_MACHINE
+#define MAKE_MACHINE TARGET_MACHINE
+#endif
+#ifdef TARGET_MACHINE_ARCH
+#undef MAKE_MACHINE_ARCH
+#define MAKE_MACHINE_ARCH TARGET_MACHINE_ARCH
+#endif
+
+static Lst archives; /* Lst of archives we've already examined */
+
+typedef struct Arch {
+ char *name; /* Name of archive */
+ Hash_Table members; /* All the members of the archive described
+ * by <name, struct ar_hdr *> key/value pairs */
+ char *fnametab; /* Extended name table strings */
+ size_t fnamesize; /* Size of the string table */
+} Arch;
+
+static int ArchFindArchive(const void *, const void *);
+#ifdef CLEANUP
+static void ArchFree(void *);
+#endif
+static struct ar_hdr *ArchStatMember(char *, char *, Boolean);
+static FILE *ArchFindMember(char *, char *, struct ar_hdr *, const char *);
+#if defined(__svr4__) || defined(__SVR4) || defined(__ELF__)
+#define SVR4ARCHIVES
+static int ArchSVR4Entry(Arch *, char *, size_t, FILE *);
+#endif
+
+
+#if defined(_AIX)
+# define AR_NAME _ar_name.ar_name
+# define AR_FMAG _ar_name.ar_fmag
+# define SARMAG SAIAMAG
+# define ARMAG AIAMAG
+# define ARFMAG AIAFMAG
+#endif
+#ifndef AR_NAME
+# define AR_NAME ar_name
+#endif
+#ifndef AR_DATE
+# define AR_DATE ar_date
+#endif
+#ifndef AR_SIZE
+# define AR_SIZE ar_size
+#endif
+#ifndef AR_FMAG
+# define AR_FMAG ar_fmag
+#endif
+#ifndef ARMAG
+# define ARMAG "!<arch>\n"
+#endif
+#ifndef SARMAG
+# define SARMAG 8
+#endif
+
+#define AR_MAX_NAME_LEN (sizeof(arh.AR_NAME)-1)
+
+#ifdef CLEANUP
+/*-
+ *-----------------------------------------------------------------------
+ * ArchFree --
+ * Free memory used by an archive
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+ArchFree(void *ap)
+{
+ Arch *a = (Arch *)ap;
+ Hash_Search search;
+ Hash_Entry *entry;
+
+ /* Free memory from hash entries */
+ for (entry = Hash_EnumFirst(&a->members, &search);
+ entry != NULL;
+ entry = Hash_EnumNext(&search))
+ free(Hash_GetValue(entry));
+
+ free(a->name);
+ if (a->fnametab)
+ free(a->fnametab);
+ Hash_DeleteTable(&a->members);
+ free(a);
+}
+#endif
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Arch_ParseArchive --
+ * Parse the archive specification in the given line and find/create
+ * the nodes for the specified archive members, placing their nodes
+ * on the given list.
+ *
+ * Input:
+ * linePtr Pointer to start of specification
+ * nodeLst Lst on which to place the nodes
+ * ctxt Context in which to expand variables
+ *
+ * Results:
+ * SUCCESS if it was a valid specification. The linePtr is updated
+ * to point to the first non-space after the archive spec. The
+ * nodes for the members are placed on the given list.
+ *
+ * Side Effects:
+ * Some nodes may be created. The given list is extended.
+ *
+ *-----------------------------------------------------------------------
+ */
+ReturnStatus
+Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
+{
+ char *cp; /* Pointer into line */
+ GNode *gn; /* New node */
+ char *libName; /* Library-part of specification */
+ char *memName; /* Member-part of specification */
+ char *nameBuf; /* temporary place for node name */
+ char saveChar; /* Ending delimiter of member-name */
+ Boolean subLibName; /* TRUE if libName should have/had
+ * variable substitution performed on it */
+
+ libName = *linePtr;
+
+ subLibName = FALSE;
+
+ for (cp = libName; *cp != '(' && *cp != '\0'; cp++) {
+ if (*cp == '$') {
+ /*
+ * Variable spec, so call the Var module to parse the puppy
+ * so we can safely advance beyond it...
+ */
+ int length;
+ void *freeIt;
+ char *result;
+
+ result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt);
+ if (freeIt)
+ free(freeIt);
+ if (result == var_Error) {
+ return(FAILURE);
+ } else {
+ subLibName = TRUE;
+ }
+
+ cp += length-1;
+ }
+ }
+
+ *cp++ = '\0';
+ if (subLibName) {
+ libName = Var_Subst(NULL, libName, ctxt, TRUE);
+ }
+
+
+ for (;;) {
+ /*
+ * First skip to the start of the member's name, mark that
+ * place and skip to the end of it (either white-space or
+ * a close paren).
+ */
+ Boolean doSubst = FALSE; /* TRUE if need to substitute in memName */
+
+ while (*cp != '\0' && *cp != ')' && isspace ((unsigned char)*cp)) {
+ cp++;
+ }
+ memName = cp;
+ while (*cp != '\0' && *cp != ')' && !isspace ((unsigned char)*cp)) {
+ if (*cp == '$') {
+ /*
+ * Variable spec, so call the Var module to parse the puppy
+ * so we can safely advance beyond it...
+ */
+ int length;
+ void *freeIt;
+ char *result;
+
+ result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt);
+ if (freeIt)
+ free(freeIt);
+ if (result == var_Error) {
+ return(FAILURE);
+ } else {
+ doSubst = TRUE;
+ }
+
+ cp += length;
+ } else {
+ cp++;
+ }
+ }
+
+ /*
+ * If the specification ends without a closing parenthesis,
+ * chances are there's something wrong (like a missing backslash),
+ * so it's better to return failure than allow such things to happen
+ */
+ if (*cp == '\0') {
+ printf("No closing parenthesis in archive specification\n");
+ return (FAILURE);
+ }
+
+ /*
+ * If we didn't move anywhere, we must be done
+ */
+ if (cp == memName) {
+ break;
+ }
+
+ saveChar = *cp;
+ *cp = '\0';
+
+ /*
+ * XXX: This should be taken care of intelligently by
+ * SuffExpandChildren, both for the archive and the member portions.
+ */
+ /*
+ * If member contains variables, try and substitute for them.
+ * This will slow down archive specs with dynamic sources, of course,
+ * since we'll be (non-)substituting them three times, but them's
+ * the breaks -- we need to do this since SuffExpandChildren calls
+ * us, otherwise we could assume the thing would be taken care of
+ * later.
+ */
+ if (doSubst) {
+ char *buf;
+ char *sacrifice;
+ char *oldMemName = memName;
+ size_t sz;
+
+ memName = Var_Subst(NULL, memName, ctxt, TRUE);
+
+ /*
+ * Now form an archive spec and recurse to deal with nested
+ * variables and multi-word variable values.... The results
+ * are just placed at the end of the nodeLst we're returning.
+ */
+ sz = strlen(memName)+strlen(libName)+3;
+ buf = sacrifice = bmake_malloc(sz);
+
+ snprintf(buf, sz, "%s(%s)", libName, memName);
+
+ if (strchr(memName, '$') && strcmp(memName, oldMemName) == 0) {
+ /*
+ * Must contain dynamic sources, so we can't deal with it now.
+ * Just create an ARCHV node for the thing and let
+ * SuffExpandChildren handle it...
+ */
+ gn = Targ_FindNode(buf, TARG_CREATE);
+
+ if (gn == NULL) {
+ free(buf);
+ return(FAILURE);
+ } else {
+ gn->type |= OP_ARCHV;
+ (void)Lst_AtEnd(nodeLst, gn);
+ }
+ } else if (Arch_ParseArchive(&sacrifice, nodeLst, ctxt)!=SUCCESS) {
+ /*
+ * Error in nested call -- free buffer and return FAILURE
+ * ourselves.
+ */
+ free(buf);
+ return(FAILURE);
+ }
+ /*
+ * Free buffer and continue with our work.
+ */
+ free(buf);
+ } else if (Dir_HasWildcards(memName)) {
+ Lst members = Lst_Init(FALSE);
+ char *member;
+ size_t sz = MAXPATHLEN, nsz;
+ nameBuf = bmake_malloc(sz);
+
+ Dir_Expand(memName, dirSearchPath, members);
+ while (!Lst_IsEmpty(members)) {
+ member = (char *)Lst_DeQueue(members);
+ nsz = strlen(libName) + strlen(member) + 3;
+ if (sz > nsz)
+ nameBuf = bmake_realloc(nameBuf, sz = nsz * 2);
+
+ snprintf(nameBuf, sz, "%s(%s)", libName, member);
+ free(member);
+ gn = Targ_FindNode(nameBuf, TARG_CREATE);
+ if (gn == NULL) {
+ free(nameBuf);
+ return (FAILURE);
+ } else {
+ /*
+ * We've found the node, but have to make sure the rest of
+ * the world knows it's an archive member, without having
+ * to constantly check for parentheses, so we type the
+ * thing with the OP_ARCHV bit before we place it on the
+ * end of the provided list.
+ */
+ gn->type |= OP_ARCHV;
+ (void)Lst_AtEnd(nodeLst, gn);
+ }
+ }
+ Lst_Destroy(members, NULL);
+ free(nameBuf);
+ } else {
+ size_t sz = strlen(libName) + strlen(memName) + 3;
+ nameBuf = bmake_malloc(sz);
+ snprintf(nameBuf, sz, "%s(%s)", libName, memName);
+ gn = Targ_FindNode(nameBuf, TARG_CREATE);
+ free(nameBuf);
+ if (gn == NULL) {
+ return (FAILURE);
+ } else {
+ /*
+ * We've found the node, but have to make sure the rest of the
+ * world knows it's an archive member, without having to
+ * constantly check for parentheses, so we type the thing with
+ * the OP_ARCHV bit before we place it on the end of the
+ * provided list.
+ */
+ gn->type |= OP_ARCHV;
+ (void)Lst_AtEnd(nodeLst, gn);
+ }
+ }
+ if (doSubst) {
+ free(memName);
+ }
+
+ *cp = saveChar;
+ }
+
+ /*
+ * If substituted libName, free it now, since we need it no longer.
+ */
+ if (subLibName) {
+ free(libName);
+ }
+
+ /*
+ * We promised the pointer would be set up at the next non-space, so
+ * we must advance cp there before setting *linePtr... (note that on
+ * entrance to the loop, cp is guaranteed to point at a ')')
+ */
+ do {
+ cp++;
+ } while (*cp != '\0' && isspace ((unsigned char)*cp));
+
+ *linePtr = cp;
+ return (SUCCESS);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * ArchFindArchive --
+ * See if the given archive is the one we are looking for. Called
+ * From ArchStatMember and ArchFindMember via Lst_Find.
+ *
+ * Input:
+ * ar Current list element
+ * archName Name we want
+ *
+ * Results:
+ * 0 if it is, non-zero if it isn't.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+ArchFindArchive(const void *ar, const void *archName)
+{
+ return (strcmp(archName, ((const Arch *)ar)->name));
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * ArchStatMember --
+ * Locate a member of an archive, given the path of the archive and
+ * the path of the desired member.
+ *
+ * Input:
+ * archive Path to the archive
+ * member Name of member. If it is a path, only the last
+ * component is used.
+ * hash TRUE if archive should be hashed if not already so.
+ *
+ * Results:
+ * A pointer to the current struct ar_hdr structure for the member. Note
+ * That no position is returned, so this is not useful for touching
+ * archive members. This is mostly because we have no assurances that
+ * The archive will remain constant after we read all the headers, so
+ * there's not much point in remembering the position...
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static struct ar_hdr *
+ArchStatMember(char *archive, char *member, Boolean hash)
+{
+ FILE * arch; /* Stream to archive */
+ int size; /* Size of archive member */
+ char *cp; /* Useful character pointer */
+ char magic[SARMAG];
+ LstNode ln; /* Lst member containing archive descriptor */
+ Arch *ar; /* Archive descriptor */
+ Hash_Entry *he; /* Entry containing member's description */
+ struct ar_hdr arh; /* archive-member header for reading archive */
+ char memName[MAXPATHLEN+1];
+ /* Current member name while hashing. */
+
+ /*
+ * Because of space constraints and similar things, files are archived
+ * using their final path components, not the entire thing, so we need
+ * to point 'member' to the final component, if there is one, to make
+ * the comparisons easier...
+ */
+ cp = strrchr(member, '/');
+ if (cp != NULL) {
+ member = cp + 1;
+ }
+
+ ln = Lst_Find(archives, archive, ArchFindArchive);
+ if (ln != NULL) {
+ ar = (Arch *)Lst_Datum(ln);
+
+ he = Hash_FindEntry(&ar->members, member);
+
+ if (he != NULL) {
+ return ((struct ar_hdr *)Hash_GetValue(he));
+ } else {
+ /* Try truncated name */
+ char copy[AR_MAX_NAME_LEN+1];
+ size_t len = strlen(member);
+
+ if (len > AR_MAX_NAME_LEN) {
+ len = AR_MAX_NAME_LEN;
+ strncpy(copy, member, AR_MAX_NAME_LEN);
+ copy[AR_MAX_NAME_LEN] = '\0';
+ }
+ if ((he = Hash_FindEntry(&ar->members, copy)) != NULL)
+ return ((struct ar_hdr *)Hash_GetValue(he));
+ return NULL;
+ }
+ }
+
+ if (!hash) {
+ /*
+ * Caller doesn't want the thing hashed, just use ArchFindMember
+ * to read the header for the member out and close down the stream
+ * again. Since the archive is not to be hashed, we assume there's
+ * no need to allocate extra room for the header we're returning,
+ * so just declare it static.
+ */
+ static struct ar_hdr sarh;
+
+ arch = ArchFindMember(archive, member, &sarh, "r");
+
+ if (arch == NULL) {
+ return NULL;
+ } else {
+ fclose(arch);
+ return (&sarh);
+ }
+ }
+
+ /*
+ * We don't have this archive on the list yet, so we want to find out
+ * everything that's in it and cache it so we can get at it quickly.
+ */
+ arch = fopen(archive, "r");
+ if (arch == NULL) {
+ return NULL;
+ }
+
+ /*
+ * We use the ARMAG string to make sure this is an archive we
+ * can handle...
+ */
+ if ((fread(magic, SARMAG, 1, arch) != 1) ||
+ (strncmp(magic, ARMAG, SARMAG) != 0)) {
+ fclose(arch);
+ return NULL;
+ }
+
+ ar = bmake_malloc(sizeof(Arch));
+ ar->name = bmake_strdup(archive);
+ ar->fnametab = NULL;
+ ar->fnamesize = 0;
+ Hash_InitTable(&ar->members, -1);
+ memName[AR_MAX_NAME_LEN] = '\0';
+
+ while (fread((char *)&arh, sizeof(struct ar_hdr), 1, arch) == 1) {
+ if (strncmp( arh.AR_FMAG, ARFMAG, sizeof(arh.AR_FMAG)) != 0) {
+ /*
+ * The header is bogus, so the archive is bad
+ * and there's no way we can recover...
+ */
+ goto badarch;
+ } else {
+ /*
+ * We need to advance the stream's pointer to the start of the
+ * next header. Files are padded with newlines to an even-byte
+ * boundary, so we need to extract the size of the file from the
+ * 'size' field of the header and round it up during the seek.
+ */
+ arh.AR_SIZE[sizeof(arh.AR_SIZE)-1] = '\0';
+ size = (int)strtol(arh.AR_SIZE, NULL, 10);
+
+ (void)strncpy(memName, arh.AR_NAME, sizeof(arh.AR_NAME));
+ for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) {
+ continue;
+ }
+ cp[1] = '\0';
+
+#ifdef SVR4ARCHIVES
+ /*
+ * svr4 names are slash terminated. Also svr4 extended AR format.
+ */
+ if (memName[0] == '/') {
+ /*
+ * svr4 magic mode; handle it
+ */
+ switch (ArchSVR4Entry(ar, memName, size, arch)) {
+ case -1: /* Invalid data */
+ goto badarch;
+ case 0: /* List of files entry */
+ continue;
+ default: /* Got the entry */
+ break;
+ }
+ }
+ else {
+ if (cp[0] == '/')
+ cp[0] = '\0';
+ }
+#endif
+
+#ifdef AR_EFMT1
+ /*
+ * BSD 4.4 extended AR format: #1/<namelen>, with name as the
+ * first <namelen> bytes of the file
+ */
+ if (strncmp(memName, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 &&
+ isdigit((unsigned char)memName[sizeof(AR_EFMT1) - 1])) {
+
+ unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);
+
+ if (elen > MAXPATHLEN)
+ goto badarch;
+ if (fread(memName, elen, 1, arch) != 1)
+ goto badarch;
+ memName[elen] = '\0';
+ fseek(arch, -elen, SEEK_CUR);
+ if (DEBUG(ARCH) || DEBUG(MAKE)) {
+ fprintf(debug_file, "ArchStat: Extended format entry for %s\n", memName);
+ }
+ }
+#endif
+
+ he = Hash_CreateEntry(&ar->members, memName, NULL);
+ Hash_SetValue(he, bmake_malloc(sizeof(struct ar_hdr)));
+ memcpy(Hash_GetValue(he), &arh, sizeof(struct ar_hdr));
+ }
+ fseek(arch, (size + 1) & ~1, SEEK_CUR);
+ }
+
+ fclose(arch);
+
+ (void)Lst_AtEnd(archives, ar);
+
+ /*
+ * Now that the archive has been read and cached, we can look into
+ * the hash table to find the desired member's header.
+ */
+ he = Hash_FindEntry(&ar->members, member);
+
+ if (he != NULL) {
+ return ((struct ar_hdr *)Hash_GetValue(he));
+ } else {
+ return NULL;
+ }
+
+badarch:
+ fclose(arch);
+ Hash_DeleteTable(&ar->members);
+ if (ar->fnametab)
+ free(ar->fnametab);
+ free(ar);
+ return NULL;
+}
+
+#ifdef SVR4ARCHIVES
+/*-
+ *-----------------------------------------------------------------------
+ * ArchSVR4Entry --
+ * Parse an SVR4 style entry that begins with a slash.
+ * If it is "//", then load the table of filenames
+ * If it is "/<offset>", then try to substitute the long file name
+ * from offset of a table previously read.
+ *
+ * Results:
+ * -1: Bad data in archive
+ * 0: A table was loaded from the file
+ * 1: Name was successfully substituted from table
+ * 2: Name was not successfully substituted from table
+ *
+ * Side Effects:
+ * If a table is read, the file pointer is moved to the next archive
+ * member
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
+{
+#define ARLONGNAMES1 "//"
+#define ARLONGNAMES2 "/ARFILENAMES"
+ size_t entry;
+ char *ptr, *eptr;
+
+ if (strncmp(name, ARLONGNAMES1, sizeof(ARLONGNAMES1) - 1) == 0 ||
+ strncmp(name, ARLONGNAMES2, sizeof(ARLONGNAMES2) - 1) == 0) {
+
+ if (ar->fnametab != NULL) {
+ if (DEBUG(ARCH)) {
+ fprintf(debug_file, "Attempted to redefine an SVR4 name table\n");
+ }
+ return -1;
+ }
+
+ /*
+ * This is a table of archive names, so we build one for
+ * ourselves
+ */
+ ar->fnametab = bmake_malloc(size);
+ ar->fnamesize = size;
+
+ if (fread(ar->fnametab, size, 1, arch) != 1) {
+ if (DEBUG(ARCH)) {
+ fprintf(debug_file, "Reading an SVR4 name table failed\n");
+ }
+ return -1;
+ }
+ eptr = ar->fnametab + size;
+ for (entry = 0, ptr = ar->fnametab; ptr < eptr; ptr++)
+ switch (*ptr) {
+ case '/':
+ entry++;
+ *ptr = '\0';
+ break;
+
+ case '\n':
+ break;
+
+ default:
+ break;
+ }
+ if (DEBUG(ARCH)) {
+ fprintf(debug_file, "Found svr4 archive name table with %lu entries\n",
+ (u_long)entry);
+ }
+ return 0;
+ }
+
+ if (name[1] == ' ' || name[1] == '\0')
+ return 2;
+
+ entry = (size_t)strtol(&name[1], &eptr, 0);
+ if ((*eptr != ' ' && *eptr != '\0') || eptr == &name[1]) {
+ if (DEBUG(ARCH)) {
+ fprintf(debug_file, "Could not parse SVR4 name %s\n", name);
+ }
+ return 2;
+ }
+ if (entry >= ar->fnamesize) {
+ if (DEBUG(ARCH)) {
+ fprintf(debug_file, "SVR4 entry offset %s is greater than %lu\n",
+ name, (u_long)ar->fnamesize);
+ }
+ return 2;
+ }
+
+ if (DEBUG(ARCH)) {
+ fprintf(debug_file, "Replaced %s with %s\n", name, &ar->fnametab[entry]);
+ }
+
+ (void)strncpy(name, &ar->fnametab[entry], MAXPATHLEN);
+ name[MAXPATHLEN] = '\0';
+ return 1;
+}
+#endif
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * ArchFindMember --
+ * Locate a member of an archive, given the path of the archive and
+ * the path of the desired member. If the archive is to be modified,
+ * the mode should be "r+", if not, it should be "r".
+ *
+ * Input:
+ * archive Path to the archive
+ * member Name of member. If it is a path, only the last
+ * component is used.
+ * arhPtr Pointer to header structure to be filled in
+ * mode The mode for opening the stream
+ *
+ * Results:
+ * An FILE *, opened for reading and writing, positioned at the
+ * start of the member's struct ar_hdr, or NULL if the member was
+ * nonexistent. The current struct ar_hdr for member.
+ *
+ * Side Effects:
+ * The passed struct ar_hdr structure is filled in.
+ *
+ *-----------------------------------------------------------------------
+ */
+static FILE *
+ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr,
+ const char *mode)
+{
+ FILE * arch; /* Stream to archive */
+ int size; /* Size of archive member */
+ char *cp; /* Useful character pointer */
+ char magic[SARMAG];
+ size_t len, tlen;
+
+ arch = fopen(archive, mode);
+ if (arch == NULL) {
+ return NULL;
+ }
+
+ /*
+ * We use the ARMAG string to make sure this is an archive we
+ * can handle...
+ */
+ if ((fread(magic, SARMAG, 1, arch) != 1) ||
+ (strncmp(magic, ARMAG, SARMAG) != 0)) {
+ fclose(arch);
+ return NULL;
+ }
+
+ /*
+ * Because of space constraints and similar things, files are archived
+ * using their final path components, not the entire thing, so we need
+ * to point 'member' to the final component, if there is one, to make
+ * the comparisons easier...
+ */
+ cp = strrchr(member, '/');
+ if (cp != NULL) {
+ member = cp + 1;
+ }
+ len = tlen = strlen(member);
+ if (len > sizeof(arhPtr->AR_NAME)) {
+ tlen = sizeof(arhPtr->AR_NAME);
+ }
+
+ while (fread((char *)arhPtr, sizeof(struct ar_hdr), 1, arch) == 1) {
+ if (strncmp(arhPtr->AR_FMAG, ARFMAG, sizeof(arhPtr->AR_FMAG) ) != 0) {
+ /*
+ * The header is bogus, so the archive is bad
+ * and there's no way we can recover...
+ */
+ fclose(arch);
+ return NULL;
+ } else if (strncmp(member, arhPtr->AR_NAME, tlen) == 0) {
+ /*
+ * If the member's name doesn't take up the entire 'name' field,
+ * we have to be careful of matching prefixes. Names are space-
+ * padded to the right, so if the character in 'name' at the end
+ * of the matched string is anything but a space, this isn't the
+ * member we sought.
+ */
+ if (tlen != sizeof(arhPtr->AR_NAME) && arhPtr->AR_NAME[tlen] != ' '){
+ goto skip;
+ } else {
+ /*
+ * To make life easier, we reposition the file at the start
+ * of the header we just read before we return the stream.
+ * In a more general situation, it might be better to leave
+ * the file at the actual member, rather than its header, but
+ * not here...
+ */
+ fseek(arch, -sizeof(struct ar_hdr), SEEK_CUR);
+ return (arch);
+ }
+ } else
+#ifdef AR_EFMT1
+ /*
+ * BSD 4.4 extended AR format: #1/<namelen>, with name as the
+ * first <namelen> bytes of the file
+ */
+ if (strncmp(arhPtr->AR_NAME, AR_EFMT1,
+ sizeof(AR_EFMT1) - 1) == 0 &&
+ isdigit((unsigned char)arhPtr->AR_NAME[sizeof(AR_EFMT1) - 1])) {
+
+ unsigned int elen = atoi(&arhPtr->AR_NAME[sizeof(AR_EFMT1)-1]);
+ char ename[MAXPATHLEN + 1];
+
+ if (elen > MAXPATHLEN) {
+ fclose(arch);
+ return NULL;
+ }
+ if (fread(ename, elen, 1, arch) != 1) {
+ fclose(arch);
+ return NULL;
+ }
+ ename[elen] = '\0';
+ if (DEBUG(ARCH) || DEBUG(MAKE)) {
+ fprintf(debug_file, "ArchFind: Extended format entry for %s\n", ename);
+ }
+ if (strncmp(ename, member, len) == 0) {
+ /* Found as extended name */
+ fseek(arch, -sizeof(struct ar_hdr) - elen, SEEK_CUR);
+ return (arch);
+ }
+ fseek(arch, -elen, SEEK_CUR);
+ goto skip;
+ } else
+#endif
+ {
+skip:
+ /*
+ * This isn't the member we're after, so we need to advance the
+ * stream's pointer to the start of the next header. Files are
+ * padded with newlines to an even-byte boundary, so we need to
+ * extract the size of the file from the 'size' field of the
+ * header and round it up during the seek.
+ */
+ arhPtr->ar_size[sizeof(arhPtr->AR_SIZE)-1] = '\0';
+ size = (int)strtol(arhPtr->AR_SIZE, NULL, 10);
+ fseek(arch, (size + 1) & ~1, SEEK_CUR);
+ }
+ }
+
+ /*
+ * We've looked everywhere, but the member is not to be found. Close the
+ * archive and return NULL -- an error.
+ */
+ fclose(arch);
+ return NULL;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Arch_Touch --
+ * Touch a member of an archive.
+ *
+ * Input:
+ * gn Node of member to touch
+ *
+ * Results:
+ * The 'time' field of the member's header is updated.
+ *
+ * Side Effects:
+ * The modification time of the entire archive is also changed.
+ * For a library, this could necessitate the re-ranlib'ing of the
+ * whole thing.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Arch_Touch(GNode *gn)
+{
+ FILE * arch; /* Stream open to archive, positioned properly */
+ struct ar_hdr arh; /* Current header describing member */
+ char *p1, *p2;
+
+ arch = ArchFindMember(Var_Value(ARCHIVE, gn, &p1),
+ Var_Value(MEMBER, gn, &p2),
+ &arh, "r+");
+ if (p1)
+ free(p1);
+ if (p2)
+ free(p2);
+ snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now);
+
+ if (arch != NULL) {
+ (void)fwrite((char *)&arh, sizeof(struct ar_hdr), 1, arch);
+ fclose(arch);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Arch_TouchLib --
+ * Given a node which represents a library, touch the thing, making
+ * sure that the table of contents also is touched.
+ *
+ * Input:
+ * gn The node of the library to touch
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Both the modification time of the library and of the RANLIBMAG
+ * member are set to 'now'.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+#if !defined(RANLIBMAG)
+Arch_TouchLib(GNode *gn MAKE_ATTR_UNUSED)
+#else
+Arch_TouchLib(GNode *gn)
+#endif
+{
+#ifdef RANLIBMAG
+ FILE * arch; /* Stream open to archive */
+ struct ar_hdr arh; /* Header describing table of contents */
+ struct utimbuf times; /* Times for utime() call */
+
+ arch = ArchFindMember(gn->path, UNCONST(RANLIBMAG), &arh, "r+");
+ snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now);
+
+ if (arch != NULL) {
+ (void)fwrite((char *)&arh, sizeof(struct ar_hdr), 1, arch);
+ fclose(arch);
+
+ times.actime = times.modtime = now;
+ utime(gn->path, &times);
+ }
+#endif
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Arch_MTime --
+ * Return the modification time of a member of an archive.
+ *
+ * Input:
+ * gn Node describing archive member
+ *
+ * Results:
+ * The modification time(seconds).
+ *
+ * Side Effects:
+ * The mtime field of the given node is filled in with the value
+ * returned by the function.
+ *
+ *-----------------------------------------------------------------------
+ */
+time_t
+Arch_MTime(GNode *gn)
+{
+ struct ar_hdr *arhPtr; /* Header of desired member */
+ time_t modTime; /* Modification time as an integer */
+ char *p1, *p2;
+
+ arhPtr = ArchStatMember(Var_Value(ARCHIVE, gn, &p1),
+ Var_Value(MEMBER, gn, &p2),
+ TRUE);
+ if (p1)
+ free(p1);
+ if (p2)
+ free(p2);
+
+ if (arhPtr != NULL) {
+ modTime = (time_t)strtol(arhPtr->AR_DATE, NULL, 10);
+ } else {
+ modTime = 0;
+ }
+
+ gn->mtime = modTime;
+ return (modTime);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Arch_MemMTime --
+ * Given a non-existent archive member's node, get its modification
+ * time from its archived form, if it exists.
+ *
+ * Results:
+ * The modification time.
+ *
+ * Side Effects:
+ * The mtime field is filled in.
+ *
+ *-----------------------------------------------------------------------
+ */
+time_t
+Arch_MemMTime(GNode *gn)
+{
+ LstNode ln;
+ GNode *pgn;
+ char *nameStart,
+ *nameEnd;
+
+ if (Lst_Open(gn->parents) != SUCCESS) {
+ gn->mtime = 0;
+ return (0);
+ }
+ while ((ln = Lst_Next(gn->parents)) != NULL) {
+ pgn = (GNode *)Lst_Datum(ln);
+
+ if (pgn->type & OP_ARCHV) {
+ /*
+ * If the parent is an archive specification and is being made
+ * and its member's name matches the name of the node we were
+ * given, record the modification time of the parent in the
+ * child. We keep searching its parents in case some other
+ * parent requires this child to exist...
+ */
+ nameStart = strchr(pgn->name, '(') + 1;
+ nameEnd = strchr(nameStart, ')');
+
+ if ((pgn->flags & REMAKE) &&
+ strncmp(nameStart, gn->name, nameEnd - nameStart) == 0) {
+ gn->mtime = Arch_MTime(pgn);
+ }
+ } else if (pgn->flags & REMAKE) {
+ /*
+ * Something which isn't a library depends on the existence of
+ * this target, so it needs to exist.
+ */
+ gn->mtime = 0;
+ break;
+ }
+ }
+
+ Lst_Close(gn->parents);
+
+ return (gn->mtime);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Arch_FindLib --
+ * Search for a library along the given search path.
+ *
+ * Input:
+ * gn Node of library to find
+ * path Search path
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The node's 'path' field is set to the found path (including the
+ * actual file name, not -l...). If the system can handle the -L
+ * flag when linking (or we cannot find the library), we assume that
+ * the user has placed the .LIBRARIES variable in the final linking
+ * command (or the linker will know where to find it) and set the
+ * TARGET variable for this node to be the node's name. Otherwise,
+ * we set the TARGET variable to be the full path of the library,
+ * as returned by Dir_FindFile.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Arch_FindLib(GNode *gn, Lst path)
+{
+ char *libName; /* file name for archive */
+ size_t sz = strlen(gn->name) + 6 - 2;
+
+ libName = bmake_malloc(sz);
+ snprintf(libName, sz, "lib%s.a", &gn->name[2]);
+
+ gn->path = Dir_FindFile(libName, path);
+
+ free(libName);
+
+#ifdef LIBRARIES
+ Var_Set(TARGET, gn->name, gn, 0);
+#else
+ Var_Set(TARGET, gn->path == NULL ? gn->name : gn->path, gn, 0);
+#endif /* LIBRARIES */
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Arch_LibOODate --
+ * Decide if a node with the OP_LIB attribute is out-of-date. Called
+ * from Make_OODate to make its life easier.
+ *
+ * There are several ways for a library to be out-of-date that are
+ * not available to ordinary files. In addition, there are ways
+ * that are open to regular files that are not available to
+ * libraries. A library that is only used as a source is never
+ * considered out-of-date by itself. This does not preclude the
+ * library's modification time from making its parent be out-of-date.
+ * A library will be considered out-of-date for any of these reasons,
+ * given that it is a target on a dependency line somewhere:
+ * Its modification time is less than that of one of its
+ * sources (gn->mtime < gn->cmgn->mtime).
+ * Its modification time is greater than the time at which the
+ * make began (i.e. it's been modified in the course
+ * of the make, probably by archiving).
+ * The modification time of one of its sources is greater than
+ * the one of its RANLIBMAG member (i.e. its table of contents
+ * is out-of-date). We don't compare of the archive time
+ * vs. TOC time because they can be too close. In my
+ * opinion we should not bother with the TOC at all since
+ * this is used by 'ar' rules that affect the data contents
+ * of the archive, not by ranlib rules, which affect the
+ * TOC.
+ *
+ * Input:
+ * gn The library's graph node
+ *
+ * Results:
+ * TRUE if the library is out-of-date. FALSE otherwise.
+ *
+ * Side Effects:
+ * The library will be hashed if it hasn't been already.
+ *
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Arch_LibOODate(GNode *gn)
+{
+ Boolean oodate;
+
+ if (gn->type & OP_PHONY) {
+ oodate = TRUE;
+ } else if (OP_NOP(gn->type) && Lst_IsEmpty(gn->children)) {
+ oodate = FALSE;
+ } else if ((!Lst_IsEmpty(gn->children) && gn->cmgn == NULL) ||
+ (gn->mtime > now) ||
+ (gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime)) {
+ oodate = TRUE;
+ } else {
+#ifdef RANLIBMAG
+ struct ar_hdr *arhPtr; /* Header for __.SYMDEF */
+ int modTimeTOC; /* The table-of-contents's mod time */
+
+ arhPtr = ArchStatMember(gn->path, UNCONST(RANLIBMAG), FALSE);
+
+ if (arhPtr != NULL) {
+ modTimeTOC = (int)strtol(arhPtr->AR_DATE, NULL, 10);
+
+ if (DEBUG(ARCH) || DEBUG(MAKE)) {
+ fprintf(debug_file, "%s modified %s...", RANLIBMAG, Targ_FmtTime(modTimeTOC));
+ }
+ oodate = (gn->cmgn == NULL || gn->cmgn->mtime > modTimeTOC);
+ } else {
+ /*
+ * A library w/o a table of contents is out-of-date
+ */
+ if (DEBUG(ARCH) || DEBUG(MAKE)) {
+ fprintf(debug_file, "No t.o.c....");
+ }
+ oodate = TRUE;
+ }
+#else
+ oodate = FALSE;
+#endif
+ }
+ return (oodate);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Arch_Init --
+ * Initialize things for this module.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The 'archives' list is initialized.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Arch_Init(void)
+{
+ archives = Lst_Init(FALSE);
+}
+
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Arch_End --
+ * Cleanup things for this module.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The 'archives' list is freed
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Arch_End(void)
+{
+#ifdef CLEANUP
+ Lst_Destroy(archives, ArchFree);
+#endif
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Arch_IsLib --
+ * Check if the node is a library
+ *
+ * Results:
+ * True or False.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+int
+Arch_IsLib(GNode *gn)
+{
+ static const char armag[] = "!<arch>\n";
+ char buf[sizeof(armag)-1];
+ int fd;
+
+ if ((fd = open(gn->path, O_RDONLY)) == -1)
+ return FALSE;
+
+ if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
+ (void)close(fd);
+ return FALSE;
+ }
+
+ (void)close(fd);
+
+ return memcmp(buf, armag, sizeof(buf)) == 0;
+}
diff --git a/external/bsd/bmake/dist/bmake.1 b/external/bsd/bmake/dist/bmake.1
new file mode 100644
index 0000000..0bb377a
--- /dev/null
+++ b/external/bsd/bmake/dist/bmake.1
@@ -0,0 +1,2043 @@
+.\" $NetBSD: make.1,v 1.204 2012/04/24 20:12:16 sjg Exp $
+.\"
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
+.\"
+.Dd April 24, 2012
+.Dt MAKE 1
+.Os
+.Sh NAME
+.Nm bmake
+.Nd maintain program dependencies
+.Sh SYNOPSIS
+.Nm
+.Op Fl BeikNnqrstWX
+.Op Fl C Ar directory
+.Op Fl D Ar variable
+.Op Fl d Ar flags
+.Op Fl f Ar makefile
+.Op Fl I Ar directory
+.Op Fl J Ar private
+.Op Fl j Ar max_jobs
+.Op Fl m Ar directory
+.Op Fl T Ar file
+.Op Fl V Ar variable
+.Op Ar variable=value
+.Op Ar target ...
+.Sh DESCRIPTION
+.Nm
+is a program designed to simplify the maintenance of other programs.
+Its input is a list of specifications as to the files upon which programs
+and other files depend.
+If no
+.Fl f Ar makefile
+makefile option is given,
+.Nm
+will try to open
+.Ql Pa makefile
+then
+.Ql Pa Makefile
+in order to find the specifications.
+If the file
+.Ql Pa .depend
+exists, it is read (see
+.Xr mkdep 1 ) .
+.Pp
+This manual page is intended as a reference document only.
+For a more thorough description of
+.Nm
+and makefiles, please refer to
+.%T "PMake \- A Tutorial" .
+.Pp
+.Nm
+will prepend the contents of the
+.Va MAKEFLAGS
+environment variable to the command line arguments before parsing them.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl B
+Try to be backwards compatible by executing a single shell per command and
+by executing the commands to make the sources of a dependency line in sequence.
+.It Fl C Ar directory
+Change to
+.Ar directory
+before reading the makefiles or doing anything else.
+If multiple
+.Fl C
+options are specified, each is interpreted relative to the previous one:
+.Fl C Pa / Fl C Pa etc
+is equivalent to
+.Fl C Pa /etc .
+.It Fl D Ar variable
+Define
+.Ar variable
+to be 1, in the global context.
+.It Fl d Ar [-]flags
+Turn on debugging, and specify which portions of
+.Nm
+are to print debugging information.
+Unless the flags are preceded by
+.Ql \-
+they are added to the
+.Va MAKEFLAGS
+environment variable and will be processed by any child make processes.
+By default, debugging information is printed to standard error,
+but this can be changed using the
+.Ar F
+debugging flag.
+The debugging output is always unbuffered; in addition, if debugging
+is enabled but debugging output is not directed to standard output,
+then the standard output is line buffered.
+.Ar Flags
+is one or more of the following:
+.Bl -tag -width Ds
+.It Ar A
+Print all possible debugging information;
+equivalent to specifying all of the debugging flags.
+.It Ar a
+Print debugging information about archive searching and caching.
+.It Ar C
+Print debugging information about current working directory.
+.It Ar c
+Print debugging information about conditional evaluation.
+.It Ar d
+Print debugging information about directory searching and caching.
+.It Ar e
+Print debugging information about failed commands and targets.
+.It Ar F Ns Oo Sy \&+ Oc Ns Ar filename
+Specify where debugging output is written.
+This must be the last flag, because it consumes the remainder of
+the argument.
+If the character immediately after the
+.Ql F
+flag is
+.Ql \&+ ,
+then the file will be opened in append mode;
+otherwise the file will be overwritten.
+If the file name is
+.Ql stdout
+or
+.Ql stderr
+then debugging output will be written to the
+standard output or standard error output file descriptors respectively
+(and the
+.Ql \&+
+option has no effect).
+Otherwise, the output will be written to the named file.
+If the file name ends
+.Ql .%d
+then the
+.Ql %d
+is replaced by the pid.
+.It Ar f
+Print debugging information about loop evaluation.
+.It Ar "g1"
+Print the input graph before making anything.
+.It Ar "g2"
+Print the input graph after making everything, or before exiting
+on error.
+.It Ar "g3"
+Print the input graph before exiting on error.
+.It Ar j
+Print debugging information about running multiple shells.
+.It Ar l
+Print commands in Makefiles regardless of whether or not they are prefixed by
+.Ql @
+or other "quiet" flags.
+Also known as "loud" behavior.
+.It Ar M
+Print debugging information about "meta" mode decisions about targets.
+.It Ar m
+Print debugging information about making targets, including modification
+dates.
+.It Ar n
+Don't delete the temporary command scripts created when running commands.
+These temporary scripts are created in the directory
+referred to by the
+.Ev TMPDIR
+environment variable, or in
+.Pa /tmp
+if
+.Ev TMPDIR
+is unset or set to the empty string.
+The temporary scripts are created by
+.Xr mkstemp 3 ,
+and have names of the form
+.Pa makeXXXXXX .
+.Em NOTE :
+This can create many files in
+.Ev TMPDIR
+or
+.Pa /tmp ,
+so use with care.
+.It Ar p
+Print debugging information about makefile parsing.
+.It Ar s
+Print debugging information about suffix-transformation rules.
+.It Ar t
+Print debugging information about target list maintenance.
+.It Ar v
+Print debugging information about variable assignment.
+.It Ar x
+Run shell commands with
+.Fl x
+so the actual commands are printed as they are executed.
+.El
+.It Fl e
+Specify that environment variables override macro assignments within
+makefiles.
+.It Fl f Ar makefile
+Specify a makefile to read instead of the default
+.Ql Pa makefile .
+If
+.Ar makefile
+is
+.Ql Fl ,
+standard input is read.
+Multiple makefiles may be specified, and are read in the order specified.
+.It Fl I Ar directory
+Specify a directory in which to search for makefiles and included makefiles.
+The system makefile directory (or directories, see the
+.Fl m
+option) is automatically included as part of this list.
+.It Fl i
+Ignore non-zero exit of shell commands in the makefile.
+Equivalent to specifying
+.Ql Fl
+before each command line in the makefile.
+.It Fl J Ar private
+This option should
+.Em not
+be specified by the user.
+.Pp
+When the
+.Ar j
+option is in use in a recursive build, this option is passed by a make
+to child makes to allow all the make processes in the build to
+cooperate to avoid overloading the system.
+.It Fl j Ar max_jobs
+Specify the maximum number of jobs that
+.Nm
+may have running at any one time.
+The value is saved in
+.Va .MAKE.JOBS .
+Turns compatibility mode off, unless the
+.Ar B
+flag is also specified.
+When compatibility mode is off, all commands associated with a
+target are executed in a single shell invocation as opposed to the
+traditional one shell invocation per line.
+This can break traditional scripts which change directories on each
+command invocation and then expect to start with a fresh environment
+on the next line.
+It is more efficient to correct the scripts rather than turn backwards
+compatibility on.
+.It Fl k
+Continue processing after errors are encountered, but only on those targets
+that do not depend on the target whose creation caused the error.
+.It Fl m Ar directory
+Specify a directory in which to search for sys.mk and makefiles included
+via the
+.Ao Ar file Ac Ns -style
+include statement.
+The
+.Fl m
+option can be used multiple times to form a search path.
+This path will override the default system include path: /usr/share/mk.
+Furthermore the system include path will be appended to the search path used
+for
+.Qo Ar file Qc Ns -style
+include statements (see the
+.Fl I
+option).
+.Pp
+If a file or directory name in the
+.Fl m
+argument (or the
+.Ev MAKESYSPATH
+environment variable) starts with the string
+.Qq \&.../
+then
+.Nm
+will search for the specified file or directory named in the remaining part
+of the argument string.
+The search starts with the current directory of
+the Makefile and then works upward towards the root of the filesystem.
+If the search is successful, then the resulting directory replaces the
+.Qq \&.../
+specification in the
+.Fl m
+argument.
+If used, this feature allows
+.Nm
+to easily search in the current source tree for customized sys.mk files
+(e.g., by using
+.Qq \&.../mk/sys.mk
+as an argument).
+.It Fl n
+Display the commands that would have been executed, but do not
+actually execute them unless the target depends on the .MAKE special
+source (see below).
+.It Fl N
+Display the commands which would have been executed, but do not
+actually execute any of them; useful for debugging top-level makefiles
+without descending into subdirectories.
+.It Fl q
+Do not execute any commands, but exit 0 if the specified targets are
+up-to-date and 1, otherwise.
+.It Fl r
+Do not use the built-in rules specified in the system makefile.
+.It Fl s
+Do not echo any commands as they are executed.
+Equivalent to specifying
+.Ql Ic @
+before each command line in the makefile.
+.It Fl T Ar tracefile
+When used with the
+.Fl j
+flag,
+append a trace record to
+.Ar tracefile
+for each job started and completed.
+.It Fl t
+Rather than re-building a target as specified in the makefile, create it
+or update its modification time to make it appear up-to-date.
+.It Fl V Ar variable
+Print
+.Nm Ns 's
+idea of the value of
+.Ar variable ,
+in the global context.
+Do not build any targets.
+Multiple instances of this option may be specified;
+the variables will be printed one per line,
+with a blank line for each null or undefined variable.
+If
+.Ar variable
+contains a
+.Ql \&$
+then the value will be expanded before printing.
+.It Fl W
+Treat any warnings during makefile parsing as errors.
+.It Fl X
+Don't export variables passed on the command line to the environment
+individually.
+Variables passed on the command line are still exported
+via the
+.Va MAKEFLAGS
+environment variable.
+This option may be useful on systems which have a small limit on the
+size of command arguments.
+.It Ar variable=value
+Set the value of the variable
+.Ar variable
+to
+.Ar value .
+Normally, all values passed on the command line are also exported to
+sub-makes in the environment.
+The
+.Fl X
+flag disables this behavior.
+Variable assignments should follow options for POSIX compatibility
+but no ordering is enforced.
+.El
+.Pp
+There are seven different types of lines in a makefile: file dependency
+specifications, shell commands, variable assignments, include statements,
+conditional directives, for loops, and comments.
+.Pp
+In general, lines may be continued from one line to the next by ending
+them with a backslash
+.Pq Ql \e .
+The trailing newline character and initial whitespace on the following
+line are compressed into a single space.
+.Sh FILE DEPENDENCY SPECIFICATIONS
+Dependency lines consist of one or more targets, an operator, and zero
+or more sources.
+This creates a relationship where the targets
+.Dq depend
+on the sources
+and are usually created from them.
+The exact relationship between the target and the source is determined
+by the operator that separates them.
+The three operators are as follows:
+.Bl -tag -width flag
+.It Ic \&:
+A target is considered out-of-date if its modification time is less than
+those of any of its sources.
+Sources for a target accumulate over dependency lines when this operator
+is used.
+The target is removed if
+.Nm
+is interrupted.
+.It Ic \&!
+Targets are always re-created, but not until all sources have been
+examined and re-created as necessary.
+Sources for a target accumulate over dependency lines when this operator
+is used.
+The target is removed if
+.Nm
+is interrupted.
+.It Ic \&::
+If no sources are specified, the target is always re-created.
+Otherwise, a target is considered out-of-date if any of its sources has
+been modified more recently than the target.
+Sources for a target do not accumulate over dependency lines when this
+operator is used.
+The target will not be removed if
+.Nm
+is interrupted.
+.El
+.Pp
+Targets and sources may contain the shell wildcard values
+.Ql \&? ,
+.Ql * ,
+.Ql [] ,
+and
+.Ql {} .
+The values
+.Ql \&? ,
+.Ql * ,
+and
+.Ql []
+may only be used as part of the final
+component of the target or source, and must be used to describe existing
+files.
+The value
+.Ql {}
+need not necessarily be used to describe existing files.
+Expansion is in directory order, not alphabetically as done in the shell.
+.Sh SHELL COMMANDS
+Each target may have associated with it a series of shell commands, normally
+used to create the target.
+Each of the commands in this script
+.Em must
+be preceded by a tab.
+While any target may appear on a dependency line, only one of these
+dependencies may be followed by a creation script, unless the
+.Ql Ic \&::
+operator is used.
+.Pp
+If the first characters of the command line are any combination of
+.Ql Ic @ ,
+.Ql Ic + ,
+or
+.Ql Ic \- ,
+the command is treated specially.
+A
+.Ql Ic @
+causes the command not to be echoed before it is executed.
+A
+.Ql Ic +
+causes the command to be executed even when
+.Fl n
+is given.
+This is similar to the effect of the .MAKE special source,
+except that the effect can be limited to a single line of a script.
+A
+.Ql Ic \-
+causes any non-zero exit status of the command line to be ignored.
+.Sh VARIABLE ASSIGNMENTS
+Variables in make are much like variables in the shell, and, by tradition,
+consist of all upper-case letters.
+.Ss Variable assignment modifiers
+The five operators that can be used to assign values to variables are as
+follows:
+.Bl -tag -width Ds
+.It Ic \&=
+Assign the value to the variable.
+Any previous value is overridden.
+.It Ic \&+=
+Append the value to the current value of the variable.
+.It Ic \&?=
+Assign the value to the variable if it is not already defined.
+.It Ic \&:=
+Assign with expansion, i.e. expand the value before assigning it
+to the variable.
+Normally, expansion is not done until the variable is referenced.
+.Em NOTE :
+References to undefined variables are
+.Em not
+expanded.
+This can cause problems when variable modifiers are used.
+.It Ic \&!=
+Expand the value and pass it to the shell for execution and assign
+the result to the variable.
+Any newlines in the result are replaced with spaces.
+.El
+.Pp
+Any white-space before the assigned
+.Ar value
+is removed; if the value is being appended, a single space is inserted
+between the previous contents of the variable and the appended value.
+.Pp
+Variables are expanded by surrounding the variable name with either
+curly braces
+.Pq Ql {}
+or parentheses
+.Pq Ql ()
+and preceding it with
+a dollar sign
+.Pq Ql \&$ .
+If the variable name contains only a single letter, the surrounding
+braces or parentheses are not required.
+This shorter form is not recommended.
+.Pp
+If the variable name contains a dollar, then the name itself is expanded first.
+This allows almost arbitrary variable names, however names containing dollar,
+braces, parenthesis, or whitespace are really best avoided!
+.Pp
+If the result of expanding a variable contains a dollar sign
+.Pq Ql \&$
+the string is expanded again.
+.Pp
+Variable substitution occurs at three distinct times, depending on where
+the variable is being used.
+.Bl -enum
+.It
+Variables in dependency lines are expanded as the line is read.
+.It
+Variables in shell commands are expanded when the shell command is
+executed.
+.It
+.Dq .for
+loop index variables are expanded on each loop iteration.
+Note that other variables are not expanded inside loops so
+the following example code:
+.Bd -literal -offset indent
+
+.Dv .for i in 1 2 3
+a+= ${i}
+j= ${i}
+b+= ${j}
+.Dv .endfor
+
+all:
+ @echo ${a}
+ @echo ${b}
+
+.Ed
+will print:
+.Bd -literal -offset indent
+1 2 3
+3 3 3
+
+.Ed
+Because while ${a} contains
+.Dq 1 2 3
+after the loop is executed, ${b}
+contains
+.Dq ${j} ${j} ${j}
+which expands to
+.Dq 3 3 3
+since after the loop completes ${j} contains
+.Dq 3 .
+.El
+.Ss Variable classes
+The four different classes of variables (in order of increasing precedence)
+are:
+.Bl -tag -width Ds
+.It Environment variables
+Variables defined as part of
+.Nm Ns 's
+environment.
+.It Global variables
+Variables defined in the makefile or in included makefiles.
+.It Command line variables
+Variables defined as part of the command line.
+.It Local variables
+Variables that are defined specific to a certain target.
+The seven local variables are as follows:
+.Bl -tag -width ".ARCHIVE"
+.It Va .ALLSRC
+The list of all sources for this target; also known as
+.Ql Va \&\*[Gt] .
+.It Va .ARCHIVE
+The name of the archive file.
+.It Va .IMPSRC
+In suffix-transformation rules, the name/path of the source from which the
+target is to be transformed (the
+.Dq implied
+source); also known as
+.Ql Va \&\*[Lt] .
+It is not defined in explicit rules.
+.It Va .MEMBER
+The name of the archive member.
+.It Va .OODATE
+The list of sources for this target that were deemed out-of-date; also
+known as
+.Ql Va \&? .
+.It Va .PREFIX
+The file prefix of the target, containing only the file portion, no suffix
+or preceding directory components; also known as
+.Ql Va * .
+.It Va .TARGET
+The name of the target; also known as
+.Ql Va @ .
+.El
+.Pp
+The shorter forms
+.Ql Va @ ,
+.Ql Va \&? ,
+.Ql Va \&\*[Lt] ,
+.Ql Va \&\*[Gt] ,
+and
+.Ql Va *
+are permitted for backward
+compatibility with historical makefiles and are not recommended.
+The six variables
+.Ql Va "@F" ,
+.Ql Va "@D" ,
+.Ql Va "\*[Lt]F" ,
+.Ql Va "\*[Lt]D" ,
+.Ql Va "*F" ,
+and
+.Ql Va "*D"
+are permitted for compatibility with
+.At V
+makefiles and are not recommended.
+.Pp
+Four of the local variables may be used in sources on dependency lines
+because they expand to the proper value for each target on the line.
+These variables are
+.Ql Va .TARGET ,
+.Ql Va .PREFIX ,
+.Ql Va .ARCHIVE ,
+and
+.Ql Va .MEMBER .
+.El
+.Ss Additional built-in variables
+In addition,
+.Nm
+sets or knows about the following variables:
+.Bl -tag -width .MAKEOVERRIDES
+.It Va \&$
+A single dollar sign
+.Ql \&$ ,
+i.e.
+.Ql \&$$
+expands to a single dollar
+sign.
+.It Va .ALLTARGETS
+The list of all targets encountered in the Makefile.
+If evaluated during
+Makefile parsing, lists only those targets encountered thus far.
+.It Va .CURDIR
+A path to the directory where
+.Nm
+was executed.
+Refer to the description of
+.Ql Ev PWD
+for more details.
+.It Ev MAKE
+The name that
+.Nm
+was executed with
+.Pq Va argv[0] .
+For compatibility
+.Nm
+also sets
+.Va .MAKE
+with the same value.
+The preferred variable to use is the environment variable
+.Ev MAKE
+because it is more compatible with other versions of
+.Nm
+and cannot be confused with the special target with the same name.
+.It Va .MAKE.DEPENDFILE
+Names the makefile (default
+.Ql Pa .depend )
+from which generated dependencies are read.
+.It Va .MAKE.EXPORTED
+The list of variables exported by
+.Nm .
+.It Va .MAKE.JOBS
+The argument to the
+.Fl j
+option.
+.It Va .MAKE.JOB.PREFIX
+If
+.Nm
+is run with
+.Ar j
+then output for each target is prefixed with a token
+.Ql --- target ---
+the first part of which can be controlled via
+.Va .MAKE.JOB.PREFIX .
+.br
+For example:
+.Li .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}]
+would produce tokens like
+.Ql ---make[1234] target ---
+making it easier to track the degree of parallelism being achieved.
+.It Ev MAKEFLAGS
+The environment variable
+.Ql Ev MAKEFLAGS
+may contain anything that
+may be specified on
+.Nm Ns 's
+command line.
+Anything specified on
+.Nm Ns 's
+command line is appended to the
+.Ql Ev MAKEFLAGS
+variable which is then
+entered into the environment for all programs which
+.Nm
+executes.
+.It Va .MAKE.LEVEL
+The recursion depth of
+.Nm .
+The initial instance of
+.Nm
+will be 0, and an incremented value is put into the environment
+to be seen by the next generation.
+This allows tests like:
+.Li .if ${.MAKE.LEVEL} == 0
+to protect things which should only be evaluated in the initial instance of
+.Nm .
+.It Va .MAKE.MAKEFILE_PREFERENCE
+The ordered list of makefile names
+(default
+.Ql Pa makefile ,
+.Ql Pa Makefile )
+that
+.Nm
+will look for.
+.It Va .MAKE.MAKEFILES
+The list of makefiles read by
+.Nm ,
+which is useful for tracking dependencies.
+Each makefile is recorded only once, regardless of the number of times read.
+.It Va .MAKE.MODE
+Processed after reading all makefiles.
+Can affect the mode that
+.Nm
+runs in.
+It can contain a number of keywords:
+.Bl -hang -width ignore-cmd
+.It Pa compat
+Like
+.Fl B ,
+puts
+.Nm
+into "compat" mode.
+.It Pa meta
+Puts
+.Nm
+into "meta" mode, where meta files are created for each target
+to capture the command run, the output generated and if
+.Xr filemon 4
+is available, the system calls which are of interest to
+.Nm .
+The captured output can be very useful when diagnosing errors.
+.It Pa curdirOk= Ar bf
+Normally
+.Nm
+will not create .meta files in
+.Ql Va .CURDIR .
+This can be overridden by setting
+.Va bf
+to a value which represents True.
+.It Pa env
+For debugging, it can be useful to inlcude the environment
+in the .meta file.
+.It Pa verbose
+If in "meta" mode, print a clue about the target being built.
+This is useful if the build is otherwise running silently.
+The message printed the value of:
+.Va .MAKE.META.PREFIX .
+.It Pa ignore-cmd
+Some makefiles have commands which are simply not stable.
+This keyword causes them to be ignored for
+determining whether a target is out of date in "meta" mode.
+See also
+.Ic .NOMETA_CMP .
+.It Pa silent= Ar bf
+If
+.Va bf
+is True, when a .meta file is created, mark the target
+.Ic .SILENT .
+.El
+.It Va .MAKE.META.BAILIWICK
+In "meta" mode, provides a list of prefixes which
+match the directories controlled by
+.Nm .
+If a file that was generated outside of
+.Va .OBJDIR
+but within said bailiwick is missing,
+the current target is considered out-of-date.
+.It Va .MAKE.META.CREATED
+In "meta" mode, this variable contains a list of all the meta files
+updated.
+If not empty, it can be used to trigger processing of
+.Va .MAKE.META.FILES .
+.It Va .MAKE.META.FILES
+In "meta" mode, this variable contains a list of all the meta files
+used (updated or not).
+This list can be used to process the meta files to extract dependency
+information.
+.It Va .MAKE.META.PREFIX
+Defines the message printed for each meta file updated in "meta verbose" mode.
+The default value is:
+.Dl Building ${.TARGET:H:tA}/${.TARGET:T}
+.It Va .MAKEOVERRIDES
+This variable is used to record the names of variables assigned to
+on the command line, so that they may be exported as part of
+.Ql Ev MAKEFLAGS .
+This behaviour can be disabled by assigning an empty value to
+.Ql Va .MAKEOVERRIDES
+within a makefile.
+Extra variables can be exported from a makefile
+by appending their names to
+.Ql Va .MAKEOVERRIDES .
+.Ql Ev MAKEFLAGS
+is re-exported whenever
+.Ql Va .MAKEOVERRIDES
+is modified.
+.It Va .MAKE.PID
+The process-id of
+.Nm .
+.It Va .MAKE.PPID
+The parent process-id of
+.Nm .
+.It Va MAKE_PRINT_VAR_ON_ERROR
+When
+.Nm
+stops due to an error, it prints its name and the value of
+.Ql Va .CURDIR
+as well as the value of any variables named in
+.Ql Va MAKE_PRINT_VAR_ON_ERROR .
+.It Va .newline
+This variable is simply assigned a newline character as its value.
+This allows expansions using the
+.Cm \&:@
+modifier to put a newline between
+iterations of the loop rather than a space.
+For example, the printing of
+.Ql Va MAKE_PRINT_VAR_ON_ERROR
+could be done as ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}.
+.It Va .OBJDIR
+A path to the directory where the targets are built.
+Its value is determined by trying to
+.Xr chdir 2
+to the following directories in order and using the first match:
+.Bl -enum
+.It
+.Ev ${MAKEOBJDIRPREFIX}${.CURDIR}
+.Pp
+(Only if
+.Ql Ev MAKEOBJDIRPREFIX
+is set in the environment or on the command line.)
+.It
+.Ev ${MAKEOBJDIR}
+.Pp
+(Only if
+.Ql Ev MAKEOBJDIR
+is set in the environment or on the command line.)
+.It
+.Ev ${.CURDIR} Ns Pa /obj. Ns Ev ${MACHINE}
+.It
+.Ev ${.CURDIR} Ns Pa /obj
+.It
+.Pa /usr/obj/ Ns Ev ${.CURDIR}
+.It
+.Ev ${.CURDIR}
+.El
+.Pp
+Variable expansion is performed on the value before it's used,
+so expressions such as
+.Dl ${.CURDIR:S,^/usr/src,/var/obj,}
+may be used.
+This is especially useful with
+.Ql Ev MAKEOBJDIR .
+.Pp
+.Ql Va .OBJDIR
+may be modified in the makefile as a global variable.
+In all cases,
+.Nm
+will
+.Xr chdir 2
+to
+.Ql Va .OBJDIR
+and set
+.Ql Ev PWD
+to that directory before executing any targets.
+.
+.It Va .PARSEDIR
+A path to the directory of the current
+.Ql Pa Makefile
+being parsed.
+.It Va .PARSEFILE
+The basename of the current
+.Ql Pa Makefile
+being parsed.
+This variable and
+.Ql Va .PARSEDIR
+are both set only while the
+.Ql Pa Makefiles
+are being parsed.
+If you want to retain their current values, assign them to a variable
+using assignment with expansion:
+.Pq Ql Cm \&:= .
+.It Va .PATH
+A variable that represents the list of directories that
+.Nm
+will search for files.
+The search list should be updated using the target
+.Ql Va .PATH
+rather than the variable.
+.It Ev PWD
+Alternate path to the current directory.
+.Nm
+normally sets
+.Ql Va .CURDIR
+to the canonical path given by
+.Xr getcwd 3 .
+However, if the environment variable
+.Ql Ev PWD
+is set and gives a path to the current directory, then
+.Nm
+sets
+.Ql Va .CURDIR
+to the value of
+.Ql Ev PWD
+instead.
+This behaviour is disabled if
+.Ql Ev MAKEOBJDIRPREFIX
+is set or
+.Ql Ev MAKEOBJDIR
+contains a variable transform.
+.Ql Ev PWD
+is set to the value of
+.Ql Va .OBJDIR
+for all programs which
+.Nm
+executes.
+.It Ev .TARGETS
+The list of targets explicitly specified on the command line, if any.
+.It Ev VPATH
+Colon-separated
+.Pq Dq \&:
+lists of directories that
+.Nm
+will search for files.
+The variable is supported for compatibility with old make programs only,
+use
+.Ql Va .PATH
+instead.
+.El
+.Ss Variable modifiers
+Variable expansion may be modified to select or modify each word of the
+variable (where a
+.Dq word
+is white-space delimited sequence of characters).
+The general format of a variable expansion is as follows:
+.Pp
+.Dl ${variable[:modifier[:...]]}
+.Pp
+Each modifier begins with a colon,
+which may be escaped with a backslash
+.Pq Ql \e .
+.Pp
+A set of modifiers can be specified via a variable, as follows:
+.Pp
+.Dl modifier_variable=modifier[:...]
+.Dl ${variable:${modifier_variable}[:...]}
+.Pp
+In this case the first modifier in the modifier_variable does not
+start with a colon, since that must appear in the referencing
+variable.
+If any of the modifiers in the modifier_variable contain a dollar sign
+.Pq Ql $ ,
+these must be doubled to avoid early expansion.
+.Pp
+The supported modifiers are:
+.Bl -tag -width EEE
+.It Cm \&:E
+Replaces each word in the variable with its suffix.
+.It Cm \&:H
+Replaces each word in the variable with everything but the last component.
+.It Cm \&:M Ns Ar pattern
+Select only those words that match
+.Ar pattern .
+The standard shell wildcard characters
+.Pf ( Ql * ,
+.Ql \&? ,
+and
+.Ql Oo Oc )
+may
+be used.
+The wildcard characters may be escaped with a backslash
+.Pq Ql \e .
+.It Cm \&:N Ns Ar pattern
+This is identical to
+.Ql Cm \&:M ,
+but selects all words which do not match
+.Ar pattern .
+.It Cm \&:O
+Order every word in variable alphabetically.
+To sort words in
+reverse order use the
+.Ql Cm \&:O:[-1..1]
+combination of modifiers.
+.It Cm \&:Ox
+Randomize words in variable.
+The results will be different each time you are referring to the
+modified variable; use the assignment with expansion
+.Pq Ql Cm \&:=
+to prevent such behaviour.
+For example,
+.Bd -literal -offset indent
+LIST= uno due tre quattro
+RANDOM_LIST= ${LIST:Ox}
+STATIC_RANDOM_LIST:= ${LIST:Ox}
+
+all:
+ @echo "${RANDOM_LIST}"
+ @echo "${RANDOM_LIST}"
+ @echo "${STATIC_RANDOM_LIST}"
+ @echo "${STATIC_RANDOM_LIST}"
+.Ed
+may produce output similar to:
+.Bd -literal -offset indent
+quattro due tre uno
+tre due quattro uno
+due uno quattro tre
+due uno quattro tre
+.Ed
+.It Cm \&:Q
+Quotes every shell meta-character in the variable, so that it can be passed
+safely through recursive invocations of
+.Nm .
+.It Cm \&:R
+Replaces each word in the variable with everything but its suffix.
+.It Cm \&:gmtime
+The value is a format string for
+.Xr strftime 3 ,
+using the current
+.Xr gmtime 3 .
+.It Cm \&:hash
+Compute a 32bit hash of the value and encode it as hex digits.
+.It Cm \&:localtime
+The value is a format string for
+.Xr strftime 3 ,
+using the current
+.Xr localtime 3 .
+.It Cm \&:tA
+Attempt to convert variable to an absolute path using
+.Xr realpath 3 ,
+if that fails, the value is unchanged.
+.It Cm \&:tl
+Converts variable to lower-case letters.
+.It Cm \&:ts Ns Ar c
+Words in the variable are normally separated by a space on expansion.
+This modifier sets the separator to the character
+.Ar c .
+If
+.Ar c
+is omitted, then no separator is used.
+The common escapes (including octal numeric codes), work as expected.
+.It Cm \&:tu
+Converts variable to upper-case letters.
+.It Cm \&:tW
+Causes the value to be treated as a single word
+(possibly containing embedded white space).
+See also
+.Ql Cm \&:[*] .
+.It Cm \&:tw
+Causes the value to be treated as a sequence of
+words delimited by white space.
+See also
+.Ql Cm \&:[@] .
+.Sm off
+.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW
+.Sm on
+Modify the first occurrence of
+.Ar old_string
+in the variable's value, replacing it with
+.Ar new_string .
+If a
+.Ql g
+is appended to the last slash of the pattern, all occurrences
+in each word are replaced.
+If a
+.Ql 1
+is appended to the last slash of the pattern, only the first word
+is affected.
+If a
+.Ql W
+is appended to the last slash of the pattern,
+then the value is treated as a single word
+(possibly containing embedded white space).
+If
+.Ar old_string
+begins with a caret
+.Pq Ql ^ ,
+.Ar old_string
+is anchored at the beginning of each word.
+If
+.Ar old_string
+ends with a dollar sign
+.Pq Ql \&$ ,
+it is anchored at the end of each word.
+Inside
+.Ar new_string ,
+an ampersand
+.Pq Ql \*[Am]
+is replaced by
+.Ar old_string
+(without any
+.Ql ^
+or
+.Ql \&$ ) .
+Any character may be used as a delimiter for the parts of the modifier
+string.
+The anchoring, ampersand and delimiter characters may be escaped with a
+backslash
+.Pq Ql \e .
+.Pp
+Variable expansion occurs in the normal fashion inside both
+.Ar old_string
+and
+.Ar new_string
+with the single exception that a backslash is used to prevent the expansion
+of a dollar sign
+.Pq Ql \&$ ,
+not a preceding dollar sign as is usual.
+.Sm off
+.It Cm \&:C No \&/ Ar pattern No \&/ Ar replacement No \&/ Op Cm 1gW
+.Sm on
+The
+.Cm \&:C
+modifier is just like the
+.Cm \&:S
+modifier except that the old and new strings, instead of being
+simple strings, are a regular expression (see
+.Xr regex 3 )
+string
+.Ar pattern
+and an
+.Xr ed 1 Ns \-style
+string
+.Ar replacement .
+Normally, the first occurrence of the pattern
+.Ar pattern
+in each word of the value is substituted with
+.Ar replacement .
+The
+.Ql 1
+modifier causes the substitution to apply to at most one word; the
+.Ql g
+modifier causes the substitution to apply to as many instances of the
+search pattern
+.Ar pattern
+as occur in the word or words it is found in; the
+.Ql W
+modifier causes the value to be treated as a single word
+(possibly containing embedded white space).
+Note that
+.Ql 1
+and
+.Ql g
+are orthogonal; the former specifies whether multiple words are
+potentially affected, the latter whether multiple substitutions can
+potentially occur within each affected word.
+.It Cm \&:T
+Replaces each word in the variable with its last component.
+.It Cm \&:u
+Remove adjacent duplicate words (like
+.Xr uniq 1 ) .
+.Sm off
+.It Cm \&:\&? Ar true_string Cm \&: Ar false_string
+.Sm on
+If the variable name (not its value), when parsed as a .if conditional
+expression, evaluates to true, return as its value the
+.Ar true_string ,
+otherwise return the
+.Ar false_string .
+Since the variable name is used as the expression, \&:\&? must be the
+first modifier after the variable name itself - which will, of course,
+usually contain variable expansions.
+A common error is trying to use expressions like
+.Dl ${NUMBERS:M42:?match:no}
+which actually tests defined(NUMBERS),
+to determine is any words match "42" you need to use something like:
+.Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} .
+.It Ar :old_string=new_string
+This is the
+.At V
+style variable substitution.
+It must be the last modifier specified.
+If
+.Ar old_string
+or
+.Ar new_string
+do not contain the pattern matching character
+.Ar %
+then it is assumed that they are
+anchored at the end of each word, so only suffixes or entire
+words may be replaced.
+Otherwise
+.Ar %
+is the substring of
+.Ar old_string
+to be replaced in
+.Ar new_string .
+.Pp
+Variable expansion occurs in the normal fashion inside both
+.Ar old_string
+and
+.Ar new_string
+with the single exception that a backslash is used to prevent the
+expansion of a dollar sign
+.Pq Ql \&$ ,
+not a preceding dollar sign as is usual.
+.Sm off
+.It Cm \&:@ Ar temp Cm @ Ar string Cm @
+.Sm on
+This is the loop expansion mechanism from the OSF Development
+Environment (ODE) make.
+Unlike
+.Cm \&.for
+loops expansion occurs at the time of
+reference.
+Assign
+.Ar temp
+to each word in the variable and evaluate
+.Ar string .
+The ODE convention is that
+.Ar temp
+should start and end with a period.
+For example.
+.Dl ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
+.Pp
+However a single character varaiable is often more readable:
+.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
+.It Cm \&:U Ns Ar newval
+If the variable is undefined
+.Ar newval
+is the value.
+If the variable is defined, the existing value is returned.
+This is another ODE make feature.
+It is handy for setting per-target CFLAGS for instance:
+.Dl ${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}}
+If a value is only required if the variable is undefined, use:
+.Dl ${VAR:D:Unewval}
+.It Cm \&:D Ns Ar newval
+If the variable is defined
+.Ar newval
+is the value.
+.It Cm \&:L
+The name of the variable is the value.
+.It Cm \&:P
+The path of the node which has the same name as the variable
+is the value.
+If no such node exists or its path is null, then the
+name of the variable is used.
+In order for this modifier to work, the name (node) must at least have
+appeared on the rhs of a dependency.
+.Sm off
+.It Cm \&:\&! Ar cmd Cm \&!
+.Sm on
+The output of running
+.Ar cmd
+is the value.
+.It Cm \&:sh
+If the variable is non-empty it is run as a command and the output
+becomes the new value.
+.It Cm \&::= Ns Ar str
+The variable is assigned the value
+.Ar str
+after substitution.
+This modifier and its variations are useful in
+obscure situations such as wanting to set a variable when shell commands
+are being parsed.
+These assignment modifiers always expand to
+nothing, so if appearing in a rule line by themselves should be
+preceded with something to keep
+.Nm
+happy.
+.Pp
+The
+.Ql Cm \&::
+helps avoid false matches with the
+.At V
+style
+.Cm \&:=
+modifier and since substitution always occurs the
+.Cm \&::=
+form is vaguely appropriate.
+.It Cm \&::?= Ns Ar str
+As for
+.Cm \&::=
+but only if the variable does not already have a value.
+.It Cm \&::+= Ns Ar str
+Append
+.Ar str
+to the variable.
+.It Cm \&::!= Ns Ar cmd
+Assign the output of
+.Ar cmd
+to the variable.
+.It Cm \&:\&[ Ns Ar range Ns Cm \&]
+Selects one or more words from the value,
+or performs other operations related to the way in which the
+value is divided into words.
+.Pp
+Ordinarily, a value is treated as a sequence of words
+delimited by white space.
+Some modifiers suppress this behaviour,
+causing a value to be treated as a single word
+(possibly containing embedded white space).
+An empty value, or a value that consists entirely of white-space,
+is treated as a single word.
+For the purposes of the
+.Ql Cm \&:[]
+modifier, the words are indexed both forwards using positive integers
+(where index 1 represents the first word),
+and backwards using negative integers
+(where index \-1 represents the last word).
+.Pp
+The
+.Ar range
+is subjected to variable expansion, and the expanded result is
+then interpreted as follows:
+.Bl -tag -width index
+.\" :[n]
+.It Ar index
+Selects a single word from the value.
+.\" :[start..end]
+.It Ar start Ns Cm \&.. Ns Ar end
+Selects all words from
+.Ar start
+to
+.Ar end ,
+inclusive.
+For example,
+.Ql Cm \&:[2..-1]
+selects all words from the second word to the last word.
+If
+.Ar start
+is greater than
+.Ar end ,
+then the words are output in reverse order.
+For example,
+.Ql Cm \&:[-1..1]
+selects all the words from last to first.
+.\" :[*]
+.It Cm \&*
+Causes subsequent modifiers to treat the value as a single word
+(possibly containing embedded white space).
+Analogous to the effect of
+\&"$*\&"
+in Bourne shell.
+.\" :[0]
+.It 0
+Means the same as
+.Ql Cm \&:[*] .
+.\" :[*]
+.It Cm \&@
+Causes subsequent modifiers to treat the value as a sequence of words
+delimited by white space.
+Analogous to the effect of
+\&"$@\&"
+in Bourne shell.
+.\" :[#]
+.It Cm \&#
+Returns the number of words in the value.
+.El \" :[range]
+.El
+.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS
+Makefile inclusion, conditional structures and for loops reminiscent
+of the C programming language are provided in
+.Nm .
+All such structures are identified by a line beginning with a single
+dot
+.Pq Ql \&.
+character.
+Files are included with either
+.Cm \&.include Aq Ar file
+or
+.Cm \&.include Pf \*q Ar file Ns \*q .
+Variables between the angle brackets or double quotes are expanded
+to form the file name.
+If angle brackets are used, the included makefile is expected to be in
+the system makefile directory.
+If double quotes are used, the including makefile's directory and any
+directories specified using the
+.Fl I
+option are searched before the system
+makefile directory.
+For compatibility with other versions of
+.Nm
+.Ql include file ...
+is also accepted.
+If the include statement is written as
+.Cm .-include
+or as
+.Cm .sinclude
+then errors locating and/or opening include files are ignored.
+.Pp
+Conditional expressions are also preceded by a single dot as the first
+character of a line.
+The possible conditionals are as follows:
+.Bl -tag -width Ds
+.It Ic .error Ar message
+The message is printed along with the name of the makefile and line number,
+then
+.Nm
+will exit.
+.It Ic .export Ar variable ...
+Export the specified global variable.
+If no variable list is provided, all globals are exported
+except for internal variables (those that start with
+.Ql \&. ) .
+This is not affected by the
+.Fl X
+flag, so should be used with caution.
+For compatibility with other
+.Nm
+programs
+.Ql export variable=value
+is also accepted.
+.Pp
+Appending a variable name to
+.Va .MAKE.EXPORTED
+is equivalent to exporting a variable.
+.It Ic .export-env Ar variable ...
+The same as
+.Ql .export ,
+except that the variable is not appended to
+.Va .MAKE.EXPORTED .
+This allows exporting a value to the environment which is different from that
+used by
+.Nm
+internally.
+.It Ic .info Ar message
+The message is printed along with the name of the makefile and line number.
+.It Ic .undef Ar variable
+Un-define the specified global variable.
+Only global variables may be un-defined.
+.It Ic .unexport Ar variable ...
+The opposite of
+.Ql .export .
+The specified global
+.Va variable
+will be removed from
+.Va .MAKE.EXPORTED .
+If no variable list is provided, all globals are unexported,
+and
+.Va .MAKE.EXPORTED
+deleted.
+.It Ic .unexport-env
+Unexport all globals previously exported and
+clear the environment inherited from the parent.
+This operation will cause a memory leak of the original environment,
+so should be used sparingly.
+Testing for
+.Va .MAKE.LEVEL
+being 0, would make sense.
+Also note that any variables which originated in the parent environment
+should be explicitly preserved if desired.
+For example:
+.Bd -literal -offset indent
+.Li .if ${.MAKE.LEVEL} == 0
+PATH := ${PATH}
+.Li .unexport-env
+.Li .export PATH
+.Li .endif
+.Pp
+.Ed
+Would result in an environment containing only
+.Ql Ev PATH ,
+which is the minimal useful environment.
+Actually
+.Ql Ev .MAKE.LEVEL
+will also be pushed into the new environment.
+.It Ic .warning Ar message
+The message prefixed by
+.Ql Pa warning:
+is printed along with the name of the makefile and line number.
+.It Ic \&.if Oo \&! Oc Ns Ar expression Op Ar operator expression ...
+Test the value of an expression.
+.It Ic .ifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
+Test the value of a variable.
+.It Ic .ifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
+Test the value of a variable.
+.It Ic .ifmake Oo \&! Oc Ns Ar target Op Ar operator target ...
+Test the target being built.
+.It Ic .ifnmake Oo \&! Ns Oc Ar target Op Ar operator target ...
+Test the target being built.
+.It Ic .else
+Reverse the sense of the last conditional.
+.It Ic .elif Oo \&! Ns Oc Ar expression Op Ar operator expression ...
+A combination of
+.Ql Ic .else
+followed by
+.Ql Ic .if .
+.It Ic .elifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
+A combination of
+.Ql Ic .else
+followed by
+.Ql Ic .ifdef .
+.It Ic .elifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
+A combination of
+.Ql Ic .else
+followed by
+.Ql Ic .ifndef .
+.It Ic .elifmake Oo \&! Oc Ns Ar target Op Ar operator target ...
+A combination of
+.Ql Ic .else
+followed by
+.Ql Ic .ifmake .
+.It Ic .elifnmake Oo \&! Oc Ns Ar target Op Ar operator target ...
+A combination of
+.Ql Ic .else
+followed by
+.Ql Ic .ifnmake .
+.It Ic .endif
+End the body of the conditional.
+.El
+.Pp
+The
+.Ar operator
+may be any one of the following:
+.Bl -tag -width "Cm XX"
+.It Cm \&|\&|
+Logical OR.
+.It Cm \&\*[Am]\*[Am]
+Logical
+.Tn AND ;
+of higher precedence than
+.Dq \&|\&| .
+.El
+.Pp
+As in C,
+.Nm
+will only evaluate a conditional as far as is necessary to determine
+its value.
+Parentheses may be used to change the order of evaluation.
+The boolean operator
+.Ql Ic \&!
+may be used to logically negate an entire
+conditional.
+It is of higher precedence than
+.Ql Ic \&\*[Am]\*[Am] .
+.Pp
+The value of
+.Ar expression
+may be any of the following:
+.Bl -tag -width defined
+.It Ic defined
+Takes a variable name as an argument and evaluates to true if the variable
+has been defined.
+.It Ic make
+Takes a target name as an argument and evaluates to true if the target
+was specified as part of
+.Nm Ns 's
+command line or was declared the default target (either implicitly or
+explicitly, see
+.Va .MAIN )
+before the line containing the conditional.
+.It Ic empty
+Takes a variable, with possible modifiers, and evaluates to true if
+the expansion of the variable would result in an empty string.
+.It Ic exists
+Takes a file name as an argument and evaluates to true if the file exists.
+The file is searched for on the system search path (see
+.Va .PATH ) .
+.It Ic target
+Takes a target name as an argument and evaluates to true if the target
+has been defined.
+.It Ic commands
+Takes a target name as an argument and evaluates to true if the target
+has been defined and has commands associated with it.
+.El
+.Pp
+.Ar Expression
+may also be an arithmetic or string comparison.
+Variable expansion is
+performed on both sides of the comparison, after which the integral
+values are compared.
+A value is interpreted as hexadecimal if it is
+preceded by 0x, otherwise it is decimal; octal numbers are not supported.
+The standard C relational operators are all supported.
+If after
+variable expansion, either the left or right hand side of a
+.Ql Ic ==
+or
+.Ql Ic "!="
+operator is not an integral value, then
+string comparison is performed between the expanded
+variables.
+If no relational operator is given, it is assumed that the expanded
+variable is being compared against 0 or an empty string in the case
+of a string comparison.
+.Pp
+When
+.Nm
+is evaluating one of these conditional expressions, and it encounters
+a (white-space separated) word it doesn't recognize, either the
+.Dq make
+or
+.Dq defined
+expression is applied to it, depending on the form of the conditional.
+If the form is
+.Ql Ic .ifdef ,
+.Ql Ic .ifndef ,
+or
+.Ql Ic .if
+the
+.Dq defined
+expression is applied.
+Similarly, if the form is
+.Ql Ic .ifmake
+or
+.Ql Ic .ifnmake , the
+.Dq make
+expression is applied.
+.Pp
+If the conditional evaluates to true the parsing of the makefile continues
+as before.
+If it evaluates to false, the following lines are skipped.
+In both cases this continues until a
+.Ql Ic .else
+or
+.Ql Ic .endif
+is found.
+.Pp
+For loops are typically used to apply a set of rules to a list of files.
+The syntax of a for loop is:
+.Pp
+.Bl -tag -compact -width Ds
+.It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression
+.It Aq make-rules
+.It Ic \&.endfor
+.El
+.Pp
+After the for
+.Ic expression
+is evaluated, it is split into words.
+On each iteration of the loop, one word is taken and assigned to each
+.Ic variable ,
+in order, and these
+.Ic variables
+are substituted into the
+.Ic make-rules
+inside the body of the for loop.
+The number of words must come out even; that is, if there are three
+iteration variables, the number of words provided must be a multiple
+of three.
+.Sh COMMENTS
+Comments begin with a hash
+.Pq Ql \&#
+character, anywhere but in a shell
+command line, and continue to the end of an unescaped new line.
+.Sh SPECIAL SOURCES (ATTRIBUTES)
+.Bl -tag -width .IGNOREx
+.It Ic .EXEC
+Target is never out of date, but always execute commands anyway.
+.It Ic .IGNORE
+Ignore any errors from the commands associated with this target, exactly
+as if they all were preceded by a dash
+.Pq Ql \- .
+.\" .It Ic .INVISIBLE
+.\" XXX
+.\" .It Ic .JOIN
+.\" XXX
+.It Ic .MADE
+Mark all sources of this target as being up-to-date.
+.It Ic .MAKE
+Execute the commands associated with this target even if the
+.Fl n
+or
+.Fl t
+options were specified.
+Normally used to mark recursive
+.Nm Ns 's .
+.It Ic .META
+Create a meta file for the target, even if it is flagged as
+.Ic .PHONY ,
+.Ic .MAKE ,
+or
+.Ic .SPECIAL .
+Usage in conjunction with
+.Ic .MAKE
+is the most likely case.
+In "meta" mode, the target is out-of-date if the meta file is missing.
+.It Ic .NOMETA
+Do not create a meta file for the target.
+Meta files are also not created for
+.Ic .PHONY ,
+.Ic .MAKE ,
+or
+.Ic .SPECIAL
+targets.
+.It Ic .NOMETA_CMP
+Ignore differences in commands when deciding if target is out of date.
+This is useful if the command contains a value which always changes.
+If the number of commands change, though, the target will still be out of date.
+.It Ic .NOPATH
+Do not search for the target in the directories specified by
+.Ic .PATH .
+.It Ic .NOTMAIN
+Normally
+.Nm
+selects the first target it encounters as the default target to be built
+if no target was specified.
+This source prevents this target from being selected.
+.It Ic .OPTIONAL
+If a target is marked with this attribute and
+.Nm
+can't figure out how to create it, it will ignore this fact and assume
+the file isn't needed or already exists.
+.It Ic .PHONY
+The target does not
+correspond to an actual file; it is always considered to be out of date,
+and will not be created with the
+.Fl t
+option.
+Suffix-transformation rules are not applied to
+.Ic .PHONY
+targets.
+.It Ic .PRECIOUS
+When
+.Nm
+is interrupted, it normally removes any partially made targets.
+This source prevents the target from being removed.
+.It Ic .RECURSIVE
+Synonym for
+.Ic .MAKE .
+.It Ic .SILENT
+Do not echo any of the commands associated with this target, exactly
+as if they all were preceded by an at sign
+.Pq Ql @ .
+.It Ic .USE
+Turn the target into
+.Nm Ns 's
+version of a macro.
+When the target is used as a source for another target, the other target
+acquires the commands, sources, and attributes (except for
+.Ic .USE )
+of the
+source.
+If the target already has commands, the
+.Ic .USE
+target's commands are appended
+to them.
+.It Ic .USEBEFORE
+Exactly like
+.Ic .USE ,
+but prepend the
+.Ic .USEBEFORE
+target commands to the target.
+.It Ic .WAIT
+If
+.Ic .WAIT
+appears in a dependency line, the sources that precede it are
+made before the sources that succeed it in the line.
+Since the dependents of files are not made until the file itself
+could be made, this also stops the dependents being built unless they
+are needed for another branch of the dependency tree.
+So given:
+.Bd -literal
+x: a .WAIT b
+ echo x
+a:
+ echo a
+b: b1
+ echo b
+b1:
+ echo b1
+
+.Ed
+the output is always
+.Ql a ,
+.Ql b1 ,
+.Ql b ,
+.Ql x .
+.br
+The ordering imposed by
+.Ic .WAIT
+is only relevant for parallel makes.
+.El
+.Sh SPECIAL TARGETS
+Special targets may not be included with other targets, i.e. they must be
+the only target specified.
+.Bl -tag -width .BEGINx
+.It Ic .BEGIN
+Any command lines attached to this target are executed before anything
+else is done.
+.It Ic .DEFAULT
+This is sort of a
+.Ic .USE
+rule for any target (that was used only as a
+source) that
+.Nm
+can't figure out any other way to create.
+Only the shell script is used.
+The
+.Ic .IMPSRC
+variable of a target that inherits
+.Ic .DEFAULT Ns 's
+commands is set
+to the target's own name.
+.It Ic .END
+Any command lines attached to this target are executed after everything
+else is done.
+.It Ic .ERROR
+Any command lines attached to this target are executed when another target fails.
+The
+.Ic .ERROR_TARGET
+variable is set to the target that failed.
+See also
+.Ic MAKE_PRINT_VAR_ON_ERROR .
+.It Ic .IGNORE
+Mark each of the sources with the
+.Ic .IGNORE
+attribute.
+If no sources are specified, this is the equivalent of specifying the
+.Fl i
+option.
+.It Ic .INTERRUPT
+If
+.Nm
+is interrupted, the commands for this target will be executed.
+.It Ic .MAIN
+If no target is specified when
+.Nm
+is invoked, this target will be built.
+.It Ic .MAKEFLAGS
+This target provides a way to specify flags for
+.Nm
+when the makefile is used.
+The flags are as if typed to the shell, though the
+.Fl f
+option will have
+no effect.
+.\" XXX: NOT YET!!!!
+.\" .It Ic .NOTPARALLEL
+.\" The named targets are executed in non parallel mode.
+.\" If no targets are
+.\" specified, then all targets are executed in non parallel mode.
+.It Ic .NOPATH
+Apply the
+.Ic .NOPATH
+attribute to any specified sources.
+.It Ic .NOTPARALLEL
+Disable parallel mode.
+.It Ic .NO_PARALLEL
+Synonym for
+.Ic .NOTPARALLEL ,
+for compatibility with other pmake variants.
+.It Ic .ORDER
+The named targets are made in sequence.
+This ordering does not add targets to the list of targets to be made.
+Since the dependents of a target do not get built until the target itself
+could be built, unless
+.Ql a
+is built by another part of the dependency graph,
+the following is a dependency loop:
+.Bd -literal
+\&.ORDER: b a
+b: a
+.Ed
+.Pp
+The ordering imposed by
+.Ic .ORDER
+is only relevant for parallel makes.
+.\" XXX: NOT YET!!!!
+.\" .It Ic .PARALLEL
+.\" The named targets are executed in parallel mode.
+.\" If no targets are
+.\" specified, then all targets are executed in parallel mode.
+.It Ic .PATH
+The sources are directories which are to be searched for files not
+found in the current directory.
+If no sources are specified, any previously specified directories are
+deleted.
+If the source is the special
+.Ic .DOTLAST
+target, then the current working
+directory is searched last.
+.It Ic .PHONY
+Apply the
+.Ic .PHONY
+attribute to any specified sources.
+.It Ic .PRECIOUS
+Apply the
+.Ic .PRECIOUS
+attribute to any specified sources.
+If no sources are specified, the
+.Ic .PRECIOUS
+attribute is applied to every
+target in the file.
+.It Ic .SHELL
+Sets the shell that
+.Nm
+will use to execute commands.
+The sources are a set of
+.Ar field=value
+pairs.
+.Bl -tag -width hasErrCtls
+.It Ar name
+This is the minimal specification, used to select one of the builtin
+shell specs;
+.Ar sh ,
+.Ar ksh ,
+and
+.Ar csh .
+.It Ar path
+Specifies the path to the shell.
+.It Ar hasErrCtl
+Indicates whether the shell supports exit on error.
+.It Ar check
+The command to turn on error checking.
+.It Ar ignore
+The command to disable error checking.
+.It Ar echo
+The command to turn on echoing of commands executed.
+.It Ar quiet
+The command to turn off echoing of commands executed.
+.It Ar filter
+The output to filter after issuing the
+.Ar quiet
+command.
+It is typically identical to
+.Ar quiet .
+.It Ar errFlag
+The flag to pass the shell to enable error checking.
+.It Ar echoFlag
+The flag to pass the shell to enable command echoing.
+.It Ar newline
+The string literal to pass the shell that results in a single newline
+character when used outside of any quoting characters.
+.El
+Example:
+.Bd -literal
+\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e
+ check="set \-e" ignore="set +e" \e
+ echo="set \-v" quiet="set +v" filter="set +v" \e
+ echoFlag=v errFlag=e newline="'\en'"
+.Ed
+.It Ic .SILENT
+Apply the
+.Ic .SILENT
+attribute to any specified sources.
+If no sources are specified, the
+.Ic .SILENT
+attribute is applied to every
+command in the file.
+.It Ic .SUFFIXES
+Each source specifies a suffix to
+.Nm .
+If no sources are specified, any previously specified suffixes are deleted.
+It allows the creation of suffix-transformation rules.
+.Pp
+Example:
+.Bd -literal
+\&.SUFFIXES: .o
+\&.c.o:
+ cc \-o ${.TARGET} \-c ${.IMPSRC}
+.Ed
+.El
+.Sh ENVIRONMENT
+.Nm
+uses the following environment variables, if they exist:
+.Ev MACHINE ,
+.Ev MACHINE_ARCH ,
+.Ev MAKE ,
+.Ev MAKEFLAGS ,
+.Ev MAKEOBJDIR ,
+.Ev MAKEOBJDIRPREFIX ,
+.Ev MAKESYSPATH ,
+.Ev PWD ,
+and
+.Ev TMPDIR .
+.Pp
+.Ev MAKEOBJDIRPREFIX
+and
+.Ev MAKEOBJDIR
+may only be set in the environment or on the command line to
+.Nm
+and not as makefile variables;
+see the description of
+.Ql Va .OBJDIR
+for more details.
+.Sh FILES
+.Bl -tag -width /usr/share/mk -compact
+.It .depend
+list of dependencies
+.It Makefile
+list of dependencies
+.It makefile
+list of dependencies
+.It sys.mk
+system makefile
+.It /usr/share/mk
+system makefile directory
+.El
+.Sh COMPATIBILITY
+The basic make syntax is compatible between different versions of make,
+however the special variables, variable modifiers and conditionals are not.
+.Pp
+The way that parallel makes are scheduled changed in
+NetBSD 4.0
+so that .ORDER and .WAIT apply recursively to the dependent nodes.
+The algorithms used may change again in the future.
+.Pp
+The way that .for loop variables are substituted changed after
+NetBSD 5.0
+so that they still appear to be variable expansions.
+In particular this stops them being treated as syntax, and removes some
+obscure problems using them in .if statements.
+.Pp
+Unlike other
+.Nm
+programs, this implementation by default executes all commands for a given
+target using a single shell invocation.
+This is done for both efficiency and to simplify error handling in remote
+command invocations.
+Typically this is transparent to the user, unless the target commands change
+the current working directory using
+.Dq cd
+or
+.Dq chdir .
+To be compatible with Makefiles that do this, one can use
+.Fl B
+to disable this behavior.
+.Sh SEE ALSO
+.Xr mkdep 1
+.Sh HISTORY
+.Nm
+is derived from NetBSD
+.Xr make 1 .
+It uses autoconf to facilitate portability to other platforms.
diff --git a/external/bsd/bmake/dist/bmake.cat1 b/external/bsd/bmake/dist/bmake.cat1
new file mode 100644
index 0000000..7624c43
--- /dev/null
+++ b/external/bsd/bmake/dist/bmake.cat1
@@ -0,0 +1,1305 @@
+MAKE(1) NetBSD General Commands Manual MAKE(1)
+
+NNAAMMEE
+ bbmmaakkee -- maintain program dependencies
+
+SSYYNNOOPPSSIISS
+ bbmmaakkee [--BBeeiikkNNnnqqrrssttWWXX] [--CC _d_i_r_e_c_t_o_r_y] [--DD _v_a_r_i_a_b_l_e] [--dd _f_l_a_g_s]
+ [--ff _m_a_k_e_f_i_l_e] [--II _d_i_r_e_c_t_o_r_y] [--JJ _p_r_i_v_a_t_e] [--jj _m_a_x___j_o_b_s]
+ [--mm _d_i_r_e_c_t_o_r_y] [--TT _f_i_l_e] [--VV _v_a_r_i_a_b_l_e] [_v_a_r_i_a_b_l_e_=_v_a_l_u_e]
+ [_t_a_r_g_e_t _._._.]
+
+DDEESSCCRRIIPPTTIIOONN
+ bbmmaakkee is a program designed to simplify the maintenance of other pro-
+ grams. Its input is a list of specifications as to the files upon which
+ programs and other files depend. If no --ff _m_a_k_e_f_i_l_e makefile option is
+ given, bbmmaakkee will try to open `_m_a_k_e_f_i_l_e' then `_M_a_k_e_f_i_l_e' in order to find
+ the specifications. If the file `_._d_e_p_e_n_d' exists, it is read (see
+ mkdep(1)).
+
+ This manual page is intended as a reference document only. For a more
+ thorough description of bbmmaakkee and makefiles, please refer to _P_M_a_k_e _- _A
+ _T_u_t_o_r_i_a_l.
+
+ bbmmaakkee will prepend the contents of the _M_A_K_E_F_L_A_G_S environment variable to
+ the command line arguments before parsing them.
+
+ The options are as follows:
+
+ --BB Try to be backwards compatible by executing a single shell per
+ command and by executing the commands to make the sources of a
+ dependency line in sequence.
+
+ --CC _d_i_r_e_c_t_o_r_y
+ Change to _d_i_r_e_c_t_o_r_y before reading the makefiles or doing any-
+ thing else. If multiple --CC options are specified, each is inter-
+ preted relative to the previous one: --CC _/ --CC _e_t_c is equivalent to
+ --CC _/_e_t_c.
+
+ --DD _v_a_r_i_a_b_l_e
+ Define _v_a_r_i_a_b_l_e to be 1, in the global context.
+
+ --dd _[_-_]_f_l_a_g_s
+ Turn on debugging, and specify which portions of bbmmaakkee are to
+ print debugging information. Unless the flags are preceded by
+ `-' they are added to the _M_A_K_E_F_L_A_G_S environment variable and will
+ be processed by any child make processes. By default, debugging
+ information is printed to standard error, but this can be changed
+ using the _F debugging flag. The debugging output is always
+ unbuffered; in addition, if debugging is enabled but debugging
+ output is not directed to standard output, then the standard out-
+ put is line buffered. _F_l_a_g_s is one or more of the following:
+
+ _A Print all possible debugging information; equivalent to
+ specifying all of the debugging flags.
+
+ _a Print debugging information about archive searching and
+ caching.
+
+ _C Print debugging information about current working direc-
+ tory.
+
+ _c Print debugging information about conditional evaluation.
+
+ _d Print debugging information about directory searching and
+ caching.
+
+ _e Print debugging information about failed commands and
+ targets.
+
+ _F[++]_f_i_l_e_n_a_m_e
+ Specify where debugging output is written. This must be
+ the last flag, because it consumes the remainder of the
+ argument. If the character immediately after the `F'
+ flag is `+', then the file will be opened in append mode;
+ otherwise the file will be overwritten. If the file name
+ is `stdout' or `stderr' then debugging output will be
+ written to the standard output or standard error output
+ file descriptors respectively (and the `+' option has no
+ effect). Otherwise, the output will be written to the
+ named file. If the file name ends `.%d' then the `%d' is
+ replaced by the pid.
+
+ _f Print debugging information about loop evaluation.
+
+ _g_1 Print the input graph before making anything.
+
+ _g_2 Print the input graph after making everything, or before
+ exiting on error.
+
+ _g_3 Print the input graph before exiting on error.
+
+ _j Print debugging information about running multiple
+ shells.
+
+ _l Print commands in Makefiles regardless of whether or not
+ they are prefixed by `@' or other "quiet" flags. Also
+ known as "loud" behavior.
+
+ _M Print debugging information about "meta" mode decisions
+ about targets.
+
+ _m Print debugging information about making targets, includ-
+ ing modification dates.
+
+ _n Don't delete the temporary command scripts created when
+ running commands. These temporary scripts are created in
+ the directory referred to by the TMPDIR environment vari-
+ able, or in _/_t_m_p if TMPDIR is unset or set to the empty
+ string. The temporary scripts are created by mkstemp(3),
+ and have names of the form _m_a_k_e_X_X_X_X_X_X. _N_O_T_E: This can
+ create many files in TMPDIR or _/_t_m_p, so use with care.
+
+ _p Print debugging information about makefile parsing.
+
+ _s Print debugging information about suffix-transformation
+ rules.
+
+ _t Print debugging information about target list mainte-
+ nance.
+
+ _v Print debugging information about variable assignment.
+
+ _x Run shell commands with --xx so the actual commands are
+ printed as they are executed.
+
+ --ee Specify that environment variables override macro assignments
+ within makefiles.
+
+ --ff _m_a_k_e_f_i_l_e
+ Specify a makefile to read instead of the default `_m_a_k_e_f_i_l_e'. If
+ _m_a_k_e_f_i_l_e is `--', standard input is read. Multiple makefiles may
+ be specified, and are read in the order specified.
+
+ --II _d_i_r_e_c_t_o_r_y
+ Specify a directory in which to search for makefiles and included
+ makefiles. The system makefile directory (or directories, see
+ the --mm option) is automatically included as part of this list.
+
+ --ii Ignore non-zero exit of shell commands in the makefile. Equiva-
+ lent to specifying `--' before each command line in the makefile.
+
+ --JJ _p_r_i_v_a_t_e
+ This option should _n_o_t be specified by the user.
+
+ When the _j option is in use in a recursive build, this option is
+ passed by a make to child makes to allow all the make processes
+ in the build to cooperate to avoid overloading the system.
+
+ --jj _m_a_x___j_o_b_s
+ Specify the maximum number of jobs that bbmmaakkee may have running at
+ any one time. The value is saved in _._M_A_K_E_._J_O_B_S. Turns compati-
+ bility mode off, unless the _B flag is also specified. When com-
+ patibility mode is off, all commands associated with a target are
+ executed in a single shell invocation as opposed to the tradi-
+ tional one shell invocation per line. This can break traditional
+ scripts which change directories on each command invocation and
+ then expect to start with a fresh environment on the next line.
+ It is more efficient to correct the scripts rather than turn
+ backwards compatibility on.
+
+ --kk Continue processing after errors are encountered, but only on
+ those targets that do not depend on the target whose creation
+ caused the error.
+
+ --mm _d_i_r_e_c_t_o_r_y
+ Specify a directory in which to search for sys.mk and makefiles
+ included via the <_f_i_l_e>-style include statement. The --mm option
+ can be used multiple times to form a search path. This path will
+ override the default system include path: /usr/share/mk. Fur-
+ thermore the system include path will be appended to the search
+ path used for "_f_i_l_e"-style include statements (see the --II
+ option).
+
+ If a file or directory name in the --mm argument (or the
+ MAKESYSPATH environment variable) starts with the string ".../"
+ then bbmmaakkee will search for the specified file or directory named
+ in the remaining part of the argument string. The search starts
+ with the current directory of the Makefile and then works upward
+ towards the root of the filesystem. If the search is successful,
+ then the resulting directory replaces the ".../" specification in
+ the --mm argument. If used, this feature allows bbmmaakkee to easily
+ search in the current source tree for customized sys.mk files
+ (e.g., by using ".../mk/sys.mk" as an argument).
+
+ --nn Display the commands that would have been executed, but do not
+ actually execute them unless the target depends on the .MAKE spe-
+ cial source (see below).
+
+ --NN Display the commands which would have been executed, but do not
+ actually execute any of them; useful for debugging top-level
+ makefiles without descending into subdirectories.
+
+ --qq Do not execute any commands, but exit 0 if the specified targets
+ are up-to-date and 1, otherwise.
+
+ --rr Do not use the built-in rules specified in the system makefile.
+
+ --ss Do not echo any commands as they are executed. Equivalent to
+ specifying `@@' before each command line in the makefile.
+
+ --TT _t_r_a_c_e_f_i_l_e
+ When used with the --jj flag, append a trace record to _t_r_a_c_e_f_i_l_e
+ for each job started and completed.
+
+ --tt Rather than re-building a target as specified in the makefile,
+ create it or update its modification time to make it appear up-
+ to-date.
+
+ --VV _v_a_r_i_a_b_l_e
+ Print bbmmaakkee's idea of the value of _v_a_r_i_a_b_l_e, in the global con-
+ text. Do not build any targets. Multiple instances of this
+ option may be specified; the variables will be printed one per
+ line, with a blank line for each null or undefined variable. If
+ _v_a_r_i_a_b_l_e contains a `$' then the value will be expanded before
+ printing.
+
+ --WW Treat any warnings during makefile parsing as errors.
+
+ --XX Don't export variables passed on the command line to the environ-
+ ment individually. Variables passed on the command line are
+ still exported via the _M_A_K_E_F_L_A_G_S environment variable. This
+ option may be useful on systems which have a small limit on the
+ size of command arguments.
+
+ _v_a_r_i_a_b_l_e_=_v_a_l_u_e
+ Set the value of the variable _v_a_r_i_a_b_l_e to _v_a_l_u_e. Normally, all
+ values passed on the command line are also exported to sub-makes
+ in the environment. The --XX flag disables this behavior. Vari-
+ able assignments should follow options for POSIX compatibility
+ but no ordering is enforced.
+
+ There are seven different types of lines in a makefile: file dependency
+ specifications, shell commands, variable assignments, include statements,
+ conditional directives, for loops, and comments.
+
+ In general, lines may be continued from one line to the next by ending
+ them with a backslash (`\'). The trailing newline character and initial
+ whitespace on the following line are compressed into a single space.
+
+FFIILLEE DDEEPPEENNDDEENNCCYY SSPPEECCIIFFIICCAATTIIOONNSS
+ Dependency lines consist of one or more targets, an operator, and zero or
+ more sources. This creates a relationship where the targets ``depend''
+ on the sources and are usually created from them. The exact relationship
+ between the target and the source is determined by the operator that sep-
+ arates them. The three operators are as follows:
+
+ :: A target is considered out-of-date if its modification time is less
+ than those of any of its sources. Sources for a target accumulate
+ over dependency lines when this operator is used. The target is
+ removed if bbmmaakkee is interrupted.
+
+ !! Targets are always re-created, but not until all sources have been
+ examined and re-created as necessary. Sources for a target accumu-
+ late over dependency lines when this operator is used. The target
+ is removed if bbmmaakkee is interrupted.
+
+ :::: If no sources are specified, the target is always re-created. Oth-
+ erwise, a target is considered out-of-date if any of its sources
+ has been modified more recently than the target. Sources for a
+ target do not accumulate over dependency lines when this operator
+ is used. The target will not be removed if bbmmaakkee is interrupted.
+
+ Targets and sources may contain the shell wildcard values `?', `*', `[]',
+ and `{}'. The values `?', `*', and `[]' may only be used as part of the
+ final component of the target or source, and must be used to describe
+ existing files. The value `{}' need not necessarily be used to describe
+ existing files. Expansion is in directory order, not alphabetically as
+ done in the shell.
+
+SSHHEELLLL CCOOMMMMAANNDDSS
+ Each target may have associated with it a series of shell commands, nor-
+ mally used to create the target. Each of the commands in this script
+ _m_u_s_t be preceded by a tab. While any target may appear on a dependency
+ line, only one of these dependencies may be followed by a creation
+ script, unless the `::::' operator is used.
+
+ If the first characters of the command line are any combination of `@@',
+ `++', or `--', the command is treated specially. A `@@' causes the command
+ not to be echoed before it is executed. A `++' causes the command to be
+ executed even when --nn is given. This is similar to the effect of the
+ .MAKE special source, except that the effect can be limited to a single
+ line of a script. A `--' causes any non-zero exit status of the command
+ line to be ignored.
+
+VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
+ Variables in make are much like variables in the shell, and, by tradi-
+ tion, consist of all upper-case letters.
+
+ VVaarriiaabbllee aassssiiggnnmmeenntt mmooddiiffiieerrss
+ The five operators that can be used to assign values to variables are as
+ follows:
+
+ == Assign the value to the variable. Any previous value is overrid-
+ den.
+
+ ++== Append the value to the current value of the variable.
+
+ ??== Assign the value to the variable if it is not already defined.
+
+ ::== Assign with expansion, i.e. expand the value before assigning it
+ to the variable. Normally, expansion is not done until the vari-
+ able is referenced. _N_O_T_E: References to undefined variables are
+ _n_o_t expanded. This can cause problems when variable modifiers
+ are used.
+
+ !!== Expand the value and pass it to the shell for execution and
+ assign the result to the variable. Any newlines in the result
+ are replaced with spaces.
+
+ Any white-space before the assigned _v_a_l_u_e is removed; if the value is
+ being appended, a single space is inserted between the previous contents
+ of the variable and the appended value.
+
+ Variables are expanded by surrounding the variable name with either curly
+ braces (`{}') or parentheses (`()') and preceding it with a dollar sign
+ (`$'). If the variable name contains only a single letter, the surround-
+ ing braces or parentheses are not required. This shorter form is not
+ recommended.
+
+ If the variable name contains a dollar, then the name itself is expanded
+ first. This allows almost arbitrary variable names, however names con-
+ taining dollar, braces, parenthesis, or whitespace are really best
+ avoided!
+
+ If the result of expanding a variable contains a dollar sign (`$') the
+ string is expanded again.
+
+ Variable substitution occurs at three distinct times, depending on where
+ the variable is being used.
+
+ 1. Variables in dependency lines are expanded as the line is read.
+
+ 2. Variables in shell commands are expanded when the shell command is
+ executed.
+
+ 3. ``.for'' loop index variables are expanded on each loop iteration.
+ Note that other variables are not expanded inside loops so the fol-
+ lowing example code:
+
+
+ .for i in 1 2 3
+ a+= ${i}
+ j= ${i}
+ b+= ${j}
+ .endfor
+
+ all:
+ @echo ${a}
+ @echo ${b}
+
+ will print:
+
+ 1 2 3
+ 3 3 3
+
+ Because while ${a} contains ``1 2 3'' after the loop is executed,
+ ${b} contains ``${j} ${j} ${j}'' which expands to ``3 3 3'' since
+ after the loop completes ${j} contains ``3''.
+
+ VVaarriiaabbllee ccllaasssseess
+ The four different classes of variables (in order of increasing prece-
+ dence) are:
+
+ Environment variables
+ Variables defined as part of bbmmaakkee's environment.
+
+ Global variables
+ Variables defined in the makefile or in included makefiles.
+
+ Command line variables
+ Variables defined as part of the command line.
+
+ Local variables
+ Variables that are defined specific to a certain target. The
+ seven local variables are as follows:
+
+ _._A_L_L_S_R_C The list of all sources for this target; also known as
+ `_>'.
+
+ _._A_R_C_H_I_V_E The name of the archive file.
+
+ _._I_M_P_S_R_C In suffix-transformation rules, the name/path of the
+ source from which the target is to be transformed (the
+ ``implied'' source); also known as `_<'. It is not
+ defined in explicit rules.
+
+ _._M_E_M_B_E_R The name of the archive member.
+
+ _._O_O_D_A_T_E The list of sources for this target that were deemed
+ out-of-date; also known as `_?'.
+
+ _._P_R_E_F_I_X The file prefix of the target, containing only the file
+ portion, no suffix or preceding directory components;
+ also known as `_*'.
+
+ _._T_A_R_G_E_T The name of the target; also known as `_@'.
+
+ The shorter forms `_@', `_?', `_<', `_>', and `_*' are permitted for
+ backward compatibility with historical makefiles and are not rec-
+ ommended. The six variables `_@_F', `_@_D', `_<_F', `_<_D', `_*_F', and
+ `_*_D' are permitted for compatibility with AT&T System V UNIX
+ makefiles and are not recommended.
+
+ Four of the local variables may be used in sources on dependency
+ lines because they expand to the proper value for each target on
+ the line. These variables are `_._T_A_R_G_E_T', `_._P_R_E_F_I_X', `_._A_R_C_H_I_V_E',
+ and `_._M_E_M_B_E_R'.
+
+ AAddddiittiioonnaall bbuuiilltt--iinn vvaarriiaabblleess
+ In addition, bbmmaakkee sets or knows about the following variables:
+
+ _$ A single dollar sign `$', i.e. `$$' expands to a single
+ dollar sign.
+
+ _._A_L_L_T_A_R_G_E_T_S The list of all targets encountered in the Makefile. If
+ evaluated during Makefile parsing, lists only those tar-
+ gets encountered thus far.
+
+ _._C_U_R_D_I_R A path to the directory where bbmmaakkee was executed. Refer
+ to the description of `PWD' for more details.
+
+ MAKE The name that bbmmaakkee was executed with (_a_r_g_v_[_0_]). For
+ compatibility bbmmaakkee also sets _._M_A_K_E with the same value.
+ The preferred variable to use is the environment variable
+ MAKE because it is more compatible with other versions of
+ bbmmaakkee and cannot be confused with the special target with
+ the same name.
+
+ _._M_A_K_E_._D_E_P_E_N_D_F_I_L_E
+ Names the makefile (default `_._d_e_p_e_n_d') from which gener-
+ ated dependencies are read.
+
+ _._M_A_K_E_._E_X_P_O_R_T_E_D The list of variables exported by bbmmaakkee.
+
+ _._M_A_K_E_._J_O_B_S The argument to the --jj option.
+
+ _._M_A_K_E_._J_O_B_._P_R_E_F_I_X
+ If bbmmaakkee is run with _j then output for each target is
+ prefixed with a token `--- target ---' the first part of
+ which can be controlled via _._M_A_K_E_._J_O_B_._P_R_E_F_I_X.
+ For example:
+ .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}]
+ would produce tokens like `---make[1234] target ---' mak-
+ ing it easier to track the degree of parallelism being
+ achieved.
+
+ MAKEFLAGS The environment variable `MAKEFLAGS' may contain anything
+ that may be specified on bbmmaakkee's command line. Anything
+ specified on bbmmaakkee's command line is appended to the
+ `MAKEFLAGS' variable which is then entered into the envi-
+ ronment for all programs which bbmmaakkee executes.
+
+ _._M_A_K_E_._L_E_V_E_L The recursion depth of bbmmaakkee. The initial instance of
+ bbmmaakkee will be 0, and an incremented value is put into the
+ environment to be seen by the next generation. This
+ allows tests like: .if ${.MAKE.LEVEL} == 0 to protect
+ things which should only be evaluated in the initial
+ instance of bbmmaakkee.
+
+ _._M_A_K_E_._M_A_K_E_F_I_L_E___P_R_E_F_E_R_E_N_C_E
+ The ordered list of makefile names (default `_m_a_k_e_f_i_l_e',
+ `_M_a_k_e_f_i_l_e') that bbmmaakkee will look for.
+
+ _._M_A_K_E_._M_A_K_E_F_I_L_E_S
+ The list of makefiles read by bbmmaakkee, which is useful for
+ tracking dependencies. Each makefile is recorded only
+ once, regardless of the number of times read.
+
+ _._M_A_K_E_._M_O_D_E Processed after reading all makefiles. Can affect the
+ mode that bbmmaakkee runs in. It can contain a number of key-
+ words:
+
+ _c_o_m_p_a_t Like --BB, puts bbmmaakkee into "compat" mode.
+
+ _m_e_t_a Puts bbmmaakkee into "meta" mode, where meta files
+ are created for each target to capture the
+ command run, the output generated and if
+ filemon(4) is available, the system calls
+ which are of interest to bbmmaakkee. The captured
+ output can be very useful when diagnosing
+ errors.
+
+ _c_u_r_d_i_r_O_k_= _b_f Normally bbmmaakkee will not create .meta files
+ in `_._C_U_R_D_I_R'. This can be overridden by set-
+ ting _b_f to a value which represents True.
+
+ _e_n_v For debugging, it can be useful to inlcude
+ the environment in the .meta file.
+
+ _v_e_r_b_o_s_e If in "meta" mode, print a clue about the
+ target being built. This is useful if the
+ build is otherwise running silently. The
+ message printed the value of:
+ _._M_A_K_E_._M_E_T_A_._P_R_E_F_I_X.
+
+ _i_g_n_o_r_e_-_c_m_d Some makefiles have commands which are simply
+ not stable. This keyword causes them to be
+ ignored for determining whether a target is
+ out of date in "meta" mode. See also
+ ..NNOOMMEETTAA__CCMMPP.
+
+ _s_i_l_e_n_t_= _b_f If _b_f is True, when a .meta file is created,
+ mark the target ..SSIILLEENNTT.
+
+ _._M_A_K_E_._M_E_T_A_._B_A_I_L_I_W_I_C_K
+ In "meta" mode, provides a list of prefixes which match
+ the directories controlled by bbmmaakkee. If a file that was
+ generated outside of _._O_B_J_D_I_R but within said bailiwick is
+ missing, the current target is considered out-of-date.
+
+ _._M_A_K_E_._M_E_T_A_._C_R_E_A_T_E_D
+ In "meta" mode, this variable contains a list of all the
+ meta files updated. If not empty, it can be used to
+ trigger processing of _._M_A_K_E_._M_E_T_A_._F_I_L_E_S.
+
+ _._M_A_K_E_._M_E_T_A_._F_I_L_E_S
+ In "meta" mode, this variable contains a list of all the
+ meta files used (updated or not). This list can be used
+ to process the meta files to extract dependency informa-
+ tion.
+
+ _._M_A_K_E_._M_E_T_A_._P_R_E_F_I_X
+ Defines the message printed for each meta file updated in
+ "meta verbose" mode. The default value is:
+ Building ${.TARGET:H:tA}/${.TARGET:T}
+
+ _._M_A_K_E_O_V_E_R_R_I_D_E_S This variable is used to record the names of variables
+ assigned to on the command line, so that they may be
+ exported as part of `MAKEFLAGS'. This behaviour can be
+ disabled by assigning an empty value to `_._M_A_K_E_O_V_E_R_R_I_D_E_S'
+ within a makefile. Extra variables can be exported from
+ a makefile by appending their names to `_._M_A_K_E_O_V_E_R_R_I_D_E_S'.
+ `MAKEFLAGS' is re-exported whenever `_._M_A_K_E_O_V_E_R_R_I_D_E_S' is
+ modified.
+
+ _._M_A_K_E_._P_I_D The process-id of bbmmaakkee.
+
+ _._M_A_K_E_._P_P_I_D The parent process-id of bbmmaakkee.
+
+ _M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R
+ When bbmmaakkee stops due to an error, it prints its name and
+ the value of `_._C_U_R_D_I_R' as well as the value of any vari-
+ ables named in `_M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R'.
+
+ _._n_e_w_l_i_n_e This variable is simply assigned a newline character as
+ its value. This allows expansions using the ::@@ modifier
+ to put a newline between iterations of the loop rather
+ than a space. For example, the printing of
+ `_M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R' could be done as
+ ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}.
+
+ _._O_B_J_D_I_R A path to the directory where the targets are built. Its
+ value is determined by trying to chdir(2) to the follow-
+ ing directories in order and using the first match:
+
+ 1. ${MAKEOBJDIRPREFIX}${.CURDIR}
+
+ (Only if `MAKEOBJDIRPREFIX' is set in the environ-
+ ment or on the command line.)
+
+ 2. ${MAKEOBJDIR}
+
+ (Only if `MAKEOBJDIR' is set in the environment or
+ on the command line.)
+
+ 3. ${.CURDIR}_/_o_b_j_.${MACHINE}
+
+ 4. ${.CURDIR}_/_o_b_j
+
+ 5. _/_u_s_r_/_o_b_j_/${.CURDIR}
+
+ 6. ${.CURDIR}
+
+ Variable expansion is performed on the value before it's
+ used, so expressions such as
+ ${.CURDIR:S,^/usr/src,/var/obj,}
+ may be used. This is especially useful with
+ `MAKEOBJDIR'.
+
+ `_._O_B_J_D_I_R' may be modified in the makefile as a global
+ variable. In all cases, bbmmaakkee will chdir(2) to `_._O_B_J_D_I_R'
+ and set `PWD' to that directory before executing any tar-
+ gets.
+
+ _._P_A_R_S_E_D_I_R A path to the directory of the current `_M_a_k_e_f_i_l_e' being
+ parsed.
+
+ _._P_A_R_S_E_F_I_L_E The basename of the current `_M_a_k_e_f_i_l_e' being parsed.
+ This variable and `_._P_A_R_S_E_D_I_R' are both set only while the
+ `_M_a_k_e_f_i_l_e_s' are being parsed. If you want to retain
+ their current values, assign them to a variable using
+ assignment with expansion: (`::==').
+
+ _._P_A_T_H A variable that represents the list of directories that
+ bbmmaakkee will search for files. The search list should be
+ updated using the target `_._P_A_T_H' rather than the vari-
+ able.
+
+ PWD Alternate path to the current directory. bbmmaakkee normally
+ sets `_._C_U_R_D_I_R' to the canonical path given by getcwd(3).
+ However, if the environment variable `PWD' is set and
+ gives a path to the current directory, then bbmmaakkee sets
+ `_._C_U_R_D_I_R' to the value of `PWD' instead. This behaviour
+ is disabled if `MAKEOBJDIRPREFIX' is set or `MAKEOBJDIR'
+ contains a variable transform. `PWD' is set to the value
+ of `_._O_B_J_D_I_R' for all programs which bbmmaakkee executes.
+
+ .TARGETS The list of targets explicitly specified on the command
+ line, if any.
+
+ VPATH Colon-separated (``:'') lists of directories that bbmmaakkee
+ will search for files. The variable is supported for
+ compatibility with old make programs only, use `_._P_A_T_H'
+ instead.
+
+ VVaarriiaabbllee mmooddiiffiieerrss
+ Variable expansion may be modified to select or modify each word of the
+ variable (where a ``word'' is white-space delimited sequence of charac-
+ ters). The general format of a variable expansion is as follows:
+
+ ${variable[:modifier[:...]]}
+
+ Each modifier begins with a colon, which may be escaped with a backslash
+ (`\').
+
+ A set of modifiers can be specified via a variable, as follows:
+
+ modifier_variable=modifier[:...]
+ ${variable:${modifier_variable}[:...]}
+
+ In this case the first modifier in the modifier_variable does not start
+ with a colon, since that must appear in the referencing variable. If any
+ of the modifiers in the modifier_variable contain a dollar sign (`$'),
+ these must be doubled to avoid early expansion.
+
+ The supported modifiers are:
+
+ ::EE Replaces each word in the variable with its suffix.
+
+ ::HH Replaces each word in the variable with everything but the last com-
+ ponent.
+
+ ::MM_p_a_t_t_e_r_n
+ Select only those words that match _p_a_t_t_e_r_n. The standard shell
+ wildcard characters (`*', `?', and `[]') may be used. The wildcard
+ characters may be escaped with a backslash (`\').
+
+ ::NN_p_a_t_t_e_r_n
+ This is identical to `::MM', but selects all words which do not match
+ _p_a_t_t_e_r_n.
+
+ ::OO Order every word in variable alphabetically. To sort words in
+ reverse order use the `::OO::[[--11....11]]' combination of modifiers.
+
+ ::OOxx Randomize words in variable. The results will be different each
+ time you are referring to the modified variable; use the assignment
+ with expansion (`::==') to prevent such behaviour. For example,
+
+ LIST= uno due tre quattro
+ RANDOM_LIST= ${LIST:Ox}
+ STATIC_RANDOM_LIST:= ${LIST:Ox}
+
+ all:
+ @echo "${RANDOM_LIST}"
+ @echo "${RANDOM_LIST}"
+ @echo "${STATIC_RANDOM_LIST}"
+ @echo "${STATIC_RANDOM_LIST}"
+ may produce output similar to:
+
+ quattro due tre uno
+ tre due quattro uno
+ due uno quattro tre
+ due uno quattro tre
+
+ ::QQ Quotes every shell meta-character in the variable, so that it can be
+ passed safely through recursive invocations of bbmmaakkee.
+
+ ::RR Replaces each word in the variable with everything but its suffix.
+
+ ::ggmmttiimmee
+ The value is a format string for strftime(3), using the current
+ gmtime(3).
+
+ ::hhaasshh
+ Compute a 32bit hash of the value and encode it as hex digits.
+
+ ::llooccaallttiimmee
+ The value is a format string for strftime(3), using the current
+ localtime(3).
+
+ ::ttAA Attempt to convert variable to an absolute path using realpath(3),
+ if that fails, the value is unchanged.
+
+ ::ttll Converts variable to lower-case letters.
+
+ ::ttss_c
+ Words in the variable are normally separated by a space on expan-
+ sion. This modifier sets the separator to the character _c. If _c is
+ omitted, then no separator is used. The common escapes (including
+ octal numeric codes), work as expected.
+
+ ::ttuu Converts variable to upper-case letters.
+
+ ::ttWW Causes the value to be treated as a single word (possibly containing
+ embedded white space). See also `::[[**]]'.
+
+ ::ttww Causes the value to be treated as a sequence of words delimited by
+ white space. See also `::[[@@]]'.
+
+ ::SS/_o_l_d___s_t_r_i_n_g/_n_e_w___s_t_r_i_n_g/[11ggWW]
+ Modify the first occurrence of _o_l_d___s_t_r_i_n_g in the variable's value,
+ replacing it with _n_e_w___s_t_r_i_n_g. If a `g' is appended to the last
+ slash of the pattern, all occurrences in each word are replaced. If
+ a `1' is appended to the last slash of the pattern, only the first
+ word is affected. If a `W' is appended to the last slash of the
+ pattern, then the value is treated as a single word (possibly con-
+ taining embedded white space). If _o_l_d___s_t_r_i_n_g begins with a caret
+ (`^'), _o_l_d___s_t_r_i_n_g is anchored at the beginning of each word. If
+ _o_l_d___s_t_r_i_n_g ends with a dollar sign (`$'), it is anchored at the end
+ of each word. Inside _n_e_w___s_t_r_i_n_g, an ampersand (`&') is replaced by
+ _o_l_d___s_t_r_i_n_g (without any `^' or `$'). Any character may be used as a
+ delimiter for the parts of the modifier string. The anchoring,
+ ampersand and delimiter characters may be escaped with a backslash
+ (`\').
+
+ Variable expansion occurs in the normal fashion inside both
+ _o_l_d___s_t_r_i_n_g and _n_e_w___s_t_r_i_n_g with the single exception that a backslash
+ is used to prevent the expansion of a dollar sign (`$'), not a pre-
+ ceding dollar sign as is usual.
+
+ ::CC/_p_a_t_t_e_r_n/_r_e_p_l_a_c_e_m_e_n_t/[11ggWW]
+ The ::CC modifier is just like the ::SS modifier except that the old and
+ new strings, instead of being simple strings, are a regular expres-
+ sion (see regex(3)) string _p_a_t_t_e_r_n and an ed(1)-style string
+ _r_e_p_l_a_c_e_m_e_n_t. Normally, the first occurrence of the pattern _p_a_t_t_e_r_n
+ in each word of the value is substituted with _r_e_p_l_a_c_e_m_e_n_t. The `1'
+ modifier causes the substitution to apply to at most one word; the
+ `g' modifier causes the substitution to apply to as many instances
+ of the search pattern _p_a_t_t_e_r_n as occur in the word or words it is
+ found in; the `W' modifier causes the value to be treated as a sin-
+ gle word (possibly containing embedded white space). Note that `1'
+ and `g' are orthogonal; the former specifies whether multiple words
+ are potentially affected, the latter whether multiple substitutions
+ can potentially occur within each affected word.
+
+ ::TT Replaces each word in the variable with its last component.
+
+ ::uu Remove adjacent duplicate words (like uniq(1)).
+
+ ::??_t_r_u_e___s_t_r_i_n_g::_f_a_l_s_e___s_t_r_i_n_g
+ If the variable name (not its value), when parsed as a .if condi-
+ tional expression, evaluates to true, return as its value the
+ _t_r_u_e___s_t_r_i_n_g, otherwise return the _f_a_l_s_e___s_t_r_i_n_g. Since the variable
+ name is used as the expression, :? must be the first modifier after
+ the variable name itself - which will, of course, usually contain
+ variable expansions. A common error is trying to use expressions
+ like
+ ${NUMBERS:M42:?match:no}
+ which actually tests defined(NUMBERS), to determine is any words
+ match "42" you need to use something like:
+ ${"${NUMBERS:M42}" != "":?match:no}.
+
+ _:_o_l_d___s_t_r_i_n_g_=_n_e_w___s_t_r_i_n_g
+ This is the AT&T System V UNIX style variable substitution. It must
+ be the last modifier specified. If _o_l_d___s_t_r_i_n_g or _n_e_w___s_t_r_i_n_g do not
+ contain the pattern matching character _% then it is assumed that
+ they are anchored at the end of each word, so only suffixes or
+ entire words may be replaced. Otherwise _% is the substring of
+ _o_l_d___s_t_r_i_n_g to be replaced in _n_e_w___s_t_r_i_n_g.
+
+ Variable expansion occurs in the normal fashion inside both
+ _o_l_d___s_t_r_i_n_g and _n_e_w___s_t_r_i_n_g with the single exception that a backslash
+ is used to prevent the expansion of a dollar sign (`$'), not a pre-
+ ceding dollar sign as is usual.
+
+ ::@@_t_e_m_p@@_s_t_r_i_n_g@@
+ This is the loop expansion mechanism from the OSF Development Envi-
+ ronment (ODE) make. Unlike ..ffoorr loops expansion occurs at the time
+ of reference. Assign _t_e_m_p to each word in the variable and evaluate
+ _s_t_r_i_n_g. The ODE convention is that _t_e_m_p should start and end with a
+ period. For example.
+ ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
+
+ However a single character varaiable is often more readable:
+ ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
+
+ ::UU_n_e_w_v_a_l
+ If the variable is undefined _n_e_w_v_a_l is the value. If the variable
+ is defined, the existing value is returned. This is another ODE
+ make feature. It is handy for setting per-target CFLAGS for
+ instance:
+ ${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}}
+ If a value is only required if the variable is undefined, use:
+ ${VAR:D:Unewval}
+
+ ::DD_n_e_w_v_a_l
+ If the variable is defined _n_e_w_v_a_l is the value.
+
+ ::LL The name of the variable is the value.
+
+ ::PP The path of the node which has the same name as the variable is the
+ value. If no such node exists or its path is null, then the name of
+ the variable is used. In order for this modifier to work, the name
+ (node) must at least have appeared on the rhs of a dependency.
+
+ ::!!_c_m_d!!
+ The output of running _c_m_d is the value.
+
+ ::sshh If the variable is non-empty it is run as a command and the output
+ becomes the new value.
+
+ ::::==_s_t_r
+ The variable is assigned the value _s_t_r after substitution. This
+ modifier and its variations are useful in obscure situations such as
+ wanting to set a variable when shell commands are being parsed.
+ These assignment modifiers always expand to nothing, so if appearing
+ in a rule line by themselves should be preceded with something to
+ keep bbmmaakkee happy.
+
+ The `::::' helps avoid false matches with the AT&T System V UNIX style
+ ::== modifier and since substitution always occurs the ::::== form is
+ vaguely appropriate.
+
+ ::::??==_s_t_r
+ As for ::::== but only if the variable does not already have a value.
+
+ ::::++==_s_t_r
+ Append _s_t_r to the variable.
+
+ ::::!!==_c_m_d
+ Assign the output of _c_m_d to the variable.
+
+ ::[[_r_a_n_g_e]]
+ Selects one or more words from the value, or performs other opera-
+ tions related to the way in which the value is divided into words.
+
+ Ordinarily, a value is treated as a sequence of words delimited by
+ white space. Some modifiers suppress this behaviour, causing a
+ value to be treated as a single word (possibly containing embedded
+ white space). An empty value, or a value that consists entirely of
+ white-space, is treated as a single word. For the purposes of the
+ `::[[]]' modifier, the words are indexed both forwards using positive
+ integers (where index 1 represents the first word), and backwards
+ using negative integers (where index -1 represents the last word).
+
+ The _r_a_n_g_e is subjected to variable expansion, and the expanded
+ result is then interpreted as follows:
+
+ _i_n_d_e_x Selects a single word from the value.
+
+ _s_t_a_r_t...._e_n_d
+ Selects all words from _s_t_a_r_t to _e_n_d, inclusive. For example,
+ `::[[22....--11]]' selects all words from the second word to the last
+ word. If _s_t_a_r_t is greater than _e_n_d, then the words are out-
+ put in reverse order. For example, `::[[--11....11]]' selects all
+ the words from last to first.
+
+ ** Causes subsequent modifiers to treat the value as a single
+ word (possibly containing embedded white space). Analogous
+ to the effect of "$*" in Bourne shell.
+
+ 0 Means the same as `::[[**]]'.
+
+ @@ Causes subsequent modifiers to treat the value as a sequence
+ of words delimited by white space. Analogous to the effect
+ of "$@" in Bourne shell.
+
+ ## Returns the number of words in the value.
+
+IINNCCLLUUDDEE SSTTAATTEEMMEENNTTSS,, CCOONNDDIITTIIOONNAALLSS AANNDD FFOORR LLOOOOPPSS
+ Makefile inclusion, conditional structures and for loops reminiscent of
+ the C programming language are provided in bbmmaakkee. All such structures
+ are identified by a line beginning with a single dot (`.') character.
+ Files are included with either ..iinncclluuddee <_f_i_l_e> or ..iinncclluuddee "_f_i_l_e". Vari-
+ ables between the angle brackets or double quotes are expanded to form
+ the file name. If angle brackets are used, the included makefile is
+ expected to be in the system makefile directory. If double quotes are
+ used, the including makefile's directory and any directories specified
+ using the --II option are searched before the system makefile directory.
+ For compatibility with other versions of bbmmaakkee `include file ...' is also
+ accepted. If the include statement is written as ..--iinncclluuddee or as
+ ..ssiinncclluuddee then errors locating and/or opening include files are ignored.
+
+ Conditional expressions are also preceded by a single dot as the first
+ character of a line. The possible conditionals are as follows:
+
+ ..eerrrroorr _m_e_s_s_a_g_e
+ The message is printed along with the name of the makefile and
+ line number, then bbmmaakkee will exit.
+
+ ..eexxppoorrtt _v_a_r_i_a_b_l_e _._._.
+ Export the specified global variable. If no variable list is
+ provided, all globals are exported except for internal variables
+ (those that start with `.'). This is not affected by the --XX
+ flag, so should be used with caution. For compatibility with
+ other bbmmaakkee programs `export variable=value' is also accepted.
+
+ Appending a variable name to _._M_A_K_E_._E_X_P_O_R_T_E_D is equivalent to
+ exporting a variable.
+
+ ..eexxppoorrtt--eennvv _v_a_r_i_a_b_l_e _._._.
+ The same as `.export', except that the variable is not appended
+ to _._M_A_K_E_._E_X_P_O_R_T_E_D. This allows exporting a value to the environ-
+ ment which is different from that used by bbmmaakkee internally.
+
+ ..iinnffoo _m_e_s_s_a_g_e
+ The message is printed along with the name of the makefile and
+ line number.
+
+ ..uunnddeeff _v_a_r_i_a_b_l_e
+ Un-define the specified global variable. Only global variables
+ may be un-defined.
+
+ ..uunneexxppoorrtt _v_a_r_i_a_b_l_e _._._.
+ The opposite of `.export'. The specified global _v_a_r_i_a_b_l_e will be
+ removed from _._M_A_K_E_._E_X_P_O_R_T_E_D. If no variable list is provided,
+ all globals are unexported, and _._M_A_K_E_._E_X_P_O_R_T_E_D deleted.
+
+ ..uunneexxppoorrtt--eennvv
+ Unexport all globals previously exported and clear the environ-
+ ment inherited from the parent. This operation will cause a mem-
+ ory leak of the original environment, so should be used spar-
+ ingly. Testing for _._M_A_K_E_._L_E_V_E_L being 0, would make sense. Also
+ note that any variables which originated in the parent environ-
+ ment should be explicitly preserved if desired. For example:
+
+ .if ${.MAKE.LEVEL} == 0
+ PATH := ${PATH}
+ .unexport-env
+ .export PATH
+ .endif
+
+ Would result in an environment containing only `PATH', which is
+ the minimal useful environment. Actually `.MAKE.LEVEL' will also
+ be pushed into the new environment.
+
+ ..wwaarrnniinngg _m_e_s_s_a_g_e
+ The message prefixed by `_w_a_r_n_i_n_g_:' is printed along with the name
+ of the makefile and line number.
+
+ ..iiff [!]_e_x_p_r_e_s_s_i_o_n [_o_p_e_r_a_t_o_r _e_x_p_r_e_s_s_i_o_n _._._.]
+ Test the value of an expression.
+
+ ..iiffddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.]
+ Test the value of a variable.
+
+ ..iiffnnddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.]
+ Test the value of a variable.
+
+ ..iiffmmaakkee [!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.]
+ Test the target being built.
+
+ ..iiffnnmmaakkee [!] _t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.]
+ Test the target being built.
+
+ ..eellssee Reverse the sense of the last conditional.
+
+ ..eelliiff [!] _e_x_p_r_e_s_s_i_o_n [_o_p_e_r_a_t_o_r _e_x_p_r_e_s_s_i_o_n _._._.]
+ A combination of `..eellssee' followed by `..iiff'.
+
+ ..eelliiffddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.]
+ A combination of `..eellssee' followed by `..iiffddeeff'.
+
+ ..eelliiffnnddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.]
+ A combination of `..eellssee' followed by `..iiffnnddeeff'.
+
+ ..eelliiffmmaakkee [!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.]
+ A combination of `..eellssee' followed by `..iiffmmaakkee'.
+
+ ..eelliiffnnmmaakkee [!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.]
+ A combination of `..eellssee' followed by `..iiffnnmmaakkee'.
+
+ ..eennddiiff End the body of the conditional.
+
+ The _o_p_e_r_a_t_o_r may be any one of the following:
+
+ |||| Logical OR.
+
+ &&&& Logical AND; of higher precedence than ``||''.
+
+ As in C, bbmmaakkee will only evaluate a conditional as far as is necessary to
+ determine its value. Parentheses may be used to change the order of
+ evaluation. The boolean operator `!!' may be used to logically negate an
+ entire conditional. It is of higher precedence than `&&&&'.
+
+ The value of _e_x_p_r_e_s_s_i_o_n may be any of the following:
+
+ ddeeffiinneedd Takes a variable name as an argument and evaluates to true if
+ the variable has been defined.
+
+ mmaakkee Takes a target name as an argument and evaluates to true if the
+ target was specified as part of bbmmaakkee's command line or was
+ declared the default target (either implicitly or explicitly,
+ see _._M_A_I_N) before the line containing the conditional.
+
+ eemmppttyy Takes a variable, with possible modifiers, and evaluates to true
+ if the expansion of the variable would result in an empty
+ string.
+
+ eexxiissttss Takes a file name as an argument and evaluates to true if the
+ file exists. The file is searched for on the system search path
+ (see _._P_A_T_H).
+
+ ttaarrggeett Takes a target name as an argument and evaluates to true if the
+ target has been defined.
+
+ ccoommmmaannddss
+ Takes a target name as an argument and evaluates to true if the
+ target has been defined and has commands associated with it.
+
+ _E_x_p_r_e_s_s_i_o_n may also be an arithmetic or string comparison. Variable
+ expansion is performed on both sides of the comparison, after which the
+ integral values are compared. A value is interpreted as hexadecimal if
+ it is preceded by 0x, otherwise it is decimal; octal numbers are not sup-
+ ported. The standard C relational operators are all supported. If after
+ variable expansion, either the left or right hand side of a `====' or `!!=='
+ operator is not an integral value, then string comparison is performed
+ between the expanded variables. If no relational operator is given, it
+ is assumed that the expanded variable is being compared against 0 or an
+ empty string in the case of a string comparison.
+
+ When bbmmaakkee is evaluating one of these conditional expressions, and it
+ encounters a (white-space separated) word it doesn't recognize, either
+ the ``make'' or ``defined'' expression is applied to it, depending on the
+ form of the conditional. If the form is `..iiffddeeff', `..iiffnnddeeff', or `..iiff'
+ the ``defined'' expression is applied. Similarly, if the form is
+ `..iiffmmaakkee' or `..iiffnnmmaakkee, tthhee' ``make'' expression is applied.
+
+ If the conditional evaluates to true the parsing of the makefile contin-
+ ues as before. If it evaluates to false, the following lines are
+ skipped. In both cases this continues until a `..eellssee' or `..eennddiiff' is
+ found.
+
+ For loops are typically used to apply a set of rules to a list of files.
+ The syntax of a for loop is:
+
+ ..ffoorr _v_a_r_i_a_b_l_e [_v_a_r_i_a_b_l_e _._._.] iinn _e_x_p_r_e_s_s_i_o_n
+ <make-rules>
+ ..eennddffoorr
+
+ After the for eexxpprreessssiioonn is evaluated, it is split into words. On each
+ iteration of the loop, one word is taken and assigned to each vvaarriiaabbllee,
+ in order, and these vvaarriiaabblleess are substituted into the mmaakkee--rruulleess inside
+ the body of the for loop. The number of words must come out even; that
+ is, if there are three iteration variables, the number of words provided
+ must be a multiple of three.
+
+CCOOMMMMEENNTTSS
+ Comments begin with a hash (`#') character, anywhere but in a shell com-
+ mand line, and continue to the end of an unescaped new line.
+
+SSPPEECCIIAALL SSOOUURRCCEESS ((AATTTTRRIIBBUUTTEESS))
+ ..EEXXEECC Target is never out of date, but always execute commands any-
+ way.
+
+ ..IIGGNNOORREE Ignore any errors from the commands associated with this tar-
+ get, exactly as if they all were preceded by a dash (`-').
+
+ ..MMAADDEE Mark all sources of this target as being up-to-date.
+
+ ..MMAAKKEE Execute the commands associated with this target even if the --nn
+ or --tt options were specified. Normally used to mark recursive
+ bbmmaakkee's.
+
+ ..MMEETTAA Create a meta file for the target, even if it is flagged as
+ ..PPHHOONNYY, ..MMAAKKEE, or ..SSPPEECCIIAALL. Usage in conjunction with ..MMAAKKEE is
+ the most likely case. In "meta" mode, the target is out-of-
+ date if the meta file is missing.
+
+ ..NNOOMMEETTAA Do not create a meta file for the target. Meta files are also
+ not created for ..PPHHOONNYY, ..MMAAKKEE, or ..SSPPEECCIIAALL targets.
+
+ ..NNOOMMEETTAA__CCMMPP
+ Ignore differences in commands when deciding if target is out
+ of date. This is useful if the command contains a value which
+ always changes. If the number of commands change, though, the
+ target will still be out of date.
+
+ ..NNOOPPAATTHH Do not search for the target in the directories specified by
+ ..PPAATTHH.
+
+ ..NNOOTTMMAAIINN Normally bbmmaakkee selects the first target it encounters as the
+ default target to be built if no target was specified. This
+ source prevents this target from being selected.
+
+ ..OOPPTTIIOONNAALL
+ If a target is marked with this attribute and bbmmaakkee can't fig-
+ ure out how to create it, it will ignore this fact and assume
+ the file isn't needed or already exists.
+
+ ..PPHHOONNYY The target does not correspond to an actual file; it is always
+ considered to be out of date, and will not be created with the
+ --tt option. Suffix-transformation rules are not applied to
+ ..PPHHOONNYY targets.
+
+ ..PPRREECCIIOOUUSS
+ When bbmmaakkee is interrupted, it normally removes any partially
+ made targets. This source prevents the target from being
+ removed.
+
+ ..RREECCUURRSSIIVVEE
+ Synonym for ..MMAAKKEE.
+
+ ..SSIILLEENNTT Do not echo any of the commands associated with this target,
+ exactly as if they all were preceded by an at sign (`@').
+
+ ..UUSSEE Turn the target into bbmmaakkee's version of a macro. When the tar-
+ get is used as a source for another target, the other target
+ acquires the commands, sources, and attributes (except for
+ ..UUSSEE) of the source. If the target already has commands, the
+ ..UUSSEE target's commands are appended to them.
+
+ ..UUSSEEBBEEFFOORREE
+ Exactly like ..UUSSEE, but prepend the ..UUSSEEBBEEFFOORREE target commands
+ to the target.
+
+ ..WWAAIITT If ..WWAAIITT appears in a dependency line, the sources that precede
+ it are made before the sources that succeed it in the line.
+ Since the dependents of files are not made until the file
+ itself could be made, this also stops the dependents being
+ built unless they are needed for another branch of the depen-
+ dency tree. So given:
+
+ x: a .WAIT b
+ echo x
+ a:
+ echo a
+ b: b1
+ echo b
+ b1:
+ echo b1
+
+ the output is always `a', `b1', `b', `x'.
+ The ordering imposed by ..WWAAIITT is only relevant for parallel
+ makes.
+
+SSPPEECCIIAALL TTAARRGGEETTSS
+ Special targets may not be included with other targets, i.e. they must be
+ the only target specified.
+
+ ..BBEEGGIINN Any command lines attached to this target are executed before
+ anything else is done.
+
+ ..DDEEFFAAUULLTT
+ This is sort of a ..UUSSEE rule for any target (that was used only
+ as a source) that bbmmaakkee can't figure out any other way to cre-
+ ate. Only the shell script is used. The ..IIMMPPSSRRCC variable of a
+ target that inherits ..DDEEFFAAUULLTT's commands is set to the target's
+ own name.
+
+ ..EENNDD Any command lines attached to this target are executed after
+ everything else is done.
+
+ ..EERRRROORR Any command lines attached to this target are executed when
+ another target fails. The ..EERRRROORR__TTAARRGGEETT variable is set to the
+ target that failed. See also MMAAKKEE__PPRRIINNTT__VVAARR__OONN__EERRRROORR.
+
+ ..IIGGNNOORREE Mark each of the sources with the ..IIGGNNOORREE attribute. If no
+ sources are specified, this is the equivalent of specifying the
+ --ii option.
+
+ ..IINNTTEERRRRUUPPTT
+ If bbmmaakkee is interrupted, the commands for this target will be
+ executed.
+
+ ..MMAAIINN If no target is specified when bbmmaakkee is invoked, this target
+ will be built.
+
+ ..MMAAKKEEFFLLAAGGSS
+ This target provides a way to specify flags for bbmmaakkee when the
+ makefile is used. The flags are as if typed to the shell,
+ though the --ff option will have no effect.
+
+ ..NNOOPPAATTHH Apply the ..NNOOPPAATTHH attribute to any specified sources.
+
+ ..NNOOTTPPAARRAALLLLEELL
+ Disable parallel mode.
+
+ ..NNOO__PPAARRAALLLLEELL
+ Synonym for ..NNOOTTPPAARRAALLLLEELL, for compatibility with other pmake
+ variants.
+
+ ..OORRDDEERR The named targets are made in sequence. This ordering does not
+ add targets to the list of targets to be made. Since the depen-
+ dents of a target do not get built until the target itself could
+ be built, unless `a' is built by another part of the dependency
+ graph, the following is a dependency loop:
+
+ .ORDER: b a
+ b: a
+
+ The ordering imposed by ..OORRDDEERR is only relevant for parallel
+ makes.
+
+ ..PPAATTHH The sources are directories which are to be searched for files
+ not found in the current directory. If no sources are speci-
+ fied, any previously specified directories are deleted. If the
+ source is the special ..DDOOTTLLAASSTT target, then the current working
+ directory is searched last.
+
+ ..PPHHOONNYY Apply the ..PPHHOONNYY attribute to any specified sources.
+
+ ..PPRREECCIIOOUUSS
+ Apply the ..PPRREECCIIOOUUSS attribute to any specified sources. If no
+ sources are specified, the ..PPRREECCIIOOUUSS attribute is applied to
+ every target in the file.
+
+ ..SSHHEELLLL Sets the shell that bbmmaakkee will use to execute commands. The
+ sources are a set of _f_i_e_l_d_=_v_a_l_u_e pairs.
+
+ _n_a_m_e This is the minimal specification, used to select
+ one of the builtin shell specs; _s_h, _k_s_h, and _c_s_h.
+
+ _p_a_t_h Specifies the path to the shell.
+
+ _h_a_s_E_r_r_C_t_l Indicates whether the shell supports exit on error.
+
+ _c_h_e_c_k The command to turn on error checking.
+
+ _i_g_n_o_r_e The command to disable error checking.
+
+ _e_c_h_o The command to turn on echoing of commands executed.
+
+ _q_u_i_e_t The command to turn off echoing of commands exe-
+ cuted.
+
+ _f_i_l_t_e_r The output to filter after issuing the _q_u_i_e_t com-
+ mand. It is typically identical to _q_u_i_e_t.
+
+ _e_r_r_F_l_a_g The flag to pass the shell to enable error checking.
+
+ _e_c_h_o_F_l_a_g The flag to pass the shell to enable command echo-
+ ing.
+
+ _n_e_w_l_i_n_e The string literal to pass the shell that results in
+ a single newline character when used outside of any
+ quoting characters.
+ Example:
+
+ .SHELL: name=ksh path=/bin/ksh hasErrCtl=true \
+ check="set -e" ignore="set +e" \
+ echo="set -v" quiet="set +v" filter="set +v" \
+ echoFlag=v errFlag=e newline="'\n'"
+
+ ..SSIILLEENNTT Apply the ..SSIILLEENNTT attribute to any specified sources. If no
+ sources are specified, the ..SSIILLEENNTT attribute is applied to every
+ command in the file.
+
+ ..SSUUFFFFIIXXEESS
+ Each source specifies a suffix to bbmmaakkee. If no sources are
+ specified, any previously specified suffixes are deleted. It
+ allows the creation of suffix-transformation rules.
+
+ Example:
+
+ .SUFFIXES: .o
+ .c.o:
+ cc -o ${.TARGET} -c ${.IMPSRC}
+
+EENNVVIIRROONNMMEENNTT
+ bbmmaakkee uses the following environment variables, if they exist: MACHINE,
+ MACHINE_ARCH, MAKE, MAKEFLAGS, MAKEOBJDIR, MAKEOBJDIRPREFIX, MAKESYSPATH,
+ PWD, and TMPDIR.
+
+ MAKEOBJDIRPREFIX and MAKEOBJDIR may only be set in the environment or on
+ the command line to bbmmaakkee and not as makefile variables; see the descrip-
+ tion of `_._O_B_J_D_I_R' for more details.
+
+FFIILLEESS
+ .depend list of dependencies
+ Makefile list of dependencies
+ makefile list of dependencies
+ sys.mk system makefile
+ /usr/share/mk system makefile directory
+
+CCOOMMPPAATTIIBBIILLIITTYY
+ The basic make syntax is compatible between different versions of make,
+ however the special variables, variable modifiers and conditionals are
+ not.
+
+ The way that parallel makes are scheduled changed in NetBSD 4.0 so that
+ .ORDER and .WAIT apply recursively to the dependent nodes. The algo-
+ rithms used may change again in the future.
+
+ The way that .for loop variables are substituted changed after NetBSD 5.0
+ so that they still appear to be variable expansions. In particular this
+ stops them being treated as syntax, and removes some obscure problems
+ using them in .if statements.
+
+ Unlike other bbmmaakkee programs, this implementation by default executes all
+ commands for a given target using a single shell invocation. This is
+ done for both efficiency and to simplify error handling in remote command
+ invocations. Typically this is transparent to the user, unless the tar-
+ get commands change the current working directory using ``cd'' or
+ ``chdir''. To be compatible with Makefiles that do this, one can use --BB
+ to disable this behavior.
+
+SSEEEE AALLSSOO
+ mkdep(1)
+
+HHIISSTTOORRYY
+ bbmmaakkee is derived from NetBSD make(1). It uses autoconf to facilitate
+ portability to other platforms.
+
+NetBSD 5.1 April 24, 2012 NetBSD 5.1
diff --git a/external/bsd/bmake/dist/boot-strap b/external/bsd/bmake/dist/boot-strap
new file mode 100755
index 0000000..660b766
--- /dev/null
+++ b/external/bsd/bmake/dist/boot-strap
@@ -0,0 +1,388 @@
+:
+# NAME:
+# boot-strap
+#
+# SYNOPSIS:
+# boot-strap [--"configure_arg" ... ][-s "srcdir"][-m "mksrc"]\\
+# ["prefix" ["bmakesrc" ["mksrc"]]]
+#
+# DESCRIPTION:
+# This script is used to configure/build bmake it builds for
+# each OS in a subdir to keep the src clean.
+# On successful completion it echos commands to put the new
+# bmake binary into the /configs tree (if it exists)
+# (http://www.crufty.net/FreeWare/configs.html), $prefix/bin
+# and a suitable ~/*bin directory.
+#
+# Options:
+#
+# -c "rc"
+# Pick up settings from "rc".
+# We look for '.bmake-boot-strap.rc' before processing
+# options.
+#
+# --share "share_dir"
+# Where to put man pages and mk files.
+# If $prefix ends in $HOST_TARGET, and $prefix/../share
+# exits, the default will be that rather than $prefix/share.
+#
+# --mksrc "mksrc"
+# Indicate where the mk files can be found.
+# Default is ./mk or ../mk, set to 'none' to force
+# building without "mksrc" but in that case a sys.mk
+# needs to exist in the default syspath ($share_dir/mk)
+#
+# Possibly useful configure_args:
+#
+# --without-meta
+# disable use of meta mode.
+#
+# --without-filemon
+# disable use of filemon(9) which is currently only
+# available for NetBSD and FreeBSD.
+#
+# --with-filemon="path/to/filemon.h"
+# enables use of filemon(9) by meta mode.
+#
+# --with-machine="machine"
+# set "machine" to override that determined by
+# machine.sh
+#
+# --with-force-machine="machine"
+# force "machine" even if uname(3) provides a value.
+#
+# --with-machine_arch="machine_arch"
+# set "machine_arch" to override that determined by
+# machine.sh
+#
+# --with-default-sys-path="syspath"
+# set an explicit default "syspath" which is where bmake
+# will look for sys.mk and friends.
+#
+# AUTHOR:
+# Simon J. Gerraty <sjg@crufty.net>
+
+# RCSid:
+# $Id: boot-strap,v 1.39 2012/03/26 17:08:22 sjg Exp $
+#
+# @(#) Copyright (c) 2001 Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+#
+
+Mydir=`dirname $0`
+. "$Mydir/os.sh"
+case "$Mydir" in
+/*) ;;
+*) Mydir=`cd "$Mydir" && 'pwd'`;;
+esac
+
+
+Usage() {
+ [ "$1" ] && echo "ERROR: $@" >&2
+ echo "Usage:" >&2
+ echo "$0 [--<configure_arg> ...][-s <srcdir>][-m <mksrc>][<prefix> [[<srcdir>] [<mksrc>]]]" >&2
+ exit 1
+}
+
+Error() {
+ echo "ERROR: $@" >&2
+ exit 1
+}
+
+source_rc() {
+ rc="$1"; shift
+ for d in ${*:-""}
+ do
+ r="${d:+$d/}$rc"
+ [ -f "$r" -a -s "$r" ] || continue
+ echo "NOTE: reading $r"
+ . "$r"
+ break
+ done
+}
+
+CONFIGURE_ARGS=
+MAKESYSPATH=
+# pick a useful default prefix (for me at least ;-)
+for prefix in /opt/$HOST_TARGET "$HOME/$HOST_TARGET" /usr/pkg /usr/local ""
+do
+ [ -d "${prefix:-.}" ] && break
+done
+srcdir=
+mksrc=
+objdir=
+quiet=:
+
+source_rc .bmake-boot-strap.rc . "$Mydir/.." "$HOME"
+
+get_optarg() {
+ expr "x$1" : "x[^=]*=\\(.*\\)"
+}
+
+while :
+do
+ case "$1" in
+ --) shift; break;;
+ --prefix) prefix="$2"; shift;;
+ --prefix=*) prefix=`get_optarg "$1"`;;
+ --src=*) srcdir=`get_optarg "$1"`;;
+ --with-mksrc=*|--mksrc=*) mksrc=`get_optarg "$1"`;;
+ --share=*) share_dir=`get_optarg "$1"`;;
+ --share) share_dir="$2"; shift;;
+ --with-default-sys-path=*)
+ CONFIGURE_ARGS="$1"
+ MAKESYSPATH=`get_optarg "$1"`;;
+ --with-default-sys-path)
+ CONFIGURE_ARGS="$1 $2"
+ MAKESYSPATH="$2"; shift;;
+ -s|--src) srcdir="$2"; shift;;
+ -m|--mksrc) mksrc="$2"; shift;;
+ -o|--objdir) objdir="$2"; shift;;
+ -q) quiet=;;
+ -c) source_rc "$2"; shift;;
+ --*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1";;
+ *=*) eval "$1"; export `expr "x$1" : "x\\(.[^=]*\\)=.*"`;;
+ *) break;;
+ esac
+ shift
+done
+
+AddConfigure() {
+ case " $CONFIGURE_ARGS " in
+ *" $1"*) ;;
+ *) CONFIGURE_ARGS="$CONFIGURE_ARGS $1$2";;
+ esac
+}
+
+GetDir() {
+ match="$1"
+ shift
+ fmatch="$1"
+ shift
+ for dir in $*
+ do
+ [ -d "$dir" ] || continue
+ case "/$dir/" in
+ *$match*) ;;
+ *) continue;;
+ esac
+ case "$fmatch" in
+ .) ;;
+ *) [ -s $dir/$fmatch ] || continue;;
+ esac
+ case "$dir/" in
+ *./*) cd "$dir" && 'pwd';;
+ /*) echo $dir;;
+ *) cd "$dir" && 'pwd';;
+ esac
+ break
+ done
+}
+
+FindHereOrAbove() {
+ (
+ _t=-s
+ while :
+ do
+ case "$1" in
+ -C) cd "$2"; shift; shift;;
+ -?) _t=$1; shift;;
+ *) break;;
+ esac
+ done
+ case "$1" in
+ /*) # we shouldn't be here
+ [ $_t "$1" ] && echo "$1"
+ return
+ ;;
+ .../*) want=`echo "$1" | sed 's,^.../*,,'`;;
+ *) want="$1";;
+ esac
+ here=`'pwd'`
+ while :
+ do
+ if [ $_t "./$want" ]; then
+ echo "$here/$want"
+ return
+ fi
+ cd ..
+ here=`'pwd'`
+ case "$here" in
+ /) return;;
+ esac
+ done
+ )
+}
+
+# is $1 missing from $2 (or PATH) ?
+no_path() {
+ eval "__p=\$${2:-PATH}"
+ case ":$__p:" in *:"$1":*) return 1;; *) return 0;; esac
+}
+
+# if $1 exists and is not in path, append it
+add_path () {
+ case "$1" in
+ -?) t=$1; shift;;
+ *) t=-d;;
+ esac
+ case "$2,$1" in
+ MAKESYSPATH,.../*) ;;
+ *) [ $t ${1:-.} ] || return;;
+ esac
+ no_path $* && eval ${2:-PATH}="$__p${__p:+:}$1"
+}
+
+
+srcdir=`GetDir /bmake make-bootstrap.sh.in "$srcdir" "$2" "$Mydir" ./bmake* "$Mydir"/../bmake*`
+[ -d "${srcdir:-/dev/null}" ] || Usage
+case "$mksrc" in
+none|-) # we don't want it
+ mksrc=
+ ;;
+.../*) # find here or above
+ mksrc=`FindHereOrAbove -C "$Mydir" -s "$mksrc/sys.mk"`
+ # that found a file
+ mksrc=`dirname $mksrc`
+ ;;
+*) # guess we want mksrc...
+ mksrc=`GetDir /mk sys.mk "$mksrc" "$3" ./mk* "$srcdir"/mk* "$srcdir"/../mk*`
+ [ -d "${mksrc:-/dev/null}" ] || Usage "Use '-m none' to build without mksrc"
+ ;;
+esac
+
+# Ok, get to work...
+objdir="${objdir:-$OS}"
+[ -d "$objdir" ] || mkdir -p "$objdir"
+[ -d "$objdir" ] || mkdir "$objdir"
+cd "$objdir" || exit 1
+# make it absolute
+objdir=`'pwd'`
+
+ShareDir() {
+ case "/$1" in
+ /) [ -d /share ] || return;;
+ */$HOST_TARGET)
+ if [ -d "$1/../share" ]; then
+ echo `dirname "$1"`/share
+ return
+ fi
+ ;;
+ esac
+ echo $1/share
+}
+
+# make it easy to force prefix to use $HOST_TARGET
+: looking at "$prefix"
+case "$prefix" in
+*/host?target) prefix=`echo "$prefix" | sed "s,host.target,${HOST_TARGET},"`;;
+esac
+
+share_dir="${share_dir:-`ShareDir $prefix`}"
+
+AddConfigure --prefix= "$prefix"
+case "$CONFIGURE_ARGS" in
+*--with-*-sys-path*) ;; # skip
+*) [ "$share_dir" ] && AddConfigure --with-default-sys-path= "$share_dir/mk";;
+esac
+if [ "$mksrc" ]; then
+ AddConfigure --with-mksrc= "$mksrc"
+ # not all cc's support this
+ CFLAGS_MF= CFLAGS_MD=
+ export CFLAGS_MF CFLAGS_MD
+fi
+
+$srcdir/configure $CONFIGURE_ARGS || exit 1
+chmod 755 make-bootstrap.sh || exit 1
+./make-bootstrap.sh || exit 1
+if [ -z "$MAKESYSPATH" ]; then
+ add_path "${share_dir:-...}/mk" MAKESYSPATH
+ case "$HOST_TARGET" in
+ netbsd*) add_path /usr/share/mk MAKESYSPATH;;
+ esac
+fi
+if [ -s "${mksrc:-/dev/null}/install-mk" ]; then
+ sh "${mksrc}/install-mk" "$objdir/mk"
+ case "$MAKESYSPATH" in
+ .../mk*) ;;
+ *) MAKESYSPATH=".../mk:${MAKESYSPATH}";;
+ esac
+fi
+# make sure test below uses the same diff that configure did
+TOOL_DIFF=`type diff | sed 's,[()],,g;s,^[^/][^/]*,,;q'`
+export MAKESYSPATH TOOL_DIFF
+if [ "$mksrc" ]; then
+ $objdir/bmake test || exit 1
+else
+ # assume nothing
+ $objdir/bmake -r -m / test || exit 1
+fi
+# If -q given, we don't want all the install instructions
+$quiet exit 0
+
+make_version=`./bmake -r -m / -f ./Makefile -V MAKE_VERSION | ( read one two; echo $one )`
+bmake_version=bmake-$make_version
+
+if [ -s /usr/share/tmac/andoc.tmac ]; then
+ # this should be ok
+ man_subdir=man1
+ man_src=$srcdir/bmake.1
+else
+ # guess not
+ man_subdir=cat1
+ man_src=$srcdir/bmake.cat1
+fi
+
+install_prefix() {
+ (
+ bin_dir=
+ share_dir=
+ man_dir=
+ mk_dir=
+ while :
+ do
+ case "$1" in
+ *=*) eval "$1"; shift;;
+ *) break;;
+ esac
+ done
+ bin_dir=${bin_dir:-$1/bin}
+ share_dir=${share_dir:-`ShareDir "$1"`}
+ man_dir=${man_dir:-$share_dir/man}
+ mk_dir=${mk_dir:-$share_dir/mk}
+ echo
+ echo Commands to install into $1/
+ echo
+ echo mkdir -p $bin_dir
+ echo cp $objdir/bmake $bin_dir/$bmake_version
+ echo rm -f $bin_dir/bmake
+ echo ln -s $bmake_version $bin_dir/bmake
+ echo mkdir -p $man_dir/$man_subdir
+ echo cp $man_src $man_dir/$man_subdir/bmake.1
+ if [ "$mksrc" ]; then
+ ev=`env | grep '_MK='`
+ echo $ev sh $mksrc/install-mk $mk_dir
+ fi
+ )
+}
+
+case "$prefix/" in
+"$HOME"/*) ;;
+*) CONFIGS=${CONFIGS:-/configs}
+ [ -d $CONFIGS ] &&
+ install_prefix mksrc= "$CONFIGS/$OS/$OSMAJOR.X/$MACHINE_ARCH$prefix"
+ # I like to keep a copy here...
+ install_prefix share_dir="$HOME/share" "$HOME/$HOST_TARGET"
+ ;;
+esac
+
+install_prefix "$prefix"
diff --git a/external/bsd/bmake/dist/bsd.after-import.mk b/external/bsd/bmake/dist/bsd.after-import.mk
new file mode 100644
index 0000000..e87026f
--- /dev/null
+++ b/external/bsd/bmake/dist/bsd.after-import.mk
@@ -0,0 +1,105 @@
+# $Id: bsd.after-import.mk,v 1.6 2012/06/27 18:23:32 sjg Exp $
+
+# This makefile is for use when integrating bmake into a BSD build
+# system. Use this makefile after importing bmake.
+# It will bootstrap the new version,
+# capture the generated files we need, and add an after-import
+# target to allow the process to be easily repeated.
+
+# The goal is to allow the benefits of autoconf without
+# the overhead of running configure.
+
+all: _makefile
+all: after-import
+
+# we rely on bmake
+.if !defined(.MAKE.LEVEL)
+.error this makefile requires bmake
+.endif
+
+_this := ${MAKEFILE:tA}
+BMAKE_SRC := ${.PARSEDIR}
+
+# it helps to know where the top of the tree is.
+.if !defined(SRCTOP)
+srctop := ${.MAKE.MAKEFILES:M*src/share/mk/sys.mk:H:H:H}
+.if empty(srctop)
+# likely locations?
+.for d in contrib/bmake external/bsd/bmake/dist
+.if ${BMAKE_SRC:M*/$d} != ""
+srctop := ${BMAKE_SRC:tA:S,/$d,,}
+.endif
+.endfor
+.endif
+.if !empty(srctop)
+SRCTOP := ${srctop}
+.endif
+.endif
+
+# This lets us match what boot-strap does
+.if !defined(HOST_OS)
+HOST_OS!= uname
+.endif
+
+# .../share/mk will find ${SRCTOP}/share/mk
+# if we are within ${SRCTOP}
+DEFAULT_SYS_PATH= .../share/mk:/usr/share/mk
+
+BOOTSTRAP_ARGS = \
+ --with-default-sys-path='${DEFAULT_SYS_PATH}' \
+ --prefix /usr \
+ --share /usr/share \
+ --mksrc none
+
+# run boot-strap with minimal influence
+bootstrap: ${BMAKE_SRC}/boot-strap ${MAKEFILE}
+ HOME=/ ${BMAKE_SRC}/boot-strap ${BOOTSTRAP_ARGS} ${BOOTSTRAP_XTRAS}
+ touch ${.TARGET}
+
+# Makefiles need a little more tweaking than say config.h
+MAKEFILE_SED = sed -e '/^MACHINE/d' \
+ -e '/^PROG/s,bmake,${.CURDIR:T},' \
+ -e 's,^.-include,.sinclude,' \
+ -e 's,${SRCTOP},$${SRCTOP},g'
+
+# These are the simple files we want to capture
+configured_files= config.h unit-tests/Makefile
+
+after-import: bootstrap ${MAKEFILE}
+.for f in ${configured_files:N*Makefile}
+ @echo Capturing $f
+ @mkdir -p ${${.CURDIR}/$f:L:H}
+ @cmp -s ${.CURDIR}/$f ${HOST_OS}/$f || \
+ cp ${HOST_OS}/$f ${.CURDIR}/$f
+.endfor
+.for f in ${configured_files:M*Makefile}
+ @echo Capturing $f
+ @mkdir -p ${${.CURDIR}/$f:L:H}
+ @${MAKEFILE_SED} ${HOST_OS}/$f > ${.CURDIR}/$f
+.endfor
+
+# this needs the most work
+_makefile: bootstrap ${MAKEFILE}
+ @echo Generating ${.CURDIR}/Makefile
+ @(echo '# This is a generated file, do NOT edit!'; \
+ echo '# See ${_this:S,${SRCTOP}/,,}'; \
+ echo '#'; echo '# $$${OS}$$'; echo; \
+ echo 'SRCTOP?= $${.CURDIR:${.CURDIR:S,${SRCTOP}/,,:C,[^/]+,H,g:S,/,:,g}}'; echo; \
+ echo; echo '# look here first for config.h'; \
+ echo 'CFLAGS+= -I$${.CURDIR}'; echo; \
+ ${MAKEFILE_SED} ${HOST_OS}/Makefile; \
+ echo; echo '# override some simple things'; \
+ echo 'BINDIR= /usr/bin'; \
+ echo 'MANDIR= /usr/share/man'; \
+ echo; echo '# make sure we get this'; \
+ echo 'CFLAGS+= $${COPTS.$${.IMPSRC:T}}'; \
+ echo 'CLEANFILES+= bootstrap'; \
+ echo; echo 'after-import: ${_this:S,${SRCTOP},\${SRCTOP},}'; \
+ echo ' cd $${.CURDIR} && $${.MAKE} -f ${_this:S,${SRCTOP},\${SRCTOP},}'; \
+ echo; echo '.sinclude "Makefile.inc"'; \
+ echo ) > ${.TARGET}
+ @cmp -s ${.TARGET} ${.CURDIR}/Makefile || \
+ mv ${.TARGET} ${.CURDIR}/Makefile
+
+.include <bsd.obj.mk>
+
diff --git a/external/bsd/bmake/dist/buf.c b/external/bsd/bmake/dist/buf.c
new file mode 100644
index 0000000..ac95c16
--- /dev/null
+++ b/external/bsd/bmake/dist/buf.c
@@ -0,0 +1,291 @@
+/* $NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: buf.c,v 1.25 2012/04/24 20:26:58 sjg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * buf.c --
+ * Functions for automatically-expanded buffers.
+ */
+
+#include "make.h"
+#include "buf.h"
+
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#define BUF_DEF_SIZE 256 /* Default buffer size */
+
+/*-
+ *-----------------------------------------------------------------------
+ * Buf_Expand_1 --
+ * Extend buffer for single byte add.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Buf_Expand_1(Buffer *bp)
+{
+ bp->size += max(bp->size, 16);
+ bp->buffer = bmake_realloc(bp->buffer, bp->size);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Buf_AddBytes --
+ * Add a number of bytes to the buffer.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Guess what?
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Buf_AddBytes(Buffer *bp, int numBytes, const Byte *bytesPtr)
+{
+ int count = bp->count;
+ Byte *ptr;
+
+ if (__predict_false(count + numBytes >= bp->size)) {
+ bp->size += max(bp->size, numBytes + 16);
+ bp->buffer = bmake_realloc(bp->buffer, bp->size);
+ }
+
+ ptr = bp->buffer + count;
+ bp->count = count + numBytes;
+ ptr[numBytes] = 0;
+ memcpy(ptr, bytesPtr, numBytes);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Buf_GetAll --
+ * Get all the available data at once.
+ *
+ * Results:
+ * A pointer to the data and the number of bytes available.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+Byte *
+Buf_GetAll(Buffer *bp, int *numBytesPtr)
+{
+
+ if (numBytesPtr != NULL)
+ *numBytesPtr = bp->count;
+
+ return (bp->buffer);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Buf_Empty --
+ * Throw away bytes in a buffer.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The bytes are discarded.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Buf_Empty(Buffer *bp)
+{
+
+ bp->count = 0;
+ *bp->buffer = 0;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Buf_Init --
+ * Initialize a buffer. If no initial size is given, a reasonable
+ * default is used.
+ *
+ * Input:
+ * size Initial size for the buffer
+ *
+ * Results:
+ * A buffer to be given to other functions in this library.
+ *
+ * Side Effects:
+ * The buffer is created, the space allocated and pointers
+ * initialized.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Buf_Init(Buffer *bp, int size)
+{
+ if (size <= 0) {
+ size = BUF_DEF_SIZE;
+ }
+ bp->size = size;
+ bp->count = 0;
+ bp->buffer = bmake_malloc(size);
+ *bp->buffer = 0;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Buf_Destroy --
+ * Nuke a buffer and all its resources.
+ *
+ * Input:
+ * buf Buffer to destroy
+ * freeData TRUE if the data should be destroyed
+ *
+ * Results:
+ * Data buffer, NULL if freed
+ *
+ * Side Effects:
+ * The buffer is freed.
+ *
+ *-----------------------------------------------------------------------
+ */
+Byte *
+Buf_Destroy(Buffer *buf, Boolean freeData)
+{
+ Byte *data;
+
+ data = buf->buffer;
+ if (freeData) {
+ free(data);
+ data = NULL;
+ }
+
+ buf->size = 0;
+ buf->count = 0;
+ buf->buffer = NULL;
+
+ return data;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Buf_DestroyCompact --
+ * Nuke a buffer and return its data.
+ *
+ * Input:
+ * buf Buffer to destroy
+ *
+ * Results:
+ * Data buffer
+ *
+ * Side Effects:
+ * If the buffer size is much greater than its content,
+ * a new buffer will be allocated and the old one freed.
+ *
+ *-----------------------------------------------------------------------
+ */
+#ifndef BUF_COMPACT_LIMIT
+# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */
+#endif
+
+Byte *
+Buf_DestroyCompact(Buffer *buf)
+{
+#if BUF_COMPACT_LIMIT > 0
+ Byte *data;
+
+ if (buf->size - buf->count >= BUF_COMPACT_LIMIT) {
+ /* We trust realloc to be smart */
+ data = bmake_realloc(buf->buffer, buf->count + 1);
+ if (data) {
+ data[buf->count] = 0;
+ Buf_Destroy(buf, FALSE);
+ return data;
+ }
+ }
+#endif
+ return Buf_Destroy(buf, FALSE);
+}
diff --git a/external/bsd/bmake/dist/buf.h b/external/bsd/bmake/dist/buf.h
new file mode 100644
index 0000000..25be67d
--- /dev/null
+++ b/external/bsd/bmake/dist/buf.h
@@ -0,0 +1,119 @@
+/* $NetBSD: buf.h,v 1.17 2012/04/24 20:26:58 sjg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)buf.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)buf.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*-
+ * buf.h --
+ * Header for users of the buf library.
+ */
+
+#ifndef _BUF_H
+#define _BUF_H
+
+typedef char Byte;
+
+typedef struct Buffer {
+ int size; /* Current size of the buffer */
+ int count; /* Number of bytes in buffer */
+ Byte *buffer; /* The buffer itself (zero terminated) */
+} Buffer;
+
+/* If we aren't on netbsd, __predict_false() might not be defined. */
+#ifndef __predict_false
+#define __predict_false(x) (x)
+#endif
+
+/* Buf_AddByte adds a single byte to a buffer. */
+#define Buf_AddByte(bp, byte) do { \
+ int _count = ++(bp)->count; \
+ char *_ptr; \
+ if (__predict_false(_count >= (bp)->size)) \
+ Buf_Expand_1(bp); \
+ _ptr = (bp)->buffer + _count; \
+ _ptr[-1] = (byte); \
+ _ptr[0] = 0; \
+ } while (0)
+
+#define BUF_ERROR 256
+
+#define Buf_Size(bp) ((bp)->count)
+
+void Buf_Expand_1(Buffer *);
+void Buf_AddBytes(Buffer *, int, const Byte *);
+Byte *Buf_GetAll(Buffer *, int *);
+void Buf_Empty(Buffer *);
+void Buf_Init(Buffer *, int);
+Byte *Buf_Destroy(Buffer *, Boolean);
+Byte *Buf_DestroyCompact(Buffer *);
+
+#endif /* _BUF_H */
diff --git a/external/bsd/bmake/dist/compat.c b/external/bsd/bmake/dist/compat.c
new file mode 100644
index 0000000..7f715cc
--- /dev/null
+++ b/external/bsd/bmake/dist/compat.c
@@ -0,0 +1,764 @@
+/* $NetBSD: compat.c,v 1.89 2012/06/10 21:44:01 wiz Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: compat.c,v 1.89 2012/06/10 21:44:01 wiz Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
+#else
+__RCSID("$NetBSD: compat.c,v 1.89 2012/06/10 21:44:01 wiz Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * compat.c --
+ * The routines in this file implement the full-compatibility
+ * mode of PMake. Most of the special functionality of PMake
+ * is available in this mode. Things not supported:
+ * - different shells.
+ * - friendly variable substitution.
+ *
+ * Interface:
+ * Compat_Run Initialize things for this module and recreate
+ * thems as need creatin'
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "wait.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+#include "job.h"
+#include "pathnames.h"
+
+/*
+ * The following array is used to make a fast determination of which
+ * characters are interpreted specially by the shell. If a command
+ * contains any of these characters, it is executed by the shell, not
+ * directly by us.
+ */
+
+static char meta[256];
+
+static GNode *curTarg = NULL;
+static GNode *ENDNode;
+static void CompatInterrupt(int);
+
+static void
+Compat_Init(void)
+{
+ const char *cp;
+
+ Shell_Init(); /* setup default shell */
+
+ for (cp = "#=|^(){};&<>*?[]:$`\\\n"; *cp != '\0'; cp++) {
+ meta[(unsigned char) *cp] = 1;
+ }
+ /*
+ * The null character serves as a sentinel in the string.
+ */
+ meta[0] = 1;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CompatInterrupt --
+ * Interrupt the creation of the current target and remove it if
+ * it ain't precious.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The target is removed and the process exits. If .INTERRUPT exists,
+ * its commands are run first WITH INTERRUPTS IGNORED..
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+CompatInterrupt(int signo)
+{
+ GNode *gn;
+
+ if ((curTarg != NULL) && !Targ_Precious (curTarg)) {
+ char *p1;
+ char *file = Var_Value(TARGET, curTarg, &p1);
+
+ if (!noExecute && eunlink(file) != -1) {
+ Error("*** %s removed", file);
+ }
+ if (p1)
+ free(p1);
+
+ /*
+ * Run .INTERRUPT only if hit with interrupt signal
+ */
+ if (signo == SIGINT) {
+ gn = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
+ if (gn != NULL) {
+ Compat_Make(gn, gn);
+ }
+ }
+
+ }
+ if (signo == SIGQUIT)
+ _exit(signo);
+ bmake_signal(signo, SIG_DFL);
+ kill(myPid, signo);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CompatRunCommand --
+ * Execute the next command for a target. If the command returns an
+ * error, the node's made field is set to ERROR and creation stops.
+ *
+ * Input:
+ * cmdp Command to execute
+ * gnp Node from which the command came
+ *
+ * Results:
+ * 0 if the command succeeded, 1 if an error occurred.
+ *
+ * Side Effects:
+ * The node's 'made' field may be set to ERROR.
+ *
+ *-----------------------------------------------------------------------
+ */
+int
+CompatRunCommand(void *cmdp, void *gnp)
+{
+ char *cmdStart; /* Start of expanded command */
+ char *cp, *bp;
+ Boolean silent, /* Don't print command */
+ doIt; /* Execute even if -n */
+ volatile Boolean errCheck; /* Check errors */
+ WAIT_T reason; /* Reason for child's death */
+ int status; /* Description of child's death */
+ pid_t cpid; /* Child actually found */
+ pid_t retstat; /* Result of wait */
+ LstNode cmdNode; /* Node where current command is located */
+ const char ** volatile av; /* Argument vector for thing to exec */
+ char ** volatile mav;/* Copy of the argument vector for freeing */
+ int argc; /* Number of arguments in av or 0 if not
+ * dynamically allocated */
+ Boolean local; /* TRUE if command should be executed
+ * locally */
+ Boolean useShell; /* TRUE if command should be executed
+ * using a shell */
+ char * volatile cmd = (char *)cmdp;
+ GNode *gn = (GNode *)gnp;
+
+ silent = gn->type & OP_SILENT;
+ errCheck = !(gn->type & OP_IGNORE);
+ doIt = FALSE;
+
+ cmdNode = Lst_Member(gn->commands, cmd);
+ cmdStart = Var_Subst(NULL, cmd, gn, FALSE);
+
+ /*
+ * brk_string will return an argv with a NULL in av[0], thus causing
+ * execvp to choke and die horribly. Besides, how can we execute a null
+ * command? In any case, we warn the user that the command expanded to
+ * nothing (is this the right thing to do?).
+ */
+
+ if (*cmdStart == '\0') {
+ free(cmdStart);
+ Error("%s expands to empty string", cmd);
+ return(0);
+ }
+ cmd = cmdStart;
+ Lst_Replace(cmdNode, cmdStart);
+
+ if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) {
+ (void)Lst_AtEnd(ENDNode->commands, cmdStart);
+ return(0);
+ }
+ if (strcmp(cmdStart, "...") == 0) {
+ gn->type |= OP_SAVE_CMDS;
+ return(0);
+ }
+
+ while ((*cmd == '@') || (*cmd == '-') || (*cmd == '+')) {
+ switch (*cmd) {
+ case '@':
+ silent = DEBUG(LOUD) ? FALSE : TRUE;
+ break;
+ case '-':
+ errCheck = FALSE;
+ break;
+ case '+':
+ doIt = TRUE;
+ if (!meta[0]) /* we came here from jobs */
+ Compat_Init();
+ break;
+ }
+ cmd++;
+ }
+
+ while (isspace((unsigned char)*cmd))
+ cmd++;
+
+ /*
+ * If we did not end up with a command, just skip it.
+ */
+ if (!*cmd)
+ return (0);
+
+#if !defined(MAKE_NATIVE)
+ /*
+ * In a non-native build, the host environment might be weird enough
+ * that it's necessary to go through a shell to get the correct
+ * behaviour. Or perhaps the shell has been replaced with something
+ * that does extra logging, and that should not be bypassed.
+ */
+ useShell = TRUE;
+#else
+ /*
+ * Search for meta characters in the command. If there are no meta
+ * characters, there's no need to execute a shell to execute the
+ * command.
+ */
+ for (cp = cmd; !meta[(unsigned char)*cp]; cp++) {
+ continue;
+ }
+ useShell = (*cp != '\0');
+#endif
+
+ /*
+ * Print the command before echoing if we're not supposed to be quiet for
+ * this one. We also print the command if -n given.
+ */
+ if (!silent || NoExecute(gn)) {
+ printf("%s\n", cmd);
+ fflush(stdout);
+ }
+
+ /*
+ * If we're not supposed to execute any commands, this is as far as
+ * we go...
+ */
+ if (!doIt && NoExecute(gn)) {
+ return (0);
+ }
+ if (DEBUG(JOB))
+ fprintf(debug_file, "Execute: '%s'\n", cmd);
+
+again:
+ if (useShell) {
+ /*
+ * We need to pass the command off to the shell, typically
+ * because the command contains a "meta" character.
+ */
+ static const char *shargv[4];
+
+ shargv[0] = shellPath;
+ /*
+ * The following work for any of the builtin shell specs.
+ */
+ if (DEBUG(SHELL))
+ shargv[1] = "-xc";
+ else
+ shargv[1] = "-c";
+ shargv[2] = cmd;
+ shargv[3] = NULL;
+ av = shargv;
+ argc = 0;
+ bp = NULL;
+ mav = NULL;
+ } else {
+ /*
+ * No meta-characters, so no need to exec a shell. Break the command
+ * into words to form an argument vector we can execute.
+ */
+ mav = brk_string(cmd, &argc, TRUE, &bp);
+ if (mav == NULL) {
+ useShell = 1;
+ goto again;
+ }
+ av = (void *)mav;
+ }
+
+ local = TRUE;
+
+#ifdef USE_META
+ if (useMeta) {
+ meta_compat_start();
+ }
+#endif
+
+ /*
+ * Fork and execute the single command. If the fork fails, we abort.
+ */
+ cpid = vFork();
+ if (cpid < 0) {
+ Fatal("Could not fork");
+ }
+ if (cpid == 0) {
+ Check_Cwd(av);
+ Var_ExportVars();
+#ifdef USE_META
+ if (useMeta) {
+ meta_compat_child();
+ }
+#endif
+ if (local)
+ (void)execvp(av[0], (char *const *)UNCONST(av));
+ else
+ (void)execv(av[0], (char *const *)UNCONST(av));
+ execError("exec", av[0]);
+ _exit(1);
+ }
+ if (mav)
+ free(mav);
+ if (bp)
+ free(bp);
+ Lst_Replace(cmdNode, NULL);
+
+#ifdef USE_META
+ if (useMeta) {
+ meta_compat_parent();
+ }
+#endif
+
+ /*
+ * The child is off and running. Now all we can do is wait...
+ */
+ while (1) {
+
+ while ((retstat = wait(&reason)) != cpid) {
+ if (retstat > 0)
+ JobReapChild(retstat, reason, FALSE); /* not ours? */
+ if (retstat == -1 && errno != EINTR) {
+ break;
+ }
+ }
+
+ if (retstat > -1) {
+ if (WIFSTOPPED(reason)) {
+ status = WSTOPSIG(reason); /* stopped */
+ } else if (WIFEXITED(reason)) {
+ status = WEXITSTATUS(reason); /* exited */
+#if defined(USE_META) && defined(USE_FILEMON_ONCE)
+ if (useMeta) {
+ meta_cmd_finish(NULL);
+ }
+#endif
+ if (status != 0) {
+ if (DEBUG(ERROR)) {
+ fprintf(debug_file, "\n*** Failed target: %s\n*** Failed command: ",
+ gn->name);
+ for (cp = cmd; *cp; ) {
+ if (isspace((unsigned char)*cp)) {
+ fprintf(debug_file, " ");
+ while (isspace((unsigned char)*cp))
+ cp++;
+ } else {
+ fprintf(debug_file, "%c", *cp);
+ cp++;
+ }
+ }
+ fprintf(debug_file, "\n");
+ }
+ printf("*** Error code %d", status);
+ }
+ } else {
+ status = WTERMSIG(reason); /* signaled */
+ printf("*** Signal %d", status);
+ }
+
+
+ if (!WIFEXITED(reason) || (status != 0)) {
+ if (errCheck) {
+#ifdef USE_META
+ if (useMeta) {
+ meta_job_error(NULL, gn, 0, status);
+ }
+#endif
+ gn->made = ERROR;
+ if (keepgoing) {
+ /*
+ * Abort the current target, but let others
+ * continue.
+ */
+ printf(" (continuing)\n");
+ }
+ } else {
+ /*
+ * Continue executing commands for this target.
+ * If we return 0, this will happen...
+ */
+ printf(" (ignored)\n");
+ status = 0;
+ }
+ }
+ break;
+ } else {
+ Fatal("error in wait: %d: %s", retstat, strerror(errno));
+ /*NOTREACHED*/
+ }
+ }
+ free(cmdStart);
+
+ return (status);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Compat_Make --
+ * Make a target.
+ *
+ * Input:
+ * gnp The node to make
+ * pgnp Parent to abort if necessary
+ *
+ * Results:
+ * 0
+ *
+ * Side Effects:
+ * If an error is detected and not being ignored, the process exits.
+ *
+ *-----------------------------------------------------------------------
+ */
+int
+Compat_Make(void *gnp, void *pgnp)
+{
+ GNode *gn = (GNode *)gnp;
+ GNode *pgn = (GNode *)pgnp;
+
+ if (!meta[0]) /* we came here from jobs */
+ Compat_Init();
+ if (gn->made == UNMADE && (gn == pgn || (pgn->type & OP_MADE) == 0)) {
+ /*
+ * First mark ourselves to be made, then apply whatever transformations
+ * the suffix module thinks are necessary. Once that's done, we can
+ * descend and make all our children. If any of them has an error
+ * but the -k flag was given, our 'make' field will be set FALSE again.
+ * This is our signal to not attempt to do anything but abort our
+ * parent as well.
+ */
+ gn->flags |= REMAKE;
+ gn->made = BEINGMADE;
+ if ((gn->type & OP_MADE) == 0)
+ Suff_FindDeps(gn);
+ Lst_ForEach(gn->children, Compat_Make, gn);
+ if ((gn->flags & REMAKE) == 0) {
+ gn->made = ABORTED;
+ pgn->flags &= ~REMAKE;
+ goto cohorts;
+ }
+
+ if (Lst_Member(gn->iParents, pgn) != NULL) {
+ char *p1;
+ Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
+ if (p1)
+ free(p1);
+ }
+
+ /*
+ * All the children were made ok. Now cmgn->mtime contains the
+ * modification time of the newest child, we need to find out if we
+ * exist and when we were modified last. The criteria for datedness
+ * are defined by the Make_OODate function.
+ */
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, "Examining %s...", gn->name);
+ }
+ if (! Make_OODate(gn)) {
+ gn->made = UPTODATE;
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, "up-to-date.\n");
+ }
+ goto cohorts;
+ } else if (DEBUG(MAKE)) {
+ fprintf(debug_file, "out-of-date.\n");
+ }
+
+ /*
+ * If the user is just seeing if something is out-of-date, exit now
+ * to tell him/her "yes".
+ */
+ if (queryFlag) {
+ exit(1);
+ }
+
+ /*
+ * We need to be re-made. We also have to make sure we've got a $?
+ * variable. To be nice, we also define the $> variable using
+ * Make_DoAllVar().
+ */
+ Make_DoAllVar(gn);
+
+ /*
+ * Alter our type to tell if errors should be ignored or things
+ * should not be printed so CompatRunCommand knows what to do.
+ */
+ if (Targ_Ignore(gn)) {
+ gn->type |= OP_IGNORE;
+ }
+ if (Targ_Silent(gn)) {
+ gn->type |= OP_SILENT;
+ }
+
+ if (Job_CheckCommands(gn, Fatal)) {
+ /*
+ * Our commands are ok, but we still have to worry about the -t
+ * flag...
+ */
+ if (!touchFlag || (gn->type & OP_MAKE)) {
+ curTarg = gn;
+#ifdef USE_META
+ if (useMeta && !NoExecute(gn)) {
+ meta_job_start(NULL, gn);
+ }
+#endif
+ Lst_ForEach(gn->commands, CompatRunCommand, gn);
+ curTarg = NULL;
+ } else {
+ Job_Touch(gn, gn->type & OP_SILENT);
+ }
+ } else {
+ gn->made = ERROR;
+ }
+#ifdef USE_META
+ if (useMeta && !NoExecute(gn)) {
+ meta_job_finish(NULL);
+ }
+#endif
+
+ if (gn->made != ERROR) {
+ /*
+ * If the node was made successfully, mark it so, update
+ * its modification time and timestamp all its parents. Note
+ * that for .ZEROTIME targets, the timestamping isn't done.
+ * This is to keep its state from affecting that of its parent.
+ */
+ gn->made = MADE;
+ pgn->flags |= Make_Recheck(gn) == 0 ? FORCE : 0;
+ if (!(gn->type & OP_EXEC)) {
+ pgn->flags |= CHILDMADE;
+ Make_TimeStamp(pgn, gn);
+ }
+ } else if (keepgoing) {
+ pgn->flags &= ~REMAKE;
+ } else {
+ PrintOnError(gn, "\n\nStop.");
+ exit(1);
+ }
+ } else if (gn->made == ERROR) {
+ /*
+ * Already had an error when making this beastie. Tell the parent
+ * to abort.
+ */
+ pgn->flags &= ~REMAKE;
+ } else {
+ if (Lst_Member(gn->iParents, pgn) != NULL) {
+ char *p1;
+ Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
+ if (p1)
+ free(p1);
+ }
+ switch(gn->made) {
+ case BEINGMADE:
+ Error("Graph cycles through %s", gn->name);
+ gn->made = ERROR;
+ pgn->flags &= ~REMAKE;
+ break;
+ case MADE:
+ if ((gn->type & OP_EXEC) == 0) {
+ pgn->flags |= CHILDMADE;
+ Make_TimeStamp(pgn, gn);
+ }
+ break;
+ case UPTODATE:
+ if ((gn->type & OP_EXEC) == 0) {
+ Make_TimeStamp(pgn, gn);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+cohorts:
+ Lst_ForEach(gn->cohorts, Compat_Make, pgnp);
+ return (0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Compat_Run --
+ * Initialize this mode and start making.
+ *
+ * Input:
+ * targs List of target nodes to re-create
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Guess what?
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Compat_Run(Lst targs)
+{
+ GNode *gn = NULL;/* Current root target */
+ int errors; /* Number of targets not remade due to errors */
+
+ Compat_Init();
+
+ if (bmake_signal(SIGINT, SIG_IGN) != SIG_IGN) {
+ bmake_signal(SIGINT, CompatInterrupt);
+ }
+ if (bmake_signal(SIGTERM, SIG_IGN) != SIG_IGN) {
+ bmake_signal(SIGTERM, CompatInterrupt);
+ }
+ if (bmake_signal(SIGHUP, SIG_IGN) != SIG_IGN) {
+ bmake_signal(SIGHUP, CompatInterrupt);
+ }
+ if (bmake_signal(SIGQUIT, SIG_IGN) != SIG_IGN) {
+ bmake_signal(SIGQUIT, CompatInterrupt);
+ }
+
+ ENDNode = Targ_FindNode(".END", TARG_CREATE);
+ ENDNode->type = OP_SPECIAL;
+ /*
+ * If the user has defined a .BEGIN target, execute the commands attached
+ * to it.
+ */
+ if (!queryFlag) {
+ gn = Targ_FindNode(".BEGIN", TARG_NOCREATE);
+ if (gn != NULL) {
+ Compat_Make(gn, gn);
+ if (gn->made == ERROR) {
+ PrintOnError(gn, "\n\nStop.");
+ exit(1);
+ }
+ }
+ }
+
+ /*
+ * Expand .USE nodes right now, because they can modify the structure
+ * of the tree.
+ */
+ Make_ExpandUse(targs);
+
+ /*
+ * For each entry in the list of targets to create, call Compat_Make on
+ * it to create the thing. Compat_Make will leave the 'made' field of gn
+ * in one of several states:
+ * UPTODATE gn was already up-to-date
+ * MADE gn was recreated successfully
+ * ERROR An error occurred while gn was being created
+ * ABORTED gn was not remade because one of its inferiors
+ * could not be made due to errors.
+ */
+ errors = 0;
+ while (!Lst_IsEmpty (targs)) {
+ gn = (GNode *)Lst_DeQueue(targs);
+ Compat_Make(gn, gn);
+
+ if (gn->made == UPTODATE) {
+ printf("`%s' is up to date.\n", gn->name);
+ } else if (gn->made == ABORTED) {
+ printf("`%s' not remade because of errors.\n", gn->name);
+ errors += 1;
+ }
+ }
+
+ /*
+ * If the user has defined a .END target, run its commands.
+ */
+ if (errors == 0) {
+ Compat_Make(ENDNode, ENDNode);
+ if (gn->made == ERROR) {
+ PrintOnError(gn, "\n\nStop.");
+ exit(1);
+ }
+ }
+}
diff --git a/external/bsd/bmake/dist/cond.c b/external/bsd/bmake/dist/cond.c
new file mode 100644
index 0000000..6d0b965
--- /dev/null
+++ b/external/bsd/bmake/dist/cond.c
@@ -0,0 +1,1410 @@
+/* $NetBSD: cond.c,v 1.64 2012/06/12 19:21:50 joerg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: cond.c,v 1.64 2012/06/12 19:21:50 joerg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94";
+#else
+__RCSID("$NetBSD: cond.c,v 1.64 2012/06/12 19:21:50 joerg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * cond.c --
+ * Functions to handle conditionals in a makefile.
+ *
+ * Interface:
+ * Cond_Eval Evaluate the conditional in the passed line.
+ *
+ */
+
+#include <ctype.h>
+#include <errno.h> /* For strtoul() error checking */
+
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+#include "buf.h"
+
+/*
+ * The parsing of conditional expressions is based on this grammar:
+ * E -> F || E
+ * E -> F
+ * F -> T && F
+ * F -> T
+ * T -> defined(variable)
+ * T -> make(target)
+ * T -> exists(file)
+ * T -> empty(varspec)
+ * T -> target(name)
+ * T -> commands(name)
+ * T -> symbol
+ * T -> $(varspec) op value
+ * T -> $(varspec) == "string"
+ * T -> $(varspec) != "string"
+ * T -> "string"
+ * T -> ( E )
+ * T -> ! T
+ * op -> == | != | > | < | >= | <=
+ *
+ * 'symbol' is some other symbol to which the default function (condDefProc)
+ * is applied.
+ *
+ * Tokens are scanned from the 'condExpr' string. The scanner (CondToken)
+ * will return TOK_AND for '&' and '&&', TOK_OR for '|' and '||',
+ * TOK_NOT for '!', TOK_LPAREN for '(', TOK_RPAREN for ')' and will evaluate
+ * the other terminal symbols, using either the default function or the
+ * function given in the terminal, and return the result as either TOK_TRUE
+ * or TOK_FALSE.
+ *
+ * TOK_FALSE is 0 and TOK_TRUE 1 so we can directly assign C comparisons.
+ *
+ * All Non-Terminal functions (CondE, CondF and CondT) return TOK_ERROR on
+ * error.
+ */
+typedef enum {
+ TOK_FALSE = 0, TOK_TRUE = 1, TOK_AND, TOK_OR, TOK_NOT,
+ TOK_LPAREN, TOK_RPAREN, TOK_EOF, TOK_NONE, TOK_ERROR
+} Token;
+
+/*-
+ * Structures to handle elegantly the different forms of #if's. The
+ * last two fields are stored in condInvert and condDefProc, respectively.
+ */
+static void CondPushBack(Token);
+static int CondGetArg(char **, char **, const char *);
+static Boolean CondDoDefined(int, const char *);
+static int CondStrMatch(const void *, const void *);
+static Boolean CondDoMake(int, const char *);
+static Boolean CondDoExists(int, const char *);
+static Boolean CondDoTarget(int, const char *);
+static Boolean CondDoCommands(int, const char *);
+static Boolean CondCvtArg(char *, double *);
+static Token CondToken(Boolean);
+static Token CondT(Boolean);
+static Token CondF(Boolean);
+static Token CondE(Boolean);
+static int do_Cond_EvalExpression(Boolean *);
+
+static const struct If {
+ const char *form; /* Form of if */
+ int formlen; /* Length of form */
+ Boolean doNot; /* TRUE if default function should be negated */
+ Boolean (*defProc)(int, const char *); /* Default function to apply */
+} ifs[] = {
+ { "def", 3, FALSE, CondDoDefined },
+ { "ndef", 4, TRUE, CondDoDefined },
+ { "make", 4, FALSE, CondDoMake },
+ { "nmake", 5, TRUE, CondDoMake },
+ { "", 0, FALSE, CondDoDefined },
+ { NULL, 0, FALSE, NULL }
+};
+
+static const struct If *if_info; /* Info for current statement */
+static char *condExpr; /* The expression to parse */
+static Token condPushBack=TOK_NONE; /* Single push-back token used in
+ * parsing */
+
+static unsigned int cond_depth = 0; /* current .if nesting level */
+static unsigned int cond_min_depth = 0; /* depth at makefile open */
+
+static int
+istoken(const char *str, const char *tok, size_t len)
+{
+ return strncmp(str, tok, len) == 0 && !isalpha((unsigned char)str[len]);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondPushBack --
+ * Push back the most recent token read. We only need one level of
+ * this, so the thing is just stored in 'condPushback'.
+ *
+ * Input:
+ * t Token to push back into the "stream"
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * condPushback is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+CondPushBack(Token t)
+{
+ condPushBack = t;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondGetArg --
+ * Find the argument of a built-in function.
+ *
+ * Input:
+ * parens TRUE if arg should be bounded by parens
+ *
+ * Results:
+ * The length of the argument and the address of the argument.
+ *
+ * Side Effects:
+ * The pointer is set to point to the closing parenthesis of the
+ * function call.
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+CondGetArg(char **linePtr, char **argPtr, const char *func)
+{
+ char *cp;
+ int argLen;
+ Buffer buf;
+ int paren_depth;
+ char ch;
+
+ cp = *linePtr;
+ if (func != NULL)
+ /* Skip opening '(' - verfied by caller */
+ cp++;
+
+ if (*cp == '\0') {
+ /*
+ * No arguments whatsoever. Because 'make' and 'defined' aren't really
+ * "reserved words", we don't print a message. I think this is better
+ * than hitting the user with a warning message every time s/he uses
+ * the word 'make' or 'defined' at the beginning of a symbol...
+ */
+ *argPtr = NULL;
+ return (0);
+ }
+
+ while (*cp == ' ' || *cp == '\t') {
+ cp++;
+ }
+
+ /*
+ * Create a buffer for the argument and start it out at 16 characters
+ * long. Why 16? Why not?
+ */
+ Buf_Init(&buf, 16);
+
+ paren_depth = 0;
+ for (;;) {
+ ch = *cp;
+ if (ch == 0 || ch == ' ' || ch == '\t')
+ break;
+ if ((ch == '&' || ch == '|') && paren_depth == 0)
+ break;
+ if (*cp == '$') {
+ /*
+ * Parse the variable spec and install it as part of the argument
+ * if it's valid. We tell Var_Parse to complain on an undefined
+ * variable, so we don't do it too. Nor do we return an error,
+ * though perhaps we should...
+ */
+ char *cp2;
+ int len;
+ void *freeIt;
+
+ cp2 = Var_Parse(cp, VAR_CMD, TRUE, &len, &freeIt);
+ Buf_AddBytes(&buf, strlen(cp2), cp2);
+ if (freeIt)
+ free(freeIt);
+ cp += len;
+ continue;
+ }
+ if (ch == '(')
+ paren_depth++;
+ else
+ if (ch == ')' && --paren_depth < 0)
+ break;
+ Buf_AddByte(&buf, *cp);
+ cp++;
+ }
+
+ *argPtr = Buf_GetAll(&buf, &argLen);
+ Buf_Destroy(&buf, FALSE);
+
+ while (*cp == ' ' || *cp == '\t') {
+ cp++;
+ }
+
+ if (func != NULL && *cp++ != ')') {
+ Parse_Error(PARSE_WARNING, "Missing closing parenthesis for %s()",
+ func);
+ return (0);
+ }
+
+ *linePtr = cp;
+ return (argLen);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondDoDefined --
+ * Handle the 'defined' function for conditionals.
+ *
+ * Results:
+ * TRUE if the given variable is defined.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+CondDoDefined(int argLen MAKE_ATTR_UNUSED, const char *arg)
+{
+ char *p1;
+ Boolean result;
+
+ if (Var_Value(arg, VAR_CMD, &p1) != NULL) {
+ result = TRUE;
+ } else {
+ result = FALSE;
+ }
+ if (p1)
+ free(p1);
+ return (result);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondStrMatch --
+ * Front-end for Str_Match so it returns 0 on match and non-zero
+ * on mismatch. Callback function for CondDoMake via Lst_Find
+ *
+ * Results:
+ * 0 if string matches pattern
+ *
+ * Side Effects:
+ * None
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+CondStrMatch(const void *string, const void *pattern)
+{
+ return(!Str_Match(string, pattern));
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondDoMake --
+ * Handle the 'make' function for conditionals.
+ *
+ * Results:
+ * TRUE if the given target is being made.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+CondDoMake(int argLen MAKE_ATTR_UNUSED, const char *arg)
+{
+ return Lst_Find(create, arg, CondStrMatch) != NULL;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondDoExists --
+ * See if the given file exists.
+ *
+ * Results:
+ * TRUE if the file exists and FALSE if it does not.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+CondDoExists(int argLen MAKE_ATTR_UNUSED, const char *arg)
+{
+ Boolean result;
+ char *path;
+
+ path = Dir_FindFile(arg, dirSearchPath);
+ if (DEBUG(COND)) {
+ fprintf(debug_file, "exists(%s) result is \"%s\"\n",
+ arg, path ? path : "");
+ }
+ if (path != NULL) {
+ result = TRUE;
+ free(path);
+ } else {
+ result = FALSE;
+ }
+ return (result);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondDoTarget --
+ * See if the given node exists and is an actual target.
+ *
+ * Results:
+ * TRUE if the node exists as a target and FALSE if it does not.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+CondDoTarget(int argLen MAKE_ATTR_UNUSED, const char *arg)
+{
+ GNode *gn;
+
+ gn = Targ_FindNode(arg, TARG_NOCREATE);
+ return (gn != NULL) && !OP_NOP(gn->type);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondDoCommands --
+ * See if the given node exists and is an actual target with commands
+ * associated with it.
+ *
+ * Results:
+ * TRUE if the node exists as a target and has commands associated with
+ * it and FALSE if it does not.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+CondDoCommands(int argLen MAKE_ATTR_UNUSED, const char *arg)
+{
+ GNode *gn;
+
+ gn = Targ_FindNode(arg, TARG_NOCREATE);
+ return (gn != NULL) && !OP_NOP(gn->type) && !Lst_IsEmpty(gn->commands);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondCvtArg --
+ * Convert the given number into a double.
+ * We try a base 10 or 16 integer conversion first, if that fails
+ * then we try a floating point conversion instead.
+ *
+ * Results:
+ * Sets 'value' to double value of string.
+ * Returns 'true' if the convertion suceeded
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+CondCvtArg(char *str, double *value)
+{
+ char *eptr, ech;
+ unsigned long l_val;
+ double d_val;
+
+ errno = 0;
+ l_val = strtoul(str, &eptr, str[1] == 'x' ? 16 : 10);
+ ech = *eptr;
+ if (ech == 0 && errno != ERANGE) {
+ d_val = str[0] == '-' ? -(double)-l_val : (double)l_val;
+ } else {
+ if (ech != 0 && ech != '.' && ech != 'e' && ech != 'E')
+ return FALSE;
+ d_val = strtod(str, &eptr);
+ if (*eptr)
+ return FALSE;
+ }
+
+ *value = d_val;
+ return TRUE;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondGetString --
+ * Get a string from a variable reference or an optionally quoted
+ * string. This is called for the lhs and rhs of string compares.
+ *
+ * Results:
+ * Sets freeIt if needed,
+ * Sets quoted if string was quoted,
+ * Returns NULL on error,
+ * else returns string - absent any quotes.
+ *
+ * Side Effects:
+ * Moves condExpr to end of this token.
+ *
+ *
+ *-----------------------------------------------------------------------
+ */
+/* coverity:[+alloc : arg-*2] */
+static char *
+CondGetString(Boolean doEval, Boolean *quoted, void **freeIt)
+{
+ Buffer buf;
+ char *cp;
+ char *str;
+ int len;
+ int qt;
+ char *start;
+
+ Buf_Init(&buf, 0);
+ str = NULL;
+ *freeIt = NULL;
+ *quoted = qt = *condExpr == '"' ? 1 : 0;
+ if (qt)
+ condExpr++;
+ for (start = condExpr; *condExpr && str == NULL; condExpr++) {
+ switch (*condExpr) {
+ case '\\':
+ if (condExpr[1] != '\0') {
+ condExpr++;
+ Buf_AddByte(&buf, *condExpr);
+ }
+ break;
+ case '"':
+ if (qt) {
+ condExpr++; /* we don't want the quotes */
+ goto got_str;
+ } else
+ Buf_AddByte(&buf, *condExpr); /* likely? */
+ break;
+ case ')':
+ case '!':
+ case '=':
+ case '>':
+ case '<':
+ case ' ':
+ case '\t':
+ if (!qt)
+ goto got_str;
+ else
+ Buf_AddByte(&buf, *condExpr);
+ break;
+ case '$':
+ /* if we are in quotes, then an undefined variable is ok */
+ str = Var_Parse(condExpr, VAR_CMD, (qt ? 0 : doEval),
+ &len, freeIt);
+ if (str == var_Error) {
+ if (*freeIt) {
+ free(*freeIt);
+ *freeIt = NULL;
+ }
+ /*
+ * Even if !doEval, we still report syntax errors, which
+ * is what getting var_Error back with !doEval means.
+ */
+ str = NULL;
+ goto cleanup;
+ }
+ condExpr += len;
+ /*
+ * If the '$' was first char (no quotes), and we are
+ * followed by space, the operator or end of expression,
+ * we are done.
+ */
+ if ((condExpr == start + len) &&
+ (*condExpr == '\0' ||
+ isspace((unsigned char) *condExpr) ||
+ strchr("!=><)", *condExpr))) {
+ goto cleanup;
+ }
+ /*
+ * Nope, we better copy str to buf
+ */
+ for (cp = str; *cp; cp++) {
+ Buf_AddByte(&buf, *cp);
+ }
+ if (*freeIt) {
+ free(*freeIt);
+ *freeIt = NULL;
+ }
+ str = NULL; /* not finished yet */
+ condExpr--; /* don't skip over next char */
+ break;
+ default:
+ Buf_AddByte(&buf, *condExpr);
+ break;
+ }
+ }
+ got_str:
+ str = Buf_GetAll(&buf, NULL);
+ *freeIt = str;
+ cleanup:
+ Buf_Destroy(&buf, FALSE);
+ return str;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondToken --
+ * Return the next token from the input.
+ *
+ * Results:
+ * A Token for the next lexical token in the stream.
+ *
+ * Side Effects:
+ * condPushback will be set back to TOK_NONE if it is used.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Token
+compare_expression(Boolean doEval)
+{
+ Token t;
+ char *lhs;
+ char *rhs;
+ char *op;
+ void *lhsFree;
+ void *rhsFree;
+ Boolean lhsQuoted;
+ Boolean rhsQuoted;
+ double left, right;
+
+ t = TOK_ERROR;
+ rhs = NULL;
+ lhsFree = rhsFree = FALSE;
+ lhsQuoted = rhsQuoted = FALSE;
+
+ /*
+ * Parse the variable spec and skip over it, saving its
+ * value in lhs.
+ */
+ lhs = CondGetString(doEval, &lhsQuoted, &lhsFree);
+ if (!lhs)
+ goto done;
+
+ /*
+ * Skip whitespace to get to the operator
+ */
+ while (isspace((unsigned char) *condExpr))
+ condExpr++;
+
+ /*
+ * Make sure the operator is a valid one. If it isn't a
+ * known relational operator, pretend we got a
+ * != 0 comparison.
+ */
+ op = condExpr;
+ switch (*condExpr) {
+ case '!':
+ case '=':
+ case '<':
+ case '>':
+ if (condExpr[1] == '=') {
+ condExpr += 2;
+ } else {
+ condExpr += 1;
+ }
+ break;
+ default:
+ if (!doEval) {
+ t = TOK_FALSE;
+ goto done;
+ }
+ /* For .ifxxx "..." check for non-empty string. */
+ if (lhsQuoted) {
+ t = lhs[0] != 0;
+ goto done;
+ }
+ /* For .ifxxx <number> compare against zero */
+ if (CondCvtArg(lhs, &left)) {
+ t = left != 0.0;
+ goto done;
+ }
+ /* For .if ${...} check for non-empty string (defProc is ifdef). */
+ if (if_info->form[0] == 0) {
+ t = lhs[0] != 0;
+ goto done;
+ }
+ /* Otherwise action default test ... */
+ t = if_info->defProc(strlen(lhs), lhs) != if_info->doNot;
+ goto done;
+ }
+
+ while (isspace((unsigned char)*condExpr))
+ condExpr++;
+
+ if (*condExpr == '\0') {
+ Parse_Error(PARSE_WARNING,
+ "Missing right-hand-side of operator");
+ goto done;
+ }
+
+ rhs = CondGetString(doEval, &rhsQuoted, &rhsFree);
+ if (!rhs)
+ goto done;
+
+ if (rhsQuoted || lhsQuoted) {
+do_string_compare:
+ if (((*op != '!') && (*op != '=')) || (op[1] != '=')) {
+ Parse_Error(PARSE_WARNING,
+ "String comparison operator should be either == or !=");
+ goto done;
+ }
+
+ if (DEBUG(COND)) {
+ fprintf(debug_file, "lhs = \"%s\", rhs = \"%s\", op = %.2s\n",
+ lhs, rhs, op);
+ }
+ /*
+ * Null-terminate rhs and perform the comparison.
+ * t is set to the result.
+ */
+ if (*op == '=') {
+ t = strcmp(lhs, rhs) == 0;
+ } else {
+ t = strcmp(lhs, rhs) != 0;
+ }
+ } else {
+ /*
+ * rhs is either a float or an integer. Convert both the
+ * lhs and the rhs to a double and compare the two.
+ */
+
+ if (!CondCvtArg(lhs, &left) || !CondCvtArg(rhs, &right))
+ goto do_string_compare;
+
+ if (DEBUG(COND)) {
+ fprintf(debug_file, "left = %f, right = %f, op = %.2s\n", left,
+ right, op);
+ }
+ switch(op[0]) {
+ case '!':
+ if (op[1] != '=') {
+ Parse_Error(PARSE_WARNING,
+ "Unknown operator");
+ goto done;
+ }
+ t = (left != right);
+ break;
+ case '=':
+ if (op[1] != '=') {
+ Parse_Error(PARSE_WARNING,
+ "Unknown operator");
+ goto done;
+ }
+ t = (left == right);
+ break;
+ case '<':
+ if (op[1] == '=') {
+ t = (left <= right);
+ } else {
+ t = (left < right);
+ }
+ break;
+ case '>':
+ if (op[1] == '=') {
+ t = (left >= right);
+ } else {
+ t = (left > right);
+ }
+ break;
+ }
+ }
+
+done:
+ if (lhsFree)
+ free(lhsFree);
+ if (rhsFree)
+ free(rhsFree);
+ return t;
+}
+
+static int
+get_mpt_arg(char **linePtr, char **argPtr, const char *func MAKE_ATTR_UNUSED)
+{
+ /*
+ * Use Var_Parse to parse the spec in parens and return
+ * TOK_TRUE if the resulting string is empty.
+ */
+ int length;
+ void *freeIt;
+ char *val;
+ char *cp = *linePtr;
+
+ /* We do all the work here and return the result as the length */
+ *argPtr = NULL;
+
+ val = Var_Parse(cp - 1, VAR_CMD, FALSE, &length, &freeIt);
+ /*
+ * Advance *linePtr to beyond the closing ). Note that
+ * we subtract one because 'length' is calculated from 'cp - 1'.
+ */
+ *linePtr = cp - 1 + length;
+
+ if (val == var_Error) {
+ free(freeIt);
+ return -1;
+ }
+
+ /* A variable is empty when it just contains spaces... 4/15/92, christos */
+ while (isspace(*(unsigned char *)val))
+ val++;
+
+ /*
+ * For consistency with the other functions we can't generate the
+ * true/false here.
+ */
+ length = *val ? 2 : 1;
+ if (freeIt)
+ free(freeIt);
+ return length;
+}
+
+static Boolean
+CondDoEmpty(int arglen, const char *arg MAKE_ATTR_UNUSED)
+{
+ return arglen == 1;
+}
+
+static Token
+compare_function(Boolean doEval)
+{
+ static const struct fn_def {
+ const char *fn_name;
+ int fn_name_len;
+ int (*fn_getarg)(char **, char **, const char *);
+ Boolean (*fn_proc)(int, const char *);
+ } fn_defs[] = {
+ { "defined", 7, CondGetArg, CondDoDefined },
+ { "make", 4, CondGetArg, CondDoMake },
+ { "exists", 6, CondGetArg, CondDoExists },
+ { "empty", 5, get_mpt_arg, CondDoEmpty },
+ { "target", 6, CondGetArg, CondDoTarget },
+ { "commands", 8, CondGetArg, CondDoCommands },
+ { NULL, 0, NULL, NULL },
+ };
+ const struct fn_def *fn_def;
+ Token t;
+ char *arg = NULL;
+ int arglen;
+ char *cp = condExpr;
+ char *cp1;
+
+ for (fn_def = fn_defs; fn_def->fn_name != NULL; fn_def++) {
+ if (!istoken(cp, fn_def->fn_name, fn_def->fn_name_len))
+ continue;
+ cp += fn_def->fn_name_len;
+ /* There can only be whitespace before the '(' */
+ while (isspace(*(unsigned char *)cp))
+ cp++;
+ if (*cp != '(')
+ break;
+
+ arglen = fn_def->fn_getarg(&cp, &arg, fn_def->fn_name);
+ if (arglen <= 0) {
+ condExpr = cp;
+ return arglen < 0 ? TOK_ERROR : TOK_FALSE;
+ }
+ /* Evaluate the argument using the required function. */
+ t = !doEval || fn_def->fn_proc(arglen, arg);
+ if (arg)
+ free(arg);
+ condExpr = cp;
+ return t;
+ }
+
+ /* Push anything numeric through the compare expression */
+ cp = condExpr;
+ if (isdigit((unsigned char)cp[0]) || strchr("+-", cp[0]))
+ return compare_expression(doEval);
+
+ /*
+ * Most likely we have a naked token to apply the default function to.
+ * However ".if a == b" gets here when the "a" is unquoted and doesn't
+ * start with a '$'. This surprises people.
+ * If what follows the function argument is a '=' or '!' then the syntax
+ * would be invalid if we did "defined(a)" - so instead treat as an
+ * expression.
+ */
+ arglen = CondGetArg(&cp, &arg, NULL);
+ for (cp1 = cp; isspace(*(unsigned char *)cp1); cp1++)
+ continue;
+ if (*cp1 == '=' || *cp1 == '!')
+ return compare_expression(doEval);
+ condExpr = cp;
+
+ /*
+ * Evaluate the argument using the default function.
+ * This path always treats .if as .ifdef. To get here the character
+ * after .if must have been taken literally, so the argument cannot
+ * be empty - even if it contained a variable expansion.
+ */
+ t = !doEval || if_info->defProc(arglen, arg) != if_info->doNot;
+ if (arg)
+ free(arg);
+ return t;
+}
+
+static Token
+CondToken(Boolean doEval)
+{
+ Token t;
+
+ t = condPushBack;
+ if (t != TOK_NONE) {
+ condPushBack = TOK_NONE;
+ return t;
+ }
+
+ while (*condExpr == ' ' || *condExpr == '\t') {
+ condExpr++;
+ }
+
+ switch (*condExpr) {
+
+ case '(':
+ condExpr++;
+ return TOK_LPAREN;
+
+ case ')':
+ condExpr++;
+ return TOK_RPAREN;
+
+ case '|':
+ if (condExpr[1] == '|') {
+ condExpr++;
+ }
+ condExpr++;
+ return TOK_OR;
+
+ case '&':
+ if (condExpr[1] == '&') {
+ condExpr++;
+ }
+ condExpr++;
+ return TOK_AND;
+
+ case '!':
+ condExpr++;
+ return TOK_NOT;
+
+ case '#':
+ case '\n':
+ case '\0':
+ return TOK_EOF;
+
+ case '"':
+ case '$':
+ return compare_expression(doEval);
+
+ default:
+ return compare_function(doEval);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondT --
+ * Parse a single term in the expression. This consists of a terminal
+ * symbol or TOK_NOT and a terminal symbol (not including the binary
+ * operators):
+ * T -> defined(variable) | make(target) | exists(file) | symbol
+ * T -> ! T | ( E )
+ *
+ * Results:
+ * TOK_TRUE, TOK_FALSE or TOK_ERROR.
+ *
+ * Side Effects:
+ * Tokens are consumed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Token
+CondT(Boolean doEval)
+{
+ Token t;
+
+ t = CondToken(doEval);
+
+ if (t == TOK_EOF) {
+ /*
+ * If we reached the end of the expression, the expression
+ * is malformed...
+ */
+ t = TOK_ERROR;
+ } else if (t == TOK_LPAREN) {
+ /*
+ * T -> ( E )
+ */
+ t = CondE(doEval);
+ if (t != TOK_ERROR) {
+ if (CondToken(doEval) != TOK_RPAREN) {
+ t = TOK_ERROR;
+ }
+ }
+ } else if (t == TOK_NOT) {
+ t = CondT(doEval);
+ if (t == TOK_TRUE) {
+ t = TOK_FALSE;
+ } else if (t == TOK_FALSE) {
+ t = TOK_TRUE;
+ }
+ }
+ return (t);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondF --
+ * Parse a conjunctive factor (nice name, wot?)
+ * F -> T && F | T
+ *
+ * Results:
+ * TOK_TRUE, TOK_FALSE or TOK_ERROR
+ *
+ * Side Effects:
+ * Tokens are consumed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Token
+CondF(Boolean doEval)
+{
+ Token l, o;
+
+ l = CondT(doEval);
+ if (l != TOK_ERROR) {
+ o = CondToken(doEval);
+
+ if (o == TOK_AND) {
+ /*
+ * F -> T && F
+ *
+ * If T is TOK_FALSE, the whole thing will be TOK_FALSE, but we have to
+ * parse the r.h.s. anyway (to throw it away).
+ * If T is TOK_TRUE, the result is the r.h.s., be it an TOK_ERROR or no.
+ */
+ if (l == TOK_TRUE) {
+ l = CondF(doEval);
+ } else {
+ (void)CondF(FALSE);
+ }
+ } else {
+ /*
+ * F -> T
+ */
+ CondPushBack(o);
+ }
+ }
+ return (l);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * CondE --
+ * Main expression production.
+ * E -> F || E | F
+ *
+ * Results:
+ * TOK_TRUE, TOK_FALSE or TOK_ERROR.
+ *
+ * Side Effects:
+ * Tokens are, of course, consumed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Token
+CondE(Boolean doEval)
+{
+ Token l, o;
+
+ l = CondF(doEval);
+ if (l != TOK_ERROR) {
+ o = CondToken(doEval);
+
+ if (o == TOK_OR) {
+ /*
+ * E -> F || E
+ *
+ * A similar thing occurs for ||, except that here we make sure
+ * the l.h.s. is TOK_FALSE before we bother to evaluate the r.h.s.
+ * Once again, if l is TOK_FALSE, the result is the r.h.s. and once
+ * again if l is TOK_TRUE, we parse the r.h.s. to throw it away.
+ */
+ if (l == TOK_FALSE) {
+ l = CondE(doEval);
+ } else {
+ (void)CondE(FALSE);
+ }
+ } else {
+ /*
+ * E -> F
+ */
+ CondPushBack(o);
+ }
+ }
+ return (l);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Cond_EvalExpression --
+ * Evaluate an expression in the passed line. The expression
+ * consists of &&, ||, !, make(target), defined(variable)
+ * and parenthetical groupings thereof.
+ *
+ * Results:
+ * COND_PARSE if the condition was valid grammatically
+ * COND_INVALID if not a valid conditional.
+ *
+ * (*value) is set to the boolean value of the condition
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+int
+Cond_EvalExpression(const struct If *info, char *line, Boolean *value, int eprint)
+{
+ static const struct If *dflt_info;
+ const struct If *sv_if_info = if_info;
+ char *sv_condExpr = condExpr;
+ Token sv_condPushBack = condPushBack;
+ int rval;
+
+ while (*line == ' ' || *line == '\t')
+ line++;
+
+ if (info == NULL && (info = dflt_info) == NULL) {
+ /* Scan for the entry for .if - it can't be first */
+ for (info = ifs; ; info++)
+ if (info->form[0] == 0)
+ break;
+ dflt_info = info;
+ }
+
+ if_info = info != NULL ? info : ifs + 4;
+ condExpr = line;
+ condPushBack = TOK_NONE;
+
+ rval = do_Cond_EvalExpression(value);
+
+ if (rval == COND_INVALID && eprint)
+ Parse_Error(PARSE_FATAL, "Malformed conditional (%s)", line);
+
+ if_info = sv_if_info;
+ condExpr = sv_condExpr;
+ condPushBack = sv_condPushBack;
+
+ return rval;
+}
+
+static int
+do_Cond_EvalExpression(Boolean *value)
+{
+
+ switch (CondE(TRUE)) {
+ case TOK_TRUE:
+ if (CondToken(TRUE) == TOK_EOF) {
+ *value = TRUE;
+ return COND_PARSE;
+ }
+ break;
+ case TOK_FALSE:
+ if (CondToken(TRUE) == TOK_EOF) {
+ *value = FALSE;
+ return COND_PARSE;
+ }
+ break;
+ default:
+ case TOK_ERROR:
+ break;
+ }
+
+ return COND_INVALID;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Cond_Eval --
+ * Evaluate the conditional in the passed line. The line
+ * looks like this:
+ * .<cond-type> <expr>
+ * where <cond-type> is any of if, ifmake, ifnmake, ifdef,
+ * ifndef, elif, elifmake, elifnmake, elifdef, elifndef
+ * and <expr> consists of &&, ||, !, make(target), defined(variable)
+ * and parenthetical groupings thereof.
+ *
+ * Input:
+ * line Line to parse
+ *
+ * Results:
+ * COND_PARSE if should parse lines after the conditional
+ * COND_SKIP if should skip lines after the conditional
+ * COND_INVALID if not a valid conditional.
+ *
+ * Side Effects:
+ * None.
+ *
+ * Note that the states IF_ACTIVE and ELSE_ACTIVE are only different in order
+ * to detect splurious .else lines (as are SKIP_TO_ELSE and SKIP_TO_ENDIF)
+ * otherwise .else could be treated as '.elif 1'.
+ *
+ *-----------------------------------------------------------------------
+ */
+int
+Cond_Eval(char *line)
+{
+ #define MAXIF 128 /* maximum depth of .if'ing */
+ enum if_states {
+ IF_ACTIVE, /* .if or .elif part active */
+ ELSE_ACTIVE, /* .else part active */
+ SEARCH_FOR_ELIF, /* searching for .elif/else to execute */
+ SKIP_TO_ELSE, /* has been true, but not seen '.else' */
+ SKIP_TO_ENDIF /* nothing else to execute */
+ };
+ static enum if_states cond_state[MAXIF + 1] = { IF_ACTIVE };
+
+ const struct If *ifp;
+ Boolean isElif;
+ Boolean value;
+ int level; /* Level at which to report errors. */
+ enum if_states state;
+
+ level = PARSE_FATAL;
+
+ /* skip leading character (the '.') and any whitespace */
+ for (line++; *line == ' ' || *line == '\t'; line++)
+ continue;
+
+ /* Find what type of if we're dealing with. */
+ if (line[0] == 'e') {
+ if (line[1] != 'l') {
+ if (!istoken(line + 1, "ndif", 4))
+ return COND_INVALID;
+ /* End of conditional section */
+ if (cond_depth == cond_min_depth) {
+ Parse_Error(level, "if-less endif");
+ return COND_PARSE;
+ }
+ /* Return state for previous conditional */
+ cond_depth--;
+ if (cond_depth > MAXIF)
+ return COND_SKIP;
+ return cond_state[cond_depth] <= ELSE_ACTIVE ? COND_PARSE : COND_SKIP;
+ }
+
+ /* Quite likely this is 'else' or 'elif' */
+ line += 2;
+ if (istoken(line, "se", 2)) {
+ /* It is else... */
+ if (cond_depth == cond_min_depth) {
+ Parse_Error(level, "if-less else");
+ return COND_PARSE;
+ }
+
+ if (cond_depth > MAXIF)
+ return COND_SKIP;
+ state = cond_state[cond_depth];
+ switch (state) {
+ case SEARCH_FOR_ELIF:
+ state = ELSE_ACTIVE;
+ break;
+ case ELSE_ACTIVE:
+ case SKIP_TO_ENDIF:
+ Parse_Error(PARSE_WARNING, "extra else");
+ /* FALLTHROUGH */
+ default:
+ case IF_ACTIVE:
+ case SKIP_TO_ELSE:
+ state = SKIP_TO_ENDIF;
+ break;
+ }
+ cond_state[cond_depth] = state;
+ return state <= ELSE_ACTIVE ? COND_PARSE : COND_SKIP;
+ }
+ /* Assume for now it is an elif */
+ isElif = TRUE;
+ } else
+ isElif = FALSE;
+
+ if (line[0] != 'i' || line[1] != 'f')
+ /* Not an ifxxx or elifxxx line */
+ return COND_INVALID;
+
+ /*
+ * Figure out what sort of conditional it is -- what its default
+ * function is, etc. -- by looking in the table of valid "ifs"
+ */
+ line += 2;
+ for (ifp = ifs; ; ifp++) {
+ if (ifp->form == NULL)
+ return COND_INVALID;
+ if (istoken(ifp->form, line, ifp->formlen)) {
+ line += ifp->formlen;
+ break;
+ }
+ }
+
+ /* Now we know what sort of 'if' it is... */
+
+ if (isElif) {
+ if (cond_depth == cond_min_depth) {
+ Parse_Error(level, "if-less elif");
+ return COND_PARSE;
+ }
+ if (cond_depth > MAXIF)
+ /* Error reported when we saw the .if ... */
+ return COND_SKIP;
+ state = cond_state[cond_depth];
+ if (state == SKIP_TO_ENDIF || state == ELSE_ACTIVE) {
+ Parse_Error(PARSE_WARNING, "extra elif");
+ cond_state[cond_depth] = SKIP_TO_ENDIF;
+ return COND_SKIP;
+ }
+ if (state != SEARCH_FOR_ELIF) {
+ /* Either just finished the 'true' block, or already SKIP_TO_ELSE */
+ cond_state[cond_depth] = SKIP_TO_ELSE;
+ return COND_SKIP;
+ }
+ } else {
+ /* Normal .if */
+ if (cond_depth >= MAXIF) {
+ cond_depth++;
+ Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.", MAXIF);
+ return COND_SKIP;
+ }
+ state = cond_state[cond_depth];
+ cond_depth++;
+ if (state > ELSE_ACTIVE) {
+ /* If we aren't parsing the data, treat as always false */
+ cond_state[cond_depth] = SKIP_TO_ELSE;
+ return COND_SKIP;
+ }
+ }
+
+ /* And evaluate the conditional expresssion */
+ if (Cond_EvalExpression(ifp, line, &value, 1) == COND_INVALID) {
+ /* Syntax error in conditional, error message already output. */
+ /* Skip everything to matching .endif */
+ cond_state[cond_depth] = SKIP_TO_ELSE;
+ return COND_SKIP;
+ }
+
+ if (!value) {
+ cond_state[cond_depth] = SEARCH_FOR_ELIF;
+ return COND_SKIP;
+ }
+ cond_state[cond_depth] = IF_ACTIVE;
+ return COND_PARSE;
+}
+
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Cond_End --
+ * Make sure everything's clean at the end of a makefile.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Parse_Error will be called if open conditionals are around.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Cond_restore_depth(unsigned int saved_depth)
+{
+ int open_conds = cond_depth - cond_min_depth;
+
+ if (open_conds != 0 || saved_depth > cond_depth) {
+ Parse_Error(PARSE_FATAL, "%d open conditional%s", open_conds,
+ open_conds == 1 ? "" : "s");
+ cond_depth = cond_min_depth;
+ }
+
+ cond_min_depth = saved_depth;
+}
+
+unsigned int
+Cond_save_depth(void)
+{
+ int depth = cond_min_depth;
+
+ cond_min_depth = cond_depth;
+ return depth;
+}
diff --git a/external/bsd/bmake/dist/config.h.in b/external/bsd/bmake/dist/config.h.in
new file mode 100644
index 0000000..7108dcf
--- /dev/null
+++ b/external/bsd/bmake/dist/config.h.in
@@ -0,0 +1,314 @@
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Path of default shell */
+#undef DEFSHELL_CUSTOM
+
+/* Shell spec to use by default */
+#undef DEFSHELL_INDEX
+
+/* Define to 1 if you have the <ar.h> header file. */
+#undef HAVE_AR_H
+
+/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SYS_SIGLIST
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the `dirname' function. */
+#undef HAVE_DIRNAME
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* Define to 1 if you have the `err' function. */
+#undef HAVE_ERR
+
+/* Define to 1 if you have the `errx' function. */
+#undef HAVE_ERRX
+
+/* Define to 1 if you have the <err.h> header file. */
+#undef HAVE_ERR_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `getenv' function. */
+#undef HAVE_GETENV
+
+/* Define to 1 if you have the `getopt' function. */
+#undef HAVE_GETOPT
+
+/* Define to 1 if you have the `getwd' function. */
+#undef HAVE_GETWD
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `killpg' function. */
+#undef HAVE_KILLPG
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <paths.h> header file. */
+#undef HAVE_PATHS_H
+
+/* Define to 1 if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the <ranlib.h> header file. */
+#undef HAVE_RANLIB_H
+
+/* Define to 1 if you have the `realpath' function. */
+#undef HAVE_REALPATH
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Define to 1 if you have the `setpgid' function. */
+#undef HAVE_SETPGID
+
+/* Define to 1 if you have the `setsid' function. */
+#undef HAVE_SETSID
+
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the `sigvec' function. */
+#undef HAVE_SIGVEC
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `stresep' function. */
+#undef HAVE_STRESEP
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define to 1 if you have the `strsep' function. */
+#undef HAVE_STRSEP
+
+/* Define to 1 if you have the `strtod' function. */
+#undef HAVE_STRTOD
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Define to 1 if `struct stat' is a member of `st_rdev'. */
+#undef HAVE_STRUCT_STAT_ST_RDEV
+
+/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
+ `HAVE_STRUCT_STAT_ST_RDEV' instead. */
+#undef HAVE_ST_RDEV
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `unsetenv' function. */
+#undef HAVE_UNSETENV
+
+/* Define to 1 if you have the <utime.h> header file. */
+#undef HAVE_UTIME_H
+
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+#undef HAVE_VFORK_H
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if you have the `wait3' function. */
+#undef HAVE_WAIT3
+
+/* Define to 1 if you have the `wait4' function. */
+#undef HAVE_WAIT4
+
+/* Define to 1 if you have the `waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define to 1 if you have the `warn' function. */
+#undef HAVE_WARN
+
+/* Define to 1 if you have the `warnx' function. */
+#undef HAVE_WARNX
+
+/* Define to 1 if `fork' works. */
+#undef HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
+
+/* define if your compiler has __attribute__ */
+#undef HAVE___ATTRIBUTE__
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+#undef STAT_MACROS_BROKEN
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `long int' if <sys/types.h> does not define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define as `fork' if `vfork' does not work. */
+#undef vfork
diff --git a/external/bsd/bmake/dist/configure b/external/bsd/bmake/dist/configure
new file mode 100755
index 0000000..ee479f1
--- /dev/null
+++ b/external/bsd/bmake/dist/configure
@@ -0,0 +1,7134 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.64 for bmake 20120620.
+#
+# Report bugs to <sjg@NetBSD.org>.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
+# Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+ # works around shells that cannot unset nonexistent variables.
+ BASH_ENV=/dev/null
+ ENV=/dev/null
+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and sjg@NetBSD.org
+$0: about your system, including any error possibly output
+$0: before this message. Then install a modern shell, or
+$0: manually run the script under such a shell if you do
+$0: have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='bmake'
+PACKAGE_TARNAME='bmake'
+PACKAGE_VERSION='20120620'
+PACKAGE_STRING='bmake 20120620'
+PACKAGE_BUGREPORT='sjg@NetBSD.org'
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+filemon_h
+use_meta
+diff_u
+GCC
+INSTALL
+default_sys_path
+mksrc
+machine_arch
+force_machine
+machine
+LIBOBJS
+ac_exe_suffix
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_defshell
+with_meta
+with_filemon
+with_machine
+with_force_machine
+with_force_machine_arch
+with_machine_arch
+with_default_sys_path
+with_path_objdirprefix
+enable_pwd_override
+enable_check_make_chdir
+with_mksrc
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures bmake 20120620 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/bmake]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of bmake 20120620:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --disable-pwd-override disable \$PWD overriding getcwd()
+ --disable-check-make-chdir disable make trying to guess
+ when it should automatically cd \${.CURDIR}
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-defshell=SHELL use SHELL by default - must be sh compatible, use sh or ksh to pick the internal definitions
+ --without-meta dissable use of meta-mode
+ --with-filemon=path/filemon.h indicate path to filemon.h for meta-mode
+ --with-machine=MACHINE explicitly set MACHINE
+ --with-force-machine=MACHINE set FORCE_MACHINE
+ --with-force-machine-arch=MACHINE set FORCE_MACHINE_ARCH
+ --with-machine_arch=MACHINE_ARCH explicitly set MACHINE_ARCH
+ --with-default-sys-path=PATH:DIR:LIST use an explicit _PATH_DEFSYSPATH
+ MAKESYSPATH is a ':' separated list of directories
+ that bmake will search for system .mk files.
+ _PATH_DEFSYSPATH is its default value.
+ --with-path-objdirprefix=PATH override _PATH_OBJDIRPREFIX
+ --with-mksrc=PATH tell makefile.boot where to find mk src
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <sjg@NetBSD.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+bmake configure 20120620
+generated by GNU Autoconf 2.64
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( cat <<\_ASBOX
+## ----------------------------- ##
+## Report this to sjg@NetBSD.org ##
+## ----------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR
+# ------------------------------------
+# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
+ac_fn_c_check_decl ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
+$as_echo_n "checking whether $2 is declared... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+#ifndef $2
+ (void) $2;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_decl
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_member
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by bmake $as_me 20120620, which was
+generated by GNU Autoconf 2.64. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+
+# Check whether --with-defshell was given.
+if test "${with_defshell+set}" = set; then :
+ withval=$with_defshell; case "${withval}" in
+yes) as_fn_error "bad value ${withval} given for bmake DEFSHELL" "$LINENO" 5 ;;
+no) ;;
+*) case "$with_defshell" in
+ sh) DEFSHELL_INDEX=DEFSHELL_INDEX_SH;; # it's the default anyway
+ ksh) DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;;
+ csh) DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;; # kidding right?
+ *) defshell_path=$with_defshell;; # better be sh compatible!
+ esac
+ ;;
+ esac
+fi
+
+use_meta=yes
+
+# Check whether --with-meta was given.
+if test "${with_meta+set}" = set; then :
+ withval=$with_meta; case "${withval}" in
+yes|no) use_meta=${withval};;
+*) as_fn_error "bad value ${withval} given for meta" "$LINENO" 5 ;;
+esac
+fi
+
+
+# Check whether --with-filemon was given.
+if test "${with_filemon+set}" = set; then :
+ withval=$with_filemon; case "/${withval}" in
+/no|*/filemon.h) filemon_h="${withval}";;
+*/filemon*) filemon_h="${withval}/filemon.h";;
+*) as_fn_error "bad value ${withval} given for filemon" "$LINENO" 5 ;;
+esac
+else
+
+OS=`uname -s`
+for d in "/usr/include/dev/filemon" "$prefix/include/dev/filemon" "$srcdir/filemon" "$srcdir/../filemon" "$srcdir/../../sys/dev/filemon"
+do
+ for x in "/$OS" ""
+ do
+ filemon_h="$d$x/filemon.h"
+ test -s "$filemon_h" && break
+ done
+ test -s "$filemon_h" && break
+done
+test -s "${filemon_h:-/dev/null}" || filemon_h=no
+
+fi
+
+case "$use_meta" in
+yes)
+ case "$filemon_h" in
+ *.h) echo "Using: filemon=$filemon_h" >&6;;
+ esac
+ ;;
+esac
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ rm -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then :
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
+fi
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = x""yes; then :
+ MINIX=yes
+else
+ MINIX=
+fi
+
+
+ if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if test "${ac_cv_safe_to_define___extensions__+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# define __EXTENSIONS__ 1
+ $ac_includes_default
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_safe_to_define___extensions__=yes
+else
+ ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+ test $ac_cv_safe_to_define___extensions__ = yes &&
+ $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+ $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+ $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ rm -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test $ac_cv_c_compiler_gnu = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5
+$as_echo_n "checking whether $CC needs -traditional... " >&6; }
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+ ac_cv_prog_gcc_traditional=yes
+else
+ ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "$ac_pattern" >/dev/null 2>&1; then :
+ ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5
+$as_echo "$ac_cv_prog_gcc_traditional" >&6; }
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ for ac_t in install-sh install.sh shtool; do
+ if test -f "$ac_dir/$ac_t"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/$ac_t -c"
+ break 2
+ fi
+ done
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+echo $ECHO_N "checking if sh will pass .MAKE. variables... $ECHO_C" >&6
+ok=`env .MAKE.LEVEL=1 /bin/sh -c env | grep LEVEL=`
+case "$ok" in
+"") echo no >&6; CPPFLAGS="${CPPFLAGS} -DNEED_MAKE_LEVEL_SAFE";;
+*) echo yes >&6;;
+esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
+$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
+if test "${ac_cv_header_sys_wait_h+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+int
+main ()
+{
+ int s;
+ wait (&s);
+ s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_sys_wait_h=yes
+else
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
+$as_echo "$ac_cv_header_sys_wait_h" >&6; }
+if test $ac_cv_header_sys_wait_h = yes; then
+
+$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+ as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$as_ac_Header=yes"
+else
+ eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_opendir+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_opendir+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+for ac_header in \
+ ar.h \
+ err.h \
+ fcntl.h \
+ paths.h \
+ poll.h \
+ ranlib.h \
+ string.h \
+ sys/mman.h \
+ sys/select.h \
+ sys/socket.h \
+ sys/time.h \
+ sys/uio.h \
+ unistd.h \
+ utime.h \
+
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "sys/cdefs.h" "ac_cv_header_sys_cdefs_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_cdefs_h" = x""yes; then :
+ echo $ECHO_N "checking whether sys/cdefs.h is compatible... $ECHO_C" >&6
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/cdefs.h>
+#ifdef __RCSID
+yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "yes" >/dev/null 2>&1; then :
+ echo yes >&6
+else
+ echo no >&6; CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd` -DNEED_HOST_CDEFS_H"
+fi
+rm -f conftest*
+
+else
+ CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd`"
+fi
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__" >&5
+$as_echo_n "checking for __attribute__... " >&6; }
+if test "${ac_cv___attribute__+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdlib.h>
+
+int
+main ()
+{
+
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+ exit(1);
+}
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv___attribute__=yes
+else
+ ac_cv___attribute__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test "$ac_cv___attribute__" = "yes"; then
+
+$as_echo "#define HAVE___ATTRIBUTE__ 1" >>confdefs.h
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute__" >&5
+$as_echo "$ac_cv___attribute__" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if test "${ac_cv_c_bigendian+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if test "${ac_cv_c_const+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this. */
+ typedef int charset[2];
+ const charset cs;
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_const=yes
+else
+ ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
+if test "x$ac_cv_type_off_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#include <signal.h>
+/* NetBSD declares sys_siglist in unistd.h. */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+"
+if test "x$ac_cv_have_decl_sys_siglist" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SYS_SIGLIST $ac_have_decl
+_ACEOF
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if test "${ac_cv_header_time+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_time=yes
+else
+ ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
+$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
+if test "${ac_cv_struct_tm+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main ()
+{
+struct tm tm;
+ int *p = &tm.tm_sec;
+ return !p;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_struct_tm=time.h
+else
+ ac_cv_struct_tm=sys/time.h
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5
+$as_echo "$ac_cv_struct_tm" >&6; }
+if test $ac_cv_struct_tm = sys/time.h; then
+
+$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
+$as_echo_n "checking return type of signal handlers... " >&6; }
+if test "${ac_cv_type_signal+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+return *(signal (0, 0)) (0) == 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_type_signal=int
+else
+ ac_cv_type_signal=void
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
+$as_echo "$ac_cv_type_signal" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+for ac_header in vfork.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
+if test "x$ac_cv_header_vfork_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VFORK_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in fork vfork
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test "x$ac_cv_func_fork" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
+$as_echo_n "checking for working fork... " >&6; }
+if test "${ac_cv_func_fork_works+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_fork_works=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* By Ruediger Kuhlmann. */
+ return fork () < 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_fork_works=yes
+else
+ ac_cv_func_fork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
+$as_echo "$ac_cv_func_fork_works" >&6; }
+
+else
+ ac_cv_func_fork_works=$ac_cv_func_fork
+fi
+if test "x$ac_cv_func_fork_works" = xcross; then
+ case $host in
+ *-*-amigaos* | *-*-msdosdjgpp*)
+ # Override, as these systems have only a dummy fork() stub
+ ac_cv_func_fork_works=no
+ ;;
+ *)
+ ac_cv_func_fork_works=yes
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
+fi
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+if test "x$ac_cv_func_vfork" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
+$as_echo_n "checking for working vfork... " >&6; }
+if test "${ac_cv_func_vfork_works+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_vfork_works=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Thanks to Paul Eggert for this test. */
+$ac_includes_default
+#include <sys/wait.h>
+#ifdef HAVE_VFORK_H
+# include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+ argument registers are propagated back to the parent. The compiler
+ is told about this with #include <vfork.h>, but some compilers
+ (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a
+ static variable whose address is put into a register that is
+ clobbered by the vfork. */
+static void
+#ifdef __cplusplus
+sparc_address_test (int arg)
+# else
+sparc_address_test (arg) int arg;
+#endif
+{
+ static pid_t child;
+ if (!child) {
+ child = vfork ();
+ if (child < 0) {
+ perror ("vfork");
+ _exit(2);
+ }
+ if (!child) {
+ arg = getpid();
+ write(-1, "", 0);
+ _exit (arg);
+ }
+ }
+}
+
+int
+main ()
+{
+ pid_t parent = getpid ();
+ pid_t child;
+
+ sparc_address_test (0);
+
+ child = vfork ();
+
+ if (child == 0) {
+ /* Here is another test for sparc vfork register problems. This
+ test uses lots of local variables, at least as many local
+ variables as main has allocated so far including compiler
+ temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
+ 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
+ reuse the register of parent for one of the local variables,
+ since it will think that parent can't possibly be used any more
+ in this routine. Assigning to the local variable will thus
+ munge parent in the parent process. */
+ pid_t
+ p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+ p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+ /* Convince the compiler that p..p7 are live; otherwise, it might
+ use the same hardware register for all 8 local variables. */
+ if (p != p1 || p != p2 || p != p3 || p != p4
+ || p != p5 || p != p6 || p != p7)
+ _exit(1);
+
+ /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+ from child file descriptors. If the child closes a descriptor
+ before it execs or exits, this munges the parent's descriptor
+ as well. Test for this by closing stdout in the child. */
+ _exit(close(fileno(stdout)) != 0);
+ } else {
+ int status;
+ struct stat st;
+
+ while (wait(&status) != child)
+ ;
+ return (
+ /* Was there some problem with vforking? */
+ child < 0
+
+ /* Did the child fail? (This shouldn't happen.) */
+ || status
+
+ /* Did the vfork/compiler bug occur? */
+ || parent != getpid()
+
+ /* Did the file descriptor bug occur? */
+ || fstat(fileno(stdout), &st) != 0
+ );
+ }
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_vfork_works=yes
+else
+ ac_cv_func_vfork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
+$as_echo "$ac_cv_func_vfork_works" >&6; }
+
+fi;
+if test "x$ac_cv_func_fork_works" = xcross; then
+ ac_cv_func_vfork_works=$ac_cv_func_vfork
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
+fi
+
+if test "x$ac_cv_func_vfork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
+
+else
+
+$as_echo "#define vfork fork" >>confdefs.h
+
+fi
+if test "x$ac_cv_func_fork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
+
+fi
+
+for ac_func in vprintf
+do :
+ ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
+if test "x$ac_cv_func_vprintf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VPRINTF 1
+_ACEOF
+
+ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
+if test "x$ac_cv_func__doprnt" = x""yes; then :
+
+$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
+
+fi
+
+fi
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for wait3 that fills in rusage" >&5
+$as_echo_n "checking for wait3 that fills in rusage... " >&6; }
+if test "${ac_cv_func_wait3_rusage+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_wait3_rusage=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+/* HP-UX has wait3 but does not fill in rusage at all. */
+int
+main ()
+{
+ struct rusage r;
+ int i;
+ /* Use a field that we can force nonzero --
+ voluntary context switches.
+ For systems like NeXT and OSF/1 that don't set it,
+ also use the system CPU time. And page faults (I/O) for Linux. */
+ r.ru_nvcsw = 0;
+ r.ru_stime.tv_sec = 0;
+ r.ru_stime.tv_usec = 0;
+ r.ru_majflt = r.ru_minflt = 0;
+ switch (fork ())
+ {
+ case 0: /* Child. */
+ sleep(1); /* Give up the CPU. */
+ _exit(0);
+ break;
+ case -1: /* What can we do? */
+ _exit(0);
+ break;
+ default: /* Parent. */
+ wait3(&i, 0, &r);
+ /* Avoid "text file busy" from rm on fast HP-UX machines. */
+ sleep(2);
+ return (r.ru_nvcsw == 0 && r.ru_majflt == 0 && r.ru_minflt == 0
+ && r.ru_stime.tv_sec == 0 && r.ru_stime.tv_usec == 0);
+ }
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_wait3_rusage=yes
+else
+ ac_cv_func_wait3_rusage=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_wait3_rusage" >&5
+$as_echo "$ac_cv_func_wait3_rusage" >&6; }
+if test $ac_cv_func_wait3_rusage = yes; then
+
+$as_echo "#define HAVE_WAIT3 1" >>confdefs.h
+
+fi
+
+for ac_func in \
+ err \
+ errx \
+ getcwd \
+ getenv \
+ getopt \
+ getwd \
+ killpg \
+ mmap \
+ putenv \
+ select \
+ setenv \
+ setpgid \
+ setsid \
+ sigaction \
+ sigvec \
+ snprintf \
+ strerror \
+ strftime \
+ strsep \
+ strtod \
+ strtol \
+ unsetenv \
+ vsnprintf \
+ wait3 \
+ wait4 \
+ waitpid \
+ warn \
+ warnx \
+
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+for ac_func in \
+ realpath \
+ dirname \
+ stresep \
+ strlcpy \
+
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+ case " $LIBOBJS " in
+ *" $ac_func.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
+ ;;
+esac
+
+fi
+done
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for emalloc in -lutil" >&5
+$as_echo_n "checking for emalloc in -lutil... " >&6; }
+if test "${ac_cv_lib_util_emalloc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lutil $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char emalloc ();
+int
+main ()
+{
+return emalloc ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_util_emalloc=yes
+else
+ ac_cv_lib_util_emalloc=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_emalloc" >&5
+$as_echo "$ac_cv_lib_util_emalloc" >&6; }
+if test "x$ac_cv_lib_util_emalloc" = x""yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erealloc in -lutil" >&5
+$as_echo_n "checking for erealloc in -lutil... " >&6; }
+if test "${ac_cv_lib_util_erealloc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lutil $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char erealloc ();
+int
+main ()
+{
+return erealloc ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_util_erealloc=yes
+else
+ ac_cv_lib_util_erealloc=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_erealloc" >&5
+$as_echo "$ac_cv_lib_util_erealloc" >&6; }
+if test "x$ac_cv_lib_util_erealloc" = x""yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for estrdup in -lutil" >&5
+$as_echo_n "checking for estrdup in -lutil... " >&6; }
+if test "${ac_cv_lib_util_estrdup+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lutil $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char estrdup ();
+int
+main ()
+{
+return estrdup ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_util_estrdup=yes
+else
+ ac_cv_lib_util_estrdup=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_estrdup" >&5
+$as_echo "$ac_cv_lib_util_estrdup" >&6; }
+if test "x$ac_cv_lib_util_estrdup" = x""yes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for estrndup in -lutil" >&5
+$as_echo_n "checking for estrndup in -lutil... " >&6; }
+if test "${ac_cv_lib_util_estrndup+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lutil $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char estrndup ();
+int
+main ()
+{
+return estrndup ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_util_estrndup=yes
+else
+ ac_cv_lib_util_estrndup=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_estrndup" >&5
+$as_echo "$ac_cv_lib_util_estrndup" >&6; }
+if test "x$ac_cv_lib_util_estrndup" = x""yes; then :
+ LIBS="$LIBS -lutil"
+ CPPFLAGS="$CPPFLAGS -DUSE_EMALLOC"
+fi
+
+fi
+
+fi
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat file-mode macros are broken" >&5
+$as_echo_n "checking whether stat file-mode macros are broken... " >&6; }
+if test "${ac_cv_header_stat_broken+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined S_ISBLK && defined S_IFDIR
+extern char c1[S_ISBLK (S_IFDIR) ? -1 : 1];
+#endif
+
+#if defined S_ISBLK && defined S_IFCHR
+extern char c2[S_ISBLK (S_IFCHR) ? -1 : 1];
+#endif
+
+#if defined S_ISLNK && defined S_IFREG
+extern char c3[S_ISLNK (S_IFREG) ? -1 : 1];
+#endif
+
+#if defined S_ISSOCK && defined S_IFREG
+extern char c4[S_ISSOCK (S_IFREG) ? -1 : 1];
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stat_broken=no
+else
+ ac_cv_header_stat_broken=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stat_broken" >&5
+$as_echo "$ac_cv_header_stat_broken" >&6; }
+if test $ac_cv_header_stat_broken = yes; then
+
+$as_echo "#define STAT_MACROS_BROKEN 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat_st_rdev" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_rdev" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_RDEV 1
+_ACEOF
+
+
+$as_echo "#define HAVE_ST_RDEV 1" >>confdefs.h
+
+fi
+
+
+echo $ECHO_N "checking if diff -u works... $ECHO_C" >&6
+if diff -u /dev/null /dev/null > /dev/null 2>&1; then
+ diff_u=-u
+ echo yes >&6
+else
+ diff_u=
+ echo no >&6
+fi
+echo "checking for MACHINE & MACHINE_ARCH..." >&6
+cat > conftest.$ac_ext <<EOF
+#include "confdefs.h"
+#include <sys/param.h>
+#ifdef MACHINE
+machine=MACHINE
+#endif
+#ifdef MACHINE_ARCH
+machine_arch=MACHINE_ARCH
+#endif
+EOF
+
+default_machine=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep machine= | tr -d ' "'`
+rm -rf conftest*
+if test "$default_machine"; then
+ eval "$default_machine"
+fi
+machine=${machine:-`$srcdir/machine.sh`}
+machine_arch=${machine_arch:-`$srcdir/machine.sh arch`}
+echo "defaults: MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6
+
+# Check whether --with-machine was given.
+if test "${with_machine+set}" = set; then :
+ withval=$with_machine; case "${withval}" in
+yes) as_fn_error "bad value ${withval} given for bmake MACHINE" "$LINENO" 5 ;;
+no) ;;
+generic) machine=`$srcdir/machine.sh`;;
+*) machine=$with_machine;;
+esac
+fi
+
+force_machine=
+
+# Check whether --with-force_machine was given.
+if test "${with_force_machine+set}" = set; then :
+ withval=$with_force_machine; case "${withval}" in
+yes) force_machine=FORCE_;;
+no) ;;
+*) force_machine=FORCE_; machine=$with_force_machine;;
+esac
+fi
+
+force_machine_arch=
+
+# Check whether --with-force_machine_arch was given.
+if test "${with_force_machine_arch+set}" = set; then :
+ withval=$with_force_machine_arch; case "${withval}" in
+yes) force_machine_arch=FORCE_;;
+no) ;;
+*) force_machine_arch=FORCE_; machine_arch=$with_force_machine;;
+esac
+fi
+
+
+# Check whether --with-machine_arch was given.
+if test "${with_machine_arch+set}" = set; then :
+ withval=$with_machine_arch; case "${withval}" in
+yes) as_fn_error "bad value ${withval} given for bmake MACHINE_ARCH" "$LINENO" 5 ;;
+no) ;;
+*) machine_arch=$with_machine_arch;;
+esac
+fi
+
+echo "Using: ${force_machine}MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6
+default_sys_path=\${prefix}/share/mk
+
+# Check whether --with-default-sys-path was given.
+if test "${with_default_sys_path+set}" = set; then :
+ withval=$with_default_sys_path; case "${withval}" in
+yes) as_fn_error "bad value ${withval} given for bmake _PATH_DEFSYSPATH" "$LINENO" 5 ;;
+no) ;;
+*) default_sys_path="$with_default_sys_path"
+ ;;
+esac
+fi
+
+
+# Check whether --with-path-objdirprefix was given.
+if test "${with_path_objdirprefix+set}" = set; then :
+ withval=$with_path_objdirprefix; case "${withval}" in
+yes) as_fn_error "bad value ${withval} given for bmake _PATH_OBJDIRPREFIX" "$LINENO" 5 ;;
+no) CPPFLAGS="$CPPFLAGS -DNO_PATH_OBJDIRPREFIX" ;;
+*) CPPFLAGS="$CPPFLAGS \"-D_PATH_OBJDIRPREFIX=\\\"$with_path-objdir\\\"\"" ;;
+esac
+fi
+
+# Check whether --enable-pwd-override was given.
+if test "${enable_pwd_override+set}" = set; then :
+ enableval=$enable_pwd_override; case "${enableval}" in
+yes) ;;
+no) CPPFLAGS="$CPPFLAGS -DNO_PWD_OVERRIDE" ;;
+*) as_fn_error "bad value ${enableval} given for pwd-override option" "$LINENO" 5 ;;
+esac
+fi
+
+# Check whether --enable-check-make-chdir was given.
+if test "${enable_check_make_chdir+set}" = set; then :
+ enableval=$enable_check_make_chdir; case "${enableval}" in
+yes) ;;
+no) CPPFLAGS="$CPPFLAGS -DNO_CHECK_MAKE_CHDIR" ;;
+*) as_fn_error "bad value ${enableval} given for check-make-chdir option" "$LINENO" 5 ;;
+esac
+fi
+
+
+# Check whether --with-mksrc was given.
+if test "${with_mksrc+set}" = set; then :
+ withval=$with_mksrc; case "${withval}" in
+""|yes|no) ;;
+*) test -s $withval/install-mk && mksrc=$withval ||
+as_fn_error "bad value ${withval} given for mksrc cannot find install-mk" "$LINENO" 5
+;;
+esac
+
+fi
+
+srcdir=`cd $srcdir && pwd`
+for mksrc in $mksrc $srcdir/mk $srcdir/../mk mk
+do
+ test -s $mksrc/install-mk || continue
+ mksrc=`cd $mksrc && pwd`
+ break
+done
+mksrc=`echo $mksrc | sed "s,$srcdir,\\\${srcdir},"`
+echo "Using: MKSRC=$mksrc" 1>&6
+if test -x /usr/xpg4/bin/sh; then
+ defshell_path=${defshell_path:-/usr/xpg4/bin/sh}
+fi
+if test -n "$defshell_path"; then
+ echo "Using: SHELL=$defshell_path" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define DEFSHELL_CUSTOM "$defshell_path"
+_ACEOF
+
+fi
+if test -n "$DEFSHELL_INDEX"; then
+
+cat >>confdefs.h <<_ACEOF
+#define DEFSHELL_INDEX $DEFSHELL_INDEX
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+
+
+ac_config_files="$ac_config_files Makefile make-bootstrap.sh unit-tests/Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by bmake $as_me 20120620, which was
+generated by GNU Autoconf 2.64. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <sjg@NetBSD.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+bmake config.status 20120620
+configured by $0, generated by GNU Autoconf 2.64,
+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "make-bootstrap.sh") CONFIG_FILES="$CONFIG_FILES make-bootstrap.sh" ;;
+ "unit-tests/Makefile") CONFIG_FILES="$CONFIG_FILES unit-tests/Makefile" ;;
+
+ *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_t"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+ } >"$tmp/config.h" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$tmp/config.h" "$ac_file" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error "could not create -" "$LINENO" 5
+ fi
+ ;;
+
+
+ esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+cat <<EOF
+
+You can now run
+
+ sh ./make-bootstrap.sh
+
+to produce a fully functional bmake.
+
+EOF
diff --git a/external/bsd/bmake/dist/configure.in b/external/bsd/bmake/dist/configure.in
new file mode 100644
index 0000000..156034b9
--- /dev/null
+++ b/external/bsd/bmake/dist/configure.in
@@ -0,0 +1,370 @@
+dnl
+dnl RCSid:
+dnl $Id: configure.in,v 1.45 2012/06/20 22:43:41 sjg Exp $
+dnl
+dnl Process this file with autoconf to produce a configure script
+dnl
+AC_INIT([bmake], [20120620], [sjg@NetBSD.org])
+AC_CONFIG_HEADER(config.h)
+
+dnl
+AC_ARG_WITH(defshell,
+[ --with-defshell=SHELL use SHELL by default - must be sh compatible, use sh or ksh to pick the internal definitions],
+[case "${withval}" in
+yes) AC_MSG_ERROR(bad value ${withval} given for bmake DEFSHELL) ;;
+no) ;;
+*) case "$with_defshell" in
+ sh) DEFSHELL_INDEX=DEFSHELL_INDEX_SH;; # it's the default anyway
+ ksh) DEFSHELL_INDEX=DEFSHELL_INDEX_KSH;;
+ csh) DEFSHELL_INDEX=DEFSHELL_INDEX_CSH;; # kidding right?
+ *) defshell_path=$with_defshell;; # better be sh compatible!
+ esac
+ ;;
+ esac])
+dnl
+use_meta=yes
+AC_ARG_WITH(meta,
+[ --without-meta dissable use of meta-mode],
+[case "${withval}" in
+yes|no) use_meta=${withval};;
+*) AC_MSG_ERROR(bad value ${withval} given for meta) ;;
+esac])
+dnl
+AC_ARG_WITH(filemon,
+[ --with-filemon=path/filemon.h indicate path to filemon.h for meta-mode],
+[ case "/${withval}" in
+/no|*/filemon.h) filemon_h="${withval}";;
+*/filemon*) filemon_h="${withval}/filemon.h";;
+*) AC_MSG_ERROR(bad value ${withval} given for filemon) ;;
+esac],
+[
+OS=`uname -s`
+for d in "/usr/include/dev/filemon" "$prefix/include/dev/filemon" "$srcdir/filemon" "$srcdir/../filemon" "$srcdir/../../sys/dev/filemon"
+do
+ for x in "/$OS" ""
+ do
+ filemon_h="$d$x/filemon.h"
+ test -s "$filemon_h" && break
+ done
+ test -s "$filemon_h" && break
+done
+test -s "${filemon_h:-/dev/null}" || filemon_h=no
+])
+dnl echo "Note: use_meta=$use_meta filemon_h=$filemon_h" >&6
+case "$use_meta" in
+yes)
+ case "$filemon_h" in
+ *.h) echo "Using: filemon=$filemon_h" >&6;;
+ esac
+ ;;
+esac
+dnl
+dnl Check for OS problems
+dnl Solaris's signal.h only privides sigset_t etc if one of
+dnl _EXTENSIONS_ _POSIX_C_SOURCE or _XOPEN_SOURCE are defined.
+dnl The later two seem to cause more problems than they solve so if we
+dnl see _EXTENSIONS_ we use it.
+AC_USE_SYSTEM_EXTENSIONS
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_GCC_TRADITIONAL
+AC_PROG_INSTALL
+dnl Executable suffix - normally empty; .exe on os2.
+AC_SUBST(ac_exe_suffix)dnl
+
+dnl
+dnl Check if /bin/sh will pass .MAKE.LEVEL
+echo $ECHO_N "checking if sh will pass .MAKE. variables... $ECHO_C" >&6
+ok=`env .MAKE.LEVEL=1 /bin/sh -c env | grep LEVEL=`
+case "$ok" in
+"") echo no >&6; CPPFLAGS="${CPPFLAGS} -DNEED_MAKE_LEVEL_SAFE";;
+*) echo yes >&6;;
+esac
+
+dnl
+dnl AC_C_CROSS
+dnl
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_HEADER_DIRENT
+dnl Keep this list sorted
+AC_CHECK_HEADERS( \
+ ar.h \
+ err.h \
+ fcntl.h \
+ paths.h \
+ poll.h \
+ ranlib.h \
+ string.h \
+ sys/mman.h \
+ sys/select.h \
+ sys/socket.h \
+ sys/time.h \
+ sys/uio.h \
+ unistd.h \
+ utime.h \
+ )
+
+dnl Both *BSD and Linux have sys/cdefs.h, most do not.
+dnl If it is missing, we add -I${srcdir}/missing to CFLAGS
+dnl also if sys/cdefs.h does not have __RCSID we need to use ours
+dnl but we need to include the host's one too *sigh*
+AC_CHECK_HEADER(sys/cdefs.h,
+echo $ECHO_N "checking whether sys/cdefs.h is compatible... $ECHO_C" >&6
+AC_EGREP_CPP(yes,
+[#include <sys/cdefs.h>
+#ifdef __RCSID
+yes
+#endif
+],
+echo yes >&6,
+echo no >&6; CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd` -DNEED_HOST_CDEFS_H"),
+CPPFLAGS="${CPPFLAGS} -I`cd ${srcdir}/missing && pwd`")
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C___ATTRIBUTE__
+AC_C_BIGENDIAN
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_DECL_SYS_SIGLIST
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl Checks for library functions.
+AC_TYPE_SIGNAL
+AC_FUNC_VFORK
+AC_FUNC_VPRINTF
+AC_FUNC_WAIT3
+dnl Keep this list sorted
+AC_CHECK_FUNCS( \
+ err \
+ errx \
+ getcwd \
+ getenv \
+ getopt \
+ getwd \
+ killpg \
+ mmap \
+ putenv \
+ select \
+ setenv \
+ setpgid \
+ setsid \
+ sigaction \
+ sigvec \
+ snprintf \
+ strerror \
+ strftime \
+ strsep \
+ strtod \
+ strtol \
+ unsetenv \
+ vsnprintf \
+ wait3 \
+ wait4 \
+ waitpid \
+ warn \
+ warnx \
+ )
+
+dnl functions which we may need to provide
+AC_REPLACE_FUNCS( \
+ realpath \
+ dirname \
+ stresep \
+ strlcpy \
+ )
+
+AC_CHECK_LIB([util], [emalloc],
+ [ AC_CHECK_LIB([util], [erealloc],
+ [ AC_CHECK_LIB([util], [estrdup],
+ [ AC_CHECK_LIB([util], [estrndup],
+ [ LIBS="$LIBS -lutil"
+ CPPFLAGS="$CPPFLAGS -DUSE_EMALLOC" ])])])])
+
+dnl
+dnl Structures
+dnl
+AC_HEADER_STAT
+AC_STRUCT_ST_RDEV
+dnl
+dnl we want this for unit-tests/Makefile
+echo $ECHO_N "checking if diff -u works... $ECHO_C" >&6
+if diff -u /dev/null /dev/null > /dev/null 2>&1; then
+ diff_u=-u
+ echo yes >&6
+else
+ diff_u=
+ echo no >&6
+fi
+dnl
+dnl AC_* don't quite cut it.
+dnl
+echo "checking for MACHINE & MACHINE_ARCH..." >&6
+cat > conftest.$ac_ext <<EOF
+#include "confdefs.h"
+#include <sys/param.h>
+#ifdef MACHINE
+machine=MACHINE
+#endif
+#ifdef MACHINE_ARCH
+machine_arch=MACHINE_ARCH
+#endif
+EOF
+
+default_machine=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep machine= | tr -d ' "'`
+rm -rf conftest*
+if test "$default_machine"; then
+ eval "$default_machine"
+fi
+machine=${machine:-`$srcdir/machine.sh`}
+machine_arch=${machine_arch:-`$srcdir/machine.sh arch`}
+echo "defaults: MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6
+dnl
+dnl now allow overrides
+dnl
+AC_ARG_WITH(machine,
+[ --with-machine=MACHINE explicitly set MACHINE],
+[case "${withval}" in
+yes) AC_MSG_ERROR(bad value ${withval} given for bmake MACHINE) ;;
+no) ;;
+generic) machine=`$srcdir/machine.sh`;;
+*) machine=$with_machine;;
+esac])
+force_machine=
+AC_ARG_WITH(force_machine,
+[ --with-force-machine=MACHINE set FORCE_MACHINE],
+[case "${withval}" in
+yes) force_machine=FORCE_;;
+no) ;;
+*) force_machine=FORCE_; machine=$with_force_machine;;
+esac])
+dnl
+force_machine_arch=
+AC_ARG_WITH(force_machine_arch,
+[ --with-force-machine-arch=MACHINE set FORCE_MACHINE_ARCH],
+[case "${withval}" in
+yes) force_machine_arch=FORCE_;;
+no) ;;
+*) force_machine_arch=FORCE_; machine_arch=$with_force_machine;;
+esac])
+dnl
+AC_ARG_WITH(machine_arch,
+[ --with-machine_arch=MACHINE_ARCH explicitly set MACHINE_ARCH],
+[case "${withval}" in
+yes) AC_MSG_ERROR(bad value ${withval} given for bmake MACHINE_ARCH) ;;
+no) ;;
+*) machine_arch=$with_machine_arch;;
+esac])
+dnl
+dnl Tell them what we ended up with
+dnl
+echo "Using: ${force_machine}MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6
+dnl
+dnl Allow folk to control _PATH_DEFSYSPATH
+dnl
+default_sys_path=\${prefix}/share/mk
+AC_ARG_WITH(default-sys-path,
+[ --with-default-sys-path=PATH:DIR:LIST use an explicit _PATH_DEFSYSPATH
+ MAKESYSPATH is a ':' separated list of directories
+ that bmake will search for system .mk files.
+ _PATH_DEFSYSPATH is its default value.],
+[case "${withval}" in
+yes) AC_MSG_ERROR(bad value ${withval} given for bmake _PATH_DEFSYSPATH) ;;
+no) ;;
+*) default_sys_path="$with_default_sys_path"
+ ;;
+esac])
+dnl
+dnl Some folk don't like this one
+dnl
+AC_ARG_WITH(path-objdirprefix,
+[ --with-path-objdirprefix=PATH override _PATH_OBJDIRPREFIX],
+[case "${withval}" in
+yes) AC_MSG_ERROR(bad value ${withval} given for bmake _PATH_OBJDIRPREFIX) ;;
+no) CPPFLAGS="$CPPFLAGS -DNO_PATH_OBJDIRPREFIX" ;;
+*) CPPFLAGS="$CPPFLAGS \"-D_PATH_OBJDIRPREFIX=\\\"$with_path-objdir\\\"\"" ;;
+esac])
+dnl
+dnl And this can be handy to do with out.
+dnl
+AC_ARG_ENABLE(pwd-override,
+[ --disable-pwd-override disable \$PWD overriding getcwd()],
+[case "${enableval}" in
+yes) ;;
+no) CPPFLAGS="$CPPFLAGS -DNO_PWD_OVERRIDE" ;;
+*) AC_MSG_ERROR(bad value ${enableval} given for pwd-override option) ;;
+esac])
+dnl
+dnl Just for grins
+dnl
+AC_ARG_ENABLE(check-make-chdir,
+[ --disable-check-make-chdir disable make trying to guess
+ when it should automatically cd \${.CURDIR}],
+[case "${enableval}" in
+yes) ;;
+no) CPPFLAGS="$CPPFLAGS -DNO_CHECK_MAKE_CHDIR" ;;
+*) AC_MSG_ERROR(bad value ${enableval} given for check-make-chdir option) ;;
+esac])
+dnl
+dnl On non-BSD systems, bootstrap won't work without mk
+dnl
+AC_ARG_WITH(mksrc,
+[ --with-mksrc=PATH tell makefile.boot where to find mk src],
+[case "${withval}" in
+""|yes|no) ;;
+*) test -s $withval/install-mk && mksrc=$withval ||
+AC_MSG_ERROR(bad value ${withval} given for mksrc cannot find install-mk)
+;;
+esac
+])
+dnl
+dnl Now make sure we have a value
+dnl
+srcdir=`cd $srcdir && pwd`
+for mksrc in $mksrc $srcdir/mk $srcdir/../mk mk
+do
+ test -s $mksrc/install-mk || continue
+ mksrc=`cd $mksrc && pwd`
+ break
+done
+mksrc=`echo $mksrc | sed "s,$srcdir,\\\${srcdir},"`
+echo "Using: MKSRC=$mksrc" 1>&6
+dnl On some systems we want a different default shell by default
+if test -x /usr/xpg4/bin/sh; then
+ defshell_path=${defshell_path:-/usr/xpg4/bin/sh}
+fi
+if test -n "$defshell_path"; then
+ echo "Using: SHELL=$defshell_path" >&6
+ AC_DEFINE_UNQUOTED(DEFSHELL_CUSTOM, "$defshell_path", Path of default shell)
+fi
+if test -n "$DEFSHELL_INDEX"; then
+ AC_DEFINE_UNQUOTED(DEFSHELL_INDEX, $DEFSHELL_INDEX, Shell spec to use by default)
+fi
+dnl
+AC_SUBST(machine)
+AC_SUBST(force_machine)
+AC_SUBST(machine_arch)
+AC_SUBST(mksrc)
+AC_SUBST(default_sys_path)
+AC_SUBST(INSTALL)
+AC_SUBST(GCC)
+AC_SUBST(diff_u)
+AC_SUBST(use_meta)
+AC_SUBST(filemon_h)
+AC_OUTPUT(Makefile make-bootstrap.sh unit-tests/Makefile)
+
+cat <<EOF
+
+You can now run
+
+ sh ./make-bootstrap.sh
+
+to produce a fully functional bmake.
+
+EOF
diff --git a/external/bsd/bmake/dist/dir.c b/external/bsd/bmake/dist/dir.c
new file mode 100644
index 0000000..1c56ea3
--- /dev/null
+++ b/external/bsd/bmake/dist/dir.c
@@ -0,0 +1,1802 @@
+/* $NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
+#else
+__RCSID("$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * dir.c --
+ * Directory searching using wildcards and/or normal names...
+ * Used both for source wildcarding in the Makefile and for finding
+ * implicit sources.
+ *
+ * The interface for this module is:
+ * Dir_Init Initialize the module.
+ *
+ * Dir_InitCur Set the cur Path.
+ *
+ * Dir_InitDot Set the dot Path.
+ *
+ * Dir_End Cleanup the module.
+ *
+ * Dir_SetPATH Set ${.PATH} to reflect state of dirSearchPath.
+ *
+ * Dir_HasWildcards Returns TRUE if the name given it needs to
+ * be wildcard-expanded.
+ *
+ * Dir_Expand Given a pattern and a path, return a Lst of names
+ * which match the pattern on the search path.
+ *
+ * Dir_FindFile Searches for a file on a given search path.
+ * If it exists, the entire path is returned.
+ * Otherwise NULL is returned.
+ *
+ * Dir_FindHereOrAbove Search for a path in the current directory and
+ * then all the directories above it in turn until
+ * the path is found or we reach the root ("/").
+ *
+ * Dir_MTime Return the modification time of a node. The file
+ * is searched for along the default search path.
+ * The path and mtime fields of the node are filled
+ * in.
+ *
+ * Dir_AddDir Add a directory to a search path.
+ *
+ * Dir_MakeFlags Given a search path and a command flag, create
+ * a string with each of the directories in the path
+ * preceded by the command flag and all of them
+ * separated by a space.
+ *
+ * Dir_Destroy Destroy an element of a search path. Frees up all
+ * things that can be freed for the element as long
+ * as the element is no longer referenced by any other
+ * search path.
+ * Dir_ClearPath Resets a search path to the empty list.
+ *
+ * For debugging:
+ * Dir_PrintDirectories Print stats about the directory cache.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+
+/*
+ * A search path consists of a Lst of Path structures. A Path structure
+ * has in it the name of the directory and a hash table of all the files
+ * in the directory. This is used to cut down on the number of system
+ * calls necessary to find implicit dependents and their like. Since
+ * these searches are made before any actions are taken, we need not
+ * worry about the directory changing due to creation commands. If this
+ * hampers the style of some makefiles, they must be changed.
+ *
+ * A list of all previously-read directories is kept in the
+ * openDirectories Lst. This list is checked first before a directory
+ * is opened.
+ *
+ * The need for the caching of whole directories is brought about by
+ * the multi-level transformation code in suff.c, which tends to search
+ * for far more files than regular make does. In the initial
+ * implementation, the amount of time spent performing "stat" calls was
+ * truly astronomical. The problem with hashing at the start is,
+ * of course, that pmake doesn't then detect changes to these directories
+ * during the course of the make. Three possibilities suggest themselves:
+ *
+ * 1) just use stat to test for a file's existence. As mentioned
+ * above, this is very inefficient due to the number of checks
+ * engendered by the multi-level transformation code.
+ * 2) use readdir() and company to search the directories, keeping
+ * them open between checks. I have tried this and while it
+ * didn't slow down the process too much, it could severely
+ * affect the amount of parallelism available as each directory
+ * open would take another file descriptor out of play for
+ * handling I/O for another job. Given that it is only recently
+ * that UNIX OS's have taken to allowing more than 20 or 32
+ * file descriptors for a process, this doesn't seem acceptable
+ * to me.
+ * 3) record the mtime of the directory in the Path structure and
+ * verify the directory hasn't changed since the contents were
+ * hashed. This will catch the creation or deletion of files,
+ * but not the updating of files. However, since it is the
+ * creation and deletion that is the problem, this could be
+ * a good thing to do. Unfortunately, if the directory (say ".")
+ * were fairly large and changed fairly frequently, the constant
+ * rehashing could seriously degrade performance. It might be
+ * good in such cases to keep track of the number of rehashes
+ * and if the number goes over a (small) limit, resort to using
+ * stat in its place.
+ *
+ * An additional thing to consider is that pmake is used primarily
+ * to create C programs and until recently pcc-based compilers refused
+ * to allow you to specify where the resulting object file should be
+ * placed. This forced all objects to be created in the current
+ * directory. This isn't meant as a full excuse, just an explanation of
+ * some of the reasons for the caching used here.
+ *
+ * One more note: the location of a target's file is only performed
+ * on the downward traversal of the graph and then only for terminal
+ * nodes in the graph. This could be construed as wrong in some cases,
+ * but prevents inadvertent modification of files when the "installed"
+ * directory for a file is provided in the search path.
+ *
+ * Another data structure maintained by this module is an mtime
+ * cache used when the searching of cached directories fails to find
+ * a file. In the past, Dir_FindFile would simply perform an access()
+ * call in such a case to determine if the file could be found using
+ * just the name given. When this hit, however, all that was gained
+ * was the knowledge that the file existed. Given that an access() is
+ * essentially a stat() without the copyout() call, and that the same
+ * filesystem overhead would have to be incurred in Dir_MTime, it made
+ * sense to replace the access() with a stat() and record the mtime
+ * in a cache for when Dir_MTime was actually called.
+ */
+
+Lst dirSearchPath; /* main search path */
+
+static Lst openDirectories; /* the list of all open directories */
+
+/*
+ * Variables for gathering statistics on the efficiency of the hashing
+ * mechanism.
+ */
+static int hits, /* Found in directory cache */
+ misses, /* Sad, but not evil misses */
+ nearmisses, /* Found under search path */
+ bigmisses; /* Sought by itself */
+
+static Path *dot; /* contents of current directory */
+static Path *cur; /* contents of current directory, if not dot */
+static Path *dotLast; /* a fake path entry indicating we need to
+ * look for . last */
+static Hash_Table mtimes; /* Results of doing a last-resort stat in
+ * Dir_FindFile -- if we have to go to the
+ * system to find the file, we might as well
+ * have its mtime on record. XXX: If this is done
+ * way early, there's a chance other rules will
+ * have already updated the file, in which case
+ * we'll update it again. Generally, there won't
+ * be two rules to update a single file, so this
+ * should be ok, but... */
+
+
+static int DirFindName(const void *, const void *);
+static int DirMatchFiles(const char *, Path *, Lst);
+static void DirExpandCurly(const char *, const char *, Lst, Lst);
+static void DirExpandInt(const char *, Lst, Lst);
+static int DirPrintWord(void *, void *);
+static int DirPrintDir(void *, void *);
+static char *DirLookup(Path *, const char *, const char *, Boolean);
+static char *DirLookupSubdir(Path *, const char *);
+static char *DirFindDot(Boolean, const char *, const char *);
+static char *DirLookupAbs(Path *, const char *, const char *);
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_Init --
+ * initialize things for this module
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * some directories may be opened.
+ *-----------------------------------------------------------------------
+ */
+void
+Dir_Init(const char *cdname)
+{
+ dirSearchPath = Lst_Init(FALSE);
+ openDirectories = Lst_Init(FALSE);
+ Hash_InitTable(&mtimes, 0);
+
+ Dir_InitCur(cdname);
+
+ dotLast = bmake_malloc(sizeof(Path));
+ dotLast->refCount = 1;
+ dotLast->hits = 0;
+ dotLast->name = bmake_strdup(".DOTLAST");
+ Hash_InitTable(&dotLast->files, -1);
+}
+
+/*
+ * Called by Dir_Init() and whenever .CURDIR is assigned to.
+ */
+void
+Dir_InitCur(const char *cdname)
+{
+ Path *p;
+
+ if (cdname != NULL) {
+ /*
+ * Our build directory is not the same as our source directory.
+ * Keep this one around too.
+ */
+ if ((p = Dir_AddDir(NULL, cdname))) {
+ p->refCount += 1;
+ if (cur && cur != p) {
+ /*
+ * We've been here before, cleanup.
+ */
+ cur->refCount -= 1;
+ Dir_Destroy(cur);
+ }
+ cur = p;
+ }
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_InitDot --
+ * (re)initialize "dot" (current/object directory) path hash
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * some directories may be opened.
+ *-----------------------------------------------------------------------
+ */
+void
+Dir_InitDot(void)
+{
+ if (dot != NULL) {
+ LstNode ln;
+
+ /* Remove old entry from openDirectories, but do not destroy. */
+ ln = Lst_Member(openDirectories, dot);
+ (void)Lst_Remove(openDirectories, ln);
+ }
+
+ dot = Dir_AddDir(NULL, ".");
+
+ if (dot == NULL) {
+ Error("Cannot open `.' (%s)", strerror(errno));
+ exit(1);
+ }
+
+ /*
+ * We always need to have dot around, so we increment its reference count
+ * to make sure it's not destroyed.
+ */
+ dot->refCount += 1;
+ Dir_SetPATH(); /* initialize */
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_End --
+ * cleanup things for this module
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * none
+ *-----------------------------------------------------------------------
+ */
+void
+Dir_End(void)
+{
+#ifdef CLEANUP
+ if (cur) {
+ cur->refCount -= 1;
+ Dir_Destroy(cur);
+ }
+ dot->refCount -= 1;
+ dotLast->refCount -= 1;
+ Dir_Destroy(dotLast);
+ Dir_Destroy(dot);
+ Dir_ClearPath(dirSearchPath);
+ Lst_Destroy(dirSearchPath, NULL);
+ Dir_ClearPath(openDirectories);
+ Lst_Destroy(openDirectories, NULL);
+ Hash_DeleteTable(&mtimes);
+#endif
+}
+
+/*
+ * We want ${.PATH} to indicate the order in which we will actually
+ * search, so we rebuild it after any .PATH: target.
+ * This is the simplest way to deal with the effect of .DOTLAST.
+ */
+void
+Dir_SetPATH(void)
+{
+ LstNode ln; /* a list element */
+ Path *p;
+ Boolean hasLastDot = FALSE; /* true we should search dot last */
+
+ Var_Delete(".PATH", VAR_GLOBAL);
+
+ if (Lst_Open(dirSearchPath) == SUCCESS) {
+ if ((ln = Lst_First(dirSearchPath)) != NULL) {
+ p = (Path *)Lst_Datum(ln);
+ if (p == dotLast) {
+ hasLastDot = TRUE;
+ Var_Append(".PATH", dotLast->name, VAR_GLOBAL);
+ }
+ }
+
+ if (!hasLastDot) {
+ if (dot)
+ Var_Append(".PATH", dot->name, VAR_GLOBAL);
+ if (cur)
+ Var_Append(".PATH", cur->name, VAR_GLOBAL);
+ }
+
+ while ((ln = Lst_Next(dirSearchPath)) != NULL) {
+ p = (Path *)Lst_Datum(ln);
+ if (p == dotLast)
+ continue;
+ if (p == dot && hasLastDot)
+ continue;
+ Var_Append(".PATH", p->name, VAR_GLOBAL);
+ }
+
+ if (hasLastDot) {
+ if (dot)
+ Var_Append(".PATH", dot->name, VAR_GLOBAL);
+ if (cur)
+ Var_Append(".PATH", cur->name, VAR_GLOBAL);
+ }
+ Lst_Close(dirSearchPath);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * DirFindName --
+ * See if the Path structure describes the same directory as the
+ * given one by comparing their names. Called from Dir_AddDir via
+ * Lst_Find when searching the list of open directories.
+ *
+ * Input:
+ * p Current name
+ * dname Desired name
+ *
+ * Results:
+ * 0 if it is the same. Non-zero otherwise
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+static int
+DirFindName(const void *p, const void *dname)
+{
+ return (strcmp(((const Path *)p)->name, dname));
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_HasWildcards --
+ * see if the given name has any wildcard characters in it
+ * be careful not to expand unmatching brackets or braces.
+ * XXX: This code is not 100% correct. ([^]] fails etc.)
+ * I really don't think that make(1) should be expanding
+ * patterns, because then you have to set a mechanism for
+ * escaping the expansion!
+ *
+ * Input:
+ * name name to check
+ *
+ * Results:
+ * returns TRUE if the word should be expanded, FALSE otherwise
+ *
+ * Side Effects:
+ * none
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Dir_HasWildcards(char *name)
+{
+ char *cp;
+ int wild = 0, brace = 0, bracket = 0;
+
+ for (cp = name; *cp; cp++) {
+ switch(*cp) {
+ case '{':
+ brace++;
+ wild = 1;
+ break;
+ case '}':
+ brace--;
+ break;
+ case '[':
+ bracket++;
+ wild = 1;
+ break;
+ case ']':
+ bracket--;
+ break;
+ case '?':
+ case '*':
+ wild = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ return wild && bracket == 0 && brace == 0;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * DirMatchFiles --
+ * Given a pattern and a Path structure, see if any files
+ * match the pattern and add their names to the 'expansions' list if
+ * any do. This is incomplete -- it doesn't take care of patterns like
+ * src / *src / *.c properly (just *.c on any of the directories), but it
+ * will do for now.
+ *
+ * Input:
+ * pattern Pattern to look for
+ * p Directory to search
+ * expansion Place to store the results
+ *
+ * Results:
+ * Always returns 0
+ *
+ * Side Effects:
+ * File names are added to the expansions lst. The directory will be
+ * fully hashed when this is done.
+ *-----------------------------------------------------------------------
+ */
+static int
+DirMatchFiles(const char *pattern, Path *p, Lst expansions)
+{
+ Hash_Search search; /* Index into the directory's table */
+ Hash_Entry *entry; /* Current entry in the table */
+ Boolean isDot; /* TRUE if the directory being searched is . */
+
+ isDot = (*p->name == '.' && p->name[1] == '\0');
+
+ for (entry = Hash_EnumFirst(&p->files, &search);
+ entry != NULL;
+ entry = Hash_EnumNext(&search))
+ {
+ /*
+ * See if the file matches the given pattern. Note we follow the UNIX
+ * convention that dot files will only be found if the pattern
+ * begins with a dot (note also that as a side effect of the hashing
+ * scheme, .* won't match . or .. since they aren't hashed).
+ */
+ if (Str_Match(entry->name, pattern) &&
+ ((entry->name[0] != '.') ||
+ (pattern[0] == '.')))
+ {
+ (void)Lst_AtEnd(expansions,
+ (isDot ? bmake_strdup(entry->name) :
+ str_concat(p->name, entry->name,
+ STR_ADDSLASH)));
+ }
+ }
+ return (0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * DirExpandCurly --
+ * Expand curly braces like the C shell. Does this recursively.
+ * Note the special case: if after the piece of the curly brace is
+ * done there are no wildcard characters in the result, the result is
+ * placed on the list WITHOUT CHECKING FOR ITS EXISTENCE.
+ *
+ * Input:
+ * word Entire word to expand
+ * brace First curly brace in it
+ * path Search path to use
+ * expansions Place to store the expansions
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The given list is filled with the expansions...
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+DirExpandCurly(const char *word, const char *brace, Lst path, Lst expansions)
+{
+ const char *end; /* Character after the closing brace */
+ const char *cp; /* Current position in brace clause */
+ const char *start; /* Start of current piece of brace clause */
+ int bracelevel; /* Number of braces we've seen. If we see a
+ * right brace when this is 0, we've hit the
+ * end of the clause. */
+ char *file; /* Current expansion */
+ int otherLen; /* The length of the other pieces of the
+ * expansion (chars before and after the
+ * clause in 'word') */
+ char *cp2; /* Pointer for checking for wildcards in
+ * expansion before calling Dir_Expand */
+
+ start = brace+1;
+
+ /*
+ * Find the end of the brace clause first, being wary of nested brace
+ * clauses.
+ */
+ for (end = start, bracelevel = 0; *end != '\0'; end++) {
+ if (*end == '{') {
+ bracelevel++;
+ } else if ((*end == '}') && (bracelevel-- == 0)) {
+ break;
+ }
+ }
+ if (*end == '\0') {
+ Error("Unterminated {} clause \"%s\"", start);
+ return;
+ } else {
+ end++;
+ }
+ otherLen = brace - word + strlen(end);
+
+ for (cp = start; cp < end; cp++) {
+ /*
+ * Find the end of this piece of the clause.
+ */
+ bracelevel = 0;
+ while (*cp != ',') {
+ if (*cp == '{') {
+ bracelevel++;
+ } else if ((*cp == '}') && (bracelevel-- <= 0)) {
+ break;
+ }
+ cp++;
+ }
+ /*
+ * Allocate room for the combination and install the three pieces.
+ */
+ file = bmake_malloc(otherLen + cp - start + 1);
+ if (brace != word) {
+ strncpy(file, word, brace-word);
+ }
+ if (cp != start) {
+ strncpy(&file[brace-word], start, cp-start);
+ }
+ strcpy(&file[(brace-word)+(cp-start)], end);
+
+ /*
+ * See if the result has any wildcards in it. If we find one, call
+ * Dir_Expand right away, telling it to place the result on our list
+ * of expansions.
+ */
+ for (cp2 = file; *cp2 != '\0'; cp2++) {
+ switch(*cp2) {
+ case '*':
+ case '?':
+ case '{':
+ case '[':
+ Dir_Expand(file, path, expansions);
+ goto next;
+ }
+ }
+ if (*cp2 == '\0') {
+ /*
+ * Hit the end w/o finding any wildcards, so stick the expansion
+ * on the end of the list.
+ */
+ (void)Lst_AtEnd(expansions, file);
+ } else {
+ next:
+ free(file);
+ }
+ start = cp+1;
+ }
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * DirExpandInt --
+ * Internal expand routine. Passes through the directories in the
+ * path one by one, calling DirMatchFiles for each. NOTE: This still
+ * doesn't handle patterns in directories...
+ *
+ * Input:
+ * word Word to expand
+ * path Path on which to look
+ * expansions Place to store the result
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Things are added to the expansions list.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+DirExpandInt(const char *word, Lst path, Lst expansions)
+{
+ LstNode ln; /* Current node */
+ Path *p; /* Directory in the node */
+
+ if (Lst_Open(path) == SUCCESS) {
+ while ((ln = Lst_Next(path)) != NULL) {
+ p = (Path *)Lst_Datum(ln);
+ DirMatchFiles(word, p, expansions);
+ }
+ Lst_Close(path);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * DirPrintWord --
+ * Print a word in the list of expansions. Callback for Dir_Expand
+ * when DEBUG(DIR), via Lst_ForEach.
+ *
+ * Results:
+ * === 0
+ *
+ * Side Effects:
+ * The passed word is printed, followed by a space.
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+DirPrintWord(void *word, void *dummy)
+{
+ fprintf(debug_file, "%s ", (char *)word);
+
+ return(dummy ? 0 : 0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_Expand --
+ * Expand the given word into a list of words by globbing it looking
+ * in the directories on the given search path.
+ *
+ * Input:
+ * word the word to expand
+ * path the list of directories in which to find the
+ * resulting files
+ * expansions the list on which to place the results
+ *
+ * Results:
+ * A list of words consisting of the files which exist along the search
+ * path matching the given pattern.
+ *
+ * Side Effects:
+ * Directories may be opened. Who knows?
+ *-----------------------------------------------------------------------
+ */
+void
+Dir_Expand(const char *word, Lst path, Lst expansions)
+{
+ const char *cp;
+
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, "Expanding \"%s\"... ", word);
+ }
+
+ cp = strchr(word, '{');
+ if (cp) {
+ DirExpandCurly(word, cp, path, expansions);
+ } else {
+ cp = strchr(word, '/');
+ if (cp) {
+ /*
+ * The thing has a directory component -- find the first wildcard
+ * in the string.
+ */
+ for (cp = word; *cp; cp++) {
+ if (*cp == '?' || *cp == '[' || *cp == '*' || *cp == '{') {
+ break;
+ }
+ }
+ if (*cp == '{') {
+ /*
+ * This one will be fun.
+ */
+ DirExpandCurly(word, cp, path, expansions);
+ return;
+ } else if (*cp != '\0') {
+ /*
+ * Back up to the start of the component
+ */
+ char *dirpath;
+
+ while (cp > word && *cp != '/') {
+ cp--;
+ }
+ if (cp != word) {
+ char sc;
+ /*
+ * If the glob isn't in the first component, try and find
+ * all the components up to the one with a wildcard.
+ */
+ sc = cp[1];
+ ((char *)UNCONST(cp))[1] = '\0';
+ dirpath = Dir_FindFile(word, path);
+ ((char *)UNCONST(cp))[1] = sc;
+ /*
+ * dirpath is null if can't find the leading component
+ * XXX: Dir_FindFile won't find internal components.
+ * i.e. if the path contains ../Etc/Object and we're
+ * looking for Etc, it won't be found. Ah well.
+ * Probably not important.
+ */
+ if (dirpath != NULL) {
+ char *dp = &dirpath[strlen(dirpath) - 1];
+ if (*dp == '/')
+ *dp = '\0';
+ path = Lst_Init(FALSE);
+ (void)Dir_AddDir(path, dirpath);
+ DirExpandInt(cp+1, path, expansions);
+ Lst_Destroy(path, NULL);
+ }
+ } else {
+ /*
+ * Start the search from the local directory
+ */
+ DirExpandInt(word, path, expansions);
+ }
+ } else {
+ /*
+ * Return the file -- this should never happen.
+ */
+ DirExpandInt(word, path, expansions);
+ }
+ } else {
+ /*
+ * First the files in dot
+ */
+ DirMatchFiles(word, dot, expansions);
+
+ /*
+ * Then the files in every other directory on the path.
+ */
+ DirExpandInt(word, path, expansions);
+ }
+ }
+ if (DEBUG(DIR)) {
+ Lst_ForEach(expansions, DirPrintWord, NULL);
+ fprintf(debug_file, "\n");
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * DirLookup --
+ * Find if the file with the given name exists in the given path.
+ *
+ * Results:
+ * The path to the file or NULL. This path is guaranteed to be in a
+ * different part of memory than name and so may be safely free'd.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+static char *
+DirLookup(Path *p, const char *name MAKE_ATTR_UNUSED, const char *cp,
+ Boolean hasSlash MAKE_ATTR_UNUSED)
+{
+ char *file; /* the current filename to check */
+
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " %s ...\n", p->name);
+ }
+
+ if (Hash_FindEntry(&p->files, cp) == NULL)
+ return NULL;
+
+ file = str_concat(p->name, cp, STR_ADDSLASH);
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " returning %s\n", file);
+ }
+ p->hits += 1;
+ hits += 1;
+ return file;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * DirLookupSubdir --
+ * Find if the file with the given name exists in the given path.
+ *
+ * Results:
+ * The path to the file or NULL. This path is guaranteed to be in a
+ * different part of memory than name and so may be safely free'd.
+ *
+ * Side Effects:
+ * If the file is found, it is added in the modification times hash
+ * table.
+ *-----------------------------------------------------------------------
+ */
+static char *
+DirLookupSubdir(Path *p, const char *name)
+{
+ struct stat stb; /* Buffer for stat, if necessary */
+ Hash_Entry *entry; /* Entry for mtimes table */
+ char *file; /* the current filename to check */
+
+ if (p != dot) {
+ file = str_concat(p->name, name, STR_ADDSLASH);
+ } else {
+ /*
+ * Checking in dot -- DON'T put a leading ./ on the thing.
+ */
+ file = bmake_strdup(name);
+ }
+
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, "checking %s ...\n", file);
+ }
+
+ if (stat(file, &stb) == 0) {
+ if (stb.st_mtime == 0)
+ stb.st_mtime = 1;
+ /*
+ * Save the modification time so if it's needed, we don't have
+ * to fetch it again.
+ */
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
+ file);
+ }
+ entry = Hash_CreateEntry(&mtimes, file, NULL);
+ Hash_SetTimeValue(entry, stb.st_mtime);
+ nearmisses += 1;
+ return (file);
+ }
+ free(file);
+ return NULL;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * DirLookupAbs --
+ * Find if the file with the given name exists in the given path.
+ *
+ * Results:
+ * The path to the file, the empty string or NULL. If the file is
+ * the empty string, the search should be terminated.
+ * This path is guaranteed to be in a different part of memory
+ * than name and so may be safely free'd.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+static char *
+DirLookupAbs(Path *p, const char *name, const char *cp)
+{
+ char *p1; /* pointer into p->name */
+ const char *p2; /* pointer into name */
+
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " %s ...\n", p->name);
+ }
+
+ /*
+ * If the file has a leading path component and that component
+ * exactly matches the entire name of the current search
+ * directory, we can attempt another cache lookup. And if we don't
+ * have a hit, we can safely assume the file does not exist at all.
+ */
+ for (p1 = p->name, p2 = name; *p1 && *p1 == *p2; p1++, p2++) {
+ continue;
+ }
+ if (*p1 != '\0' || p2 != cp - 1) {
+ return NULL;
+ }
+
+ if (Hash_FindEntry(&p->files, cp) == NULL) {
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " must be here but isn't -- returning\n");
+ }
+ /* Return empty string: terminates search */
+ return bmake_strdup("");
+ }
+
+ p->hits += 1;
+ hits += 1;
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " returning %s\n", name);
+ }
+ return (bmake_strdup(name));
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * DirFindDot --
+ * Find the file given on "." or curdir
+ *
+ * Results:
+ * The path to the file or NULL. This path is guaranteed to be in a
+ * different part of memory than name and so may be safely free'd.
+ *
+ * Side Effects:
+ * Hit counts change
+ *-----------------------------------------------------------------------
+ */
+static char *
+DirFindDot(Boolean hasSlash MAKE_ATTR_UNUSED, const char *name, const char *cp)
+{
+
+ if (Hash_FindEntry(&dot->files, cp) != NULL) {
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " in '.'\n");
+ }
+ hits += 1;
+ dot->hits += 1;
+ return (bmake_strdup(name));
+ }
+ if (cur &&
+ Hash_FindEntry(&cur->files, cp) != NULL) {
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " in ${.CURDIR} = %s\n", cur->name);
+ }
+ hits += 1;
+ cur->hits += 1;
+ return str_concat(cur->name, cp, STR_ADDSLASH);
+ }
+
+ return NULL;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_FindFile --
+ * Find the file with the given name along the given search path.
+ *
+ * Input:
+ * name the file to find
+ * path the Lst of directories to search
+ *
+ * Results:
+ * The path to the file or NULL. This path is guaranteed to be in a
+ * different part of memory than name and so may be safely free'd.
+ *
+ * Side Effects:
+ * If the file is found in a directory which is not on the path
+ * already (either 'name' is absolute or it is a relative path
+ * [ dir1/.../dirn/file ] which exists below one of the directories
+ * already on the search path), its directory is added to the end
+ * of the path on the assumption that there will be more files in
+ * that directory later on. Sometimes this is true. Sometimes not.
+ *-----------------------------------------------------------------------
+ */
+char *
+Dir_FindFile(const char *name, Lst path)
+{
+ LstNode ln; /* a list element */
+ char *file; /* the current filename to check */
+ Path *p; /* current path member */
+ const char *cp; /* Terminal name of file */
+ Boolean hasLastDot = FALSE; /* true we should search dot last */
+ Boolean hasSlash; /* true if 'name' contains a / */
+ struct stat stb; /* Buffer for stat, if necessary */
+ Hash_Entry *entry; /* Entry for mtimes table */
+ const char *trailing_dot = ".";
+
+ /*
+ * Find the final component of the name and note whether it has a
+ * slash in it (the name, I mean)
+ */
+ cp = strrchr(name, '/');
+ if (cp) {
+ hasSlash = TRUE;
+ cp += 1;
+ } else {
+ hasSlash = FALSE;
+ cp = name;
+ }
+
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, "Searching for %s ...", name);
+ }
+
+ if (Lst_Open(path) == FAILURE) {
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, "couldn't open path, file not found\n");
+ }
+ misses += 1;
+ return NULL;
+ }
+
+ if ((ln = Lst_First(path)) != NULL) {
+ p = (Path *)Lst_Datum(ln);
+ if (p == dotLast) {
+ hasLastDot = TRUE;
+ if (DEBUG(DIR))
+ fprintf(debug_file, "[dot last]...");
+ }
+ }
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, "\n");
+ }
+
+ /*
+ * If there's no leading directory components or if the leading
+ * directory component is exactly `./', consult the cached contents
+ * of each of the directories on the search path.
+ */
+ if (!hasSlash || (cp - name == 2 && *name == '.')) {
+ /*
+ * We look through all the directories on the path seeking one which
+ * contains the final component of the given name. If such a beast
+ * is found, we concatenate the directory name and the final
+ * component and return the resulting string. If we don't find any
+ * such thing, we go on to phase two...
+ *
+ * No matter what, we always look for the file in the current
+ * directory before anywhere else (unless we found the magic
+ * DOTLAST path, in which case we search it last) and we *do not*
+ * add the ./ to it if it exists.
+ * This is so there are no conflicts between what the user
+ * specifies (fish.c) and what pmake finds (./fish.c).
+ */
+ if (!hasLastDot &&
+ (file = DirFindDot(hasSlash, name, cp)) != NULL) {
+ Lst_Close(path);
+ return file;
+ }
+
+ while ((ln = Lst_Next(path)) != NULL) {
+ p = (Path *)Lst_Datum(ln);
+ if (p == dotLast)
+ continue;
+ if ((file = DirLookup(p, name, cp, hasSlash)) != NULL) {
+ Lst_Close(path);
+ return file;
+ }
+ }
+
+ if (hasLastDot &&
+ (file = DirFindDot(hasSlash, name, cp)) != NULL) {
+ Lst_Close(path);
+ return file;
+ }
+ }
+ Lst_Close(path);
+
+ /*
+ * We didn't find the file on any directory in the search path.
+ * If the name doesn't contain a slash, that means it doesn't exist.
+ * If it *does* contain a slash, however, there is still hope: it
+ * could be in a subdirectory of one of the members of the search
+ * path. (eg. /usr/include and sys/types.h. The above search would
+ * fail to turn up types.h in /usr/include, but it *is* in
+ * /usr/include/sys/types.h).
+ * [ This no longer applies: If we find such a beast, we assume there
+ * will be more (what else can we assume?) and add all but the last
+ * component of the resulting name onto the search path (at the
+ * end).]
+ * This phase is only performed if the file is *not* absolute.
+ */
+ if (!hasSlash) {
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " failed.\n");
+ }
+ misses += 1;
+ return NULL;
+ }
+
+ if (*cp == '\0') {
+ /* we were given a trailing "/" */
+ cp = trailing_dot;
+ }
+
+ if (name[0] != '/') {
+ Boolean checkedDot = FALSE;
+
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " Trying subdirectories...\n");
+ }
+
+ if (!hasLastDot) {
+ if (dot) {
+ checkedDot = TRUE;
+ if ((file = DirLookupSubdir(dot, name)) != NULL)
+ return file;
+ }
+ if (cur && (file = DirLookupSubdir(cur, name)) != NULL)
+ return file;
+ }
+
+ (void)Lst_Open(path);
+ while ((ln = Lst_Next(path)) != NULL) {
+ p = (Path *)Lst_Datum(ln);
+ if (p == dotLast)
+ continue;
+ if (p == dot) {
+ if (checkedDot)
+ continue;
+ checkedDot = TRUE;
+ }
+ if ((file = DirLookupSubdir(p, name)) != NULL) {
+ Lst_Close(path);
+ return file;
+ }
+ }
+ Lst_Close(path);
+
+ if (hasLastDot) {
+ if (dot && !checkedDot) {
+ checkedDot = TRUE;
+ if ((file = DirLookupSubdir(dot, name)) != NULL)
+ return file;
+ }
+ if (cur && (file = DirLookupSubdir(cur, name)) != NULL)
+ return file;
+ }
+
+ if (checkedDot) {
+ /*
+ * Already checked by the given name, since . was in the path,
+ * so no point in proceeding...
+ */
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " Checked . already, returning NULL\n");
+ }
+ return NULL;
+ }
+
+ } else { /* name[0] == '/' */
+
+ /*
+ * For absolute names, compare directory path prefix against the
+ * the directory path of each member on the search path for an exact
+ * match. If we have an exact match on any member of the search path,
+ * use the cached contents of that member to lookup the final file
+ * component. If that lookup fails we can safely assume that the
+ * file does not exist at all. This is signified by DirLookupAbs()
+ * returning an empty string.
+ */
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " Trying exact path matches...\n");
+ }
+
+ if (!hasLastDot && cur && (file = DirLookupAbs(cur, name, cp)) != NULL)
+ return *file?file:NULL;
+
+ (void)Lst_Open(path);
+ while ((ln = Lst_Next(path)) != NULL) {
+ p = (Path *)Lst_Datum(ln);
+ if (p == dotLast)
+ continue;
+ if ((file = DirLookupAbs(p, name, cp)) != NULL) {
+ Lst_Close(path);
+ return *file?file:NULL;
+ }
+ }
+ Lst_Close(path);
+
+ if (hasLastDot && cur && (file = DirLookupAbs(cur, name, cp)) != NULL)
+ return *file?file:NULL;
+ }
+
+ /*
+ * Didn't find it that way, either. Sigh. Phase 3. Add its directory
+ * onto the search path in any case, just in case, then look for the
+ * thing in the hash table. If we find it, grand. We return a new
+ * copy of the name. Otherwise we sadly return a NULL pointer. Sigh.
+ * Note that if the directory holding the file doesn't exist, this will
+ * do an extra search of the final directory on the path. Unless something
+ * weird happens, this search won't succeed and life will be groovy.
+ *
+ * Sigh. We cannot add the directory onto the search path because
+ * of this amusing case:
+ * $(INSTALLDIR)/$(FILE): $(FILE)
+ *
+ * $(FILE) exists in $(INSTALLDIR) but not in the current one.
+ * When searching for $(FILE), we will find it in $(INSTALLDIR)
+ * b/c we added it here. This is not good...
+ */
+#ifdef notdef
+ if (cp == traling_dot) {
+ cp = strrchr(name, '/');
+ cp += 1;
+ }
+ cp[-1] = '\0';
+ (void)Dir_AddDir(path, name);
+ cp[-1] = '/';
+
+ bigmisses += 1;
+ ln = Lst_Last(path);
+ if (ln == NULL) {
+ return NULL;
+ } else {
+ p = (Path *)Lst_Datum(ln);
+ }
+
+ if (Hash_FindEntry(&p->files, cp) != NULL) {
+ return (bmake_strdup(name));
+ } else {
+ return NULL;
+ }
+#else /* !notdef */
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " Looking for \"%s\" ...\n", name);
+ }
+
+ bigmisses += 1;
+ entry = Hash_FindEntry(&mtimes, name);
+ if (entry != NULL) {
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " got it (in mtime cache)\n");
+ }
+ return(bmake_strdup(name));
+ } else if (stat(name, &stb) == 0) {
+ if (stb.st_mtime == 0)
+ stb.st_mtime = 1;
+ entry = Hash_CreateEntry(&mtimes, name, NULL);
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
+ name);
+ }
+ Hash_SetTimeValue(entry, stb.st_mtime);
+ return (bmake_strdup(name));
+ } else {
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, " failed. Returning NULL\n");
+ }
+ return NULL;
+ }
+#endif /* notdef */
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_FindHereOrAbove --
+ * search for a path starting at a given directory and then working
+ * our way up towards the root.
+ *
+ * Input:
+ * here starting directory
+ * search_path the path we are looking for
+ * result the result of a successful search is placed here
+ * rlen the length of the result buffer
+ * (typically MAXPATHLEN + 1)
+ *
+ * Results:
+ * 0 on failure, 1 on success [in which case the found path is put
+ * in the result buffer].
+ *
+ * Side Effects:
+ *-----------------------------------------------------------------------
+ */
+int
+Dir_FindHereOrAbove(char *here, char *search_path, char *result, int rlen) {
+
+ struct stat st;
+ char dirbase[MAXPATHLEN + 1], *db_end;
+ char try[MAXPATHLEN + 1], *try_end;
+
+ /* copy out our starting point */
+ snprintf(dirbase, sizeof(dirbase), "%s", here);
+ db_end = dirbase + strlen(dirbase);
+
+ /* loop until we determine a result */
+ while (1) {
+
+ /* try and stat(2) it ... */
+ snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
+ if (stat(try, &st) != -1) {
+ /*
+ * success! if we found a file, chop off
+ * the filename so we return a directory.
+ */
+ if ((st.st_mode & S_IFMT) != S_IFDIR) {
+ try_end = try + strlen(try);
+ while (try_end > try && *try_end != '/')
+ try_end--;
+ if (try_end > try)
+ *try_end = 0; /* chop! */
+ }
+
+ /*
+ * done!
+ */
+ snprintf(result, rlen, "%s", try);
+ return(1);
+ }
+
+ /*
+ * nope, we didn't find it. if we used up dirbase we've
+ * reached the root and failed.
+ */
+ if (db_end == dirbase)
+ break; /* failed! */
+
+ /*
+ * truncate dirbase from the end to move up a dir
+ */
+ while (db_end > dirbase && *db_end != '/')
+ db_end--;
+ *db_end = 0; /* chop! */
+
+ } /* while (1) */
+
+ /*
+ * we failed...
+ */
+ return(0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_MTime --
+ * Find the modification time of the file described by gn along the
+ * search path dirSearchPath.
+ *
+ * Input:
+ * gn the file whose modification time is desired
+ *
+ * Results:
+ * The modification time or 0 if it doesn't exist
+ *
+ * Side Effects:
+ * The modification time is placed in the node's mtime slot.
+ * If the node didn't have a path entry before, and Dir_FindFile
+ * found one for it, the full name is placed in the path slot.
+ *-----------------------------------------------------------------------
+ */
+int
+Dir_MTime(GNode *gn, Boolean recheck)
+{
+ char *fullName; /* the full pathname of name */
+ struct stat stb; /* buffer for finding the mod time */
+ Hash_Entry *entry;
+
+ if (gn->type & OP_ARCHV) {
+ return Arch_MTime(gn);
+ } else if (gn->type & OP_PHONY) {
+ gn->mtime = 0;
+ return 0;
+ } else if (gn->path == NULL) {
+ if (gn->type & OP_NOPATH)
+ fullName = NULL;
+ else {
+ fullName = Dir_FindFile(gn->name, Suff_FindPath(gn));
+ if (fullName == NULL && gn->flags & FROM_DEPEND &&
+ !Lst_IsEmpty(gn->iParents)) {
+ char *cp;
+
+ cp = strrchr(gn->name, '/');
+ if (cp) {
+ /*
+ * This is an implied source, and it may have moved,
+ * see if we can find it via the current .PATH
+ */
+ cp++;
+
+ fullName = Dir_FindFile(cp, Suff_FindPath(gn));
+ if (fullName) {
+ /*
+ * Put the found file in gn->path
+ * so that we give that to the compiler.
+ */
+ gn->path = bmake_strdup(fullName);
+ fprintf(stdout,
+ "%s: ignoring stale %s for %s, found %s\n",
+ progname, makeDependfile, gn->name, fullName);
+ }
+ }
+ }
+ if (DEBUG(DIR))
+ fprintf(debug_file, "Found '%s' as '%s'\n",
+ gn->name, fullName ? fullName : "(not found)" );
+ }
+ } else {
+ fullName = gn->path;
+ }
+
+ if (fullName == NULL) {
+ fullName = bmake_strdup(gn->name);
+ }
+
+ if (!recheck)
+ entry = Hash_FindEntry(&mtimes, fullName);
+ else
+ entry = NULL;
+ if (entry != NULL) {
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, "Using cached time %s for %s\n",
+ Targ_FmtTime(Hash_GetTimeValue(entry)), fullName);
+ }
+ stb.st_mtime = Hash_GetTimeValue(entry);
+ } else if (stat(fullName, &stb) < 0) {
+ if (gn->type & OP_MEMBER) {
+ if (fullName != gn->path)
+ free(fullName);
+ return Arch_MemMTime(gn);
+ } else {
+ stb.st_mtime = 0;
+ }
+ } else {
+ if (stb.st_mtime == 0) {
+ /*
+ * 0 handled specially by the code, if the time is really 0,
+ * return something else instead
+ */
+ stb.st_mtime = 1;
+ }
+ entry = Hash_CreateEntry(&mtimes, fullName, NULL);
+ Hash_SetTimeValue(entry, stb.st_mtime);
+ }
+
+ if (fullName && gn->path == NULL) {
+ gn->path = fullName;
+ }
+
+ gn->mtime = stb.st_mtime;
+ return (gn->mtime);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_AddDir --
+ * Add the given name to the end of the given path. The order of
+ * the arguments is backwards so ParseDoDependency can do a
+ * Lst_ForEach of its list of paths...
+ *
+ * Input:
+ * path the path to which the directory should be
+ * added
+ * name the name of the directory to add
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * A structure is added to the list and the directory is
+ * read and hashed.
+ *-----------------------------------------------------------------------
+ */
+Path *
+Dir_AddDir(Lst path, const char *name)
+{
+ LstNode ln = NULL; /* node in case Path structure is found */
+ Path *p = NULL; /* pointer to new Path structure */
+ DIR *d; /* for reading directory */
+ struct dirent *dp; /* entry in directory */
+
+ if (strcmp(name, ".DOTLAST") == 0) {
+ ln = Lst_Find(path, name, DirFindName);
+ if (ln != NULL)
+ return (Path *)Lst_Datum(ln);
+ else {
+ dotLast->refCount += 1;
+ (void)Lst_AtFront(path, dotLast);
+ }
+ }
+
+ if (path)
+ ln = Lst_Find(openDirectories, name, DirFindName);
+ if (ln != NULL) {
+ p = (Path *)Lst_Datum(ln);
+ if (path && Lst_Member(path, p) == NULL) {
+ p->refCount += 1;
+ (void)Lst_AtEnd(path, p);
+ }
+ } else {
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, "Caching %s ...", name);
+ }
+
+ if ((d = opendir(name)) != NULL) {
+ p = bmake_malloc(sizeof(Path));
+ p->name = bmake_strdup(name);
+ p->hits = 0;
+ p->refCount = 1;
+ Hash_InitTable(&p->files, -1);
+
+ while ((dp = readdir(d)) != NULL) {
+#if defined(sun) && defined(d_ino) /* d_ino is a sunos4 #define for d_fileno */
+ /*
+ * The sun directory library doesn't check for a 0 inode
+ * (0-inode slots just take up space), so we have to do
+ * it ourselves.
+ */
+ if (dp->d_fileno == 0) {
+ continue;
+ }
+#endif /* sun && d_ino */
+ (void)Hash_CreateEntry(&p->files, dp->d_name, NULL);
+ }
+ (void)closedir(d);
+ (void)Lst_AtEnd(openDirectories, p);
+ if (path != NULL)
+ (void)Lst_AtEnd(path, p);
+ }
+ if (DEBUG(DIR)) {
+ fprintf(debug_file, "done\n");
+ }
+ }
+ return p;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_CopyDir --
+ * Callback function for duplicating a search path via Lst_Duplicate.
+ * Ups the reference count for the directory.
+ *
+ * Results:
+ * Returns the Path it was given.
+ *
+ * Side Effects:
+ * The refCount of the path is incremented.
+ *
+ *-----------------------------------------------------------------------
+ */
+void *
+Dir_CopyDir(void *p)
+{
+ ((Path *)p)->refCount += 1;
+
+ return (p);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_MakeFlags --
+ * Make a string by taking all the directories in the given search
+ * path and preceding them by the given flag. Used by the suffix
+ * module to create variables for compilers based on suffix search
+ * paths.
+ *
+ * Input:
+ * flag flag which should precede each directory
+ * path list of directories
+ *
+ * Results:
+ * The string mentioned above. Note that there is no space between
+ * the given flag and each directory. The empty string is returned if
+ * Things don't go well.
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+char *
+Dir_MakeFlags(const char *flag, Lst path)
+{
+ char *str; /* the string which will be returned */
+ char *s1, *s2;/* the current directory preceded by 'flag' */
+ LstNode ln; /* the node of the current directory */
+ Path *p; /* the structure describing the current directory */
+
+ str = bmake_strdup("");
+
+ if (Lst_Open(path) == SUCCESS) {
+ while ((ln = Lst_Next(path)) != NULL) {
+ p = (Path *)Lst_Datum(ln);
+ s2 = str_concat(flag, p->name, 0);
+ str = str_concat(s1 = str, s2, STR_ADDSPACE);
+ free(s1);
+ free(s2);
+ }
+ Lst_Close(path);
+ }
+
+ return (str);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_Destroy --
+ * Nuke a directory descriptor, if possible. Callback procedure
+ * for the suffixes module when destroying a search path.
+ *
+ * Input:
+ * pp The directory descriptor to nuke
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * If no other path references this directory (refCount == 0),
+ * the Path and all its data are freed.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Dir_Destroy(void *pp)
+{
+ Path *p = (Path *)pp;
+ p->refCount -= 1;
+
+ if (p->refCount == 0) {
+ LstNode ln;
+
+ ln = Lst_Member(openDirectories, p);
+ (void)Lst_Remove(openDirectories, ln);
+
+ Hash_DeleteTable(&p->files);
+ free(p->name);
+ free(p);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_ClearPath --
+ * Clear out all elements of the given search path. This is different
+ * from destroying the list, notice.
+ *
+ * Input:
+ * path Path to clear
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The path is set to the empty list.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Dir_ClearPath(Lst path)
+{
+ Path *p;
+ while (!Lst_IsEmpty(path)) {
+ p = (Path *)Lst_DeQueue(path);
+ Dir_Destroy(p);
+ }
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Dir_Concat --
+ * Concatenate two paths, adding the second to the end of the first.
+ * Makes sure to avoid duplicates.
+ *
+ * Input:
+ * path1 Dest
+ * path2 Source
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * Reference counts for added dirs are upped.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Dir_Concat(Lst path1, Lst path2)
+{
+ LstNode ln;
+ Path *p;
+
+ for (ln = Lst_First(path2); ln != NULL; ln = Lst_Succ(ln)) {
+ p = (Path *)Lst_Datum(ln);
+ if (Lst_Member(path1, p) == NULL) {
+ p->refCount += 1;
+ (void)Lst_AtEnd(path1, p);
+ }
+ }
+}
+
+/********** DEBUG INFO **********/
+void
+Dir_PrintDirectories(void)
+{
+ LstNode ln;
+ Path *p;
+
+ fprintf(debug_file, "#*** Directory Cache:\n");
+ fprintf(debug_file, "# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n",
+ hits, misses, nearmisses, bigmisses,
+ (hits+bigmisses+nearmisses ?
+ hits * 100 / (hits + bigmisses + nearmisses) : 0));
+ fprintf(debug_file, "# %-20s referenced\thits\n", "directory");
+ if (Lst_Open(openDirectories) == SUCCESS) {
+ while ((ln = Lst_Next(openDirectories)) != NULL) {
+ p = (Path *)Lst_Datum(ln);
+ fprintf(debug_file, "# %-20s %10d\t%4d\n", p->name, p->refCount, p->hits);
+ }
+ Lst_Close(openDirectories);
+ }
+}
+
+static int
+DirPrintDir(void *p, void *dummy)
+{
+ fprintf(debug_file, "%s ", ((Path *)p)->name);
+ return (dummy ? 0 : 0);
+}
+
+void
+Dir_PrintPath(Lst path)
+{
+ Lst_ForEach(path, DirPrintDir, NULL);
+}
diff --git a/external/bsd/bmake/dist/dir.h b/external/bsd/bmake/dist/dir.h
new file mode 100644
index 0000000..aa00450
--- /dev/null
+++ b/external/bsd/bmake/dist/dir.h
@@ -0,0 +1,108 @@
+/* $NetBSD: dir.h,v 1.15 2012/04/07 18:29:08 christos Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)dir.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)dir.h 8.1 (Berkeley) 6/6/93
+ */
+
+/* dir.h --
+ */
+
+#ifndef _DIR
+#define _DIR
+
+typedef struct Path {
+ char *name; /* Name of directory */
+ int refCount; /* Number of paths with this directory */
+ int hits; /* the number of times a file in this
+ * directory has been found */
+ Hash_Table files; /* Hash table of files in directory */
+} Path;
+
+void Dir_Init(const char *);
+void Dir_InitCur(const char *);
+void Dir_InitDot(void);
+void Dir_End(void);
+void Dir_SetPATH(void);
+Boolean Dir_HasWildcards(char *);
+void Dir_Expand(const char *, Lst, Lst);
+char *Dir_FindFile(const char *, Lst);
+int Dir_FindHereOrAbove(char *, char *, char *, int);
+int Dir_MTime(GNode *, Boolean);
+Path *Dir_AddDir(Lst, const char *);
+char *Dir_MakeFlags(const char *, Lst);
+void Dir_ClearPath(Lst);
+void Dir_Concat(Lst, Lst);
+void Dir_PrintDirectories(void);
+void Dir_PrintPath(Lst);
+void Dir_Destroy(void *);
+void * Dir_CopyDir(void *);
+
+#endif /* _DIR */
diff --git a/external/bsd/bmake/dist/dirname.c b/external/bsd/bmake/dist/dirname.c
new file mode 100644
index 0000000..8b6b6c3
--- /dev/null
+++ b/external/bsd/bmake/dist/dirname.c
@@ -0,0 +1,95 @@
+/* $NetBSD: dirname.c,v 1.11 2009/11/24 13:34:20 tnozaki Exp $ */
+
+/*-
+ * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Klaus Klein and Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#ifndef HAVE_DIRNAME
+
+#include <sys/cdefs.h>
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifndef PATH_MAX
+# define PATH_MAX 1024
+#endif
+
+char *
+dirname(char *path)
+{
+ static char result[PATH_MAX];
+ const char *lastp;
+ size_t len;
+
+ /*
+ * If `path' is a null pointer or points to an empty string,
+ * return a pointer to the string ".".
+ */
+ if ((path == NULL) || (*path == '\0'))
+ goto singledot;
+
+
+ /* Strip trailing slashes, if any. */
+ lastp = path + strlen(path) - 1;
+ while (lastp != path && *lastp == '/')
+ lastp--;
+
+ /* Terminate path at the last occurence of '/'. */
+ do {
+ if (*lastp == '/') {
+ /* Strip trailing slashes, if any. */
+ while (lastp != path && *lastp == '/')
+ lastp--;
+
+ /* ...and copy the result into the result buffer. */
+ len = (lastp - path) + 1 /* last char */;
+ if (len > (PATH_MAX - 1))
+ len = PATH_MAX - 1;
+
+ memcpy(result, path, len);
+ result[len] = '\0';
+
+ return (result);
+ }
+ } while (--lastp >= path);
+
+ /* No /'s found, return a pointer to the string ".". */
+singledot:
+ result[0] = '.';
+ result[1] = '\0';
+
+ return (result);
+}
+#endif
diff --git a/external/bsd/bmake/dist/find_lib.sh b/external/bsd/bmake/dist/find_lib.sh
new file mode 100755
index 0000000..3c2e4af
--- /dev/null
+++ b/external/bsd/bmake/dist/find_lib.sh
@@ -0,0 +1,13 @@
+:
+re=$1; shift
+
+for lib in $*
+do
+ found=`nm $lib | egrep "$re"`
+ case "$found" in
+ "") ;;
+ *) echo "$lib: $found";;
+ esac
+done
+
+
diff --git a/external/bsd/bmake/dist/for.c b/external/bsd/bmake/dist/for.c
new file mode 100644
index 0000000..33bcf13
--- /dev/null
+++ b/external/bsd/bmake/dist/for.c
@@ -0,0 +1,496 @@
+/* $NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $ */
+
+/*
+ * Copyright (c) 1992, The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * for.c --
+ * Functions to handle loops in a makefile.
+ *
+ * Interface:
+ * For_Eval Evaluate the loop in the passed line.
+ * For_Run Run accumulated loop
+ *
+ */
+
+#include <assert.h>
+#include <ctype.h>
+
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+#include "buf.h"
+#include "strlist.h"
+
+#define FOR_SUB_ESCAPE_CHAR 1
+#define FOR_SUB_ESCAPE_BRACE 2
+#define FOR_SUB_ESCAPE_PAREN 4
+
+/*
+ * For statements are of the form:
+ *
+ * .for <variable> in <varlist>
+ * ...
+ * .endfor
+ *
+ * The trick is to look for the matching end inside for for loop
+ * To do that, we count the current nesting level of the for loops.
+ * and the .endfor statements, accumulating all the statements between
+ * the initial .for loop and the matching .endfor;
+ * then we evaluate the for loop for each variable in the varlist.
+ *
+ * Note that any nested fors are just passed through; they get handled
+ * recursively in For_Eval when we're expanding the enclosing for in
+ * For_Run.
+ */
+
+static int forLevel = 0; /* Nesting level */
+
+/*
+ * State of a for loop.
+ */
+typedef struct _For {
+ Buffer buf; /* Body of loop */
+ strlist_t vars; /* Iteration variables */
+ strlist_t items; /* Substitution items */
+ char *parse_buf;
+ int short_var;
+ int sub_next;
+} For;
+
+static For *accumFor; /* Loop being accumulated */
+
+
+
+static char *
+make_str(const char *ptr, int len)
+{
+ char *new_ptr;
+
+ new_ptr = bmake_malloc(len + 1);
+ memcpy(new_ptr, ptr, len);
+ new_ptr[len] = 0;
+ return new_ptr;
+}
+
+static void
+For_Free(For *arg)
+{
+ Buf_Destroy(&arg->buf, TRUE);
+ strlist_clean(&arg->vars);
+ strlist_clean(&arg->items);
+ free(arg->parse_buf);
+
+ free(arg);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * For_Eval --
+ * Evaluate the for loop in the passed line. The line
+ * looks like this:
+ * .for <variable> in <varlist>
+ *
+ * Input:
+ * line Line to parse
+ *
+ * Results:
+ * 0: Not a .for statement, parse the line
+ * 1: We found a for loop
+ * -1: A .for statement with a bad syntax error, discard.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+int
+For_Eval(char *line)
+{
+ For *new_for;
+ char *ptr = line, *sub;
+ int len;
+ int escapes;
+ unsigned char ch;
+ char **words, *word_buf;
+ int n, nwords;
+
+ /* Skip the '.' and any following whitespace */
+ for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
+ continue;
+
+ /*
+ * If we are not in a for loop quickly determine if the statement is
+ * a for.
+ */
+ if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' ||
+ !isspace((unsigned char) ptr[3])) {
+ if (ptr[0] == 'e' && strncmp(ptr+1, "ndfor", 5) == 0) {
+ Parse_Error(PARSE_FATAL, "for-less endfor");
+ return -1;
+ }
+ return 0;
+ }
+ ptr += 3;
+
+ /*
+ * we found a for loop, and now we are going to parse it.
+ */
+
+ new_for = bmake_malloc(sizeof *new_for);
+ memset(new_for, 0, sizeof *new_for);
+
+ /* Grab the variables. Terminate on "in". */
+ for (;; ptr += len) {
+ while (*ptr && isspace((unsigned char) *ptr))
+ ptr++;
+ if (*ptr == '\0') {
+ Parse_Error(PARSE_FATAL, "missing `in' in for");
+ For_Free(new_for);
+ return -1;
+ }
+ for (len = 1; ptr[len] && !isspace((unsigned char)ptr[len]); len++)
+ continue;
+ if (len == 2 && ptr[0] == 'i' && ptr[1] == 'n') {
+ ptr += 2;
+ break;
+ }
+ if (len == 1)
+ new_for->short_var = 1;
+ strlist_add_str(&new_for->vars, make_str(ptr, len), len);
+ }
+
+ if (strlist_num(&new_for->vars) == 0) {
+ Parse_Error(PARSE_FATAL, "no iteration variables in for");
+ For_Free(new_for);
+ return -1;
+ }
+
+ while (*ptr && isspace((unsigned char) *ptr))
+ ptr++;
+
+ /*
+ * Make a list with the remaining words
+ * The values are substituted as ${:U<value>...} so we must \ escape
+ * characters that break that syntax.
+ * Variables are fully expanded - so it is safe for escape $.
+ * We can't do the escapes here - because we don't know whether
+ * we are substuting into ${...} or $(...).
+ */
+ sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE);
+
+ /*
+ * Split into words allowing for quoted strings.
+ */
+ words = brk_string(sub, &nwords, FALSE, &word_buf);
+
+ free(sub);
+
+ if (words != NULL) {
+ for (n = 0; n < nwords; n++) {
+ ptr = words[n];
+ if (!*ptr)
+ continue;
+ escapes = 0;
+ while ((ch = *ptr++)) {
+ switch(ch) {
+ case ':':
+ case '$':
+ case '\\':
+ escapes |= FOR_SUB_ESCAPE_CHAR;
+ break;
+ case ')':
+ escapes |= FOR_SUB_ESCAPE_PAREN;
+ break;
+ case /*{*/ '}':
+ escapes |= FOR_SUB_ESCAPE_BRACE;
+ break;
+ }
+ }
+ /*
+ * We have to dup words[n] to maintain the semantics of
+ * strlist.
+ */
+ strlist_add_str(&new_for->items, bmake_strdup(words[n]), escapes);
+ }
+
+ free(words);
+ free(word_buf);
+
+ if ((len = strlist_num(&new_for->items)) > 0 &&
+ len % (n = strlist_num(&new_for->vars))) {
+ Parse_Error(PARSE_FATAL,
+ "Wrong number of words (%d) in .for substitution list"
+ " with %d vars", len, n);
+ /*
+ * Return 'success' so that the body of the .for loop is
+ * accumulated.
+ * Remove all items so that the loop doesn't iterate.
+ */
+ strlist_clean(&new_for->items);
+ }
+ }
+
+ Buf_Init(&new_for->buf, 0);
+ accumFor = new_for;
+ forLevel = 1;
+ return 1;
+}
+
+/*
+ * Add another line to a .for loop.
+ * Returns 0 when the matching .endfor is reached.
+ */
+
+int
+For_Accum(char *line)
+{
+ char *ptr = line;
+
+ if (*ptr == '.') {
+
+ for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
+ continue;
+
+ if (strncmp(ptr, "endfor", 6) == 0 &&
+ (isspace((unsigned char) ptr[6]) || !ptr[6])) {
+ if (DEBUG(FOR))
+ (void)fprintf(debug_file, "For: end for %d\n", forLevel);
+ if (--forLevel <= 0)
+ return 0;
+ } else if (strncmp(ptr, "for", 3) == 0 &&
+ isspace((unsigned char) ptr[3])) {
+ forLevel++;
+ if (DEBUG(FOR))
+ (void)fprintf(debug_file, "For: new loop %d\n", forLevel);
+ }
+ }
+
+ Buf_AddBytes(&accumFor->buf, strlen(line), line);
+ Buf_AddByte(&accumFor->buf, '\n');
+ return 1;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * For_Run --
+ * Run the for loop, imitating the actions of an include file
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+static int
+for_var_len(const char *var)
+{
+ char ch, var_start, var_end;
+ int depth;
+ int len;
+
+ var_start = *var;
+ if (var_start == 0)
+ /* just escape the $ */
+ return 0;
+
+ if (var_start == '(')
+ var_end = ')';
+ else if (var_start == '{')
+ var_end = '}';
+ else
+ /* Single char variable */
+ return 1;
+
+ depth = 1;
+ for (len = 1; (ch = var[len++]) != 0;) {
+ if (ch == var_start)
+ depth++;
+ else if (ch == var_end && --depth == 0)
+ return len;
+ }
+
+ /* Variable end not found, escape the $ */
+ return 0;
+}
+
+static void
+for_substitute(Buffer *cmds, strlist_t *items, unsigned int item_no, char ech)
+{
+ const char *item = strlist_str(items, item_no);
+ int len;
+ char ch;
+
+ /* If there were no escapes, or the only escape is the other variable
+ * terminator, then just substitute the full string */
+ if (!(strlist_info(items, item_no) &
+ (ech == ')' ? ~FOR_SUB_ESCAPE_BRACE : ~FOR_SUB_ESCAPE_PAREN))) {
+ Buf_AddBytes(cmds, strlen(item), item);
+ return;
+ }
+
+ /* Escape ':', '$', '\\' and 'ech' - removed by :U processing */
+ while ((ch = *item++) != 0) {
+ if (ch == '$') {
+ len = for_var_len(item);
+ if (len != 0) {
+ Buf_AddBytes(cmds, len + 1, item - 1);
+ item += len;
+ continue;
+ }
+ Buf_AddByte(cmds, '\\');
+ } else if (ch == ':' || ch == '\\' || ch == ech)
+ Buf_AddByte(cmds, '\\');
+ Buf_AddByte(cmds, ch);
+ }
+}
+
+static char *
+For_Iterate(void *v_arg, size_t *ret_len)
+{
+ For *arg = v_arg;
+ int i, len;
+ char *var;
+ char *cp;
+ char *cmd_cp;
+ char *body_end;
+ char ch;
+ Buffer cmds;
+
+ if (arg->sub_next + strlist_num(&arg->vars) > strlist_num(&arg->items)) {
+ /* No more iterations */
+ For_Free(arg);
+ return NULL;
+ }
+
+ free(arg->parse_buf);
+ arg->parse_buf = NULL;
+
+ /*
+ * Scan the for loop body and replace references to the loop variables
+ * with variable references that expand to the required text.
+ * Using variable expansions ensures that the .for loop can't generate
+ * syntax, and that the later parsing will still see a variable.
+ * We assume that the null variable will never be defined.
+ *
+ * The detection of substitions of the loop control variable is naive.
+ * Many of the modifiers use \ to escape $ (not $) so it is possible
+ * to contrive a makefile where an unwanted substitution happens.
+ */
+
+ cmd_cp = Buf_GetAll(&arg->buf, &len);
+ body_end = cmd_cp + len;
+ Buf_Init(&cmds, len + 256);
+ for (cp = cmd_cp; (cp = strchr(cp, '$')) != NULL;) {
+ char ech;
+ ch = *++cp;
+ if ((ch == '(' && (ech = ')')) || (ch == '{' && (ech = '}'))) {
+ cp++;
+ /* Check variable name against the .for loop variables */
+ STRLIST_FOREACH(var, &arg->vars, i) {
+ len = strlist_info(&arg->vars, i);
+ if (memcmp(cp, var, len) != 0)
+ continue;
+ if (cp[len] != ':' && cp[len] != ech && cp[len] != '\\')
+ continue;
+ /* Found a variable match. Replace with :U<value> */
+ Buf_AddBytes(&cmds, cp - cmd_cp, cmd_cp);
+ Buf_AddBytes(&cmds, 2, ":U");
+ cp += len;
+ cmd_cp = cp;
+ for_substitute(&cmds, &arg->items, arg->sub_next + i, ech);
+ break;
+ }
+ continue;
+ }
+ if (ch == 0)
+ break;
+ /* Probably a single character name, ignore $$ and stupid ones. {*/
+ if (!arg->short_var || strchr("}):$", ch) != NULL) {
+ cp++;
+ continue;
+ }
+ STRLIST_FOREACH(var, &arg->vars, i) {
+ if (var[0] != ch || var[1] != 0)
+ continue;
+ /* Found a variable match. Replace with ${:U<value>} */
+ Buf_AddBytes(&cmds, cp - cmd_cp, cmd_cp);
+ Buf_AddBytes(&cmds, 3, "{:U");
+ cmd_cp = ++cp;
+ for_substitute(&cmds, &arg->items, arg->sub_next + i, /*{*/ '}');
+ Buf_AddBytes(&cmds, 1, "}");
+ break;
+ }
+ }
+ Buf_AddBytes(&cmds, body_end - cmd_cp, cmd_cp);
+
+ cp = Buf_Destroy(&cmds, FALSE);
+ if (DEBUG(FOR))
+ (void)fprintf(debug_file, "For: loop body:\n%s", cp);
+
+ arg->sub_next += strlist_num(&arg->vars);
+
+ arg->parse_buf = cp;
+ *ret_len = strlen(cp);
+ return cp;
+}
+
+void
+For_Run(int lineno)
+{
+ For *arg;
+
+ arg = accumFor;
+ accumFor = NULL;
+
+ if (strlist_num(&arg->items) == 0) {
+ /* Nothing to expand - possibly due to an earlier syntax error. */
+ For_Free(arg);
+ return;
+ }
+
+ Parse_SetInput(NULL, lineno, -1, For_Iterate, arg);
+}
diff --git a/external/bsd/bmake/dist/getopt.c b/external/bsd/bmake/dist/getopt.c
new file mode 100644
index 0000000..c40bc13
--- /dev/null
+++ b/external/bsd/bmake/dist/getopt.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#if !defined(HAVE_GETOPT) || defined(WANT_GETOPT_LONG) || defined(BROKEN_GETOPT)
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/* static char sccsid[] = "from: @(#)getopt.c 8.2 (Berkeley) 4/2/94"; */
+static char *rcsid = "$Id: getopt.c,v 1.3 1999/01/08 02:14:18 sjg Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+int opterr = 1, /* if error message should be printed */
+ optind = 1, /* index into parent argv vector */
+ optopt = BADCH, /* character checked for validity */
+ optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt(nargc, nargv, ostr)
+ int nargc;
+ char * const *nargv;
+ const char *ostr;
+{
+ extern char *__progname;
+ static char *place = EMSG; /* option letter processing */
+ char *oli; /* option letter list index */
+
+#ifndef BSD4_4
+ if (!__progname) {
+ if (__progname = strrchr(nargv[0], '/'))
+ ++__progname;
+ else
+ __progname = nargv[0];
+ }
+#endif
+
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc || *(place = nargv[optind]) != '-') {
+ place = EMSG;
+ return (-1);
+ }
+ if (place[1] && *++place == '-' /* found "--" */
+ && !place[1]) { /* and not "--foo" */
+ ++optind;
+ place = EMSG;
+ return (-1);
+ }
+ } /* option letter okay? */
+ if ((optopt = (int)*place++) == (int)':' ||
+ !(oli = strchr(ostr, optopt))) {
+ /*
+ * if the user didn't specify '-' as an option,
+ * assume it means -1.
+ */
+ if (optopt == (int)'-')
+ return (-1);
+ if (!*place)
+ ++optind;
+ if (opterr && *ostr != ':')
+ (void)fprintf(stderr,
+ "%s: illegal option -- %c\n", __progname, optopt);
+ return (BADCH);
+ }
+ if (*++oli != ':') { /* don't need argument */
+ optarg = NULL;
+ if (!*place)
+ ++optind;
+ }
+ else { /* need an argument */
+ if (*place) /* no white space */
+ optarg = place;
+ else if (nargc <= ++optind) { /* no arg */
+ place = EMSG;
+ if (*ostr == ':')
+ return (BADARG);
+ if (opterr)
+ (void)fprintf(stderr,
+ "%s: option requires an argument -- %c\n",
+ __progname, optopt);
+ return (BADCH);
+ }
+ else /* white space */
+ optarg = nargv[optind];
+ place = EMSG;
+ ++optind;
+ }
+ return (optopt); /* dump back option letter */
+}
+#endif
+#ifdef MAIN
+#ifndef BSD4_4
+char *__progname;
+#endif
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int c;
+ char *opts = argv[1];
+
+ --argc;
+ ++argv;
+
+ while ((c = getopt(argc, argv, opts)) != EOF) {
+ switch (c) {
+ case '-':
+ if (optarg)
+ printf("--%s ", optarg);
+ break;
+ case '?':
+ exit(1);
+ break;
+ default:
+ if (optarg)
+ printf("-%c %s ", c, optarg);
+ else
+ printf("-%c ", c);
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ printf("-- ");
+ for (; optind < argc; ++optind) {
+ printf("%s ", argv[optind]);
+ }
+ }
+ printf("\n");
+ exit(0);
+}
+#endif
diff --git a/external/bsd/bmake/dist/hash.c b/external/bsd/bmake/dist/hash.c
new file mode 100644
index 0000000..a22e2f2
--- /dev/null
+++ b/external/bsd/bmake/dist/hash.c
@@ -0,0 +1,463 @@
+/* $NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/* hash.c --
+ *
+ * This module contains routines to manipulate a hash table.
+ * See hash.h for a definition of the structure of the hash
+ * table. Hash tables grow automatically as the amount of
+ * information increases.
+ */
+#include "sprite.h"
+#include "make.h"
+#include "hash.h"
+
+/*
+ * Forward references to local procedures that are used before they're
+ * defined:
+ */
+
+static void RebuildTable(Hash_Table *);
+
+/*
+ * The following defines the ratio of # entries to # buckets
+ * at which we rebuild the table to make it larger.
+ */
+
+#define rebuildLimit 3
+
+/*
+ *---------------------------------------------------------
+ *
+ * Hash_InitTable --
+ *
+ * This routine just sets up the hash table.
+ *
+ * Input:
+ * t Structure to to hold table.
+ * numBuckets How many buckets to create for starters. This
+ * number is rounded up to a power of two. If
+ * <= 0, a reasonable default is chosen. The
+ * table will grow in size later as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Memory is allocated for the initial bucket area.
+ *
+ *---------------------------------------------------------
+ */
+
+void
+Hash_InitTable(Hash_Table *t, int numBuckets)
+{
+ int i;
+ struct Hash_Entry **hp;
+
+ /*
+ * Round up the size to a power of two.
+ */
+ if (numBuckets <= 0)
+ i = 16;
+ else {
+ for (i = 2; i < numBuckets; i <<= 1)
+ continue;
+ }
+ t->numEntries = 0;
+ t->size = i;
+ t->mask = i - 1;
+ t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i);
+ while (--i >= 0)
+ *hp++ = NULL;
+}
+
+/*
+ *---------------------------------------------------------
+ *
+ * Hash_DeleteTable --
+ *
+ * This routine removes everything from a hash table
+ * and frees up the memory space it occupied (except for
+ * the space in the Hash_Table structure).
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Lots of memory is freed up.
+ *
+ *---------------------------------------------------------
+ */
+
+void
+Hash_DeleteTable(Hash_Table *t)
+{
+ struct Hash_Entry **hp, *h, *nexth = NULL;
+ int i;
+
+ for (hp = t->bucketPtr, i = t->size; --i >= 0;) {
+ for (h = *hp++; h != NULL; h = nexth) {
+ nexth = h->next;
+ free(h);
+ }
+ }
+ free(t->bucketPtr);
+
+ /*
+ * Set up the hash table to cause memory faults on any future access
+ * attempts until re-initialization.
+ */
+ t->bucketPtr = NULL;
+}
+
+/*
+ *---------------------------------------------------------
+ *
+ * Hash_FindEntry --
+ *
+ * Searches a hash table for an entry corresponding to key.
+ *
+ * Input:
+ * t Hash table to search.
+ * key A hash key.
+ *
+ * Results:
+ * The return value is a pointer to the entry for key,
+ * if key was present in the table. If key was not
+ * present, NULL is returned.
+ *
+ * Side Effects:
+ * None.
+ *
+ *---------------------------------------------------------
+ */
+
+Hash_Entry *
+Hash_FindEntry(Hash_Table *t, const char *key)
+{
+ Hash_Entry *e;
+ unsigned h;
+ const char *p;
+
+ for (h = 0, p = key; *p;)
+ h = (h << 5) - h + *p++;
+ p = key;
+ for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next)
+ if (e->namehash == h && strcmp(e->name, p) == 0)
+ return (e);
+ return NULL;
+}
+
+/*
+ *---------------------------------------------------------
+ *
+ * Hash_CreateEntry --
+ *
+ * Searches a hash table for an entry corresponding to
+ * key. If no entry is found, then one is created.
+ *
+ * Input:
+ * t Hash table to search.
+ * key A hash key.
+ * newPtr Filled in with TRUE if new entry created,
+ * FALSE otherwise.
+ *
+ * Results:
+ * The return value is a pointer to the entry. If *newPtr
+ * isn't NULL, then *newPtr is filled in with TRUE if a
+ * new entry was created, and FALSE if an entry already existed
+ * with the given key.
+ *
+ * Side Effects:
+ * Memory may be allocated, and the hash buckets may be modified.
+ *---------------------------------------------------------
+ */
+
+Hash_Entry *
+Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr)
+{
+ Hash_Entry *e;
+ unsigned h;
+ const char *p;
+ int keylen;
+ struct Hash_Entry **hp;
+
+ /*
+ * Hash the key. As a side effect, save the length (strlen) of the
+ * key in case we need to create the entry.
+ */
+ for (h = 0, p = key; *p;)
+ h = (h << 5) - h + *p++;
+ keylen = p - key;
+ p = key;
+ for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) {
+ if (e->namehash == h && strcmp(e->name, p) == 0) {
+ if (newPtr != NULL)
+ *newPtr = FALSE;
+ return (e);
+ }
+ }
+
+ /*
+ * The desired entry isn't there. Before allocating a new entry,
+ * expand the table if necessary (and this changes the resulting
+ * bucket chain).
+ */
+ if (t->numEntries >= rebuildLimit * t->size)
+ RebuildTable(t);
+ e = bmake_malloc(sizeof(*e) + keylen);
+ hp = &t->bucketPtr[h & t->mask];
+ e->next = *hp;
+ *hp = e;
+ Hash_SetValue(e, NULL);
+ e->namehash = h;
+ (void)strcpy(e->name, p);
+ t->numEntries++;
+
+ if (newPtr != NULL)
+ *newPtr = TRUE;
+ return (e);
+}
+
+/*
+ *---------------------------------------------------------
+ *
+ * Hash_DeleteEntry --
+ *
+ * Delete the given hash table entry and free memory associated with
+ * it.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Hash chain that entry lives in is modified and memory is freed.
+ *
+ *---------------------------------------------------------
+ */
+
+void
+Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
+{
+ Hash_Entry **hp, *p;
+
+ if (e == NULL)
+ return;
+ for (hp = &t->bucketPtr[e->namehash & t->mask];
+ (p = *hp) != NULL; hp = &p->next) {
+ if (p == e) {
+ *hp = p->next;
+ free(p);
+ t->numEntries--;
+ return;
+ }
+ }
+ (void)write(2, "bad call to Hash_DeleteEntry\n", 29);
+ abort();
+}
+
+/*
+ *---------------------------------------------------------
+ *
+ * Hash_EnumFirst --
+ * This procedure sets things up for a complete search
+ * of all entries recorded in the hash table.
+ *
+ * Input:
+ * t Table to be searched.
+ * searchPtr Area in which to keep state about search.
+ *
+ * Results:
+ * The return value is the address of the first entry in
+ * the hash table, or NULL if the table is empty.
+ *
+ * Side Effects:
+ * The information in searchPtr is initialized so that successive
+ * calls to Hash_Next will return successive HashEntry's
+ * from the table.
+ *
+ *---------------------------------------------------------
+ */
+
+Hash_Entry *
+Hash_EnumFirst(Hash_Table *t, Hash_Search *searchPtr)
+{
+ searchPtr->tablePtr = t;
+ searchPtr->nextIndex = 0;
+ searchPtr->hashEntryPtr = NULL;
+ return Hash_EnumNext(searchPtr);
+}
+
+/*
+ *---------------------------------------------------------
+ *
+ * Hash_EnumNext --
+ * This procedure returns successive entries in the hash table.
+ *
+ * Input:
+ * searchPtr Area used to keep state about search.
+ *
+ * Results:
+ * The return value is a pointer to the next HashEntry
+ * in the table, or NULL when the end of the table is
+ * reached.
+ *
+ * Side Effects:
+ * The information in searchPtr is modified to advance to the
+ * next entry.
+ *
+ *---------------------------------------------------------
+ */
+
+Hash_Entry *
+Hash_EnumNext(Hash_Search *searchPtr)
+{
+ Hash_Entry *e;
+ Hash_Table *t = searchPtr->tablePtr;
+
+ /*
+ * The hashEntryPtr field points to the most recently returned
+ * entry, or is nil if we are starting up. If not nil, we have
+ * to start at the next one in the chain.
+ */
+ e = searchPtr->hashEntryPtr;
+ if (e != NULL)
+ e = e->next;
+ /*
+ * If the chain ran out, or if we are starting up, we need to
+ * find the next nonempty chain.
+ */
+ while (e == NULL) {
+ if (searchPtr->nextIndex >= t->size)
+ return NULL;
+ e = t->bucketPtr[searchPtr->nextIndex++];
+ }
+ searchPtr->hashEntryPtr = e;
+ return (e);
+}
+
+/*
+ *---------------------------------------------------------
+ *
+ * RebuildTable --
+ * This local routine makes a new hash table that
+ * is larger than the old one.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The entire hash table is moved, so any bucket numbers
+ * from the old table are invalid.
+ *
+ *---------------------------------------------------------
+ */
+
+static void
+RebuildTable(Hash_Table *t)
+{
+ Hash_Entry *e, *next = NULL, **hp, **xp;
+ int i, mask;
+ Hash_Entry **oldhp;
+ int oldsize;
+
+ oldhp = t->bucketPtr;
+ oldsize = i = t->size;
+ i <<= 1;
+ t->size = i;
+ t->mask = mask = i - 1;
+ t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i);
+ while (--i >= 0)
+ *hp++ = NULL;
+ for (hp = oldhp, i = oldsize; --i >= 0;) {
+ for (e = *hp++; e != NULL; e = next) {
+ next = e->next;
+ xp = &t->bucketPtr[e->namehash & mask];
+ e->next = *xp;
+ *xp = e;
+ }
+ }
+ free(oldhp);
+}
diff --git a/external/bsd/bmake/dist/hash.h b/external/bsd/bmake/dist/hash.h
new file mode 100644
index 0000000..31d2ff1
--- /dev/null
+++ b/external/bsd/bmake/dist/hash.h
@@ -0,0 +1,154 @@
+/* $NetBSD: hash.h,v 1.10 2009/01/24 10:59:09 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)hash.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)hash.h 8.1 (Berkeley) 6/6/93
+ */
+
+/* hash.h --
+ *
+ * This file contains definitions used by the hash module,
+ * which maintains hash tables.
+ */
+
+#ifndef _HASH
+#define _HASH
+
+/*
+ * The following defines one entry in the hash table.
+ */
+
+typedef struct Hash_Entry {
+ struct Hash_Entry *next; /* Used to link together all the
+ * entries associated with the same
+ * bucket. */
+ union {
+ void *clientPtr; /* Arbitrary pointer */
+ time_t clientTime; /* Arbitrary Time */
+ } clientInfo;
+ unsigned namehash; /* hash value of key */
+ char name[1]; /* key string */
+} Hash_Entry;
+
+typedef struct Hash_Table {
+ struct Hash_Entry **bucketPtr;/* Pointers to Hash_Entry, one
+ * for each bucket in the table. */
+ int size; /* Actual size of array. */
+ int numEntries; /* Number of entries in the table. */
+ int mask; /* Used to select bits for hashing. */
+} Hash_Table;
+
+/*
+ * The following structure is used by the searching routines
+ * to record where we are in the search.
+ */
+
+typedef struct Hash_Search {
+ Hash_Table *tablePtr; /* Table being searched. */
+ int nextIndex; /* Next bucket to check (after current). */
+ Hash_Entry *hashEntryPtr; /* Next entry to check in current bucket. */
+} Hash_Search;
+
+/*
+ * Macros.
+ */
+
+/*
+ * void * Hash_GetValue(h)
+ * Hash_Entry *h;
+ */
+
+#define Hash_GetValue(h) ((h)->clientInfo.clientPtr)
+#define Hash_GetTimeValue(h) ((h)->clientInfo.clientTime)
+
+/*
+ * Hash_SetValue(h, val);
+ * Hash_Entry *h;
+ * char *val;
+ */
+
+#define Hash_SetValue(h, val) ((h)->clientInfo.clientPtr = (val))
+#define Hash_SetTimeValue(h, val) ((h)->clientInfo.clientTime = (val))
+
+/*
+ * Hash_Size(n) returns the number of words in an object of n bytes
+ */
+
+#define Hash_Size(n) (((n) + sizeof (int) - 1) / sizeof (int))
+
+void Hash_InitTable(Hash_Table *, int);
+void Hash_DeleteTable(Hash_Table *);
+Hash_Entry *Hash_FindEntry(Hash_Table *, const char *);
+Hash_Entry *Hash_CreateEntry(Hash_Table *, const char *, Boolean *);
+void Hash_DeleteEntry(Hash_Table *, Hash_Entry *);
+Hash_Entry *Hash_EnumFirst(Hash_Table *, Hash_Search *);
+Hash_Entry *Hash_EnumNext(Hash_Search *);
+
+#endif /* _HASH */
diff --git a/external/bsd/bmake/dist/install-sh b/external/bsd/bmake/dist/install-sh
new file mode 100755
index 0000000..a247329
--- /dev/null
+++ b/external/bsd/bmake/dist/install-sh
@@ -0,0 +1,201 @@
+:
+# NAME:
+# install.sh - portable version of install(1)
+#
+# SYNOPSIS:
+# install [-CNcs] [-f flags] [-i errs] [-o owner] [-g group] [-m mode] file1 file2 ...
+# install -d [-i errs] [-o owner] [-g group] [-m mode] directory ...
+#
+# DESCRIPTION:
+# Compatible with BSD install(1). Except that '-c' is always
+# true and we always move an already installed target aside as
+# this is important on many systems. Recent BSD install(1)
+# versions have a '-b' option for this.
+#
+#
+# OPTIONS:
+# -b move previous target file aside (always true).
+#
+# -B "suffix"
+# use "suffix" instead of .old for saving existing target.
+#
+# -c copy rather than move the file into place (always true).
+#
+# -C compare. Only install if target is missing or
+# different.
+#
+# -N newer. Only install if target is missing or older.
+#
+# -s strip target
+#
+# -o "owner"
+# make target owned by "owner"
+#
+# -g "group"
+# make target group owned by "group"
+#
+# -m "mode"
+# set permissions to "mode"
+#
+# -f "flags"
+# Pass "flags" onto chflags(1)
+#
+# -i "errs"
+# Ignore errors from steps indicated by "errs" (``s,o,g,m'').
+#
+# BUGS:
+# The '-i' option is to save your sanity when 'bsd.prog.mk'
+# insists on haveing a '-o' "owner" option which is doomed to
+# fail on many systems. We ignore '-b', '-B' and '-c' options.
+#
+# AUTHOR:
+# Simon J. Gerraty <sjg@quick.com.au>
+#
+
+# RCSid:
+# $Id: install-sh,v 1.18 2001/03/16 17:33:02 sjg Exp $
+#
+# @(#) Copyright (c) 1993 Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@quick.com.au
+#
+
+set -- `getopt B:bpxCNcsdo:g:m:i:f: $*`
+
+Mydir=`dirname $0`
+[ -s $Mydir/.installrc ] && . $Mydir/.installrc
+
+owner=:
+group=:
+mode=:
+strip=:
+mkdirs=
+compare=:
+newer=:
+chflags=:
+LS1=
+CP_P=
+
+while [ $# -gt 1 ]
+do
+ case $1 in
+ --) shift; break;;
+ -p) CP_P=-p;;
+ -x) set -x;;
+ -B) OLD_EXT=$2; shift;;
+ -C) compare=Different;;
+ -N) newer=Newer;
+ # check if /bin/ls supports -1
+ /bin/ls -1 $0 >/dev/null 2>&1 && LS1=1
+ ;;
+ -o) owner="${CHOWN:-chown} $2 "; shift;;
+ -g) group="${CHGRP:-chgrp} $2 "; shift;;
+ -m) mode="${CHMOD:-chmod} $2 "; shift;;
+ -s) strip=${STRIP:-strip};;
+ -d) mkdirs="mkdir -p";;
+ -i) ignore_err="$ignore_err$2"; shift;;
+ -f) chflags="${CHFLAGS:-chflags} $2 "; shift;;
+ esac
+ shift
+done
+
+Newer() {
+ n=`/bin/ls -t$LS1 $* 2>/dev/null | head -1`
+ [ $1 = $n ]
+}
+
+Different() {
+ cmp -s $*
+ [ $? != 0 ]
+}
+
+Err() {
+ case "$ignore_err" in
+ *$1*) ;;
+ *) exit 1;;
+ esac
+}
+
+Setem() {
+ # the order is important
+ if [ ! -d $1 ]; then
+ $strip $1 || Err s
+ fi
+ $group $1 || Err g
+ $owner $1 || Err o
+ $mode $1 || Err m
+ $chflags $1 || Err f
+ return 0
+}
+
+# a bug in HP-UX's /bin/sh, means we need to re-set $*
+# after any calls to add_path()
+args="$*"
+
+# all this just for chown!
+add_path () { [ -d $1 ] && eval ${2:-PATH}="\$${2:-PATH}:$1"; }
+add_path /etc
+add_path /usr/etc
+add_path /sbin
+add_path /usr/sbin
+
+# restore saved $*
+set -- $args
+
+# make directories if needed
+# and ensure mode etc are as desired
+if [ "$mkdirs" ]; then
+ for d in $*
+ do
+ [ ! -d $d ] && $mkdirs $d
+ Setem $d
+ done
+ exit 0 # that's all we do
+fi
+
+# install files
+if [ $# -gt 2 ]; then
+ dest_dir=yes
+elif [ $# -eq 1 ]; then
+ echo "what should I do with $*?" >&2
+ exit 1
+fi
+
+# get list of files
+while [ $# -gt 1 ]
+do
+ files="$files $1"
+ shift
+done
+# last one is dest
+dest=$1
+shift
+
+
+if [ "$dest_dir" = yes -a ! -d $dest ]; then
+ echo "no directory $dest" >&2
+ exit 1
+fi
+
+for f in $files
+do
+ b=`basename $f`
+ if [ -d $dest ]; then
+ t=$dest/$b
+ else
+ t=$dest
+ fi
+ $newer $f $t || continue
+ $compare $f $t || continue
+ [ -f $t ] && { mv -f $t $t.old || exit 1; }
+ { cp $CP_P $f $t && Setem $t; } || exit 1
+done
+exit 0
diff --git a/external/bsd/bmake/dist/job.c b/external/bsd/bmake/dist/job.c
new file mode 100644
index 0000000..99e05d5
--- /dev/null
+++ b/external/bsd/bmake/dist/job.c
@@ -0,0 +1,2994 @@
+/* $NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
+#else
+__RCSID("$NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * job.c --
+ * handle the creation etc. of our child processes.
+ *
+ * Interface:
+ * Job_Make Start the creation of the given target.
+ *
+ * Job_CatchChildren Check for and handle the termination of any
+ * children. This must be called reasonably
+ * frequently to keep the whole make going at
+ * a decent clip, since job table entries aren't
+ * removed until their process is caught this way.
+ *
+ * Job_CatchOutput Print any output our children have produced.
+ * Should also be called fairly frequently to
+ * keep the user informed of what's going on.
+ * If no output is waiting, it will block for
+ * a time given by the SEL_* constants, below,
+ * or until output is ready.
+ *
+ * Job_Init Called to intialize this module. in addition,
+ * any commands attached to the .BEGIN target
+ * are executed before this function returns.
+ * Hence, the makefile must have been parsed
+ * before this function is called.
+ *
+ * Job_End Cleanup any memory used.
+ *
+ * Job_ParseShell Given the line following a .SHELL target, parse
+ * the line as a shell specification. Returns
+ * FAILURE if the spec was incorrect.
+ *
+ * Job_Finish Perform any final processing which needs doing.
+ * This includes the execution of any commands
+ * which have been/were attached to the .END
+ * target. It should only be called when the
+ * job table is empty.
+ *
+ * Job_AbortAll Abort all currently running jobs. It doesn't
+ * handle output or do anything for the jobs,
+ * just kills them. It should only be called in
+ * an emergency, as it were.
+ *
+ * Job_CheckCommands Verify that the commands for a target are
+ * ok. Provide them if necessary and possible.
+ *
+ * Job_Touch Update a target without really updating it.
+ *
+ * Job_Wait Wait for all currently-running jobs to finish.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include "wait.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#if !defined(USE_SELECT) && defined(HAVE_POLL_H)
+#include <poll.h>
+#else
+#ifndef USE_SELECT /* no poll.h */
+# define USE_SELECT
+#endif
+#if defined(HAVE_SYS_SELECT_H)
+# include <sys/select.h>
+#endif
+#endif
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <utime.h>
+#if defined(HAVE_SYS_SOCKET_H)
+# include <sys/socket.h>
+#endif
+
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+#include "job.h"
+#include "pathnames.h"
+#include "trace.h"
+# define STATIC static
+
+/*
+ * error handling variables
+ */
+static int errors = 0; /* number of errors reported */
+static int aborting = 0; /* why is the make aborting? */
+#define ABORT_ERROR 1 /* Because of an error */
+#define ABORT_INTERRUPT 2 /* Because it was interrupted */
+#define ABORT_WAIT 3 /* Waiting for jobs to finish */
+#define JOB_TOKENS "+EI+" /* Token to requeue for each abort state */
+
+/*
+ * this tracks the number of tokens currently "out" to build jobs.
+ */
+int jobTokensRunning = 0;
+int not_parallel = 0; /* set if .NOT_PARALLEL */
+
+/*
+ * XXX: Avoid SunOS bug... FILENO() is fp->_file, and file
+ * is a char! So when we go above 127 we turn negative!
+ */
+#define FILENO(a) ((unsigned) fileno(a))
+
+/*
+ * post-make command processing. The node postCommands is really just the
+ * .END target but we keep it around to avoid having to search for it
+ * all the time.
+ */
+static GNode *postCommands = NULL;
+ /* node containing commands to execute when
+ * everything else is done */
+static int numCommands; /* The number of commands actually printed
+ * for a target. Should this number be
+ * 0, no shell will be executed. */
+
+/*
+ * Return values from JobStart.
+ */
+#define JOB_RUNNING 0 /* Job is running */
+#define JOB_ERROR 1 /* Error in starting the job */
+#define JOB_FINISHED 2 /* The job is already finished */
+
+/*
+ * Descriptions for various shells.
+ *
+ * The build environment may set DEFSHELL_INDEX to one of
+ * DEFSHELL_INDEX_SH, DEFSHELL_INDEX_KSH, or DEFSHELL_INDEX_CSH, to
+ * select one of the prefedined shells as the default shell.
+ *
+ * Alternatively, the build environment may set DEFSHELL_CUSTOM to the
+ * name or the full path of a sh-compatible shell, which will be used as
+ * the default shell.
+ *
+ * ".SHELL" lines in Makefiles can choose the default shell from the
+ # set defined here, or add additional shells.
+ */
+
+#ifdef DEFSHELL_CUSTOM
+#define DEFSHELL_INDEX_CUSTOM 0
+#define DEFSHELL_INDEX_SH 1
+#define DEFSHELL_INDEX_KSH 2
+#define DEFSHELL_INDEX_CSH 3
+#else /* !DEFSHELL_CUSTOM */
+#define DEFSHELL_INDEX_SH 0
+#define DEFSHELL_INDEX_KSH 1
+#define DEFSHELL_INDEX_CSH 2
+#endif /* !DEFSHELL_CUSTOM */
+
+#ifndef DEFSHELL_INDEX
+#define DEFSHELL_INDEX 0 /* DEFSHELL_INDEX_CUSTOM or DEFSHELL_INDEX_SH */
+#endif /* !DEFSHELL_INDEX */
+
+static Shell shells[] = {
+#ifdef DEFSHELL_CUSTOM
+ /*
+ * An sh-compatible shell with a non-standard name.
+ *
+ * Keep this in sync with the "sh" description below, but avoid
+ * non-portable features that might not be supplied by all
+ * sh-compatible shells.
+ */
+{
+ DEFSHELL_CUSTOM,
+ FALSE, "", "", "", 0,
+ FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", "'\n'", '#',
+ "",
+ "",
+},
+#endif /* DEFSHELL_CUSTOM */
+ /*
+ * SH description. Echo control is also possible and, under
+ * sun UNIX anyway, one can even control error checking.
+ */
+{
+ "sh",
+ FALSE, "", "", "", 0,
+ FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", "'\n'", '#',
+#if defined(MAKE_NATIVE) && defined(__NetBSD__)
+ "q",
+#else
+ "",
+#endif
+ "",
+},
+ /*
+ * KSH description.
+ */
+{
+ "ksh",
+ TRUE, "set +v", "set -v", "set +v", 6,
+ FALSE, "echo \"%s\"\n", "%s\n", "{ %s \n} || exit $?\n", "'\n'", '#',
+ "v",
+ "",
+},
+ /*
+ * CSH description. The csh can do echo control by playing
+ * with the setting of the 'echo' shell variable. Sadly,
+ * however, it is unable to do error control nicely.
+ */
+{
+ "csh",
+ TRUE, "unset verbose", "set verbose", "unset verbose", 10,
+ FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"\n", "", "'\\\n'", '#',
+ "v", "e",
+},
+ /*
+ * UNKNOWN.
+ */
+{
+ NULL,
+ FALSE, NULL, NULL, NULL, 0,
+ FALSE, NULL, NULL, NULL, NULL, 0,
+ NULL, NULL,
+}
+};
+static Shell *commandShell = &shells[DEFSHELL_INDEX]; /* this is the shell to
+ * which we pass all
+ * commands in the Makefile.
+ * It is set by the
+ * Job_ParseShell function */
+const char *shellPath = NULL, /* full pathname of
+ * executable image */
+ *shellName = NULL; /* last component of shell */
+static const char *shellArgv = NULL; /* Custom shell args */
+
+
+STATIC Job *job_table; /* The structures that describe them */
+STATIC Job *job_table_end; /* job_table + maxJobs */
+static int wantToken; /* we want a token */
+static int lurking_children = 0;
+static int make_suspended = 0; /* non-zero if we've seen a SIGTSTP (etc) */
+
+/*
+ * Set of descriptors of pipes connected to
+ * the output channels of children
+ */
+static struct pollfd *fds = NULL;
+static Job **jobfds = NULL;
+static int nfds = 0;
+static void watchfd(Job *);
+static void clearfd(Job *);
+static int readyfd(Job *);
+
+STATIC GNode *lastNode; /* The node for which output was most recently
+ * produced. */
+static char *targPrefix = NULL; /* What we print at the start of TARG_FMT */
+static Job tokenWaitJob; /* token wait pseudo-job */
+
+static Job childExitJob; /* child exit pseudo-job */
+#define CHILD_EXIT "."
+#define DO_JOB_RESUME "R"
+
+#define TARG_FMT "%s %s ---\n" /* Default format */
+#define MESSAGE(fp, gn) \
+ if (maxJobs != 1) \
+ (void)fprintf(fp, TARG_FMT, targPrefix, gn->name)
+
+static sigset_t caught_signals; /* Set of signals we handle */
+#if defined(SYSV)
+#define KILLPG(pid, sig) kill(-(pid), (sig))
+#else
+#define KILLPG(pid, sig) killpg((pid), (sig))
+#endif
+
+static void JobChildSig(int);
+static void JobContinueSig(int);
+static Job *JobFindPid(int, int, Boolean);
+static int JobPrintCommand(void *, void *);
+static int JobSaveCommand(void *, void *);
+static void JobClose(Job *);
+static void JobExec(Job *, char **);
+static void JobMakeArgv(Job *, char **);
+static int JobStart(GNode *, int);
+static char *JobOutput(Job *, char *, char *, int);
+static void JobDoOutput(Job *, Boolean);
+static Shell *JobMatchShell(const char *);
+static void JobInterrupt(int, int) MAKE_ATTR_DEAD;
+static void JobRestartJobs(void);
+static void JobTokenAdd(void);
+static void JobSigLock(sigset_t *);
+static void JobSigUnlock(sigset_t *);
+static void JobSigReset(void);
+
+const char *malloc_options="A";
+
+static void
+job_table_dump(const char *where)
+{
+ Job *job;
+
+ fprintf(debug_file, "job table @ %s\n", where);
+ for (job = job_table; job < job_table_end; job++) {
+ fprintf(debug_file, "job %d, status %d, flags %d, pid %d\n",
+ (int)(job - job_table), job->job_state, job->flags, job->pid);
+ }
+}
+
+/*
+ * JobSigLock/JobSigUnlock
+ *
+ * Signal lock routines to get exclusive access. Currently used to
+ * protect `jobs' and `stoppedJobs' list manipulations.
+ */
+static void JobSigLock(sigset_t *omaskp)
+{
+ if (sigprocmask(SIG_BLOCK, &caught_signals, omaskp) != 0) {
+ Punt("JobSigLock: sigprocmask: %s", strerror(errno));
+ sigemptyset(omaskp);
+ }
+}
+
+static void JobSigUnlock(sigset_t *omaskp)
+{
+ (void)sigprocmask(SIG_SETMASK, omaskp, NULL);
+}
+
+static void
+JobCreatePipe(Job *job, int minfd)
+{
+ int i, fd;
+
+ if (pipe(job->jobPipe) == -1)
+ Punt("Cannot create pipe: %s", strerror(errno));
+
+ /* Set close-on-exec flag for both */
+ (void)fcntl(job->jobPipe[0], F_SETFD, 1);
+ (void)fcntl(job->jobPipe[1], F_SETFD, 1);
+
+ /*
+ * We mark the input side of the pipe non-blocking; we poll(2) the
+ * pipe when we're waiting for a job token, but we might lose the
+ * race for the token when a new one becomes available, so the read
+ * from the pipe should not block.
+ */
+ fcntl(job->jobPipe[0], F_SETFL,
+ fcntl(job->jobPipe[0], F_GETFL, 0) | O_NONBLOCK);
+
+ for (i = 0; i < 2; i++) {
+ /* Avoid using low numbered fds */
+ fd = fcntl(job->jobPipe[i], F_DUPFD, minfd);
+ if (fd != -1) {
+ close(job->jobPipe[i]);
+ job->jobPipe[i] = fd;
+ }
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobCondPassSig --
+ * Pass a signal to a job
+ *
+ * Input:
+ * signop Signal to send it
+ *
+ * Side Effects:
+ * None, except the job may bite it.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+JobCondPassSig(int signo)
+{
+ Job *job;
+
+ if (DEBUG(JOB)) {
+ (void)fprintf(debug_file, "JobCondPassSig(%d) called.\n", signo);
+ }
+
+ for (job = job_table; job < job_table_end; job++) {
+ if (job->job_state != JOB_ST_RUNNING)
+ continue;
+ if (DEBUG(JOB)) {
+ (void)fprintf(debug_file,
+ "JobCondPassSig passing signal %d to child %d.\n",
+ signo, job->pid);
+ }
+ KILLPG(job->pid, signo);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobChldSig --
+ * SIGCHLD handler.
+ *
+ * Input:
+ * signo The signal number we've received
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Sends a token on the child exit pipe to wake us up from
+ * select()/poll().
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+JobChildSig(int signo MAKE_ATTR_UNUSED)
+{
+ write(childExitJob.outPipe, CHILD_EXIT, 1);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobContinueSig --
+ * Resume all stopped jobs.
+ *
+ * Input:
+ * signo The signal number we've received
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Jobs start running again.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+JobContinueSig(int signo MAKE_ATTR_UNUSED)
+{
+ /*
+ * Defer sending to SIGCONT to our stopped children until we return
+ * from the signal handler.
+ */
+ write(childExitJob.outPipe, DO_JOB_RESUME, 1);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobPassSig --
+ * Pass a signal on to all jobs, then resend to ourselves.
+ *
+ * Input:
+ * signo The signal number we've received
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * We die by the same signal.
+ *
+ *-----------------------------------------------------------------------
+ */
+MAKE_ATTR_DEAD static void
+JobPassSig_int(int signo)
+{
+ /* Run .INTERRUPT target then exit */
+ JobInterrupt(TRUE, signo);
+}
+
+MAKE_ATTR_DEAD static void
+JobPassSig_term(int signo)
+{
+ /* Dont run .INTERRUPT target then exit */
+ JobInterrupt(FALSE, signo);
+}
+
+static void
+JobPassSig_suspend(int signo)
+{
+ sigset_t nmask, omask;
+ struct sigaction act;
+
+ /* Suppress job started/continued messages */
+ make_suspended = 1;
+
+ /* Pass the signal onto every job */
+ JobCondPassSig(signo);
+
+ /*
+ * Send ourselves the signal now we've given the message to everyone else.
+ * Note we block everything else possible while we're getting the signal.
+ * This ensures that all our jobs get continued when we wake up before
+ * we take any other signal.
+ */
+ sigfillset(&nmask);
+ sigdelset(&nmask, signo);
+ (void)sigprocmask(SIG_SETMASK, &nmask, &omask);
+
+ act.sa_handler = SIG_DFL;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ (void)sigaction(signo, &act, NULL);
+
+ if (DEBUG(JOB)) {
+ (void)fprintf(debug_file,
+ "JobPassSig passing signal %d to self.\n", signo);
+ }
+
+ (void)kill(getpid(), signo);
+
+ /*
+ * We've been continued.
+ *
+ * A whole host of signals continue to happen!
+ * SIGCHLD for any processes that actually suspended themselves.
+ * SIGCHLD for any processes that exited while we were alseep.
+ * The SIGCONT that actually caused us to wakeup.
+ *
+ * Since we defer passing the SIGCONT on to our children until
+ * the main processing loop, we can be sure that all the SIGCHLD
+ * events will have happened by then - and that the waitpid() will
+ * collect the child 'suspended' events.
+ * For correct sequencing we just need to ensure we process the
+ * waitpid() before passign on the SIGCONT.
+ *
+ * In any case nothing else is needed here.
+ */
+
+ /* Restore handler and signal mask */
+ act.sa_handler = JobPassSig_suspend;
+ (void)sigaction(signo, &act, NULL);
+ (void)sigprocmask(SIG_SETMASK, &omask, NULL);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobFindPid --
+ * Compare the pid of the job with the given pid and return 0 if they
+ * are equal. This function is called from Job_CatchChildren
+ * to find the job descriptor of the finished job.
+ *
+ * Input:
+ * job job to examine
+ * pid process id desired
+ *
+ * Results:
+ * Job with matching pid
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+static Job *
+JobFindPid(int pid, int status, Boolean isJobs)
+{
+ Job *job;
+
+ for (job = job_table; job < job_table_end; job++) {
+ if ((job->job_state == status) && job->pid == pid)
+ return job;
+ }
+ if (DEBUG(JOB) && isJobs)
+ job_table_dump("no pid");
+ return NULL;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobPrintCommand --
+ * Put out another command for the given job. If the command starts
+ * with an @ or a - we process it specially. In the former case,
+ * so long as the -s and -n flags weren't given to make, we stick
+ * a shell-specific echoOff command in the script. In the latter,
+ * we ignore errors for the entire job, unless the shell has error
+ * control.
+ * If the command is just "..." we take all future commands for this
+ * job to be commands to be executed once the entire graph has been
+ * made and return non-zero to signal that the end of the commands
+ * was reached. These commands are later attached to the postCommands
+ * node and executed by Job_End when all things are done.
+ * This function is called from JobStart via Lst_ForEach.
+ *
+ * Input:
+ * cmdp command string to print
+ * jobp job for which to print it
+ *
+ * Results:
+ * Always 0, unless the command was "..."
+ *
+ * Side Effects:
+ * If the command begins with a '-' and the shell has no error control,
+ * the JOB_IGNERR flag is set in the job descriptor.
+ * If the command is "..." and we're not ignoring such things,
+ * tailCmds is set to the successor node of the cmd.
+ * numCommands is incremented if the command is actually printed.
+ *-----------------------------------------------------------------------
+ */
+static int
+JobPrintCommand(void *cmdp, void *jobp)
+{
+ Boolean noSpecials; /* true if we shouldn't worry about
+ * inserting special commands into
+ * the input stream. */
+ Boolean shutUp = FALSE; /* true if we put a no echo command
+ * into the command file */
+ Boolean errOff = FALSE; /* true if we turned error checking
+ * off before printing the command
+ * and need to turn it back on */
+ const char *cmdTemplate; /* Template to use when printing the
+ * command */
+ char *cmdStart; /* Start of expanded command */
+ char *escCmd = NULL; /* Command with quotes/backticks escaped */
+ char *cmd = (char *)cmdp;
+ Job *job = (Job *)jobp;
+ char *cp, *tmp;
+ int i, j;
+
+ noSpecials = NoExecute(job->node);
+
+ if (strcmp(cmd, "...") == 0) {
+ job->node->type |= OP_SAVE_CMDS;
+ if ((job->flags & JOB_IGNDOTS) == 0) {
+ job->tailCmds = Lst_Succ(Lst_Member(job->node->commands,
+ cmd));
+ return 1;
+ }
+ return 0;
+ }
+
+#define DBPRINTF(fmt, arg) if (DEBUG(JOB)) { \
+ (void)fprintf(debug_file, fmt, arg); \
+ } \
+ (void)fprintf(job->cmdFILE, fmt, arg); \
+ (void)fflush(job->cmdFILE);
+
+ numCommands += 1;
+
+ cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE);
+
+ cmdTemplate = "%s\n";
+
+ /*
+ * Check for leading @' and -'s to control echoing and error checking.
+ */
+ while (*cmd == '@' || *cmd == '-' || (*cmd == '+')) {
+ switch (*cmd) {
+ case '@':
+ shutUp = DEBUG(LOUD) ? FALSE : TRUE;
+ break;
+ case '-':
+ job->flags |= JOB_IGNERR;
+ errOff = TRUE;
+ break;
+ case '+':
+ if (noSpecials) {
+ /*
+ * We're not actually executing anything...
+ * but this one needs to be - use compat mode just for it.
+ */
+ CompatRunCommand(cmdp, job->node);
+ return 0;
+ }
+ break;
+ }
+ cmd++;
+ }
+
+ while (isspace((unsigned char) *cmd))
+ cmd++;
+
+ /*
+ * If the shell doesn't have error control the alternate echo'ing will
+ * be done (to avoid showing additional error checking code)
+ * and this will need the characters '$ ` \ "' escaped
+ */
+
+ if (!commandShell->hasErrCtl) {
+ /* Worst that could happen is every char needs escaping. */
+ escCmd = bmake_malloc((strlen(cmd) * 2) + 1);
+ for (i = 0, j= 0; cmd[i] != '\0'; i++, j++) {
+ if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' ||
+ cmd[i] == '"')
+ escCmd[j++] = '\\';
+ escCmd[j] = cmd[i];
+ }
+ escCmd[j] = 0;
+ }
+
+ if (shutUp) {
+ if (!(job->flags & JOB_SILENT) && !noSpecials &&
+ commandShell->hasEchoCtl) {
+ DBPRINTF("%s\n", commandShell->echoOff);
+ } else {
+ if (commandShell->hasErrCtl)
+ shutUp = FALSE;
+ }
+ }
+
+ if (errOff) {
+ if (!noSpecials) {
+ if (commandShell->hasErrCtl) {
+ /*
+ * we don't want the error-control commands showing
+ * up either, so we turn off echoing while executing
+ * them. We could put another field in the shell
+ * structure to tell JobDoOutput to look for this
+ * string too, but why make it any more complex than
+ * it already is?
+ */
+ if (!(job->flags & JOB_SILENT) && !shutUp &&
+ commandShell->hasEchoCtl) {
+ DBPRINTF("%s\n", commandShell->echoOff);
+ DBPRINTF("%s\n", commandShell->ignErr);
+ DBPRINTF("%s\n", commandShell->echoOn);
+ } else {
+ DBPRINTF("%s\n", commandShell->ignErr);
+ }
+ } else if (commandShell->ignErr &&
+ (*commandShell->ignErr != '\0'))
+ {
+ /*
+ * The shell has no error control, so we need to be
+ * weird to get it to ignore any errors from the command.
+ * If echoing is turned on, we turn it off and use the
+ * errCheck template to echo the command. Leave echoing
+ * off so the user doesn't see the weirdness we go through
+ * to ignore errors. Set cmdTemplate to use the weirdness
+ * instead of the simple "%s\n" template.
+ */
+ if (!(job->flags & JOB_SILENT) && !shutUp) {
+ if (commandShell->hasEchoCtl) {
+ DBPRINTF("%s\n", commandShell->echoOff);
+ }
+ DBPRINTF(commandShell->errCheck, escCmd);
+ shutUp = TRUE;
+ } else {
+ if (!shutUp) {
+ DBPRINTF(commandShell->errCheck, escCmd);
+ }
+ }
+ cmdTemplate = commandShell->ignErr;
+ /*
+ * The error ignoration (hee hee) is already taken care
+ * of by the ignErr template, so pretend error checking
+ * is still on.
+ */
+ errOff = FALSE;
+ } else {
+ errOff = FALSE;
+ }
+ } else {
+ errOff = FALSE;
+ }
+ } else {
+
+ /*
+ * If errors are being checked and the shell doesn't have error control
+ * but does supply an errOut template, then setup commands to run
+ * through it.
+ */
+
+ if (!commandShell->hasErrCtl && commandShell->errOut &&
+ (*commandShell->errOut != '\0')) {
+ if (!(job->flags & JOB_SILENT) && !shutUp) {
+ if (commandShell->hasEchoCtl) {
+ DBPRINTF("%s\n", commandShell->echoOff);
+ }
+ DBPRINTF(commandShell->errCheck, escCmd);
+ shutUp = TRUE;
+ }
+ /* If it's a comment line or blank, treat as an ignored error */
+ if ((escCmd[0] == commandShell->commentChar) ||
+ (escCmd[0] == 0))
+ cmdTemplate = commandShell->ignErr;
+ else
+ cmdTemplate = commandShell->errOut;
+ errOff = FALSE;
+ }
+ }
+
+ if (DEBUG(SHELL) && strcmp(shellName, "sh") == 0 &&
+ (job->flags & JOB_TRACED) == 0) {
+ DBPRINTF("set -%s\n", "x");
+ job->flags |= JOB_TRACED;
+ }
+
+ if ((cp = Check_Cwd_Cmd(cmd)) != NULL) {
+ DBPRINTF("test -d %s && ", cp);
+ DBPRINTF("cd %s\n", cp);
+ }
+
+ DBPRINTF(cmdTemplate, cmd);
+ free(cmdStart);
+ if (escCmd)
+ free(escCmd);
+ if (errOff) {
+ /*
+ * If echoing is already off, there's no point in issuing the
+ * echoOff command. Otherwise we issue it and pretend it was on
+ * for the whole command...
+ */
+ if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){
+ DBPRINTF("%s\n", commandShell->echoOff);
+ shutUp = TRUE;
+ }
+ DBPRINTF("%s\n", commandShell->errCheck);
+ }
+ if (shutUp && commandShell->hasEchoCtl) {
+ DBPRINTF("%s\n", commandShell->echoOn);
+ }
+ if (cp != NULL) {
+ DBPRINTF("test -d %s && ", cp);
+ DBPRINTF("cd %s\n", Var_Value(".OBJDIR", VAR_GLOBAL, &tmp));
+ }
+ return 0;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobSaveCommand --
+ * Save a command to be executed when everything else is done.
+ * Callback function for JobFinish...
+ *
+ * Results:
+ * Always returns 0
+ *
+ * Side Effects:
+ * The command is tacked onto the end of postCommands's commands list.
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+JobSaveCommand(void *cmd, void *gn)
+{
+ cmd = Var_Subst(NULL, (char *)cmd, (GNode *)gn, FALSE);
+ (void)Lst_AtEnd(postCommands->commands, cmd);
+ return(0);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobClose --
+ * Called to close both input and output pipes when a job is finished.
+ *
+ * Results:
+ * Nada
+ *
+ * Side Effects:
+ * The file descriptors associated with the job are closed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+JobClose(Job *job)
+{
+ clearfd(job);
+ (void)close(job->outPipe);
+ job->outPipe = -1;
+
+ JobDoOutput(job, TRUE);
+ (void)close(job->inPipe);
+ job->inPipe = -1;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobFinish --
+ * Do final processing for the given job including updating
+ * parents and starting new jobs as available/necessary. Note
+ * that we pay no attention to the JOB_IGNERR flag here.
+ * This is because when we're called because of a noexecute flag
+ * or something, jstat.w_status is 0 and when called from
+ * Job_CatchChildren, the status is zeroed if it s/b ignored.
+ *
+ * Input:
+ * job job to finish
+ * status sub-why job went away
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * Final commands for the job are placed on postCommands.
+ *
+ * If we got an error and are aborting (aborting == ABORT_ERROR) and
+ * the job list is now empty, we are done for the day.
+ * If we recognized an error (errors !=0), we set the aborting flag
+ * to ABORT_ERROR so no more jobs will be started.
+ *-----------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static void
+JobFinish (Job *job, WAIT_T status)
+{
+ Boolean done, return_job_token;
+
+ if (DEBUG(JOB)) {
+ fprintf(debug_file, "Jobfinish: %d [%s], status %d\n",
+ job->pid, job->node->name, status);
+ }
+
+ if ((WIFEXITED(status) &&
+ (((WEXITSTATUS(status) != 0) && !(job->flags & JOB_IGNERR)))) ||
+ WIFSIGNALED(status))
+ {
+ /*
+ * If it exited non-zero and either we're doing things our
+ * way or we're not ignoring errors, the job is finished.
+ * Similarly, if the shell died because of a signal
+ * the job is also finished. In these
+ * cases, finish out the job's output before printing the exit
+ * status...
+ */
+ JobClose(job);
+ if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
+ (void)fclose(job->cmdFILE);
+ job->cmdFILE = NULL;
+ }
+ done = TRUE;
+ } else if (WIFEXITED(status)) {
+ /*
+ * Deal with ignored errors in -B mode. We need to print a message
+ * telling of the ignored error as well as setting status.w_status
+ * to 0 so the next command gets run. To do this, we set done to be
+ * TRUE if in -B mode and the job exited non-zero.
+ */
+ done = WEXITSTATUS(status) != 0;
+ /*
+ * Old comment said: "Note we don't
+ * want to close down any of the streams until we know we're at the
+ * end."
+ * But we do. Otherwise when are we going to print the rest of the
+ * stuff?
+ */
+ JobClose(job);
+ } else {
+ /*
+ * No need to close things down or anything.
+ */
+ done = FALSE;
+ }
+
+ if (done) {
+ if (WIFEXITED(status)) {
+ if (DEBUG(JOB)) {
+ (void)fprintf(debug_file, "Process %d [%s] exited.\n",
+ job->pid, job->node->name);
+ }
+ if (WEXITSTATUS(status) != 0) {
+ if (job->node != lastNode) {
+ MESSAGE(stdout, job->node);
+ lastNode = job->node;
+ }
+#ifdef USE_META
+ if (useMeta) {
+ meta_job_error(job, job->node, job->flags, WEXITSTATUS(status));
+ }
+#endif
+ (void)printf("*** [%s] Error code %d%s\n",
+ job->node->name,
+ WEXITSTATUS(status),
+ (job->flags & JOB_IGNERR) ? " (ignored)" : "");
+ if (job->flags & JOB_IGNERR) {
+ WAIT_STATUS(status) = 0;
+ } else {
+ PrintOnError(job->node, NULL);
+ }
+ } else if (DEBUG(JOB)) {
+ if (job->node != lastNode) {
+ MESSAGE(stdout, job->node);
+ lastNode = job->node;
+ }
+ (void)printf("*** [%s] Completed successfully\n",
+ job->node->name);
+ }
+ } else {
+ if (job->node != lastNode) {
+ MESSAGE(stdout, job->node);
+ lastNode = job->node;
+ }
+ (void)printf("*** [%s] Signal %d\n",
+ job->node->name, WTERMSIG(status));
+ }
+ (void)fflush(stdout);
+ }
+
+#ifdef USE_META
+ if (useMeta) {
+ meta_job_finish(job);
+ }
+#endif
+
+ return_job_token = FALSE;
+
+ Trace_Log(JOBEND, job);
+ if (!(job->flags & JOB_SPECIAL)) {
+ if ((WAIT_STATUS(status) != 0) ||
+ (aborting == ABORT_ERROR) ||
+ (aborting == ABORT_INTERRUPT))
+ return_job_token = TRUE;
+ }
+
+ if ((aborting != ABORT_ERROR) && (aborting != ABORT_INTERRUPT) &&
+ (WAIT_STATUS(status) == 0)) {
+ /*
+ * As long as we aren't aborting and the job didn't return a non-zero
+ * status that we shouldn't ignore, we call Make_Update to update
+ * the parents. In addition, any saved commands for the node are placed
+ * on the .END target.
+ */
+ if (job->tailCmds != NULL) {
+ Lst_ForEachFrom(job->node->commands, job->tailCmds,
+ JobSaveCommand,
+ job->node);
+ }
+ job->node->made = MADE;
+ if (!(job->flags & JOB_SPECIAL))
+ return_job_token = TRUE;
+ Make_Update(job->node);
+ job->job_state = JOB_ST_FREE;
+ } else if (WAIT_STATUS(status)) {
+ errors += 1;
+ job->job_state = JOB_ST_FREE;
+ }
+
+ /*
+ * Set aborting if any error.
+ */
+ if (errors && !keepgoing && (aborting != ABORT_INTERRUPT)) {
+ /*
+ * If we found any errors in this batch of children and the -k flag
+ * wasn't given, we set the aborting flag so no more jobs get
+ * started.
+ */
+ aborting = ABORT_ERROR;
+ }
+
+ if (return_job_token)
+ Job_TokenReturn();
+
+ if (aborting == ABORT_ERROR && jobTokensRunning == 0) {
+ /*
+ * If we are aborting and the job table is now empty, we finish.
+ */
+ Finish(errors);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_Touch --
+ * Touch the given target. Called by JobStart when the -t flag was
+ * given
+ *
+ * Input:
+ * gn the node of the file to touch
+ * silent TRUE if should not print message
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The data modification of the file is changed. In addition, if the
+ * file did not exist, it is created.
+ *-----------------------------------------------------------------------
+ */
+void
+Job_Touch(GNode *gn, Boolean silent)
+{
+ int streamID; /* ID of stream opened to do the touch */
+ struct utimbuf times; /* Times for utime() call */
+
+ if (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC|OP_OPTIONAL|
+ OP_SPECIAL|OP_PHONY)) {
+ /*
+ * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" targets
+ * and, as such, shouldn't really be created.
+ */
+ return;
+ }
+
+ if (!silent || NoExecute(gn)) {
+ (void)fprintf(stdout, "touch %s\n", gn->name);
+ (void)fflush(stdout);
+ }
+
+ if (NoExecute(gn)) {
+ return;
+ }
+
+ if (gn->type & OP_ARCHV) {
+ Arch_Touch(gn);
+ } else if (gn->type & OP_LIB) {
+ Arch_TouchLib(gn);
+ } else {
+ char *file = gn->path ? gn->path : gn->name;
+
+ times.actime = times.modtime = now;
+ if (utime(file, &times) < 0){
+ streamID = open(file, O_RDWR | O_CREAT, 0666);
+
+ if (streamID >= 0) {
+ char c;
+
+ /*
+ * Read and write a byte to the file to change the
+ * modification time, then close the file.
+ */
+ if (read(streamID, &c, 1) == 1) {
+ (void)lseek(streamID, (off_t)0, SEEK_SET);
+ (void)write(streamID, &c, 1);
+ }
+
+ (void)close(streamID);
+ } else {
+ (void)fprintf(stdout, "*** couldn't touch %s: %s",
+ file, strerror(errno));
+ (void)fflush(stdout);
+ }
+ }
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_CheckCommands --
+ * Make sure the given node has all the commands it needs.
+ *
+ * Input:
+ * gn The target whose commands need verifying
+ * abortProc Function to abort with message
+ *
+ * Results:
+ * TRUE if the commands list is/was ok.
+ *
+ * Side Effects:
+ * The node will have commands from the .DEFAULT rule added to it
+ * if it needs them.
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
+{
+ if (OP_NOP(gn->type) && Lst_IsEmpty(gn->commands) &&
+ ((gn->type & OP_LIB) == 0 || Lst_IsEmpty(gn->children))) {
+ /*
+ * No commands. Look for .DEFAULT rule from which we might infer
+ * commands
+ */
+ if ((DEFAULT != NULL) && !Lst_IsEmpty(DEFAULT->commands) &&
+ (gn->type & OP_SPECIAL) == 0) {
+ char *p1;
+ /*
+ * Make only looks for a .DEFAULT if the node was never the
+ * target of an operator, so that's what we do too. If
+ * a .DEFAULT was given, we substitute its commands for gn's
+ * commands and set the IMPSRC variable to be the target's name
+ * The DEFAULT node acts like a transformation rule, in that
+ * gn also inherits any attributes or sources attached to
+ * .DEFAULT itself.
+ */
+ Make_HandleUse(DEFAULT, gn);
+ Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn, 0);
+ if (p1)
+ free(p1);
+ } else if (Dir_MTime(gn, 0) == 0 && (gn->type & OP_SPECIAL) == 0) {
+ /*
+ * The node wasn't the target of an operator we have no .DEFAULT
+ * rule to go on and the target doesn't already exist. There's
+ * nothing more we can do for this branch. If the -k flag wasn't
+ * given, we stop in our tracks, otherwise we just don't update
+ * this node's parents so they never get examined.
+ */
+ static const char msg[] = ": don't know how to make";
+
+ if (gn->flags & FROM_DEPEND) {
+ fprintf(stdout, "%s: ignoring stale %s for %s\n",
+ progname, makeDependfile, gn->name);
+ return TRUE;
+ }
+
+ if (gn->type & OP_OPTIONAL) {
+ (void)fprintf(stdout, "%s%s %s (ignored)\n", progname,
+ msg, gn->name);
+ (void)fflush(stdout);
+ } else if (keepgoing) {
+ (void)fprintf(stdout, "%s%s %s (continuing)\n", progname,
+ msg, gn->name);
+ (void)fflush(stdout);
+ return FALSE;
+ } else {
+ (*abortProc)("%s%s %s. Stop", progname, msg, gn->name);
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobExec --
+ * Execute the shell for the given job. Called from JobStart
+ *
+ * Input:
+ * job Job to execute
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * A shell is executed, outputs is altered and the Job structure added
+ * to the job table.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+JobExec(Job *job, char **argv)
+{
+ int cpid; /* ID of new child */
+ sigset_t mask;
+
+ job->flags &= ~JOB_TRACED;
+
+ if (DEBUG(JOB)) {
+ int i;
+
+ (void)fprintf(debug_file, "Running %s %sly\n", job->node->name, "local");
+ (void)fprintf(debug_file, "\tCommand: ");
+ for (i = 0; argv[i] != NULL; i++) {
+ (void)fprintf(debug_file, "%s ", argv[i]);
+ }
+ (void)fprintf(debug_file, "\n");
+ }
+
+ /*
+ * Some jobs produce no output and it's disconcerting to have
+ * no feedback of their running (since they produce no output, the
+ * banner with their name in it never appears). This is an attempt to
+ * provide that feedback, even if nothing follows it.
+ */
+ if ((lastNode != job->node) && !(job->flags & JOB_SILENT)) {
+ MESSAGE(stdout, job->node);
+ lastNode = job->node;
+ }
+
+ /* No interruptions until this job is on the `jobs' list */
+ JobSigLock(&mask);
+
+ /* Pre-emptively mark job running, pid still zero though */
+ job->job_state = JOB_ST_RUNNING;
+
+ cpid = vFork();
+ if (cpid == -1)
+ Punt("Cannot vfork: %s", strerror(errno));
+
+ if (cpid == 0) {
+ /* Child */
+ sigset_t tmask;
+
+#ifdef USE_META
+ if (useMeta) {
+ meta_job_child(job);
+ }
+#endif
+ /*
+ * Reset all signal handlers; this is necessary because we also
+ * need to unblock signals before we exec(2).
+ */
+ JobSigReset();
+
+ /* Now unblock signals */
+ sigemptyset(&tmask);
+ JobSigUnlock(&tmask);
+
+ /*
+ * Must duplicate the input stream down to the child's input and
+ * reset it to the beginning (again). Since the stream was marked
+ * close-on-exec, we must clear that bit in the new input.
+ */
+ if (dup2(FILENO(job->cmdFILE), 0) == -1) {
+ execError("dup2", "job->cmdFILE");
+ _exit(1);
+ }
+ (void)fcntl(0, F_SETFD, 0);
+ (void)lseek(0, (off_t)0, SEEK_SET);
+
+ if (job->node->type & OP_MAKE) {
+ /*
+ * Pass job token pipe to submakes.
+ */
+ fcntl(tokenWaitJob.inPipe, F_SETFD, 0);
+ fcntl(tokenWaitJob.outPipe, F_SETFD, 0);
+ }
+
+ /*
+ * Set up the child's output to be routed through the pipe
+ * we've created for it.
+ */
+ if (dup2(job->outPipe, 1) == -1) {
+ execError("dup2", "job->outPipe");
+ _exit(1);
+ }
+ /*
+ * The output channels are marked close on exec. This bit was
+ * duplicated by the dup2(on some systems), so we have to clear
+ * it before routing the shell's error output to the same place as
+ * its standard output.
+ */
+ (void)fcntl(1, F_SETFD, 0);
+ if (dup2(1, 2) == -1) {
+ execError("dup2", "1, 2");
+ _exit(1);
+ }
+
+ /*
+ * We want to switch the child into a different process family so
+ * we can kill it and all its descendants in one fell swoop,
+ * by killing its process family, but not commit suicide.
+ */
+#if defined(HAVE_SETPGID)
+ (void)setpgid(0, getpid());
+#else
+#if defined(HAVE_SETSID)
+ /* XXX: dsl - I'm sure this should be setpgrp()... */
+ (void)setsid();
+#else
+ (void)setpgrp(0, getpid());
+#endif
+#endif
+
+ Var_ExportVars();
+
+ (void)execv(shellPath, argv);
+ execError("exec", shellPath);
+ _exit(1);
+ }
+
+ /* Parent, continuing after the child exec */
+ job->pid = cpid;
+
+ Trace_Log(JOBSTART, job);
+
+ /*
+ * Set the current position in the buffer to the beginning
+ * and mark another stream to watch in the outputs mask
+ */
+ job->curPos = 0;
+
+ watchfd(job);
+
+ if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
+ (void)fclose(job->cmdFILE);
+ job->cmdFILE = NULL;
+ }
+
+ /*
+ * Now the job is actually running, add it to the table.
+ */
+ if (DEBUG(JOB)) {
+ fprintf(debug_file, "JobExec(%s): pid %d added to jobs table\n",
+ job->node->name, job->pid);
+ job_table_dump("job started");
+ }
+ JobSigUnlock(&mask);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobMakeArgv --
+ * Create the argv needed to execute the shell for a given job.
+ *
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+JobMakeArgv(Job *job, char **argv)
+{
+ int argc;
+ static char args[10]; /* For merged arguments */
+
+ argv[0] = UNCONST(shellName);
+ argc = 1;
+
+ if ((commandShell->exit && (*commandShell->exit != '-')) ||
+ (commandShell->echo && (*commandShell->echo != '-')))
+ {
+ /*
+ * At least one of the flags doesn't have a minus before it, so
+ * merge them together. Have to do this because the *(&(@*#*&#$#
+ * Bourne shell thinks its second argument is a file to source.
+ * Grrrr. Note the ten-character limitation on the combined arguments.
+ */
+ (void)snprintf(args, sizeof(args), "-%s%s",
+ ((job->flags & JOB_IGNERR) ? "" :
+ (commandShell->exit ? commandShell->exit : "")),
+ ((job->flags & JOB_SILENT) ? "" :
+ (commandShell->echo ? commandShell->echo : "")));
+
+ if (args[1]) {
+ argv[argc] = args;
+ argc++;
+ }
+ } else {
+ if (!(job->flags & JOB_IGNERR) && commandShell->exit) {
+ argv[argc] = UNCONST(commandShell->exit);
+ argc++;
+ }
+ if (!(job->flags & JOB_SILENT) && commandShell->echo) {
+ argv[argc] = UNCONST(commandShell->echo);
+ argc++;
+ }
+ }
+ argv[argc] = NULL;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobStart --
+ * Start a target-creation process going for the target described
+ * by the graph node gn.
+ *
+ * Input:
+ * gn target to create
+ * flags flags for the job to override normal ones.
+ * e.g. JOB_SPECIAL or JOB_IGNDOTS
+ * previous The previous Job structure for this node, if any.
+ *
+ * Results:
+ * JOB_ERROR if there was an error in the commands, JOB_FINISHED
+ * if there isn't actually anything left to do for the job and
+ * JOB_RUNNING if the job has been started.
+ *
+ * Side Effects:
+ * A new Job node is created and added to the list of running
+ * jobs. PMake is forked and a child shell created.
+ *
+ * NB: I'm fairly sure that this code is never called with JOB_SPECIAL set
+ * JOB_IGNDOTS is never set (dsl)
+ * Also the return value is ignored by everyone.
+ *-----------------------------------------------------------------------
+ */
+static int
+JobStart(GNode *gn, int flags)
+{
+ Job *job; /* new job descriptor */
+ char *argv[10]; /* Argument vector to shell */
+ Boolean cmdsOK; /* true if the nodes commands were all right */
+ Boolean noExec; /* Set true if we decide not to run the job */
+ int tfd; /* File descriptor to the temp file */
+
+ for (job = job_table; job < job_table_end; job++) {
+ if (job->job_state == JOB_ST_FREE)
+ break;
+ }
+ if (job >= job_table_end)
+ Punt("JobStart no job slots vacant");
+
+ memset(job, 0, sizeof *job);
+ job->job_state = JOB_ST_SETUP;
+ if (gn->type & OP_SPECIAL)
+ flags |= JOB_SPECIAL;
+
+ job->node = gn;
+ job->tailCmds = NULL;
+
+ /*
+ * Set the initial value of the flags for this job based on the global
+ * ones and the node's attributes... Any flags supplied by the caller
+ * are also added to the field.
+ */
+ job->flags = 0;
+ if (Targ_Ignore(gn)) {
+ job->flags |= JOB_IGNERR;
+ }
+ if (Targ_Silent(gn)) {
+ job->flags |= JOB_SILENT;
+ }
+ job->flags |= flags;
+
+ /*
+ * Check the commands now so any attributes from .DEFAULT have a chance
+ * to migrate to the node
+ */
+ cmdsOK = Job_CheckCommands(gn, Error);
+
+ job->inPollfd = NULL;
+ /*
+ * If the -n flag wasn't given, we open up OUR (not the child's)
+ * temporary file to stuff commands in it. The thing is rd/wr so we don't
+ * need to reopen it to feed it to the shell. If the -n flag *was* given,
+ * we just set the file to be stdout. Cute, huh?
+ */
+ if (((gn->type & OP_MAKE) && !(noRecursiveExecute)) ||
+ (!noExecute && !touchFlag)) {
+ /*
+ * tfile is the name of a file into which all shell commands are
+ * put. It is removed before the child shell is executed, unless
+ * DEBUG(SCRIPT) is set.
+ */
+ char *tfile;
+ sigset_t mask;
+ /*
+ * We're serious here, but if the commands were bogus, we're
+ * also dead...
+ */
+ if (!cmdsOK) {
+ PrintOnError(gn, NULL); /* provide some clue */
+ DieHorribly();
+ }
+
+ JobSigLock(&mask);
+ tfd = mkTempFile(TMPPAT, &tfile);
+ if (!DEBUG(SCRIPT))
+ (void)eunlink(tfile);
+ JobSigUnlock(&mask);
+
+ job->cmdFILE = fdopen(tfd, "w+");
+ if (job->cmdFILE == NULL) {
+ Punt("Could not fdopen %s", tfile);
+ }
+ (void)fcntl(FILENO(job->cmdFILE), F_SETFD, 1);
+ /*
+ * Send the commands to the command file, flush all its buffers then
+ * rewind and remove the thing.
+ */
+ noExec = FALSE;
+
+#ifdef USE_META
+ if (useMeta) {
+ meta_job_start(job, gn);
+ if (Targ_Silent(gn)) { /* might have changed */
+ job->flags |= JOB_SILENT;
+ }
+ }
+#endif
+ /*
+ * We can do all the commands at once. hooray for sanity
+ */
+ numCommands = 0;
+ Lst_ForEach(gn->commands, JobPrintCommand, job);
+
+ /*
+ * If we didn't print out any commands to the shell script,
+ * there's not much point in executing the shell, is there?
+ */
+ if (numCommands == 0) {
+ noExec = TRUE;
+ }
+
+ free(tfile);
+ } else if (NoExecute(gn)) {
+ /*
+ * Not executing anything -- just print all the commands to stdout
+ * in one fell swoop. This will still set up job->tailCmds correctly.
+ */
+ if (lastNode != gn) {
+ MESSAGE(stdout, gn);
+ lastNode = gn;
+ }
+ job->cmdFILE = stdout;
+ /*
+ * Only print the commands if they're ok, but don't die if they're
+ * not -- just let the user know they're bad and keep going. It
+ * doesn't do any harm in this case and may do some good.
+ */
+ if (cmdsOK) {
+ Lst_ForEach(gn->commands, JobPrintCommand, job);
+ }
+ /*
+ * Don't execute the shell, thank you.
+ */
+ noExec = TRUE;
+ } else {
+ /*
+ * Just touch the target and note that no shell should be executed.
+ * Set cmdFILE to stdout to make life easier. Check the commands, too,
+ * but don't die if they're no good -- it does no harm to keep working
+ * up the graph.
+ */
+ job->cmdFILE = stdout;
+ Job_Touch(gn, job->flags&JOB_SILENT);
+ noExec = TRUE;
+ }
+ /* Just in case it isn't already... */
+ (void)fflush(job->cmdFILE);
+
+ /*
+ * If we're not supposed to execute a shell, don't.
+ */
+ if (noExec) {
+ if (!(job->flags & JOB_SPECIAL))
+ Job_TokenReturn();
+ /*
+ * Unlink and close the command file if we opened one
+ */
+ if (job->cmdFILE != stdout) {
+ if (job->cmdFILE != NULL) {
+ (void)fclose(job->cmdFILE);
+ job->cmdFILE = NULL;
+ }
+ }
+
+ /*
+ * We only want to work our way up the graph if we aren't here because
+ * the commands for the job were no good.
+ */
+ if (cmdsOK && aborting == 0) {
+ if (job->tailCmds != NULL) {
+ Lst_ForEachFrom(job->node->commands, job->tailCmds,
+ JobSaveCommand,
+ job->node);
+ }
+ job->node->made = MADE;
+ Make_Update(job->node);
+ }
+ job->job_state = JOB_ST_FREE;
+ return cmdsOK ? JOB_FINISHED : JOB_ERROR;
+ }
+
+ /*
+ * Set up the control arguments to the shell. This is based on the flags
+ * set earlier for this job.
+ */
+ JobMakeArgv(job, argv);
+
+ /* Create the pipe by which we'll get the shell's output. */
+ JobCreatePipe(job, 3);
+
+ JobExec(job, argv);
+ return(JOB_RUNNING);
+}
+
+static char *
+JobOutput(Job *job, char *cp, char *endp, int msg)
+{
+ char *ecp;
+
+ if (commandShell->noPrint) {
+ ecp = Str_FindSubstring(cp, commandShell->noPrint);
+ while (ecp != NULL) {
+ if (cp != ecp) {
+ *ecp = '\0';
+ if (!beSilent && msg && job->node != lastNode) {
+ MESSAGE(stdout, job->node);
+ lastNode = job->node;
+ }
+ /*
+ * The only way there wouldn't be a newline after
+ * this line is if it were the last in the buffer.
+ * however, since the non-printable comes after it,
+ * there must be a newline, so we don't print one.
+ */
+ (void)fprintf(stdout, "%s", cp);
+ (void)fflush(stdout);
+ }
+ cp = ecp + commandShell->noPLen;
+ if (cp != endp) {
+ /*
+ * Still more to print, look again after skipping
+ * the whitespace following the non-printable
+ * command....
+ */
+ cp++;
+ while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
+ cp++;
+ }
+ ecp = Str_FindSubstring(cp, commandShell->noPrint);
+ } else {
+ return cp;
+ }
+ }
+ }
+ return cp;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobDoOutput --
+ * This function is called at different times depending on
+ * whether the user has specified that output is to be collected
+ * via pipes or temporary files. In the former case, we are called
+ * whenever there is something to read on the pipe. We collect more
+ * output from the given job and store it in the job's outBuf. If
+ * this makes up a line, we print it tagged by the job's identifier,
+ * as necessary.
+ * If output has been collected in a temporary file, we open the
+ * file and read it line by line, transfering it to our own
+ * output channel until the file is empty. At which point we
+ * remove the temporary file.
+ * In both cases, however, we keep our figurative eye out for the
+ * 'noPrint' line for the shell from which the output came. If
+ * we recognize a line, we don't print it. If the command is not
+ * alone on the line (the character after it is not \0 or \n), we
+ * do print whatever follows it.
+ *
+ * Input:
+ * job the job whose output needs printing
+ * finish TRUE if this is the last time we'll be called
+ * for this job
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * curPos may be shifted as may the contents of outBuf.
+ *-----------------------------------------------------------------------
+ */
+STATIC void
+JobDoOutput(Job *job, Boolean finish)
+{
+ Boolean gotNL = FALSE; /* true if got a newline */
+ Boolean fbuf; /* true if our buffer filled up */
+ int nr; /* number of bytes read */
+ int i; /* auxiliary index into outBuf */
+ int max; /* limit for i (end of current data) */
+ int nRead; /* (Temporary) number of bytes read */
+
+ /*
+ * Read as many bytes as will fit in the buffer.
+ */
+end_loop:
+ gotNL = FALSE;
+ fbuf = FALSE;
+
+ nRead = read(job->inPipe, &job->outBuf[job->curPos],
+ JOB_BUFSIZE - job->curPos);
+ if (nRead < 0) {
+ if (errno == EAGAIN)
+ return;
+ if (DEBUG(JOB)) {
+ perror("JobDoOutput(piperead)");
+ }
+ nr = 0;
+ } else {
+ nr = nRead;
+ }
+
+ /*
+ * If we hit the end-of-file (the job is dead), we must flush its
+ * remaining output, so pretend we read a newline if there's any
+ * output remaining in the buffer.
+ * Also clear the 'finish' flag so we stop looping.
+ */
+ if ((nr == 0) && (job->curPos != 0)) {
+ job->outBuf[job->curPos] = '\n';
+ nr = 1;
+ finish = FALSE;
+ } else if (nr == 0) {
+ finish = FALSE;
+ }
+
+ /*
+ * Look for the last newline in the bytes we just got. If there is
+ * one, break out of the loop with 'i' as its index and gotNL set
+ * TRUE.
+ */
+ max = job->curPos + nr;
+ for (i = job->curPos + nr - 1; i >= job->curPos; i--) {
+ if (job->outBuf[i] == '\n') {
+ gotNL = TRUE;
+ break;
+ } else if (job->outBuf[i] == '\0') {
+ /*
+ * Why?
+ */
+ job->outBuf[i] = ' ';
+ }
+ }
+
+ if (!gotNL) {
+ job->curPos += nr;
+ if (job->curPos == JOB_BUFSIZE) {
+ /*
+ * If we've run out of buffer space, we have no choice
+ * but to print the stuff. sigh.
+ */
+ fbuf = TRUE;
+ i = job->curPos;
+ }
+ }
+ if (gotNL || fbuf) {
+ /*
+ * Need to send the output to the screen. Null terminate it
+ * first, overwriting the newline character if there was one.
+ * So long as the line isn't one we should filter (according
+ * to the shell description), we print the line, preceded
+ * by a target banner if this target isn't the same as the
+ * one for which we last printed something.
+ * The rest of the data in the buffer are then shifted down
+ * to the start of the buffer and curPos is set accordingly.
+ */
+ job->outBuf[i] = '\0';
+ if (i >= job->curPos) {
+ char *cp;
+
+ cp = JobOutput(job, job->outBuf, &job->outBuf[i], FALSE);
+
+ /*
+ * There's still more in that thar buffer. This time, though,
+ * we know there's no newline at the end, so we add one of
+ * our own free will.
+ */
+ if (*cp != '\0') {
+ if (!beSilent && job->node != lastNode) {
+ MESSAGE(stdout, job->node);
+ lastNode = job->node;
+ }
+#ifdef USE_META
+ if (useMeta) {
+ meta_job_output(job, cp, gotNL ? "\n" : "");
+ }
+#endif
+ (void)fprintf(stdout, "%s%s", cp, gotNL ? "\n" : "");
+ (void)fflush(stdout);
+ }
+ }
+ if (i < max - 1) {
+ /* shift the remaining characters down */
+ (void)memcpy(job->outBuf, &job->outBuf[i + 1], max - (i + 1));
+ job->curPos = max - (i + 1);
+
+ } else {
+ /*
+ * We have written everything out, so we just start over
+ * from the start of the buffer. No copying. No nothing.
+ */
+ job->curPos = 0;
+ }
+ }
+ if (finish) {
+ /*
+ * If the finish flag is true, we must loop until we hit
+ * end-of-file on the pipe. This is guaranteed to happen
+ * eventually since the other end of the pipe is now closed
+ * (we closed it explicitly and the child has exited). When
+ * we do get an EOF, finish will be set FALSE and we'll fall
+ * through and out.
+ */
+ goto end_loop;
+ }
+}
+
+static void
+JobRun(GNode *targ)
+{
+#ifdef notyet
+ /*
+ * Unfortunately it is too complicated to run .BEGIN, .END,
+ * and .INTERRUPT job in the parallel job module. This has
+ * the nice side effect that it avoids a lot of other problems.
+ */
+ Lst lst = Lst_Init(FALSE);
+ Lst_AtEnd(lst, targ);
+ (void)Make_Run(lst);
+ Lst_Destroy(lst, NULL);
+ JobStart(targ, JOB_SPECIAL);
+ while (jobTokensRunning) {
+ Job_CatchOutput();
+ }
+#else
+ Compat_Make(targ, targ);
+ if (targ->made == ERROR) {
+ PrintOnError(targ, "\n\nStop.");
+ exit(1);
+ }
+#endif
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_CatchChildren --
+ * Handle the exit of a child. Called from Make_Make.
+ *
+ * Input:
+ * block TRUE if should block on the wait
+ *
+ * Results:
+ * none.
+ *
+ * Side Effects:
+ * The job descriptor is removed from the list of children.
+ *
+ * Notes:
+ * We do waits, blocking or not, according to the wisdom of our
+ * caller, until there are no more children to report. For each
+ * job, call JobFinish to finish things off.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+void
+Job_CatchChildren(void)
+{
+ int pid; /* pid of dead child */
+ WAIT_T status; /* Exit/termination status */
+
+ /*
+ * Don't even bother if we know there's no one around.
+ */
+ if (jobTokensRunning == 0)
+ return;
+
+ while ((pid = waitpid((pid_t) -1, &status, WNOHANG | WUNTRACED)) > 0) {
+ if (DEBUG(JOB)) {
+ (void)fprintf(debug_file, "Process %d exited/stopped status %x.\n", pid,
+ WAIT_STATUS(status));
+ }
+ JobReapChild(pid, status, TRUE);
+ }
+}
+
+/*
+ * It is possible that wait[pid]() was called from elsewhere,
+ * this lets us reap jobs regardless.
+ */
+void
+JobReapChild(pid_t pid, WAIT_T status, Boolean isJobs)
+{
+ Job *job; /* job descriptor for dead child */
+
+ /*
+ * Don't even bother if we know there's no one around.
+ */
+ if (jobTokensRunning == 0)
+ return;
+
+ job = JobFindPid(pid, JOB_ST_RUNNING, isJobs);
+ if (job == NULL) {
+ if (isJobs) {
+ if (!lurking_children)
+ Error("Child (%d) status %x not in table?", pid, status);
+ }
+ return; /* not ours */
+ }
+ if (WIFSTOPPED(status)) {
+ if (DEBUG(JOB)) {
+ (void)fprintf(debug_file, "Process %d (%s) stopped.\n",
+ job->pid, job->node->name);
+ }
+ if (!make_suspended) {
+ switch (WSTOPSIG(status)) {
+ case SIGTSTP:
+ (void)printf("*** [%s] Suspended\n", job->node->name);
+ break;
+ case SIGSTOP:
+ (void)printf("*** [%s] Stopped\n", job->node->name);
+ break;
+ default:
+ (void)printf("*** [%s] Stopped -- signal %d\n",
+ job->node->name, WSTOPSIG(status));
+ }
+ job->job_suspended = 1;
+ }
+ (void)fflush(stdout);
+ return;
+ }
+
+ job->job_state = JOB_ST_FINISHED;
+ job->exit_status = WAIT_STATUS(status);
+
+ JobFinish(job, status);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_CatchOutput --
+ * Catch the output from our children, if we're using
+ * pipes do so. Otherwise just block time until we get a
+ * signal(most likely a SIGCHLD) since there's no point in
+ * just spinning when there's nothing to do and the reaping
+ * of a child can wait for a while.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * Output is read from pipes if we're piping.
+ * -----------------------------------------------------------------------
+ */
+void
+Job_CatchOutput(void)
+{
+ int nready;
+ Job *job;
+ int i;
+
+ (void)fflush(stdout);
+
+ /* The first fd in the list is the job token pipe */
+ nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC);
+
+ if (nready < 0 || readyfd(&childExitJob)) {
+ char token = 0;
+ nready -= 1;
+ (void)read(childExitJob.inPipe, &token, 1);
+ if (token == DO_JOB_RESUME[0])
+ /* Complete relay requested from our SIGCONT handler */
+ JobRestartJobs();
+ Job_CatchChildren();
+ }
+
+ if (nready <= 0)
+ return;
+
+ if (wantToken && readyfd(&tokenWaitJob))
+ nready--;
+
+ for (i = 2; i < nfds; i++) {
+ if (!fds[i].revents)
+ continue;
+ job = jobfds[i];
+ if (job->job_state != JOB_ST_RUNNING)
+ continue;
+ JobDoOutput(job, FALSE);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_Make --
+ * Start the creation of a target. Basically a front-end for
+ * JobStart used by the Make module.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Another job is started.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Job_Make(GNode *gn)
+{
+ (void)JobStart(gn, 0);
+}
+
+void
+Shell_Init(void)
+{
+ if (shellPath == NULL) {
+ /*
+ * We are using the default shell, which may be an absolute
+ * path if DEFSHELL_CUSTOM is defined.
+ */
+ shellName = commandShell->name;
+#ifdef DEFSHELL_CUSTOM
+ if (*shellName == '/') {
+ shellPath = shellName;
+ shellName = strrchr(shellPath, '/');
+ shellName++;
+ } else
+#endif
+ shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
+ }
+ if (commandShell->exit == NULL) {
+ commandShell->exit = "";
+ }
+ if (commandShell->echo == NULL) {
+ commandShell->echo = "";
+ }
+}
+
+/*-
+ * Returns the string literal that is used in the current command shell
+ * to produce a newline character.
+ */
+const char *
+Shell_GetNewline(void)
+{
+
+ return commandShell->newline;
+}
+
+void
+Job_SetPrefix(void)
+{
+
+ if (targPrefix) {
+ free(targPrefix);
+ } else if (!Var_Exists(MAKE_JOB_PREFIX, VAR_GLOBAL)) {
+ Var_Set(MAKE_JOB_PREFIX, "---", VAR_GLOBAL, 0);
+ }
+
+ targPrefix = Var_Subst(NULL, "${" MAKE_JOB_PREFIX "}", VAR_GLOBAL, 0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_Init --
+ * Initialize the process module
+ *
+ * Input:
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * lists and counters are initialized
+ *-----------------------------------------------------------------------
+ */
+void
+Job_Init(void)
+{
+ GNode *begin; /* node for commands to do at the very start */
+
+ /* Allocate space for all the job info */
+ job_table = bmake_malloc(maxJobs * sizeof *job_table);
+ memset(job_table, 0, maxJobs * sizeof *job_table);
+ job_table_end = job_table + maxJobs;
+ wantToken = 0;
+
+ aborting = 0;
+ errors = 0;
+
+ lastNode = NULL;
+
+ /*
+ * There is a non-zero chance that we already have children.
+ * eg after 'make -f- <<EOF'
+ * Since their termination causes a 'Child (pid) not in table' message,
+ * Collect the status of any that are already dead, and suppress the
+ * error message if there are any undead ones.
+ */
+ for (;;) {
+ int rval, status;
+ rval = waitpid((pid_t) -1, &status, WNOHANG);
+ if (rval > 0)
+ continue;
+ if (rval == 0)
+ lurking_children = 1;
+ break;
+ }
+
+ Shell_Init();
+
+ JobCreatePipe(&childExitJob, 3);
+
+ /* We can only need to wait for tokens, children and output from each job */
+ fds = bmake_malloc(sizeof (*fds) * (2 + maxJobs));
+ jobfds = bmake_malloc(sizeof (*jobfds) * (2 + maxJobs));
+
+ /* These are permanent entries and take slots 0 and 1 */
+ watchfd(&tokenWaitJob);
+ watchfd(&childExitJob);
+
+ sigemptyset(&caught_signals);
+ /*
+ * Install a SIGCHLD handler.
+ */
+ (void)bmake_signal(SIGCHLD, JobChildSig);
+ sigaddset(&caught_signals, SIGCHLD);
+
+#define ADDSIG(s,h) \
+ if (bmake_signal(s, SIG_IGN) != SIG_IGN) { \
+ sigaddset(&caught_signals, s); \
+ (void)bmake_signal(s, h); \
+ }
+
+ /*
+ * Catch the four signals that POSIX specifies if they aren't ignored.
+ * JobPassSig will take care of calling JobInterrupt if appropriate.
+ */
+ ADDSIG(SIGINT, JobPassSig_int)
+ ADDSIG(SIGHUP, JobPassSig_term)
+ ADDSIG(SIGTERM, JobPassSig_term)
+ ADDSIG(SIGQUIT, JobPassSig_term)
+
+ /*
+ * There are additional signals that need to be caught and passed if
+ * either the export system wants to be told directly of signals or if
+ * we're giving each job its own process group (since then it won't get
+ * signals from the terminal driver as we own the terminal)
+ */
+ ADDSIG(SIGTSTP, JobPassSig_suspend)
+ ADDSIG(SIGTTOU, JobPassSig_suspend)
+ ADDSIG(SIGTTIN, JobPassSig_suspend)
+ ADDSIG(SIGWINCH, JobCondPassSig)
+ ADDSIG(SIGCONT, JobContinueSig)
+#undef ADDSIG
+
+ begin = Targ_FindNode(".BEGIN", TARG_NOCREATE);
+
+ if (begin != NULL) {
+ JobRun(begin);
+ if (begin->made == ERROR) {
+ PrintOnError(begin, "\n\nStop.");
+ exit(1);
+ }
+ }
+ postCommands = Targ_FindNode(".END", TARG_CREATE);
+}
+
+static void JobSigReset(void)
+{
+#define DELSIG(s) \
+ if (sigismember(&caught_signals, s)) { \
+ (void)bmake_signal(s, SIG_DFL); \
+ }
+
+ DELSIG(SIGINT)
+ DELSIG(SIGHUP)
+ DELSIG(SIGQUIT)
+ DELSIG(SIGTERM)
+ DELSIG(SIGTSTP)
+ DELSIG(SIGTTOU)
+ DELSIG(SIGTTIN)
+ DELSIG(SIGWINCH)
+ DELSIG(SIGCONT)
+#undef DELSIG
+ (void)bmake_signal(SIGCHLD, SIG_DFL);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobMatchShell --
+ * Find a shell in 'shells' given its name.
+ *
+ * Results:
+ * A pointer to the Shell structure.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Shell *
+JobMatchShell(const char *name)
+{
+ Shell *sh;
+
+ for (sh = shells; sh->name != NULL; sh++) {
+ if (strcmp(name, sh->name) == 0)
+ return (sh);
+ }
+ return NULL;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_ParseShell --
+ * Parse a shell specification and set up commandShell, shellPath
+ * and shellName appropriately.
+ *
+ * Input:
+ * line The shell spec
+ *
+ * Results:
+ * FAILURE if the specification was incorrect.
+ *
+ * Side Effects:
+ * commandShell points to a Shell structure (either predefined or
+ * created from the shell spec), shellPath is the full path of the
+ * shell described by commandShell, while shellName is just the
+ * final component of shellPath.
+ *
+ * Notes:
+ * A shell specification consists of a .SHELL target, with dependency
+ * operator, followed by a series of blank-separated words. Double
+ * quotes can be used to use blanks in words. A backslash escapes
+ * anything (most notably a double-quote and a space) and
+ * provides the functionality it does in C. Each word consists of
+ * keyword and value separated by an equal sign. There should be no
+ * unnecessary spaces in the word. The keywords are as follows:
+ * name Name of shell.
+ * path Location of shell.
+ * quiet Command to turn off echoing.
+ * echo Command to turn echoing on
+ * filter Result of turning off echoing that shouldn't be
+ * printed.
+ * echoFlag Flag to turn echoing on at the start
+ * errFlag Flag to turn error checking on at the start
+ * hasErrCtl True if shell has error checking control
+ * newline String literal to represent a newline char
+ * check Command to turn on error checking if hasErrCtl
+ * is TRUE or template of command to echo a command
+ * for which error checking is off if hasErrCtl is
+ * FALSE.
+ * ignore Command to turn off error checking if hasErrCtl
+ * is TRUE or template of command to execute a
+ * command so as to ignore any errors it returns if
+ * hasErrCtl is FALSE.
+ *
+ *-----------------------------------------------------------------------
+ */
+ReturnStatus
+Job_ParseShell(char *line)
+{
+ char **words;
+ char **argv;
+ int argc;
+ char *path;
+ Shell newShell;
+ Boolean fullSpec = FALSE;
+ Shell *sh;
+
+ while (isspace((unsigned char)*line)) {
+ line++;
+ }
+
+ if (shellArgv)
+ free(UNCONST(shellArgv));
+
+ memset(&newShell, 0, sizeof(newShell));
+
+ /*
+ * Parse the specification by keyword
+ */
+ words = brk_string(line, &argc, TRUE, &path);
+ if (words == NULL) {
+ Error("Unterminated quoted string [%s]", line);
+ return FAILURE;
+ }
+ shellArgv = path;
+
+ for (path = NULL, argv = words; argc != 0; argc--, argv++) {
+ if (strncmp(*argv, "path=", 5) == 0) {
+ path = &argv[0][5];
+ } else if (strncmp(*argv, "name=", 5) == 0) {
+ newShell.name = &argv[0][5];
+ } else {
+ if (strncmp(*argv, "quiet=", 6) == 0) {
+ newShell.echoOff = &argv[0][6];
+ } else if (strncmp(*argv, "echo=", 5) == 0) {
+ newShell.echoOn = &argv[0][5];
+ } else if (strncmp(*argv, "filter=", 7) == 0) {
+ newShell.noPrint = &argv[0][7];
+ newShell.noPLen = strlen(newShell.noPrint);
+ } else if (strncmp(*argv, "echoFlag=", 9) == 0) {
+ newShell.echo = &argv[0][9];
+ } else if (strncmp(*argv, "errFlag=", 8) == 0) {
+ newShell.exit = &argv[0][8];
+ } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) {
+ char c = argv[0][10];
+ newShell.hasErrCtl = !((c != 'Y') && (c != 'y') &&
+ (c != 'T') && (c != 't'));
+ } else if (strncmp(*argv, "newline=", 8) == 0) {
+ newShell.newline = &argv[0][8];
+ } else if (strncmp(*argv, "check=", 6) == 0) {
+ newShell.errCheck = &argv[0][6];
+ } else if (strncmp(*argv, "ignore=", 7) == 0) {
+ newShell.ignErr = &argv[0][7];
+ } else if (strncmp(*argv, "errout=", 7) == 0) {
+ newShell.errOut = &argv[0][7];
+ } else if (strncmp(*argv, "comment=", 8) == 0) {
+ newShell.commentChar = argv[0][8];
+ } else {
+ Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"",
+ *argv);
+ free(words);
+ return(FAILURE);
+ }
+ fullSpec = TRUE;
+ }
+ }
+
+ if (path == NULL) {
+ /*
+ * If no path was given, the user wants one of the pre-defined shells,
+ * yes? So we find the one s/he wants with the help of JobMatchShell
+ * and set things up the right way. shellPath will be set up by
+ * Shell_Init.
+ */
+ if (newShell.name == NULL) {
+ Parse_Error(PARSE_FATAL, "Neither path nor name specified");
+ free(words);
+ return(FAILURE);
+ } else {
+ if ((sh = JobMatchShell(newShell.name)) == NULL) {
+ Parse_Error(PARSE_WARNING, "%s: No matching shell",
+ newShell.name);
+ free(words);
+ return(FAILURE);
+ }
+ commandShell = sh;
+ shellName = newShell.name;
+ if (shellPath) {
+ /* Shell_Init has already been called! Do it again. */
+ free(UNCONST(shellPath));
+ shellPath = NULL;
+ Shell_Init();
+ }
+ }
+ } else {
+ /*
+ * The user provided a path. If s/he gave nothing else (fullSpec is
+ * FALSE), try and find a matching shell in the ones we know of.
+ * Else we just take the specification at its word and copy it
+ * to a new location. In either case, we need to record the
+ * path the user gave for the shell.
+ */
+ shellPath = path;
+ path = strrchr(path, '/');
+ if (path == NULL) {
+ path = UNCONST(shellPath);
+ } else {
+ path += 1;
+ }
+ if (newShell.name != NULL) {
+ shellName = newShell.name;
+ } else {
+ shellName = path;
+ }
+ if (!fullSpec) {
+ if ((sh = JobMatchShell(shellName)) == NULL) {
+ Parse_Error(PARSE_WARNING, "%s: No matching shell",
+ shellName);
+ free(words);
+ return(FAILURE);
+ }
+ commandShell = sh;
+ } else {
+ commandShell = bmake_malloc(sizeof(Shell));
+ *commandShell = newShell;
+ }
+ }
+
+ if (commandShell->echoOn && commandShell->echoOff) {
+ commandShell->hasEchoCtl = TRUE;
+ }
+
+ if (!commandShell->hasErrCtl) {
+ if (commandShell->errCheck == NULL) {
+ commandShell->errCheck = "";
+ }
+ if (commandShell->ignErr == NULL) {
+ commandShell->ignErr = "%s\n";
+ }
+ }
+
+ /*
+ * Do not free up the words themselves, since they might be in use by the
+ * shell specification.
+ */
+ free(words);
+ return SUCCESS;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobInterrupt --
+ * Handle the receipt of an interrupt.
+ *
+ * Input:
+ * runINTERRUPT Non-zero if commands for the .INTERRUPT target
+ * should be executed
+ * signo signal received
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * All children are killed. Another job will be started if the
+ * .INTERRUPT target was given.
+ *-----------------------------------------------------------------------
+ */
+static void
+JobInterrupt(int runINTERRUPT, int signo)
+{
+ Job *job; /* job descriptor in that element */
+ GNode *interrupt; /* the node describing the .INTERRUPT target */
+ sigset_t mask;
+ GNode *gn;
+
+ aborting = ABORT_INTERRUPT;
+
+ JobSigLock(&mask);
+
+ for (job = job_table; job < job_table_end; job++) {
+ if (job->job_state != JOB_ST_RUNNING)
+ continue;
+
+ gn = job->node;
+
+ if ((gn->type & (OP_JOIN|OP_PHONY)) == 0 && !Targ_Precious(gn)) {
+ char *file = (gn->path == NULL ? gn->name : gn->path);
+ if (!noExecute && eunlink(file) != -1) {
+ Error("*** %s removed", file);
+ }
+ }
+ if (job->pid) {
+ if (DEBUG(JOB)) {
+ (void)fprintf(debug_file,
+ "JobInterrupt passing signal %d to child %d.\n",
+ signo, job->pid);
+ }
+ KILLPG(job->pid, signo);
+ }
+ }
+
+ JobSigUnlock(&mask);
+
+ if (runINTERRUPT && !touchFlag) {
+ interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
+ if (interrupt != NULL) {
+ ignoreErrors = FALSE;
+ JobRun(interrupt);
+ }
+ }
+ Trace_Log(MAKEINTR, 0);
+ exit(signo);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * Job_Finish --
+ * Do final processing such as the running of the commands
+ * attached to the .END target.
+ *
+ * Results:
+ * Number of errors reported.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+int
+Job_Finish(void)
+{
+ if (postCommands != NULL &&
+ (!Lst_IsEmpty(postCommands->commands) ||
+ !Lst_IsEmpty(postCommands->children))) {
+ if (errors) {
+ Error("Errors reported so .END ignored");
+ } else {
+ JobRun(postCommands);
+ }
+ }
+ return(errors);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_End --
+ * Cleanup any memory used by the jobs module
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Memory is freed
+ *-----------------------------------------------------------------------
+ */
+void
+Job_End(void)
+{
+#ifdef CLEANUP
+ if (shellArgv)
+ free(shellArgv);
+#endif
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_Wait --
+ * Waits for all running jobs to finish and returns. Sets 'aborting'
+ * to ABORT_WAIT to prevent other jobs from starting.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Currently running jobs finish.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Job_Wait(void)
+{
+ aborting = ABORT_WAIT;
+ while (jobTokensRunning != 0) {
+ Job_CatchOutput();
+ }
+ aborting = 0;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_AbortAll --
+ * Abort all currently running jobs without handling output or anything.
+ * This function is to be called only in the event of a major
+ * error. Most definitely NOT to be called from JobInterrupt.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * All children are killed, not just the firstborn
+ *-----------------------------------------------------------------------
+ */
+void
+Job_AbortAll(void)
+{
+ Job *job; /* the job descriptor in that element */
+ WAIT_T foo;
+
+ aborting = ABORT_ERROR;
+
+ if (jobTokensRunning) {
+ for (job = job_table; job < job_table_end; job++) {
+ if (job->job_state != JOB_ST_RUNNING)
+ continue;
+ /*
+ * kill the child process with increasingly drastic signals to make
+ * darn sure it's dead.
+ */
+ KILLPG(job->pid, SIGINT);
+ KILLPG(job->pid, SIGKILL);
+ }
+ }
+
+ /*
+ * Catch as many children as want to report in at first, then give up
+ */
+ while (waitpid((pid_t) -1, &foo, WNOHANG) > 0)
+ continue;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobRestartJobs --
+ * Tries to restart stopped jobs if there are slots available.
+ * Called in process context in response to a SIGCONT.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Resumes jobs.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+JobRestartJobs(void)
+{
+ Job *job;
+
+ for (job = job_table; job < job_table_end; job++) {
+ if (job->job_state == JOB_ST_RUNNING &&
+ (make_suspended || job->job_suspended)) {
+ if (DEBUG(JOB)) {
+ (void)fprintf(debug_file, "Restarting stopped job pid %d.\n",
+ job->pid);
+ }
+ if (job->job_suspended) {
+ (void)printf("*** [%s] Continued\n", job->node->name);
+ (void)fflush(stdout);
+ }
+ job->job_suspended = 0;
+ if (KILLPG(job->pid, SIGCONT) != 0 && DEBUG(JOB)) {
+ fprintf(debug_file, "Failed to send SIGCONT to %d\n", job->pid);
+ }
+ }
+ if (job->job_state == JOB_ST_FINISHED)
+ /* Job exit deferred after calling waitpid() in a signal handler */
+ JobFinish(job, job->exit_status);
+ }
+ make_suspended = 0;
+}
+
+static void
+watchfd(Job *job)
+{
+ if (job->inPollfd != NULL)
+ Punt("Watching watched job");
+
+ fds[nfds].fd = job->inPipe;
+ fds[nfds].events = POLLIN;
+ jobfds[nfds] = job;
+ job->inPollfd = &fds[nfds];
+ nfds++;
+}
+
+static void
+clearfd(Job *job)
+{
+ int i;
+ if (job->inPollfd == NULL)
+ Punt("Unwatching unwatched job");
+ i = job->inPollfd - fds;
+ nfds--;
+ /*
+ * Move last job in table into hole made by dead job.
+ */
+ if (nfds != i) {
+ fds[i] = fds[nfds];
+ jobfds[i] = jobfds[nfds];
+ jobfds[i]->inPollfd = &fds[i];
+ }
+ job->inPollfd = NULL;
+}
+
+static int
+readyfd(Job *job)
+{
+ if (job->inPollfd == NULL)
+ Punt("Polling unwatched job");
+ return (job->inPollfd->revents & POLLIN) != 0;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobTokenAdd --
+ * Put a token into the job pipe so that some make process can start
+ * another job.
+ *
+ * Side Effects:
+ * Allows more build jobs to be spawned somewhere.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+static void
+JobTokenAdd(void)
+{
+ char tok = JOB_TOKENS[aborting], tok1;
+
+ /* If we are depositing an error token flush everything else */
+ while (tok != '+' && read(tokenWaitJob.inPipe, &tok1, 1) == 1)
+ continue;
+
+ if (DEBUG(JOB))
+ fprintf(debug_file, "(%d) aborting %d, deposit token %c\n",
+ getpid(), aborting, JOB_TOKENS[aborting]);
+ write(tokenWaitJob.outPipe, &tok, 1);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_ServerStartTokenAdd --
+ * Prep the job token pipe in the root make process.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+void
+Job_ServerStart(int max_tokens, int jp_0, int jp_1)
+{
+ int i;
+ char jobarg[64];
+
+ if (jp_0 >= 0 && jp_1 >= 0) {
+ /* Pipe passed in from parent */
+ tokenWaitJob.inPipe = jp_0;
+ tokenWaitJob.outPipe = jp_1;
+ return;
+ }
+
+ JobCreatePipe(&tokenWaitJob, 15);
+
+ snprintf(jobarg, sizeof(jobarg), "%d,%d",
+ tokenWaitJob.inPipe, tokenWaitJob.outPipe);
+
+ Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
+ Var_Append(MAKEFLAGS, jobarg, VAR_GLOBAL);
+
+ /*
+ * Preload the job pipe with one token per job, save the one
+ * "extra" token for the primary job.
+ *
+ * XXX should clip maxJobs against PIPE_BUF -- if max_tokens is
+ * larger than the write buffer size of the pipe, we will
+ * deadlock here.
+ */
+ for (i = 1; i < max_tokens; i++)
+ JobTokenAdd();
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_TokenReturn --
+ * Return a withdrawn token to the pool.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+void
+Job_TokenReturn(void)
+{
+ jobTokensRunning--;
+ if (jobTokensRunning < 0)
+ Punt("token botch");
+ if (jobTokensRunning || JOB_TOKENS[aborting] != '+')
+ JobTokenAdd();
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Job_TokenWithdraw --
+ * Attempt to withdraw a token from the pool.
+ *
+ * Results:
+ * Returns TRUE if a token was withdrawn, and FALSE if the pool
+ * is currently empty.
+ *
+ * Side Effects:
+ * If pool is empty, set wantToken so that we wake up
+ * when a token is released.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+
+Boolean
+Job_TokenWithdraw(void)
+{
+ char tok, tok1;
+ int count;
+
+ wantToken = 0;
+ if (DEBUG(JOB))
+ fprintf(debug_file, "Job_TokenWithdraw(%d): aborting %d, running %d\n",
+ getpid(), aborting, jobTokensRunning);
+
+ if (aborting || (jobTokensRunning >= maxJobs))
+ return FALSE;
+
+ count = read(tokenWaitJob.inPipe, &tok, 1);
+ if (count == 0)
+ Fatal("eof on job pipe!");
+ if (count < 0 && jobTokensRunning != 0) {
+ if (errno != EAGAIN) {
+ Fatal("job pipe read: %s", strerror(errno));
+ }
+ if (DEBUG(JOB))
+ fprintf(debug_file, "(%d) blocked for token\n", getpid());
+ wantToken = 1;
+ return FALSE;
+ }
+
+ if (count == 1 && tok != '+') {
+ /* make being abvorted - remove any other job tokens */
+ if (DEBUG(JOB))
+ fprintf(debug_file, "(%d) aborted by token %c\n", getpid(), tok);
+ while (read(tokenWaitJob.inPipe, &tok1, 1) == 1)
+ continue;
+ /* And put the stopper back */
+ write(tokenWaitJob.outPipe, &tok, 1);
+ Fatal("A failure has been detected in another branch of the parallel make");
+ }
+
+ if (count == 1 && jobTokensRunning == 0)
+ /* We didn't want the token really */
+ write(tokenWaitJob.outPipe, &tok, 1);
+
+ jobTokensRunning++;
+ if (DEBUG(JOB))
+ fprintf(debug_file, "(%d) withdrew token\n", getpid());
+ return TRUE;
+}
+
+#ifdef USE_SELECT
+int
+emul_poll(struct pollfd *fd, int nfd, int timeout)
+{
+ fd_set rfds, wfds;
+ int i, maxfd, nselect, npoll;
+ struct timeval tv, *tvp;
+ long usecs;
+
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+
+ maxfd = -1;
+ for (i = 0; i < nfd; i++) {
+ fd[i].revents = 0;
+
+ if (fd[i].events & POLLIN)
+ FD_SET(fd[i].fd, &rfds);
+
+ if (fd[i].events & POLLOUT)
+ FD_SET(fd[i].fd, &wfds);
+
+ if (fd[i].fd > maxfd)
+ maxfd = fd[i].fd;
+ }
+
+ if (maxfd >= FD_SETSIZE) {
+ Punt("Ran out of fd_set slots; "
+ "recompile with a larger FD_SETSIZE.");
+ }
+
+ if (timeout < 0) {
+ tvp = NULL;
+ } else {
+ usecs = timeout * 1000;
+ tv.tv_sec = usecs / 1000000;
+ tv.tv_usec = usecs % 1000000;
+ tvp = &tv;
+ }
+
+ nselect = select(maxfd + 1, &rfds, &wfds, 0, tvp);
+
+ if (nselect <= 0)
+ return nselect;
+
+ npoll = 0;
+ for (i = 0; i < nfd; i++) {
+ if (FD_ISSET(fd[i].fd, &rfds))
+ fd[i].revents |= POLLIN;
+
+ if (FD_ISSET(fd[i].fd, &wfds))
+ fd[i].revents |= POLLOUT;
+
+ if (fd[i].revents)
+ npoll++;
+ }
+
+ return npoll;
+}
+#endif /* USE_SELECT */
diff --git a/external/bsd/bmake/dist/job.h b/external/bsd/bmake/dist/job.h
new file mode 100644
index 0000000..560b70b
--- /dev/null
+++ b/external/bsd/bmake/dist/job.h
@@ -0,0 +1,272 @@
+/* $NetBSD: job.h,v 1.40 2010/09/13 15:36:57 sjg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)job.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)job.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*-
+ * job.h --
+ * Definitions pertaining to the running of jobs in parallel mode.
+ */
+#ifndef _JOB_H_
+#define _JOB_H_
+
+#define TMPPAT "makeXXXXXX" /* relative to tmpdir */
+
+#ifdef USE_SELECT
+/*
+ * Emulate poll() in terms of select(). This is not a complete
+ * emulation but it is sufficient for make's purposes.
+ */
+
+#define poll emul_poll
+#define pollfd emul_pollfd
+
+struct emul_pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+#define POLLIN 0x0001
+#define POLLOUT 0x0004
+
+int
+emul_poll(struct pollfd *fd, int nfd, int timeout);
+#endif
+
+/*
+ * The POLL_MSEC constant determines the maximum number of milliseconds spent
+ * in poll before coming out to see if a child has finished.
+ */
+#define POLL_MSEC 5000
+
+
+/*-
+ * Job Table definitions.
+ *
+ * Each job has several things associated with it:
+ * 1) The process id of the child shell
+ * 2) The graph node describing the target being made by this job
+ * 3) A LstNode for the first command to be saved after the job
+ * completes. This is NULL if there was no "..." in the job's
+ * commands.
+ * 4) An FILE* for writing out the commands. This is only
+ * used before the job is actually started.
+ * 5) The output is being caught via a pipe and
+ * the descriptors of our pipe, an array in which output is line
+ * buffered and the current position in that buffer are all
+ * maintained for each job.
+ * 6) A word of flags which determine how the module handles errors,
+ * echoing, etc. for the job
+ *
+ * When a job is finished, the Make_Update function is called on each of the
+ * parents of the node which was just remade. This takes care of the upward
+ * traversal of the dependency graph.
+ */
+struct pollfd;
+
+
+#ifdef USE_META
+# include "meta.h"
+#endif
+
+#define JOB_BUFSIZE 1024
+typedef struct Job {
+ int pid; /* The child's process ID */
+ GNode *node; /* The target the child is making */
+ LstNode tailCmds; /* The node of the first command to be
+ * saved when the job has been run */
+ FILE *cmdFILE; /* When creating the shell script, this is
+ * where the commands go */
+ int exit_status; /* from wait4() in signal handler */
+ char job_state; /* status of the job entry */
+#define JOB_ST_FREE 0 /* Job is available */
+#define JOB_ST_SETUP 1 /* Job is allocated but otherwise invalid */
+#define JOB_ST_RUNNING 3 /* Job is running, pid valid */
+#define JOB_ST_FINISHED 4 /* Job is done (ie after SIGCHILD) */
+ char job_suspended;
+ short flags; /* Flags to control treatment of job */
+#define JOB_IGNERR 0x001 /* Ignore non-zero exits */
+#define JOB_SILENT 0x002 /* no output */
+#define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally
+ * if we can't export it and maxLocal is 0 */
+#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing
+ * commands */
+#define JOB_TRACED 0x400 /* we've sent 'set -x' */
+
+ int jobPipe[2]; /* Pipe for readind output from job */
+ struct pollfd *inPollfd; /* pollfd associated with inPipe */
+ char outBuf[JOB_BUFSIZE + 1];
+ /* Buffer for storing the output of the
+ * job, line by line */
+ int curPos; /* Current position in op_outBuf */
+
+#ifdef USE_META
+ struct BuildMon bm;
+#endif
+} Job;
+
+#define inPipe jobPipe[0]
+#define outPipe jobPipe[1]
+
+
+/*-
+ * Shell Specifications:
+ * Each shell type has associated with it the following information:
+ * 1) The string which must match the last character of the shell name
+ * for the shell to be considered of this type. The longest match
+ * wins.
+ * 2) A command to issue to turn off echoing of command lines
+ * 3) A command to issue to turn echoing back on again
+ * 4) What the shell prints, and its length, when given the echo-off
+ * command. This line will not be printed when received from the shell
+ * 5) A boolean to tell if the shell has the ability to control
+ * error checking for individual commands.
+ * 6) The string to turn this checking on.
+ * 7) The string to turn it off.
+ * 8) The command-flag to give to cause the shell to start echoing
+ * commands right away.
+ * 9) The command-flag to cause the shell to Lib_Exit when an error is
+ * detected in one of the commands.
+ *
+ * Some special stuff goes on if a shell doesn't have error control. In such
+ * a case, errCheck becomes a printf template for echoing the command,
+ * should echoing be on and ignErr becomes another printf template for
+ * executing the command while ignoring the return status. Finally errOut
+ * is a printf template for running the command and causing the shell to
+ * exit on error. If any of these strings are empty when hasErrCtl is FALSE,
+ * the command will be executed anyway as is and if it causes an error, so be
+ * it. Any templates setup to echo the command will escape any '$ ` \ "'i
+ * characters in the command string to avoid common problems with
+ * echo "%s\n" as a template.
+ */
+typedef struct Shell {
+ const char *name; /* the name of the shell. For Bourne and C
+ * shells, this is used only to find the
+ * shell description when used as the single
+ * source of a .SHELL target. For user-defined
+ * shells, this is the full path of the shell.
+ */
+ Boolean hasEchoCtl; /* True if both echoOff and echoOn defined */
+ const char *echoOff; /* command to turn off echo */
+ const char *echoOn; /* command to turn it back on again */
+ const char *noPrint; /* command to skip when printing output from
+ * shell. This is usually the command which
+ * was executed to turn off echoing */
+ int noPLen; /* length of noPrint command */
+ Boolean hasErrCtl; /* set if can control error checking for
+ * individual commands */
+ const char *errCheck; /* string to turn error checking on */
+ const char *ignErr; /* string to turn off error checking */
+ const char *errOut; /* string to use for testing exit code */
+ const char *newline; /* string literal that results in a newline
+ * character when it appears outside of any
+ * 'quote' or "quote" characters */
+ char commentChar; /* character used by shell for comment lines */
+
+ /*
+ * command-line flags
+ */
+ const char *echo; /* echo commands */
+ const char *exit; /* exit on error */
+} Shell;
+
+extern const char *shellPath;
+extern const char *shellName;
+
+extern int jobTokensRunning; /* tokens currently "out" */
+extern int maxJobs; /* Max jobs we can run */
+
+void Shell_Init(void);
+const char *Shell_GetNewline(void);
+void Job_Touch(GNode *, Boolean);
+Boolean Job_CheckCommands(GNode *, void (*abortProc )(const char *, ...));
+#define CATCH_BLOCK 1
+void Job_CatchChildren(void);
+void Job_CatchOutput(void);
+void Job_Make(GNode *);
+void Job_Init(void);
+Boolean Job_Full(void);
+Boolean Job_Empty(void);
+ReturnStatus Job_ParseShell(char *);
+int Job_Finish(void);
+void Job_End(void);
+void Job_Wait(void);
+void Job_AbortAll(void);
+void JobFlagForMigration(int);
+void Job_TokenReturn(void);
+Boolean Job_TokenWithdraw(void);
+void Job_ServerStart(int, int, int);
+void Job_SetPrefix(void);
+
+#endif /* _JOB_H_ */
diff --git a/external/bsd/bmake/dist/lst.h b/external/bsd/bmake/dist/lst.h
new file mode 100644
index 0000000..e067407
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.h
@@ -0,0 +1,189 @@
+/* $NetBSD: lst.h,v 1.18 2009/01/23 21:58:27 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)lst.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)lst.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*-
+ * lst.h --
+ * Header for using the list library
+ */
+#ifndef _LST_H_
+#define _LST_H_
+
+#include <sys/param.h>
+#include <stdlib.h>
+
+#include "sprite.h"
+
+/*
+ * basic typedef. This is what the Lst_ functions handle
+ */
+
+typedef struct List *Lst;
+typedef struct ListNode *LstNode;
+
+typedef void *DuplicateProc(void *);
+typedef void FreeProc(void *);
+
+#define LST_CONCNEW 0 /* create new LstNode's when using Lst_Concat */
+#define LST_CONCLINK 1 /* relink LstNode's when using Lst_Concat */
+
+/*
+ * Creation/destruction functions
+ */
+/* Create a new list */
+Lst Lst_Init(Boolean);
+/* Duplicate an existing list */
+Lst Lst_Duplicate(Lst, DuplicateProc *);
+/* Destroy an old one */
+void Lst_Destroy(Lst, FreeProc *);
+/* True if list is empty */
+Boolean Lst_IsEmpty(Lst);
+
+/*
+ * Functions to modify a list
+ */
+/* Insert an element before another */
+ReturnStatus Lst_InsertBefore(Lst, LstNode, void *);
+/* Insert an element after another */
+ReturnStatus Lst_InsertAfter(Lst, LstNode, void *);
+/* Place an element at the front of a lst. */
+ReturnStatus Lst_AtFront(Lst, void *);
+/* Place an element at the end of a lst. */
+ReturnStatus Lst_AtEnd(Lst, void *);
+/* Remove an element */
+ReturnStatus Lst_Remove(Lst, LstNode);
+/* Replace a node with a new value */
+ReturnStatus Lst_Replace(LstNode, void *);
+/* Concatenate two lists */
+ReturnStatus Lst_Concat(Lst, Lst, int);
+
+/*
+ * Node-specific functions
+ */
+/* Return first element in list */
+LstNode Lst_First(Lst);
+/* Return last element in list */
+LstNode Lst_Last(Lst);
+/* Return successor to given element */
+LstNode Lst_Succ(LstNode);
+/* Return predecessor to given element */
+LstNode Lst_Prev(LstNode);
+/* Get datum from LstNode */
+void *Lst_Datum(LstNode);
+
+/*
+ * Functions for entire lists
+ */
+/* Find an element in a list */
+LstNode Lst_Find(Lst, const void *, int (*)(const void *, const void *));
+/* Find an element starting from somewhere */
+LstNode Lst_FindFrom(Lst, LstNode, const void *,
+ int (*cProc)(const void *, const void *));
+/*
+ * See if the given datum is on the list. Returns the LstNode containing
+ * the datum
+ */
+LstNode Lst_Member(Lst, void *);
+/* Apply a function to all elements of a lst */
+int Lst_ForEach(Lst, int (*)(void *, void *), void *);
+/*
+ * Apply a function to all elements of a lst starting from a certain point.
+ * If the list is circular, the application will wrap around to the
+ * beginning of the list again.
+ */
+int Lst_ForEachFrom(Lst, LstNode, int (*)(void *, void *),
+ void *);
+/*
+ * these functions are for dealing with a list as a table, of sorts.
+ * An idea of the "current element" is kept and used by all the functions
+ * between Lst_Open() and Lst_Close().
+ */
+/* Open the list */
+ReturnStatus Lst_Open(Lst);
+/* Next element please */
+LstNode Lst_Next(Lst);
+/* Done yet? */
+Boolean Lst_IsAtEnd(Lst);
+/* Finish table access */
+void Lst_Close(Lst);
+
+/*
+ * for using the list as a queue
+ */
+/* Place an element at tail of queue */
+ReturnStatus Lst_EnQueue(Lst, void *);
+/* Remove an element from head of queue */
+void *Lst_DeQueue(Lst);
+
+#endif /* _LST_H_ */
diff --git a/external/bsd/bmake/dist/lst.lib/Makefile b/external/bsd/bmake/dist/lst.lib/Makefile
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/Makefile
diff --git a/external/bsd/bmake/dist/lst.lib/lstAppend.c b/external/bsd/bmake/dist/lst.lib/lstAppend.c
new file mode 100644
index 0000000..4dafe83
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstAppend.c
@@ -0,0 +1,122 @@
+/* $NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstAppend.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstAppend.c --
+ * Add a new node with a new datum after an existing node
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_InsertAfter --
+ * Create a new node and add it to the given list after the given node.
+ *
+ * Input:
+ * l affected list
+ * ln node after which to append the datum
+ * d said datum
+ *
+ * Results:
+ * SUCCESS if all went well.
+ *
+ * Side Effects:
+ * A new ListNode is created and linked in to the List. The lastPtr
+ * field of the List will be altered if ln is the last node in the
+ * list. lastPtr and firstPtr will alter if the list was empty and
+ * ln was NULL.
+ *
+ *-----------------------------------------------------------------------
+ */
+ReturnStatus
+Lst_InsertAfter(Lst l, LstNode ln, void *d)
+{
+ List list;
+ ListNode lNode;
+ ListNode nLNode;
+
+ if (LstValid (l) && (ln == NULL && LstIsEmpty (l))) {
+ goto ok;
+ }
+
+ if (!LstValid (l) || LstIsEmpty (l) || ! LstNodeValid (ln, l)) {
+ return (FAILURE);
+ }
+ ok:
+
+ list = l;
+ lNode = ln;
+
+ PAlloc (nLNode, ListNode);
+ nLNode->datum = d;
+ nLNode->useCount = nLNode->flags = 0;
+
+ if (lNode == NULL) {
+ if (list->isCirc) {
+ nLNode->nextPtr = nLNode->prevPtr = nLNode;
+ } else {
+ nLNode->nextPtr = nLNode->prevPtr = NULL;
+ }
+ list->firstPtr = list->lastPtr = nLNode;
+ } else {
+ nLNode->prevPtr = lNode;
+ nLNode->nextPtr = lNode->nextPtr;
+
+ lNode->nextPtr = nLNode;
+ if (nLNode->nextPtr != NULL) {
+ nLNode->nextPtr->prevPtr = nLNode;
+ }
+
+ if (lNode == list->lastPtr) {
+ list->lastPtr = nLNode;
+ }
+ }
+
+ return (SUCCESS);
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstAtEnd.c b/external/bsd/bmake/dist/lst.lib/lstAtEnd.c
new file mode 100644
index 0000000..10f191a
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstAtEnd.c
@@ -0,0 +1,79 @@
+/* $NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstAtEnd.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstAtEnd.c --
+ * Add a node at the end of the list
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_AtEnd --
+ * Add a node to the end of the given list
+ *
+ * Input:
+ * l List to which to add the datum
+ * d Datum to add
+ *
+ * Results:
+ * SUCCESS if life is good.
+ *
+ * Side Effects:
+ * A new ListNode is created and added to the list.
+ *
+ *-----------------------------------------------------------------------
+ */
+ReturnStatus
+Lst_AtEnd(Lst l, void *d)
+{
+ LstNode end;
+
+ end = Lst_Last(l);
+ return (Lst_InsertAfter(l, end, d));
+}
diff --git a/external/bsd/bmake/dist/lst.lib/lstAtFront.c b/external/bsd/bmake/dist/lst.lib/lstAtFront.c
new file mode 100644
index 0000000..d8be166
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstAtFront.c
@@ -0,0 +1,76 @@
+/* $NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstAtFront.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstAtFront.c --
+ * Add a node at the front of the list
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_AtFront --
+ * Place a piece of data at the front of a list
+ *
+ * Results:
+ * SUCCESS or FAILURE
+ *
+ * Side Effects:
+ * A new ListNode is created and stuck at the front of the list.
+ * hence, firstPtr (and possible lastPtr) in the list are altered.
+ *
+ *-----------------------------------------------------------------------
+ */
+ReturnStatus
+Lst_AtFront(Lst l, void *d)
+{
+ LstNode front;
+
+ front = Lst_First(l);
+ return (Lst_InsertBefore(l, front, d));
+}
diff --git a/external/bsd/bmake/dist/lst.lib/lstClose.c b/external/bsd/bmake/dist/lst.lib/lstClose.c
new file mode 100644
index 0000000..06b68c5
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstClose.c
@@ -0,0 +1,86 @@
+/* $NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstClose.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstClose.c --
+ * Close a list for sequential access.
+ * The sequential functions access the list in a slightly different way.
+ * CurPtr points to their idea of the current node in the list and they
+ * access the list based on it. Because the list is circular, Lst_Next
+ * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
+ * used to determine when to stop.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Close --
+ * Close a list which was opened for sequential access.
+ *
+ * Input:
+ * l The list to close
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The list is closed.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Lst_Close(Lst l)
+{
+ List list = l;
+
+ if (LstValid(l) == TRUE) {
+ list->isOpen = FALSE;
+ list->atEnd = Unknown;
+ }
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstConcat.c b/external/bsd/bmake/dist/lst.lib/lstConcat.c
new file mode 100644
index 0000000..534d34e
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstConcat.c
@@ -0,0 +1,185 @@
+/* $NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstConcat.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * listConcat.c --
+ * Function to concatentate two lists.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Concat --
+ * Concatenate two lists. New elements are created to hold the data
+ * elements, if specified, but the elements themselves are not copied.
+ * If the elements should be duplicated to avoid confusion with another
+ * list, the Lst_Duplicate function should be called first.
+ * If LST_CONCLINK is specified, the second list is destroyed since
+ * its pointers have been corrupted and the list is no longer useable.
+ *
+ * Input:
+ * l1 The list to which l2 is to be appended
+ * l2 The list to append to l1
+ * flags LST_CONCNEW if LstNode's should be duplicated
+ * LST_CONCLINK if should just be relinked
+ *
+ * Results:
+ * SUCCESS if all went well. FAILURE otherwise.
+ *
+ * Side Effects:
+ * New elements are created and appended the first list.
+ *-----------------------------------------------------------------------
+ */
+ReturnStatus
+Lst_Concat(Lst l1, Lst l2, int flags)
+{
+ ListNode ln; /* original LstNode */
+ ListNode nln; /* new LstNode */
+ ListNode last; /* the last element in the list. Keeps
+ * bookkeeping until the end */
+ List list1 = l1;
+ List list2 = l2;
+
+ if (!LstValid (l1) || !LstValid (l2)) {
+ return (FAILURE);
+ }
+
+ if (flags == LST_CONCLINK) {
+ if (list2->firstPtr != NULL) {
+ /*
+ * We set the nextPtr of the
+ * last element of list two to be NIL to make the loop easier and
+ * so we don't need an extra case should the first list turn
+ * out to be non-circular -- the final element will already point
+ * to NIL space and the first element will be untouched if it
+ * existed before and will also point to NIL space if it didn't.
+ */
+ list2->lastPtr->nextPtr = NULL;
+ /*
+ * So long as the second list isn't empty, we just link the
+ * first element of the second list to the last element of the
+ * first list. If the first list isn't empty, we then link the
+ * last element of the list to the first element of the second list
+ * The last element of the second list, if it exists, then becomes
+ * the last element of the first list.
+ */
+ list2->firstPtr->prevPtr = list1->lastPtr;
+ if (list1->lastPtr != NULL) {
+ list1->lastPtr->nextPtr = list2->firstPtr;
+ } else {
+ list1->firstPtr = list2->firstPtr;
+ }
+ list1->lastPtr = list2->lastPtr;
+ }
+ if (list1->isCirc && list1->firstPtr != NULL) {
+ /*
+ * If the first list is supposed to be circular and it is (now)
+ * non-empty, we must make sure it's circular by linking the
+ * first element to the last and vice versa
+ */
+ list1->firstPtr->prevPtr = list1->lastPtr;
+ list1->lastPtr->nextPtr = list1->firstPtr;
+ }
+ free(l2);
+ } else if (list2->firstPtr != NULL) {
+ /*
+ * We set the nextPtr of the last element of list 2 to be nil to make
+ * the loop less difficult. The loop simply goes through the entire
+ * second list creating new LstNodes and filling in the nextPtr, and
+ * prevPtr to fit into l1 and its datum field from the
+ * datum field of the corresponding element in l2. The 'last' node
+ * follows the last of the new nodes along until the entire l2 has
+ * been appended. Only then does the bookkeeping catch up with the
+ * changes. During the first iteration of the loop, if 'last' is nil,
+ * the first list must have been empty so the newly-created node is
+ * made the first node of the list.
+ */
+ list2->lastPtr->nextPtr = NULL;
+ for (last = list1->lastPtr, ln = list2->firstPtr;
+ ln != NULL;
+ ln = ln->nextPtr)
+ {
+ PAlloc (nln, ListNode);
+ nln->datum = ln->datum;
+ if (last != NULL) {
+ last->nextPtr = nln;
+ } else {
+ list1->firstPtr = nln;
+ }
+ nln->prevPtr = last;
+ nln->flags = nln->useCount = 0;
+ last = nln;
+ }
+
+ /*
+ * Finish bookkeeping. The last new element becomes the last element
+ * of list one.
+ */
+ list1->lastPtr = last;
+
+ /*
+ * The circularity of both list one and list two must be corrected
+ * for -- list one because of the new nodes added to it; list two
+ * because of the alteration of list2->lastPtr's nextPtr to ease the
+ * above for loop.
+ */
+ if (list1->isCirc) {
+ list1->lastPtr->nextPtr = list1->firstPtr;
+ list1->firstPtr->prevPtr = list1->lastPtr;
+ } else {
+ last->nextPtr = NULL;
+ }
+
+ if (list2->isCirc) {
+ list2->lastPtr->nextPtr = list2->firstPtr;
+ }
+ }
+
+ return (SUCCESS);
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstDatum.c b/external/bsd/bmake/dist/lst.lib/lstDatum.c
new file mode 100644
index 0000000..6e2d9ad
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstDatum.c
@@ -0,0 +1,77 @@
+/* $NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstDatum.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstDatum.c --
+ * Return the datum associated with a list node.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Datum --
+ * Return the datum stored in the given node.
+ *
+ * Results:
+ * The datum or NULL if the node is invalid.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+void *
+Lst_Datum(LstNode ln)
+{
+ if (ln != NULL) {
+ return ((ln)->datum);
+ } else {
+ return NULL;
+ }
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstDeQueue.c b/external/bsd/bmake/dist/lst.lib/lstDeQueue.c
new file mode 100644
index 0000000..bdb05cc
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstDeQueue.c
@@ -0,0 +1,87 @@
+/* $NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstDeQueue.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstDeQueue.c --
+ * Remove the node and return its datum from the head of the list
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_DeQueue --
+ * Remove and return the datum at the head of the given list.
+ *
+ * Results:
+ * The datum in the node at the head or NULL if the list
+ * is empty.
+ *
+ * Side Effects:
+ * The head node is removed from the list.
+ *
+ *-----------------------------------------------------------------------
+ */
+void *
+Lst_DeQueue(Lst l)
+{
+ void *rd;
+ ListNode tln;
+
+ tln = Lst_First(l);
+ if (tln == NULL) {
+ return NULL;
+ }
+
+ rd = tln->datum;
+ if (Lst_Remove(l, tln) == FAILURE) {
+ return NULL;
+ } else {
+ return (rd);
+ }
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstDestroy.c b/external/bsd/bmake/dist/lst.lib/lstDestroy.c
new file mode 100644
index 0000000..92c5b2b
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstDestroy.c
@@ -0,0 +1,101 @@
+/* $NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstDestroy.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstDestroy.c --
+ * Nuke a list and all its resources
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Destroy --
+ * Destroy a list and free all its resources. If the freeProc is
+ * given, it is called with the datum from each node in turn before
+ * the node is freed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The given list is freed in its entirety.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Lst_Destroy(Lst list, FreeProc *freeProc)
+{
+ ListNode ln;
+ ListNode tln = NULL;
+
+ if (list == NULL)
+ return;
+
+ /* To ease scanning */
+ if (list->lastPtr != NULL)
+ list->lastPtr->nextPtr = NULL;
+ else {
+ free(list);
+ return;
+ }
+
+ if (freeProc) {
+ for (ln = list->firstPtr; ln != NULL; ln = tln) {
+ tln = ln->nextPtr;
+ freeProc(ln->datum);
+ free(ln);
+ }
+ } else {
+ for (ln = list->firstPtr; ln != NULL; ln = tln) {
+ tln = ln->nextPtr;
+ free(ln);
+ }
+ }
+
+ free(list);
+}
diff --git a/external/bsd/bmake/dist/lst.lib/lstDupl.c b/external/bsd/bmake/dist/lst.lib/lstDupl.c
new file mode 100644
index 0000000..2174ff7
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstDupl.c
@@ -0,0 +1,107 @@
+/* $NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstDupl.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * listDupl.c --
+ * Duplicate a list. This includes duplicating the individual
+ * elements.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Duplicate --
+ * Duplicate an entire list. If a function to copy a void *is
+ * given, the individual client elements will be duplicated as well.
+ *
+ * Input:
+ * l the list to duplicate
+ * copyProc A function to duplicate each void *
+ *
+ * Results:
+ * The new Lst structure or NULL if failure.
+ *
+ * Side Effects:
+ * A new list is created.
+ *-----------------------------------------------------------------------
+ */
+Lst
+Lst_Duplicate(Lst l, DuplicateProc *copyProc)
+{
+ Lst nl;
+ ListNode ln;
+ List list = l;
+
+ if (!LstValid (l)) {
+ return NULL;
+ }
+
+ nl = Lst_Init(list->isCirc);
+ if (nl == NULL) {
+ return NULL;
+ }
+
+ ln = list->firstPtr;
+ while (ln != NULL) {
+ if (copyProc != NULL) {
+ if (Lst_AtEnd(nl, copyProc(ln->datum)) == FAILURE) {
+ return NULL;
+ }
+ } else if (Lst_AtEnd(nl, ln->datum) == FAILURE) {
+ return NULL;
+ }
+
+ if (list->isCirc && ln == list->lastPtr) {
+ ln = NULL;
+ } else {
+ ln = ln->nextPtr;
+ }
+ }
+
+ return (nl);
+}
diff --git a/external/bsd/bmake/dist/lst.lib/lstEnQueue.c b/external/bsd/bmake/dist/lst.lib/lstEnQueue.c
new file mode 100644
index 0000000..be386c9
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstEnQueue.c
@@ -0,0 +1,78 @@
+/* $NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstEnQueue.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstEnQueue.c--
+ * Treat the list as a queue and place a datum at its end
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_EnQueue --
+ * Add the datum to the tail of the given list.
+ *
+ * Results:
+ * SUCCESS or FAILURE as returned by Lst_InsertAfter.
+ *
+ * Side Effects:
+ * the lastPtr field is altered all the time and the firstPtr field
+ * will be altered if the list used to be empty.
+ *
+ *-----------------------------------------------------------------------
+ */
+ReturnStatus
+Lst_EnQueue(Lst l, void *d)
+{
+ if (LstValid (l) == FALSE) {
+ return (FAILURE);
+ }
+
+ return (Lst_InsertAfter(l, Lst_Last(l), d));
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstFind.c b/external/bsd/bmake/dist/lst.lib/lstFind.c
new file mode 100644
index 0000000..d07dbe7
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstFind.c
@@ -0,0 +1,74 @@
+/* $NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstFind.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstFind.c --
+ * Find a node on a list.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Find --
+ * Find a node on the given list using the given comparison function
+ * and the given datum.
+ *
+ * Results:
+ * The found node or NULL if none matches.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+LstNode
+Lst_Find(Lst l, const void *d, int (*cProc)(const void *, const void *))
+{
+ return (Lst_FindFrom(l, Lst_First(l), d, cProc));
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstFindFrom.c b/external/bsd/bmake/dist/lst.lib/lstFindFrom.c
new file mode 100644
index 0000000..e2beab6
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstFindFrom.c
@@ -0,0 +1,90 @@
+/* $NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstFindFrom.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstFindFrom.c --
+ * Find a node on a list from a given starting point. Used by Lst_Find.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_FindFrom --
+ * Search for a node starting and ending with the given one on the
+ * given list using the passed datum and comparison function to
+ * determine when it has been found.
+ *
+ * Results:
+ * The found node or NULL
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+LstNode
+Lst_FindFrom(Lst l, LstNode ln, const void *d,
+ int (*cProc)(const void *, const void *))
+{
+ ListNode tln;
+
+ if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) {
+ return NULL;
+ }
+
+ tln = ln;
+
+ do {
+ if ((*cProc)(tln->datum, d) == 0)
+ return (tln);
+ tln = tln->nextPtr;
+ } while (tln != ln && tln != NULL);
+
+ return NULL;
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstFirst.c b/external/bsd/bmake/dist/lst.lib/lstFirst.c
new file mode 100644
index 0000000..4e8334f
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstFirst.c
@@ -0,0 +1,77 @@
+/* $NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstFirst.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstFirst.c --
+ * Return the first node of a list
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_First --
+ * Return the first node on the given list.
+ *
+ * Results:
+ * The first node or NULL if the list is empty.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+LstNode
+Lst_First(Lst l)
+{
+ if (!LstValid (l) || LstIsEmpty (l)) {
+ return NULL;
+ } else {
+ return (l->firstPtr);
+ }
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstForEach.c b/external/bsd/bmake/dist/lst.lib/lstForEach.c
new file mode 100644
index 0000000..917e4ea
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstForEach.c
@@ -0,0 +1,76 @@
+/* $NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstForEach.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstForeach.c --
+ * Perform a given function on all elements of a list.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_ForEach --
+ * Apply the given function to each element of the given list. The
+ * function should return 0 if Lst_ForEach should continue and non-
+ * zero if it should abort.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Only those created by the passed-in function.
+ *
+ *-----------------------------------------------------------------------
+ */
+/*VARARGS2*/
+int
+Lst_ForEach(Lst l, int (*proc)(void *, void *), void *d)
+{
+ return Lst_ForEachFrom(l, Lst_First(l), proc, d);
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstForEachFrom.c b/external/bsd/bmake/dist/lst.lib/lstForEachFrom.c
new file mode 100644
index 0000000..c7f44ad
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstForEachFrom.c
@@ -0,0 +1,125 @@
+/* $NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstForEachFrom.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * lstForEachFrom.c --
+ * Perform a given function on all elements of a list starting from
+ * a given point.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_ForEachFrom --
+ * Apply the given function to each element of the given list. The
+ * function should return 0 if traversal should continue and non-
+ * zero if it should abort.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Only those created by the passed-in function.
+ *
+ *-----------------------------------------------------------------------
+ */
+/*VARARGS2*/
+int
+Lst_ForEachFrom(Lst l, LstNode ln, int (*proc)(void *, void *),
+ void *d)
+{
+ ListNode tln = ln;
+ List list = l;
+ ListNode next;
+ Boolean done;
+ int result;
+
+ if (!LstValid (list) || LstIsEmpty (list)) {
+ return 0;
+ }
+
+ do {
+ /*
+ * Take care of having the current element deleted out from under
+ * us.
+ */
+
+ next = tln->nextPtr;
+
+ /*
+ * We're done with the traversal if
+ * - the next node to examine is the first in the queue or
+ * doesn't exist and
+ * - nothing's been added after the current node (check this
+ * after proc() has been called).
+ */
+ done = (next == NULL || next == list->firstPtr);
+
+ (void) tln->useCount++;
+ result = (*proc) (tln->datum, d);
+ (void) tln->useCount--;
+
+ /*
+ * Now check whether a node has been added.
+ * Note: this doesn't work if this node was deleted before
+ * the new node was added.
+ */
+ if (next != tln->nextPtr) {
+ next = tln->nextPtr;
+ done = 0;
+ }
+
+ if (tln->flags & LN_DELETED) {
+ free((char *)tln);
+ }
+ tln = next;
+ } while (!result && !LstIsEmpty(list) && !done);
+
+ return result;
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstInit.c b/external/bsd/bmake/dist/lst.lib/lstInit.c
new file mode 100644
index 0000000..f98ac42
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstInit.c
@@ -0,0 +1,85 @@
+/* $NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstInit.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * init.c --
+ * Initialize a new linked list.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Init --
+ * Create and initialize a new list.
+ *
+ * Input:
+ * circ TRUE if the list should be made circular
+ *
+ * Results:
+ * The created list.
+ *
+ * Side Effects:
+ * A list is created, what else?
+ *
+ *-----------------------------------------------------------------------
+ */
+Lst
+Lst_Init(Boolean circ)
+{
+ List nList;
+
+ PAlloc (nList, List);
+
+ nList->firstPtr = NULL;
+ nList->lastPtr = NULL;
+ nList->isOpen = FALSE;
+ nList->isCirc = circ;
+ nList->atEnd = Unknown;
+
+ return (nList);
+}
diff --git a/external/bsd/bmake/dist/lst.lib/lstInsert.c b/external/bsd/bmake/dist/lst.lib/lstInsert.c
new file mode 100644
index 0000000..77187bb
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstInsert.c
@@ -0,0 +1,122 @@
+/* $NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstInsert.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstInsert.c --
+ * Insert a new datum before an old one
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_InsertBefore --
+ * Insert a new node with the given piece of data before the given
+ * node in the given list.
+ *
+ * Input:
+ * l list to manipulate
+ * ln node before which to insert d
+ * d datum to be inserted
+ *
+ * Results:
+ * SUCCESS or FAILURE.
+ *
+ * Side Effects:
+ * the firstPtr field will be changed if ln is the first node in the
+ * list.
+ *
+ *-----------------------------------------------------------------------
+ */
+ReturnStatus
+Lst_InsertBefore(Lst l, LstNode ln, void *d)
+{
+ ListNode nLNode; /* new lnode for d */
+ ListNode lNode = ln;
+ List list = l;
+
+
+ /*
+ * check validity of arguments
+ */
+ if (LstValid (l) && (LstIsEmpty (l) && ln == NULL))
+ goto ok;
+
+ if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) {
+ return (FAILURE);
+ }
+
+ ok:
+ PAlloc (nLNode, ListNode);
+
+ nLNode->datum = d;
+ nLNode->useCount = nLNode->flags = 0;
+
+ if (ln == NULL) {
+ if (list->isCirc) {
+ nLNode->prevPtr = nLNode->nextPtr = nLNode;
+ } else {
+ nLNode->prevPtr = nLNode->nextPtr = NULL;
+ }
+ list->firstPtr = list->lastPtr = nLNode;
+ } else {
+ nLNode->prevPtr = lNode->prevPtr;
+ nLNode->nextPtr = lNode;
+
+ if (nLNode->prevPtr != NULL) {
+ nLNode->prevPtr->nextPtr = nLNode;
+ }
+ lNode->prevPtr = nLNode;
+
+ if (lNode == list->firstPtr) {
+ list->firstPtr = nLNode;
+ }
+ }
+
+ return (SUCCESS);
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstInt.h b/external/bsd/bmake/dist/lst.lib/lstInt.h
new file mode 100644
index 0000000..34a2fbd
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstInt.h
@@ -0,0 +1,105 @@
+/* $NetBSD: lstInt.h,v 1.20 2009/01/24 14:43:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)lstInt.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*-
+ * lstInt.h --
+ * Internals for the list library
+ */
+#ifndef _LSTINT_H_
+#define _LSTINT_H_
+
+#include "../lst.h"
+#include "../make_malloc.h"
+
+typedef struct ListNode {
+ struct ListNode *prevPtr; /* previous element in list */
+ struct ListNode *nextPtr; /* next in list */
+ unsigned int useCount:8, /* Count of functions using the node.
+ * node may not be deleted until count
+ * goes to 0 */
+ flags:8; /* Node status flags */
+ void *datum; /* datum associated with this element */
+} *ListNode;
+/*
+ * Flags required for synchronization
+ */
+#define LN_DELETED 0x0001 /* List node should be removed when done */
+
+typedef enum {
+ Head, Middle, Tail, Unknown
+} Where;
+
+typedef struct List {
+ ListNode firstPtr; /* first node in list */
+ ListNode lastPtr; /* last node in list */
+ Boolean isCirc; /* true if the list should be considered
+ * circular */
+/*
+ * fields for sequential access
+ */
+ Where atEnd; /* Where in the list the last access was */
+ Boolean isOpen; /* true if list has been Lst_Open'ed */
+ ListNode curPtr; /* current node, if open. NULL if
+ * *just* opened */
+ ListNode prevPtr; /* Previous node, if open. Used by
+ * Lst_Remove */
+} *List;
+
+/*
+ * PAlloc (var, ptype) --
+ * Allocate a pointer-typedef structure 'ptype' into the variable 'var'
+ */
+#define PAlloc(var,ptype) var = (ptype) bmake_malloc(sizeof *(var))
+
+/*
+ * LstValid (l) --
+ * Return TRUE if the list l is valid
+ */
+#define LstValid(l) ((Lst)(l) != NULL)
+
+/*
+ * LstNodeValid (ln, l) --
+ * Return TRUE if the LstNode ln is valid with respect to l
+ */
+#define LstNodeValid(ln, l) ((ln) != NULL)
+
+/*
+ * LstIsEmpty (l) --
+ * TRUE if the list l is empty.
+ */
+#define LstIsEmpty(l) (((List)(l))->firstPtr == NULL)
+
+#endif /* _LSTINT_H_ */
diff --git a/external/bsd/bmake/dist/lst.lib/lstIsAtEnd.c b/external/bsd/bmake/dist/lst.lib/lstIsAtEnd.c
new file mode 100644
index 0000000..70270d2
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstIsAtEnd.c
@@ -0,0 +1,87 @@
+/* $NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstIsAtEnd.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstIsAtEnd.c --
+ * Tell if the current node is at the end of the list.
+ * The sequential functions access the list in a slightly different way.
+ * CurPtr points to their idea of the current node in the list and they
+ * access the list based on it. Because the list is circular, Lst_Next
+ * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
+ * used to determine when to stop.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_IsAtEnd --
+ * Return true if have reached the end of the given list.
+ *
+ * Results:
+ * TRUE if at the end of the list (this includes the list not being
+ * open or being invalid) or FALSE if not. We return TRUE if the list
+ * is invalid or unopend so as to cause the caller to exit its loop
+ * asap, the assumption being that the loop is of the form
+ * while (!Lst_IsAtEnd (l)) {
+ * ...
+ * }
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Lst_IsAtEnd(Lst l)
+{
+ List list = l;
+
+ return (!LstValid (l) || !list->isOpen ||
+ (list->atEnd == Head) || (list->atEnd == Tail));
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstIsEmpty.c b/external/bsd/bmake/dist/lst.lib/lstIsEmpty.c
new file mode 100644
index 0000000..8b1d6ed
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstIsEmpty.c
@@ -0,0 +1,75 @@
+/* $NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstIsEmpty.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstIsEmpty.c --
+ * A single function to decide if a list is empty
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_IsEmpty --
+ * Return TRUE if the given list is empty.
+ *
+ * Results:
+ * TRUE if the list is empty, FALSE otherwise.
+ *
+ * Side Effects:
+ * None.
+ *
+ * A list is considered empty if its firstPtr == NULL (or if
+ * the list itself is NULL).
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Lst_IsEmpty(Lst l)
+{
+ return ( ! LstValid (l) || LstIsEmpty(l));
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstLast.c b/external/bsd/bmake/dist/lst.lib/lstLast.c
new file mode 100644
index 0000000..096ca24
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstLast.c
@@ -0,0 +1,77 @@
+/* $NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstLast.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstLast.c --
+ * Return the last element of a list
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Last --
+ * Return the last node on the list l.
+ *
+ * Results:
+ * The requested node or NULL if the list is empty.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+LstNode
+Lst_Last(Lst l)
+{
+ if (!LstValid(l) || LstIsEmpty (l)) {
+ return NULL;
+ } else {
+ return (l->lastPtr);
+ }
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstMember.c b/external/bsd/bmake/dist/lst.lib/lstMember.c
new file mode 100644
index 0000000..0ff2ed1
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstMember.c
@@ -0,0 +1,74 @@
+/* $NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstMember.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * lstMember.c --
+ * See if a given datum is on a given list.
+ */
+
+#include "lstInt.h"
+
+LstNode
+Lst_Member(Lst l, void *d)
+{
+ List list = l;
+ ListNode lNode;
+
+ lNode = list->firstPtr;
+ if (lNode == NULL) {
+ return NULL;
+ }
+
+ do {
+ if (lNode->datum == d) {
+ return lNode;
+ }
+ lNode = lNode->nextPtr;
+ } while (lNode != NULL && lNode != list->firstPtr);
+
+ return NULL;
+}
diff --git a/external/bsd/bmake/dist/lst.lib/lstNext.c b/external/bsd/bmake/dist/lst.lib/lstNext.c
new file mode 100644
index 0000000..5c2e0ee
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstNext.c
@@ -0,0 +1,120 @@
+/* $NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstNext.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstNext.c --
+ * Return the next node for a list.
+ * The sequential functions access the list in a slightly different way.
+ * CurPtr points to their idea of the current node in the list and they
+ * access the list based on it. Because the list is circular, Lst_Next
+ * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
+ * used to determine when to stop.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Next --
+ * Return the next node for the given list.
+ *
+ * Results:
+ * The next node or NULL if the list has yet to be opened. Also
+ * if the list is non-circular and the end has been reached, NULL
+ * is returned.
+ *
+ * Side Effects:
+ * the curPtr field is updated.
+ *
+ *-----------------------------------------------------------------------
+ */
+LstNode
+Lst_Next(Lst l)
+{
+ ListNode tln;
+ List list = l;
+
+ if ((LstValid (l) == FALSE) ||
+ (list->isOpen == FALSE)) {
+ return NULL;
+ }
+
+ list->prevPtr = list->curPtr;
+
+ if (list->curPtr == NULL) {
+ if (list->atEnd == Unknown) {
+ /*
+ * If we're just starting out, atEnd will be Unknown.
+ * Then we want to start this thing off in the right
+ * direction -- at the start with atEnd being Middle.
+ */
+ list->curPtr = tln = list->firstPtr;
+ list->atEnd = Middle;
+ } else {
+ tln = NULL;
+ list->atEnd = Tail;
+ }
+ } else {
+ tln = list->curPtr->nextPtr;
+ list->curPtr = tln;
+
+ if (tln == list->firstPtr || tln == NULL) {
+ /*
+ * If back at the front, then we've hit the end...
+ */
+ list->atEnd = Tail;
+ } else {
+ /*
+ * Reset to Middle if gone past first.
+ */
+ list->atEnd = Middle;
+ }
+ }
+
+ return (tln);
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstOpen.c b/external/bsd/bmake/dist/lst.lib/lstOpen.c
new file mode 100644
index 0000000..941293e
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstOpen.c
@@ -0,0 +1,87 @@
+/* $NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstOpen.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstOpen.c --
+ * Open a list for sequential access. The sequential functions access the
+ * list in a slightly different way. CurPtr points to their idea of the
+ * current node in the list and they access the list based on it.
+ * If the list is circular, Lst_Next and Lst_Prev will go around
+ * the list forever. Lst_IsAtEnd must be used to determine when to stop.
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Open --
+ * Open a list for sequential access. A list can still be searched,
+ * etc., without confusing these functions.
+ *
+ * Results:
+ * SUCCESS or FAILURE.
+ *
+ * Side Effects:
+ * isOpen is set TRUE and curPtr is set to NULL so the
+ * other sequential functions no it was just opened and can choose
+ * the first element accessed based on this.
+ *
+ *-----------------------------------------------------------------------
+ */
+ReturnStatus
+Lst_Open(Lst l)
+{
+ if (LstValid (l) == FALSE) {
+ return (FAILURE);
+ }
+ (l)->isOpen = TRUE;
+ (l)->atEnd = LstIsEmpty (l) ? Head : Unknown;
+ (l)->curPtr = NULL;
+
+ return (SUCCESS);
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstPrev.c b/external/bsd/bmake/dist/lst.lib/lstPrev.c
new file mode 100644
index 0000000..0ec865d
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstPrev.c
@@ -0,0 +1,79 @@
+/* $NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstPrev.c --
+ * return the predecessor to a given node
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Prev --
+ * Return the predecessor to the given node on its list.
+ *
+ * Results:
+ * The predecessor of the node, if it exists (note that on a circular
+ * list, if the node is the only one in the list, it is its own
+ * predecessor).
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+LstNode
+Lst_Prev(LstNode ln)
+{
+ if (ln == NULL) {
+ return NULL;
+ } else {
+ return (ln->prevPtr);
+ }
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstRemove.c b/external/bsd/bmake/dist/lst.lib/lstRemove.c
new file mode 100644
index 0000000..54d7b33
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstRemove.c
@@ -0,0 +1,136 @@
+/* $NetBSD: lstRemove.c,v 1.14 2008/12/13 15:19:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstRemove.c,v 1.14 2008/12/13 15:19:29 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstRemove.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstRemove.c,v 1.14 2008/12/13 15:19:29 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstRemove.c --
+ * Remove an element from a list
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Remove --
+ * Remove the given node from the given list.
+ *
+ * Results:
+ * SUCCESS or FAILURE.
+ *
+ * Side Effects:
+ * The list's firstPtr will be set to NULL if ln is the last
+ * node on the list. firsPtr and lastPtr will be altered if ln is
+ * either the first or last node, respectively, on the list.
+ *
+ *-----------------------------------------------------------------------
+ */
+ReturnStatus
+Lst_Remove(Lst l, LstNode ln)
+{
+ List list = l;
+ ListNode lNode = ln;
+
+ if (!LstValid (l) ||
+ !LstNodeValid (ln, l)) {
+ return (FAILURE);
+ }
+
+ /*
+ * unlink it from the list
+ */
+ if (lNode->nextPtr != NULL) {
+ lNode->nextPtr->prevPtr = lNode->prevPtr;
+ }
+ if (lNode->prevPtr != NULL) {
+ lNode->prevPtr->nextPtr = lNode->nextPtr;
+ }
+
+ /*
+ * if either the firstPtr or lastPtr of the list point to this node,
+ * adjust them accordingly
+ */
+ if (list->firstPtr == lNode) {
+ list->firstPtr = lNode->nextPtr;
+ }
+ if (list->lastPtr == lNode) {
+ list->lastPtr = lNode->prevPtr;
+ }
+
+ /*
+ * Sequential access stuff. If the node we're removing is the current
+ * node in the list, reset the current node to the previous one. If the
+ * previous one was non-existent (prevPtr == NULL), we set the
+ * end to be Unknown, since it is.
+ */
+ if (list->isOpen && (list->curPtr == lNode)) {
+ list->curPtr = list->prevPtr;
+ if (list->curPtr == NULL) {
+ list->atEnd = Unknown;
+ }
+ }
+
+ /*
+ * the only way firstPtr can still point to ln is if ln is the last
+ * node on the list (the list is circular, so lNode->nextptr == lNode in
+ * this case). The list is, therefore, empty and is marked as such
+ */
+ if (list->firstPtr == lNode) {
+ list->firstPtr = NULL;
+ }
+
+ /*
+ * note that the datum is unmolested. The caller must free it as
+ * necessary and as expected.
+ */
+ if (lNode->useCount == 0) {
+ free(ln);
+ } else {
+ lNode->flags |= LN_DELETED;
+ }
+
+ return (SUCCESS);
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstReplace.c b/external/bsd/bmake/dist/lst.lib/lstReplace.c
new file mode 100644
index 0000000..090e91a
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstReplace.c
@@ -0,0 +1,78 @@
+/* $NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstReplace.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstReplace.c --
+ * Replace the datum in a node with a new datum
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Replace --
+ * Replace the datum in the given node with the new datum
+ *
+ * Results:
+ * SUCCESS or FAILURE.
+ *
+ * Side Effects:
+ * The datum field fo the node is altered.
+ *
+ *-----------------------------------------------------------------------
+ */
+ReturnStatus
+Lst_Replace(LstNode ln, void *d)
+{
+ if (ln == NULL) {
+ return (FAILURE);
+ } else {
+ (ln)->datum = d;
+ return (SUCCESS);
+ }
+}
+
diff --git a/external/bsd/bmake/dist/lst.lib/lstSucc.c b/external/bsd/bmake/dist/lst.lib/lstSucc.c
new file mode 100644
index 0000000..3f13aa5
--- /dev/null
+++ b/external/bsd/bmake/dist/lst.lib/lstSucc.c
@@ -0,0 +1,79 @@
+/* $NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * LstSucc.c --
+ * return the successor to a given node
+ */
+
+#include "lstInt.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * Lst_Succ --
+ * Return the successor to the given node on its list.
+ *
+ * Results:
+ * The successor of the node, if it exists (note that on a circular
+ * list, if the node is the only one in the list, it is its own
+ * successor).
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+LstNode
+Lst_Succ(LstNode ln)
+{
+ if (ln == NULL) {
+ return NULL;
+ } else {
+ return (ln->nextPtr);
+ }
+}
+
diff --git a/external/bsd/bmake/dist/machine.sh b/external/bsd/bmake/dist/machine.sh
new file mode 100755
index 0000000..32a0f7a
--- /dev/null
+++ b/external/bsd/bmake/dist/machine.sh
@@ -0,0 +1,96 @@
+:
+# derrived from /etc/rc_d/os.sh
+
+# RCSid:
+# $Id: machine.sh,v 1.16 2010/10/17 00:05:51 sjg Exp $
+#
+# @(#) Copyright (c) 1994-2002 Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+#
+
+OS=`uname`
+OSREL=`uname -r`
+OSMAJOR=`IFS=.; set $OSREL; echo $1`
+machine=`uname -p 2>/dev/null || uname -m`
+MACHINE=
+
+# there is at least one case of `uname -p` outputting
+# a bunch of usless drivel
+case "$machine" in
+unknown|*[!A-Za-z0-9_-]*)
+ machine=`uname -m`
+ ;;
+esac
+
+# Great! Solaris keeps moving arch(1)
+# we need this here, and it is not always available...
+Which() {
+ # some shells cannot correctly handle `IFS`
+ # in conjunction with the for loop.
+ _dirs=`IFS=:; echo ${2:-$PATH}`
+ for d in $_dirs
+ do
+ test -x $d/$1 && { echo $d/$1; break; }
+ done
+}
+
+case $OS in
+OpenBSD)
+ MACHINE=$OS$OSMAJOR.$machine
+ arch=`Which arch /usr/bin:/usr/ucb:$PATH`
+ MACHINE_ARCH=`$arch -s`;
+ ;;
+*BSD)
+ MACHINE=$OS$OSMAJOR.$machine
+ ;;
+SunOS)
+ arch=`Which arch /usr/bin:/usr/ucb:$PATH`
+ test "$arch" && machine_arch=`$arch`
+
+ case "$OSREL" in
+ 4.0*) MACHINE_ARCH=$machine_arch MACHINE=$machine_arch;;
+ 4*) MACHINE_ARCH=$machine_arch;;
+ esac
+ ;;
+HP-UX)
+ MACHINE_ARCH=`IFS="/-."; set $machine; echo $1`
+ ;;
+Interix)
+ MACHINE=i386
+ MACHINE_ARCH=i386
+ ;;
+UnixWare)
+ OSREL=`uname -v`
+ OSMAJOR=`IFS=.; set $OSREL; echo $1`
+ MACHINE_ARCH=`uname -m`
+ ;;
+Linux)
+ case "$machine" in
+ i?86) MACHINE_ARCH=i386;;# does anyone really care about 686 vs 586?
+ esac
+ ;;
+esac
+
+MACHINE=${MACHINE:-$OS$OSMAJOR}
+MACHINE_ARCH=${MACHINE_ARCH:-$machine}
+
+(
+case "$0" in
+arch*) echo $MACHINE_ARCH;;
+*)
+ case "$1" in
+ "") echo $MACHINE;;
+ *) echo $MACHINE_ARCH;;
+ esac
+ ;;
+esac
+) | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz
diff --git a/external/bsd/bmake/dist/main.c b/external/bsd/bmake/dist/main.c
new file mode 100644
index 0000000..085c534
--- /dev/null
+++ b/external/bsd/bmake/dist/main.c
@@ -0,0 +1,2078 @@
+/* $NetBSD: main.c,v 1.200 2012/06/12 19:21:51 joerg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: main.c,v 1.200 2012/06/12 19:21:51 joerg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
+ The Regents of the University of California. All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
+#else
+__RCSID("$NetBSD: main.c,v 1.200 2012/06/12 19:21:51 joerg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * main.c --
+ * The main file for this entire program. Exit routines etc
+ * reside here.
+ *
+ * Utility functions defined in this file:
+ * Main_ParseArgLine Takes a line of arguments, breaks them and
+ * treats them as if they were given when first
+ * invoked. Used by the parse module to implement
+ * the .MFLAGS target.
+ *
+ * Error Print a tagged error message. The global
+ * MAKE variable must have been defined. This
+ * takes a format string and two optional
+ * arguments for it.
+ *
+ * Fatal Print an error message and exit. Also takes
+ * a format string and two arguments.
+ *
+ * Punt Aborts all jobs and exits with a message. Also
+ * takes a format string and two arguments.
+ *
+ * Finish Finish things up by printing the number of
+ * errors which occurred, as passed to it, and
+ * exiting.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/resource.h>
+#include <signal.h>
+#include <sys/stat.h>
+#ifdef MAKE_NATIVE
+#include <sys/utsname.h>
+#endif
+#include "wait.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+#include "job.h"
+#include "pathnames.h"
+#include "trace.h"
+
+#ifdef USE_IOVEC
+#include <sys/uio.h>
+#endif
+
+#ifndef DEFMAXLOCAL
+#define DEFMAXLOCAL DEFMAXJOBS
+#endif /* DEFMAXLOCAL */
+
+Lst create; /* Targets to be made */
+time_t now; /* Time at start of make */
+GNode *DEFAULT; /* .DEFAULT node */
+Boolean allPrecious; /* .PRECIOUS given on line by itself */
+
+static Boolean noBuiltins; /* -r flag */
+static Lst makefiles; /* ordered list of makefiles to read */
+static Boolean printVars; /* print value of one or more vars */
+static Lst variables; /* list of variables to print */
+int maxJobs; /* -j argument */
+static int maxJobTokens; /* -j argument */
+Boolean compatMake; /* -B argument */
+int debug; /* -d argument */
+Boolean noExecute; /* -n flag */
+Boolean noRecursiveExecute; /* -N flag */
+Boolean keepgoing; /* -k flag */
+Boolean queryFlag; /* -q flag */
+Boolean touchFlag; /* -t flag */
+Boolean ignoreErrors; /* -i flag */
+Boolean beSilent; /* -s flag */
+Boolean oldVars; /* variable substitution style */
+Boolean checkEnvFirst; /* -e flag */
+Boolean parseWarnFatal; /* -W flag */
+Boolean jobServer; /* -J flag */
+static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */
+Boolean varNoExportEnv; /* -X flag */
+Boolean doing_depend; /* Set while reading .depend */
+static Boolean jobsRunning; /* TRUE if the jobs might be running */
+static const char * tracefile;
+#ifndef NO_CHECK_MAKE_CHDIR
+static char * Check_Cwd_av(int, char **, int);
+#endif
+static void MainParseArgs(int, char **);
+static int ReadMakefile(const void *, const void *);
+static void usage(void) MAKE_ATTR_DEAD;
+
+static Boolean ignorePWD; /* if we use -C, PWD is meaningless */
+static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
+char curdir[MAXPATHLEN + 1]; /* Startup directory */
+char *progname; /* the program name */
+char *makeDependfile;
+pid_t myPid;
+
+Boolean forceJobs = FALSE;
+
+/*
+ * On some systems MACHINE is defined as something other than
+ * what we want.
+ */
+#ifdef FORCE_MACHINE
+# undef MACHINE
+# define MACHINE FORCE_MACHINE
+#endif
+
+extern Lst parseIncPath;
+
+static void
+parse_debug_options(const char *argvalue)
+{
+ const char *modules;
+ const char *mode;
+ char *fname;
+ int len;
+
+ for (modules = argvalue; *modules; ++modules) {
+ switch (*modules) {
+ case 'A':
+ debug = ~0;
+ break;
+ case 'a':
+ debug |= DEBUG_ARCH;
+ break;
+ case 'C':
+ debug |= DEBUG_CWD;
+ break;
+ case 'c':
+ debug |= DEBUG_COND;
+ break;
+ case 'd':
+ debug |= DEBUG_DIR;
+ break;
+ case 'e':
+ debug |= DEBUG_ERROR;
+ break;
+ case 'f':
+ debug |= DEBUG_FOR;
+ break;
+ case 'g':
+ if (modules[1] == '1') {
+ debug |= DEBUG_GRAPH1;
+ ++modules;
+ }
+ else if (modules[1] == '2') {
+ debug |= DEBUG_GRAPH2;
+ ++modules;
+ }
+ else if (modules[1] == '3') {
+ debug |= DEBUG_GRAPH3;
+ ++modules;
+ }
+ break;
+ case 'j':
+ debug |= DEBUG_JOB;
+ break;
+ case 'l':
+ debug |= DEBUG_LOUD;
+ break;
+ case 'M':
+ debug |= DEBUG_META;
+ break;
+ case 'm':
+ debug |= DEBUG_MAKE;
+ break;
+ case 'n':
+ debug |= DEBUG_SCRIPT;
+ break;
+ case 'p':
+ debug |= DEBUG_PARSE;
+ break;
+ case 's':
+ debug |= DEBUG_SUFF;
+ break;
+ case 't':
+ debug |= DEBUG_TARG;
+ break;
+ case 'v':
+ debug |= DEBUG_VAR;
+ break;
+ case 'x':
+ debug |= DEBUG_SHELL;
+ break;
+ case 'F':
+ if (debug_file != stdout && debug_file != stderr)
+ fclose(debug_file);
+ if (*++modules == '+') {
+ modules++;
+ mode = "a";
+ } else
+ mode = "w";
+ if (strcmp(modules, "stdout") == 0) {
+ debug_file = stdout;
+ goto debug_setbuf;
+ }
+ if (strcmp(modules, "stderr") == 0) {
+ debug_file = stderr;
+ goto debug_setbuf;
+ }
+ len = strlen(modules);
+ fname = malloc(len + 20);
+ memcpy(fname, modules, len + 1);
+ /* Let the filename be modified by the pid */
+ if (strcmp(fname + len - 3, ".%d") == 0)
+ snprintf(fname + len - 2, 20, "%d", getpid());
+ debug_file = fopen(fname, mode);
+ if (!debug_file) {
+ fprintf(stderr, "Cannot open debug file %s\n",
+ fname);
+ usage();
+ }
+ free(fname);
+ goto debug_setbuf;
+ default:
+ (void)fprintf(stderr,
+ "%s: illegal argument to d option -- %c\n",
+ progname, *modules);
+ usage();
+ }
+ }
+debug_setbuf:
+ /*
+ * Make the debug_file unbuffered, and make
+ * stdout line buffered (unless debugfile == stdout).
+ */
+ setvbuf(debug_file, NULL, _IONBF, 0);
+ if (debug_file != stdout) {
+ setvbuf(stdout, NULL, _IOLBF, 0);
+ }
+}
+
+/*-
+ * MainParseArgs --
+ * Parse a given argument vector. Called from main() and from
+ * Main_ParseArgLine() when the .MAKEFLAGS target is used.
+ *
+ * XXX: Deal with command line overriding .MAKEFLAGS in makefile
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * Various global and local flags will be set depending on the flags
+ * given
+ */
+static void
+MainParseArgs(int argc, char **argv)
+{
+ char *p;
+ int c = '?';
+ int arginc;
+ char *argvalue;
+ const char *getopt_def;
+ char *optscan;
+ Boolean inOption, dashDash = FALSE;
+ char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
+
+#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrst"
+/* Can't actually use getopt(3) because rescanning is not portable */
+
+ getopt_def = OPTFLAGS;
+rearg:
+ inOption = FALSE;
+ optscan = NULL;
+ while(argc > 1) {
+ char *getopt_spec;
+ if(!inOption)
+ optscan = argv[1];
+ c = *optscan++;
+ arginc = 0;
+ if(inOption) {
+ if(c == '\0') {
+ ++argv;
+ --argc;
+ inOption = FALSE;
+ continue;
+ }
+ } else {
+ if (c != '-' || dashDash)
+ break;
+ inOption = TRUE;
+ c = *optscan++;
+ }
+ /* '-' found at some earlier point */
+ getopt_spec = strchr(getopt_def, c);
+ if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') {
+ /* -<something> found, and <something> should have an arg */
+ inOption = FALSE;
+ arginc = 1;
+ argvalue = optscan;
+ if(*argvalue == '\0') {
+ if (argc < 3)
+ goto noarg;
+ argvalue = argv[2];
+ arginc = 2;
+ }
+ } else {
+ argvalue = NULL;
+ }
+ switch(c) {
+ case '\0':
+ arginc = 1;
+ inOption = FALSE;
+ break;
+ case 'B':
+ compatMake = TRUE;
+ Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
+ Var_Set(MAKE_MODE, "compat", VAR_GLOBAL, 0);
+ break;
+ case 'C':
+ if (chdir(argvalue) == -1) {
+ (void)fprintf(stderr,
+ "%s: chdir %s: %s\n",
+ progname, argvalue,
+ strerror(errno));
+ exit(1);
+ }
+ if (getcwd(curdir, MAXPATHLEN) == NULL) {
+ (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
+ exit(2);
+ }
+ ignorePWD = TRUE;
+ break;
+ case 'D':
+ if (argvalue == NULL || argvalue[0] == 0) goto noarg;
+ Var_Set(argvalue, "1", VAR_GLOBAL, 0);
+ Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
+ Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
+ break;
+ case 'I':
+ if (argvalue == NULL) goto noarg;
+ Parse_AddIncludeDir(argvalue);
+ Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
+ Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
+ break;
+ case 'J':
+ if (argvalue == NULL) goto noarg;
+ if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) {
+ (void)fprintf(stderr,
+ "%s: internal error -- J option malformed (%s)\n",
+ progname, argvalue);
+ usage();
+ }
+ if ((fcntl(jp_0, F_GETFD, 0) < 0) ||
+ (fcntl(jp_1, F_GETFD, 0) < 0)) {
+#if 0
+ (void)fprintf(stderr,
+ "%s: ###### warning -- J descriptors were closed!\n",
+ progname);
+ exit(2);
+#endif
+ jp_0 = -1;
+ jp_1 = -1;
+ compatMake = TRUE;
+ } else {
+ Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
+ Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
+ jobServer = TRUE;
+ }
+ break;
+ case 'N':
+ noExecute = TRUE;
+ noRecursiveExecute = TRUE;
+ Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
+ break;
+ case 'S':
+ keepgoing = FALSE;
+ Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
+ break;
+ case 'T':
+ if (argvalue == NULL) goto noarg;
+ tracefile = bmake_strdup(argvalue);
+ Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
+ Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
+ break;
+ case 'V':
+ if (argvalue == NULL) goto noarg;
+ printVars = TRUE;
+ (void)Lst_AtEnd(variables, argvalue);
+ Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
+ Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
+ break;
+ case 'W':
+ parseWarnFatal = TRUE;
+ break;
+ case 'X':
+ varNoExportEnv = TRUE;
+ Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
+ break;
+ case 'd':
+ if (argvalue == NULL) goto noarg;
+ /* If '-d-opts' don't pass to children */
+ if (argvalue[0] == '-')
+ argvalue++;
+ else {
+ Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
+ Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
+ }
+ parse_debug_options(argvalue);
+ break;
+ case 'e':
+ checkEnvFirst = TRUE;
+ Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
+ break;
+ case 'f':
+ if (argvalue == NULL) goto noarg;
+ (void)Lst_AtEnd(makefiles, argvalue);
+ break;
+ case 'i':
+ ignoreErrors = TRUE;
+ Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
+ break;
+ case 'j':
+ if (argvalue == NULL) goto noarg;
+ forceJobs = TRUE;
+ maxJobs = strtol(argvalue, &p, 0);
+ if (*p != '\0' || maxJobs < 1) {
+ (void)fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n",
+ progname);
+ exit(1);
+ }
+ Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
+ Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
+ Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL, 0);
+ maxJobTokens = maxJobs;
+ break;
+ case 'k':
+ keepgoing = TRUE;
+ Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
+ break;
+ case 'm':
+ if (argvalue == NULL) goto noarg;
+ /* look for magic parent directory search string */
+ if (strncmp(".../", argvalue, 4) == 0) {
+ if (!Dir_FindHereOrAbove(curdir, argvalue+4,
+ found_path, sizeof(found_path)))
+ break; /* nothing doing */
+ (void)Dir_AddDir(sysIncPath, found_path);
+ } else {
+ (void)Dir_AddDir(sysIncPath, argvalue);
+ }
+ Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
+ Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
+ break;
+ case 'n':
+ noExecute = TRUE;
+ Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
+ break;
+ case 'q':
+ queryFlag = TRUE;
+ /* Kind of nonsensical, wot? */
+ Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
+ break;
+ case 'r':
+ noBuiltins = TRUE;
+ Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
+ break;
+ case 's':
+ beSilent = TRUE;
+ Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
+ break;
+ case 't':
+ touchFlag = TRUE;
+ Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
+ break;
+ case '-':
+ dashDash = TRUE;
+ break;
+ default:
+ case '?':
+#ifndef MAKE_NATIVE
+ fprintf(stderr, "getopt(%s) -> %d (%c)\n",
+ OPTFLAGS, c, c);
+#endif
+ usage();
+ }
+ argv += arginc;
+ argc -= arginc;
+ }
+
+ oldVars = TRUE;
+
+ /*
+ * See if the rest of the arguments are variable assignments and
+ * perform them if so. Else take them to be targets and stuff them
+ * on the end of the "create" list.
+ */
+ for (; argc > 1; ++argv, --argc)
+ if (Parse_IsVar(argv[1])) {
+ Parse_DoVar(argv[1], VAR_CMD);
+ } else {
+ if (!*argv[1])
+ Punt("illegal (null) argument.");
+ if (*argv[1] == '-' && !dashDash)
+ goto rearg;
+ (void)Lst_AtEnd(create, bmake_strdup(argv[1]));
+ }
+
+ return;
+noarg:
+ (void)fprintf(stderr, "%s: option requires an argument -- %c\n",
+ progname, c);
+ usage();
+}
+
+/*-
+ * Main_ParseArgLine --
+ * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
+ * is encountered and by main() when reading the .MAKEFLAGS envariable.
+ * Takes a line of arguments and breaks it into its
+ * component words and passes those words and the number of them to the
+ * MainParseArgs function.
+ * The line should have all its leading whitespace removed.
+ *
+ * Input:
+ * line Line to fracture
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * Only those that come from the various arguments.
+ */
+void
+Main_ParseArgLine(const char *line)
+{
+ char **argv; /* Manufactured argument vector */
+ int argc; /* Number of arguments in argv */
+ char *args; /* Space used by the args */
+ char *buf, *p1;
+ char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
+ size_t len;
+
+ if (line == NULL)
+ return;
+ for (; *line == ' '; ++line)
+ continue;
+ if (!*line)
+ return;
+
+#ifndef POSIX
+ {
+ /*
+ * $MAKE may simply be naming the make(1) binary
+ */
+ char *cp;
+
+ if (!(cp = strrchr(line, '/')))
+ cp = line;
+ if ((cp = strstr(cp, "make")) &&
+ strcmp(cp, "make") == 0)
+ return;
+ }
+#endif
+ buf = bmake_malloc(len = strlen(line) + strlen(argv0) + 2);
+ (void)snprintf(buf, len, "%s %s", argv0, line);
+ if (p1)
+ free(p1);
+
+ argv = brk_string(buf, &argc, TRUE, &args);
+ if (argv == NULL) {
+ Error("Unterminated quoted string [%s]", buf);
+ free(buf);
+ return;
+ }
+ free(buf);
+ MainParseArgs(argc, argv);
+
+ free(args);
+ free(argv);
+}
+
+Boolean
+Main_SetObjdir(const char *path)
+{
+ struct stat sb;
+ char *p = NULL;
+ char buf[MAXPATHLEN + 1];
+ Boolean rc = FALSE;
+
+ /* expand variable substitutions */
+ if (strchr(path, '$') != 0) {
+ snprintf(buf, MAXPATHLEN, "%s", path);
+ path = p = Var_Subst(NULL, buf, VAR_GLOBAL, 0);
+ }
+
+ if (path[0] != '/') {
+ snprintf(buf, MAXPATHLEN, "%s/%s", curdir, path);
+ path = buf;
+ }
+
+ /* look for the directory and try to chdir there */
+ if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
+ if (chdir(path)) {
+ (void)fprintf(stderr, "make warning: %s: %s.\n",
+ path, strerror(errno));
+ } else {
+ strncpy(objdir, path, MAXPATHLEN);
+ Var_Set(".OBJDIR", objdir, VAR_GLOBAL, 0);
+ setenv("PWD", objdir, 1);
+ Dir_InitDot();
+ rc = TRUE;
+ }
+ }
+
+ if (p)
+ free(p);
+ return rc;
+}
+
+/*-
+ * ReadAllMakefiles --
+ * wrapper around ReadMakefile() to read all.
+ *
+ * Results:
+ * TRUE if ok, FALSE on error
+ */
+static int
+ReadAllMakefiles(const void *p, const void *q)
+{
+ return (ReadMakefile(p, q) == 0);
+}
+
+int
+str2Lst_Append(Lst lp, char *str, const char *sep)
+{
+ char *cp;
+ int n;
+
+ if (!sep)
+ sep = " \t";
+
+ for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
+ (void)Lst_AtEnd(lp, cp);
+ n++;
+ }
+ return (n);
+}
+
+#ifdef SIGINFO
+/*ARGSUSED*/
+static void
+siginfo(int signo MAKE_ATTR_UNUSED)
+{
+ char dir[MAXPATHLEN];
+ char str[2 * MAXPATHLEN];
+ int len;
+ if (getcwd(dir, sizeof(dir)) == NULL)
+ return;
+ len = snprintf(str, sizeof(str), "%s: Working in: %s\n", progname, dir);
+ if (len > 0)
+ (void)write(STDERR_FILENO, str, (size_t)len);
+}
+#endif
+
+/*
+ * Allow makefiles some control over the mode we run in.
+ */
+void
+MakeMode(const char *mode)
+{
+ char *mp = NULL;
+
+ if (!mode)
+ mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}", VAR_GLOBAL, 0);
+
+ if (mode && *mode) {
+ if (strstr(mode, "compat")) {
+ compatMake = TRUE;
+ forceJobs = FALSE;
+ }
+#if USE_META
+ if (strstr(mode, "meta"))
+ meta_init(mode);
+#endif
+ }
+ if (mp)
+ free(mp);
+}
+
+/*-
+ * main --
+ * The main function, for obvious reasons. Initializes variables
+ * and a few modules, then parses the arguments give it in the
+ * environment and on the command line. Reads the system makefile
+ * followed by either Makefile, makefile or the file given by the
+ * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
+ * flags it has received by then uses either the Make or the Compat
+ * module to create the initial list of targets.
+ *
+ * Results:
+ * If -q was given, exits -1 if anything was out-of-date. Else it exits
+ * 0.
+ *
+ * Side Effects:
+ * The program exits when done. Targets are created. etc. etc. etc.
+ */
+int
+main(int argc, char **argv)
+{
+ Lst targs; /* target nodes to create -- passed to Make_Init */
+ Boolean outOfDate = FALSE; /* FALSE if all targets up to date */
+ struct stat sb, sa;
+ char *p1, *path, *pwd;
+ char mdpath[MAXPATHLEN];
+#ifdef FORCE_MACHINE
+ const char *machine = FORCE_MACHINE;
+#else
+ const char *machine = getenv("MACHINE");
+#endif
+ const char *machine_arch = getenv("MACHINE_ARCH");
+ char *syspath = getenv("MAKESYSPATH");
+ Lst sysMkPath; /* Path of sys.mk */
+ char *cp = NULL, *start;
+ /* avoid faults on read-only strings */
+ static char defsyspath[] = _PATH_DEFSYSPATH;
+ char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
+ struct timeval rightnow; /* to initialize random seed */
+#ifdef MAKE_NATIVE
+ struct utsname utsname;
+#endif
+
+ /* default to writing debug to stderr */
+ debug_file = stderr;
+
+#ifdef SIGINFO
+ (void)bmake_signal(SIGINFO, siginfo);
+#endif
+ /*
+ * Set the seed to produce a different random sequence
+ * on each program execution.
+ */
+ gettimeofday(&rightnow, NULL);
+ srandom(rightnow.tv_sec + rightnow.tv_usec);
+
+ if ((progname = strrchr(argv[0], '/')) != NULL)
+ progname++;
+ else
+ progname = argv[0];
+#ifdef RLIMIT_NOFILE
+ /*
+ * get rid of resource limit on file descriptors
+ */
+ {
+ struct rlimit rl;
+ if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
+ rl.rlim_cur != rl.rlim_max) {
+ rl.rlim_cur = rl.rlim_max;
+ (void)setrlimit(RLIMIT_NOFILE, &rl);
+ }
+ }
+#endif
+
+ /*
+ * Get the name of this type of MACHINE from utsname
+ * so we can share an executable for similar machines.
+ * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
+ *
+ * Note that both MACHINE and MACHINE_ARCH are decided at
+ * run-time.
+ */
+ if (!machine) {
+#ifdef MAKE_NATIVE
+ if (uname(&utsname) == -1) {
+ (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
+ strerror(errno));
+ exit(2);
+ }
+ machine = utsname.machine;
+#else
+#ifdef MAKE_MACHINE
+ machine = MAKE_MACHINE;
+#else
+ machine = "unknown";
+#endif
+#endif
+ }
+
+ if (!machine_arch) {
+#ifndef MACHINE_ARCH
+#ifdef MAKE_MACHINE_ARCH
+ machine_arch = MAKE_MACHINE_ARCH;
+#else
+ machine_arch = "unknown";
+#endif
+#else
+ machine_arch = MACHINE_ARCH;
+#endif
+ }
+
+ myPid = getpid(); /* remember this for vFork() */
+
+ /*
+ * Just in case MAKEOBJDIR wants us to do something tricky.
+ */
+ Var_Init(); /* Initialize the lists of variables for
+ * parsing arguments */
+ Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
+ Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
+#ifdef MAKE_VERSION
+ Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0);
+#endif
+ Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */
+ /*
+ * This is the traditional preference for makefiles.
+ */
+#ifndef MAKEFILE_PREFERENCE_LIST
+# define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
+#endif
+ Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST,
+ VAR_GLOBAL, 0);
+ Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL, 0);
+
+ create = Lst_Init(FALSE);
+ makefiles = Lst_Init(FALSE);
+ printVars = FALSE;
+ variables = Lst_Init(FALSE);
+ beSilent = FALSE; /* Print commands as executed */
+ ignoreErrors = FALSE; /* Pay attention to non-zero returns */
+ noExecute = FALSE; /* Execute all commands */
+ noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
+ keepgoing = FALSE; /* Stop on error */
+ allPrecious = FALSE; /* Remove targets when interrupted */
+ queryFlag = FALSE; /* This is not just a check-run */
+ noBuiltins = FALSE; /* Read the built-in rules */
+ touchFlag = FALSE; /* Actually update targets */
+ debug = 0; /* No debug verbosity, please. */
+ jobsRunning = FALSE;
+
+ maxJobs = DEFMAXLOCAL; /* Set default local max concurrency */
+ maxJobTokens = maxJobs;
+ compatMake = FALSE; /* No compat mode */
+ ignorePWD = FALSE;
+
+ /*
+ * Initialize the parsing, directory and variable modules to prepare
+ * for the reading of inclusion paths and variable settings on the
+ * command line
+ */
+
+ /*
+ * Initialize various variables.
+ * MAKE also gets this name, for compatibility
+ * .MAKEFLAGS gets set to the empty string just in case.
+ * MFLAGS also gets initialized empty, for compatibility.
+ */
+ Parse_Init();
+ if (argv[0][0] == '/' || strchr(argv[0], '/') == NULL) {
+ /*
+ * Leave alone if it is an absolute path, or if it does
+ * not contain a '/' in which case we need to find it in
+ * the path, like execvp(3) and the shells do.
+ */
+ p1 = argv[0];
+ } else {
+ /*
+ * A relative path, canonicalize it.
+ */
+ p1 = realpath(argv[0], mdpath);
+ if (!p1 || *p1 != '/' || stat(p1, &sb) < 0) {
+ p1 = argv[0]; /* realpath failed */
+ }
+ }
+ Var_Set("MAKE", p1, VAR_GLOBAL, 0);
+ Var_Set(".MAKE", p1, VAR_GLOBAL, 0);
+ Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0);
+ Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0);
+ Var_Set("MFLAGS", "", VAR_GLOBAL, 0);
+ Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0);
+
+ /*
+ * Set some other useful macros
+ */
+ {
+ char tmp[64];
+ const char *ep;
+
+ if (!(ep = getenv(MAKE_LEVEL))) {
+#ifdef MAKE_LEVEL_SAFE
+ if (!(ep = getenv(MAKE_LEVEL_SAFE)))
+#endif
+ ep = "0";
+ }
+ Var_Set(MAKE_LEVEL, ep, VAR_GLOBAL, 0);
+ snprintf(tmp, sizeof(tmp), "%u", myPid);
+ Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0);
+ snprintf(tmp, sizeof(tmp), "%u", getppid());
+ Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0);
+ }
+ Job_SetPrefix();
+
+ /*
+ * First snag any flags out of the MAKE environment variable.
+ * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
+ * in a different format).
+ */
+#ifdef POSIX
+ Main_ParseArgLine(getenv("MAKEFLAGS"));
+#else
+ Main_ParseArgLine(getenv("MAKE"));
+#endif
+
+ /*
+ * Find where we are (now).
+ * We take care of PWD for the automounter below...
+ */
+ if (getcwd(curdir, MAXPATHLEN) == NULL) {
+ (void)fprintf(stderr, "%s: getcwd: %s.\n",
+ progname, strerror(errno));
+ exit(2);
+ }
+
+ MainParseArgs(argc, argv);
+
+ /*
+ * Verify that cwd is sane.
+ */
+ if (stat(curdir, &sa) == -1) {
+ (void)fprintf(stderr, "%s: %s: %s.\n",
+ progname, curdir, strerror(errno));
+ exit(2);
+ }
+
+ /*
+ * All this code is so that we know where we are when we start up
+ * on a different machine with pmake.
+ * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX
+ * since the value of curdir can vary depending on how we got
+ * here. Ie sitting at a shell prompt (shell that provides $PWD)
+ * or via subdir.mk in which case its likely a shell which does
+ * not provide it.
+ * So, to stop it breaking this case only, we ignore PWD if
+ * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform.
+ */
+#ifndef NO_PWD_OVERRIDE
+ if (!ignorePWD &&
+ (pwd = getenv("PWD")) != NULL &&
+ getenv("MAKEOBJDIRPREFIX") == NULL) {
+ const char *makeobjdir = getenv("MAKEOBJDIR");
+
+ if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
+ if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
+ sa.st_dev == sb.st_dev)
+ (void)strncpy(curdir, pwd, MAXPATHLEN);
+ }
+ }
+#endif
+ Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0);
+
+ /*
+ * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that,
+ * MAKEOBJDIR is set in the environment, try only that value
+ * and fall back to .CURDIR if it does not exist.
+ *
+ * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and
+ * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none
+ * of these paths exist, just use .CURDIR.
+ */
+ Dir_Init(curdir);
+ (void)Main_SetObjdir(curdir);
+
+ if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) {
+ (void)snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir);
+ (void)Main_SetObjdir(mdpath);
+ } else if ((path = getenv("MAKEOBJDIR")) != NULL) {
+ (void)Main_SetObjdir(path);
+ } else {
+ (void)snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine);
+ if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) {
+ (void)snprintf(mdpath, MAXPATHLEN, "%s%s",
+ _PATH_OBJDIRPREFIX, curdir);
+ (void)Main_SetObjdir(mdpath);
+ }
+ }
+
+ /*
+ * Be compatible if user did not specify -j and did not explicitly
+ * turned compatibility on
+ */
+ if (!compatMake && !forceJobs) {
+ compatMake = TRUE;
+ }
+
+ /*
+ * Initialize archive, target and suffix modules in preparation for
+ * parsing the makefile(s)
+ */
+ Arch_Init();
+ Targ_Init();
+ Suff_Init();
+ Trace_Init(tracefile);
+
+ DEFAULT = NULL;
+ (void)time(&now);
+
+ Trace_Log(MAKESTART, NULL);
+
+ /*
+ * Set up the .TARGETS variable to contain the list of targets to be
+ * created. If none specified, make the variable empty -- the parser
+ * will fill the thing in with the default or .MAIN target.
+ */
+ if (!Lst_IsEmpty(create)) {
+ LstNode ln;
+
+ for (ln = Lst_First(create); ln != NULL;
+ ln = Lst_Succ(ln)) {
+ char *name = (char *)Lst_Datum(ln);
+
+ Var_Append(".TARGETS", name, VAR_GLOBAL);
+ }
+ } else
+ Var_Set(".TARGETS", "", VAR_GLOBAL, 0);
+
+
+ /*
+ * If no user-supplied system path was given (through the -m option)
+ * add the directories from the DEFSYSPATH (more than one may be given
+ * as dir1:...:dirn) to the system include path.
+ */
+ if (syspath == NULL || *syspath == '\0')
+ syspath = defsyspath;
+ else
+ syspath = bmake_strdup(syspath);
+
+ for (start = syspath; *start != '\0'; start = cp) {
+ for (cp = start; *cp != '\0' && *cp != ':'; cp++)
+ continue;
+ if (*cp == ':') {
+ *cp++ = '\0';
+ }
+ /* look for magic parent directory search string */
+ if (strncmp(".../", start, 4) != 0) {
+ (void)Dir_AddDir(defIncPath, start);
+ } else {
+ if (Dir_FindHereOrAbove(curdir, start+4,
+ found_path, sizeof(found_path))) {
+ (void)Dir_AddDir(defIncPath, found_path);
+ }
+ }
+ }
+ if (syspath != defsyspath)
+ free(syspath);
+
+ /*
+ * Read in the built-in rules first, followed by the specified
+ * makefile, if it was (makefile != NULL), or the default
+ * makefile and Makefile, in that order, if it wasn't.
+ */
+ if (!noBuiltins) {
+ LstNode ln;
+
+ sysMkPath = Lst_Init(FALSE);
+ Dir_Expand(_PATH_DEFSYSMK,
+ Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath,
+ sysMkPath);
+ if (Lst_IsEmpty(sysMkPath))
+ Fatal("%s: no system rules (%s).", progname,
+ _PATH_DEFSYSMK);
+ ln = Lst_Find(sysMkPath, NULL, ReadMakefile);
+ if (ln == NULL)
+ Fatal("%s: cannot open %s.", progname,
+ (char *)Lst_Datum(ln));
+ }
+
+ if (!Lst_IsEmpty(makefiles)) {
+ LstNode ln;
+
+ ln = Lst_Find(makefiles, NULL, ReadAllMakefiles);
+ if (ln != NULL)
+ Fatal("%s: cannot open %s.", progname,
+ (char *)Lst_Datum(ln));
+ } else {
+ p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}",
+ VAR_CMD, 0);
+ if (p1) {
+ (void)str2Lst_Append(makefiles, p1, NULL);
+ (void)Lst_Find(makefiles, NULL, ReadMakefile);
+ free(p1);
+ }
+ }
+
+ /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
+ if (!noBuiltins || !printVars) {
+ makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}",
+ VAR_CMD, 0);
+ doing_depend = TRUE;
+ (void)ReadMakefile(makeDependfile, NULL);
+ doing_depend = FALSE;
+ }
+
+ MakeMode(NULL);
+
+ Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
+ if (p1)
+ free(p1);
+
+ if (!compatMake)
+ Job_ServerStart(maxJobTokens, jp_0, jp_1);
+ if (DEBUG(JOB))
+ fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
+ jp_0, jp_1, maxJobs, maxJobTokens, compatMake);
+
+ Main_ExportMAKEFLAGS(TRUE); /* initial export */
+
+#ifndef NO_CHECK_MAKE_CHDIR
+ Check_Cwd_av(0, NULL, 0); /* initialize it */
+#endif
+
+ /*
+ * For compatibility, look at the directories in the VPATH variable
+ * and add them to the search path, if the variable is defined. The
+ * variable's value is in the same format as the PATH envariable, i.e.
+ * <directory>:<directory>:<directory>...
+ */
+ if (Var_Exists("VPATH", VAR_CMD)) {
+ char *vpath, savec;
+ /*
+ * GCC stores string constants in read-only memory, but
+ * Var_Subst will want to write this thing, so store it
+ * in an array
+ */
+ static char VPATH[] = "${VPATH}";
+
+ vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
+ path = vpath;
+ do {
+ /* skip to end of directory */
+ for (cp = path; *cp != ':' && *cp != '\0'; cp++)
+ continue;
+ /* Save terminator character so know when to stop */
+ savec = *cp;
+ *cp = '\0';
+ /* Add directory to search path */
+ (void)Dir_AddDir(dirSearchPath, path);
+ *cp = savec;
+ path = cp + 1;
+ } while (savec == ':');
+ free(vpath);
+ }
+
+ /*
+ * Now that all search paths have been read for suffixes et al, it's
+ * time to add the default search path to their lists...
+ */
+ Suff_DoPaths();
+
+ /*
+ * Propagate attributes through :: dependency lists.
+ */
+ Targ_Propagate();
+
+ /* print the initial graph, if the user requested it */
+ if (DEBUG(GRAPH1))
+ Targ_PrintGraph(1);
+
+ /* print the values of any variables requested by the user */
+ if (printVars) {
+ LstNode ln;
+
+ for (ln = Lst_First(variables); ln != NULL;
+ ln = Lst_Succ(ln)) {
+ char *var = (char *)Lst_Datum(ln);
+ char *value;
+
+ if (strchr(var, '$')) {
+ value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0);
+ } else {
+ value = Var_Value(var, VAR_GLOBAL, &p1);
+ }
+ printf("%s\n", value ? value : "");
+ if (p1)
+ free(p1);
+ }
+ } else {
+ /*
+ * Have now read the entire graph and need to make a list of
+ * targets to create. If none was given on the command line,
+ * we consult the parsing module to find the main target(s)
+ * to create.
+ */
+ if (Lst_IsEmpty(create))
+ targs = Parse_MainName();
+ else
+ targs = Targ_FindList(create, TARG_CREATE);
+
+ if (!compatMake) {
+ /*
+ * Initialize job module before traversing the graph
+ * now that any .BEGIN and .END targets have been read.
+ * This is done only if the -q flag wasn't given
+ * (to prevent the .BEGIN from being executed should
+ * it exist).
+ */
+ if (!queryFlag) {
+ Job_Init();
+ jobsRunning = TRUE;
+ }
+
+ /* Traverse the graph, checking on all the targets */
+ outOfDate = Make_Run(targs);
+ } else {
+ /*
+ * Compat_Init will take care of creating all the
+ * targets as well as initializing the module.
+ */
+ Compat_Run(targs);
+ }
+ }
+
+#ifdef CLEANUP
+ Lst_Destroy(targs, NULL);
+ Lst_Destroy(variables, NULL);
+ Lst_Destroy(makefiles, NULL);
+ Lst_Destroy(create, (FreeProc *)free);
+#endif
+
+ /* print the graph now it's been processed if the user requested it */
+ if (DEBUG(GRAPH2))
+ Targ_PrintGraph(2);
+
+ Trace_Log(MAKEEND, 0);
+
+ Suff_End();
+ Targ_End();
+ Arch_End();
+ Var_End();
+ Parse_End();
+ Dir_End();
+ Job_End();
+ Trace_End();
+
+ return outOfDate ? 1 : 0;
+}
+
+/*-
+ * ReadMakefile --
+ * Open and parse the given makefile.
+ *
+ * Results:
+ * 0 if ok. -1 if couldn't open file.
+ *
+ * Side Effects:
+ * lots
+ */
+static int
+ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
+{
+ const char *fname = p; /* makefile to read */
+ int fd;
+ size_t len = MAXPATHLEN;
+ char *name, *path = bmake_malloc(len);
+
+ if (!strcmp(fname, "-")) {
+ Parse_File(NULL /*stdin*/, -1);
+ Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
+ } else {
+ /* if we've chdir'd, rebuild the path name */
+ if (strcmp(curdir, objdir) && *fname != '/') {
+ size_t plen = strlen(curdir) + strlen(fname) + 2;
+ if (len < plen)
+ path = bmake_realloc(path, len = 2 * plen);
+
+ (void)snprintf(path, len, "%s/%s", curdir, fname);
+ fd = open(path, O_RDONLY);
+ if (fd != -1) {
+ fname = path;
+ goto found;
+ }
+
+ /* If curdir failed, try objdir (ala .depend) */
+ plen = strlen(objdir) + strlen(fname) + 2;
+ if (len < plen)
+ path = bmake_realloc(path, len = 2 * plen);
+ (void)snprintf(path, len, "%s/%s", objdir, fname);
+ fd = open(path, O_RDONLY);
+ if (fd != -1) {
+ fname = path;
+ goto found;
+ }
+ } else {
+ fd = open(fname, O_RDONLY);
+ if (fd != -1)
+ goto found;
+ }
+ /* look in -I and system include directories. */
+ name = Dir_FindFile(fname, parseIncPath);
+ if (!name)
+ name = Dir_FindFile(fname,
+ Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath);
+ if (!name || (fd = open(name, O_RDONLY)) == -1) {
+ if (name)
+ free(name);
+ free(path);
+ return(-1);
+ }
+ fname = name;
+ /*
+ * set the MAKEFILE variable desired by System V fans -- the
+ * placement of the setting here means it gets set to the last
+ * makefile specified, as it is set by SysV make.
+ */
+found:
+ if (!doing_depend)
+ Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
+ Parse_File(fname, fd);
+ }
+ free(path);
+ return(0);
+}
+
+
+/*
+ * If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR
+ * in situations that would not arrise with ./obj (links or not).
+ * This tends to break things like:
+ *
+ * build:
+ * ${MAKE} includes
+ *
+ * This function spots when ${.MAKE:T} or ${.MAKE} is a command (as
+ * opposed to an argument) in a command line and if so returns
+ * ${.CURDIR} so caller can chdir() so that the assumptions made by
+ * the Makefile hold true.
+ *
+ * If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped.
+ *
+ * The chdir() only happens in the child process, and does nothing if
+ * MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it
+ * should not break anything. Also if NOCHECKMAKECHDIR is set we
+ * do nothing - to ensure historic semantics can be retained.
+ */
+#ifdef NO_CHECK_MAKE_CHDIR
+char *
+Check_Cwd_Cmd(cmd)
+ char *cmd;
+{
+ return 0;
+}
+
+void
+Check_Cwd(argv)
+ char **argv;
+{
+ return;
+}
+
+#else
+
+static int Check_Cwd_Off = 0;
+
+static char *
+Check_Cwd_av(int ac, char **av, int copy)
+{
+ static char *make[4];
+ static char *cur_dir = NULL;
+ char **mp;
+ char *cp;
+ int is_cmd, next_cmd;
+ int i;
+ int n;
+
+ if (Check_Cwd_Off) {
+ if (DEBUG(CWD))
+ fprintf(debug_file, "check_cwd: check is off.\n");
+ return NULL;
+ }
+
+ if (make[0] == NULL) {
+ if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) {
+ Check_Cwd_Off = 1;
+ if (DEBUG(CWD))
+ fprintf(debug_file, "check_cwd: turning check off.\n");
+ return NULL;
+ }
+
+ make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp);
+ if ((make[0] = strrchr(make[1], '/')) == NULL) {
+ make[0] = make[1];
+ make[1] = NULL;
+ } else
+ ++make[0];
+ make[2] = NULL;
+ cur_dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp);
+ }
+ if (ac == 0 || av == NULL) {
+ if (DEBUG(CWD))
+ fprintf(debug_file, "check_cwd: empty command.\n");
+ return NULL; /* initialization only */
+ }
+
+ if (getenv("MAKEOBJDIR") == NULL &&
+ getenv("MAKEOBJDIRPREFIX") == NULL) {
+ if (DEBUG(CWD))
+ fprintf(debug_file, "check_cwd: no obj dirs.\n");
+ return NULL;
+ }
+
+
+ next_cmd = 1;
+ for (i = 0; i < ac; ++i) {
+ is_cmd = next_cmd;
+
+ n = strlen(av[i]);
+ cp = &(av[i])[n - 1];
+ if (strspn(av[i], "|&;") == (size_t)n) {
+ next_cmd = 1;
+ continue;
+ } else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') {
+ next_cmd = 1;
+ if (copy) {
+ do {
+ *cp-- = '\0';
+ } while (*cp == ';' || *cp == '&' || *cp == '|' ||
+ *cp == ')' || *cp == '}') ;
+ } else {
+ /*
+ * XXX this should not happen.
+ */
+ fprintf(stderr, "%s: WARNING: raw arg ends in shell meta '%s'\n",
+ progname, av[i]);
+ }
+ } else
+ next_cmd = 0;
+
+ cp = av[i];
+ if (*cp == ';' || *cp == '&' || *cp == '|')
+ is_cmd = 1;
+
+ if (DEBUG(CWD))
+ fprintf(debug_file, "av[%d] == %s '%s'",
+ i, (is_cmd) ? "cmd" : "arg", av[i]);
+ if (is_cmd != 0) {
+ if (*cp == '(' || *cp == '{' ||
+ *cp == ';' || *cp == '&' || *cp == '|') {
+ do {
+ ++cp;
+ } while (*cp == '(' || *cp == '{' ||
+ *cp == ';' || *cp == '&' || *cp == '|');
+ if (*cp == '\0') {
+ next_cmd = 1;
+ continue;
+ }
+ }
+ if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) {
+ if (DEBUG(CWD))
+ fprintf(debug_file, " == cd, done.\n");
+ return NULL;
+ }
+ for (mp = make; *mp != NULL; ++mp) {
+ n = strlen(*mp);
+ if (strcmp(cp, *mp) == 0) {
+ if (DEBUG(CWD))
+ fprintf(debug_file, " %s == '%s', chdir(%s)\n",
+ cp, *mp, cur_dir);
+ return cur_dir;
+ }
+ }
+ }
+ if (DEBUG(CWD))
+ fprintf(debug_file, "\n");
+ }
+ return NULL;
+}
+
+char *
+Check_Cwd_Cmd(const char *cmd)
+{
+ char *cp, *bp;
+ char **av;
+ int ac;
+
+ if (Check_Cwd_Off)
+ return NULL;
+
+ if (cmd) {
+ av = brk_string(cmd, &ac, TRUE, &bp);
+ if (DEBUG(CWD))
+ fprintf(debug_file, "splitting: '%s' -> %d words\n",
+ cmd, ac);
+ } else {
+ ac = 0;
+ av = NULL;
+ bp = NULL;
+ }
+ cp = Check_Cwd_av(ac, av, 1);
+ if (bp)
+ free(bp);
+ if (av)
+ free(av);
+ return cp;
+}
+
+void
+Check_Cwd(const char **argv)
+{
+ char *cp;
+ int ac;
+
+ if (Check_Cwd_Off)
+ return;
+
+ for (ac = 0; argv[ac] != NULL; ++ac)
+ /* NOTHING */;
+ if (ac == 3 && *argv[1] == '-') {
+ cp = Check_Cwd_Cmd(argv[2]);
+ } else {
+ cp = Check_Cwd_av(ac, UNCONST(argv), 0);
+ }
+ if (cp) {
+ chdir(cp);
+ }
+}
+#endif /* NO_CHECK_MAKE_CHDIR */
+
+/*-
+ * Cmd_Exec --
+ * Execute the command in cmd, and return the output of that command
+ * in a string.
+ *
+ * Results:
+ * A string containing the output of the command, or the empty string
+ * If errnum is not NULL, it contains the reason for the command failure
+ *
+ * Side Effects:
+ * The string must be freed by the caller.
+ */
+char *
+Cmd_Exec(const char *cmd, const char **errnum)
+{
+ const char *args[4]; /* Args for invoking the shell */
+ int fds[2]; /* Pipe streams */
+ int cpid; /* Child PID */
+ int pid; /* PID from wait() */
+ char *res; /* result */
+ WAIT_T status; /* command exit status */
+ Buffer buf; /* buffer to store the result */
+ char *cp;
+ int cc;
+
+
+ *errnum = NULL;
+
+ if (!shellName)
+ Shell_Init();
+ /*
+ * Set up arguments for shell
+ */
+ args[0] = shellName;
+ args[1] = "-c";
+ args[2] = cmd;
+ args[3] = NULL;
+
+ /*
+ * Open a pipe for fetching its output
+ */
+ if (pipe(fds) == -1) {
+ *errnum = "Couldn't create pipe for \"%s\"";
+ goto bad;
+ }
+
+ /*
+ * Fork
+ */
+ switch (cpid = vFork()) {
+ case 0:
+ /*
+ * Close input side of pipe
+ */
+ (void)close(fds[0]);
+
+ /*
+ * Duplicate the output stream to the shell's output, then
+ * shut the extra thing down. Note we don't fetch the error
+ * stream...why not? Why?
+ */
+ (void)dup2(fds[1], 1);
+ (void)close(fds[1]);
+
+ Var_ExportVars();
+
+ (void)execv(shellPath, UNCONST(args));
+ _exit(1);
+ /*NOTREACHED*/
+
+ case -1:
+ *errnum = "Couldn't exec \"%s\"";
+ goto bad;
+
+ default:
+ /*
+ * No need for the writing half
+ */
+ (void)close(fds[1]);
+
+ Buf_Init(&buf, 0);
+
+ do {
+ char result[BUFSIZ];
+ cc = read(fds[0], result, sizeof(result));
+ if (cc > 0)
+ Buf_AddBytes(&buf, cc, result);
+ }
+ while (cc > 0 || (cc == -1 && errno == EINTR));
+
+ /*
+ * Close the input side of the pipe.
+ */
+ (void)close(fds[0]);
+
+ /*
+ * Wait for the process to exit.
+ */
+ while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0)) {
+ JobReapChild(pid, status, FALSE);
+ continue;
+ }
+ cc = Buf_Size(&buf);
+ res = Buf_Destroy(&buf, FALSE);
+
+ if (cc == 0)
+ *errnum = "Couldn't read shell's output for \"%s\"";
+
+ if (WIFSIGNALED(status))
+ *errnum = "\"%s\" exited on a signal";
+ else if (WEXITSTATUS(status) != 0)
+ *errnum = "\"%s\" returned non-zero status";
+
+ /*
+ * Null-terminate the result, convert newlines to spaces and
+ * install it in the variable.
+ */
+ res[cc] = '\0';
+ cp = &res[cc];
+
+ if (cc > 0 && *--cp == '\n') {
+ /*
+ * A final newline is just stripped
+ */
+ *cp-- = '\0';
+ }
+ while (cp >= res) {
+ if (*cp == '\n') {
+ *cp = ' ';
+ }
+ cp--;
+ }
+ break;
+ }
+ return res;
+bad:
+ res = bmake_malloc(1);
+ *res = '\0';
+ return res;
+}
+
+/*-
+ * Error --
+ * Print an error message given its format.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The message is printed.
+ */
+/* VARARGS */
+void
+Error(const char *fmt, ...)
+{
+ va_list ap;
+ FILE *err_file;
+
+ err_file = debug_file;
+ if (err_file == stdout)
+ err_file = stderr;
+ (void)fflush(stdout);
+ for (;;) {
+ va_start(ap, fmt);
+ fprintf(err_file, "%s: ", progname);
+ (void)vfprintf(err_file, fmt, ap);
+ va_end(ap);
+ (void)fprintf(err_file, "\n");
+ (void)fflush(err_file);
+ if (err_file == stderr)
+ break;
+ err_file = stderr;
+ }
+}
+
+/*-
+ * Fatal --
+ * Produce a Fatal error message. If jobs are running, waits for them
+ * to finish.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The program exits
+ */
+/* VARARGS */
+void
+Fatal(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (jobsRunning)
+ Job_Wait();
+
+ (void)fflush(stdout);
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void)fprintf(stderr, "\n");
+ (void)fflush(stderr);
+
+ PrintOnError(NULL, NULL);
+
+ if (DEBUG(GRAPH2) || DEBUG(GRAPH3))
+ Targ_PrintGraph(2);
+ Trace_Log(MAKEERROR, 0);
+ exit(2); /* Not 1 so -q can distinguish error */
+}
+
+/*
+ * Punt --
+ * Major exception once jobs are being created. Kills all jobs, prints
+ * a message and exits.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * All children are killed indiscriminately and the program Lib_Exits
+ */
+/* VARARGS */
+void
+Punt(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void)fflush(stdout);
+ (void)fprintf(stderr, "%s: ", progname);
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void)fprintf(stderr, "\n");
+ (void)fflush(stderr);
+
+ PrintOnError(NULL, NULL);
+
+ DieHorribly();
+}
+
+/*-
+ * DieHorribly --
+ * Exit without giving a message.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * A big one...
+ */
+void
+DieHorribly(void)
+{
+ if (jobsRunning)
+ Job_AbortAll();
+ if (DEBUG(GRAPH2))
+ Targ_PrintGraph(2);
+ Trace_Log(MAKEERROR, 0);
+ exit(2); /* Not 1, so -q can distinguish error */
+}
+
+/*
+ * Finish --
+ * Called when aborting due to errors in child shell to signal
+ * abnormal exit.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The program exits
+ */
+void
+Finish(int errors)
+ /* number of errors encountered in Make_Make */
+{
+ Fatal("%d error%s", errors, errors == 1 ? "" : "s");
+}
+
+/*
+ * enunlink --
+ * Remove a file carefully, avoiding directories.
+ */
+int
+eunlink(const char *file)
+{
+ struct stat st;
+
+ if (lstat(file, &st) == -1)
+ return -1;
+
+ if (S_ISDIR(st.st_mode)) {
+ errno = EISDIR;
+ return -1;
+ }
+ return unlink(file);
+}
+
+/*
+ * execError --
+ * Print why exec failed, avoiding stdio.
+ */
+void
+execError(const char *af, const char *av)
+{
+#ifdef USE_IOVEC
+ int i = 0;
+ struct iovec iov[8];
+#define IOADD(s) \
+ (void)(iov[i].iov_base = UNCONST(s), \
+ iov[i].iov_len = strlen(iov[i].iov_base), \
+ i++)
+#else
+#define IOADD(s) (void)write(2, s, strlen(s))
+#endif
+
+ IOADD(progname);
+ IOADD(": ");
+ IOADD(af);
+ IOADD("(");
+ IOADD(av);
+ IOADD(") failed (");
+ IOADD(strerror(errno));
+ IOADD(")\n");
+
+#ifdef USE_IOVEC
+ (void)writev(2, iov, 8);
+#endif
+}
+
+/*
+ * usage --
+ * exit with usage message
+ */
+static void
+usage(void)
+{
+ (void)fprintf(stderr,
+"usage: %s [-BeikNnqrstWX] \n\
+ [-C directory] [-D variable] [-d flags] [-f makefile]\n\
+ [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\
+ [-V variable] [variable=value] [target ...]\n", progname);
+ exit(2);
+}
+
+
+int
+PrintAddr(void *a, void *b)
+{
+ printf("%lx ", (unsigned long) a);
+ return b ? 0 : 0;
+}
+
+
+
+void
+PrintOnError(GNode *gn, const char *s)
+{
+ static GNode *en = NULL;
+ char tmp[64];
+ char *cp;
+
+ if (s)
+ printf("%s", s);
+
+ printf("\n%s: stopped in %s\n", progname, curdir);
+
+ if (en)
+ return; /* we've been here! */
+ if (gn) {
+ /*
+ * We can print this even if there is no .ERROR target.
+ */
+ Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL, 0);
+ }
+ strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
+ sizeof(tmp) - 1);
+ cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
+ if (cp) {
+ if (*cp)
+ printf("%s", cp);
+ free(cp);
+ }
+ /*
+ * Finally, see if there is a .ERROR target, and run it if so.
+ */
+ en = Targ_FindNode(".ERROR", TARG_NOCREATE);
+ if (en) {
+ en->type |= OP_SPECIAL;
+ Compat_Make(en, en);
+ }
+}
+
+void
+Main_ExportMAKEFLAGS(Boolean first)
+{
+ static int once = 1;
+ char tmp[64];
+ char *s;
+
+ if (once != first)
+ return;
+ once = 0;
+
+ strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
+ sizeof(tmp));
+ s = Var_Subst(NULL, tmp, VAR_CMD, 0);
+ if (s && *s) {
+#ifdef POSIX
+ setenv("MAKEFLAGS", s, 1);
+#else
+ setenv("MAKE", s, 1);
+#endif
+ }
+}
+
+char *
+getTmpdir(void)
+{
+ static char *tmpdir = NULL;
+
+ if (!tmpdir) {
+ struct stat st;
+
+ /*
+ * Honor $TMPDIR but only if it is valid.
+ * Ensure it ends with /.
+ */
+ tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL, 0);
+ if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
+ free(tmpdir);
+ tmpdir = bmake_strdup(_PATH_TMP);
+ }
+ }
+ return tmpdir;
+}
+
+/*
+ * Create and open a temp file using "pattern".
+ * If "fnamep" is provided set it to a copy of the filename created.
+ * Otherwise unlink the file once open.
+ */
+int
+mkTempFile(const char *pattern, char **fnamep)
+{
+ static char *tmpdir = NULL;
+ char tfile[MAXPATHLEN];
+ int fd;
+
+ if (!pattern)
+ pattern = TMPPAT;
+ if (!tmpdir)
+ tmpdir = getTmpdir();
+ if (pattern[0] == '/') {
+ snprintf(tfile, sizeof(tfile), "%s", pattern);
+ } else {
+ snprintf(tfile, sizeof(tfile), "%s%s", tmpdir, pattern);
+ }
+ if ((fd = mkstemp(tfile)) < 0)
+ Punt("Could not create temporary file %s: %s", tfile, strerror(errno));
+ if (fnamep) {
+ *fnamep = bmake_strdup(tfile);
+ } else {
+ unlink(tfile); /* we just want the descriptor */
+ }
+ return fd;
+}
diff --git a/external/bsd/bmake/dist/make-bootstrap.sh.in b/external/bsd/bmake/dist/make-bootstrap.sh.in
new file mode 100755
index 0000000..d9ff9ff
--- /dev/null
+++ b/external/bsd/bmake/dist/make-bootstrap.sh.in
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+set -e
+
+srcdir=@srcdir@
+
+DEFAULT_SYS_PATH="@default_sys_path@"
+
+case "@use_meta@" in
+yes) XDEFS="-DUSE_META ${XDEFS}";;
+esac
+
+CC="@CC@"
+CFLAGS="@CFLAGS@ -I. -I${srcdir} @DEFS@ @CPPFLAGS@ -DMAKE_NATIVE ${XDEFS}"
+
+MAKE_VERSION=`sed -n '/^MAKE_VERSION=/s,.*=[^0-9]*,,p' Makefile`
+
+MDEFS="-DMAKE_VERSION=\"$MAKE_VERSION\" \
+-D@force_machine@MACHINE=\"@machine@\" -DMACHINE_ARCH=\"@machine_arch@\" \
+-D_PATH_DEFSYSPATH=\"${DEFAULT_SYS_PATH}\""
+
+
+LDFLAGS="@LDFLAGS@"
+LIBS="@LIBS@"
+
+do_compile2() {
+ obj="$1"; shift
+ src="$1"; shift
+ echo ${CC} -c ${CFLAGS} "$@" -o "$obj" "$src"
+ ${CC} -c ${CFLAGS} "$@" -o "$obj" "$src"
+}
+
+do_compile() {
+ obj="$1"; shift
+ src=`basename "$obj" .o`.c
+
+ for d in "$srcdir" "$srcdir/lst.lib"
+ do
+ test -s "$d/$src" || continue
+
+ do_compile2 "$obj" "$d/$src" "$@" || exit 1
+ return
+ done
+ echo "Unknown object file '$obj'" >&2
+ exit 1
+}
+
+do_link() {
+ output="$1"; shift
+ echo ${CC} ${LDSTATIC} ${LDFLAGS} -o "$output" "$@" ${LIBS}
+ ${CC} ${LDSTATIC} ${LDFLAGS} -o "$output" "$@" ${LIBS}
+}
+
+BASE_OBJECTS="arch.o buf.o compat.o cond.o dir.o for.o getopt hash.o \
+job.o make.o make_malloc.o parse.o sigcompat.o str.o strlist.o \
+suff.o targ.o trace.o var.o util.o"
+
+LST_OBJECTS="lstAppend.o lstDupl.o lstInit.o lstOpen.o \
+lstAtEnd.o lstEnQueue.o lstInsert.o lstAtFront.o lstIsAtEnd.o \
+lstClose.o lstFind.o lstIsEmpty.o lstRemove.o lstConcat.o \
+lstFindFrom.o lstLast.o lstReplace.o lstFirst.o lstDatum.o \
+lstForEach.o lstMember.o lstSucc.o lstDeQueue.o lstForEachFrom.o \
+lstDestroy.o lstNext.o lstPrev.o"
+
+LIB_OBJECTS="@LIBOBJS@"
+
+do_compile main.o ${MDEFS}
+
+for o in ${BASE_OBJECTS} ${LST_OBJECTS} ${LIB_OBJECTS}
+do
+ do_compile "$o"
+done
+
+case "@use_meta@" in
+yes)
+ case "@filemon_h@" in
+ */filemon.h) FDEFS="-DHAVE_FILEMON_H -I`dirname @filemon_h@`";;
+ esac
+ do_compile meta.o ${FDEFS}
+ BASE_OBJECTS="meta.o ${BASE_OBJECTS}"
+ ;;
+esac
+
+do_link bmake main.o ${BASE_OBJECTS} ${LST_OBJECTS} ${LIB_OBJECTS}
diff --git a/external/bsd/bmake/dist/make-conf.h b/external/bsd/bmake/dist/make-conf.h
new file mode 100644
index 0000000..a85b86d
--- /dev/null
+++ b/external/bsd/bmake/dist/make-conf.h
@@ -0,0 +1,162 @@
+/* $NetBSD: config.h,v 1.21 2012/03/31 00:12:24 christos Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)config.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Copyright (c) 1988, 1989 by Adam de Boor
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)config.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * DEFMAXJOBS
+ * DEFMAXLOCAL
+ * These control the default concurrency. On no occasion will more
+ * than DEFMAXJOBS targets be created at once (locally or remotely)
+ * DEFMAXLOCAL is the highest number of targets which will be
+ * created on the local machine at once. Note that if you set this
+ * to 0, nothing will ever happen...
+ */
+#define DEFMAXJOBS 4
+#define DEFMAXLOCAL 1
+
+/*
+ * INCLUDES
+ * LIBRARIES
+ * These control the handling of the .INCLUDES and .LIBS variables.
+ * If INCLUDES is defined, the .INCLUDES variable will be filled
+ * from the search paths of those suffixes which are marked by
+ * .INCLUDES dependency lines. Similarly for LIBRARIES and .LIBS
+ * See suff.c for more details.
+ */
+#define INCLUDES
+#define LIBRARIES
+
+/*
+ * LIBSUFF
+ * Is the suffix used to denote libraries and is used by the Suff module
+ * to find the search path on which to seek any -l<xx> targets.
+ *
+ * RECHECK
+ * If defined, Make_Update will check a target for its current
+ * modification time after it has been re-made, setting it to the
+ * starting time of the make only if the target still doesn't exist.
+ * Unfortunately, under NFS the modification time often doesn't
+ * get updated in time, so a target will appear to not have been
+ * re-made, causing later targets to appear up-to-date. On systems
+ * that don't have this problem, you should defined this. Under
+ * NFS you probably should not, unless you aren't exporting jobs.
+ */
+#define LIBSUFF ".a"
+#define RECHECK
+
+/*
+ * POSIX
+ * Adhere to the POSIX 1003.2 draft for the make(1) program.
+ * - Use MAKEFLAGS instead of MAKE to pick arguments from the
+ * environment.
+ * - Allow empty command lines if starting with tab.
+ */
+#define POSIX
+
+/*
+ * SYSVINCLUDE
+ * Recognize system V like include directives [include "filename"]
+ * SYSVVARSUB
+ * Recognize system V like ${VAR:x=y} variable substitutions
+ */
+#define SYSVINCLUDE
+#define SYSVVARSUB
+
+/*
+ * GMAKEEXPORT
+ * Recognize gmake like variable export directives [export <VAR>=<VALUE>]
+ */
+#define GMAKEEXPORT
+
+/*
+ * SUNSHCMD
+ * Recognize SunOS and Solaris:
+ * VAR :sh= CMD # Assign VAR to the command substitution of CMD
+ * ${VAR:sh} # Return the command substitution of the value
+ * # of ${VAR}
+ */
+#define SUNSHCMD
+
+/*
+ * USE_IOVEC
+ * We have writev(2)
+ */
+#ifdef HAVE_SYS_UIO_H
+# define USE_IOVEC
+#endif
+
+#if defined(MAKE_NATIVE) && !defined(__ELF__)
+# ifndef RANLIBMAG
+# define RANLIBMAG "__.SYMDEF"
+# endif
+#endif
diff --git a/external/bsd/bmake/dist/make.1 b/external/bsd/bmake/dist/make.1
new file mode 100644
index 0000000..86f747b
--- /dev/null
+++ b/external/bsd/bmake/dist/make.1
@@ -0,0 +1,2061 @@
+.\" $NetBSD: make.1,v 1.204 2012/04/24 20:12:16 sjg Exp $
+.\"
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
+.\"
+.Dd April 24, 2012
+.Dt MAKE 1
+.Os
+.Sh NAME
+.Nm make
+.Nd maintain program dependencies
+.Sh SYNOPSIS
+.Nm
+.Op Fl BeikNnqrstWX
+.Op Fl C Ar directory
+.Op Fl D Ar variable
+.Op Fl d Ar flags
+.Op Fl f Ar makefile
+.Op Fl I Ar directory
+.Op Fl J Ar private
+.Op Fl j Ar max_jobs
+.Op Fl m Ar directory
+.Op Fl T Ar file
+.Op Fl V Ar variable
+.Op Ar variable=value
+.Op Ar target ...
+.Sh DESCRIPTION
+.Nm
+is a program designed to simplify the maintenance of other programs.
+Its input is a list of specifications as to the files upon which programs
+and other files depend.
+If no
+.Fl f Ar makefile
+makefile option is given,
+.Nm
+will try to open
+.Ql Pa makefile
+then
+.Ql Pa Makefile
+in order to find the specifications.
+If the file
+.Ql Pa .depend
+exists, it is read (see
+.Xr mkdep 1 ) .
+.Pp
+This manual page is intended as a reference document only.
+For a more thorough description of
+.Nm
+and makefiles, please refer to
+.%T "PMake \- A Tutorial" .
+.Pp
+.Nm
+will prepend the contents of the
+.Va MAKEFLAGS
+environment variable to the command line arguments before parsing them.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl B
+Try to be backwards compatible by executing a single shell per command and
+by executing the commands to make the sources of a dependency line in sequence.
+.It Fl C Ar directory
+Change to
+.Ar directory
+before reading the makefiles or doing anything else.
+If multiple
+.Fl C
+options are specified, each is interpreted relative to the previous one:
+.Fl C Pa / Fl C Pa etc
+is equivalent to
+.Fl C Pa /etc .
+.It Fl D Ar variable
+Define
+.Ar variable
+to be 1, in the global context.
+.It Fl d Ar [-]flags
+Turn on debugging, and specify which portions of
+.Nm
+are to print debugging information.
+Unless the flags are preceded by
+.Ql \-
+they are added to the
+.Va MAKEFLAGS
+environment variable and will be processed by any child make processes.
+By default, debugging information is printed to standard error,
+but this can be changed using the
+.Ar F
+debugging flag.
+The debugging output is always unbuffered; in addition, if debugging
+is enabled but debugging output is not directed to standard output,
+then the standard output is line buffered.
+.Ar Flags
+is one or more of the following:
+.Bl -tag -width Ds
+.It Ar A
+Print all possible debugging information;
+equivalent to specifying all of the debugging flags.
+.It Ar a
+Print debugging information about archive searching and caching.
+.It Ar C
+Print debugging information about current working directory.
+.It Ar c
+Print debugging information about conditional evaluation.
+.It Ar d
+Print debugging information about directory searching and caching.
+.It Ar e
+Print debugging information about failed commands and targets.
+.It Ar F Ns Oo Sy \&+ Oc Ns Ar filename
+Specify where debugging output is written.
+This must be the last flag, because it consumes the remainder of
+the argument.
+If the character immediately after the
+.Ql F
+flag is
+.Ql \&+ ,
+then the file will be opened in append mode;
+otherwise the file will be overwritten.
+If the file name is
+.Ql stdout
+or
+.Ql stderr
+then debugging output will be written to the
+standard output or standard error output file descriptors respectively
+(and the
+.Ql \&+
+option has no effect).
+Otherwise, the output will be written to the named file.
+If the file name ends
+.Ql .%d
+then the
+.Ql %d
+is replaced by the pid.
+.It Ar f
+Print debugging information about loop evaluation.
+.It Ar "g1"
+Print the input graph before making anything.
+.It Ar "g2"
+Print the input graph after making everything, or before exiting
+on error.
+.It Ar "g3"
+Print the input graph before exiting on error.
+.It Ar j
+Print debugging information about running multiple shells.
+.It Ar l
+Print commands in Makefiles regardless of whether or not they are prefixed by
+.Ql @
+or other "quiet" flags.
+Also known as "loud" behavior.
+.It Ar M
+Print debugging information about "meta" mode decisions about targets.
+.It Ar m
+Print debugging information about making targets, including modification
+dates.
+.It Ar n
+Don't delete the temporary command scripts created when running commands.
+These temporary scripts are created in the directory
+referred to by the
+.Ev TMPDIR
+environment variable, or in
+.Pa /tmp
+if
+.Ev TMPDIR
+is unset or set to the empty string.
+The temporary scripts are created by
+.Xr mkstemp 3 ,
+and have names of the form
+.Pa makeXXXXXX .
+.Em NOTE :
+This can create many files in
+.Ev TMPDIR
+or
+.Pa /tmp ,
+so use with care.
+.It Ar p
+Print debugging information about makefile parsing.
+.It Ar s
+Print debugging information about suffix-transformation rules.
+.It Ar t
+Print debugging information about target list maintenance.
+.It Ar v
+Print debugging information about variable assignment.
+.It Ar x
+Run shell commands with
+.Fl x
+so the actual commands are printed as they are executed.
+.El
+.It Fl e
+Specify that environment variables override macro assignments within
+makefiles.
+.It Fl f Ar makefile
+Specify a makefile to read instead of the default
+.Ql Pa makefile .
+If
+.Ar makefile
+is
+.Ql Fl ,
+standard input is read.
+Multiple makefiles may be specified, and are read in the order specified.
+.It Fl I Ar directory
+Specify a directory in which to search for makefiles and included makefiles.
+The system makefile directory (or directories, see the
+.Fl m
+option) is automatically included as part of this list.
+.It Fl i
+Ignore non-zero exit of shell commands in the makefile.
+Equivalent to specifying
+.Ql Fl
+before each command line in the makefile.
+.It Fl J Ar private
+This option should
+.Em not
+be specified by the user.
+.Pp
+When the
+.Ar j
+option is in use in a recursive build, this option is passed by a make
+to child makes to allow all the make processes in the build to
+cooperate to avoid overloading the system.
+.It Fl j Ar max_jobs
+Specify the maximum number of jobs that
+.Nm
+may have running at any one time.
+The value is saved in
+.Va .MAKE.JOBS .
+Turns compatibility mode off, unless the
+.Ar B
+flag is also specified.
+When compatibility mode is off, all commands associated with a
+target are executed in a single shell invocation as opposed to the
+traditional one shell invocation per line.
+This can break traditional scripts which change directories on each
+command invocation and then expect to start with a fresh environment
+on the next line.
+It is more efficient to correct the scripts rather than turn backwards
+compatibility on.
+.It Fl k
+Continue processing after errors are encountered, but only on those targets
+that do not depend on the target whose creation caused the error.
+.It Fl m Ar directory
+Specify a directory in which to search for sys.mk and makefiles included
+via the
+.Ao Ar file Ac Ns -style
+include statement.
+The
+.Fl m
+option can be used multiple times to form a search path.
+This path will override the default system include path: /usr/share/mk.
+Furthermore the system include path will be appended to the search path used
+for
+.Qo Ar file Qc Ns -style
+include statements (see the
+.Fl I
+option).
+.Pp
+If a file or directory name in the
+.Fl m
+argument (or the
+.Ev MAKESYSPATH
+environment variable) starts with the string
+.Qq \&.../
+then
+.Nm
+will search for the specified file or directory named in the remaining part
+of the argument string.
+The search starts with the current directory of
+the Makefile and then works upward towards the root of the filesystem.
+If the search is successful, then the resulting directory replaces the
+.Qq \&.../
+specification in the
+.Fl m
+argument.
+If used, this feature allows
+.Nm
+to easily search in the current source tree for customized sys.mk files
+(e.g., by using
+.Qq \&.../mk/sys.mk
+as an argument).
+.It Fl n
+Display the commands that would have been executed, but do not
+actually execute them unless the target depends on the .MAKE special
+source (see below).
+.It Fl N
+Display the commands which would have been executed, but do not
+actually execute any of them; useful for debugging top-level makefiles
+without descending into subdirectories.
+.It Fl q
+Do not execute any commands, but exit 0 if the specified targets are
+up-to-date and 1, otherwise.
+.It Fl r
+Do not use the built-in rules specified in the system makefile.
+.It Fl s
+Do not echo any commands as they are executed.
+Equivalent to specifying
+.Ql Ic @
+before each command line in the makefile.
+.It Fl T Ar tracefile
+When used with the
+.Fl j
+flag,
+append a trace record to
+.Ar tracefile
+for each job started and completed.
+.It Fl t
+Rather than re-building a target as specified in the makefile, create it
+or update its modification time to make it appear up-to-date.
+.It Fl V Ar variable
+Print
+.Nm Ns 's
+idea of the value of
+.Ar variable ,
+in the global context.
+Do not build any targets.
+Multiple instances of this option may be specified;
+the variables will be printed one per line,
+with a blank line for each null or undefined variable.
+If
+.Ar variable
+contains a
+.Ql \&$
+then the value will be expanded before printing.
+.It Fl W
+Treat any warnings during makefile parsing as errors.
+.It Fl X
+Don't export variables passed on the command line to the environment
+individually.
+Variables passed on the command line are still exported
+via the
+.Va MAKEFLAGS
+environment variable.
+This option may be useful on systems which have a small limit on the
+size of command arguments.
+.It Ar variable=value
+Set the value of the variable
+.Ar variable
+to
+.Ar value .
+Normally, all values passed on the command line are also exported to
+sub-makes in the environment.
+The
+.Fl X
+flag disables this behavior.
+Variable assignments should follow options for POSIX compatibility
+but no ordering is enforced.
+.El
+.Pp
+There are seven different types of lines in a makefile: file dependency
+specifications, shell commands, variable assignments, include statements,
+conditional directives, for loops, and comments.
+.Pp
+In general, lines may be continued from one line to the next by ending
+them with a backslash
+.Pq Ql \e .
+The trailing newline character and initial whitespace on the following
+line are compressed into a single space.
+.Sh FILE DEPENDENCY SPECIFICATIONS
+Dependency lines consist of one or more targets, an operator, and zero
+or more sources.
+This creates a relationship where the targets
+.Dq depend
+on the sources
+and are usually created from them.
+The exact relationship between the target and the source is determined
+by the operator that separates them.
+The three operators are as follows:
+.Bl -tag -width flag
+.It Ic \&:
+A target is considered out-of-date if its modification time is less than
+those of any of its sources.
+Sources for a target accumulate over dependency lines when this operator
+is used.
+The target is removed if
+.Nm
+is interrupted.
+.It Ic \&!
+Targets are always re-created, but not until all sources have been
+examined and re-created as necessary.
+Sources for a target accumulate over dependency lines when this operator
+is used.
+The target is removed if
+.Nm
+is interrupted.
+.It Ic \&::
+If no sources are specified, the target is always re-created.
+Otherwise, a target is considered out-of-date if any of its sources has
+been modified more recently than the target.
+Sources for a target do not accumulate over dependency lines when this
+operator is used.
+The target will not be removed if
+.Nm
+is interrupted.
+.El
+.Pp
+Targets and sources may contain the shell wildcard values
+.Ql \&? ,
+.Ql * ,
+.Ql [] ,
+and
+.Ql {} .
+The values
+.Ql \&? ,
+.Ql * ,
+and
+.Ql []
+may only be used as part of the final
+component of the target or source, and must be used to describe existing
+files.
+The value
+.Ql {}
+need not necessarily be used to describe existing files.
+Expansion is in directory order, not alphabetically as done in the shell.
+.Sh SHELL COMMANDS
+Each target may have associated with it a series of shell commands, normally
+used to create the target.
+Each of the commands in this script
+.Em must
+be preceded by a tab.
+While any target may appear on a dependency line, only one of these
+dependencies may be followed by a creation script, unless the
+.Ql Ic \&::
+operator is used.
+.Pp
+If the first characters of the command line are any combination of
+.Ql Ic @ ,
+.Ql Ic + ,
+or
+.Ql Ic \- ,
+the command is treated specially.
+A
+.Ql Ic @
+causes the command not to be echoed before it is executed.
+A
+.Ql Ic +
+causes the command to be executed even when
+.Fl n
+is given.
+This is similar to the effect of the .MAKE special source,
+except that the effect can be limited to a single line of a script.
+A
+.Ql Ic \-
+causes any non-zero exit status of the command line to be ignored.
+.Sh VARIABLE ASSIGNMENTS
+Variables in make are much like variables in the shell, and, by tradition,
+consist of all upper-case letters.
+.Ss Variable assignment modifiers
+The five operators that can be used to assign values to variables are as
+follows:
+.Bl -tag -width Ds
+.It Ic \&=
+Assign the value to the variable.
+Any previous value is overridden.
+.It Ic \&+=
+Append the value to the current value of the variable.
+.It Ic \&?=
+Assign the value to the variable if it is not already defined.
+.It Ic \&:=
+Assign with expansion, i.e. expand the value before assigning it
+to the variable.
+Normally, expansion is not done until the variable is referenced.
+.Em NOTE :
+References to undefined variables are
+.Em not
+expanded.
+This can cause problems when variable modifiers are used.
+.It Ic \&!=
+Expand the value and pass it to the shell for execution and assign
+the result to the variable.
+Any newlines in the result are replaced with spaces.
+.El
+.Pp
+Any white-space before the assigned
+.Ar value
+is removed; if the value is being appended, a single space is inserted
+between the previous contents of the variable and the appended value.
+.Pp
+Variables are expanded by surrounding the variable name with either
+curly braces
+.Pq Ql {}
+or parentheses
+.Pq Ql ()
+and preceding it with
+a dollar sign
+.Pq Ql \&$ .
+If the variable name contains only a single letter, the surrounding
+braces or parentheses are not required.
+This shorter form is not recommended.
+.Pp
+If the variable name contains a dollar, then the name itself is expanded first.
+This allows almost arbitrary variable names, however names containing dollar,
+braces, parenthesis, or whitespace are really best avoided!
+.Pp
+If the result of expanding a variable contains a dollar sign
+.Pq Ql \&$
+the string is expanded again.
+.Pp
+Variable substitution occurs at three distinct times, depending on where
+the variable is being used.
+.Bl -enum
+.It
+Variables in dependency lines are expanded as the line is read.
+.It
+Variables in shell commands are expanded when the shell command is
+executed.
+.It
+.Dq .for
+loop index variables are expanded on each loop iteration.
+Note that other variables are not expanded inside loops so
+the following example code:
+.Bd -literal -offset indent
+
+.Dv .for i in 1 2 3
+a+= ${i}
+j= ${i}
+b+= ${j}
+.Dv .endfor
+
+all:
+ @echo ${a}
+ @echo ${b}
+
+.Ed
+will print:
+.Bd -literal -offset indent
+1 2 3
+3 3 3
+
+.Ed
+Because while ${a} contains
+.Dq 1 2 3
+after the loop is executed, ${b}
+contains
+.Dq ${j} ${j} ${j}
+which expands to
+.Dq 3 3 3
+since after the loop completes ${j} contains
+.Dq 3 .
+.El
+.Ss Variable classes
+The four different classes of variables (in order of increasing precedence)
+are:
+.Bl -tag -width Ds
+.It Environment variables
+Variables defined as part of
+.Nm Ns 's
+environment.
+.It Global variables
+Variables defined in the makefile or in included makefiles.
+.It Command line variables
+Variables defined as part of the command line.
+.It Local variables
+Variables that are defined specific to a certain target.
+The seven local variables are as follows:
+.Bl -tag -width ".ARCHIVE"
+.It Va .ALLSRC
+The list of all sources for this target; also known as
+.Ql Va \&\*[Gt] .
+.It Va .ARCHIVE
+The name of the archive file.
+.It Va .IMPSRC
+In suffix-transformation rules, the name/path of the source from which the
+target is to be transformed (the
+.Dq implied
+source); also known as
+.Ql Va \&\*[Lt] .
+It is not defined in explicit rules.
+.It Va .MEMBER
+The name of the archive member.
+.It Va .OODATE
+The list of sources for this target that were deemed out-of-date; also
+known as
+.Ql Va \&? .
+.It Va .PREFIX
+The file prefix of the target, containing only the file portion, no suffix
+or preceding directory components; also known as
+.Ql Va * .
+.It Va .TARGET
+The name of the target; also known as
+.Ql Va @ .
+.El
+.Pp
+The shorter forms
+.Ql Va @ ,
+.Ql Va \&? ,
+.Ql Va \&\*[Lt] ,
+.Ql Va \&\*[Gt] ,
+and
+.Ql Va *
+are permitted for backward
+compatibility with historical makefiles and are not recommended.
+The six variables
+.Ql Va "@F" ,
+.Ql Va "@D" ,
+.Ql Va "\*[Lt]F" ,
+.Ql Va "\*[Lt]D" ,
+.Ql Va "*F" ,
+and
+.Ql Va "*D"
+are permitted for compatibility with
+.At V
+makefiles and are not recommended.
+.Pp
+Four of the local variables may be used in sources on dependency lines
+because they expand to the proper value for each target on the line.
+These variables are
+.Ql Va .TARGET ,
+.Ql Va .PREFIX ,
+.Ql Va .ARCHIVE ,
+and
+.Ql Va .MEMBER .
+.El
+.Ss Additional built-in variables
+In addition,
+.Nm
+sets or knows about the following variables:
+.Bl -tag -width .MAKEOVERRIDES
+.It Va \&$
+A single dollar sign
+.Ql \&$ ,
+i.e.
+.Ql \&$$
+expands to a single dollar
+sign.
+.It Va .ALLTARGETS
+The list of all targets encountered in the Makefile.
+If evaluated during
+Makefile parsing, lists only those targets encountered thus far.
+.It Va .CURDIR
+A path to the directory where
+.Nm
+was executed.
+Refer to the description of
+.Ql Ev PWD
+for more details.
+.It Ev MAKE
+The name that
+.Nm
+was executed with
+.Pq Va argv[0] .
+For compatibility
+.Nm
+also sets
+.Va .MAKE
+with the same value.
+The preferred variable to use is the environment variable
+.Ev MAKE
+because it is more compatible with other versions of
+.Nm
+and cannot be confused with the special target with the same name.
+.It Va .MAKE.DEPENDFILE
+Names the makefile (default
+.Ql Pa .depend )
+from which generated dependencies are read.
+.It Va .MAKE.EXPORTED
+The list of variables exported by
+.Nm .
+.It Va .MAKE.JOBS
+The argument to the
+.Fl j
+option.
+.It Va .MAKE.JOB.PREFIX
+If
+.Nm
+is run with
+.Ar j
+then output for each target is prefixed with a token
+.Ql --- target ---
+the first part of which can be controlled via
+.Va .MAKE.JOB.PREFIX .
+.br
+For example:
+.Li .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}]
+would produce tokens like
+.Ql ---make[1234] target ---
+making it easier to track the degree of parallelism being achieved.
+.It Ev MAKEFLAGS
+The environment variable
+.Ql Ev MAKEFLAGS
+may contain anything that
+may be specified on
+.Nm Ns 's
+command line.
+Anything specified on
+.Nm Ns 's
+command line is appended to the
+.Ql Ev MAKEFLAGS
+variable which is then
+entered into the environment for all programs which
+.Nm
+executes.
+.It Va .MAKE.LEVEL
+The recursion depth of
+.Nm .
+The initial instance of
+.Nm
+will be 0, and an incremented value is put into the environment
+to be seen by the next generation.
+This allows tests like:
+.Li .if ${.MAKE.LEVEL} == 0
+to protect things which should only be evaluated in the initial instance of
+.Nm .
+.It Va .MAKE.MAKEFILE_PREFERENCE
+The ordered list of makefile names
+(default
+.Ql Pa makefile ,
+.Ql Pa Makefile )
+that
+.Nm
+will look for.
+.It Va .MAKE.MAKEFILES
+The list of makefiles read by
+.Nm ,
+which is useful for tracking dependencies.
+Each makefile is recorded only once, regardless of the number of times read.
+.It Va .MAKE.MODE
+Processed after reading all makefiles.
+Can affect the mode that
+.Nm
+runs in.
+It can contain a number of keywords:
+.Bl -hang -width ignore-cmd
+.It Pa compat
+Like
+.Fl B ,
+puts
+.Nm
+into "compat" mode.
+.It Pa meta
+Puts
+.Nm
+into "meta" mode, where meta files are created for each target
+to capture the command run, the output generated and if
+.Xr filemon 4
+is available, the system calls which are of interest to
+.Nm .
+The captured output can be very useful when diagnosing errors.
+.It Pa curdirOk= Ar bf
+Normally
+.Nm
+will not create .meta files in
+.Ql Va .CURDIR .
+This can be overridden by setting
+.Va bf
+to a value which represents True.
+.It Pa env
+For debugging, it can be useful to inlcude the environment
+in the .meta file.
+.It Pa verbose
+If in "meta" mode, print a clue about the target being built.
+This is useful if the build is otherwise running silently.
+The message printed the value of:
+.Va .MAKE.META.PREFIX .
+.It Pa ignore-cmd
+Some makefiles have commands which are simply not stable.
+This keyword causes them to be ignored for
+determining whether a target is out of date in "meta" mode.
+See also
+.Ic .NOMETA_CMP .
+.It Pa silent= Ar bf
+If
+.Va bf
+is True, when a .meta file is created, mark the target
+.Ic .SILENT .
+.El
+.It Va .MAKE.META.BAILIWICK
+In "meta" mode, provides a list of prefixes which
+match the directories controlled by
+.Nm .
+If a file that was generated outside of
+.Va .OBJDIR
+but within said bailiwick is missing,
+the current target is considered out-of-date.
+.It Va .MAKE.META.CREATED
+In "meta" mode, this variable contains a list of all the meta files
+updated.
+If not empty, it can be used to trigger processing of
+.Va .MAKE.META.FILES .
+.It Va .MAKE.META.FILES
+In "meta" mode, this variable contains a list of all the meta files
+used (updated or not).
+This list can be used to process the meta files to extract dependency
+information.
+.It Va .MAKE.META.PREFIX
+Defines the message printed for each meta file updated in "meta verbose" mode.
+The default value is:
+.Dl Building ${.TARGET:H:tA}/${.TARGET:T}
+.It Va .MAKEOVERRIDES
+This variable is used to record the names of variables assigned to
+on the command line, so that they may be exported as part of
+.Ql Ev MAKEFLAGS .
+This behaviour can be disabled by assigning an empty value to
+.Ql Va .MAKEOVERRIDES
+within a makefile.
+Extra variables can be exported from a makefile
+by appending their names to
+.Ql Va .MAKEOVERRIDES .
+.Ql Ev MAKEFLAGS
+is re-exported whenever
+.Ql Va .MAKEOVERRIDES
+is modified.
+.It Va .MAKE.PID
+The process-id of
+.Nm .
+.It Va .MAKE.PPID
+The parent process-id of
+.Nm .
+.It Va MAKE_PRINT_VAR_ON_ERROR
+When
+.Nm
+stops due to an error, it prints its name and the value of
+.Ql Va .CURDIR
+as well as the value of any variables named in
+.Ql Va MAKE_PRINT_VAR_ON_ERROR .
+.It Va .newline
+This variable is simply assigned a newline character as its value.
+This allows expansions using the
+.Cm \&:@
+modifier to put a newline between
+iterations of the loop rather than a space.
+For example, the printing of
+.Ql Va MAKE_PRINT_VAR_ON_ERROR
+could be done as ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}.
+.It Va .OBJDIR
+A path to the directory where the targets are built.
+Its value is determined by trying to
+.Xr chdir 2
+to the following directories in order and using the first match:
+.Bl -enum
+.It
+.Ev ${MAKEOBJDIRPREFIX}${.CURDIR}
+.Pp
+(Only if
+.Ql Ev MAKEOBJDIRPREFIX
+is set in the environment or on the command line.)
+.It
+.Ev ${MAKEOBJDIR}
+.Pp
+(Only if
+.Ql Ev MAKEOBJDIR
+is set in the environment or on the command line.)
+.It
+.Ev ${.CURDIR} Ns Pa /obj. Ns Ev ${MACHINE}
+.It
+.Ev ${.CURDIR} Ns Pa /obj
+.It
+.Pa /usr/obj/ Ns Ev ${.CURDIR}
+.It
+.Ev ${.CURDIR}
+.El
+.Pp
+Variable expansion is performed on the value before it's used,
+so expressions such as
+.Dl ${.CURDIR:S,^/usr/src,/var/obj,}
+may be used.
+This is especially useful with
+.Ql Ev MAKEOBJDIR .
+.Pp
+.Ql Va .OBJDIR
+may be modified in the makefile as a global variable.
+In all cases,
+.Nm
+will
+.Xr chdir 2
+to
+.Ql Va .OBJDIR
+and set
+.Ql Ev PWD
+to that directory before executing any targets.
+.
+.It Va .PARSEDIR
+A path to the directory of the current
+.Ql Pa Makefile
+being parsed.
+.It Va .PARSEFILE
+The basename of the current
+.Ql Pa Makefile
+being parsed.
+This variable and
+.Ql Va .PARSEDIR
+are both set only while the
+.Ql Pa Makefiles
+are being parsed.
+If you want to retain their current values, assign them to a variable
+using assignment with expansion:
+.Pq Ql Cm \&:= .
+.It Va .PATH
+A variable that represents the list of directories that
+.Nm
+will search for files.
+The search list should be updated using the target
+.Ql Va .PATH
+rather than the variable.
+.It Ev PWD
+Alternate path to the current directory.
+.Nm
+normally sets
+.Ql Va .CURDIR
+to the canonical path given by
+.Xr getcwd 3 .
+However, if the environment variable
+.Ql Ev PWD
+is set and gives a path to the current directory, then
+.Nm
+sets
+.Ql Va .CURDIR
+to the value of
+.Ql Ev PWD
+instead.
+This behaviour is disabled if
+.Ql Ev MAKEOBJDIRPREFIX
+is set or
+.Ql Ev MAKEOBJDIR
+contains a variable transform.
+.Ql Ev PWD
+is set to the value of
+.Ql Va .OBJDIR
+for all programs which
+.Nm
+executes.
+.It Ev .TARGETS
+The list of targets explicitly specified on the command line, if any.
+.It Ev VPATH
+Colon-separated
+.Pq Dq \&:
+lists of directories that
+.Nm
+will search for files.
+The variable is supported for compatibility with old make programs only,
+use
+.Ql Va .PATH
+instead.
+.El
+.Ss Variable modifiers
+Variable expansion may be modified to select or modify each word of the
+variable (where a
+.Dq word
+is white-space delimited sequence of characters).
+The general format of a variable expansion is as follows:
+.Pp
+.Dl ${variable[:modifier[:...]]}
+.Pp
+Each modifier begins with a colon,
+which may be escaped with a backslash
+.Pq Ql \e .
+.Pp
+A set of modifiers can be specified via a variable, as follows:
+.Pp
+.Dl modifier_variable=modifier[:...]
+.Dl ${variable:${modifier_variable}[:...]}
+.Pp
+In this case the first modifier in the modifier_variable does not
+start with a colon, since that must appear in the referencing
+variable.
+If any of the modifiers in the modifier_variable contain a dollar sign
+.Pq Ql $ ,
+these must be doubled to avoid early expansion.
+.Pp
+The supported modifiers are:
+.Bl -tag -width EEE
+.It Cm \&:E
+Replaces each word in the variable with its suffix.
+.It Cm \&:H
+Replaces each word in the variable with everything but the last component.
+.It Cm \&:M Ns Ar pattern
+Select only those words that match
+.Ar pattern .
+The standard shell wildcard characters
+.Pf ( Ql * ,
+.Ql \&? ,
+and
+.Ql Oo Oc )
+may
+be used.
+The wildcard characters may be escaped with a backslash
+.Pq Ql \e .
+.It Cm \&:N Ns Ar pattern
+This is identical to
+.Ql Cm \&:M ,
+but selects all words which do not match
+.Ar pattern .
+.It Cm \&:O
+Order every word in variable alphabetically.
+To sort words in
+reverse order use the
+.Ql Cm \&:O:[-1..1]
+combination of modifiers.
+.It Cm \&:Ox
+Randomize words in variable.
+The results will be different each time you are referring to the
+modified variable; use the assignment with expansion
+.Pq Ql Cm \&:=
+to prevent such behaviour.
+For example,
+.Bd -literal -offset indent
+LIST= uno due tre quattro
+RANDOM_LIST= ${LIST:Ox}
+STATIC_RANDOM_LIST:= ${LIST:Ox}
+
+all:
+ @echo "${RANDOM_LIST}"
+ @echo "${RANDOM_LIST}"
+ @echo "${STATIC_RANDOM_LIST}"
+ @echo "${STATIC_RANDOM_LIST}"
+.Ed
+may produce output similar to:
+.Bd -literal -offset indent
+quattro due tre uno
+tre due quattro uno
+due uno quattro tre
+due uno quattro tre
+.Ed
+.It Cm \&:Q
+Quotes every shell meta-character in the variable, so that it can be passed
+safely through recursive invocations of
+.Nm .
+.It Cm \&:R
+Replaces each word in the variable with everything but its suffix.
+.It Cm \&:gmtime
+The value is a format string for
+.Xr strftime 3 ,
+using the current
+.Xr gmtime 3 .
+.It Cm \&:hash
+Compute a 32bit hash of the value and encode it as hex digits.
+.It Cm \&:localtime
+The value is a format string for
+.Xr strftime 3 ,
+using the current
+.Xr localtime 3 .
+.It Cm \&:tA
+Attempt to convert variable to an absolute path using
+.Xr realpath 3 ,
+if that fails, the value is unchanged.
+.It Cm \&:tl
+Converts variable to lower-case letters.
+.It Cm \&:ts Ns Ar c
+Words in the variable are normally separated by a space on expansion.
+This modifier sets the separator to the character
+.Ar c .
+If
+.Ar c
+is omitted, then no separator is used.
+The common escapes (including octal numeric codes), work as expected.
+.It Cm \&:tu
+Converts variable to upper-case letters.
+.It Cm \&:tW
+Causes the value to be treated as a single word
+(possibly containing embedded white space).
+See also
+.Ql Cm \&:[*] .
+.It Cm \&:tw
+Causes the value to be treated as a sequence of
+words delimited by white space.
+See also
+.Ql Cm \&:[@] .
+.Sm off
+.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW
+.Sm on
+Modify the first occurrence of
+.Ar old_string
+in the variable's value, replacing it with
+.Ar new_string .
+If a
+.Ql g
+is appended to the last slash of the pattern, all occurrences
+in each word are replaced.
+If a
+.Ql 1
+is appended to the last slash of the pattern, only the first word
+is affected.
+If a
+.Ql W
+is appended to the last slash of the pattern,
+then the value is treated as a single word
+(possibly containing embedded white space).
+If
+.Ar old_string
+begins with a caret
+.Pq Ql ^ ,
+.Ar old_string
+is anchored at the beginning of each word.
+If
+.Ar old_string
+ends with a dollar sign
+.Pq Ql \&$ ,
+it is anchored at the end of each word.
+Inside
+.Ar new_string ,
+an ampersand
+.Pq Ql \*[Am]
+is replaced by
+.Ar old_string
+(without any
+.Ql ^
+or
+.Ql \&$ ) .
+Any character may be used as a delimiter for the parts of the modifier
+string.
+The anchoring, ampersand and delimiter characters may be escaped with a
+backslash
+.Pq Ql \e .
+.Pp
+Variable expansion occurs in the normal fashion inside both
+.Ar old_string
+and
+.Ar new_string
+with the single exception that a backslash is used to prevent the expansion
+of a dollar sign
+.Pq Ql \&$ ,
+not a preceding dollar sign as is usual.
+.Sm off
+.It Cm \&:C No \&/ Ar pattern No \&/ Ar replacement No \&/ Op Cm 1gW
+.Sm on
+The
+.Cm \&:C
+modifier is just like the
+.Cm \&:S
+modifier except that the old and new strings, instead of being
+simple strings, are a regular expression (see
+.Xr regex 3 )
+string
+.Ar pattern
+and an
+.Xr ed 1 Ns \-style
+string
+.Ar replacement .
+Normally, the first occurrence of the pattern
+.Ar pattern
+in each word of the value is substituted with
+.Ar replacement .
+The
+.Ql 1
+modifier causes the substitution to apply to at most one word; the
+.Ql g
+modifier causes the substitution to apply to as many instances of the
+search pattern
+.Ar pattern
+as occur in the word or words it is found in; the
+.Ql W
+modifier causes the value to be treated as a single word
+(possibly containing embedded white space).
+Note that
+.Ql 1
+and
+.Ql g
+are orthogonal; the former specifies whether multiple words are
+potentially affected, the latter whether multiple substitutions can
+potentially occur within each affected word.
+.It Cm \&:T
+Replaces each word in the variable with its last component.
+.It Cm \&:u
+Remove adjacent duplicate words (like
+.Xr uniq 1 ) .
+.Sm off
+.It Cm \&:\&? Ar true_string Cm \&: Ar false_string
+.Sm on
+If the variable name (not its value), when parsed as a .if conditional
+expression, evaluates to true, return as its value the
+.Ar true_string ,
+otherwise return the
+.Ar false_string .
+Since the variable name is used as the expression, \&:\&? must be the
+first modifier after the variable name itself - which will, of course,
+usually contain variable expansions.
+A common error is trying to use expressions like
+.Dl ${NUMBERS:M42:?match:no}
+which actually tests defined(NUMBERS),
+to determine is any words match "42" you need to use something like:
+.Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} .
+.It Ar :old_string=new_string
+This is the
+.At V
+style variable substitution.
+It must be the last modifier specified.
+If
+.Ar old_string
+or
+.Ar new_string
+do not contain the pattern matching character
+.Ar %
+then it is assumed that they are
+anchored at the end of each word, so only suffixes or entire
+words may be replaced.
+Otherwise
+.Ar %
+is the substring of
+.Ar old_string
+to be replaced in
+.Ar new_string .
+.Pp
+Variable expansion occurs in the normal fashion inside both
+.Ar old_string
+and
+.Ar new_string
+with the single exception that a backslash is used to prevent the
+expansion of a dollar sign
+.Pq Ql \&$ ,
+not a preceding dollar sign as is usual.
+.Sm off
+.It Cm \&:@ Ar temp Cm @ Ar string Cm @
+.Sm on
+This is the loop expansion mechanism from the OSF Development
+Environment (ODE) make.
+Unlike
+.Cm \&.for
+loops expansion occurs at the time of
+reference.
+Assign
+.Ar temp
+to each word in the variable and evaluate
+.Ar string .
+The ODE convention is that
+.Ar temp
+should start and end with a period.
+For example.
+.Dl ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
+.Pp
+However a single character varaiable is often more readable:
+.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
+.It Cm \&:U Ns Ar newval
+If the variable is undefined
+.Ar newval
+is the value.
+If the variable is defined, the existing value is returned.
+This is another ODE make feature.
+It is handy for setting per-target CFLAGS for instance:
+.Dl ${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}}
+If a value is only required if the variable is undefined, use:
+.Dl ${VAR:D:Unewval}
+.It Cm \&:D Ns Ar newval
+If the variable is defined
+.Ar newval
+is the value.
+.It Cm \&:L
+The name of the variable is the value.
+.It Cm \&:P
+The path of the node which has the same name as the variable
+is the value.
+If no such node exists or its path is null, then the
+name of the variable is used.
+In order for this modifier to work, the name (node) must at least have
+appeared on the rhs of a dependency.
+.Sm off
+.It Cm \&:\&! Ar cmd Cm \&!
+.Sm on
+The output of running
+.Ar cmd
+is the value.
+.It Cm \&:sh
+If the variable is non-empty it is run as a command and the output
+becomes the new value.
+.It Cm \&::= Ns Ar str
+The variable is assigned the value
+.Ar str
+after substitution.
+This modifier and its variations are useful in
+obscure situations such as wanting to set a variable when shell commands
+are being parsed.
+These assignment modifiers always expand to
+nothing, so if appearing in a rule line by themselves should be
+preceded with something to keep
+.Nm
+happy.
+.Pp
+The
+.Ql Cm \&::
+helps avoid false matches with the
+.At V
+style
+.Cm \&:=
+modifier and since substitution always occurs the
+.Cm \&::=
+form is vaguely appropriate.
+.It Cm \&::?= Ns Ar str
+As for
+.Cm \&::=
+but only if the variable does not already have a value.
+.It Cm \&::+= Ns Ar str
+Append
+.Ar str
+to the variable.
+.It Cm \&::!= Ns Ar cmd
+Assign the output of
+.Ar cmd
+to the variable.
+.It Cm \&:\&[ Ns Ar range Ns Cm \&]
+Selects one or more words from the value,
+or performs other operations related to the way in which the
+value is divided into words.
+.Pp
+Ordinarily, a value is treated as a sequence of words
+delimited by white space.
+Some modifiers suppress this behaviour,
+causing a value to be treated as a single word
+(possibly containing embedded white space).
+An empty value, or a value that consists entirely of white-space,
+is treated as a single word.
+For the purposes of the
+.Ql Cm \&:[]
+modifier, the words are indexed both forwards using positive integers
+(where index 1 represents the first word),
+and backwards using negative integers
+(where index \-1 represents the last word).
+.Pp
+The
+.Ar range
+is subjected to variable expansion, and the expanded result is
+then interpreted as follows:
+.Bl -tag -width index
+.\" :[n]
+.It Ar index
+Selects a single word from the value.
+.\" :[start..end]
+.It Ar start Ns Cm \&.. Ns Ar end
+Selects all words from
+.Ar start
+to
+.Ar end ,
+inclusive.
+For example,
+.Ql Cm \&:[2..-1]
+selects all words from the second word to the last word.
+If
+.Ar start
+is greater than
+.Ar end ,
+then the words are output in reverse order.
+For example,
+.Ql Cm \&:[-1..1]
+selects all the words from last to first.
+.\" :[*]
+.It Cm \&*
+Causes subsequent modifiers to treat the value as a single word
+(possibly containing embedded white space).
+Analogous to the effect of
+\&"$*\&"
+in Bourne shell.
+.\" :[0]
+.It 0
+Means the same as
+.Ql Cm \&:[*] .
+.\" :[*]
+.It Cm \&@
+Causes subsequent modifiers to treat the value as a sequence of words
+delimited by white space.
+Analogous to the effect of
+\&"$@\&"
+in Bourne shell.
+.\" :[#]
+.It Cm \&#
+Returns the number of words in the value.
+.El \" :[range]
+.El
+.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS
+Makefile inclusion, conditional structures and for loops reminiscent
+of the C programming language are provided in
+.Nm .
+All such structures are identified by a line beginning with a single
+dot
+.Pq Ql \&.
+character.
+Files are included with either
+.Cm \&.include Aq Ar file
+or
+.Cm \&.include Pf \*q Ar file Ns \*q .
+Variables between the angle brackets or double quotes are expanded
+to form the file name.
+If angle brackets are used, the included makefile is expected to be in
+the system makefile directory.
+If double quotes are used, the including makefile's directory and any
+directories specified using the
+.Fl I
+option are searched before the system
+makefile directory.
+For compatibility with other versions of
+.Nm
+.Ql include file ...
+is also accepted.
+If the include statement is written as
+.Cm .-include
+or as
+.Cm .sinclude
+then errors locating and/or opening include files are ignored.
+.Pp
+Conditional expressions are also preceded by a single dot as the first
+character of a line.
+The possible conditionals are as follows:
+.Bl -tag -width Ds
+.It Ic .error Ar message
+The message is printed along with the name of the makefile and line number,
+then
+.Nm
+will exit.
+.It Ic .export Ar variable ...
+Export the specified global variable.
+If no variable list is provided, all globals are exported
+except for internal variables (those that start with
+.Ql \&. ) .
+This is not affected by the
+.Fl X
+flag, so should be used with caution.
+For compatibility with other
+.Nm
+programs
+.Ql export variable=value
+is also accepted.
+.Pp
+Appending a variable name to
+.Va .MAKE.EXPORTED
+is equivalent to exporting a variable.
+.It Ic .export-env Ar variable ...
+The same as
+.Ql .export ,
+except that the variable is not appended to
+.Va .MAKE.EXPORTED .
+This allows exporting a value to the environment which is different from that
+used by
+.Nm
+internally.
+.It Ic .info Ar message
+The message is printed along with the name of the makefile and line number.
+.It Ic .undef Ar variable
+Un-define the specified global variable.
+Only global variables may be un-defined.
+.It Ic .unexport Ar variable ...
+The opposite of
+.Ql .export .
+The specified global
+.Va variable
+will be removed from
+.Va .MAKE.EXPORTED .
+If no variable list is provided, all globals are unexported,
+and
+.Va .MAKE.EXPORTED
+deleted.
+.It Ic .unexport-env
+Unexport all globals previously exported and
+clear the environment inherited from the parent.
+This operation will cause a memory leak of the original environment,
+so should be used sparingly.
+Testing for
+.Va .MAKE.LEVEL
+being 0, would make sense.
+Also note that any variables which originated in the parent environment
+should be explicitly preserved if desired.
+For example:
+.Bd -literal -offset indent
+.Li .if ${.MAKE.LEVEL} == 0
+PATH := ${PATH}
+.Li .unexport-env
+.Li .export PATH
+.Li .endif
+.Pp
+.Ed
+Would result in an environment containing only
+.Ql Ev PATH ,
+which is the minimal useful environment.
+Actually
+.Ql Ev .MAKE.LEVEL
+will also be pushed into the new environment.
+.It Ic .warning Ar message
+The message prefixed by
+.Ql Pa warning:
+is printed along with the name of the makefile and line number.
+.It Ic \&.if Oo \&! Oc Ns Ar expression Op Ar operator expression ...
+Test the value of an expression.
+.It Ic .ifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
+Test the value of a variable.
+.It Ic .ifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
+Test the value of a variable.
+.It Ic .ifmake Oo \&! Oc Ns Ar target Op Ar operator target ...
+Test the target being built.
+.It Ic .ifnmake Oo \&! Ns Oc Ar target Op Ar operator target ...
+Test the target being built.
+.It Ic .else
+Reverse the sense of the last conditional.
+.It Ic .elif Oo \&! Ns Oc Ar expression Op Ar operator expression ...
+A combination of
+.Ql Ic .else
+followed by
+.Ql Ic .if .
+.It Ic .elifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
+A combination of
+.Ql Ic .else
+followed by
+.Ql Ic .ifdef .
+.It Ic .elifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
+A combination of
+.Ql Ic .else
+followed by
+.Ql Ic .ifndef .
+.It Ic .elifmake Oo \&! Oc Ns Ar target Op Ar operator target ...
+A combination of
+.Ql Ic .else
+followed by
+.Ql Ic .ifmake .
+.It Ic .elifnmake Oo \&! Oc Ns Ar target Op Ar operator target ...
+A combination of
+.Ql Ic .else
+followed by
+.Ql Ic .ifnmake .
+.It Ic .endif
+End the body of the conditional.
+.El
+.Pp
+The
+.Ar operator
+may be any one of the following:
+.Bl -tag -width "Cm XX"
+.It Cm \&|\&|
+Logical OR.
+.It Cm \&\*[Am]\*[Am]
+Logical
+.Tn AND ;
+of higher precedence than
+.Dq \&|\&| .
+.El
+.Pp
+As in C,
+.Nm
+will only evaluate a conditional as far as is necessary to determine
+its value.
+Parentheses may be used to change the order of evaluation.
+The boolean operator
+.Ql Ic \&!
+may be used to logically negate an entire
+conditional.
+It is of higher precedence than
+.Ql Ic \&\*[Am]\*[Am] .
+.Pp
+The value of
+.Ar expression
+may be any of the following:
+.Bl -tag -width defined
+.It Ic defined
+Takes a variable name as an argument and evaluates to true if the variable
+has been defined.
+.It Ic make
+Takes a target name as an argument and evaluates to true if the target
+was specified as part of
+.Nm Ns 's
+command line or was declared the default target (either implicitly or
+explicitly, see
+.Va .MAIN )
+before the line containing the conditional.
+.It Ic empty
+Takes a variable, with possible modifiers, and evaluates to true if
+the expansion of the variable would result in an empty string.
+.It Ic exists
+Takes a file name as an argument and evaluates to true if the file exists.
+The file is searched for on the system search path (see
+.Va .PATH ) .
+.It Ic target
+Takes a target name as an argument and evaluates to true if the target
+has been defined.
+.It Ic commands
+Takes a target name as an argument and evaluates to true if the target
+has been defined and has commands associated with it.
+.El
+.Pp
+.Ar Expression
+may also be an arithmetic or string comparison.
+Variable expansion is
+performed on both sides of the comparison, after which the integral
+values are compared.
+A value is interpreted as hexadecimal if it is
+preceded by 0x, otherwise it is decimal; octal numbers are not supported.
+The standard C relational operators are all supported.
+If after
+variable expansion, either the left or right hand side of a
+.Ql Ic ==
+or
+.Ql Ic "!="
+operator is not an integral value, then
+string comparison is performed between the expanded
+variables.
+If no relational operator is given, it is assumed that the expanded
+variable is being compared against 0 or an empty string in the case
+of a string comparison.
+.Pp
+When
+.Nm
+is evaluating one of these conditional expressions, and it encounters
+a (white-space separated) word it doesn't recognize, either the
+.Dq make
+or
+.Dq defined
+expression is applied to it, depending on the form of the conditional.
+If the form is
+.Ql Ic .ifdef ,
+.Ql Ic .ifndef ,
+or
+.Ql Ic .if
+the
+.Dq defined
+expression is applied.
+Similarly, if the form is
+.Ql Ic .ifmake
+or
+.Ql Ic .ifnmake , the
+.Dq make
+expression is applied.
+.Pp
+If the conditional evaluates to true the parsing of the makefile continues
+as before.
+If it evaluates to false, the following lines are skipped.
+In both cases this continues until a
+.Ql Ic .else
+or
+.Ql Ic .endif
+is found.
+.Pp
+For loops are typically used to apply a set of rules to a list of files.
+The syntax of a for loop is:
+.Pp
+.Bl -tag -compact -width Ds
+.It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression
+.It Aq make-rules
+.It Ic \&.endfor
+.El
+.Pp
+After the for
+.Ic expression
+is evaluated, it is split into words.
+On each iteration of the loop, one word is taken and assigned to each
+.Ic variable ,
+in order, and these
+.Ic variables
+are substituted into the
+.Ic make-rules
+inside the body of the for loop.
+The number of words must come out even; that is, if there are three
+iteration variables, the number of words provided must be a multiple
+of three.
+.Sh COMMENTS
+Comments begin with a hash
+.Pq Ql \&#
+character, anywhere but in a shell
+command line, and continue to the end of an unescaped new line.
+.Sh SPECIAL SOURCES (ATTRIBUTES)
+.Bl -tag -width .IGNOREx
+.It Ic .EXEC
+Target is never out of date, but always execute commands anyway.
+.It Ic .IGNORE
+Ignore any errors from the commands associated with this target, exactly
+as if they all were preceded by a dash
+.Pq Ql \- .
+.\" .It Ic .INVISIBLE
+.\" XXX
+.\" .It Ic .JOIN
+.\" XXX
+.It Ic .MADE
+Mark all sources of this target as being up-to-date.
+.It Ic .MAKE
+Execute the commands associated with this target even if the
+.Fl n
+or
+.Fl t
+options were specified.
+Normally used to mark recursive
+.Nm Ns 's .
+.It Ic .META
+Create a meta file for the target, even if it is flagged as
+.Ic .PHONY ,
+.Ic .MAKE ,
+or
+.Ic .SPECIAL .
+Usage in conjunction with
+.Ic .MAKE
+is the most likely case.
+In "meta" mode, the target is out-of-date if the meta file is missing.
+.It Ic .NOMETA
+Do not create a meta file for the target.
+Meta files are also not created for
+.Ic .PHONY ,
+.Ic .MAKE ,
+or
+.Ic .SPECIAL
+targets.
+.It Ic .NOMETA_CMP
+Ignore differences in commands when deciding if target is out of date.
+This is useful if the command contains a value which always changes.
+If the number of commands change, though, the target will still be out of date.
+.It Ic .NOPATH
+Do not search for the target in the directories specified by
+.Ic .PATH .
+.It Ic .NOTMAIN
+Normally
+.Nm
+selects the first target it encounters as the default target to be built
+if no target was specified.
+This source prevents this target from being selected.
+.It Ic .OPTIONAL
+If a target is marked with this attribute and
+.Nm
+can't figure out how to create it, it will ignore this fact and assume
+the file isn't needed or already exists.
+.It Ic .PHONY
+The target does not
+correspond to an actual file; it is always considered to be out of date,
+and will not be created with the
+.Fl t
+option.
+Suffix-transformation rules are not applied to
+.Ic .PHONY
+targets.
+.It Ic .PRECIOUS
+When
+.Nm
+is interrupted, it normally removes any partially made targets.
+This source prevents the target from being removed.
+.It Ic .RECURSIVE
+Synonym for
+.Ic .MAKE .
+.It Ic .SILENT
+Do not echo any of the commands associated with this target, exactly
+as if they all were preceded by an at sign
+.Pq Ql @ .
+.It Ic .USE
+Turn the target into
+.Nm Ns 's
+version of a macro.
+When the target is used as a source for another target, the other target
+acquires the commands, sources, and attributes (except for
+.Ic .USE )
+of the
+source.
+If the target already has commands, the
+.Ic .USE
+target's commands are appended
+to them.
+.It Ic .USEBEFORE
+Exactly like
+.Ic .USE ,
+but prepend the
+.Ic .USEBEFORE
+target commands to the target.
+.It Ic .WAIT
+If
+.Ic .WAIT
+appears in a dependency line, the sources that precede it are
+made before the sources that succeed it in the line.
+Since the dependents of files are not made until the file itself
+could be made, this also stops the dependents being built unless they
+are needed for another branch of the dependency tree.
+So given:
+.Bd -literal
+x: a .WAIT b
+ echo x
+a:
+ echo a
+b: b1
+ echo b
+b1:
+ echo b1
+
+.Ed
+the output is always
+.Ql a ,
+.Ql b1 ,
+.Ql b ,
+.Ql x .
+.br
+The ordering imposed by
+.Ic .WAIT
+is only relevant for parallel makes.
+.El
+.Sh SPECIAL TARGETS
+Special targets may not be included with other targets, i.e. they must be
+the only target specified.
+.Bl -tag -width .BEGINx
+.It Ic .BEGIN
+Any command lines attached to this target are executed before anything
+else is done.
+.It Ic .DEFAULT
+This is sort of a
+.Ic .USE
+rule for any target (that was used only as a
+source) that
+.Nm
+can't figure out any other way to create.
+Only the shell script is used.
+The
+.Ic .IMPSRC
+variable of a target that inherits
+.Ic .DEFAULT Ns 's
+commands is set
+to the target's own name.
+.It Ic .END
+Any command lines attached to this target are executed after everything
+else is done.
+.It Ic .ERROR
+Any command lines attached to this target are executed when another target fails.
+The
+.Ic .ERROR_TARGET
+variable is set to the target that failed.
+See also
+.Ic MAKE_PRINT_VAR_ON_ERROR .
+.It Ic .IGNORE
+Mark each of the sources with the
+.Ic .IGNORE
+attribute.
+If no sources are specified, this is the equivalent of specifying the
+.Fl i
+option.
+.It Ic .INTERRUPT
+If
+.Nm
+is interrupted, the commands for this target will be executed.
+.It Ic .MAIN
+If no target is specified when
+.Nm
+is invoked, this target will be built.
+.It Ic .MAKEFLAGS
+This target provides a way to specify flags for
+.Nm
+when the makefile is used.
+The flags are as if typed to the shell, though the
+.Fl f
+option will have
+no effect.
+.\" XXX: NOT YET!!!!
+.\" .It Ic .NOTPARALLEL
+.\" The named targets are executed in non parallel mode.
+.\" If no targets are
+.\" specified, then all targets are executed in non parallel mode.
+.It Ic .NOPATH
+Apply the
+.Ic .NOPATH
+attribute to any specified sources.
+.It Ic .NOTPARALLEL
+Disable parallel mode.
+.It Ic .NO_PARALLEL
+Synonym for
+.Ic .NOTPARALLEL ,
+for compatibility with other pmake variants.
+.It Ic .ORDER
+The named targets are made in sequence.
+This ordering does not add targets to the list of targets to be made.
+Since the dependents of a target do not get built until the target itself
+could be built, unless
+.Ql a
+is built by another part of the dependency graph,
+the following is a dependency loop:
+.Bd -literal
+\&.ORDER: b a
+b: a
+.Ed
+.Pp
+The ordering imposed by
+.Ic .ORDER
+is only relevant for parallel makes.
+.\" XXX: NOT YET!!!!
+.\" .It Ic .PARALLEL
+.\" The named targets are executed in parallel mode.
+.\" If no targets are
+.\" specified, then all targets are executed in parallel mode.
+.It Ic .PATH
+The sources are directories which are to be searched for files not
+found in the current directory.
+If no sources are specified, any previously specified directories are
+deleted.
+If the source is the special
+.Ic .DOTLAST
+target, then the current working
+directory is searched last.
+.It Ic .PHONY
+Apply the
+.Ic .PHONY
+attribute to any specified sources.
+.It Ic .PRECIOUS
+Apply the
+.Ic .PRECIOUS
+attribute to any specified sources.
+If no sources are specified, the
+.Ic .PRECIOUS
+attribute is applied to every
+target in the file.
+.It Ic .SHELL
+Sets the shell that
+.Nm
+will use to execute commands.
+The sources are a set of
+.Ar field=value
+pairs.
+.Bl -tag -width hasErrCtls
+.It Ar name
+This is the minimal specification, used to select one of the builtin
+shell specs;
+.Ar sh ,
+.Ar ksh ,
+and
+.Ar csh .
+.It Ar path
+Specifies the path to the shell.
+.It Ar hasErrCtl
+Indicates whether the shell supports exit on error.
+.It Ar check
+The command to turn on error checking.
+.It Ar ignore
+The command to disable error checking.
+.It Ar echo
+The command to turn on echoing of commands executed.
+.It Ar quiet
+The command to turn off echoing of commands executed.
+.It Ar filter
+The output to filter after issuing the
+.Ar quiet
+command.
+It is typically identical to
+.Ar quiet .
+.It Ar errFlag
+The flag to pass the shell to enable error checking.
+.It Ar echoFlag
+The flag to pass the shell to enable command echoing.
+.It Ar newline
+The string literal to pass the shell that results in a single newline
+character when used outside of any quoting characters.
+.El
+Example:
+.Bd -literal
+\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e
+ check="set \-e" ignore="set +e" \e
+ echo="set \-v" quiet="set +v" filter="set +v" \e
+ echoFlag=v errFlag=e newline="'\en'"
+.Ed
+.It Ic .SILENT
+Apply the
+.Ic .SILENT
+attribute to any specified sources.
+If no sources are specified, the
+.Ic .SILENT
+attribute is applied to every
+command in the file.
+.It Ic .SUFFIXES
+Each source specifies a suffix to
+.Nm .
+If no sources are specified, any previously specified suffixes are deleted.
+It allows the creation of suffix-transformation rules.
+.Pp
+Example:
+.Bd -literal
+\&.SUFFIXES: .o
+\&.c.o:
+ cc \-o ${.TARGET} \-c ${.IMPSRC}
+.Ed
+.El
+.Sh ENVIRONMENT
+.Nm
+uses the following environment variables, if they exist:
+.Ev MACHINE ,
+.Ev MACHINE_ARCH ,
+.Ev MAKE ,
+.Ev MAKEFLAGS ,
+.Ev MAKEOBJDIR ,
+.Ev MAKEOBJDIRPREFIX ,
+.Ev MAKESYSPATH ,
+.Ev PWD ,
+and
+.Ev TMPDIR .
+.Pp
+.Ev MAKEOBJDIRPREFIX
+and
+.Ev MAKEOBJDIR
+may only be set in the environment or on the command line to
+.Nm
+and not as makefile variables;
+see the description of
+.Ql Va .OBJDIR
+for more details.
+.Sh FILES
+.Bl -tag -width /usr/share/mk -compact
+.It .depend
+list of dependencies
+.It Makefile
+list of dependencies
+.It makefile
+list of dependencies
+.It sys.mk
+system makefile
+.It /usr/share/mk
+system makefile directory
+.El
+.Sh COMPATIBILITY
+The basic make syntax is compatible between different versions of make,
+however the special variables, variable modifiers and conditionals are not.
+.Pp
+The way that parallel makes are scheduled changed in
+.Nx 4.0
+so that .ORDER and .WAIT apply recursively to the dependent nodes.
+The algorithms used may change again in the future.
+.Pp
+The way that .for loop variables are substituted changed after
+.Nx 5.0
+so that they still appear to be variable expansions.
+In particular this stops them being treated as syntax, and removes some
+obscure problems using them in .if statements.
+.Pp
+Unlike other
+.Nm
+programs, this implementation by default executes all commands for a given
+target using a single shell invocation.
+This is done for both efficiency and to simplify error handling in remote
+command invocations.
+Typically this is transparent to the user, unless the target commands change
+the current working directory using
+.Dq cd
+or
+.Dq chdir .
+To be compatible with Makefiles that do this, one can use
+.Fl B
+to disable this behavior.
+.Sh SEE ALSO
+.Xr mkdep 1
+.Sh HISTORY
+A
+.Nm
+command appeared in
+.At v7 .
+This
+.Nm
+implementation is based on Adam De Boor's pmake program which was written
+for Sprint at Berkeley.
+It was designed to be a parallel distributed make running jobs on different
+machines using a daemon called
+.Dq customs .
+.Sh BUGS
+The
+.Nm
+syntax is difficult to parse without actually acting of the data.
+For instance finding the end of a variable use should involve scanning each
+the modifiers using the correct terminator for each field.
+In many places
+.Nm
+just counts {} and () in order to find the end of a variable expansion.
+.Pp
+There is no way of escaping a space character in a filename.
diff --git a/external/bsd/bmake/dist/make.c b/external/bsd/bmake/dist/make.c
new file mode 100644
index 0000000..4fa4ff9
--- /dev/null
+++ b/external/bsd/bmake/dist/make.c
@@ -0,0 +1,1561 @@
+/* $NetBSD: make.c,v 1.87 2012/06/12 19:21:51 joerg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: make.c,v 1.87 2012/06/12 19:21:51 joerg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93";
+#else
+__RCSID("$NetBSD: make.c,v 1.87 2012/06/12 19:21:51 joerg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * make.c --
+ * The functions which perform the examination of targets and
+ * their suitability for creation
+ *
+ * Interface:
+ * Make_Run Initialize things for the module and recreate
+ * whatever needs recreating. Returns TRUE if
+ * work was (or would have been) done and FALSE
+ * otherwise.
+ *
+ * Make_Update Update all parents of a given child. Performs
+ * various bookkeeping chores like the updating
+ * of the cmgn field of the parent, filling
+ * of the IMPSRC context variable, etc. It will
+ * place the parent on the toBeMade queue if it
+ * should be.
+ *
+ * Make_TimeStamp Function to set the parent's cmgn field
+ * based on a child's modification time.
+ *
+ * Make_DoAllVar Set up the various local variables for a
+ * target, including the .ALLSRC variable, making
+ * sure that any variable that needs to exist
+ * at the very least has the empty value.
+ *
+ * Make_OODate Determine if a target is out-of-date.
+ *
+ * Make_HandleUse See if a child is a .USE node for a parent
+ * and perform the .USE actions if so.
+ *
+ * Make_ExpandUse Expand .USE nodes
+ */
+
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+#include "job.h"
+
+static unsigned int checked = 1;/* Sequence # to detect recursion */
+static Lst toBeMade; /* The current fringe of the graph. These
+ * are nodes which await examination by
+ * MakeOODate. It is added to by
+ * Make_Update and subtracted from by
+ * MakeStartJobs */
+
+static int MakeAddChild(void *, void *);
+static int MakeFindChild(void *, void *);
+static int MakeUnmark(void *, void *);
+static int MakeAddAllSrc(void *, void *);
+static int MakeTimeStamp(void *, void *);
+static int MakeHandleUse(void *, void *);
+static Boolean MakeStartJobs(void);
+static int MakePrintStatus(void *, void *);
+static int MakeCheckOrder(void *, void *);
+static int MakeBuildChild(void *, void *);
+static int MakeBuildParent(void *, void *);
+
+MAKE_ATTR_DEAD static void
+make_abort(GNode *gn, int line)
+{
+ static int two = 2;
+
+ fprintf(debug_file, "make_abort from line %d\n", line);
+ Targ_PrintNode(gn, &two);
+ Lst_ForEach(toBeMade, Targ_PrintNode, &two);
+ Targ_PrintGraph(3);
+ abort();
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Make_TimeStamp --
+ * Set the cmgn field of a parent node based on the mtime stamp in its
+ * child. Called from MakeOODate via Lst_ForEach.
+ *
+ * Input:
+ * pgn the current parent
+ * cgn the child we've just examined
+ *
+ * Results:
+ * Always returns 0.
+ *
+ * Side Effects:
+ * The cmgn of the parent node will be changed if the mtime
+ * field of the child is greater than it.
+ *-----------------------------------------------------------------------
+ */
+int
+Make_TimeStamp(GNode *pgn, GNode *cgn)
+{
+ if (pgn->cmgn == NULL || cgn->mtime > pgn->cmgn->mtime) {
+ pgn->cmgn = cgn;
+ }
+ return (0);
+}
+
+/*
+ * Input:
+ * pgn the current parent
+ * cgn the child we've just examined
+ *
+ */
+static int
+MakeTimeStamp(void *pgn, void *cgn)
+{
+ return Make_TimeStamp((GNode *)pgn, (GNode *)cgn);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Make_OODate --
+ * See if a given node is out of date with respect to its sources.
+ * Used by Make_Run when deciding which nodes to place on the
+ * toBeMade queue initially and by Make_Update to screen out USE and
+ * EXEC nodes. In the latter case, however, any other sort of node
+ * must be considered out-of-date since at least one of its children
+ * will have been recreated.
+ *
+ * Input:
+ * gn the node to check
+ *
+ * Results:
+ * TRUE if the node is out of date. FALSE otherwise.
+ *
+ * Side Effects:
+ * The mtime field of the node and the cmgn field of its parents
+ * will/may be changed.
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Make_OODate(GNode *gn)
+{
+ Boolean oodate;
+
+ /*
+ * Certain types of targets needn't even be sought as their datedness
+ * doesn't depend on their modification time...
+ */
+ if ((gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC)) == 0) {
+ (void)Dir_MTime(gn, 1);
+ if (DEBUG(MAKE)) {
+ if (gn->mtime != 0) {
+ fprintf(debug_file, "modified %s...", Targ_FmtTime(gn->mtime));
+ } else {
+ fprintf(debug_file, "non-existent...");
+ }
+ }
+ }
+
+ /*
+ * A target is remade in one of the following circumstances:
+ * its modification time is smaller than that of its youngest child
+ * and it would actually be run (has commands or type OP_NOP)
+ * it's the object of a force operator
+ * it has no children, was on the lhs of an operator and doesn't exist
+ * already.
+ *
+ * Libraries are only considered out-of-date if the archive module says
+ * they are.
+ *
+ * These weird rules are brought to you by Backward-Compatibility and
+ * the strange people who wrote 'Make'.
+ */
+ if (gn->type & (OP_USE|OP_USEBEFORE)) {
+ /*
+ * If the node is a USE node it is *never* out of date
+ * no matter *what*.
+ */
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, ".USE node...");
+ }
+ oodate = FALSE;
+ } else if ((gn->type & OP_LIB) &&
+ ((gn->mtime==0) || Arch_IsLib(gn))) {
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, "library...");
+ }
+
+ /*
+ * always out of date if no children and :: target
+ * or non-existent.
+ */
+ oodate = (gn->mtime == 0 || Arch_LibOODate(gn) ||
+ (gn->cmgn == NULL && (gn->type & OP_DOUBLEDEP)));
+ } else if (gn->type & OP_JOIN) {
+ /*
+ * A target with the .JOIN attribute is only considered
+ * out-of-date if any of its children was out-of-date.
+ */
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, ".JOIN node...");
+ }
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, "source %smade...", gn->flags & CHILDMADE ? "" : "not ");
+ }
+ oodate = (gn->flags & CHILDMADE) ? TRUE : FALSE;
+ } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) {
+ /*
+ * A node which is the object of the force (!) operator or which has
+ * the .EXEC attribute is always considered out-of-date.
+ */
+ if (DEBUG(MAKE)) {
+ if (gn->type & OP_FORCE) {
+ fprintf(debug_file, "! operator...");
+ } else if (gn->type & OP_PHONY) {
+ fprintf(debug_file, ".PHONY node...");
+ } else {
+ fprintf(debug_file, ".EXEC node...");
+ }
+ }
+ oodate = TRUE;
+ } else if ((gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime) ||
+ (gn->cmgn == NULL &&
+ ((gn->mtime == 0 && !(gn->type & OP_OPTIONAL))
+ || gn->type & OP_DOUBLEDEP)))
+ {
+ /*
+ * A node whose modification time is less than that of its
+ * youngest child or that has no children (cmgn == NULL) and
+ * either doesn't exist (mtime == 0) and it isn't optional
+ * or was the object of a * :: operator is out-of-date.
+ * Why? Because that's the way Make does it.
+ */
+ if (DEBUG(MAKE)) {
+ if (gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime) {
+ fprintf(debug_file, "modified before source %s...",
+ gn->cmgn->path);
+ } else if (gn->mtime == 0) {
+ fprintf(debug_file, "non-existent and no sources...");
+ } else {
+ fprintf(debug_file, ":: operator and no sources...");
+ }
+ }
+ oodate = TRUE;
+ } else {
+ /*
+ * When a non-existing child with no sources
+ * (such as a typically used FORCE source) has been made and
+ * the target of the child (usually a directory) has the same
+ * timestamp as the timestamp just given to the non-existing child
+ * after it was considered made.
+ */
+ if (DEBUG(MAKE)) {
+ if (gn->flags & FORCE)
+ fprintf(debug_file, "non existing child...");
+ }
+ oodate = (gn->flags & FORCE) ? TRUE : FALSE;
+ }
+
+#ifdef USE_META
+ if (useMeta) {
+ oodate = meta_oodate(gn, oodate);
+ }
+#endif
+
+ /*
+ * If the target isn't out-of-date, the parents need to know its
+ * modification time. Note that targets that appear to be out-of-date
+ * but aren't, because they have no commands and aren't of type OP_NOP,
+ * have their mtime stay below their children's mtime to keep parents from
+ * thinking they're out-of-date.
+ */
+ if (!oodate) {
+ Lst_ForEach(gn->parents, MakeTimeStamp, gn);
+ }
+
+ return (oodate);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * MakeAddChild --
+ * Function used by Make_Run to add a child to the list l.
+ * It will only add the child if its make field is FALSE.
+ *
+ * Input:
+ * gnp the node to add
+ * lp the list to which to add it
+ *
+ * Results:
+ * Always returns 0
+ *
+ * Side Effects:
+ * The given list is extended
+ *-----------------------------------------------------------------------
+ */
+static int
+MakeAddChild(void *gnp, void *lp)
+{
+ GNode *gn = (GNode *)gnp;
+ Lst l = (Lst) lp;
+
+ if ((gn->flags & REMAKE) == 0 && !(gn->type & (OP_USE|OP_USEBEFORE))) {
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "MakeAddChild: need to examine %s%s\n",
+ gn->name, gn->cohort_num);
+ (void)Lst_EnQueue(l, gn);
+ }
+ return (0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * MakeFindChild --
+ * Function used by Make_Run to find the pathname of a child
+ * that was already made.
+ *
+ * Input:
+ * gnp the node to find
+ *
+ * Results:
+ * Always returns 0
+ *
+ * Side Effects:
+ * The path and mtime of the node and the cmgn of the parent are
+ * updated; the unmade children count of the parent is decremented.
+ *-----------------------------------------------------------------------
+ */
+static int
+MakeFindChild(void *gnp, void *pgnp)
+{
+ GNode *gn = (GNode *)gnp;
+ GNode *pgn = (GNode *)pgnp;
+
+ (void)Dir_MTime(gn, 0);
+ Make_TimeStamp(pgn, gn);
+ pgn->unmade--;
+
+ return (0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Make_HandleUse --
+ * Function called by Make_Run and SuffApplyTransform on the downward
+ * pass to handle .USE and transformation nodes. It implements the
+ * .USE and transformation functionality by copying the node's commands,
+ * type flags and children to the parent node.
+ *
+ * A .USE node is much like an explicit transformation rule, except
+ * its commands are always added to the target node, even if the
+ * target already has commands.
+ *
+ * Input:
+ * cgn The .USE node
+ * pgn The target of the .USE node
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * Children and commands may be added to the parent and the parent's
+ * type may be changed.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Make_HandleUse(GNode *cgn, GNode *pgn)
+{
+ LstNode ln; /* An element in the children list */
+
+#ifdef DEBUG_SRC
+ if ((cgn->type & (OP_USE|OP_USEBEFORE|OP_TRANSFORM)) == 0) {
+ fprintf(debug_file, "Make_HandleUse: called for plain node %s\n", cgn->name);
+ return;
+ }
+#endif
+
+ if ((cgn->type & (OP_USE|OP_USEBEFORE)) || Lst_IsEmpty(pgn->commands)) {
+ if (cgn->type & OP_USEBEFORE) {
+ /*
+ * .USEBEFORE --
+ * prepend the child's commands to the parent.
+ */
+ Lst cmds = pgn->commands;
+ pgn->commands = Lst_Duplicate(cgn->commands, NULL);
+ (void)Lst_Concat(pgn->commands, cmds, LST_CONCNEW);
+ Lst_Destroy(cmds, NULL);
+ } else {
+ /*
+ * .USE or target has no commands --
+ * append the child's commands to the parent.
+ */
+ (void)Lst_Concat(pgn->commands, cgn->commands, LST_CONCNEW);
+ }
+ }
+
+ if (Lst_Open(cgn->children) == SUCCESS) {
+ while ((ln = Lst_Next(cgn->children)) != NULL) {
+ GNode *tgn, *gn = (GNode *)Lst_Datum(ln);
+
+ /*
+ * Expand variables in the .USE node's name
+ * and save the unexpanded form.
+ * We don't need to do this for commands.
+ * They get expanded properly when we execute.
+ */
+ if (gn->uname == NULL) {
+ gn->uname = gn->name;
+ } else {
+ if (gn->name)
+ free(gn->name);
+ }
+ gn->name = Var_Subst(NULL, gn->uname, pgn, FALSE);
+ if (gn->name && gn->uname && strcmp(gn->name, gn->uname) != 0) {
+ /* See if we have a target for this node. */
+ tgn = Targ_FindNode(gn->name, TARG_NOCREATE);
+ if (tgn != NULL)
+ gn = tgn;
+ }
+
+ (void)Lst_AtEnd(pgn->children, gn);
+ (void)Lst_AtEnd(gn->parents, pgn);
+ pgn->unmade += 1;
+ }
+ Lst_Close(cgn->children);
+ }
+
+ pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_USEBEFORE|OP_TRANSFORM);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * MakeHandleUse --
+ * Callback function for Lst_ForEach, used by Make_Run on the downward
+ * pass to handle .USE nodes. Should be called before the children
+ * are enqueued to be looked at by MakeAddChild.
+ * This function calls Make_HandleUse to copy the .USE node's commands,
+ * type flags and children to the parent node.
+ *
+ * Input:
+ * cgnp the child we've just examined
+ * pgnp the current parent
+ *
+ * Results:
+ * returns 0.
+ *
+ * Side Effects:
+ * After expansion, .USE child nodes are removed from the parent
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+MakeHandleUse(void *cgnp, void *pgnp)
+{
+ GNode *cgn = (GNode *)cgnp;
+ GNode *pgn = (GNode *)pgnp;
+ LstNode ln; /* An element in the children list */
+ int unmarked;
+
+ unmarked = ((cgn->type & OP_MARK) == 0);
+ cgn->type |= OP_MARK;
+
+ if ((cgn->type & (OP_USE|OP_USEBEFORE)) == 0)
+ return (0);
+
+ if (unmarked)
+ Make_HandleUse(cgn, pgn);
+
+ /*
+ * This child node is now "made", so we decrement the count of
+ * unmade children in the parent... We also remove the child
+ * from the parent's list to accurately reflect the number of decent
+ * children the parent has. This is used by Make_Run to decide
+ * whether to queue the parent or examine its children...
+ */
+ if ((ln = Lst_Member(pgn->children, cgn)) != NULL) {
+ Lst_Remove(pgn->children, ln);
+ pgn->unmade--;
+ }
+ return (0);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Make_Recheck --
+ * Check the modification time of a gnode, and update it as described
+ * in the comments below.
+ *
+ * Results:
+ * returns 0 if the gnode does not exist, or it's filesystem
+ * time if it does.
+ *
+ * Side Effects:
+ * the gnode's modification time and path name are affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+time_t
+Make_Recheck(GNode *gn)
+{
+ time_t mtime = Dir_MTime(gn, 1);
+
+#ifndef RECHECK
+ /*
+ * We can't re-stat the thing, but we can at least take care of rules
+ * where a target depends on a source that actually creates the
+ * target, but only if it has changed, e.g.
+ *
+ * parse.h : parse.o
+ *
+ * parse.o : parse.y
+ * yacc -d parse.y
+ * cc -c y.tab.c
+ * mv y.tab.o parse.o
+ * cmp -s y.tab.h parse.h || mv y.tab.h parse.h
+ *
+ * In this case, if the definitions produced by yacc haven't changed
+ * from before, parse.h won't have been updated and gn->mtime will
+ * reflect the current modification time for parse.h. This is
+ * something of a kludge, I admit, but it's a useful one..
+ * XXX: People like to use a rule like
+ *
+ * FRC:
+ *
+ * To force things that depend on FRC to be made, so we have to
+ * check for gn->children being empty as well...
+ */
+ if (!Lst_IsEmpty(gn->commands) || Lst_IsEmpty(gn->children)) {
+ gn->mtime = now;
+ }
+#else
+ /*
+ * This is what Make does and it's actually a good thing, as it
+ * allows rules like
+ *
+ * cmp -s y.tab.h parse.h || cp y.tab.h parse.h
+ *
+ * to function as intended. Unfortunately, thanks to the stateless
+ * nature of NFS (by which I mean the loose coupling of two clients
+ * using the same file from a common server), there are times
+ * when the modification time of a file created on a remote
+ * machine will not be modified before the local stat() implied by
+ * the Dir_MTime occurs, thus leading us to believe that the file
+ * is unchanged, wreaking havoc with files that depend on this one.
+ *
+ * I have decided it is better to make too much than to make too
+ * little, so this stuff is commented out unless you're sure it's ok.
+ * -- ardeb 1/12/88
+ */
+ /*
+ * Christos, 4/9/92: If we are saving commands pretend that
+ * the target is made now. Otherwise archives with ... rules
+ * don't work!
+ */
+ if (NoExecute(gn) || (gn->type & OP_SAVE_CMDS) ||
+ (mtime == 0 && !(gn->type & OP_WAIT))) {
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, " recheck(%s): update time from %s to now\n",
+ gn->name, Targ_FmtTime(gn->mtime));
+ }
+ gn->mtime = now;
+ }
+ else {
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, " recheck(%s): current update time: %s\n",
+ gn->name, Targ_FmtTime(gn->mtime));
+ }
+ }
+#endif
+ return mtime;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Make_Update --
+ * Perform update on the parents of a node. Used by JobFinish once
+ * a node has been dealt with and by MakeStartJobs if it finds an
+ * up-to-date node.
+ *
+ * Input:
+ * cgn the child node
+ *
+ * Results:
+ * Always returns 0
+ *
+ * Side Effects:
+ * The unmade field of pgn is decremented and pgn may be placed on
+ * the toBeMade queue if this field becomes 0.
+ *
+ * If the child was made, the parent's flag CHILDMADE field will be
+ * set true.
+ *
+ * If the child is not up-to-date and still does not exist,
+ * set the FORCE flag on the parents.
+ *
+ * If the child wasn't made, the cmgn field of the parent will be
+ * altered if the child's mtime is big enough.
+ *
+ * Finally, if the child is the implied source for the parent, the
+ * parent's IMPSRC variable is set appropriately.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Make_Update(GNode *cgn)
+{
+ GNode *pgn; /* the parent node */
+ char *cname; /* the child's name */
+ LstNode ln; /* Element in parents and iParents lists */
+ time_t mtime = -1;
+ char *p1;
+ Lst parents;
+ GNode *centurion;
+
+ /* It is save to re-examine any nodes again */
+ checked++;
+
+ cname = Var_Value(TARGET, cgn, &p1);
+ if (p1)
+ free(p1);
+
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "Make_Update: %s%s\n", cgn->name, cgn->cohort_num);
+
+ /*
+ * If the child was actually made, see what its modification time is
+ * now -- some rules won't actually update the file. If the file still
+ * doesn't exist, make its mtime now.
+ */
+ if (cgn->made != UPTODATE) {
+ mtime = Make_Recheck(cgn);
+ }
+
+ /*
+ * If this is a `::' node, we must consult its first instance
+ * which is where all parents are linked.
+ */
+ if ((centurion = cgn->centurion) != NULL) {
+ if (!Lst_IsEmpty(cgn->parents))
+ Punt("%s%s: cohort has parents", cgn->name, cgn->cohort_num);
+ centurion->unmade_cohorts -= 1;
+ if (centurion->unmade_cohorts < 0)
+ Error("Graph cycles through centurion %s", centurion->name);
+ } else {
+ centurion = cgn;
+ }
+ parents = centurion->parents;
+
+ /* If this was a .ORDER node, schedule the RHS */
+ Lst_ForEach(centurion->order_succ, MakeBuildParent, Lst_First(toBeMade));
+
+ /* Now mark all the parents as having one less unmade child */
+ if (Lst_Open(parents) == SUCCESS) {
+ while ((ln = Lst_Next(parents)) != NULL) {
+ pgn = (GNode *)Lst_Datum(ln);
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "inspect parent %s%s: flags %x, "
+ "type %x, made %d, unmade %d ",
+ pgn->name, pgn->cohort_num, pgn->flags,
+ pgn->type, pgn->made, pgn->unmade-1);
+
+ if (!(pgn->flags & REMAKE)) {
+ /* This parent isn't needed */
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "- not needed\n");
+ continue;
+ }
+ if (mtime == 0 && !(cgn->type & OP_WAIT))
+ pgn->flags |= FORCE;
+
+ /*
+ * If the parent has the .MADE attribute, its timestamp got
+ * updated to that of its newest child, and its unmake
+ * child count got set to zero in Make_ExpandUse().
+ * However other things might cause us to build one of its
+ * children - and so we mustn't do any processing here when
+ * the child build finishes.
+ */
+ if (pgn->type & OP_MADE) {
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "- .MADE\n");
+ continue;
+ }
+
+ if ( ! (cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE))) {
+ if (cgn->made == MADE)
+ pgn->flags |= CHILDMADE;
+ (void)Make_TimeStamp(pgn, cgn);
+ }
+
+ /*
+ * A parent must wait for the completion of all instances
+ * of a `::' dependency.
+ */
+ if (centurion->unmade_cohorts != 0 || centurion->made < MADE) {
+ if (DEBUG(MAKE))
+ fprintf(debug_file,
+ "- centurion made %d, %d unmade cohorts\n",
+ centurion->made, centurion->unmade_cohorts);
+ continue;
+ }
+
+ /* One more child of this parent is now made */
+ pgn->unmade -= 1;
+ if (pgn->unmade < 0) {
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, "Graph cycles through %s%s\n",
+ pgn->name, pgn->cohort_num);
+ Targ_PrintGraph(2);
+ }
+ Error("Graph cycles through %s%s", pgn->name, pgn->cohort_num);
+ }
+
+ /* We must always rescan the parents of .WAIT and .ORDER nodes. */
+ if (pgn->unmade != 0 && !(centurion->type & OP_WAIT)
+ && !(centurion->flags & DONE_ORDER)) {
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "- unmade children\n");
+ continue;
+ }
+ if (pgn->made != DEFERRED) {
+ /*
+ * Either this parent is on a different branch of the tree,
+ * or it on the RHS of a .WAIT directive
+ * or it is already on the toBeMade list.
+ */
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "- not deferred\n");
+ continue;
+ }
+ if (pgn->order_pred
+ && Lst_ForEach(pgn->order_pred, MakeCheckOrder, 0)) {
+ /* A .ORDER rule stops us building this */
+ continue;
+ }
+ if (DEBUG(MAKE)) {
+ static int two = 2;
+ fprintf(debug_file, "- %s%s made, schedule %s%s (made %d)\n",
+ cgn->name, cgn->cohort_num,
+ pgn->name, pgn->cohort_num, pgn->made);
+ Targ_PrintNode(pgn, &two);
+ }
+ /* Ok, we can schedule the parent again */
+ pgn->made = REQUESTED;
+ (void)Lst_EnQueue(toBeMade, pgn);
+ }
+ Lst_Close(parents);
+ }
+
+ /*
+ * Set the .PREFIX and .IMPSRC variables for all the implied parents
+ * of this node.
+ */
+ if (Lst_Open(cgn->iParents) == SUCCESS) {
+ char *cpref = Var_Value(PREFIX, cgn, &p1);
+
+ while ((ln = Lst_Next(cgn->iParents)) != NULL) {
+ pgn = (GNode *)Lst_Datum(ln);
+ if (pgn->flags & REMAKE) {
+ Var_Set(IMPSRC, cname, pgn, 0);
+ if (cpref != NULL)
+ Var_Set(PREFIX, cpref, pgn, 0);
+ }
+ }
+ if (p1)
+ free(p1);
+ Lst_Close(cgn->iParents);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * MakeAddAllSrc --
+ * Add a child's name to the ALLSRC and OODATE variables of the given
+ * node. Called from Make_DoAllVar via Lst_ForEach. A child is added only
+ * if it has not been given the .EXEC, .USE or .INVISIBLE attributes.
+ * .EXEC and .USE children are very rarely going to be files, so...
+ * If the child is a .JOIN node, its ALLSRC is propagated to the parent.
+ *
+ * A child is added to the OODATE variable if its modification time is
+ * later than that of its parent, as defined by Make, except if the
+ * parent is a .JOIN node. In that case, it is only added to the OODATE
+ * variable if it was actually made (since .JOIN nodes don't have
+ * modification times, the comparison is rather unfair...)..
+ *
+ * Results:
+ * Always returns 0
+ *
+ * Side Effects:
+ * The ALLSRC variable for the given node is extended.
+ *-----------------------------------------------------------------------
+ */
+static int
+MakeUnmark(void *cgnp, void *pgnp MAKE_ATTR_UNUSED)
+{
+ GNode *cgn = (GNode *)cgnp;
+
+ cgn->type &= ~OP_MARK;
+ return (0);
+}
+
+/*
+ * Input:
+ * cgnp The child to add
+ * pgnp The parent to whose ALLSRC variable it should
+ * be added
+ *
+ */
+static int
+MakeAddAllSrc(void *cgnp, void *pgnp)
+{
+ GNode *cgn = (GNode *)cgnp;
+ GNode *pgn = (GNode *)pgnp;
+
+ if (cgn->type & OP_MARK)
+ return (0);
+ cgn->type |= OP_MARK;
+
+ if ((cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE|OP_INVISIBLE)) == 0) {
+ char *child, *allsrc;
+ char *p1 = NULL, *p2 = NULL;
+
+ if (cgn->type & OP_ARCHV)
+ child = Var_Value(MEMBER, cgn, &p1);
+ else
+ child = cgn->path ? cgn->path : cgn->name;
+ if (cgn->type & OP_JOIN) {
+ allsrc = Var_Value(ALLSRC, cgn, &p2);
+ } else {
+ allsrc = child;
+ }
+ if (allsrc != NULL)
+ Var_Append(ALLSRC, allsrc, pgn);
+ if (p2)
+ free(p2);
+ if (pgn->type & OP_JOIN) {
+ if (cgn->made == MADE) {
+ Var_Append(OODATE, child, pgn);
+ }
+ } else if ((pgn->mtime < cgn->mtime) ||
+ (cgn->mtime >= now && cgn->made == MADE))
+ {
+ /*
+ * It goes in the OODATE variable if the parent is younger than the
+ * child or if the child has been modified more recently than
+ * the start of the make. This is to keep pmake from getting
+ * confused if something else updates the parent after the
+ * make starts (shouldn't happen, I know, but sometimes it
+ * does). In such a case, if we've updated the kid, the parent
+ * is likely to have a modification time later than that of
+ * the kid and anything that relies on the OODATE variable will
+ * be hosed.
+ *
+ * XXX: This will cause all made children to go in the OODATE
+ * variable, even if they're not touched, if RECHECK isn't defined,
+ * since cgn->mtime is set to now in Make_Update. According to
+ * some people, this is good...
+ */
+ Var_Append(OODATE, child, pgn);
+ }
+ if (p1)
+ free(p1);
+ }
+ return (0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Make_DoAllVar --
+ * Set up the ALLSRC and OODATE variables. Sad to say, it must be
+ * done separately, rather than while traversing the graph. This is
+ * because Make defined OODATE to contain all sources whose modification
+ * times were later than that of the target, *not* those sources that
+ * were out-of-date. Since in both compatibility and native modes,
+ * the modification time of the parent isn't found until the child
+ * has been dealt with, we have to wait until now to fill in the
+ * variable. As for ALLSRC, the ordering is important and not
+ * guaranteed when in native mode, so it must be set here, too.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The ALLSRC and OODATE variables of the given node is filled in.
+ * If the node is a .JOIN node, its TARGET variable will be set to
+ * match its ALLSRC variable.
+ *-----------------------------------------------------------------------
+ */
+void
+Make_DoAllVar(GNode *gn)
+{
+ if (gn->flags & DONE_ALLSRC)
+ return;
+
+ Lst_ForEach(gn->children, MakeUnmark, gn);
+ Lst_ForEach(gn->children, MakeAddAllSrc, gn);
+
+ if (!Var_Exists (OODATE, gn)) {
+ Var_Set(OODATE, "", gn, 0);
+ }
+ if (!Var_Exists (ALLSRC, gn)) {
+ Var_Set(ALLSRC, "", gn, 0);
+ }
+
+ if (gn->type & OP_JOIN) {
+ char *p1;
+ Var_Set(TARGET, Var_Value(ALLSRC, gn, &p1), gn, 0);
+ if (p1)
+ free(p1);
+ }
+ gn->flags |= DONE_ALLSRC;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * MakeStartJobs --
+ * Start as many jobs as possible.
+ *
+ * Results:
+ * If the query flag was given to pmake, no job will be started,
+ * but as soon as an out-of-date target is found, this function
+ * returns TRUE. At all other times, this function returns FALSE.
+ *
+ * Side Effects:
+ * Nodes are removed from the toBeMade queue and job table slots
+ * are filled.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+static int
+MakeCheckOrder(void *v_bn, void *ignore MAKE_ATTR_UNUSED)
+{
+ GNode *bn = v_bn;
+
+ if (bn->made >= MADE || !(bn->flags & REMAKE))
+ return 0;
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "MakeCheckOrder: Waiting for .ORDER node %s%s\n",
+ bn->name, bn->cohort_num);
+ return 1;
+}
+
+static int
+MakeBuildChild(void *v_cn, void *toBeMade_next)
+{
+ GNode *cn = v_cn;
+
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "MakeBuildChild: inspect %s%s, made %d, type %x\n",
+ cn->name, cn->cohort_num, cn->made, cn->type);
+ if (cn->made > DEFERRED)
+ return 0;
+
+ /* If this node is on the RHS of a .ORDER, check LHSs. */
+ if (cn->order_pred && Lst_ForEach(cn->order_pred, MakeCheckOrder, 0)) {
+ /* Can't build this (or anything else in this child list) yet */
+ cn->made = DEFERRED;
+ return 1;
+ }
+
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "MakeBuildChild: schedule %s%s\n",
+ cn->name, cn->cohort_num);
+
+ cn->made = REQUESTED;
+ if (toBeMade_next == NULL)
+ Lst_AtEnd(toBeMade, cn);
+ else
+ Lst_InsertBefore(toBeMade, toBeMade_next, cn);
+
+ if (cn->unmade_cohorts != 0)
+ Lst_ForEach(cn->cohorts, MakeBuildChild, toBeMade_next);
+
+ /*
+ * If this node is a .WAIT node with unmade chlidren
+ * then don't add the next sibling.
+ */
+ return cn->type & OP_WAIT && cn->unmade > 0;
+}
+
+/* When a .ORDER RHS node completes we do this on each LHS */
+static int
+MakeBuildParent(void *v_pn, void *toBeMade_next)
+{
+ GNode *pn = v_pn;
+
+ if (pn->made != DEFERRED)
+ return 0;
+
+ if (MakeBuildChild(pn, toBeMade_next) == 0) {
+ /* Mark so that when this node is built we reschedule its parents */
+ pn->flags |= DONE_ORDER;
+ }
+
+ return 0;
+}
+
+static Boolean
+MakeStartJobs(void)
+{
+ GNode *gn;
+ int have_token = 0;
+
+ while (!Lst_IsEmpty (toBeMade)) {
+ /* Get token now to avoid cycling job-list when we only have 1 token */
+ if (!have_token && !Job_TokenWithdraw())
+ break;
+ have_token = 1;
+
+ gn = (GNode *)Lst_DeQueue(toBeMade);
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "Examining %s%s...\n",
+ gn->name, gn->cohort_num);
+
+ if (gn->made != REQUESTED) {
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "state %d\n", gn->made);
+
+ make_abort(gn, __LINE__);
+ }
+
+ if (gn->checked == checked) {
+ /* We've already looked at this node since a job finished... */
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "already checked %s%s\n",
+ gn->name, gn->cohort_num);
+ gn->made = DEFERRED;
+ continue;
+ }
+ gn->checked = checked;
+
+ if (gn->unmade != 0) {
+ /*
+ * We can't build this yet, add all unmade children to toBeMade,
+ * just before the current first element.
+ */
+ gn->made = DEFERRED;
+ Lst_ForEach(gn->children, MakeBuildChild, Lst_First(toBeMade));
+ /* and drop this node on the floor */
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "dropped %s%s\n", gn->name, gn->cohort_num);
+ continue;
+ }
+
+ gn->made = BEINGMADE;
+ if (Make_OODate(gn)) {
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, "out-of-date\n");
+ }
+ if (queryFlag) {
+ return (TRUE);
+ }
+ Make_DoAllVar(gn);
+ Job_Make(gn);
+ have_token = 0;
+ } else {
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, "up-to-date\n");
+ }
+ gn->made = UPTODATE;
+ if (gn->type & OP_JOIN) {
+ /*
+ * Even for an up-to-date .JOIN node, we need it to have its
+ * context variables so references to it get the correct
+ * value for .TARGET when building up the context variables
+ * of its parent(s)...
+ */
+ Make_DoAllVar(gn);
+ }
+ Make_Update(gn);
+ }
+ }
+
+ if (have_token)
+ Job_TokenReturn();
+
+ return (FALSE);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * MakePrintStatus --
+ * Print the status of a top-level node, viz. it being up-to-date
+ * already or not created due to an error in a lower level.
+ * Callback function for Make_Run via Lst_ForEach.
+ *
+ * Input:
+ * gnp Node to examine
+ * cyclep True if gn->unmade being non-zero implies a
+ * cycle in the graph, not an error in an
+ * inferior.
+ *
+ * Results:
+ * Always returns 0.
+ *
+ * Side Effects:
+ * A message may be printed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+MakePrintStatusOrder(void *ognp, void *gnp)
+{
+ GNode *ogn = ognp;
+ GNode *gn = gnp;
+
+ if (!(ogn->flags & REMAKE) || ogn->made > REQUESTED)
+ /* not waiting for this one */
+ return 0;
+
+ printf(" `%s%s' has .ORDER dependency against %s%s "
+ "(made %d, flags %x, type %x)\n",
+ gn->name, gn->cohort_num,
+ ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type);
+ if (DEBUG(MAKE) && debug_file != stdout)
+ fprintf(debug_file, " `%s%s' has .ORDER dependency against %s%s "
+ "(made %d, flags %x, type %x)\n",
+ gn->name, gn->cohort_num,
+ ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type);
+ return 0;
+}
+
+static int
+MakePrintStatus(void *gnp, void *v_errors)
+{
+ GNode *gn = (GNode *)gnp;
+ int *errors = v_errors;
+
+ if (gn->flags & DONECYCLE)
+ /* We've completely processed this node before, don't do it again. */
+ return 0;
+
+ if (gn->unmade == 0) {
+ gn->flags |= DONECYCLE;
+ switch (gn->made) {
+ case UPTODATE:
+ printf("`%s%s' is up to date.\n", gn->name, gn->cohort_num);
+ break;
+ case MADE:
+ break;
+ case UNMADE:
+ case DEFERRED:
+ case REQUESTED:
+ case BEINGMADE:
+ (*errors)++;
+ printf("`%s%s' was not built (made %d, flags %x, type %x)!\n",
+ gn->name, gn->cohort_num, gn->made, gn->flags, gn->type);
+ if (DEBUG(MAKE) && debug_file != stdout)
+ fprintf(debug_file,
+ "`%s%s' was not built (made %d, flags %x, type %x)!\n",
+ gn->name, gn->cohort_num, gn->made, gn->flags, gn->type);
+ /* Most likely problem is actually caused by .ORDER */
+ Lst_ForEach(gn->order_pred, MakePrintStatusOrder, gn);
+ break;
+ default:
+ /* Errors - already counted */
+ printf("`%s%s' not remade because of errors.\n",
+ gn->name, gn->cohort_num);
+ if (DEBUG(MAKE) && debug_file != stdout)
+ fprintf(debug_file, "`%s%s' not remade because of errors.\n",
+ gn->name, gn->cohort_num);
+ break;
+ }
+ return 0;
+ }
+
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "MakePrintStatus: %s%s has %d unmade children\n",
+ gn->name, gn->cohort_num, gn->unmade);
+ /*
+ * If printing cycles and came to one that has unmade children,
+ * print out the cycle by recursing on its children.
+ */
+ if (!(gn->flags & CYCLE)) {
+ /* Fist time we've seen this node, check all children */
+ gn->flags |= CYCLE;
+ Lst_ForEach(gn->children, MakePrintStatus, errors);
+ /* Mark that this node needn't be processed again */
+ gn->flags |= DONECYCLE;
+ return 0;
+ }
+
+ /* Only output the error once per node */
+ gn->flags |= DONECYCLE;
+ Error("Graph cycles through `%s%s'", gn->name, gn->cohort_num);
+ if ((*errors)++ > 100)
+ /* Abandon the whole error report */
+ return 1;
+
+ /* Reporting for our children will give the rest of the loop */
+ Lst_ForEach(gn->children, MakePrintStatus, errors);
+ return 0;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Make_ExpandUse --
+ * Expand .USE nodes and create a new targets list
+ *
+ * Input:
+ * targs the initial list of targets
+ *
+ * Side Effects:
+ *-----------------------------------------------------------------------
+ */
+void
+Make_ExpandUse(Lst targs)
+{
+ GNode *gn; /* a temporary pointer */
+ Lst examine; /* List of targets to examine */
+
+ examine = Lst_Duplicate(targs, NULL);
+
+ /*
+ * Make an initial downward pass over the graph, marking nodes to be made
+ * as we go down. We call Suff_FindDeps to find where a node is and
+ * to get some children for it if it has none and also has no commands.
+ * If the node is a leaf, we stick it on the toBeMade queue to
+ * be looked at in a minute, otherwise we add its children to our queue
+ * and go on about our business.
+ */
+ while (!Lst_IsEmpty (examine)) {
+ gn = (GNode *)Lst_DeQueue(examine);
+
+ if (gn->flags & REMAKE)
+ /* We've looked at this one already */
+ continue;
+ gn->flags |= REMAKE;
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "Make_ExpandUse: examine %s%s\n",
+ gn->name, gn->cohort_num);
+
+ if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) {
+ /* Append all the 'cohorts' to the list of things to examine */
+ Lst new;
+ new = Lst_Duplicate(gn->cohorts, NULL);
+ Lst_Concat(new, examine, LST_CONCLINK);
+ examine = new;
+ }
+
+ /*
+ * Apply any .USE rules before looking for implicit dependencies
+ * to make sure everything has commands that should...
+ * Make sure that the TARGET is set, so that we can make
+ * expansions.
+ */
+ if (gn->type & OP_ARCHV) {
+ char *eoa, *eon;
+ eoa = strchr(gn->name, '(');
+ eon = strchr(gn->name, ')');
+ if (eoa == NULL || eon == NULL)
+ continue;
+ *eoa = '\0';
+ *eon = '\0';
+ Var_Set(MEMBER, eoa + 1, gn, 0);
+ Var_Set(ARCHIVE, gn->name, gn, 0);
+ *eoa = '(';
+ *eon = ')';
+ }
+
+ (void)Dir_MTime(gn, 0);
+ Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0);
+ Lst_ForEach(gn->children, MakeUnmark, gn);
+ Lst_ForEach(gn->children, MakeHandleUse, gn);
+
+ if ((gn->type & OP_MADE) == 0)
+ Suff_FindDeps(gn);
+ else {
+ /* Pretend we made all this node's children */
+ Lst_ForEach(gn->children, MakeFindChild, gn);
+ if (gn->unmade != 0)
+ printf("Warning: %s%s still has %d unmade children\n",
+ gn->name, gn->cohort_num, gn->unmade);
+ }
+
+ if (gn->unmade != 0)
+ Lst_ForEach(gn->children, MakeAddChild, examine);
+ }
+
+ Lst_Destroy(examine, NULL);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Make_ProcessWait --
+ * Convert .WAIT nodes into dependencies
+ *
+ * Input:
+ * targs the initial list of targets
+ *
+ *-----------------------------------------------------------------------
+ */
+
+static int
+link_parent(void *cnp, void *pnp)
+{
+ GNode *cn = cnp;
+ GNode *pn = pnp;
+
+ Lst_AtEnd(pn->children, cn);
+ Lst_AtEnd(cn->parents, pn);
+ pn->unmade++;
+ return 0;
+}
+
+static int
+add_wait_dep(void *v_cn, void *v_wn)
+{
+ GNode *cn = v_cn;
+ GNode *wn = v_wn;
+
+ if (cn == wn)
+ return 1;
+
+ if (cn == NULL || wn == NULL) {
+ printf("bad wait dep %p %p\n", cn, wn);
+ exit(4);
+ }
+ if (DEBUG(MAKE))
+ fprintf(debug_file, ".WAIT: add dependency %s%s -> %s\n",
+ cn->name, cn->cohort_num, wn->name);
+
+ Lst_AtEnd(wn->children, cn);
+ wn->unmade++;
+ Lst_AtEnd(cn->parents, wn);
+ return 0;
+}
+
+static void
+Make_ProcessWait(Lst targs)
+{
+ GNode *pgn; /* 'parent' node we are examining */
+ GNode *cgn; /* Each child in turn */
+ LstNode owln; /* Previous .WAIT node */
+ Lst examine; /* List of targets to examine */
+ LstNode ln;
+
+ /*
+ * We need all the nodes to have a common parent in order for the
+ * .WAIT and .ORDER scheduling to work.
+ * Perhaps this should be done earlier...
+ */
+
+ pgn = Targ_NewGN(".MAIN");
+ pgn->flags = REMAKE;
+ pgn->type = OP_PHONY | OP_DEPENDS;
+ /* Get it displayed in the diag dumps */
+ Lst_AtFront(Targ_List(), pgn);
+
+ Lst_ForEach(targs, link_parent, pgn);
+
+ /* Start building with the 'dummy' .MAIN' node */
+ MakeBuildChild(pgn, NULL);
+
+ examine = Lst_Init(FALSE);
+ Lst_AtEnd(examine, pgn);
+
+ while (!Lst_IsEmpty (examine)) {
+ pgn = Lst_DeQueue(examine);
+
+ /* We only want to process each child-list once */
+ if (pgn->flags & DONE_WAIT)
+ continue;
+ pgn->flags |= DONE_WAIT;
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "Make_ProcessWait: examine %s\n", pgn->name);
+
+ if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (pgn->cohorts)) {
+ /* Append all the 'cohorts' to the list of things to examine */
+ Lst new;
+ new = Lst_Duplicate(pgn->cohorts, NULL);
+ Lst_Concat(new, examine, LST_CONCLINK);
+ examine = new;
+ }
+
+ owln = Lst_First(pgn->children);
+ Lst_Open(pgn->children);
+ for (; (ln = Lst_Next(pgn->children)) != NULL; ) {
+ cgn = Lst_Datum(ln);
+ if (cgn->type & OP_WAIT) {
+ /* Make the .WAIT node depend on the previous children */
+ Lst_ForEachFrom(pgn->children, owln, add_wait_dep, cgn);
+ owln = ln;
+ } else {
+ Lst_AtEnd(examine, cgn);
+ }
+ }
+ Lst_Close(pgn->children);
+ }
+
+ Lst_Destroy(examine, NULL);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Make_Run --
+ * Initialize the nodes to remake and the list of nodes which are
+ * ready to be made by doing a breadth-first traversal of the graph
+ * starting from the nodes in the given list. Once this traversal
+ * is finished, all the 'leaves' of the graph are in the toBeMade
+ * queue.
+ * Using this queue and the Job module, work back up the graph,
+ * calling on MakeStartJobs to keep the job table as full as
+ * possible.
+ *
+ * Input:
+ * targs the initial list of targets
+ *
+ * Results:
+ * TRUE if work was done. FALSE otherwise.
+ *
+ * Side Effects:
+ * The make field of all nodes involved in the creation of the given
+ * targets is set to 1. The toBeMade list is set to contain all the
+ * 'leaves' of these subgraphs.
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Make_Run(Lst targs)
+{
+ int errors; /* Number of errors the Job module reports */
+
+ /* Start trying to make the current targets... */
+ toBeMade = Lst_Init(FALSE);
+
+ Make_ExpandUse(targs);
+ Make_ProcessWait(targs);
+
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, "#***# full graph\n");
+ Targ_PrintGraph(1);
+ }
+
+ if (queryFlag) {
+ /*
+ * We wouldn't do any work unless we could start some jobs in the
+ * next loop... (we won't actually start any, of course, this is just
+ * to see if any of the targets was out of date)
+ */
+ return (MakeStartJobs());
+ }
+ /*
+ * Initialization. At the moment, no jobs are running and until some
+ * get started, nothing will happen since the remaining upward
+ * traversal of the graph is performed by the routines in job.c upon
+ * the finishing of a job. So we fill the Job table as much as we can
+ * before going into our loop.
+ */
+ (void)MakeStartJobs();
+
+ /*
+ * Main Loop: The idea here is that the ending of jobs will take
+ * care of the maintenance of data structures and the waiting for output
+ * will cause us to be idle most of the time while our children run as
+ * much as possible. Because the job table is kept as full as possible,
+ * the only time when it will be empty is when all the jobs which need
+ * running have been run, so that is the end condition of this loop.
+ * Note that the Job module will exit if there were any errors unless the
+ * keepgoing flag was given.
+ */
+ while (!Lst_IsEmpty(toBeMade) || jobTokensRunning > 0) {
+ Job_CatchOutput();
+ (void)MakeStartJobs();
+ }
+
+ errors = Job_Finish();
+
+ /*
+ * Print the final status of each target. E.g. if it wasn't made
+ * because some inferior reported an error.
+ */
+ if (DEBUG(MAKE))
+ fprintf(debug_file, "done: errors %d\n", errors);
+ if (errors == 0) {
+ Lst_ForEach(targs, MakePrintStatus, &errors);
+ if (DEBUG(MAKE)) {
+ fprintf(debug_file, "done: errors %d\n", errors);
+ if (errors)
+ Targ_PrintGraph(4);
+ }
+ }
+ return errors != 0;
+}
diff --git a/external/bsd/bmake/dist/make.h b/external/bsd/bmake/dist/make.h
new file mode 100644
index 0000000..384d109
--- /dev/null
+++ b/external/bsd/bmake/dist/make.h
@@ -0,0 +1,518 @@
+/* $NetBSD: make.h,v 1.89 2012/06/12 19:21:51 joerg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)make.h 8.3 (Berkeley) 6/13/95
+ */
+
+/*
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)make.h 8.3 (Berkeley) 6/13/95
+ */
+
+/*-
+ * make.h --
+ * The global definitions for pmake
+ */
+
+#ifndef _MAKE_H_
+#define _MAKE_H_
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <unistd.h>
+#include <sys/cdefs.h>
+
+#if defined(__GNUC__)
+#define MAKE_GNUC_PREREQ(x, y) \
+ ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
+ (__GNUC__ > (x)))
+#else /* defined(__GNUC__) */
+#define MAKE_GNUC_PREREQx, y) 0
+#endif /* defined(__GNUC__) */
+
+#if MAKE_GNUC_PREREQ(2, 7)
+#define MAKE_ATTR_UNUSED __attribute__((__unused__))
+#else
+#define MAKE_ATTR_UNUSED /* delete */
+#endif
+
+#if MAKE_GNUC_PREREQ(2, 5)
+#define MAKE_ATTR_DEAD __attribute__((__noreturn__))
+#elif defined(__GNUC__)
+#define MAKE_ATTR_DEAD __volatile
+#else
+#define MAKE_ATTR_DEAD /* delete */
+#endif
+
+#if MAKE_GNUC_PREREQ(2, 7)
+#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) \
+ __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
+#else
+#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) /* delete */
+#endif
+
+#include "sprite.h"
+#include "lst.h"
+#include "hash.h"
+#include "make-conf.h"
+#include "buf.h"
+#include "make_malloc.h"
+
+/*
+ * some vendors don't have this --sjg
+ */
+#if defined(S_IFDIR) && !defined(S_ISDIR)
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+#if defined(sun) && (defined(__svr4__) || defined(__SVR4))
+#define POSIX_SIGNALS
+#endif
+
+/*-
+ * The structure for an individual graph node. Each node has several
+ * pieces of data associated with it.
+ * 1) the name of the target it describes
+ * 2) the location of the target file in the file system.
+ * 3) the type of operator used to define its sources (qv. parse.c)
+ * 4) whether it is involved in this invocation of make
+ * 5) whether the target has been remade
+ * 6) whether any of its children has been remade
+ * 7) the number of its children that are, as yet, unmade
+ * 8) its modification time
+ * 9) the modification time of its youngest child (qv. make.c)
+ * 10) a list of nodes for which this is a source (parents)
+ * 11) a list of nodes on which this depends (children)
+ * 12) a list of nodes that depend on this, as gleaned from the
+ * transformation rules (iParents)
+ * 13) a list of ancestor nodes, which includes parents, iParents,
+ * and recursive parents of parents
+ * 14) a list of nodes of the same name created by the :: operator
+ * 15) a list of nodes that must be made (if they're made) before
+ * this node can be, but that do not enter into the datedness of
+ * this node.
+ * 16) a list of nodes that must be made (if they're made) before
+ * this node or any child of this node can be, but that do not
+ * enter into the datedness of this node.
+ * 17) a list of nodes that must be made (if they're made) after
+ * this node is, but that do not depend on this node, in the
+ * normal sense.
+ * 18) a Lst of ``local'' variables that are specific to this target
+ * and this target only (qv. var.c [$@ $< $?, etc.])
+ * 19) a Lst of strings that are commands to be given to a shell
+ * to create this target.
+ */
+typedef struct GNode {
+ char *name; /* The target's name */
+ char *uname; /* The unexpanded name of a .USE node */
+ char *path; /* The full pathname of the file */
+ int type; /* Its type (see the OP flags, below) */
+
+ int flags;
+#define REMAKE 0x1 /* this target needs to be (re)made */
+#define CHILDMADE 0x2 /* children of this target were made */
+#define FORCE 0x4 /* children don't exist, and we pretend made */
+#define DONE_WAIT 0x8 /* Set by Make_ProcessWait() */
+#define DONE_ORDER 0x10 /* Build requested by .ORDER processing */
+#define FROM_DEPEND 0x20 /* Node created from .depend */
+#define DONE_ALLSRC 0x40 /* We do it once only */
+#define CYCLE 0x1000 /* Used by MakePrintStatus */
+#define DONECYCLE 0x2000 /* Used by MakePrintStatus */
+ enum enum_made {
+ UNMADE, DEFERRED, REQUESTED, BEINGMADE,
+ MADE, UPTODATE, ERROR, ABORTED
+ } made; /* Set to reflect the state of processing
+ * on this node:
+ * UNMADE - Not examined yet
+ * DEFERRED - Examined once (building child)
+ * REQUESTED - on toBeMade list
+ * BEINGMADE - Target is already being made.
+ * Indicates a cycle in the graph.
+ * MADE - Was out-of-date and has been made
+ * UPTODATE - Was already up-to-date
+ * ERROR - An error occurred while it was being
+ * made (used only in compat mode)
+ * ABORTED - The target was aborted due to
+ * an error making an inferior (compat).
+ */
+ int unmade; /* The number of unmade children */
+
+ time_t mtime; /* Its modification time */
+ struct GNode *cmgn; /* The youngest child */
+
+ Lst iParents; /* Links to parents for which this is an
+ * implied source, if any */
+ Lst cohorts; /* Other nodes for the :: operator */
+ Lst parents; /* Nodes that depend on this one */
+ Lst children; /* Nodes on which this one depends */
+ Lst order_pred; /* .ORDER nodes we need made */
+ Lst order_succ; /* .ORDER nodes who need us */
+
+ char cohort_num[8]; /* #n for this cohort */
+ int unmade_cohorts;/* # of unmade instances on the
+ cohorts list */
+ struct GNode *centurion; /* Pointer to the first instance of a ::
+ node; only set when on a cohorts list */
+ unsigned int checked; /* Last time we tried to makle this node */
+
+ Hash_Table context; /* The local variables */
+ Lst commands; /* Creation commands */
+
+ struct _Suff *suffix; /* Suffix for the node (determined by
+ * Suff_FindDeps and opaque to everyone
+ * but the Suff module) */
+ const char *fname; /* filename where the GNode got defined */
+ int lineno; /* line number where the GNode got defined */
+} GNode;
+
+/*
+ * The OP_ constants are used when parsing a dependency line as a way of
+ * communicating to other parts of the program the way in which a target
+ * should be made. These constants are bitwise-OR'ed together and
+ * placed in the 'type' field of each node. Any node that has
+ * a 'type' field which satisfies the OP_NOP function was never never on
+ * the lefthand side of an operator, though it may have been on the
+ * righthand side...
+ */
+#define OP_DEPENDS 0x00000001 /* Execution of commands depends on
+ * kids (:) */
+#define OP_FORCE 0x00000002 /* Always execute commands (!) */
+#define OP_DOUBLEDEP 0x00000004 /* Execution of commands depends on kids
+ * per line (::) */
+#define OP_OPMASK (OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP)
+
+#define OP_OPTIONAL 0x00000008 /* Don't care if the target doesn't
+ * exist and can't be created */
+#define OP_USE 0x00000010 /* Use associated commands for parents */
+#define OP_EXEC 0x00000020 /* Target is never out of date, but always
+ * execute commands anyway. Its time
+ * doesn't matter, so it has none...sort
+ * of */
+#define OP_IGNORE 0x00000040 /* Ignore errors when creating the node */
+#define OP_PRECIOUS 0x00000080 /* Don't remove the target when
+ * interrupted */
+#define OP_SILENT 0x00000100 /* Don't echo commands when executed */
+#define OP_MAKE 0x00000200 /* Target is a recursive make so its
+ * commands should always be executed when
+ * it is out of date, regardless of the
+ * state of the -n or -t flags */
+#define OP_JOIN 0x00000400 /* Target is out-of-date only if any of its
+ * children was out-of-date */
+#define OP_MADE 0x00000800 /* Assume the children of the node have
+ * been already made */
+#define OP_SPECIAL 0x00001000 /* Special .BEGIN, .END, .INTERRUPT */
+#define OP_USEBEFORE 0x00002000 /* Like .USE, only prepend commands */
+#define OP_INVISIBLE 0x00004000 /* The node is invisible to its parents.
+ * I.e. it doesn't show up in the parents's
+ * local variables. */
+#define OP_NOTMAIN 0x00008000 /* The node is exempt from normal 'main
+ * target' processing in parse.c */
+#define OP_PHONY 0x00010000 /* Not a file target; run always */
+#define OP_NOPATH 0x00020000 /* Don't search for file in the path */
+#define OP_WAIT 0x00040000 /* .WAIT phony node */
+#define OP_NOMETA 0x00080000 /* .NOMETA do not create a .meta file */
+#define OP_META 0x00100000 /* .META we _do_ want a .meta file */
+#define OP_NOMETA_CMP 0x00200000 /* Do not compare commands in .meta file */
+/* Attributes applied by PMake */
+#define OP_TRANSFORM 0x80000000 /* The node is a transformation rule */
+#define OP_MEMBER 0x40000000 /* Target is a member of an archive */
+#define OP_LIB 0x20000000 /* Target is a library */
+#define OP_ARCHV 0x10000000 /* Target is an archive construct */
+#define OP_HAS_COMMANDS 0x08000000 /* Target has all the commands it should.
+ * Used when parsing to catch multiple
+ * commands for a target */
+#define OP_SAVE_CMDS 0x04000000 /* Saving commands on .END (Compat) */
+#define OP_DEPS_FOUND 0x02000000 /* Already processed by Suff_FindDeps */
+#define OP_MARK 0x01000000 /* Node found while expanding .ALLSRC */
+
+#define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute)
+/*
+ * OP_NOP will return TRUE if the node with the given type was not the
+ * object of a dependency operator
+ */
+#define OP_NOP(t) (((t) & OP_OPMASK) == 0x00000000)
+
+#define OP_NOTARGET (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM)
+
+/*
+ * The TARG_ constants are used when calling the Targ_FindNode and
+ * Targ_FindList functions in targ.c. They simply tell the functions what to
+ * do if the desired node(s) is (are) not found. If the TARG_CREATE constant
+ * is given, a new, empty node will be created for the target, placed in the
+ * table of all targets and its address returned. If TARG_NOCREATE is given,
+ * a NULL pointer will be returned.
+ */
+#define TARG_NOCREATE 0x00 /* don't create it */
+#define TARG_CREATE 0x01 /* create node if not found */
+#define TARG_NOHASH 0x02 /* don't look in/add to hash table */
+
+/*
+ * These constants are all used by the Str_Concat function to decide how the
+ * final string should look. If STR_ADDSPACE is given, a space will be
+ * placed between the two strings. If STR_ADDSLASH is given, a '/' will
+ * be used instead of a space. If neither is given, no intervening characters
+ * will be placed between the two strings in the final output. If the
+ * STR_DOFREE bit is set, the two input strings will be freed before
+ * Str_Concat returns.
+ */
+#define STR_ADDSPACE 0x01 /* add a space when Str_Concat'ing */
+#define STR_ADDSLASH 0x02 /* add a slash when Str_Concat'ing */
+
+/*
+ * Error levels for parsing. PARSE_FATAL means the process cannot continue
+ * once the makefile has been parsed. PARSE_WARNING means it can. Passed
+ * as the first argument to Parse_Error.
+ */
+#define PARSE_WARNING 2
+#define PARSE_FATAL 1
+
+/*
+ * Values returned by Cond_Eval.
+ */
+#define COND_PARSE 0 /* Parse the next lines */
+#define COND_SKIP 1 /* Skip the next lines */
+#define COND_INVALID 2 /* Not a conditional statement */
+
+/*
+ * Definitions for the "local" variables. Used only for clarity.
+ */
+#define TARGET "@" /* Target of dependency */
+#define OODATE "?" /* All out-of-date sources */
+#define ALLSRC ">" /* All sources */
+#define IMPSRC "<" /* Source implied by transformation */
+#define PREFIX "*" /* Common prefix */
+#define ARCHIVE "!" /* Archive in "archive(member)" syntax */
+#define MEMBER "%" /* Member in "archive(member)" syntax */
+
+#define FTARGET "@F" /* file part of TARGET */
+#define DTARGET "@D" /* directory part of TARGET */
+#define FIMPSRC "<F" /* file part of IMPSRC */
+#define DIMPSRC "<D" /* directory part of IMPSRC */
+#define FPREFIX "*F" /* file part of PREFIX */
+#define DPREFIX "*D" /* directory part of PREFIX */
+
+/*
+ * Global Variables
+ */
+extern Lst create; /* The list of target names specified on the
+ * command line. used to resolve #if
+ * make(...) statements */
+extern Lst dirSearchPath; /* The list of directories to search when
+ * looking for targets */
+
+extern Boolean compatMake; /* True if we are make compatible */
+extern Boolean ignoreErrors; /* True if should ignore all errors */
+extern Boolean beSilent; /* True if should print no commands */
+extern Boolean noExecute; /* True if should execute nothing */
+extern Boolean noRecursiveExecute; /* True if should execute nothing */
+extern Boolean allPrecious; /* True if every target is precious */
+extern Boolean keepgoing; /* True if should continue on unaffected
+ * portions of the graph when have an error
+ * in one portion */
+extern Boolean touchFlag; /* TRUE if targets should just be 'touched'
+ * if out of date. Set by the -t flag */
+extern Boolean queryFlag; /* TRUE if we aren't supposed to really make
+ * anything, just see if the targets are out-
+ * of-date */
+extern Boolean doing_depend; /* TRUE if processing .depend */
+
+extern Boolean checkEnvFirst; /* TRUE if environment should be searched for
+ * variables before the global context */
+extern Boolean jobServer; /* a jobServer already exists */
+
+extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are
+ * treated as errors */
+
+extern Boolean varNoExportEnv; /* TRUE if we should not export variables
+ * set on the command line to the env. */
+
+extern GNode *DEFAULT; /* .DEFAULT rule */
+
+extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g
+ * in the Makefile itself */
+extern GNode *VAR_CMD; /* Variables defined on the command line */
+extern GNode *VAR_FOR; /* Iteration variables */
+extern char var_Error[]; /* Value returned by Var_Parse when an error
+ * is encountered. It actually points to
+ * an empty string, so naive callers needn't
+ * worry about it. */
+
+extern time_t now; /* The time at the start of this whole
+ * process */
+
+extern Boolean oldVars; /* Do old-style variable substitution */
+
+extern Lst sysIncPath; /* The system include path. */
+extern Lst defIncPath; /* The default include path. */
+
+extern char curdir[]; /* Startup directory */
+extern char *progname; /* The program name */
+extern char *makeDependfile; /* .depend */
+extern char **savedEnv; /* if we replaced environ this will be non-NULL */
+
+/*
+ * We cannot vfork() in a child of vfork().
+ * Most systems do not enforce this but some do.
+ */
+#define vFork() ((getpid() == myPid) ? vfork() : fork())
+extern pid_t myPid;
+
+#define MAKEFLAGS ".MAKEFLAGS"
+#define MAKEOVERRIDES ".MAKEOVERRIDES"
+#define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX" /* prefix for job target output */
+#define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */
+#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */
+#define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */
+#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
+#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */
+#define MAKE_MODE ".MAKE.MODE"
+
+#ifdef NEED_MAKE_LEVEL_SAFE
+# define MAKE_LEVEL_SAFE "_MAKE_LEVEL" /* some shells will not pass .MAKE. */
+#endif
+
+/*
+ * debug control:
+ * There is one bit per module. It is up to the module what debug
+ * information to print.
+ */
+FILE *debug_file; /* Output written here - default stdout */
+extern int debug;
+#define DEBUG_ARCH 0x00001
+#define DEBUG_COND 0x00002
+#define DEBUG_DIR 0x00004
+#define DEBUG_GRAPH1 0x00008
+#define DEBUG_GRAPH2 0x00010
+#define DEBUG_JOB 0x00020
+#define DEBUG_MAKE 0x00040
+#define DEBUG_SUFF 0x00080
+#define DEBUG_TARG 0x00100
+#define DEBUG_VAR 0x00200
+#define DEBUG_FOR 0x00400
+#define DEBUG_SHELL 0x00800
+#define DEBUG_ERROR 0x01000
+#define DEBUG_LOUD 0x02000
+#define DEBUG_META 0x04000
+
+#define DEBUG_GRAPH3 0x10000
+#define DEBUG_SCRIPT 0x20000
+#define DEBUG_PARSE 0x40000
+#define DEBUG_CWD 0x80000
+
+#define CONCAT(a,b) a##b
+
+#define DEBUG(module) (debug & CONCAT(DEBUG_,module))
+
+#include "nonints.h"
+
+int Make_TimeStamp(GNode *, GNode *);
+Boolean Make_OODate(GNode *);
+void Make_ExpandUse(Lst);
+time_t Make_Recheck(GNode *);
+void Make_HandleUse(GNode *, GNode *);
+void Make_Update(GNode *);
+void Make_DoAllVar(GNode *);
+Boolean Make_Run(Lst);
+char * Check_Cwd_Cmd(const char *);
+void Check_Cwd(const char **);
+void PrintOnError(GNode *, const char *);
+void Main_ExportMAKEFLAGS(Boolean);
+Boolean Main_SetObjdir(const char *);
+int mkTempFile(const char *, char **);
+int str2Lst_Append(Lst, char *, const char *);
+
+#ifdef __GNUC__
+#define UNCONST(ptr) ({ \
+ union __unconst { \
+ const void *__cp; \
+ void *__p; \
+ } __d; \
+ __d.__cp = ptr, __d.__p; })
+#else
+#define UNCONST(ptr) (void *)(ptr)
+#endif
+
+#ifndef MIN
+#define MIN(a, b) ((a < b) ? a : b)
+#endif
+#ifndef MAX
+#define MAX(a, b) ((a > b) ? a : b)
+#endif
+
+#endif /* _MAKE_H_ */
diff --git a/external/bsd/bmake/dist/make_malloc.c b/external/bsd/bmake/dist/make_malloc.c
new file mode 100644
index 0000000..b8ac23f
--- /dev/null
+++ b/external/bsd/bmake/dist/make_malloc.c
@@ -0,0 +1,119 @@
+/* $NetBSD: make_malloc.c,v 1.10 2012/06/20 17:46:28 sjg Exp $ */
+
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef MAKE_NATIVE
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: make_malloc.c,v 1.10 2012/06/20 17:46:28 sjg Exp $");
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "make.h"
+
+#ifndef USE_EMALLOC
+static void enomem(void) MAKE_ATTR_DEAD;
+
+/*
+ * enomem --
+ * die when out of memory.
+ */
+static void
+enomem(void)
+{
+ (void)fprintf(stderr, "%s: %s.\n", progname, strerror(ENOMEM));
+ exit(2);
+}
+
+/*
+ * bmake_malloc --
+ * malloc, but die on error.
+ */
+void *
+bmake_malloc(size_t len)
+{
+ void *p;
+
+ if ((p = malloc(len)) == NULL)
+ enomem();
+ return(p);
+}
+
+/*
+ * bmake_strdup --
+ * strdup, but die on error.
+ */
+char *
+bmake_strdup(const char *str)
+{
+ size_t len;
+ char *p;
+
+ len = strlen(str) + 1;
+ if ((p = malloc(len)) == NULL)
+ enomem();
+ return memcpy(p, str, len);
+}
+
+/*
+ * bmake_strndup --
+ * strndup, but die on error.
+ */
+char *
+bmake_strndup(const char *str, size_t max_len)
+{
+ size_t len;
+ char *p;
+
+ if (str == NULL)
+ return NULL;
+
+ len = strlen(str);
+ if (len > max_len)
+ len = max_len;
+ p = bmake_malloc(len + 1);
+ memcpy(p, str, len);
+ p[len] = '\0';
+
+ return(p);
+}
+
+/*
+ * bmake_realloc --
+ * realloc, but die on error.
+ */
+void *
+bmake_realloc(void *ptr, size_t size)
+{
+ if ((ptr = realloc(ptr, size)) == NULL)
+ enomem();
+ return(ptr);
+}
+#endif
diff --git a/external/bsd/bmake/dist/make_malloc.h b/external/bsd/bmake/dist/make_malloc.h
new file mode 100644
index 0000000..36d3eff
--- /dev/null
+++ b/external/bsd/bmake/dist/make_malloc.h
@@ -0,0 +1,41 @@
+/* $NetBSD: make_malloc.h,v 1.4 2009/01/24 14:43:29 dsl Exp $ */
+
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef USE_EMALLOC
+void *bmake_malloc(size_t);
+void *bmake_realloc(void *, size_t);
+char *bmake_strdup(const char *);
+char *bmake_strndup(const char *, size_t);
+#else
+#include <util.h>
+#define bmake_malloc(x) emalloc(x)
+#define bmake_realloc(x,y) erealloc(x,y)
+#define bmake_strdup(x) estrdup(x)
+#define bmake_strndup(x,y) estrndup(x,y)
+#endif
+
diff --git a/external/bsd/bmake/dist/meta.c b/external/bsd/bmake/dist/meta.c
new file mode 100644
index 0000000..77af4e8
--- /dev/null
+++ b/external/bsd/bmake/dist/meta.c
@@ -0,0 +1,1346 @@
+/* $NetBSD: meta.c,v 1.25 2012/06/27 17:22:58 sjg Exp $ */
+
+/*
+ * Implement 'meta' mode.
+ * Adapted from John Birrell's patches to FreeBSD make.
+ * --sjg
+ */
+/*
+ * Copyright (c) 2009-2010, Juniper Networks, Inc.
+ * Portions Copyright (c) 2009, John Birrell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#if defined(USE_META)
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <errno.h>
+#if !defined(HAVE_CONFIG_H) || defined(HAVE_ERR_H)
+#include <err.h>
+#endif
+
+#include "make.h"
+#include "job.h"
+
+#ifdef HAVE_FILEMON_H
+# include <filemon.h>
+#endif
+#if !defined(USE_FILEMON) && defined(FILEMON_SET_FD)
+# define USE_FILEMON
+#endif
+
+static BuildMon Mybm; /* for compat */
+static Lst metaBailiwick; /* our scope of control */
+
+Boolean useMeta = FALSE;
+static Boolean useFilemon = FALSE;
+static Boolean writeMeta = FALSE;
+static Boolean metaEnv = FALSE; /* don't save env unless asked */
+static Boolean metaVerbose = FALSE;
+static Boolean metaIgnoreCMDs = FALSE; /* ignore CMDs in .meta files */
+static Boolean metaCurdirOk = FALSE; /* write .meta in .CURDIR Ok? */
+static Boolean metaSilent = FALSE; /* if we have a .meta be SILENT */
+
+extern Boolean forceJobs;
+extern Boolean comatMake;
+extern char **environ;
+
+#define MAKE_META_PREFIX ".MAKE.META.PREFIX"
+
+#ifndef N2U
+# define N2U(n, u) (((n) + ((u) - 1)) / (u))
+#endif
+#ifndef ROUNDUP
+# define ROUNDUP(n, u) (N2U((n), (u)) * (u))
+#endif
+
+#if !defined(HAVE_STRSEP)
+# define strsep(s, d) stresep((s), (d), 0)
+#endif
+
+/*
+ * Filemon is a kernel module which snoops certain syscalls.
+ *
+ * C chdir
+ * E exec
+ * F [v]fork
+ * L [sym]link
+ * M rename
+ * R read
+ * W write
+ * S stat
+ *
+ * See meta_oodate below - we mainly care about 'E' and 'R'.
+ *
+ * We can still use meta mode without filemon, but
+ * the benefits are more limited.
+ */
+#ifdef USE_FILEMON
+# ifndef _PATH_FILEMON
+# define _PATH_FILEMON "/dev/filemon"
+# endif
+
+/*
+ * Open the filemon device.
+ */
+static void
+filemon_open(BuildMon *pbm)
+{
+ int retry;
+
+ pbm->mon_fd = pbm->filemon_fd = -1;
+ if (!useFilemon)
+ return;
+
+ for (retry = 5; retry >= 0; retry--) {
+ if ((pbm->filemon_fd = open(_PATH_FILEMON, O_RDWR)) >= 0)
+ break;
+ }
+
+ if (pbm->filemon_fd < 0) {
+ useFilemon = FALSE;
+ warn("Could not open %s", _PATH_FILEMON);
+ return;
+ }
+
+ /*
+ * We use a file outside of '.'
+ * to avoid a FreeBSD kernel bug where unlink invalidates
+ * cwd causing getcwd to do a lot more work.
+ * We only care about the descriptor.
+ */
+ pbm->mon_fd = mkTempFile("filemon.XXXXXX", NULL);
+ if (ioctl(pbm->filemon_fd, FILEMON_SET_FD, &pbm->mon_fd) < 0) {
+ err(1, "Could not set filemon file descriptor!");
+ }
+ /* we don't need these once we exec */
+ (void)fcntl(pbm->mon_fd, F_SETFD, 1);
+ (void)fcntl(pbm->filemon_fd, F_SETFD, 1);
+}
+
+/*
+ * Read the build monitor output file and write records to the target's
+ * metadata file.
+ */
+static void
+filemon_read(FILE *mfp, int fd)
+{
+ FILE *fp;
+ char buf[BUFSIZ];
+
+ /* Check if we're not writing to a meta data file.*/
+ if (mfp == NULL) {
+ if (fd >= 0)
+ close(fd); /* not interested */
+ return;
+ }
+ /* rewind */
+ (void)lseek(fd, (off_t)0, SEEK_SET);
+ if ((fp = fdopen(fd, "r")) == NULL)
+ err(1, "Could not read build monitor file '%d'", fd);
+
+ fprintf(mfp, "-- filemon acquired metadata --\n");
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ fprintf(mfp, "%s", buf);
+ }
+ fflush(mfp);
+ clearerr(fp);
+ fclose(fp);
+}
+#endif
+
+/*
+ * when realpath() fails,
+ * we use this, to clean up ./ and ../
+ */
+static void
+eat_dots(char *buf, size_t bufsz, int dots)
+{
+ char *cp;
+ char *cp2;
+ const char *eat;
+ size_t eatlen;
+
+ switch (dots) {
+ case 1:
+ eat = "/./";
+ eatlen = 2;
+ break;
+ case 2:
+ eat = "/../";
+ eatlen = 3;
+ break;
+ default:
+ return;
+ }
+
+ do {
+ cp = strstr(buf, eat);
+ if (cp) {
+ cp2 = cp + eatlen;
+ if (dots == 2 && cp > buf) {
+ do {
+ cp--;
+ } while (cp > buf && *cp != '/');
+ }
+ if (*cp == '/') {
+ strlcpy(cp, cp2, bufsz - (cp - buf));
+ } else {
+ return; /* can't happen? */
+ }
+ }
+ } while (cp);
+}
+
+static char *
+meta_name(struct GNode *gn, char *mname, size_t mnamelen,
+ const char *dname,
+ const char *tname)
+{
+ char buf[MAXPATHLEN];
+ char cwd[MAXPATHLEN];
+ char *rp;
+ char *cp;
+ char *tp;
+ char *p[4]; /* >= number of possible uses */
+ int i;
+
+ i = 0;
+ if (!dname)
+ dname = Var_Value(".OBJDIR", gn, &p[i++]);
+ if (!tname)
+ tname = Var_Value(TARGET, gn, &p[i++]);
+
+ if (realpath(dname, cwd))
+ dname = cwd;
+
+ /*
+ * Weed out relative paths from the target file name.
+ * We have to be careful though since if target is a
+ * symlink, the result will be unstable.
+ * So we use realpath() just to get the dirname, and leave the
+ * basename as given to us.
+ */
+ if ((cp = strrchr(tname, '/'))) {
+ if (realpath(tname, buf)) {
+ if ((rp = strrchr(buf, '/'))) {
+ rp++;
+ cp++;
+ if (strcmp(cp, rp) != 0)
+ strlcpy(rp, cp, sizeof(buf) - (rp - buf));
+ }
+ tname = buf;
+ } else {
+ /*
+ * We likely have a directory which is about to be made.
+ * We pretend realpath() succeeded, to have a chance
+ * of generating the same meta file name that we will
+ * next time through.
+ */
+ if (tname[0] == '/') {
+ strlcpy(buf, tname, sizeof(buf));
+ } else {
+ snprintf(buf, sizeof(buf), "%s/%s", cwd, tname);
+ }
+ eat_dots(buf, sizeof(buf), 1); /* ./ */
+ eat_dots(buf, sizeof(buf), 2); /* ../ */
+ tname = buf;
+ }
+ }
+ /* on some systems dirname may modify its arg */
+ tp = bmake_strdup(tname);
+ if (strcmp(dname, dirname(tp)) == 0)
+ snprintf(mname, mnamelen, "%s.meta", tname);
+ else {
+ snprintf(mname, mnamelen, "%s/%s.meta", dname, tname);
+
+ /*
+ * Replace path separators in the file name after the
+ * current object directory path.
+ */
+ cp = mname + strlen(dname) + 1;
+
+ while (*cp != '\0') {
+ if (*cp == '/')
+ *cp = '_';
+ cp++;
+ }
+ }
+ free(tp);
+ for (i--; i >= 0; i--) {
+ if (p[i])
+ free(p[i]);
+ }
+ return (mname);
+}
+
+/*
+ * Return true if running ${.MAKE}
+ * Bypassed if target is flagged .MAKE
+ */
+static int
+is_submake(void *cmdp, void *gnp)
+{
+ static char *p_make = NULL;
+ static int p_len;
+ char *cmd = cmdp;
+ GNode *gn = gnp;
+ char *mp = NULL;
+ char *cp;
+ char *cp2;
+ int rc = 0; /* keep looking */
+
+ if (!p_make) {
+ p_make = Var_Value(".MAKE", gn, &cp);
+ p_len = strlen(p_make);
+ }
+ cp = strchr(cmd, '$');
+ if ((cp)) {
+ mp = Var_Subst(NULL, cmd, gn, FALSE);
+ cmd = mp;
+ }
+ cp2 = strstr(cmd, p_make);
+ if ((cp2)) {
+ switch (cp2[p_len]) {
+ case '\0':
+ case ' ':
+ case '\t':
+ case '\n':
+ rc = 1;
+ break;
+ }
+ if (cp2 > cmd && rc > 0) {
+ switch (cp2[-1]) {
+ case ' ':
+ case '\t':
+ case '\n':
+ break;
+ default:
+ rc = 0; /* no match */
+ break;
+ }
+ }
+ }
+ if (mp)
+ free(mp);
+ return (rc);
+}
+
+typedef struct meta_file_s {
+ FILE *fp;
+ GNode *gn;
+} meta_file_t;
+
+static int
+printCMD(void *cmdp, void *mfpp)
+{
+ meta_file_t *mfp = mfpp;
+ char *cmd = cmdp;
+ char *cp = NULL;
+
+ if (strchr(cmd, '$')) {
+ cmd = cp = Var_Subst(NULL, cmd, mfp->gn, FALSE);
+ }
+ fprintf(mfp->fp, "CMD %s\n", cmd);
+ if (cp)
+ free(cp);
+ return 0;
+}
+
+/*
+ * Certain node types never get a .meta file
+ */
+#define SKIP_META_TYPE(_type) do { \
+ if ((gn->type & __CONCAT(OP_, _type))) { \
+ if (DEBUG(META)) { \
+ fprintf(debug_file, "Skipping meta for %s: .%s\n", \
+ gn->name, __STRING(_type)); \
+ } \
+ return (NULL); \
+ } \
+} while (0)
+
+static FILE *
+meta_create(BuildMon *pbm, GNode *gn)
+{
+ meta_file_t mf;
+ char buf[MAXPATHLEN];
+ char objdir[MAXPATHLEN];
+ char **ptr;
+ const char *dname;
+ const char *tname;
+ char *fname;
+ const char *cp;
+ char *p[4]; /* >= possible uses */
+ int i;
+ struct stat fs;
+
+
+ /* This may be a phony node which we don't want meta data for... */
+ /* Skip .meta for .BEGIN, .END, .ERROR etc as well. */
+ /* Or it may be explicitly flagged as .NOMETA */
+ SKIP_META_TYPE(NOMETA);
+ /* Unless it is explicitly flagged as .META */
+ if (!(gn->type & OP_META)) {
+ SKIP_META_TYPE(PHONY);
+ SKIP_META_TYPE(SPECIAL);
+ SKIP_META_TYPE(MAKE);
+ }
+
+ mf.fp = NULL;
+
+ i = 0;
+
+ dname = Var_Value(".OBJDIR", gn, &p[i++]);
+ tname = Var_Value(TARGET, gn, &p[i++]);
+
+ /* The object directory may not exist. Check it.. */
+ if (stat(dname, &fs) != 0) {
+ if (DEBUG(META))
+ fprintf(debug_file, "Skipping meta for %s: no .OBJDIR\n",
+ gn->name);
+ goto out;
+ }
+ /* Check if there are no commands to execute. */
+ if (Lst_IsEmpty(gn->commands)) {
+ if (DEBUG(META))
+ fprintf(debug_file, "Skipping meta for %s: no commands\n",
+ gn->name);
+ goto out;
+ }
+
+ /* make sure these are canonical */
+ if (realpath(dname, objdir))
+ dname = objdir;
+
+ /* If we aren't in the object directory, don't create a meta file. */
+ if (!metaCurdirOk && strcmp(curdir, dname) == 0) {
+ if (DEBUG(META))
+ fprintf(debug_file, "Skipping meta for %s: .OBJDIR == .CURDIR\n",
+ gn->name);
+ goto out;
+ }
+ if (!(gn->type & OP_META)) {
+ /* We do not generate .meta files for sub-makes */
+ if (Lst_ForEach(gn->commands, is_submake, gn)) {
+ if (DEBUG(META))
+ fprintf(debug_file, "Skipping meta for %s: .MAKE\n",
+ gn->name);
+ goto out;
+ }
+ }
+
+ if (metaVerbose) {
+ char *mp;
+
+ /* Describe the target we are building */
+ mp = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", gn, 0);
+ if (*mp)
+ fprintf(stdout, "%s\n", mp);
+ free(mp);
+ }
+ /* Get the basename of the target */
+ if ((cp = strrchr(tname, '/')) == NULL) {
+ cp = tname;
+ } else {
+ cp++;
+ }
+
+ fflush(stdout);
+
+ if (strcmp(cp, makeDependfile) == 0)
+ goto out;
+
+ if (!writeMeta)
+ /* Don't create meta data. */
+ goto out;
+
+ fname = meta_name(gn, pbm->meta_fname, sizeof(pbm->meta_fname),
+ dname, tname);
+
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "meta_create: %s\n", fname);
+#endif
+
+ if ((mf.fp = fopen(fname, "w")) == NULL)
+ err(1, "Could not open meta file '%s'", fname);
+
+ fprintf(mf.fp, "# Meta data file %s\n", fname);
+
+ mf.gn = gn;
+
+ Lst_ForEach(gn->commands, printCMD, &mf);
+
+ fprintf(mf.fp, "CWD %s\n", getcwd(buf, sizeof(buf)));
+ fprintf(mf.fp, "TARGET %s\n", tname);
+
+ if (metaEnv) {
+ for (ptr = environ; *ptr != NULL; ptr++)
+ fprintf(mf.fp, "ENV %s\n", *ptr);
+ }
+
+ fprintf(mf.fp, "-- command output --\n");
+ fflush(mf.fp);
+
+ Var_Append(".MAKE.META.FILES", fname, VAR_GLOBAL);
+ Var_Append(".MAKE.META.CREATED", fname, VAR_GLOBAL);
+
+ gn->type |= OP_META; /* in case anyone wants to know */
+ if (metaSilent) {
+ gn->type |= OP_SILENT;
+ }
+ out:
+ for (i--; i >= 0; i--) {
+ if (p[i])
+ free(p[i]);
+ }
+
+ return (mf.fp);
+}
+
+static Boolean
+boolValue(char *s)
+{
+ switch(*s) {
+ case '0':
+ case 'N':
+ case 'n':
+ case 'F':
+ case 'f':
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+meta_init(const char *make_mode)
+{
+ static int once = 0;
+ char *cp;
+
+ useMeta = TRUE;
+ useFilemon = TRUE;
+ writeMeta = TRUE;
+
+ if (make_mode) {
+ if (strstr(make_mode, "env"))
+ metaEnv = TRUE;
+ if (strstr(make_mode, "verb"))
+ metaVerbose = TRUE;
+ if (strstr(make_mode, "read"))
+ writeMeta = FALSE;
+ if (strstr(make_mode, "nofilemon"))
+ useFilemon = FALSE;
+ if ((cp = strstr(make_mode, "curdirok="))) {
+ metaCurdirOk = boolValue(&cp[9]);
+ }
+ if ((cp = strstr(make_mode, "silent="))) {
+ metaSilent = boolValue(&cp[7]);
+ }
+ if (strstr(make_mode, "ignore-cmd"))
+ metaIgnoreCMDs = TRUE;
+ /* for backwards compatability */
+ Var_Set(".MAKE.META_CREATED", "${.MAKE.META.CREATED}", VAR_GLOBAL, 0);
+ Var_Set(".MAKE.META_FILES", "${.MAKE.META.FILES}", VAR_GLOBAL, 0);
+ }
+ if (metaVerbose && !Var_Exists(MAKE_META_PREFIX, VAR_GLOBAL)) {
+ /*
+ * The default value for MAKE_META_PREFIX
+ * prints the absolute path of the target.
+ * This works be cause :H will generate '.' if there is no /
+ * and :tA will resolve that to cwd.
+ */
+ Var_Set(MAKE_META_PREFIX, "Building ${.TARGET:H:tA}/${.TARGET:T}", VAR_GLOBAL, 0);
+ }
+ if (once)
+ return;
+ once = 1;
+ memset(&Mybm, 0, sizeof(Mybm));
+ /*
+ * We consider ourselves master of all within ${.MAKE.META.BAILIWICK}
+ */
+ metaBailiwick = Lst_Init(FALSE);
+ cp = Var_Subst(NULL, "${.MAKE.META.BAILIWICK:O:u:tA}", VAR_GLOBAL, 0);
+ if (cp) {
+ str2Lst_Append(metaBailiwick, cp, NULL);
+ }
+}
+
+/*
+ * In each case below we allow for job==NULL
+ */
+void
+meta_job_start(Job *job, GNode *gn)
+{
+ BuildMon *pbm;
+
+ if (job != NULL) {
+ pbm = &job->bm;
+ } else {
+ pbm = &Mybm;
+ }
+ pbm->mfp = meta_create(pbm, gn);
+#ifdef USE_FILEMON_ONCE
+ /* compat mode we open the filemon dev once per command */
+ if (job == NULL)
+ return;
+#endif
+#ifdef USE_FILEMON
+ if (pbm->mfp != NULL && useFilemon) {
+ filemon_open(pbm);
+ } else {
+ pbm->mon_fd = pbm->filemon_fd = -1;
+ }
+#endif
+}
+
+/*
+ * The child calls this before doing anything.
+ * It does not disturb our state.
+ */
+void
+meta_job_child(Job *job)
+{
+#ifdef USE_FILEMON
+ BuildMon *pbm;
+ pid_t pid;
+
+ if (job != NULL) {
+ pbm = &job->bm;
+ } else {
+ pbm = &Mybm;
+ }
+ pid = getpid();
+ if (pbm->mfp != NULL && useFilemon) {
+ if (ioctl(pbm->filemon_fd, FILEMON_SET_PID, &pid) < 0) {
+ err(1, "Could not set filemon pid!");
+ }
+ }
+#endif
+}
+
+void
+meta_job_error(Job *job, GNode *gn, int flags, int status)
+{
+ char cwd[MAXPATHLEN];
+ BuildMon *pbm;
+
+ if (job != NULL) {
+ pbm = &job->bm;
+ } else {
+ if (!gn)
+ gn = job->node;
+ pbm = &Mybm;
+ }
+ if (pbm->mfp != NULL) {
+ fprintf(pbm->mfp, "*** Error code %d%s\n",
+ status,
+ (flags & JOB_IGNERR) ?
+ "(ignored)" : "");
+ }
+ if (gn) {
+ Var_Set(".ERROR_TARGET", gn->path ? gn->path : gn->name, VAR_GLOBAL, 0);
+ }
+ getcwd(cwd, sizeof(cwd));
+ Var_Set(".ERROR_CWD", cwd, VAR_GLOBAL, 0);
+ if (pbm && pbm->meta_fname[0]) {
+ Var_Set(".ERROR_META_FILE", pbm->meta_fname, VAR_GLOBAL, 0);
+ }
+ meta_job_finish(job);
+}
+
+void
+meta_job_output(Job *job, char *cp, const char *nl)
+{
+ BuildMon *pbm;
+
+ if (job != NULL) {
+ pbm = &job->bm;
+ } else {
+ pbm = &Mybm;
+ }
+ if (pbm->mfp != NULL) {
+ if (metaVerbose) {
+ static char *meta_prefix = NULL;
+ static int meta_prefix_len;
+
+ if (!meta_prefix) {
+ char *cp2;
+
+ meta_prefix = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", VAR_GLOBAL, 0);
+ if ((cp2 = strchr(meta_prefix, '$')))
+ meta_prefix_len = cp2 - meta_prefix;
+ else
+ meta_prefix_len = strlen(meta_prefix);
+ }
+ if (strncmp(cp, meta_prefix, meta_prefix_len) == 0) {
+ cp = strchr(cp+1, '\n');
+ if (!cp++)
+ return;
+ }
+ }
+ fprintf(pbm->mfp, "%s%s", cp, nl);
+ }
+}
+
+void
+meta_cmd_finish(void *pbmp)
+{
+#ifdef USE_FILEMON
+ BuildMon *pbm = pbmp;
+
+ if (!pbm)
+ pbm = &Mybm;
+
+ if (pbm->filemon_fd >= 0) {
+ close(pbm->filemon_fd);
+ filemon_read(pbm->mfp, pbm->mon_fd);
+ pbm->filemon_fd = pbm->mon_fd = -1;
+ }
+#endif
+}
+
+void
+meta_job_finish(Job *job)
+{
+ BuildMon *pbm;
+
+ if (job != NULL) {
+ pbm = &job->bm;
+ } else {
+ pbm = &Mybm;
+ }
+ if (pbm->mfp != NULL) {
+ meta_cmd_finish(pbm);
+ fclose(pbm->mfp);
+ pbm->mfp = NULL;
+ pbm->meta_fname[0] = '\0';
+ }
+}
+
+/*
+ * Fetch a full line from fp - growing bufp if needed
+ * Return length in bufp.
+ */
+static int
+fgetLine(char **bufp, size_t *szp, int o, FILE *fp)
+{
+ char *buf = *bufp;
+ size_t bufsz = *szp;
+ struct stat fs;
+ int x;
+
+ if (fgets(&buf[o], bufsz - o, fp) != NULL) {
+ check_newline:
+ x = o + strlen(&buf[o]);
+ if (buf[x - 1] == '\n')
+ return x;
+ /*
+ * We need to grow the buffer.
+ * The meta file can give us a clue.
+ */
+ if (fstat(fileno(fp), &fs) == 0) {
+ size_t newsz;
+ char *p;
+
+ newsz = ROUNDUP((fs.st_size / 2), BUFSIZ);
+ if (newsz <= bufsz)
+ newsz = ROUNDUP(fs.st_size, BUFSIZ);
+ if (DEBUG(META))
+ fprintf(debug_file, "growing buffer %u -> %u\n",
+ (unsigned)bufsz, (unsigned)newsz);
+ p = bmake_realloc(buf, newsz);
+ if (p) {
+ *bufp = buf = p;
+ *szp = bufsz = newsz;
+ /* fetch the rest */
+ if (!fgets(&buf[x], bufsz - x, fp))
+ return x; /* truncated! */
+ goto check_newline;
+ }
+ }
+ }
+ return 0;
+}
+
+static int
+prefix_match(void *p, void *q)
+{
+ const char *prefix = p;
+ const char *path = q;
+ size_t n = strlen(prefix);
+
+ return (0 == strncmp(path, prefix, n));
+}
+
+static int
+string_match(const void *p, const void *q)
+{
+ const char *p1 = p;
+ const char *p2 = q;
+
+ return strcmp(p1, p2);
+}
+
+
+/*
+ * When running with 'meta' functionality, a target can be out-of-date
+ * if any of the references in it's meta data file is more recent.
+ * We have to track the latestdir on a per-process basis.
+ */
+#define LDIR_VNAME_FMT ".meta.%d.ldir"
+
+/*
+ * It is possible that a .meta file is corrupted,
+ * if we detect this we want to reproduce it.
+ * Setting oodate TRUE will have that effect.
+ */
+#define CHECK_VALID_META(p) if (!(p && *p)) { \
+ warnx("%s: %d: malformed", fname, lineno); \
+ oodate = TRUE; \
+ continue; \
+ }
+
+Boolean
+meta_oodate(GNode *gn, Boolean oodate)
+{
+ static char *tmpdir = NULL;
+ static char cwd[MAXPATHLEN];
+ char ldir_vname[64];
+ char latestdir[MAXPATHLEN];
+ char fname[MAXPATHLEN];
+ char fname1[MAXPATHLEN];
+ char fname2[MAXPATHLEN];
+ char *p;
+ char *cp;
+ static size_t cwdlen = 0;
+ static size_t tmplen = 0;
+ FILE *fp;
+ Boolean ignoreOODATE = FALSE;
+ Lst missingFiles;
+
+ if (oodate)
+ return oodate; /* we're done */
+
+ missingFiles = Lst_Init(FALSE);
+
+ /*
+ * We need to check if the target is out-of-date. This includes
+ * checking if the expanded command has changed. This in turn
+ * requires that all variables are set in the same way that they
+ * would be if the target needs to be re-built.
+ */
+ Make_DoAllVar(gn);
+
+ meta_name(gn, fname, sizeof(fname), NULL, NULL);
+
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "meta_oodate: %s\n", fname);
+#endif
+
+ if ((fp = fopen(fname, "r")) != NULL) {
+ static char *buf = NULL;
+ static size_t bufsz;
+ int lineno = 0;
+ int lastpid = 0;
+ int pid;
+ int f = 0;
+ int x;
+ LstNode ln;
+ struct stat fs;
+
+ if (!buf) {
+ bufsz = 8 * BUFSIZ;
+ buf = bmake_malloc(bufsz);
+ }
+
+ if (!cwdlen) {
+ if (getcwd(cwd, sizeof(cwd)) == NULL)
+ err(1, "Could not get current working directory");
+ cwdlen = strlen(cwd);
+ }
+
+ if (!tmpdir) {
+ tmpdir = getTmpdir();
+ tmplen = strlen(tmpdir);
+ }
+
+ /* we want to track all the .meta we read */
+ Var_Append(".MAKE.META.FILES", fname, VAR_GLOBAL);
+
+ ln = Lst_First(gn->commands);
+ while (!oodate && (x = fgetLine(&buf, &bufsz, 0, fp)) > 0) {
+ lineno++;
+ if (buf[x - 1] == '\n')
+ buf[x - 1] = '\0';
+ else {
+ warnx("%s: %d: line truncated at %u", fname, lineno, x);
+ oodate = TRUE;
+ break;
+ }
+ /* Find the start of the build monitor section. */
+ if (!f) {
+ if (strncmp(buf, "-- filemon", 10) == 0) {
+ f = 1;
+ continue;
+ }
+ if (strncmp(buf, "# buildmon", 10) == 0) {
+ f = 1;
+ continue;
+ }
+ }
+
+ /* Delimit the record type. */
+ p = buf;
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: %s\n", fname, lineno, buf);
+#endif
+ strsep(&p, " ");
+ if (f) {
+ /*
+ * We are in the 'filemon' output section.
+ * Each record from filemon follows the general form:
+ *
+ * <key> <pid> <data>
+ *
+ * Where:
+ * <key> is a single letter, denoting the syscall.
+ * <pid> is the process that made the syscall.
+ * <data> is the arguments (of interest).
+ */
+ switch(buf[0]) {
+ case '#': /* comment */
+ case 'V': /* version */
+ break;
+ default:
+ /*
+ * We need to track pathnames per-process.
+ *
+ * Each process run by make, starts off in the 'CWD'
+ * recorded in the .meta file, if it chdirs ('C')
+ * elsewhere we need to track that - but only for
+ * that process. If it forks ('F'), we initialize
+ * the child to have the same cwd as its parent.
+ *
+ * We also need to track the 'latestdir' of
+ * interest. This is usually the same as cwd, but
+ * not if a process is reading directories.
+ *
+ * Each time we spot a different process ('pid')
+ * we save the current value of 'latestdir' in a
+ * variable qualified by 'lastpid', and
+ * re-initialize 'latestdir' to any pre-saved
+ * value for the current 'pid' and 'CWD' if none.
+ */
+ CHECK_VALID_META(p);
+ pid = atoi(p);
+ if (pid > 0 && pid != lastpid) {
+ char *ldir;
+ char *tp;
+
+ if (lastpid > 0) {
+ /* We need to remember this. */
+ Var_Set(ldir_vname, latestdir, VAR_GLOBAL, 0);
+ }
+ snprintf(ldir_vname, sizeof(ldir_vname), LDIR_VNAME_FMT, pid);
+ lastpid = pid;
+ ldir = Var_Value(ldir_vname, VAR_GLOBAL, &tp);
+ if (ldir) {
+ strlcpy(latestdir, ldir, sizeof(latestdir));
+ if (tp)
+ free(tp);
+ } else
+ strlcpy(latestdir, cwd, sizeof(latestdir));
+ }
+ /* Skip past the pid. */
+ if (strsep(&p, " ") == NULL)
+ continue;
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: cwd=%s ldir=%s\n", fname, lineno, cwd, latestdir);
+#endif
+ break;
+ }
+
+ CHECK_VALID_META(p);
+
+ /* Process according to record type. */
+ switch (buf[0]) {
+ case 'X': /* eXit */
+ Var_Delete(ldir_vname, VAR_GLOBAL);
+ lastpid = 0; /* no need to save ldir_vname */
+ break;
+
+ case 'F': /* [v]Fork */
+ {
+ char cldir[64];
+ int child;
+
+ child = atoi(p);
+ if (child > 0) {
+ snprintf(cldir, sizeof(cldir), LDIR_VNAME_FMT, child);
+ Var_Set(cldir, latestdir, VAR_GLOBAL, 0);
+ }
+ }
+ break;
+
+ case 'C': /* Chdir */
+ /* Update the latest directory. */
+ strlcpy(latestdir, p, sizeof(latestdir));
+ break;
+
+ case 'M': /* renaMe */
+ if (Lst_IsEmpty(missingFiles))
+ break;
+ /* 'L' and 'M' put single quotes around the args */
+ if (*p == '\'') {
+ char *ep;
+
+ p++;
+ if ((ep = strchr(p, '\'')))
+ *ep = '\0';
+ }
+ /* FALLTHROUGH */
+ case 'D': /* unlink */
+ if (*p == '/' && !Lst_IsEmpty(missingFiles)) {
+ /* remove p from the missingFiles list if present */
+ if ((ln = Lst_Find(missingFiles, p, string_match)) != NULL) {
+ char *tp = Lst_Datum(ln);
+ Lst_Remove(missingFiles, ln);
+ free(tp);
+ }
+ }
+ break;
+ case 'L': /* Link */
+ /* we want the target */
+ if (strsep(&p, " ") == NULL)
+ continue;
+ CHECK_VALID_META(p);
+ /* 'L' and 'M' put single quotes around the args */
+ if (*p == '\'') {
+ char *ep;
+
+ p++;
+ if ((ep = strchr(p, '\'')))
+ *ep = '\0';
+ }
+ /* FALLTHROUGH */
+ case 'W': /* Write */
+ /*
+ * If a file we generated within our bailiwick
+ * but outside of .OBJDIR is missing,
+ * we need to do it again.
+ */
+ /* ignore non-absolute paths */
+ if (*p != '/')
+ break;
+
+ if (Lst_IsEmpty(metaBailiwick))
+ break;
+
+ /* ignore cwd - normal dependencies handle those */
+ if (strncmp(p, cwd, cwdlen) == 0)
+ break;
+
+ if (!Lst_ForEach(metaBailiwick, prefix_match, p))
+ break;
+
+ /* tmpdir might be within */
+ if (tmplen > 0 && strncmp(p, tmpdir, tmplen) == 0)
+ break;
+
+ /* ignore anything containing the string "tmp" */
+ if ((strstr("tmp", p)))
+ break;
+
+ if (stat(p, &fs) < 0) {
+ Lst_AtEnd(missingFiles, bmake_strdup(p));
+ }
+ break;
+ case 'R': /* Read */
+ case 'E': /* Exec */
+ /*
+ * Check for runtime files that can't
+ * be part of the dependencies because
+ * they are _expected_ to change.
+ */
+ if (strncmp(p, "/tmp/", 5) == 0 ||
+ (tmplen > 0 && strncmp(p, tmpdir, tmplen) == 0))
+ break;
+
+ if (strncmp(p, "/var/", 5) == 0)
+ break;
+
+ /* Ignore device files. */
+ if (strncmp(p, "/dev/", 5) == 0)
+ break;
+
+ /* Ignore /etc/ files. */
+ if (strncmp(p, "/etc/", 5) == 0)
+ break;
+
+ if ((cp = strrchr(p, '/'))) {
+ cp++;
+ /*
+ * We don't normally expect to see this,
+ * but we do expect it to change.
+ */
+ if (strcmp(cp, makeDependfile) == 0)
+ break;
+ }
+
+ /*
+ * The rest of the record is the file name.
+ * Check if it's not an absolute path.
+ */
+ {
+ char *sdirs[4];
+ char **sdp;
+ int sdx = 0;
+ int found = 0;
+
+ if (*p == '/') {
+ sdirs[sdx++] = p; /* done */
+ } else {
+ if (strcmp(".", p) == 0)
+ continue; /* no point */
+
+ /* Check vs latestdir */
+ snprintf(fname1, sizeof(fname1), "%s/%s", latestdir, p);
+ sdirs[sdx++] = fname1;
+
+ if (strcmp(latestdir, cwd) != 0) {
+ /* Check vs cwd */
+ snprintf(fname2, sizeof(fname2), "%s/%s", cwd, p);
+ sdirs[sdx++] = fname2;
+ }
+ }
+ sdirs[sdx++] = NULL;
+
+ for (sdp = sdirs; *sdp && !found; sdp++) {
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: looking for: %s\n", fname, lineno, *sdp);
+#endif
+ if (stat(*sdp, &fs) == 0) {
+ found = 1;
+ p = *sdp;
+ }
+ }
+ if (found) {
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: found: %s\n", fname, lineno, p);
+#endif
+ if (!S_ISDIR(fs.st_mode) &&
+ fs.st_mtime > gn->mtime) {
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: file '%s' is newer than the target...\n", fname, lineno, p);
+ oodate = TRUE;
+ } else if (S_ISDIR(fs.st_mode)) {
+ /* Update the latest directory. */
+ realpath(p, latestdir);
+ }
+ } else if (errno == ENOENT && *p == '/' &&
+ strncmp(p, cwd, cwdlen) != 0) {
+ /*
+ * A referenced file outside of CWD is missing.
+ * We cannot catch every eventuality here...
+ */
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: file '%s' may have moved?...\n", fname, lineno, p);
+ oodate = TRUE;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ } else if (strcmp(buf, "CMD") == 0) {
+ /*
+ * Compare the current command with the one in the
+ * meta data file.
+ */
+ if (ln == NULL) {
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: there were more build commands in the meta data file than there are now...\n", fname, lineno);
+ oodate = TRUE;
+ } else {
+ char *cmd = (char *)Lst_Datum(ln);
+
+ if (!ignoreOODATE) {
+ if (strstr(cmd, "$?"))
+ ignoreOODATE = TRUE;
+ else if ((cp = strstr(cmd, ".OODATE"))) {
+ /* check for $[{(].OODATE[)}] */
+ if (cp > cmd + 2 && cp[-2] == '$')
+ ignoreOODATE = TRUE;
+ }
+ if (ignoreOODATE && DEBUG(META))
+ fprintf(debug_file, "%s: %d: cannot compare commands using .OODATE\n", fname, lineno);
+ }
+ cmd = Var_Subst(NULL, cmd, gn, TRUE);
+
+ if ((cp = strchr(cmd, '\n'))) {
+ int n;
+
+ /*
+ * This command contains newlines, we need to
+ * fetch more from the .meta file before we
+ * attempt a comparison.
+ */
+ /* first put the newline back at buf[x - 1] */
+ buf[x - 1] = '\n';
+ do {
+ /* now fetch the next line */
+ if ((n = fgetLine(&buf, &bufsz, x, fp)) <= 0)
+ break;
+ x = n;
+ lineno++;
+ if (buf[x - 1] != '\n') {
+ warnx("%s: %d: line truncated at %u", fname, lineno, x);
+ break;
+ }
+ cp = strchr(++cp, '\n');
+ } while (cp);
+ if (buf[x - 1] == '\n')
+ buf[x - 1] = '\0';
+ }
+ if (!ignoreOODATE &&
+ !(gn->type & OP_NOMETA_CMP) &&
+ strcmp(p, cmd) != 0) {
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: a build command has changed\n%s\nvs\n%s\n", fname, lineno, p, cmd);
+ if (!metaIgnoreCMDs)
+ oodate = TRUE;
+ }
+ free(cmd);
+ ln = Lst_Succ(ln);
+ }
+ } else if (strcmp(buf, "CWD") == 0) {
+ /*
+ * Check if there are extra commands now
+ * that weren't in the meta data file.
+ */
+ if (!oodate && ln != NULL) {
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: there are extra build commands now that weren't in the meta data file\n", fname, lineno);
+ oodate = TRUE;
+ }
+ if (strcmp(p, cwd) != 0) {
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: the current working directory has changed from '%s' to '%s'\n", fname, lineno, p, curdir);
+ oodate = TRUE;
+ }
+ }
+ }
+
+ fclose(fp);
+ if (!Lst_IsEmpty(missingFiles)) {
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: missing files: %s...\n",
+ fname, (char *)Lst_Datum(Lst_First(missingFiles)));
+ oodate = TRUE;
+ Lst_Destroy(missingFiles, (FreeProc *)free);
+ }
+ } else {
+ if ((gn->type & OP_META)) {
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: required but missing\n", fname);
+ oodate = TRUE;
+ }
+ }
+ if (oodate && ignoreOODATE) {
+ /*
+ * Target uses .OODATE, so we need to re-compute it.
+ * We need to clean up what Make_DoAllVar() did.
+ */
+ Var_Delete(ALLSRC, gn);
+ Var_Delete(OODATE, gn);
+ gn->flags &= ~DONE_ALLSRC;
+ }
+ return oodate;
+}
+
+/* support for compat mode */
+
+static int childPipe[2];
+
+void
+meta_compat_start(void)
+{
+#ifdef USE_FILEMON_ONCE
+ /*
+ * We need to re-open filemon for each cmd.
+ */
+ BuildMon *pbm = &Mybm;
+
+ if (pbm->mfp != NULL && useFilemon) {
+ filemon_open(pbm);
+ } else {
+ pbm->mon_fd = pbm->filemon_fd = -1;
+ }
+#endif
+ if (pipe(childPipe) < 0)
+ Punt("Cannot create pipe: %s", strerror(errno));
+ /* Set close-on-exec flag for both */
+ (void)fcntl(childPipe[0], F_SETFD, 1);
+ (void)fcntl(childPipe[1], F_SETFD, 1);
+}
+
+void
+meta_compat_child(void)
+{
+ meta_job_child(NULL);
+ if (dup2(childPipe[1], 1) < 0 ||
+ dup2(1, 2) < 0) {
+ execError("dup2", "pipe");
+ _exit(1);
+ }
+}
+
+void
+meta_compat_parent(void)
+{
+ FILE *fp;
+ char buf[BUFSIZ];
+
+ close(childPipe[1]); /* child side */
+ fp = fdopen(childPipe[0], "r");
+ while (fgets(buf, sizeof(buf), fp)) {
+ meta_job_output(NULL, buf, "");
+ printf("%s", buf);
+ }
+ fclose(fp);
+}
+
+#endif /* USE_META */
diff --git a/external/bsd/bmake/dist/meta.h b/external/bsd/bmake/dist/meta.h
new file mode 100644
index 0000000..1ce01ca
--- /dev/null
+++ b/external/bsd/bmake/dist/meta.h
@@ -0,0 +1,54 @@
+/* $NetBSD: meta.h,v 1.2 2011/03/30 22:03:49 sjg Exp $ */
+
+/*
+ * Things needed for 'meta' mode.
+ */
+/*
+ * Copyright (c) 2009-2010, Juniper Networks, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef struct BuildMon {
+ char meta_fname[MAXPATHLEN];
+ int filemon_fd;
+ int mon_fd;
+ FILE *mfp;
+} BuildMon;
+
+extern Boolean useMeta;
+
+struct Job; /* not defined yet */
+void meta_init(const char *);
+void meta_job_start(struct Job *, GNode *);
+void meta_job_child(struct Job *);
+void meta_job_error(struct Job *, GNode *, int, int);
+void meta_job_output(struct Job *, char *, const char *);
+void meta_cmd_finish(void *);
+void meta_job_finish(struct Job *);
+Boolean meta_oodate(GNode *, Boolean);
+void meta_compat_start(void);
+void meta_compat_child(void);
+void meta_compat_parent(void);
diff --git a/external/bsd/bmake/dist/mkdeps.sh b/external/bsd/bmake/dist/mkdeps.sh
new file mode 100755
index 0000000..dd87c4f
--- /dev/null
+++ b/external/bsd/bmake/dist/mkdeps.sh
@@ -0,0 +1,314 @@
+:
+# NAME:
+# mkdeps - generate dependencies
+#
+# SYNOPSIS:
+# mkdeps [options] file ...
+#
+# DESCRIPTION:
+# This script updates "makefile" with dependencies for
+# "file"(s). It borrows ideas from various makedepend scripts
+# and should be compatible with most.
+#
+# By default we use grep to extract include file names from
+# source files. We source an "rc" file '$Mydir/.${Myname}rc' which
+# can contain variable assignments such as:
+#.nf
+#
+# cpp_c=/usr/lib/cpp
+# cpp_cc=g++ -E
+# ...
+#
+#.fi
+# If the variable 'cpp_$suffix' is set, we use it as our cpp in
+# place of grep. The program referenced by these variables are
+# expected to produce output like:
+#.nf
+#
+# # 10 \"/usr/include/stdio.h\" 1
+#
+#.fi
+# This allows us to skip most of our processing. For lex,yacc
+# and other source files, grep is probably just as quick and
+# certainly more portable.
+#
+# If the "rc" file does not exist, we create it and attempt to
+# find cpp or an equivalent cc invocation to assign to 'cpp_c'.
+#
+# AUTHOR:
+# Simon J. Gerraty <sjg@zen.void.oz.au>
+#
+
+# RCSid:
+# $Id: mkdeps.sh,v 1.23 2002/11/29 06:58:59 sjg Exp $
+#
+# @(#) Copyright (c) 1993 Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@zen.void.oz.au
+#
+
+Myname=`basename $0 .sh`
+Mydir=`dirname $0`
+
+case `echo -n .` in
+-n*) N=; C="\c";;
+*) N=-n; C=;;
+esac
+
+cc_include=-I/usr/include
+
+TF=/tmp/dep.$$
+EF=/tmp/deperr.$$
+> $EF
+
+case "$*" in
+*-n*) # don't use rc file
+ rc=/dev/null
+ norc=yes;;
+*)
+ rc=$Mydir/.${Myname}rc
+ ;;
+esac
+
+update=
+Include=include
+
+if [ x"$norc" = x -a -f $rc ]; then
+ . $rc
+else
+ # if /usr/lib/cpp or equivalent is available it is better than
+ # grepping .c files.
+ # See what (if anything) works on this system...
+ echo : > $rc
+ echo "# pre-processor for .c files" >> $rc
+ # try a couple of sane places first
+ for d in /usr/libexec /usr/lib /usr/bin /lib /usr/ccs/bin
+ do
+ cpp_c=$d/cpp
+ [ -x $cpp_c ] && break
+ done
+
+ if [ -x $cpp_c ]; then
+ echo cpp_c=$cpp_c >> $rc
+ else
+ cpp_c=
+ # rats see if cc can be used
+ echo "#include <stdio.h>" > /tmp/f$$.c
+ echo "main() { return 0; }" >> /tmp/f$$.c
+ # try some sensible args to cc
+ for arg in -E -P -M
+ do
+ ok=`${REALCC:-${CC:-cc}} $arg /tmp/f$$.c 2>/dev/null | grep '^#.*stdio.h' | tail -1`
+ case "$ok" in
+ "") ;;
+ *)
+ cpp_c="${REALCC:-${CC:-cc}} $arg"
+ echo cpp_c="'$cpp_c'" >> $rc
+ break;;
+ esac
+ done
+ rm -f /tmp/f$$.c
+ fi
+fi
+
+clean_up() {
+ trap "" 2 3
+ trap 0
+ if [ -s $EF ]; then
+ egrep -vi "included from|warning" $EF > ${EF}2
+ if [ -s ${EF}2 ]; then
+ cat $EF >&2
+ rm -f .depend
+ ests=1
+ fi
+ fi
+ rm -f $TF $EF*
+ exit ${ests:-0}
+}
+
+# this lot does not work on HPsUX - complain to Hp.
+trap clean_up 0
+trap exit 2 3
+
+get_incs() {
+ case "$cpp" in
+ grep)
+ # set IGNORE="<" to skip system includes
+ egrep '^#[ ]*include' $* | egrep -v "$IGNORE" | \
+ sed -e 's/^.*include[^"<]*["<]//' -e 's/[">].*//g';;
+ *)
+ # $cpp (eg. /usr/lib/cpp or cc -E) should produce output like:
+ # 1 "/usr/include/stdio.h" 2
+ # set IGNORE=/usr/include to skip system includes
+ $cpp $cpp_opts $cc_include $* 2>> $EF | egrep '^#.*\.h"' | sed 's,^#.*"\(.*\)".*,\1,' |
+ egrep -v "$IGNORE" | sort -u;;
+ esac
+}
+
+gen_deps() {
+ llen=$1
+ shift
+
+ for ifile in $*
+ do
+ case "$cpp" in
+ grep)
+ # this lot is not needed if not using grep.
+ for dir in $srcdir $dirlist /usr/include
+ do
+ [ -f "$dir/$ifile" ] && break
+ done
+
+ if [ ! -f "$dir/$ifile" ]; then
+ # produce a useful error message (useful to emacs or error)
+ iline=`grep -n ".*include.*[\"<]$ifile[\">]" $file | cut -d: -f1`
+ echo "\"$file\", line $iline: cannot find include file \"$ifile\"" >> $EF
+ # no point adding to dependency list as the resulting makefile
+ # would not work anyway...
+ continue
+ fi
+ ifile=$dir/$ifile
+
+ # check whether we have done it yet
+ case `grep "$ifile" $TF` in
+ "") echo "$ifile" >> $TF;;
+ *) continue;; # no repeats...
+ esac
+ ;;
+ esac
+
+ len=`expr "$ifile " : '.*'`
+ if [ "`expr $llen + $len`" -gt ${width:-76} ]; then
+ echo "\\" >> .depend
+ echo $N " $C" >> .depend
+ llen=8
+ fi
+ echo $N "$ifile $C" >> .depend
+ llen=`expr $llen + $len`
+
+ case "$cpp" in
+ grep)
+ # this lot is not needed unless using grep.
+ ilist=`get_incs $ifile` # recurse needed?
+ [ "$ilist" ] && llen=`gen_deps $llen $ilist`
+ ;;
+ esac
+ done
+ echo $llen
+}
+
+for f in makefile Makefile
+do
+ test -s $f && { MAKEFILE=$f; break; }
+done
+
+MAKEFILE=${MAKEFILE:-makefile}
+IGNORE=${IGNORE:-"^-"} # won't happen
+obj=o
+cpp_opts= # incase cpp != grep
+vpath=
+append=
+progDep=
+
+set -- `getopt "AanNV:s:w:o:I:D:b:f:i:p" "$@"`
+for key in "$@"
+do
+ case $key in
+ --) shift; break;;
+ -A) Include=;; # cat .depend >> $MAKEFILE
+ -a) append=yes; shift;;
+ -n) shift;; # ignore rc
+ -N) update=no; shift;; # don't update $MAKEFILE
+ -I) cpp_opts="$cpp_opts$1$2 "; dirlist="$dirlist $2"; shift 2;;
+ -o) obj=$2; shift 2;;
+ -s) shift 2;; # can't handle it anyway...
+ -w) width=$2; shift 2;;
+ -f) MAKEFILE=$2; shift 2;;
+ -b) BASEDIR=$2; shift 2;;
+ -i) IGNORE="$2"; shift 2;; # ignore headers matching this...
+ -D) cpp_opts="$cpp_opts$1$2 "; shift 2;;
+ -V) VPATH="$2"; shift 2;; # where to look for files
+ -p) progDep=yes; shift;;
+ esac
+done
+
+[ "$VPATH" ] && vpath=`IFS=:; set -- $VPATH; echo $*`
+
+[ "$append" ] || > .depend
+
+for file in $*
+do
+ cpp=
+ suffix=`expr $file : '.*\.\([^.]*\)'`
+
+ eval cpp=\"\${cpp_${suffix}:-grep}\"
+
+ if [ ! -f $file -a "$vpath" ]; then
+ for d in . $vpath
+ do
+ [ -f $d/$file ] && { file=$d/$file; break; }
+ done
+ fi
+ srcdir=`dirname $file`
+ base=`basename $file .$suffix`
+
+ ilist=`get_incs $file`
+
+ if [ "$ilist" ]; then
+ > $TF
+ if [ "$progDep" ]; then
+ echo "$base: $file \\" >> .depend
+ else
+ echo "$base.$obj: $file \\" >> .depend
+ fi
+ echo $N " $C" >> .depend
+ llen=8
+ llen=`gen_deps $llen $ilist`
+ echo >> .depend
+ echo >> .depend
+ elif [ "$progDep" ]; then
+ echo "$base: $file" >> .depend
+ echo >> .depend
+ fi
+done
+
+if [ -s .depend ]; then
+ # ./foo.h looks ugly
+ mv .depend $TF
+ { test "$BASEDIR" && sed -e "s;$BASEDIR;\$(BASEDIR);g" $TF || cat $TF; } |
+ sed 's;\([^.]\)\./;\1;g' > .depend
+
+ #
+ # Save the manually updated section of the makefile
+ #
+ if [ x$update != xno ]; then
+ trap "" 2 # don't die if we got this far
+
+ # if make doesn't support include, then append our deps...
+ depended=`grep 'include.*\.depend' $MAKEFILE`
+ test "$depended" && clean_up
+
+ sed '/^# DO NOT DELETE.*depend.*$/,$d' < $MAKEFILE > $TF
+ mv $TF $MAKEFILE
+ cat <<! >> $MAKEFILE
+# DO NOT DELETE THIS LINE -- make depend depends on it
+# Do not edit anything below, it was added automagically by $Myname.
+
+!
+
+ case "$Include" in
+ "") cat .depend >> $MAKEFILE;;
+ .include) echo '.include ".depend"' >> $MAKEFILE;;
+ include) echo include .depend >> $MAKEFILE;;
+ esac
+ fi
+fi
+clean_up
diff --git a/external/bsd/bmake/dist/nonints.h b/external/bsd/bmake/dist/nonints.h
new file mode 100644
index 0000000..eeb197e
--- /dev/null
+++ b/external/bsd/bmake/dist/nonints.h
@@ -0,0 +1,198 @@
+/* $NetBSD: nonints.h,v 1.64 2012/06/12 19:21:51 joerg Exp $ */
+
+/*-
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)nonints.h 8.3 (Berkeley) 3/19/94
+ */
+
+/*-
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)nonints.h 8.3 (Berkeley) 3/19/94
+ */
+
+/* arch.c */
+ReturnStatus Arch_ParseArchive(char **, Lst, GNode *);
+void Arch_Touch(GNode *);
+void Arch_TouchLib(GNode *);
+time_t Arch_MTime(GNode *);
+time_t Arch_MemMTime(GNode *);
+void Arch_FindLib(GNode *, Lst);
+Boolean Arch_LibOODate(GNode *);
+void Arch_Init(void);
+void Arch_End(void);
+int Arch_IsLib(GNode *);
+
+/* compat.c */
+int CompatRunCommand(void *, void *);
+void Compat_Run(Lst);
+int Compat_Make(void *, void *);
+
+/* cond.c */
+struct If;
+int Cond_EvalExpression(const struct If *, char *, Boolean *, int);
+int Cond_Eval(char *);
+void Cond_restore_depth(unsigned int);
+unsigned int Cond_save_depth(void);
+
+/* for.c */
+int For_Eval(char *);
+int For_Accum(char *);
+void For_Run(int);
+
+/* job.c */
+#ifdef WAIT_T
+void JobReapChild(pid_t, WAIT_T, Boolean);
+#endif
+
+/* main.c */
+void Main_ParseArgLine(const char *);
+void MakeMode(const char *);
+int main(int, char **);
+char *Cmd_Exec(const char *, const char **);
+void Error(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
+void Fatal(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD;
+void Punt(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD;
+void DieHorribly(void) MAKE_ATTR_DEAD;
+int PrintAddr(void *, void *);
+void Finish(int) MAKE_ATTR_DEAD;
+int eunlink(const char *);
+void execError(const char *, const char *);
+char *getTmpdir(void);
+
+/* parse.c */
+void Parse_Error(int, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
+Boolean Parse_AnyExport(void);
+Boolean Parse_IsVar(char *);
+void Parse_DoVar(char *, GNode *);
+void Parse_AddIncludeDir(char *);
+void Parse_File(const char *, int);
+void Parse_Init(void);
+void Parse_End(void);
+void Parse_SetInput(const char *, int, int, char *(*)(void *, size_t *), void *);
+Lst Parse_MainName(void);
+
+/* str.c */
+char *str_concat(const char *, const char *, int);
+char **brk_string(const char *, int *, Boolean, char **);
+char *Str_FindSubstring(const char *, const char *);
+int Str_Match(const char *, const char *);
+char *Str_SYSVMatch(const char *, const char *, int *len);
+void Str_SYSVSubst(Buffer *, char *, char *, int);
+
+/* suff.c */
+void Suff_ClearSuffixes(void);
+Boolean Suff_IsTransform(char *);
+GNode *Suff_AddTransform(char *);
+int Suff_EndTransform(void *, void *);
+void Suff_AddSuffix(char *, GNode **);
+Lst Suff_GetPath(char *);
+void Suff_DoPaths(void);
+void Suff_AddInclude(char *);
+void Suff_AddLib(char *);
+void Suff_FindDeps(GNode *);
+Lst Suff_FindPath(GNode *);
+void Suff_SetNull(char *);
+void Suff_Init(void);
+void Suff_End(void);
+void Suff_PrintAll(void);
+
+/* targ.c */
+void Targ_Init(void);
+void Targ_End(void);
+Lst Targ_List(void);
+GNode *Targ_NewGN(const char *);
+GNode *Targ_FindNode(const char *, int);
+Lst Targ_FindList(Lst, int);
+Boolean Targ_Ignore(GNode *);
+Boolean Targ_Silent(GNode *);
+Boolean Targ_Precious(GNode *);
+void Targ_SetMain(GNode *);
+int Targ_PrintCmd(void *, void *);
+int Targ_PrintNode(void *, void *);
+char *Targ_FmtTime(time_t);
+void Targ_PrintType(int);
+void Targ_PrintGraph(int);
+void Targ_Propagate(void);
+void Targ_Propagate_Wait(void);
+
+/* var.c */
+void Var_Delete(const char *, GNode *);
+void Var_Set(const char *, const char *, GNode *, int);
+void Var_Append(const char *, const char *, GNode *);
+Boolean Var_Exists(const char *, GNode *);
+char *Var_Value(const char *, GNode *, char **);
+char *Var_Parse(const char *, GNode *, Boolean, int *, void **);
+char *Var_Subst(const char *, const char *, GNode *, Boolean);
+char *Var_GetTail(const char *);
+char *Var_GetHead(const char *);
+void Var_Init(void);
+void Var_End(void);
+void Var_Dump(GNode *);
+void Var_ExportVars(void);
+void Var_Export(char *, int);
+void Var_UnExport(char *);
+
+/* util.c */
+void (*bmake_signal(int, void (*)(int)))(int);
diff --git a/external/bsd/bmake/dist/os.sh b/external/bsd/bmake/dist/os.sh
new file mode 100755
index 0000000..9e45f37
--- /dev/null
+++ b/external/bsd/bmake/dist/os.sh
@@ -0,0 +1,228 @@
+:
+# NAME:
+# os.sh - operating system specifics
+#
+# DESCRIPTION:
+# This file is included at the start of processing. Its role is
+# to set the variables OS, OSREL, OSMAJOR, MACHINE and MACHINE_ARCH to
+# reflect the current system.
+#
+# It also sets variables such as MAILER, LOCAL_FS, PS_AXC to hide
+# certain aspects of different UNIX flavours.
+#
+# SEE ALSO:
+# site.sh,funcs.sh
+#
+# AUTHOR:
+# Simon J. Gerraty <sjg@crufty.net>
+
+# RCSid:
+# $Id: os.sh,v 1.44 2010/06/29 15:37:21 sjg Exp $
+#
+# @(#) Copyright (c) 1994 Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+#
+
+# this lets us skip sourcing it again
+_OS_SH=:
+
+OS=`uname`
+OSREL=`uname -r`
+OSMAJOR=`IFS=.; set $OSREL; echo $1`
+MACHINE=`uname -m`
+MACHINE_ARCH=`uname -p 2>/dev/null || echo $MACHINE`
+
+# there is at least one case of `uname -p` outputting
+# a bunch of usless drivel
+case "$MACHINE_ARCH" in
+*[!A-Za-z0-9_-]*) MACHINE_ARCH="$MACHINE";;
+esac
+
+# we need this here, and it is not always available...
+Which() {
+ case "$1" in
+ -*) t=$1; shift;;
+ *) t=-x;;
+ esac
+ case "$1" in
+ /*) test $t $1 && echo $1;;
+ *)
+ # some shells cannot correctly handle `IFS`
+ # in conjunction with the for loop.
+ _dirs=`IFS=:; echo ${2:-$PATH}`
+ for d in $_dirs
+ do
+ test $t $d/$1 && { echo $d/$1; break; }
+ done
+ ;;
+ esac
+}
+
+# tr is insanely non-portable wrt char classes, so we need to
+# spell out the alphabet. sed y/// would work too.
+toUpper() {
+ ${TR:-tr} abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
+}
+
+toLower() {
+ ${TR:-tr} ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz
+}
+
+K=
+case $OS in
+AIX) # everyone loves to be different...
+ OSMAJOR=`uname -v`
+ OSREL="$OSMAJOR.`uname -r`"
+ LOCAL_FS=jfs
+ PS_AXC=-e
+ SHARE_ARCH=$OS/$OSMAJOR.X
+ ;;
+SunOS)
+ CHOWN=`Which chown /usr/etc:/usr/bin`
+ export CHOWN
+
+ # Great! Solaris keeps moving arch(1)
+ # should just bite the bullet and use uname -p
+ arch=`Which arch /usr/bin:/usr/ucb`
+
+ MAILER=/usr/ucb/Mail
+ LOCAL_FS=4.2
+
+ case "$OSREL" in
+ 4.0*)
+ # uname -m just says sun which could be anything
+ # so use arch(1).
+ MACHINE_ARCH=`arch`
+ MACHINE=$MACHINE_ARCH
+ ;;
+ 4*)
+ MACHINE_ARCH=`arch`
+ ;;
+ 5*)
+ K=-k
+ LOCAL_FS=ufs
+ MAILER=mailx
+ PS_AXC=-e
+ # can you believe that ln on Solaris defaults to
+ # overwriting an existing file!!!!! We want one that works!
+ test -x /usr/xpg4/bin/ln && LN=${LN:-/usr/xpg4/bin/ln}
+ # wonderful, 5.8's tr again require's []'s
+ # but /usr/xpg4/bin/tr causes problems if LC_COLLATE is set!
+ # use toUpper/toLower instead.
+ ;;
+ esac
+ case "$OS/$MACHINE_ARCH" in
+ *sun386) SHARE_ARCH=$MACHINE_ARCH;;
+ esac
+ ;;
+*BSD)
+ K=-k
+ MAILER=/usr/bin/Mail
+ LOCAL_FS=local
+ case "$-" in
+ *i*) ;;
+ *) ENV=;;
+ esac
+ # NetBSD at least has good backward compatability
+ # so NetBSD/i386 is good enough
+ case $OS in
+ NetBSD) SHARE_ARCH=$OS/${MACHINE_ARCH:-$MACHINE};;
+ OpenBSD)
+ arch=`Which arch /usr/bin:/usr/ucb:$PATH`
+ MACHINE_ARCH=`$arch -s`
+ ;;
+ esac
+ NAWK=awk
+ export NAWK
+ ;;
+HP-UX)
+ TMP_DIRS="/tmp /usr/tmp"
+ LOCAL_FS=hfs
+ MAILER=mailx
+ # don't rely on /bin/sh, its broken
+ _shell=/bin/ksh; ENV=
+ # also, no one would be interested in OSMAJOR=A
+ case "$OSREL" in
+ ?.09*) OSMAJOR=9; PS_AXC=-e;;
+ ?.10*) OSMAJOR=10; PS_AXC=-e;;
+ esac
+ ;;
+IRIX)
+ LOCAL_FS=efs
+ ;;
+Interix)
+ MACHINE=i386
+ MACHINE_ARCH=i386
+ ;;
+UnixWare)
+ OSREL=`uname -v`
+ OSMAJOR=`IFS=.; set $OSREL; echo $1`
+ MACHINE_ARCH=`uname -m`
+ ;;
+Linux)
+ # Not really any such thing as Linux, but
+ # this covers red-hat and hopefully others.
+ case $MACHINE in
+ i?86) MACHINE_ARCH=i386;; # we don't care about i686 vs i586
+ esac
+ LOCAL_FS=ext2
+ PS_AXC=axc
+ [ -x /usr/bin/md5sum ] && { MD5=/usr/bin/md5sum; export MD5; }
+ ;;
+QNX)
+ case $MACHINE in
+ x86pc) MACHINE_ARCH=i386;;
+ esac
+ ;;
+Haiku)
+ case $MACHINE in
+ BeBox) MACHINE_ARCH=powerpc;;
+ BeMac) MACHINE_ARCH=powerpc;;
+ BePC) MACHINE_ARCH=i386;;
+ esac
+ ;;
+esac
+
+HOSTNAME=${HOSTNAME:-`( hostname ) 2>/dev/null`}
+HOSTNAME=${HOSTNAME:-`( uname -n ) 2>/dev/null`}
+case "$HOSTNAME" in
+*.*) HOST=`IFS=.; set -- $HOSTNAME; echo $1`;;
+*) HOST=$HOSTNAME;;
+esac
+
+TMP_DIRS=${TMP_DIRS:-"/tmp /var/tmp"}
+MACHINE_ARCH=${MACHINE_ARCH:-$MACHINE}
+# we mount server:/share/arch/$SHARE_ARCH as /usr/local
+SHARE_ARCH=${SHARE_ARCH:-$OS/$OSMAJOR.X/$MACHINE_ARCH}
+LN=${LN:-ln}
+TR=${TR:-tr}
+
+# Some people like have /share/$HOST_TARGET/bin etc.
+HOST_TARGET=`echo ${OS}${OSMAJOR}-${MACHINE_ARCH} | toLower`
+export HOST_TARGET
+
+case `echo -n .` in -n*) N=; C="\c";; *) N=-n; C=;; esac
+
+export HOSTNAME HOST
+export OS MACHINE MACHINE_ARCH OSREL OSMAJOR LOCAL_FS TMP_DIRS MAILER N C K PS_AXC
+export LN SHARE_ARCH TR
+
+case /$0 in
+*/os.sh)
+ for v in $*
+ do
+ eval vv=\$$v
+ echo "$v='$vv'"
+ done
+ ;;
+esac
+
diff --git a/external/bsd/bmake/dist/parse.c b/external/bsd/bmake/dist/parse.c
new file mode 100644
index 0000000..0b18f5d
--- /dev/null
+++ b/external/bsd/bmake/dist/parse.c
@@ -0,0 +1,3122 @@
+/* $NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
+#else
+__RCSID("$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * parse.c --
+ * Functions to parse a makefile.
+ *
+ * One function, Parse_Init, must be called before any functions
+ * in this module are used. After that, the function Parse_File is the
+ * main entry point and controls most of the other functions in this
+ * module.
+ *
+ * Most important structures are kept in Lsts. Directories for
+ * the .include "..." function are kept in the 'parseIncPath' Lst, while
+ * those for the .include <...> are kept in the 'sysIncPath' Lst. The
+ * targets currently being defined are kept in the 'targets' Lst.
+ *
+ * The variables 'fname' and 'lineno' are used to track the name
+ * of the current file and the line number in that file so that error
+ * messages can be more meaningful.
+ *
+ * Interface:
+ * Parse_Init Initialization function which must be
+ * called before anything else in this module
+ * is used.
+ *
+ * Parse_End Cleanup the module
+ *
+ * Parse_File Function used to parse a makefile. It must
+ * be given the name of the file, which should
+ * already have been opened, and a function
+ * to call to read a character from the file.
+ *
+ * Parse_IsVar Returns TRUE if the given line is a
+ * variable assignment. Used by MainParseArgs
+ * to determine if an argument is a target
+ * or a variable assignment. Used internally
+ * for pretty much the same thing...
+ *
+ * Parse_Error Function called when an error occurs in
+ * parsing. Used by the variable and
+ * conditional modules.
+ * Parse_MainName Returns a Lst of the main target to create.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+#include "job.h"
+#include "buf.h"
+#include "pathnames.h"
+
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+
+#ifndef MAP_COPY
+#define MAP_COPY MAP_PRIVATE
+#endif
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+#endif
+
+////////////////////////////////////////////////////////////
+// types and constants
+
+/*
+ * Structure for a file being read ("included file")
+ */
+typedef struct IFile {
+ const char *fname; /* name of file */
+ int lineno; /* current line number in file */
+ int first_lineno; /* line number of start of text */
+ int cond_depth; /* 'if' nesting when file opened */
+ char *P_str; /* point to base of string buffer */
+ char *P_ptr; /* point to next char of string buffer */
+ char *P_end; /* point to the end of string buffer */
+ char *(*nextbuf)(void *, size_t *); /* Function to get more data */
+ void *nextbuf_arg; /* Opaque arg for nextbuf() */
+ struct loadedfile *lf; /* loadedfile object, if any */
+} IFile;
+
+
+/*
+ * These values are returned by ParseEOF to tell Parse_File whether to
+ * CONTINUE parsing, i.e. it had only reached the end of an include file,
+ * or if it's DONE.
+ */
+#define CONTINUE 1
+#define DONE 0
+
+/*
+ * Tokens for target attributes
+ */
+typedef enum {
+ Begin, /* .BEGIN */
+ Default, /* .DEFAULT */
+ End, /* .END */
+ dotError, /* .ERROR */
+ Ignore, /* .IGNORE */
+ Includes, /* .INCLUDES */
+ Interrupt, /* .INTERRUPT */
+ Libs, /* .LIBS */
+ Meta, /* .META */
+ MFlags, /* .MFLAGS or .MAKEFLAGS */
+ Main, /* .MAIN and we don't have anything user-specified to
+ * make */
+ NoExport, /* .NOEXPORT */
+ NoMeta, /* .NOMETA */
+ NoMetaCmp, /* .NOMETA_CMP */
+ NoPath, /* .NOPATH */
+ Not, /* Not special */
+ NotParallel, /* .NOTPARALLEL */
+ Null, /* .NULL */
+ ExObjdir, /* .OBJDIR */
+ Order, /* .ORDER */
+ Parallel, /* .PARALLEL */
+ ExPath, /* .PATH */
+ Phony, /* .PHONY */
+#ifdef POSIX
+ Posix, /* .POSIX */
+#endif
+ Precious, /* .PRECIOUS */
+ ExShell, /* .SHELL */
+ Silent, /* .SILENT */
+ SingleShell, /* .SINGLESHELL */
+ Suffixes, /* .SUFFIXES */
+ Wait, /* .WAIT */
+ Attribute /* Generic attribute */
+} ParseSpecial;
+
+/*
+ * Other tokens
+ */
+#define LPAREN '('
+#define RPAREN ')'
+
+
+////////////////////////////////////////////////////////////
+// result data
+
+/*
+ * The main target to create. This is the first target on the first
+ * dependency line in the first makefile.
+ */
+static GNode *mainNode;
+
+////////////////////////////////////////////////////////////
+// eval state
+
+/* targets we're working on */
+static Lst targets;
+
+#ifdef CLEANUP
+/* command lines for targets */
+static Lst targCmds;
+#endif
+
+/*
+ * specType contains the SPECial TYPE of the current target. It is
+ * Not if the target is unspecial. If it *is* special, however, the children
+ * are linked as children of the parent but not vice versa. This variable is
+ * set in ParseDoDependency
+ */
+static ParseSpecial specType;
+
+/*
+ * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER
+ * seen, then set to each successive source on the line.
+ */
+static GNode *predecessor;
+
+////////////////////////////////////////////////////////////
+// parser state
+
+/* true if currently in a dependency line or its commands */
+static Boolean inLine;
+
+/* number of fatal errors */
+static int fatals = 0;
+
+/*
+ * Variables for doing includes
+ */
+
+/* current file being read */
+static IFile *curFile;
+
+/* stack of IFiles generated by .includes */
+static Lst includes;
+
+/* include paths (lists of directories) */
+Lst parseIncPath; /* dirs for "..." includes */
+Lst sysIncPath; /* dirs for <...> includes */
+Lst defIncPath; /* default for sysIncPath */
+
+////////////////////////////////////////////////////////////
+// parser tables
+
+/*
+ * The parseKeywords table is searched using binary search when deciding
+ * if a target or source is special. The 'spec' field is the ParseSpecial
+ * type of the keyword ("Not" if the keyword isn't special as a target) while
+ * the 'op' field is the operator to apply to the list of targets if the
+ * keyword is used as a source ("0" if the keyword isn't special as a source)
+ */
+static const struct {
+ const char *name; /* Name of keyword */
+ ParseSpecial spec; /* Type when used as a target */
+ int op; /* Operator when used as a source */
+} parseKeywords[] = {
+{ ".BEGIN", Begin, 0 },
+{ ".DEFAULT", Default, 0 },
+{ ".END", End, 0 },
+{ ".ERROR", dotError, 0 },
+{ ".EXEC", Attribute, OP_EXEC },
+{ ".IGNORE", Ignore, OP_IGNORE },
+{ ".INCLUDES", Includes, 0 },
+{ ".INTERRUPT", Interrupt, 0 },
+{ ".INVISIBLE", Attribute, OP_INVISIBLE },
+{ ".JOIN", Attribute, OP_JOIN },
+{ ".LIBS", Libs, 0 },
+{ ".MADE", Attribute, OP_MADE },
+{ ".MAIN", Main, 0 },
+{ ".MAKE", Attribute, OP_MAKE },
+{ ".MAKEFLAGS", MFlags, 0 },
+{ ".META", Meta, OP_META },
+{ ".MFLAGS", MFlags, 0 },
+{ ".NOMETA", NoMeta, OP_NOMETA },
+{ ".NOMETA_CMP", NoMetaCmp, OP_NOMETA_CMP },
+{ ".NOPATH", NoPath, OP_NOPATH },
+{ ".NOTMAIN", Attribute, OP_NOTMAIN },
+{ ".NOTPARALLEL", NotParallel, 0 },
+{ ".NO_PARALLEL", NotParallel, 0 },
+{ ".NULL", Null, 0 },
+{ ".OBJDIR", ExObjdir, 0 },
+{ ".OPTIONAL", Attribute, OP_OPTIONAL },
+{ ".ORDER", Order, 0 },
+{ ".PARALLEL", Parallel, 0 },
+{ ".PATH", ExPath, 0 },
+{ ".PHONY", Phony, OP_PHONY },
+#ifdef POSIX
+{ ".POSIX", Posix, 0 },
+#endif
+{ ".PRECIOUS", Precious, OP_PRECIOUS },
+{ ".RECURSIVE", Attribute, OP_MAKE },
+{ ".SHELL", ExShell, 0 },
+{ ".SILENT", Silent, OP_SILENT },
+{ ".SINGLESHELL", SingleShell, 0 },
+{ ".SUFFIXES", Suffixes, 0 },
+{ ".USE", Attribute, OP_USE },
+{ ".USEBEFORE", Attribute, OP_USEBEFORE },
+{ ".WAIT", Wait, 0 },
+};
+
+////////////////////////////////////////////////////////////
+// local functions
+
+static int ParseIsEscaped(const char *, const char *);
+static void ParseErrorInternal(const char *, size_t, int, const char *, ...)
+ MAKE_ATTR_PRINTFLIKE(4,5);
+static void ParseVErrorInternal(FILE *, const char *, size_t, int, const char *, va_list)
+ MAKE_ATTR_PRINTFLIKE(5, 0);
+static int ParseFindKeyword(const char *);
+static int ParseLinkSrc(void *, void *);
+static int ParseDoOp(void *, void *);
+static void ParseDoSrc(int, const char *);
+static int ParseFindMain(void *, void *);
+static int ParseAddDir(void *, void *);
+static int ParseClearPath(void *, void *);
+static void ParseDoDependency(char *);
+static int ParseAddCmd(void *, void *);
+static void ParseHasCommands(void *);
+static void ParseDoInclude(char *);
+static void ParseSetParseFile(const char *);
+#ifdef SYSVINCLUDE
+static void ParseTraditionalInclude(char *);
+#endif
+#ifdef GMAKEEXPORT
+static void ParseGmakeExport(char *);
+#endif
+static int ParseEOF(void);
+static char *ParseReadLine(void);
+static void ParseFinishLine(void);
+static void ParseMark(GNode *);
+
+////////////////////////////////////////////////////////////
+// file loader
+
+struct loadedfile {
+ const char *path; /* name, for error reports */
+ char *buf; /* contents buffer */
+ size_t len; /* length of contents */
+ size_t maplen; /* length of mmap area, or 0 */
+ Boolean used; /* XXX: have we used the data yet */
+};
+
+/*
+ * Constructor/destructor for loadedfile
+ */
+static struct loadedfile *
+loadedfile_create(const char *path)
+{
+ struct loadedfile *lf;
+
+ lf = bmake_malloc(sizeof(*lf));
+ lf->path = (path == NULL ? "(stdin)" : path);
+ lf->buf = NULL;
+ lf->len = 0;
+ lf->maplen = 0;
+ lf->used = FALSE;
+ return lf;
+}
+
+static void
+loadedfile_destroy(struct loadedfile *lf)
+{
+ if (lf->buf != NULL) {
+ if (lf->maplen > 0) {
+#ifdef HAVE_MMAP
+ munmap(lf->buf, lf->maplen);
+#endif
+ } else {
+ free(lf->buf);
+ }
+ }
+ free(lf);
+}
+
+/*
+ * nextbuf() operation for loadedfile, as needed by the weird and twisted
+ * logic below. Once that's cleaned up, we can get rid of lf->used...
+ */
+static char *
+loadedfile_nextbuf(void *x, size_t *len)
+{
+ struct loadedfile *lf = x;
+
+ if (lf->used) {
+ return NULL;
+ }
+ lf->used = TRUE;
+ *len = lf->len;
+ return lf->buf;
+}
+
+/*
+ * Try to get the size of a file.
+ */
+static ReturnStatus
+load_getsize(int fd, size_t *ret)
+{
+ struct stat st;
+
+ if (fstat(fd, &st) < 0) {
+ return FAILURE;
+ }
+
+ if (!S_ISREG(st.st_mode)) {
+ return FAILURE;
+ }
+
+ /*
+ * st_size is an off_t, which is 64 bits signed; *ret is
+ * size_t, which might be 32 bits unsigned or 64 bits
+ * unsigned. Rather than being elaborate, just punt on
+ * files that are more than 2^31 bytes. We should never
+ * see a makefile that size in practice...
+ *
+ * While we're at it reject negative sizes too, just in case.
+ */
+ if (st.st_size < 0 || st.st_size > 0x7fffffff) {
+ return FAILURE;
+ }
+
+ *ret = (size_t) st.st_size;
+ return SUCCESS;
+}
+
+/*
+ * Read in a file.
+ *
+ * Until the path search logic can be moved under here instead of
+ * being in the caller in another source file, we need to have the fd
+ * passed in already open. Bleh.
+ *
+ * If the path is NULL use stdin and (to insure against fd leaks)
+ * assert that the caller passed in -1.
+ */
+static struct loadedfile *
+loadfile(const char *path, int fd)
+{
+ struct loadedfile *lf;
+#ifdef HAVE_MMAP
+ long pagesize;
+#endif
+ ssize_t result;
+ size_t bufpos;
+
+ lf = loadedfile_create(path);
+
+ if (path == NULL) {
+ assert(fd == -1);
+ fd = STDIN_FILENO;
+ } else {
+#if 0 /* notyet */
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ ...
+ Error("%s: %s", path, strerror(errno));
+ exit(1);
+ }
+#endif
+ }
+
+#ifdef HAVE_MMAP
+ if (load_getsize(fd, &lf->len) == SUCCESS) {
+ /* found a size, try mmap */
+ pagesize = sysconf(_SC_PAGESIZE);
+ if (pagesize <= 0) {
+ pagesize = 0x1000;
+ }
+ /* round size up to a page */
+ lf->maplen = pagesize * ((lf->len + pagesize - 1)/pagesize);
+
+ /*
+ * XXX hack for dealing with empty files; remove when
+ * we're no longer limited by interfacing to the old
+ * logic elsewhere in this file.
+ */
+ if (lf->maplen == 0) {
+ lf->maplen = pagesize;
+ }
+
+ /*
+ * FUTURE: remove PROT_WRITE when the parser no longer
+ * needs to scribble on the input.
+ */
+ lf->buf = mmap(NULL, lf->maplen, PROT_READ|PROT_WRITE,
+ MAP_FILE|MAP_COPY, fd, 0);
+ if (lf->buf != MAP_FAILED) {
+ /* succeeded */
+ if (lf->len == lf->maplen && lf->buf[lf->len - 1] != '\n') {
+ char *b = malloc(lf->len + 1);
+ b[lf->len] = '\n';
+ memcpy(b, lf->buf, lf->len++);
+ munmap(lf->buf, lf->maplen);
+ lf->maplen = 0;
+ lf->buf = b;
+ }
+ goto done;
+ }
+ }
+#endif
+ /* cannot mmap; load the traditional way */
+
+ lf->maplen = 0;
+ lf->len = 1024;
+ lf->buf = bmake_malloc(lf->len);
+
+ bufpos = 0;
+ while (1) {
+ assert(bufpos <= lf->len);
+ if (bufpos == lf->len) {
+ lf->len *= 2;
+ lf->buf = bmake_realloc(lf->buf, lf->len);
+ }
+ result = read(fd, lf->buf + bufpos, lf->len - bufpos);
+ if (result < 0) {
+ Error("%s: read error: %s", path, strerror(errno));
+ exit(1);
+ }
+ if (result == 0) {
+ break;
+ }
+ bufpos += result;
+ }
+ assert(bufpos <= lf->len);
+ lf->len = bufpos;
+
+ /* truncate malloc region to actual length (maybe not useful) */
+ if (lf->len > 0) {
+ lf->buf = bmake_realloc(lf->buf, lf->len);
+ }
+
+#ifdef HAVE_MMAP
+done:
+#endif
+ if (path != NULL) {
+ close(fd);
+ }
+ return lf;
+}
+
+////////////////////////////////////////////////////////////
+// old code
+
+/*-
+ *----------------------------------------------------------------------
+ * ParseIsEscaped --
+ * Check if the current character is escaped on the current line
+ *
+ * Results:
+ * 0 if the character is not backslash escaped, 1 otherwise
+ *
+ * Side Effects:
+ * None
+ *----------------------------------------------------------------------
+ */
+static int
+ParseIsEscaped(const char *line, const char *c)
+{
+ int active = 0;
+ for (;;) {
+ if (line == c)
+ return active;
+ if (*--c != '\\')
+ return active;
+ active = !active;
+ }
+}
+
+/*-
+ *----------------------------------------------------------------------
+ * ParseFindKeyword --
+ * Look in the table of keywords for one matching the given string.
+ *
+ * Input:
+ * str String to find
+ *
+ * Results:
+ * The index of the keyword, or -1 if it isn't there.
+ *
+ * Side Effects:
+ * None
+ *----------------------------------------------------------------------
+ */
+static int
+ParseFindKeyword(const char *str)
+{
+ int start, end, cur;
+ int diff;
+
+ start = 0;
+ end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1;
+
+ do {
+ cur = start + ((end - start) / 2);
+ diff = strcmp(str, parseKeywords[cur].name);
+
+ if (diff == 0) {
+ return (cur);
+ } else if (diff < 0) {
+ end = cur - 1;
+ } else {
+ start = cur + 1;
+ }
+ } while (start <= end);
+ return (-1);
+}
+
+/*-
+ * ParseVErrorInternal --
+ * Error message abort function for parsing. Prints out the context
+ * of the error (line number and file) as well as the message with
+ * two optional arguments.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * "fatals" is incremented if the level is PARSE_FATAL.
+ */
+/* VARARGS */
+static void
+ParseVErrorInternal(FILE *f, const char *cfname, size_t clineno, int type,
+ const char *fmt, va_list ap)
+{
+ static Boolean fatal_warning_error_printed = FALSE;
+
+ (void)fprintf(f, "%s: ", progname);
+
+ if (cfname != NULL) {
+ (void)fprintf(f, "\"");
+ if (*cfname != '/' && strcmp(cfname, "(stdin)") != 0) {
+ char *cp;
+ const char *dir;
+
+ /*
+ * Nothing is more annoying than not knowing
+ * which Makefile is the culprit.
+ */
+ dir = Var_Value(".PARSEDIR", VAR_GLOBAL, &cp);
+ if (dir == NULL || *dir == '\0' ||
+ (*dir == '.' && dir[1] == '\0'))
+ dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp);
+ if (dir == NULL)
+ dir = ".";
+
+ (void)fprintf(f, "%s/%s", dir, cfname);
+ } else
+ (void)fprintf(f, "%s", cfname);
+
+ (void)fprintf(f, "\" line %d: ", (int)clineno);
+ }
+ if (type == PARSE_WARNING)
+ (void)fprintf(f, "warning: ");
+ (void)vfprintf(f, fmt, ap);
+ (void)fprintf(f, "\n");
+ (void)fflush(f);
+ if (type == PARSE_FATAL || parseWarnFatal)
+ fatals += 1;
+ if (parseWarnFatal && !fatal_warning_error_printed) {
+ Error("parsing warnings being treated as errors");
+ fatal_warning_error_printed = TRUE;
+ }
+}
+
+/*-
+ * ParseErrorInternal --
+ * Error function
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * None
+ */
+/* VARARGS */
+static void
+ParseErrorInternal(const char *cfname, size_t clineno, int type,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void)fflush(stdout);
+ ParseVErrorInternal(stderr, cfname, clineno, type, fmt, ap);
+ va_end(ap);
+
+ if (debug_file != stderr && debug_file != stdout) {
+ va_start(ap, fmt);
+ ParseVErrorInternal(debug_file, cfname, clineno, type, fmt, ap);
+ va_end(ap);
+ }
+}
+
+/*-
+ * Parse_Error --
+ * External interface to ParseErrorInternal; uses the default filename
+ * Line number.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * None
+ */
+/* VARARGS */
+void
+Parse_Error(int type, const char *fmt, ...)
+{
+ va_list ap;
+ const char *fname;
+ size_t lineno;
+
+ if (curFile == NULL) {
+ fname = NULL;
+ lineno = 0;
+ } else {
+ fname = curFile->fname;
+ lineno = curFile->lineno;
+ }
+
+ va_start(ap, fmt);
+ (void)fflush(stdout);
+ ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap);
+ va_end(ap);
+
+ if (debug_file != stderr && debug_file != stdout) {
+ va_start(ap, fmt);
+ ParseVErrorInternal(debug_file, fname, lineno, type, fmt, ap);
+ va_end(ap);
+ }
+}
+
+
+/*
+ * ParseMessage
+ * Parse a .info .warning or .error directive
+ *
+ * The input is the line minus the ".". We substitute
+ * variables, print the message and exit(1) (for .error) or just print
+ * a warning if the directive is malformed.
+ */
+static Boolean
+ParseMessage(char *line)
+{
+ int mtype;
+
+ switch(*line) {
+ case 'i':
+ mtype = 0;
+ break;
+ case 'w':
+ mtype = PARSE_WARNING;
+ break;
+ case 'e':
+ mtype = PARSE_FATAL;
+ break;
+ default:
+ Parse_Error(PARSE_WARNING, "invalid syntax: \".%s\"", line);
+ return FALSE;
+ }
+
+ while (isalpha((u_char)*line))
+ line++;
+ if (!isspace((u_char)*line))
+ return FALSE; /* not for us */
+ while (isspace((u_char)*line))
+ line++;
+
+ line = Var_Subst(NULL, line, VAR_CMD, 0);
+ Parse_Error(mtype, "%s", line);
+ free(line);
+
+ if (mtype == PARSE_FATAL) {
+ /* Terminate immediately. */
+ exit(1);
+ }
+ return TRUE;
+}
+
+/*-
+ *---------------------------------------------------------------------
+ * ParseLinkSrc --
+ * Link the parent node to its new child. Used in a Lst_ForEach by
+ * ParseDoDependency. If the specType isn't 'Not', the parent
+ * isn't linked as a parent of the child.
+ *
+ * Input:
+ * pgnp The parent node
+ * cgpn The child node
+ *
+ * Results:
+ * Always = 0
+ *
+ * Side Effects:
+ * New elements are added to the parents list of cgn and the
+ * children list of cgn. the unmade field of pgn is updated
+ * to reflect the additional child.
+ *---------------------------------------------------------------------
+ */
+static int
+ParseLinkSrc(void *pgnp, void *cgnp)
+{
+ GNode *pgn = (GNode *)pgnp;
+ GNode *cgn = (GNode *)cgnp;
+
+ if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (pgn->cohorts))
+ pgn = (GNode *)Lst_Datum(Lst_Last(pgn->cohorts));
+ (void)Lst_AtEnd(pgn->children, cgn);
+ if (specType == Not)
+ (void)Lst_AtEnd(cgn->parents, pgn);
+ pgn->unmade += 1;
+ if (DEBUG(PARSE)) {
+ fprintf(debug_file, "# ParseLinkSrc: added child %s - %s\n", pgn->name, cgn->name);
+ Targ_PrintNode(pgn, 0);
+ Targ_PrintNode(cgn, 0);
+ }
+ return (0);
+}
+
+/*-
+ *---------------------------------------------------------------------
+ * ParseDoOp --
+ * Apply the parsed operator to the given target node. Used in a
+ * Lst_ForEach call by ParseDoDependency once all targets have
+ * been found and their operator parsed. If the previous and new
+ * operators are incompatible, a major error is taken.
+ *
+ * Input:
+ * gnp The node to which the operator is to be applied
+ * opp The operator to apply
+ *
+ * Results:
+ * Always 0
+ *
+ * Side Effects:
+ * The type field of the node is altered to reflect any new bits in
+ * the op.
+ *---------------------------------------------------------------------
+ */
+static int
+ParseDoOp(void *gnp, void *opp)
+{
+ GNode *gn = (GNode *)gnp;
+ int op = *(int *)opp;
+ /*
+ * If the dependency mask of the operator and the node don't match and
+ * the node has actually had an operator applied to it before, and
+ * the operator actually has some dependency information in it, complain.
+ */
+ if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) &&
+ !OP_NOP(gn->type) && !OP_NOP(op))
+ {
+ Parse_Error(PARSE_FATAL, "Inconsistent operator for %s", gn->name);
+ return (1);
+ }
+
+ if ((op == OP_DOUBLEDEP) && ((gn->type & OP_OPMASK) == OP_DOUBLEDEP)) {
+ /*
+ * If the node was the object of a :: operator, we need to create a
+ * new instance of it for the children and commands on this dependency
+ * line. The new instance is placed on the 'cohorts' list of the
+ * initial one (note the initial one is not on its own cohorts list)
+ * and the new instance is linked to all parents of the initial
+ * instance.
+ */
+ GNode *cohort;
+
+ /*
+ * Propagate copied bits to the initial node. They'll be propagated
+ * back to the rest of the cohorts later.
+ */
+ gn->type |= op & ~OP_OPMASK;
+
+ cohort = Targ_FindNode(gn->name, TARG_NOHASH);
+ /*
+ * Make the cohort invisible as well to avoid duplicating it into
+ * other variables. True, parents of this target won't tend to do
+ * anything with their local variables, but better safe than
+ * sorry. (I think this is pointless now, since the relevant list
+ * traversals will no longer see this node anyway. -mycroft)
+ */
+ cohort->type = op | OP_INVISIBLE;
+ (void)Lst_AtEnd(gn->cohorts, cohort);
+ cohort->centurion = gn;
+ gn->unmade_cohorts += 1;
+ snprintf(cohort->cohort_num, sizeof cohort->cohort_num, "#%d",
+ gn->unmade_cohorts);
+ } else {
+ /*
+ * We don't want to nuke any previous flags (whatever they were) so we
+ * just OR the new operator into the old
+ */
+ gn->type |= op;
+ }
+
+ return (0);
+}
+
+/*-
+ *---------------------------------------------------------------------
+ * ParseDoSrc --
+ * Given the name of a source, figure out if it is an attribute
+ * and apply it to the targets if it is. Else decide if there is
+ * some attribute which should be applied *to* the source because
+ * of some special target and apply it if so. Otherwise, make the
+ * source be a child of the targets in the list 'targets'
+ *
+ * Input:
+ * tOp operator (if any) from special targets
+ * src name of the source to handle
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * Operator bits may be added to the list of targets or to the source.
+ * The targets may have a new source added to their lists of children.
+ *---------------------------------------------------------------------
+ */
+static void
+ParseDoSrc(int tOp, const char *src)
+{
+ GNode *gn = NULL;
+ static int wait_number = 0;
+ char wait_src[16];
+
+ if (*src == '.' && isupper ((unsigned char)src[1])) {
+ int keywd = ParseFindKeyword(src);
+ if (keywd != -1) {
+ int op = parseKeywords[keywd].op;
+ if (op != 0) {
+ Lst_ForEach(targets, ParseDoOp, &op);
+ return;
+ }
+ if (parseKeywords[keywd].spec == Wait) {
+ /*
+ * We add a .WAIT node in the dependency list.
+ * After any dynamic dependencies (and filename globbing)
+ * have happened, it is given a dependency on the each
+ * previous child back to and previous .WAIT node.
+ * The next child won't be scheduled until the .WAIT node
+ * is built.
+ * We give each .WAIT node a unique name (mainly for diag).
+ */
+ snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number);
+ gn = Targ_FindNode(wait_src, TARG_NOHASH);
+ gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
+ Lst_ForEach(targets, ParseLinkSrc, gn);
+ return;
+ }
+ }
+ }
+
+ switch (specType) {
+ case Main:
+ /*
+ * If we have noted the existence of a .MAIN, it means we need
+ * to add the sources of said target to the list of things
+ * to create. The string 'src' is likely to be free, so we
+ * must make a new copy of it. Note that this will only be
+ * invoked if the user didn't specify a target on the command
+ * line. This is to allow #ifmake's to succeed, or something...
+ */
+ (void)Lst_AtEnd(create, bmake_strdup(src));
+ /*
+ * Add the name to the .TARGETS variable as well, so the user can
+ * employ that, if desired.
+ */
+ Var_Append(".TARGETS", src, VAR_GLOBAL);
+ return;
+
+ case Order:
+ /*
+ * Create proper predecessor/successor links between the previous
+ * source and the current one.
+ */
+ gn = Targ_FindNode(src, TARG_CREATE);
+ if (predecessor != NULL) {
+ (void)Lst_AtEnd(predecessor->order_succ, gn);
+ (void)Lst_AtEnd(gn->order_pred, predecessor);
+ if (DEBUG(PARSE)) {
+ fprintf(debug_file, "# ParseDoSrc: added Order dependency %s - %s\n",
+ predecessor->name, gn->name);
+ Targ_PrintNode(predecessor, 0);
+ Targ_PrintNode(gn, 0);
+ }
+ }
+ /*
+ * The current source now becomes the predecessor for the next one.
+ */
+ predecessor = gn;
+ break;
+
+ default:
+ /*
+ * If the source is not an attribute, we need to find/create
+ * a node for it. After that we can apply any operator to it
+ * from a special target or link it to its parents, as
+ * appropriate.
+ *
+ * In the case of a source that was the object of a :: operator,
+ * the attribute is applied to all of its instances (as kept in
+ * the 'cohorts' list of the node) or all the cohorts are linked
+ * to all the targets.
+ */
+
+ /* Find/create the 'src' node and attach to all targets */
+ gn = Targ_FindNode(src, TARG_CREATE);
+ if (tOp) {
+ gn->type |= tOp;
+ } else {
+ Lst_ForEach(targets, ParseLinkSrc, gn);
+ }
+ break;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * ParseFindMain --
+ * Find a real target in the list and set it to be the main one.
+ * Called by ParseDoDependency when a main target hasn't been found
+ * yet.
+ *
+ * Input:
+ * gnp Node to examine
+ *
+ * Results:
+ * 0 if main not found yet, 1 if it is.
+ *
+ * Side Effects:
+ * mainNode is changed and Targ_SetMain is called.
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+ParseFindMain(void *gnp, void *dummy)
+{
+ GNode *gn = (GNode *)gnp;
+ if ((gn->type & OP_NOTARGET) == 0) {
+ mainNode = gn;
+ Targ_SetMain(gn);
+ return (dummy ? 1 : 1);
+ } else {
+ return (dummy ? 0 : 0);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * ParseAddDir --
+ * Front-end for Dir_AddDir to make sure Lst_ForEach keeps going
+ *
+ * Results:
+ * === 0
+ *
+ * Side Effects:
+ * See Dir_AddDir.
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+ParseAddDir(void *path, void *name)
+{
+ (void)Dir_AddDir((Lst) path, (char *)name);
+ return(0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * ParseClearPath --
+ * Front-end for Dir_ClearPath to make sure Lst_ForEach keeps going
+ *
+ * Results:
+ * === 0
+ *
+ * Side Effects:
+ * See Dir_ClearPath
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+ParseClearPath(void *path, void *dummy)
+{
+ Dir_ClearPath((Lst) path);
+ return(dummy ? 0 : 0);
+}
+
+/*-
+ *---------------------------------------------------------------------
+ * ParseDoDependency --
+ * Parse the dependency line in line.
+ *
+ * Input:
+ * line the line to parse
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The nodes of the sources are linked as children to the nodes of the
+ * targets. Some nodes may be created.
+ *
+ * We parse a dependency line by first extracting words from the line and
+ * finding nodes in the list of all targets with that name. This is done
+ * until a character is encountered which is an operator character. Currently
+ * these are only ! and :. At this point the operator is parsed and the
+ * pointer into the line advanced until the first source is encountered.
+ * The parsed operator is applied to each node in the 'targets' list,
+ * which is where the nodes found for the targets are kept, by means of
+ * the ParseDoOp function.
+ * The sources are read in much the same way as the targets were except
+ * that now they are expanded using the wildcarding scheme of the C-Shell
+ * and all instances of the resulting words in the list of all targets
+ * are found. Each of the resulting nodes is then linked to each of the
+ * targets as one of its children.
+ * Certain targets are handled specially. These are the ones detailed
+ * by the specType variable.
+ * The storing of transformation rules is also taken care of here.
+ * A target is recognized as a transformation rule by calling
+ * Suff_IsTransform. If it is a transformation rule, its node is gotten
+ * from the suffix module via Suff_AddTransform rather than the standard
+ * Targ_FindNode in the target module.
+ *---------------------------------------------------------------------
+ */
+static void
+ParseDoDependency(char *line)
+{
+ char *cp; /* our current position */
+ GNode *gn = NULL; /* a general purpose temporary node */
+ int op; /* the operator on the line */
+ char savec; /* a place to save a character */
+ Lst paths; /* List of search paths to alter when parsing
+ * a list of .PATH targets */
+ int tOp; /* operator from special target */
+ Lst sources; /* list of archive source names after
+ * expansion */
+ Lst curTargs; /* list of target names to be found and added
+ * to the targets list */
+ char *lstart = line;
+
+ if (DEBUG(PARSE))
+ fprintf(debug_file, "ParseDoDependency(%s)\n", line);
+ tOp = 0;
+
+ specType = Not;
+ paths = NULL;
+
+ curTargs = Lst_Init(FALSE);
+
+ do {
+ for (cp = line; *cp && (ParseIsEscaped(lstart, cp) ||
+ !(isspace((unsigned char)*cp) ||
+ *cp == '!' || *cp == ':' || *cp == LPAREN));
+ cp++) {
+ if (*cp == '$') {
+ /*
+ * Must be a dynamic source (would have been expanded
+ * otherwise), so call the Var module to parse the puppy
+ * so we can safely advance beyond it...There should be
+ * no errors in this, as they would have been discovered
+ * in the initial Var_Subst and we wouldn't be here.
+ */
+ int length;
+ void *freeIt;
+ char *result;
+
+ result = Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt);
+ if (freeIt)
+ free(freeIt);
+ cp += length-1;
+ }
+ }
+
+ if (!ParseIsEscaped(lstart, cp) && *cp == LPAREN) {
+ /*
+ * Archives must be handled specially to make sure the OP_ARCHV
+ * flag is set in their 'type' field, for one thing, and because
+ * things like "archive(file1.o file2.o file3.o)" are permissible.
+ * Arch_ParseArchive will set 'line' to be the first non-blank
+ * after the archive-spec. It creates/finds nodes for the members
+ * and places them on the given list, returning SUCCESS if all
+ * went well and FAILURE if there was an error in the
+ * specification. On error, line should remain untouched.
+ */
+ if (Arch_ParseArchive(&line, targets, VAR_CMD) != SUCCESS) {
+ Parse_Error(PARSE_FATAL,
+ "Error in archive specification: \"%s\"", line);
+ goto out;
+ } else {
+ continue;
+ }
+ }
+ savec = *cp;
+
+ if (!*cp) {
+ /*
+ * Ending a dependency line without an operator is a Bozo
+ * no-no. As a heuristic, this is also often triggered by
+ * undetected conflicts from cvs/rcs merges.
+ */
+ if ((strncmp(line, "<<<<<<", 6) == 0) ||
+ (strncmp(line, "======", 6) == 0) ||
+ (strncmp(line, ">>>>>>", 6) == 0))
+ Parse_Error(PARSE_FATAL,
+ "Makefile appears to contain unresolved cvs/rcs/??? merge conflicts");
+ else
+ Parse_Error(PARSE_FATAL, lstart[0] == '.' ? "Unknown directive"
+ : "Need an operator");
+ goto out;
+ }
+ *cp = '\0';
+
+ /*
+ * Have a word in line. See if it's a special target and set
+ * specType to match it.
+ */
+ if (*line == '.' && isupper ((unsigned char)line[1])) {
+ /*
+ * See if the target is a special target that must have it
+ * or its sources handled specially.
+ */
+ int keywd = ParseFindKeyword(line);
+ if (keywd != -1) {
+ if (specType == ExPath && parseKeywords[keywd].spec != ExPath) {
+ Parse_Error(PARSE_FATAL, "Mismatched special targets");
+ goto out;
+ }
+
+ specType = parseKeywords[keywd].spec;
+ tOp = parseKeywords[keywd].op;
+
+ /*
+ * Certain special targets have special semantics:
+ * .PATH Have to set the dirSearchPath
+ * variable too
+ * .MAIN Its sources are only used if
+ * nothing has been specified to
+ * create.
+ * .DEFAULT Need to create a node to hang
+ * commands on, but we don't want
+ * it in the graph, nor do we want
+ * it to be the Main Target, so we
+ * create it, set OP_NOTMAIN and
+ * add it to the list, setting
+ * DEFAULT to the new node for
+ * later use. We claim the node is
+ * A transformation rule to make
+ * life easier later, when we'll
+ * use Make_HandleUse to actually
+ * apply the .DEFAULT commands.
+ * .PHONY The list of targets
+ * .NOPATH Don't search for file in the path
+ * .BEGIN
+ * .END
+ * .ERROR
+ * .INTERRUPT Are not to be considered the
+ * main target.
+ * .NOTPARALLEL Make only one target at a time.
+ * .SINGLESHELL Create a shell for each command.
+ * .ORDER Must set initial predecessor to NULL
+ */
+ switch (specType) {
+ case ExPath:
+ if (paths == NULL) {
+ paths = Lst_Init(FALSE);
+ }
+ (void)Lst_AtEnd(paths, dirSearchPath);
+ break;
+ case Main:
+ if (!Lst_IsEmpty(create)) {
+ specType = Not;
+ }
+ break;
+ case Begin:
+ case End:
+ case dotError:
+ case Interrupt:
+ gn = Targ_FindNode(line, TARG_CREATE);
+ gn->type |= OP_NOTMAIN|OP_SPECIAL;
+ (void)Lst_AtEnd(targets, gn);
+ break;
+ case Default:
+ gn = Targ_NewGN(".DEFAULT");
+ gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
+ (void)Lst_AtEnd(targets, gn);
+ DEFAULT = gn;
+ break;
+ case NotParallel:
+ maxJobs = 1;
+ break;
+ case SingleShell:
+ compatMake = TRUE;
+ break;
+ case Order:
+ predecessor = NULL;
+ break;
+ default:
+ break;
+ }
+ } else if (strncmp(line, ".PATH", 5) == 0) {
+ /*
+ * .PATH<suffix> has to be handled specially.
+ * Call on the suffix module to give us a path to
+ * modify.
+ */
+ Lst path;
+
+ specType = ExPath;
+ path = Suff_GetPath(&line[5]);
+ if (path == NULL) {
+ Parse_Error(PARSE_FATAL,
+ "Suffix '%s' not defined (yet)",
+ &line[5]);
+ goto out;
+ } else {
+ if (paths == NULL) {
+ paths = Lst_Init(FALSE);
+ }
+ (void)Lst_AtEnd(paths, path);
+ }
+ }
+ }
+
+ /*
+ * Have word in line. Get or create its node and stick it at
+ * the end of the targets list
+ */
+ if ((specType == Not) && (*line != '\0')) {
+ if (Dir_HasWildcards(line)) {
+ /*
+ * Targets are to be sought only in the current directory,
+ * so create an empty path for the thing. Note we need to
+ * use Dir_Destroy in the destruction of the path as the
+ * Dir module could have added a directory to the path...
+ */
+ Lst emptyPath = Lst_Init(FALSE);
+
+ Dir_Expand(line, emptyPath, curTargs);
+
+ Lst_Destroy(emptyPath, Dir_Destroy);
+ } else {
+ /*
+ * No wildcards, but we want to avoid code duplication,
+ * so create a list with the word on it.
+ */
+ (void)Lst_AtEnd(curTargs, line);
+ }
+
+ while(!Lst_IsEmpty(curTargs)) {
+ char *targName = (char *)Lst_DeQueue(curTargs);
+
+ if (!Suff_IsTransform (targName)) {
+ gn = Targ_FindNode(targName, TARG_CREATE);
+ } else {
+ gn = Suff_AddTransform(targName);
+ }
+
+ (void)Lst_AtEnd(targets, gn);
+ }
+ } else if (specType == ExPath && *line != '.' && *line != '\0') {
+ Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line);
+ }
+
+ *cp = savec;
+ /*
+ * If it is a special type and not .PATH, it's the only target we
+ * allow on this line...
+ */
+ if (specType != Not && specType != ExPath) {
+ Boolean warning = FALSE;
+
+ while (*cp && (ParseIsEscaped(lstart, cp) ||
+ ((*cp != '!') && (*cp != ':')))) {
+ if (ParseIsEscaped(lstart, cp) ||
+ (*cp != ' ' && *cp != '\t')) {
+ warning = TRUE;
+ }
+ cp++;
+ }
+ if (warning) {
+ Parse_Error(PARSE_WARNING, "Extra target ignored");
+ }
+ } else {
+ while (*cp && isspace ((unsigned char)*cp)) {
+ cp++;
+ }
+ }
+ line = cp;
+ } while (*line && (ParseIsEscaped(lstart, line) ||
+ ((*line != '!') && (*line != ':'))));
+
+ /*
+ * Don't need the list of target names anymore...
+ */
+ Lst_Destroy(curTargs, NULL);
+ curTargs = NULL;
+
+ if (!Lst_IsEmpty(targets)) {
+ switch(specType) {
+ default:
+ Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored");
+ break;
+ case Default:
+ case Begin:
+ case End:
+ case dotError:
+ case Interrupt:
+ /*
+ * These four create nodes on which to hang commands, so
+ * targets shouldn't be empty...
+ */
+ case Not:
+ /*
+ * Nothing special here -- targets can be empty if it wants.
+ */
+ break;
+ }
+ }
+
+ /*
+ * Have now parsed all the target names. Must parse the operator next. The
+ * result is left in op .
+ */
+ if (*cp == '!') {
+ op = OP_FORCE;
+ } else if (*cp == ':') {
+ if (cp[1] == ':') {
+ op = OP_DOUBLEDEP;
+ cp++;
+ } else {
+ op = OP_DEPENDS;
+ }
+ } else {
+ Parse_Error(PARSE_FATAL, lstart[0] == '.' ? "Unknown directive"
+ : "Missing dependency operator");
+ goto out;
+ }
+
+ cp++; /* Advance beyond operator */
+
+ Lst_ForEach(targets, ParseDoOp, &op);
+
+ /*
+ * Get to the first source
+ */
+ while (*cp && isspace ((unsigned char)*cp)) {
+ cp++;
+ }
+ line = cp;
+
+ /*
+ * Several special targets take different actions if present with no
+ * sources:
+ * a .SUFFIXES line with no sources clears out all old suffixes
+ * a .PRECIOUS line makes all targets precious
+ * a .IGNORE line ignores errors for all targets
+ * a .SILENT line creates silence when making all targets
+ * a .PATH removes all directories from the search path(s).
+ */
+ if (!*line) {
+ switch (specType) {
+ case Suffixes:
+ Suff_ClearSuffixes();
+ break;
+ case Precious:
+ allPrecious = TRUE;
+ break;
+ case Ignore:
+ ignoreErrors = TRUE;
+ break;
+ case Silent:
+ beSilent = TRUE;
+ break;
+ case ExPath:
+ Lst_ForEach(paths, ParseClearPath, NULL);
+ Dir_SetPATH();
+ break;
+#ifdef POSIX
+ case Posix:
+ Var_Set("%POSIX", "1003.2", VAR_GLOBAL, 0);
+ break;
+#endif
+ default:
+ break;
+ }
+ } else if (specType == MFlags) {
+ /*
+ * Call on functions in main.c to deal with these arguments and
+ * set the initial character to a null-character so the loop to
+ * get sources won't get anything
+ */
+ Main_ParseArgLine(line);
+ *line = '\0';
+ } else if (specType == ExShell) {
+ if (Job_ParseShell(line) != SUCCESS) {
+ Parse_Error(PARSE_FATAL, "improper shell specification");
+ goto out;
+ }
+ *line = '\0';
+ } else if ((specType == NotParallel) || (specType == SingleShell)) {
+ *line = '\0';
+ }
+
+ /*
+ * NOW GO FOR THE SOURCES
+ */
+ if ((specType == Suffixes) || (specType == ExPath) ||
+ (specType == Includes) || (specType == Libs) ||
+ (specType == Null) || (specType == ExObjdir))
+ {
+ while (*line) {
+ /*
+ * If the target was one that doesn't take files as its sources
+ * but takes something like suffixes, we take each
+ * space-separated word on the line as a something and deal
+ * with it accordingly.
+ *
+ * If the target was .SUFFIXES, we take each source as a
+ * suffix and add it to the list of suffixes maintained by the
+ * Suff module.
+ *
+ * If the target was a .PATH, we add the source as a directory
+ * to search on the search path.
+ *
+ * If it was .INCLUDES, the source is taken to be the suffix of
+ * files which will be #included and whose search path should
+ * be present in the .INCLUDES variable.
+ *
+ * If it was .LIBS, the source is taken to be the suffix of
+ * files which are considered libraries and whose search path
+ * should be present in the .LIBS variable.
+ *
+ * If it was .NULL, the source is the suffix to use when a file
+ * has no valid suffix.
+ *
+ * If it was .OBJDIR, the source is a new definition for .OBJDIR,
+ * and will cause make to do a new chdir to that path.
+ */
+ while (*cp && !isspace ((unsigned char)*cp)) {
+ cp++;
+ }
+ savec = *cp;
+ *cp = '\0';
+ switch (specType) {
+ case Suffixes:
+ Suff_AddSuffix(line, &mainNode);
+ break;
+ case ExPath:
+ Lst_ForEach(paths, ParseAddDir, line);
+ break;
+ case Includes:
+ Suff_AddInclude(line);
+ break;
+ case Libs:
+ Suff_AddLib(line);
+ break;
+ case Null:
+ Suff_SetNull(line);
+ break;
+ case ExObjdir:
+ Main_SetObjdir(line);
+ break;
+ default:
+ break;
+ }
+ *cp = savec;
+ if (savec != '\0') {
+ cp++;
+ }
+ while (*cp && isspace ((unsigned char)*cp)) {
+ cp++;
+ }
+ line = cp;
+ }
+ if (paths) {
+ Lst_Destroy(paths, NULL);
+ }
+ if (specType == ExPath)
+ Dir_SetPATH();
+ } else {
+ while (*line) {
+ /*
+ * The targets take real sources, so we must beware of archive
+ * specifications (i.e. things with left parentheses in them)
+ * and handle them accordingly.
+ */
+ for (; *cp && !isspace ((unsigned char)*cp); cp++) {
+ if ((*cp == LPAREN) && (cp > line) && (cp[-1] != '$')) {
+ /*
+ * Only stop for a left parenthesis if it isn't at the
+ * start of a word (that'll be for variable changes
+ * later) and isn't preceded by a dollar sign (a dynamic
+ * source).
+ */
+ break;
+ }
+ }
+
+ if (*cp == LPAREN) {
+ sources = Lst_Init(FALSE);
+ if (Arch_ParseArchive(&line, sources, VAR_CMD) != SUCCESS) {
+ Parse_Error(PARSE_FATAL,
+ "Error in source archive spec \"%s\"", line);
+ goto out;
+ }
+
+ while (!Lst_IsEmpty (sources)) {
+ gn = (GNode *)Lst_DeQueue(sources);
+ ParseDoSrc(tOp, gn->name);
+ }
+ Lst_Destroy(sources, NULL);
+ cp = line;
+ } else {
+ if (*cp) {
+ *cp = '\0';
+ cp += 1;
+ }
+
+ ParseDoSrc(tOp, line);
+ }
+ while (*cp && isspace ((unsigned char)*cp)) {
+ cp++;
+ }
+ line = cp;
+ }
+ }
+
+ if (mainNode == NULL) {
+ /*
+ * If we have yet to decide on a main target to make, in the
+ * absence of any user input, we want the first target on
+ * the first dependency line that is actually a real target
+ * (i.e. isn't a .USE or .EXEC rule) to be made.
+ */
+ Lst_ForEach(targets, ParseFindMain, NULL);
+ }
+
+out:
+ if (curTargs)
+ Lst_Destroy(curTargs, NULL);
+}
+
+/*-
+ *---------------------------------------------------------------------
+ * Parse_IsVar --
+ * Return TRUE if the passed line is a variable assignment. A variable
+ * assignment consists of a single word followed by optional whitespace
+ * followed by either a += or an = operator.
+ * This function is used both by the Parse_File function and main when
+ * parsing the command-line arguments.
+ *
+ * Input:
+ * line the line to check
+ *
+ * Results:
+ * TRUE if it is. FALSE if it ain't
+ *
+ * Side Effects:
+ * none
+ *---------------------------------------------------------------------
+ */
+Boolean
+Parse_IsVar(char *line)
+{
+ Boolean wasSpace = FALSE; /* set TRUE if found a space */
+ char ch;
+ int level = 0;
+#define ISEQOPERATOR(c) \
+ (((c) == '+') || ((c) == ':') || ((c) == '?') || ((c) == '!'))
+
+ /*
+ * Skip to variable name
+ */
+ for (;(*line == ' ') || (*line == '\t'); line++)
+ continue;
+
+ /* Scan for one of the assignment operators outside a variable expansion */
+ while ((ch = *line++) != 0) {
+ if (ch == '(' || ch == '{') {
+ level++;
+ continue;
+ }
+ if (ch == ')' || ch == '}') {
+ level--;
+ continue;
+ }
+ if (level != 0)
+ continue;
+ while (ch == ' ' || ch == '\t') {
+ ch = *line++;
+ wasSpace = TRUE;
+ }
+ if (ch == '=')
+ return TRUE;
+ if (*line == '=' && ISEQOPERATOR(ch))
+ return TRUE;
+ if (wasSpace)
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+/*-
+ *---------------------------------------------------------------------
+ * Parse_DoVar --
+ * Take the variable assignment in the passed line and do it in the
+ * global context.
+ *
+ * Note: There is a lexical ambiguity with assignment modifier characters
+ * in variable names. This routine interprets the character before the =
+ * as a modifier. Therefore, an assignment like
+ * C++=/usr/bin/CC
+ * is interpreted as "C+ +=" instead of "C++ =".
+ *
+ * Input:
+ * line a line guaranteed to be a variable assignment.
+ * This reduces error checks
+ * ctxt Context in which to do the assignment
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * the variable structure of the given variable name is altered in the
+ * global context.
+ *---------------------------------------------------------------------
+ */
+void
+Parse_DoVar(char *line, GNode *ctxt)
+{
+ char *cp; /* pointer into line */
+ enum {
+ VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL
+ } type; /* Type of assignment */
+ char *opc; /* ptr to operator character to
+ * null-terminate the variable name */
+ Boolean freeCp = FALSE; /* TRUE if cp needs to be freed,
+ * i.e. if any variable expansion was
+ * performed */
+ int depth;
+
+ /*
+ * Skip to variable name
+ */
+ while ((*line == ' ') || (*line == '\t')) {
+ line++;
+ }
+
+ /*
+ * Skip to operator character, nulling out whitespace as we go
+ * XXX Rather than counting () and {} we should look for $ and
+ * then expand the variable.
+ */
+ for (depth = 0, cp = line + 1; depth != 0 || *cp != '='; cp++) {
+ if (*cp == '(' || *cp == '{') {
+ depth++;
+ continue;
+ }
+ if (*cp == ')' || *cp == '}') {
+ depth--;
+ continue;
+ }
+ if (depth == 0 && isspace ((unsigned char)*cp)) {
+ *cp = '\0';
+ }
+ }
+ opc = cp-1; /* operator is the previous character */
+ *cp++ = '\0'; /* nuke the = */
+
+ /*
+ * Check operator type
+ */
+ switch (*opc) {
+ case '+':
+ type = VAR_APPEND;
+ *opc = '\0';
+ break;
+
+ case '?':
+ /*
+ * If the variable already has a value, we don't do anything.
+ */
+ *opc = '\0';
+ if (Var_Exists(line, ctxt)) {
+ return;
+ } else {
+ type = VAR_NORMAL;
+ }
+ break;
+
+ case ':':
+ type = VAR_SUBST;
+ *opc = '\0';
+ break;
+
+ case '!':
+ type = VAR_SHELL;
+ *opc = '\0';
+ break;
+
+ default:
+#ifdef SUNSHCMD
+ while (opc > line && *opc != ':')
+ opc--;
+
+ if (strncmp(opc, ":sh", 3) == 0) {
+ type = VAR_SHELL;
+ *opc = '\0';
+ break;
+ }
+#endif
+ type = VAR_NORMAL;
+ break;
+ }
+
+ while (isspace ((unsigned char)*cp)) {
+ cp++;
+ }
+
+ if (type == VAR_APPEND) {
+ Var_Append(line, cp, ctxt);
+ } else if (type == VAR_SUBST) {
+ /*
+ * Allow variables in the old value to be undefined, but leave their
+ * invocation alone -- this is done by forcing oldVars to be false.
+ * XXX: This can cause recursive variables, but that's not hard to do,
+ * and this allows someone to do something like
+ *
+ * CFLAGS = $(.INCLUDES)
+ * CFLAGS := -I.. $(CFLAGS)
+ *
+ * And not get an error.
+ */
+ Boolean oldOldVars = oldVars;
+
+ oldVars = FALSE;
+
+ /*
+ * make sure that we set the variable the first time to nothing
+ * so that it gets substituted!
+ */
+ if (!Var_Exists(line, ctxt))
+ Var_Set(line, "", ctxt, 0);
+
+ cp = Var_Subst(NULL, cp, ctxt, FALSE);
+ oldVars = oldOldVars;
+ freeCp = TRUE;
+
+ Var_Set(line, cp, ctxt, 0);
+ } else if (type == VAR_SHELL) {
+ char *res;
+ const char *error;
+
+ if (strchr(cp, '$') != NULL) {
+ /*
+ * There's a dollar sign in the command, so perform variable
+ * expansion on the whole thing. The resulting string will need
+ * freeing when we're done, so set freeCmd to TRUE.
+ */
+ cp = Var_Subst(NULL, cp, VAR_CMD, TRUE);
+ freeCp = TRUE;
+ }
+
+ res = Cmd_Exec(cp, &error);
+ Var_Set(line, res, ctxt, 0);
+ free(res);
+
+ if (error)
+ Parse_Error(PARSE_WARNING, error, cp);
+ } else {
+ /*
+ * Normal assignment -- just do it.
+ */
+ Var_Set(line, cp, ctxt, 0);
+ }
+ if (strcmp(line, MAKEOVERRIDES) == 0)
+ Main_ExportMAKEFLAGS(FALSE); /* re-export MAKEFLAGS */
+ else if (strcmp(line, ".CURDIR") == 0) {
+ /*
+ * Somone is being (too?) clever...
+ * Let's pretend they know what they are doing and
+ * re-initialize the 'cur' Path.
+ */
+ Dir_InitCur(cp);
+ Dir_SetPATH();
+ } else if (strcmp(line, MAKE_JOB_PREFIX) == 0) {
+ Job_SetPrefix();
+ } else if (strcmp(line, MAKE_EXPORTED) == 0) {
+ Var_Export(cp, 0);
+ }
+ if (freeCp)
+ free(cp);
+}
+
+
+/*-
+ * ParseAddCmd --
+ * Lst_ForEach function to add a command line to all targets
+ *
+ * Input:
+ * gnp the node to which the command is to be added
+ * cmd the command to add
+ *
+ * Results:
+ * Always 0
+ *
+ * Side Effects:
+ * A new element is added to the commands list of the node.
+ */
+static int
+ParseAddCmd(void *gnp, void *cmd)
+{
+ GNode *gn = (GNode *)gnp;
+
+ /* Add to last (ie current) cohort for :: targets */
+ if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts))
+ gn = (GNode *)Lst_Datum(Lst_Last(gn->cohorts));
+
+ /* if target already supplied, ignore commands */
+ if (!(gn->type & OP_HAS_COMMANDS)) {
+ (void)Lst_AtEnd(gn->commands, cmd);
+ ParseMark(gn);
+ } else {
+#ifdef notyet
+ /* XXX: We cannot do this until we fix the tree */
+ (void)Lst_AtEnd(gn->commands, cmd);
+ Parse_Error(PARSE_WARNING,
+ "overriding commands for target \"%s\"; "
+ "previous commands defined at %s: %d ignored",
+ gn->name, gn->fname, gn->lineno);
+#else
+ Parse_Error(PARSE_WARNING,
+ "duplicate script for target \"%s\" ignored",
+ gn->name);
+ ParseErrorInternal(gn->fname, gn->lineno, PARSE_WARNING,
+ "using previous script for \"%s\" defined here",
+ gn->name);
+#endif
+ }
+ return(0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * ParseHasCommands --
+ * Callback procedure for Parse_File when destroying the list of
+ * targets on the last dependency line. Marks a target as already
+ * having commands if it does, to keep from having shell commands
+ * on multiple dependency lines.
+ *
+ * Input:
+ * gnp Node to examine
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * OP_HAS_COMMANDS may be set for the target.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+ParseHasCommands(void *gnp)
+{
+ GNode *gn = (GNode *)gnp;
+ if (!Lst_IsEmpty(gn->commands)) {
+ gn->type |= OP_HAS_COMMANDS;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Parse_AddIncludeDir --
+ * Add a directory to the path searched for included makefiles
+ * bracketed by double-quotes. Used by functions in main.c
+ *
+ * Input:
+ * dir The name of the directory to add
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The directory is appended to the list.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Parse_AddIncludeDir(char *dir)
+{
+ (void)Dir_AddDir(parseIncPath, dir);
+}
+
+/*-
+ *---------------------------------------------------------------------
+ * ParseDoInclude --
+ * Push to another file.
+ *
+ * The input is the line minus the `.'. A file spec is a string
+ * enclosed in <> or "". The former is looked for only in sysIncPath.
+ * The latter in . and the directories specified by -I command line
+ * options
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * A structure is added to the includes Lst and readProc, lineno,
+ * fname and curFILE are altered for the new file
+ *---------------------------------------------------------------------
+ */
+
+static void
+Parse_include_file(char *file, Boolean isSystem, int silent)
+{
+ struct loadedfile *lf;
+ char *fullname; /* full pathname of file */
+ char *newName;
+ char *prefEnd, *incdir;
+ int fd;
+ int i;
+
+ /*
+ * Now we know the file's name and its search path, we attempt to
+ * find the durn thing. A return of NULL indicates the file don't
+ * exist.
+ */
+ fullname = file[0] == '/' ? bmake_strdup(file) : NULL;
+
+ if (fullname == NULL && !isSystem) {
+ /*
+ * Include files contained in double-quotes are first searched for
+ * relative to the including file's location. We don't want to
+ * cd there, of course, so we just tack on the old file's
+ * leading path components and call Dir_FindFile to see if
+ * we can locate the beast.
+ */
+
+ incdir = bmake_strdup(curFile->fname);
+ prefEnd = strrchr(incdir, '/');
+ if (prefEnd != NULL) {
+ *prefEnd = '\0';
+ /* Now do lexical processing of leading "../" on the filename */
+ for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) {
+ prefEnd = strrchr(incdir + 1, '/');
+ if (prefEnd == NULL || strcmp(prefEnd, "/..") == 0)
+ break;
+ *prefEnd = '\0';
+ }
+ newName = str_concat(incdir, file + i, STR_ADDSLASH);
+ fullname = Dir_FindFile(newName, parseIncPath);
+ if (fullname == NULL)
+ fullname = Dir_FindFile(newName, dirSearchPath);
+ free(newName);
+ }
+ free(incdir);
+
+ if (fullname == NULL) {
+ /*
+ * Makefile wasn't found in same directory as included makefile.
+ * Search for it first on the -I search path,
+ * then on the .PATH search path, if not found in a -I directory.
+ * If we have a suffix specific path we should use that.
+ */
+ char *suff;
+ Lst suffPath = NULL;
+
+ if ((suff = strrchr(file, '.'))) {
+ suffPath = Suff_GetPath(suff);
+ if (suffPath != NULL) {
+ fullname = Dir_FindFile(file, suffPath);
+ }
+ }
+ if (fullname == NULL) {
+ fullname = Dir_FindFile(file, parseIncPath);
+ if (fullname == NULL) {
+ fullname = Dir_FindFile(file, dirSearchPath);
+ }
+ }
+ }
+ }
+
+ /* Looking for a system file or file still not found */
+ if (fullname == NULL) {
+ /*
+ * Look for it on the system path
+ */
+ fullname = Dir_FindFile(file,
+ Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath);
+ }
+
+ if (fullname == NULL) {
+ if (!silent)
+ Parse_Error(PARSE_FATAL, "Could not find %s", file);
+ return;
+ }
+
+ /* Actually open the file... */
+ fd = open(fullname, O_RDONLY);
+ if (fd == -1) {
+ if (!silent)
+ Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
+ free(fullname);
+ return;
+ }
+
+ /* load it */
+ lf = loadfile(fullname, fd);
+
+ /* Start reading from this file next */
+ Parse_SetInput(fullname, 0, -1, loadedfile_nextbuf, lf);
+ curFile->lf = lf;
+}
+
+static void
+ParseDoInclude(char *line)
+{
+ char endc; /* the character which ends the file spec */
+ char *cp; /* current position in file spec */
+ int silent = (*line != 'i') ? 1 : 0;
+ char *file = &line[7 + silent];
+
+ /* Skip to delimiter character so we know where to look */
+ while (*file == ' ' || *file == '\t')
+ file++;
+
+ if (*file != '"' && *file != '<') {
+ Parse_Error(PARSE_FATAL,
+ ".include filename must be delimited by '\"' or '<'");
+ return;
+ }
+
+ /*
+ * Set the search path on which to find the include file based on the
+ * characters which bracket its name. Angle-brackets imply it's
+ * a system Makefile while double-quotes imply it's a user makefile
+ */
+ if (*file == '<') {
+ endc = '>';
+ } else {
+ endc = '"';
+ }
+
+ /* Skip to matching delimiter */
+ for (cp = ++file; *cp && *cp != endc; cp++)
+ continue;
+
+ if (*cp != endc) {
+ Parse_Error(PARSE_FATAL,
+ "Unclosed %cinclude filename. '%c' expected",
+ '.', endc);
+ return;
+ }
+ *cp = '\0';
+
+ /*
+ * Substitute for any variables in the file name before trying to
+ * find the thing.
+ */
+ file = Var_Subst(NULL, file, VAR_CMD, FALSE);
+
+ Parse_include_file(file, endc == '>', silent);
+ free(file);
+}
+
+
+/*-
+ *---------------------------------------------------------------------
+ * ParseSetParseFile --
+ * Set the .PARSEDIR and .PARSEFILE variables to the dirname and
+ * basename of the given filename
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The .PARSEDIR and .PARSEFILE variables are overwritten by the
+ * dirname and basename of the given filename.
+ *---------------------------------------------------------------------
+ */
+static void
+ParseSetParseFile(const char *filename)
+{
+ char *slash, *dirname;
+ const char *pd, *pf;
+ int len;
+
+ slash = strrchr(filename, '/');
+ if (slash == NULL) {
+ Var_Set(".PARSEDIR", pd = curdir, VAR_GLOBAL, 0);
+ Var_Set(".PARSEFILE", pf = filename, VAR_GLOBAL, 0);
+ dirname= NULL;
+ } else {
+ len = slash - filename;
+ dirname = bmake_malloc(len + 1);
+ memcpy(dirname, filename, len);
+ dirname[len] = '\0';
+ Var_Set(".PARSEDIR", pd = dirname, VAR_GLOBAL, 0);
+ Var_Set(".PARSEFILE", pf = slash + 1, VAR_GLOBAL, 0);
+ }
+ if (DEBUG(PARSE))
+ fprintf(debug_file, "ParseSetParseFile: ${.PARSEDIR} = `%s' "
+ "${.PARSEFILE} = `%s'\n", pd, pf);
+ free(dirname);
+}
+
+/*
+ * Track the makefiles we read - so makefiles can
+ * set dependencies on them.
+ * Avoid adding anything more than once.
+ */
+
+static void
+ParseTrackInput(const char *name)
+{
+ char *old;
+ char *fp = NULL;
+ size_t name_len = strlen(name);
+
+ old = Var_Value(MAKE_MAKEFILES, VAR_GLOBAL, &fp);
+ if (old) {
+ /* does it contain name? */
+ for (; old != NULL; old = strchr(old, ' ')) {
+ if (*old == ' ')
+ old++;
+ if (memcmp(old, name, name_len) == 0
+ && (old[name_len] == 0 || old[name_len] == ' '))
+ goto cleanup;
+ }
+ }
+ Var_Append (MAKE_MAKEFILES, name, VAR_GLOBAL);
+ cleanup:
+ if (fp) {
+ free(fp);
+ }
+}
+
+
+/*-
+ *---------------------------------------------------------------------
+ * Parse_setInput --
+ * Start Parsing from the given source
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * A structure is added to the includes Lst and readProc, lineno,
+ * fname and curFile are altered for the new file
+ *---------------------------------------------------------------------
+ */
+void
+Parse_SetInput(const char *name, int line, int fd,
+ char *(*nextbuf)(void *, size_t *), void *arg)
+{
+ char *buf;
+ size_t len;
+
+ if (name == NULL)
+ name = curFile->fname;
+ else
+ ParseTrackInput(name);
+
+ if (DEBUG(PARSE))
+ fprintf(debug_file, "Parse_SetInput: file %s, line %d, fd %d, nextbuf %p, arg %p\n",
+ name, line, fd, nextbuf, arg);
+
+ if (fd == -1 && nextbuf == NULL)
+ /* sanity */
+ return;
+
+ if (curFile != NULL)
+ /* Save exiting file info */
+ Lst_AtFront(includes, curFile);
+
+ /* Allocate and fill in new structure */
+ curFile = bmake_malloc(sizeof *curFile);
+
+ /*
+ * Once the previous state has been saved, we can get down to reading
+ * the new file. We set up the name of the file to be the absolute
+ * name of the include file so error messages refer to the right
+ * place.
+ */
+ curFile->fname = name;
+ curFile->lineno = line;
+ curFile->first_lineno = line;
+ curFile->nextbuf = nextbuf;
+ curFile->nextbuf_arg = arg;
+ curFile->lf = NULL;
+
+ assert(nextbuf != NULL);
+
+ /* Get first block of input data */
+ buf = curFile->nextbuf(curFile->nextbuf_arg, &len);
+ if (buf == NULL) {
+ /* Was all a waste of time ... */
+ free(curFile);
+ return;
+ }
+ curFile->P_str = buf;
+ curFile->P_ptr = buf;
+ curFile->P_end = buf+len;
+
+ curFile->cond_depth = Cond_save_depth();
+ ParseSetParseFile(name);
+}
+
+#ifdef SYSVINCLUDE
+/*-
+ *---------------------------------------------------------------------
+ * ParseTraditionalInclude --
+ * Push to another file.
+ *
+ * The input is the current line. The file name(s) are
+ * following the "include".
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * A structure is added to the includes Lst and readProc, lineno,
+ * fname and curFILE are altered for the new file
+ *---------------------------------------------------------------------
+ */
+static void
+ParseTraditionalInclude(char *line)
+{
+ char *cp; /* current position in file spec */
+ int done = 0;
+ int silent = (line[0] != 'i') ? 1 : 0;
+ char *file = &line[silent + 7];
+ char *all_files;
+
+ if (DEBUG(PARSE)) {
+ fprintf(debug_file, "ParseTraditionalInclude: %s\n", file);
+ }
+
+ /*
+ * Skip over whitespace
+ */
+ while (isspace((unsigned char)*file))
+ file++;
+
+ /*
+ * Substitute for any variables in the file name before trying to
+ * find the thing.
+ */
+ all_files = Var_Subst(NULL, file, VAR_CMD, FALSE);
+
+ if (*file == '\0') {
+ Parse_Error(PARSE_FATAL,
+ "Filename missing from \"include\"");
+ return;
+ }
+
+ for (file = all_files; !done; file = cp + 1) {
+ /* Skip to end of line or next whitespace */
+ for (cp = file; *cp && !isspace((unsigned char) *cp); cp++)
+ continue;
+
+ if (*cp)
+ *cp = '\0';
+ else
+ done = 1;
+
+ Parse_include_file(file, FALSE, silent);
+ }
+ free(all_files);
+}
+#endif
+
+#ifdef GMAKEEXPORT
+/*-
+ *---------------------------------------------------------------------
+ * ParseGmakeExport --
+ * Parse export <variable>=<value>
+ *
+ * And set the environment with it.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * None
+ *---------------------------------------------------------------------
+ */
+static void
+ParseGmakeExport(char *line)
+{
+ char *variable = &line[6];
+ char *value;
+
+ if (DEBUG(PARSE)) {
+ fprintf(debug_file, "ParseGmakeExport: %s\n", variable);
+ }
+
+ /*
+ * Skip over whitespace
+ */
+ while (isspace((unsigned char)*variable))
+ variable++;
+
+ for (value = variable; *value && *value != '='; value++)
+ continue;
+
+ if (*value != '=') {
+ Parse_Error(PARSE_FATAL,
+ "Variable/Value missing from \"export\"");
+ return;
+ }
+
+ /*
+ * Expand the value before putting it in the environment.
+ */
+ value = Var_Subst(NULL, value, VAR_CMD, FALSE);
+ setenv(variable, value, 1);
+}
+#endif
+
+/*-
+ *---------------------------------------------------------------------
+ * ParseEOF --
+ * Called when EOF is reached in the current file. If we were reading
+ * an include file, the includes stack is popped and things set up
+ * to go back to reading the previous file at the previous location.
+ *
+ * Results:
+ * CONTINUE if there's more to do. DONE if not.
+ *
+ * Side Effects:
+ * The old curFILE, is closed. The includes list is shortened.
+ * lineno, curFILE, and fname are changed if CONTINUE is returned.
+ *---------------------------------------------------------------------
+ */
+static int
+ParseEOF(void)
+{
+ char *ptr;
+ size_t len;
+
+ assert(curFile->nextbuf != NULL);
+
+ /* get next input buffer, if any */
+ ptr = curFile->nextbuf(curFile->nextbuf_arg, &len);
+ curFile->P_ptr = ptr;
+ curFile->P_str = ptr;
+ curFile->P_end = ptr + len;
+ curFile->lineno = curFile->first_lineno;
+ if (ptr != NULL) {
+ /* Iterate again */
+ return CONTINUE;
+ }
+
+ /* Ensure the makefile (or loop) didn't have mismatched conditionals */
+ Cond_restore_depth(curFile->cond_depth);
+
+ if (curFile->lf != NULL) {
+ loadedfile_destroy(curFile->lf);
+ curFile->lf = NULL;
+ }
+
+ /* Dispose of curFile info */
+ /* Leak curFile->fname because all the gnodes have pointers to it */
+ free(curFile->P_str);
+ free(curFile);
+
+ curFile = Lst_DeQueue(includes);
+
+ if (curFile == NULL) {
+ /* We've run out of input */
+ Var_Delete(".PARSEDIR", VAR_GLOBAL);
+ Var_Delete(".PARSEFILE", VAR_GLOBAL);
+ return DONE;
+ }
+
+ if (DEBUG(PARSE))
+ fprintf(debug_file, "ParseEOF: returning to file %s, line %d\n",
+ curFile->fname, curFile->lineno);
+
+ /* Restore the PARSEDIR/PARSEFILE variables */
+ ParseSetParseFile(curFile->fname);
+ return (CONTINUE);
+}
+
+#define PARSE_RAW 1
+#define PARSE_SKIP 2
+
+static char *
+ParseGetLine(int flags, int *length)
+{
+ IFile *cf = curFile;
+ char *ptr;
+ char ch;
+ char *line;
+ char *line_end;
+ char *escaped;
+ char *comment;
+ char *tp;
+
+ /* Loop through blank lines and comment lines */
+ for (;;) {
+ cf->lineno++;
+ line = cf->P_ptr;
+ ptr = line;
+ line_end = line;
+ escaped = NULL;
+ comment = NULL;
+ for (;;) {
+ if (cf->P_end != NULL && ptr == cf->P_end) {
+ /* end of buffer */
+ ch = 0;
+ break;
+ }
+ ch = *ptr;
+ if (ch == 0 || (ch == '\\' && ptr[1] == 0)) {
+ if (cf->P_end == NULL)
+ /* End of string (aka for loop) data */
+ break;
+ if (cf->nextbuf != NULL) {
+ /*
+ * End of this buffer; return EOF and outer logic
+ * will get the next one. (eww)
+ */
+ break;
+ }
+ Parse_Error(PARSE_FATAL, "Zero byte read from file");
+ return NULL;
+ }
+
+ if (ch == '\\') {
+ /* Don't treat next character as special, remember first one */
+ if (escaped == NULL)
+ escaped = ptr;
+ if (ptr[1] == '\n')
+ cf->lineno++;
+ ptr += 2;
+ line_end = ptr;
+ continue;
+ }
+ if (ch == '#' && comment == NULL) {
+ /* Remember first '#' for comment stripping */
+ /* Unless previous char was '[', as in modifier :[#] */
+ if (!(ptr > line && ptr[-1] == '['))
+ comment = line_end;
+ }
+ ptr++;
+ if (ch == '\n')
+ break;
+ if (!isspace((unsigned char)ch))
+ /* We are not interested in trailing whitespace */
+ line_end = ptr;
+ }
+
+ /* Save next 'to be processed' location */
+ cf->P_ptr = ptr;
+
+ /* Check we have a non-comment, non-blank line */
+ if (line_end == line || comment == line) {
+ if (ch == 0)
+ /* At end of file */
+ return NULL;
+ /* Parse another line */
+ continue;
+ }
+
+ /* We now have a line of data */
+ *line_end = 0;
+
+ if (flags & PARSE_RAW) {
+ /* Leave '\' (etc) in line buffer (eg 'for' lines) */
+ *length = line_end - line;
+ return line;
+ }
+
+ if (flags & PARSE_SKIP) {
+ /* Completely ignore non-directives */
+ if (line[0] != '.')
+ continue;
+ /* We could do more of the .else/.elif/.endif checks here */
+ }
+ break;
+ }
+
+ /* Brutally ignore anything after a non-escaped '#' in non-commands */
+ if (comment != NULL && line[0] != '\t') {
+ line_end = comment;
+ *line_end = 0;
+ }
+
+ /* If we didn't see a '\\' then the in-situ data is fine */
+ if (escaped == NULL) {
+ *length = line_end - line;
+ return line;
+ }
+
+ /* Remove escapes from '\n' and '#' */
+ tp = ptr = escaped;
+ escaped = line;
+ for (; ; *tp++ = ch) {
+ ch = *ptr++;
+ if (ch != '\\') {
+ if (ch == 0)
+ break;
+ continue;
+ }
+
+ ch = *ptr++;
+ if (ch == 0) {
+ /* Delete '\\' at end of buffer */
+ tp--;
+ break;
+ }
+
+ if (ch == '#' && line[0] != '\t')
+ /* Delete '\\' from before '#' on non-command lines */
+ continue;
+
+ if (ch != '\n') {
+ /* Leave '\\' in buffer for later */
+ *tp++ = '\\';
+ /* Make sure we don't delete an escaped ' ' from the line end */
+ escaped = tp + 1;
+ continue;
+ }
+
+ /* Escaped '\n' replace following whitespace with a single ' ' */
+ while (ptr[0] == ' ' || ptr[0] == '\t')
+ ptr++;
+ ch = ' ';
+ }
+
+ /* Delete any trailing spaces - eg from empty continuations */
+ while (tp > escaped && isspace((unsigned char)tp[-1]))
+ tp--;
+
+ *tp = 0;
+ *length = tp - line;
+ return line;
+}
+
+/*-
+ *---------------------------------------------------------------------
+ * ParseReadLine --
+ * Read an entire line from the input file. Called only by Parse_File.
+ *
+ * Results:
+ * A line w/o its newline
+ *
+ * Side Effects:
+ * Only those associated with reading a character
+ *---------------------------------------------------------------------
+ */
+static char *
+ParseReadLine(void)
+{
+ char *line; /* Result */
+ int lineLength; /* Length of result */
+ int lineno; /* Saved line # */
+ int rval;
+
+ for (;;) {
+ line = ParseGetLine(0, &lineLength);
+ if (line == NULL)
+ return NULL;
+
+ if (line[0] != '.')
+ return line;
+
+ /*
+ * The line might be a conditional. Ask the conditional module
+ * about it and act accordingly
+ */
+ switch (Cond_Eval(line)) {
+ case COND_SKIP:
+ /* Skip to next conditional that evaluates to COND_PARSE. */
+ do {
+ line = ParseGetLine(PARSE_SKIP, &lineLength);
+ } while (line && Cond_Eval(line) != COND_PARSE);
+ if (line == NULL)
+ break;
+ continue;
+ case COND_PARSE:
+ continue;
+ case COND_INVALID: /* Not a conditional line */
+ /* Check for .for loops */
+ rval = For_Eval(line);
+ if (rval == 0)
+ /* Not a .for line */
+ break;
+ if (rval < 0)
+ /* Syntax error - error printed, ignore line */
+ continue;
+ /* Start of a .for loop */
+ lineno = curFile->lineno;
+ /* Accumulate loop lines until matching .endfor */
+ do {
+ line = ParseGetLine(PARSE_RAW, &lineLength);
+ if (line == NULL) {
+ Parse_Error(PARSE_FATAL,
+ "Unexpected end of file in for loop.");
+ break;
+ }
+ } while (For_Accum(line));
+ /* Stash each iteration as a new 'input file' */
+ For_Run(lineno);
+ /* Read next line from for-loop buffer */
+ continue;
+ }
+ return (line);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * ParseFinishLine --
+ * Handle the end of a dependency group.
+ *
+ * Results:
+ * Nothing.
+ *
+ * Side Effects:
+ * inLine set FALSE. 'targets' list destroyed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+ParseFinishLine(void)
+{
+ if (inLine) {
+ Lst_ForEach(targets, Suff_EndTransform, NULL);
+ Lst_Destroy(targets, ParseHasCommands);
+ targets = NULL;
+ inLine = FALSE;
+ }
+}
+
+
+/*-
+ *---------------------------------------------------------------------
+ * Parse_File --
+ * Parse a file into its component parts, incorporating it into the
+ * current dependency graph. This is the main function and controls
+ * almost every other function in this module
+ *
+ * Input:
+ * name the name of the file being read
+ * fd Open file to makefile to parse
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * closes fd.
+ * Loads. Nodes are added to the list of all targets, nodes and links
+ * are added to the dependency graph. etc. etc. etc.
+ *---------------------------------------------------------------------
+ */
+void
+Parse_File(const char *name, int fd)
+{
+ char *cp; /* pointer into the line */
+ char *line; /* the line we're working on */
+ struct loadedfile *lf;
+
+ lf = loadfile(name, fd);
+
+ inLine = FALSE;
+ fatals = 0;
+
+ if (name == NULL) {
+ name = "(stdin)";
+ }
+
+ Parse_SetInput(name, 0, -1, loadedfile_nextbuf, lf);
+ curFile->lf = lf;
+
+ do {
+ for (; (line = ParseReadLine()) != NULL; ) {
+ if (DEBUG(PARSE))
+ fprintf(debug_file, "ParseReadLine (%d): '%s'\n",
+ curFile->lineno, line);
+ if (*line == '.') {
+ /*
+ * Lines that begin with the special character may be
+ * include or undef directives.
+ * On the other hand they can be suffix rules (.c.o: ...)
+ * or just dependencies for filenames that start '.'.
+ */
+ for (cp = line + 1; isspace((unsigned char)*cp); cp++) {
+ continue;
+ }
+ if (strncmp(cp, "include", 7) == 0 ||
+ ((cp[0] == 's' || cp[0] == '-') &&
+ strncmp(&cp[1], "include", 7) == 0)) {
+ ParseDoInclude(cp);
+ continue;
+ }
+ if (strncmp(cp, "undef", 5) == 0) {
+ char *cp2;
+ for (cp += 5; isspace((unsigned char) *cp); cp++)
+ continue;
+ for (cp2 = cp; !isspace((unsigned char) *cp2) &&
+ (*cp2 != '\0'); cp2++)
+ continue;
+ *cp2 = '\0';
+ Var_Delete(cp, VAR_GLOBAL);
+ continue;
+ } else if (strncmp(cp, "export", 6) == 0) {
+ for (cp += 6; isspace((unsigned char) *cp); cp++)
+ continue;
+ Var_Export(cp, 1);
+ continue;
+ } else if (strncmp(cp, "unexport", 8) == 0) {
+ Var_UnExport(cp);
+ continue;
+ } else if (strncmp(cp, "info", 4) == 0 ||
+ strncmp(cp, "error", 5) == 0 ||
+ strncmp(cp, "warning", 7) == 0) {
+ if (ParseMessage(cp))
+ continue;
+ }
+ }
+
+ if (*line == '\t') {
+ /*
+ * If a line starts with a tab, it can only hope to be
+ * a creation command.
+ */
+ cp = line + 1;
+ shellCommand:
+ for (; isspace ((unsigned char)*cp); cp++) {
+ continue;
+ }
+ if (*cp) {
+ if (!inLine)
+ Parse_Error(PARSE_FATAL,
+ "Unassociated shell command \"%s\"",
+ cp);
+ /*
+ * So long as it's not a blank line and we're actually
+ * in a dependency spec, add the command to the list of
+ * commands of all targets in the dependency spec
+ */
+ if (targets) {
+ cp = bmake_strdup(cp);
+ Lst_ForEach(targets, ParseAddCmd, cp);
+#ifdef CLEANUP
+ Lst_AtEnd(targCmds, cp);
+#endif
+ }
+ }
+ continue;
+ }
+
+#ifdef SYSVINCLUDE
+ if (((strncmp(line, "include", 7) == 0 &&
+ isspace((unsigned char) line[7])) ||
+ ((line[0] == 's' || line[0] == '-') &&
+ strncmp(&line[1], "include", 7) == 0 &&
+ isspace((unsigned char) line[8]))) &&
+ strchr(line, ':') == NULL) {
+ /*
+ * It's an S3/S5-style "include".
+ */
+ ParseTraditionalInclude(line);
+ continue;
+ }
+#endif
+#ifdef GMAKEEXPORT
+ if (strncmp(line, "export", 6) == 0 &&
+ isspace((unsigned char) line[6]) &&
+ strchr(line, ':') == NULL) {
+ /*
+ * It's a Gmake "export".
+ */
+ ParseGmakeExport(line);
+ continue;
+ }
+#endif
+ if (Parse_IsVar(line)) {
+ ParseFinishLine();
+ Parse_DoVar(line, VAR_GLOBAL);
+ continue;
+ }
+
+#ifndef POSIX
+ /*
+ * To make life easier on novices, if the line is indented we
+ * first make sure the line has a dependency operator in it.
+ * If it doesn't have an operator and we're in a dependency
+ * line's script, we assume it's actually a shell command
+ * and add it to the current list of targets.
+ */
+ cp = line;
+ if (isspace((unsigned char) line[0])) {
+ while ((*cp != '\0') && isspace((unsigned char) *cp))
+ cp++;
+ while (*cp && (ParseIsEscaped(line, cp) ||
+ (*cp != ':') && (*cp != '!'))) {
+ cp++;
+ }
+ if (*cp == '\0') {
+ if (inLine) {
+ Parse_Error(PARSE_WARNING,
+ "Shell command needs a leading tab");
+ goto shellCommand;
+ }
+ }
+ }
+#endif
+ ParseFinishLine();
+
+ /*
+ * For some reason - probably to make the parser impossible -
+ * a ';' can be used to separate commands from dependencies.
+ * Attempt to avoid ';' inside substitution patterns.
+ */
+ {
+ int level = 0;
+
+ for (cp = line; *cp != 0; cp++) {
+ if (*cp == '\\' && cp[1] != 0) {
+ cp++;
+ continue;
+ }
+ if (*cp == '$' &&
+ (cp[1] == '(' || cp[1] == '{')) {
+ level++;
+ continue;
+ }
+ if (level > 0) {
+ if (*cp == ')' || *cp == '}') {
+ level--;
+ continue;
+ }
+ } else if (*cp == ';') {
+ break;
+ }
+ }
+ }
+ if (*cp != 0)
+ /* Terminate the dependency list at the ';' */
+ *cp++ = 0;
+ else
+ cp = NULL;
+
+ /*
+ * We now know it's a dependency line so it needs to have all
+ * variables expanded before being parsed. Tell the variable
+ * module to complain if some variable is undefined...
+ */
+ line = Var_Subst(NULL, line, VAR_CMD, TRUE);
+
+ /*
+ * Need a non-circular list for the target nodes
+ */
+ if (targets)
+ Lst_Destroy(targets, NULL);
+
+ targets = Lst_Init(FALSE);
+ inLine = TRUE;
+
+ ParseDoDependency(line);
+ free(line);
+
+ /* If there were commands after a ';', add them now */
+ if (cp != NULL) {
+ goto shellCommand;
+ }
+ }
+ /*
+ * Reached EOF, but it may be just EOF of an include file...
+ */
+ } while (ParseEOF() == CONTINUE);
+
+ if (fatals) {
+ (void)fflush(stdout);
+ (void)fprintf(stderr,
+ "%s: Fatal errors encountered -- cannot continue",
+ progname);
+ PrintOnError(NULL, NULL);
+ exit(1);
+ }
+}
+
+/*-
+ *---------------------------------------------------------------------
+ * Parse_Init --
+ * initialize the parsing module
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * the parseIncPath list is initialized...
+ *---------------------------------------------------------------------
+ */
+void
+Parse_Init(void)
+{
+ mainNode = NULL;
+ parseIncPath = Lst_Init(FALSE);
+ sysIncPath = Lst_Init(FALSE);
+ defIncPath = Lst_Init(FALSE);
+ includes = Lst_Init(FALSE);
+#ifdef CLEANUP
+ targCmds = Lst_Init(FALSE);
+#endif
+}
+
+void
+Parse_End(void)
+{
+#ifdef CLEANUP
+ Lst_Destroy(targCmds, (FreeProc *)free);
+ if (targets)
+ Lst_Destroy(targets, NULL);
+ Lst_Destroy(defIncPath, Dir_Destroy);
+ Lst_Destroy(sysIncPath, Dir_Destroy);
+ Lst_Destroy(parseIncPath, Dir_Destroy);
+ Lst_Destroy(includes, NULL); /* Should be empty now */
+#endif
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Parse_MainName --
+ * Return a Lst of the main target to create for main()'s sake. If
+ * no such target exists, we Punt with an obnoxious error message.
+ *
+ * Results:
+ * A Lst of the single node to create.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+Lst
+Parse_MainName(void)
+{
+ Lst mainList; /* result list */
+
+ mainList = Lst_Init(FALSE);
+
+ if (mainNode == NULL) {
+ Punt("no target to make.");
+ /*NOTREACHED*/
+ } else if (mainNode->type & OP_DOUBLEDEP) {
+ (void)Lst_AtEnd(mainList, mainNode);
+ Lst_Concat(mainList, mainNode->cohorts, LST_CONCNEW);
+ }
+ else
+ (void)Lst_AtEnd(mainList, mainNode);
+ Var_Append(".TARGETS", mainNode->name, VAR_GLOBAL);
+ return (mainList);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * ParseMark --
+ * Add the filename and lineno to the GNode so that we remember
+ * where it was first defined.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+ParseMark(GNode *gn)
+{
+ gn->fname = curFile->fname;
+ gn->lineno = curFile->lineno;
+}
diff --git a/external/bsd/bmake/dist/pathnames.h b/external/bsd/bmake/dist/pathnames.h
new file mode 100644
index 0000000..9c597b1
--- /dev/null
+++ b/external/bsd/bmake/dist/pathnames.h
@@ -0,0 +1,62 @@
+/* $NetBSD: pathnames.h,v 1.17 2009/04/11 09:41:18 apb Exp $ */
+
+/*
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)pathnames.h 5.2 (Berkeley) 6/1/90
+ * $Id: pathnames.h,v 1.13 2009/08/26 23:43:42 sjg Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifndef MAKE_NATIVE
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+#endif
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#define _PATH_OBJDIR "obj"
+#define _PATH_OBJDIRPREFIX "/usr/obj"
+#ifndef _PATH_DEFSHELLDIR
+#define _PATH_DEFSHELLDIR "/bin"
+#endif
+#define _PATH_DEFSYSMK "sys.mk"
+#define _path_defsyspath "/usr/share/mk:/usr/local/share/mk:/opt/share/mk"
+#ifndef _PATH_DEFSYSPATH
+# ifdef _PATH_PREFIX_SYSPATH
+# define _PATH_DEFSYSPATH _PATH_PREFIX_SYSPATH ":" _path_defsyspath
+# else
+# define _PATH_DEFSYSPATH _path_defsyspath
+# endif
+#endif
+#ifndef _PATH_TMP
+#define _PATH_TMP "/tmp/" /* with trailing slash */
+#endif
diff --git a/external/bsd/bmake/dist/ranlib.h b/external/bsd/bmake/dist/ranlib.h
new file mode 100644
index 0000000..503c7c1
--- /dev/null
+++ b/external/bsd/bmake/dist/ranlib.h
@@ -0,0 +1,32 @@
+/* @(#)ranlib.h 1.6 88/08/19 SMI; from UCB 4.1 83/05/03 */
+/* $Id: ranlib.h,v 1.5 2005/11/01 02:35:15 sjg Exp $ */
+
+/*
+ * Structure of the __.SYMDEF table of contents for an archive.
+ * __.SYMDEF begins with a word giving the number of ranlib structures
+ * which immediately follow, and then continues with a string
+ * table consisting of a word giving the number of bytes of strings
+ * which follow and then the strings themselves.
+ * The ran_strx fields index the string table whose first byte is numbered 0.
+ */
+
+#if !defined(IRIX) && !defined(__digital__) && !defined(__osf__)
+#ifndef _ranlib_h
+#define _ranlib_h
+
+#if 0
+#define RANLIBMAG "!<arch>\n__.SYMDEF" /* archive file name */
+#endif
+#define RANLIBMAG "__.SYMDEF" /* archive file name */
+#define RANLIBSKEW 3 /* creation time offset */
+
+struct ranlib {
+ union {
+ off_t ran_strx; /* string table index of */
+ char *ran_name; /* symbol defined by */
+ } ran_un;
+ off_t ran_off; /* library member at this offset */
+};
+
+#endif /*!_ranlib_h*/
+#endif
diff --git a/external/bsd/bmake/dist/realpath.c b/external/bsd/bmake/dist/realpath.c
new file mode 100644
index 0000000..1ef2cd8
--- /dev/null
+++ b/external/bsd/bmake/dist/realpath.c
@@ -0,0 +1,196 @@
+/* $Id: realpath.c,v 1.2 2010/04/21 17:47:49 sjg Exp $ */
+/* from: $NetBSD: getcwd.c,v 1.45 2007/10/26 19:48:14 christos Exp $ */
+
+/*
+ * Copyright (c) 1989, 1991, 1993, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Jan-Simon Pendry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#ifndef HAVE_REALPATH
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+/*
+ * char *realpath(const char *path, char resolved[MAXPATHLEN]);
+ *
+ * Find the real name of path, by removing all ".", ".." and symlink
+ * components. Returns (resolved) on success, or (NULL) on failure,
+ * in which case the path which caused trouble is left in (resolved).
+ */
+char *
+realpath(const char *path, char *resolved)
+{
+ struct stat sb;
+ int idx = 0, n, nlnk = 0;
+ const char *q;
+ char *p, wbuf[2][MAXPATHLEN];
+ size_t len;
+
+ if (!path || !resolved || path == resolved)
+ return (NULL);
+
+ /*
+ * Build real path one by one with paying an attention to .,
+ * .. and symbolic link.
+ */
+
+ /*
+ * `p' is where we'll put a new component with prepending
+ * a delimiter.
+ */
+ p = resolved;
+
+ if (*path == 0) {
+ *p = 0;
+ errno = ENOENT;
+ return (NULL);
+ }
+
+ /* If relative path, start from current working directory. */
+ if (*path != '/') {
+ /* check for resolved pointer to appease coverity */
+ if (resolved && getcwd(resolved, MAXPATHLEN) == NULL) {
+ p[0] = '.';
+ p[1] = 0;
+ return (NULL);
+ }
+ len = strlen(resolved);
+ if (len > 1)
+ p += len;
+ }
+
+loop:
+ /* Skip any slash. */
+ while (*path == '/')
+ path++;
+
+ if (*path == 0) {
+ if (p == resolved)
+ *p++ = '/';
+ *p = 0;
+ return (resolved);
+ }
+
+ /* Find the end of this component. */
+ q = path;
+ do
+ q++;
+ while (*q != '/' && *q != 0);
+
+ /* Test . or .. */
+ if (path[0] == '.') {
+ if (q - path == 1) {
+ path = q;
+ goto loop;
+ }
+ if (path[1] == '.' && q - path == 2) {
+ /* Trim the last component. */
+ if (p != resolved)
+ while (*--p != '/')
+ ;
+ path = q;
+ goto loop;
+ }
+ }
+
+ /* Append this component. */
+ if (p - resolved + 1 + q - path + 1 > MAXPATHLEN) {
+ errno = ENAMETOOLONG;
+ if (p == resolved)
+ *p++ = '/';
+ *p = 0;
+ return (NULL);
+ }
+ p[0] = '/';
+ memcpy(&p[1], path,
+ /* LINTED We know q > path. */
+ q - path);
+ p[1 + q - path] = 0;
+
+ /*
+ * If this component is a symlink, toss it and prepend link
+ * target to unresolved path.
+ */
+ if (lstat(resolved, &sb) == -1) {
+ return (NULL);
+ }
+ if (S_ISLNK(sb.st_mode)) {
+ if (nlnk++ >= MAXSYMLINKS) {
+ errno = ELOOP;
+ return (NULL);
+ }
+ n = readlink(resolved, wbuf[idx], sizeof(wbuf[0]) - 1);
+ if (n < 0)
+ return (NULL);
+ if (n == 0) {
+ errno = ENOENT;
+ return (NULL);
+ }
+
+ /* Append unresolved path to link target and switch to it. */
+ if (n + (len = strlen(q)) + 1 > sizeof(wbuf[0])) {
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ memcpy(&wbuf[idx][n], q, len + 1);
+ path = wbuf[idx];
+ idx ^= 1;
+
+ /* If absolute symlink, start from root. */
+ if (*path == '/')
+ p = resolved;
+ goto loop;
+ }
+ if (*q == '/' && !S_ISDIR(sb.st_mode)) {
+ errno = ENOTDIR;
+ return (NULL);
+ }
+
+ /* Advance both resolved and unresolved path. */
+ p += 1 + q - path;
+ path = q;
+ goto loop;
+}
+#endif
diff --git a/external/bsd/bmake/dist/setenv.c b/external/bsd/bmake/dist/setenv.c
new file mode 100644
index 0000000..efd0f74
--- /dev/null
+++ b/external/bsd/bmake/dist/setenv.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#ifndef HAVE_SETENV
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)setenv.c 5.6 (Berkeley) 6/4/91";*/
+static char *rcsid = "$Id: setenv.c,v 1.5 1996/09/04 22:10:42 sjg Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * __findenv --
+ * Returns pointer to value associated with name, if any, else NULL.
+ * Sets offset to be the offset of the name/value combination in the
+ * environmental array, for use by setenv(3) and unsetenv(3).
+ * Explicitly removes '=' in argument name.
+ *
+ * This routine *should* be a static; don't use it.
+ */
+static char *
+__findenv(name, offset)
+ register char *name;
+ int *offset;
+{
+ extern char **environ;
+ register int len;
+ register char **P, *C;
+
+ for (C = name, len = 0; *C && *C != '='; ++C, ++len);
+ for (P = environ; *P; ++P)
+ if (!strncmp(*P, name, len))
+ if (*(C = *P + len) == '=') {
+ *offset = P - environ;
+ return(++C);
+ }
+ return(NULL);
+}
+
+/*
+ * setenv --
+ * Set the value of the environmental variable "name" to be
+ * "value". If rewrite is set, replace any current value.
+ */
+setenv(name, value, rewrite)
+ register const char *name;
+ register const char *value;
+ int rewrite;
+{
+ extern char **environ;
+ static int alloced; /* if allocated space before */
+ register char *C;
+ int l_value, offset;
+ char *__findenv();
+
+ if (*value == '=') /* no `=' in value */
+ ++value;
+ l_value = strlen(value);
+ if ((C = __findenv(name, &offset))) { /* find if already exists */
+ if (!rewrite)
+ return (0);
+ if (strlen(C) >= l_value) { /* old larger; copy over */
+ while (*C++ = *value++);
+ return (0);
+ }
+ } else { /* create new slot */
+ register int cnt;
+ register char **P;
+
+ for (P = environ, cnt = 0; *P; ++P, ++cnt);
+ if (alloced) { /* just increase size */
+ environ = (char **)realloc((char *)environ,
+ (size_t)(sizeof(char *) * (cnt + 2)));
+ if (!environ)
+ return (-1);
+ }
+ else { /* get new space */
+ alloced = 1; /* copy old entries into it */
+ P = (char **)malloc((size_t)(sizeof(char *) *
+ (cnt + 2)));
+ if (!P)
+ return (-1);
+ bcopy(environ, P, cnt * sizeof(char *));
+ environ = P;
+ }
+ environ[cnt + 1] = NULL;
+ offset = cnt;
+ }
+ for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */
+ if (!(environ[offset] = /* name + `=' + value */
+ malloc((size_t)((int)(C - name) + l_value + 2))))
+ return (-1);
+ for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
+ ;
+ for (*C++ = '='; *C++ = *value++; )
+ ;
+ return (0);
+}
+
+/*
+ * unsetenv(name) --
+ * Delete environmental variable "name".
+ */
+void
+unsetenv(name)
+ const char *name;
+{
+ extern char **environ;
+ register char **P;
+ int offset;
+ char *__findenv();
+
+ while (__findenv(name, &offset)) /* if set multiple times */
+ for (P = &environ[offset];; ++P)
+ if (!(*P = *(P + 1)))
+ break;
+}
+#endif
diff --git a/external/bsd/bmake/dist/sigcompat.c b/external/bsd/bmake/dist/sigcompat.c
new file mode 100644
index 0000000..608538d
--- /dev/null
+++ b/external/bsd/bmake/dist/sigcompat.c
@@ -0,0 +1,325 @@
+/*
+ * NAME:
+ * sigcompat - BSD compat signals via POSIX
+ *
+ * SYNOPSIS:
+ * void (*signal(int "sig", void (*"handler")(int)))(int);
+ * int sigsetmask(int "mask");
+ * int sigblock(int "mask");
+ * int sigpause(int "mask");
+ * int sigvec(int "signo", struct sigvec *"sv", struct sigvec *"osv");
+ *
+ * DESCRIPTION:
+ * These implement the old BSD routines via the POSIX equivalents.
+ * This module can be used to provide the missing routines, or if
+ * 'FORCE_POSIX_SIGNALS' is defined, force use of these.
+ *
+ * Note that signal() is identical to my Signal() routine except
+ * for checking for recursion. Within libsig, signal() just
+ * calls Signal().
+ *
+ * BUGS:
+ * This package assumes POSIX signal handling is available and
+ * NOT implemeneted using these routines. To be safe, we check
+ * for recursion and abort(3) if detected.
+ *
+ * Sadly, on some systems, sigset_t is an array, and we cannot
+ * test for this via #if sizeof(sigset_t) ..., so unless
+ * 'SIGSET_T_INT' is defined, we have to assume the worst and use
+ * memcpy(3) to handle args and return values.
+ *
+ * HISTORY:
+ * These routines originate from BSD, and are derrived from the
+ * NetBSD 1.1 implementation. They have been seriously hacked to
+ * make them portable to other systems.
+ *
+ * AUTHOR:
+ * Simon J. Gerraty <sjg@crufty.net>
+ */
+/*
+ * @(#)Copyright (c) 1994, Simon J. Gerraty.
+ *
+ * This is free software. It comes with NO WARRANTY.
+ * Permission to use, modify and distribute this source code
+ * is granted subject to the following conditions.
+ * 1/ that the above copyright notice and this notice
+ * are preserved in all copies and that due credit be given
+ * to the author.
+ * 2/ that any changes to this code are clearly commented
+ * as such so that the author does not get blamed for bugs
+ * other than his own.
+ *
+ * Please send copies of changes and bug-fixes to:
+ * sjg@crufty.net
+ */
+
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <signal.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if defined(sun) && !(defined(__svr4__) || defined(__SVR4))
+# define NO_SIGCOMPAT
+#endif
+#if defined(__MINT__)
+# define NO_SIGCOMPAT
+#endif
+
+#if !defined(NO_SIGCOMPAT) && (defined(HAVE_SIGACTION) || defined(SA_NOCLDSTOP))
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)sigcompat.c 5.3 (Berkeley) 2/24/91";*/
+static char *rcsid = "$Id: sigcompat.c,v 1.23 2011/02/14 00:07:11 sjg Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#undef signal
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/cdefs.h>
+#include "assert.h"
+
+#ifndef ASSERT
+# define ASSERT assert
+#endif
+
+#ifdef NDEBUG
+# define _DBUG(x)
+#else
+# define _DBUG(x) x
+#endif
+
+#ifndef SA_RESTART
+# define SA_RESTART 2
+#endif
+#ifndef SV_INTERRUPT
+# define SV_INTERRUPT SA_RESTART
+#endif
+
+#ifndef MASK_T
+# if defined(__hpux__) || defined(__hpux)
+# define MASK_T long
+# else
+# define MASK_T int
+# endif
+#endif
+/* I just hate HPsUX */
+#if (defined(__HPUX_VERSION) && __HPUX_VERSION > 9) || defined(__hpux)
+# define PAUSE_MASK_T int
+#else
+# define PAUSE_MASK_T MASK_T
+#endif
+
+#ifndef SIG_HDLR
+# define SIG_HDLR void
+#endif
+
+#ifdef FORCE_POSIX_SIGNALS
+#if !(defined(libsig) || defined(libsjg))
+/*
+ * This little block is almost identical to Signal(),
+ * and make this module standalone.
+ * We don't use it in libsig by default, as some apps might use both
+ * and expect _SignalFlags to be used by both.
+ */
+
+#ifndef SIGNAL_FLAGS
+# define SIGNAL_FLAGS 0 /* no auto-restart */
+#endif
+int _signalFlags = SIGNAL_FLAGS;
+
+SIG_HDLR(*signal(int sig, SIG_HDLR(*handler)(int)))(int)
+{
+ _DBUG(static int depth_signal = 0);
+ struct sigaction act, oact;
+ int n;
+
+ _DBUG(++depth_signal);
+ ASSERT(depth_signal < 2);
+ act.sa_handler = handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = _signalFlags;
+ n = sigaction(sig, &act, &oact);
+ _DBUG(--depth_signal);
+ if (n < 0)
+ return (SIG_ERR);
+ return (oact.sa_handler);
+}
+#else
+SIG_HDLR(*signal(int sig, SIG_HDLR(*handler)(int)))(int)
+{
+ extern SIG_HDLR(*Signal(int, void (*)(int)))(int);
+ _DBUG(static int depth_signal = 0);
+ SIG_HDLR(*old) __P((int));
+
+ _DBUG(++depth_signal);
+ ASSERT(depth_signal < 2);
+ old = Signal(sig, handler);
+ _DBUG(--depth_signal);
+ return old;
+}
+#endif
+#endif
+
+/*
+ * on some systems, sigset_t is an array...
+ * it would be nicer if we could do
+ * #if sizeof(sigset_t) > sizeof(MASK_T)
+ */
+#ifdef SIGSET_T_INT
+# define ss2m(ss) (MASK_T) *(ss)
+# define m2ss(ss, m) *ss = (sigset_t) *(m)
+#else
+static MASK_T
+ss2m(sigset_t *ss)
+{
+ MASK_T ma[(sizeof(sigset_t) / sizeof(MASK_T)) + 1];
+
+ memcpy((char *) ma, (char *) ss, sizeof(sigset_t));
+ return ma[0];
+}
+
+static void
+m2ss(sigset_t *ss, MASK_T *m)
+{
+ if (sizeof(sigset_t) > sizeof(MASK_T))
+ memset((char *) ss, 0, sizeof(sigset_t));
+
+ memcpy((char *) ss, (char *) m, sizeof(MASK_T));
+}
+#endif
+
+#if !defined(HAVE_SIGSETMASK) || defined(FORCE_POSIX_SIGNALS)
+MASK_T
+sigsetmask(MASK_T mask)
+{
+ _DBUG(static int depth_sigsetmask = 0);
+ sigset_t m, omask;
+ int n;
+
+ _DBUG(++depth_sigsetmask);
+ ASSERT(depth_sigsetmask < 2);
+ m2ss(&m, &mask);
+ n = sigprocmask(SIG_SETMASK, (sigset_t *) & m, (sigset_t *) & omask);
+ _DBUG(--depth_sigsetmask);
+ if (n)
+ return (n);
+
+ return ss2m(&omask);
+}
+
+
+MASK_T
+sigblock(MASK_T mask)
+{
+ _DBUG(static int depth_sigblock = 0);
+ sigset_t m, omask;
+ int n;
+
+ _DBUG(++depth_sigblock);
+ ASSERT(depth_sigblock < 2);
+ if (mask)
+ m2ss(&m, &mask);
+ n = sigprocmask(SIG_BLOCK, (sigset_t *) ((mask) ? &m : 0), (sigset_t *) & omask);
+ _DBUG(--depth_sigblock);
+ if (n)
+ return (n);
+ return ss2m(&omask);
+}
+
+#undef sigpause /* Linux at least */
+
+PAUSE_MASK_T
+sigpause(PAUSE_MASK_T mask)
+{
+ _DBUG(static int depth_sigpause = 0);
+ sigset_t m;
+ PAUSE_MASK_T n;
+
+ _DBUG(++depth_sigpause);
+ ASSERT(depth_sigpause < 2);
+ m2ss(&m, &mask);
+ n = sigsuspend(&m);
+ _DBUG(--depth_sigpause);
+ return n;
+}
+#endif
+
+#if defined(HAVE_SIGVEC) && defined(FORCE_POSIX_SIGNALS)
+int
+sigvec(int signo, struct sigvec *sv, struct sigvec *osv)
+{
+ _DBUG(static int depth_sigvec = 0);
+ int ret;
+ struct sigvec nsv;
+
+ _DBUG(++depth_sigvec);
+ ASSERT(depth_sigvec < 2);
+ if (sv) {
+ nsv = *sv;
+ nsv.sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */
+ }
+ ret = sigaction(signo, sv ? (struct sigaction *) & nsv : NULL,
+ (struct sigaction *) osv);
+ _DBUG(--depth_sigvec);
+ if (ret == 0 && osv)
+ osv->sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */
+ return (ret);
+}
+#endif
+
+#ifdef MAIN
+# ifndef sigmask
+# define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1)))
+# endif
+
+int
+main(int argc, char *argv[])
+{
+ MASK_T old = 0;
+
+ printf("expect: old=0,old=2\n");
+ fflush(stdout);
+ signal(SIGQUIT, SIG_IGN);
+ old = sigblock(sigmask(SIGINT));
+ printf("old=%d,", old);
+ old = sigsetmask(sigmask(SIGALRM));
+ printf("old=%d\n", old);
+}
+#endif
+#endif
diff --git a/external/bsd/bmake/dist/sprite.h b/external/bsd/bmake/dist/sprite.h
new file mode 100644
index 0000000..6ec4fe2
--- /dev/null
+++ b/external/bsd/bmake/dist/sprite.h
@@ -0,0 +1,116 @@
+/* $NetBSD: sprite.h,v 1.11 2009/01/23 21:26:30 dsl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)sprite.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)sprite.h 8.1 (Berkeley) 6/6/93
+ */
+
+/*
+ * sprite.h --
+ *
+ * Common constants and type declarations for Sprite.
+ */
+
+#ifndef _SPRITE
+#define _SPRITE
+
+
+/*
+ * A boolean type is defined as an integer, not an enum. This allows a
+ * boolean argument to be an expression that isn't strictly 0 or 1 valued.
+ */
+
+typedef int Boolean;
+#ifndef TRUE
+#define TRUE 1
+#endif /* TRUE */
+#ifndef FALSE
+#define FALSE 0
+#endif /* FALSE */
+
+/*
+ * Functions that must return a status can return a ReturnStatus to
+ * indicate success or type of failure.
+ */
+
+typedef int ReturnStatus;
+
+/*
+ * The following statuses overlap with the first 2 generic statuses
+ * defined in status.h:
+ *
+ * SUCCESS There was no error.
+ * FAILURE There was a general error.
+ */
+
+#define SUCCESS 0x00000000
+#define FAILURE 0x00000001
+
+#endif /* _SPRITE */
diff --git a/external/bsd/bmake/dist/str.c b/external/bsd/bmake/dist/str.c
new file mode 100644
index 0000000..bc324b8
--- /dev/null
+++ b/external/bsd/bmake/dist/str.c
@@ -0,0 +1,508 @@
+/* $NetBSD: str.c,v 1.34 2012/03/03 23:16:47 dholland Exp $ */
+
+/*-
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: str.c,v 1.34 2012/03/03 23:16:47 dholland Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90";
+#else
+__RCSID("$NetBSD: str.c,v 1.34 2012/03/03 23:16:47 dholland Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+#include "make.h"
+
+/*-
+ * str_concat --
+ * concatenate the two strings, inserting a space or slash between them,
+ * freeing them if requested.
+ *
+ * returns --
+ * the resulting string in allocated space.
+ */
+char *
+str_concat(const char *s1, const char *s2, int flags)
+{
+ int len1, len2;
+ char *result;
+
+ /* get the length of both strings */
+ len1 = strlen(s1);
+ len2 = strlen(s2);
+
+ /* allocate length plus separator plus EOS */
+ result = bmake_malloc((u_int)(len1 + len2 + 2));
+
+ /* copy first string into place */
+ memcpy(result, s1, len1);
+
+ /* add separator character */
+ if (flags & STR_ADDSPACE) {
+ result[len1] = ' ';
+ ++len1;
+ } else if (flags & STR_ADDSLASH) {
+ result[len1] = '/';
+ ++len1;
+ }
+
+ /* copy second string plus EOS into place */
+ memcpy(result + len1, s2, len2 + 1);
+
+ return(result);
+}
+
+/*-
+ * brk_string --
+ * Fracture a string into an array of words (as delineated by tabs or
+ * spaces) taking quotation marks into account. Leading tabs/spaces
+ * are ignored.
+ *
+ * If expand is TRUE, quotes are removed and escape sequences
+ * such as \r, \t, etc... are expanded.
+ *
+ * returns --
+ * Pointer to the array of pointers to the words.
+ * Memory containing the actual words in *buffer.
+ * Both of these must be free'd by the caller.
+ * Number of words in *store_argc.
+ */
+char **
+brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
+{
+ int argc, ch;
+ char inquote, *start, *t;
+ const char *p;
+ int len;
+ int argmax = 50, curlen = 0;
+ char **argv = bmake_malloc((argmax + 1) * sizeof(char *));
+
+ /* skip leading space chars. */
+ for (; *str == ' ' || *str == '\t'; ++str)
+ continue;
+
+ /* allocate room for a copy of the string */
+ if ((len = strlen(str) + 1) > curlen)
+ *buffer = bmake_malloc(curlen = len);
+
+ /*
+ * copy the string; at the same time, parse backslashes,
+ * quotes and build the argument list.
+ */
+ argc = 0;
+ inquote = '\0';
+ for (p = str, start = t = *buffer;; ++p) {
+ switch(ch = *p) {
+ case '"':
+ case '\'':
+ if (inquote) {
+ if (inquote == ch)
+ inquote = '\0';
+ else
+ break;
+ }
+ else {
+ inquote = (char) ch;
+ /* Don't miss "" or '' */
+ if (start == NULL && p[1] == inquote) {
+ if (!expand) {
+ start = t;
+ *t++ = ch;
+ } else
+ start = t + 1;
+ p++;
+ inquote = '\0';
+ break;
+ }
+ }
+ if (!expand) {
+ if (!start)
+ start = t;
+ *t++ = ch;
+ }
+ continue;
+ case ' ':
+ case '\t':
+ case '\n':
+ if (inquote)
+ break;
+ if (!start)
+ continue;
+ /* FALLTHROUGH */
+ case '\0':
+ /*
+ * end of a token -- make sure there's enough argv
+ * space and save off a pointer.
+ */
+ if (!start)
+ goto done;
+
+ *t++ = '\0';
+ if (argc == argmax) {
+ argmax *= 2; /* ramp up fast */
+ argv = (char **)bmake_realloc(argv,
+ (argmax + 1) * sizeof(char *));
+ }
+ argv[argc++] = start;
+ start = NULL;
+ if (ch == '\n' || ch == '\0') {
+ if (expand && inquote) {
+ free(argv);
+ free(*buffer);
+ *buffer = NULL;
+ return NULL;
+ }
+ goto done;
+ }
+ continue;
+ case '\\':
+ if (!expand) {
+ if (!start)
+ start = t;
+ *t++ = '\\';
+ if (*(p+1) == '\0') /* catch '\' at end of line */
+ continue;
+ ch = *++p;
+ break;
+ }
+
+ switch (ch = *++p) {
+ case '\0':
+ case '\n':
+ /* hmmm; fix it up as best we can */
+ ch = '\\';
+ --p;
+ break;
+ case 'b':
+ ch = '\b';
+ break;
+ case 'f':
+ ch = '\f';
+ break;
+ case 'n':
+ ch = '\n';
+ break;
+ case 'r':
+ ch = '\r';
+ break;
+ case 't':
+ ch = '\t';
+ break;
+ }
+ break;
+ }
+ if (!start)
+ start = t;
+ *t++ = (char) ch;
+ }
+done: argv[argc] = NULL;
+ *store_argc = argc;
+ return(argv);
+}
+
+/*
+ * Str_FindSubstring -- See if a string contains a particular substring.
+ *
+ * Input:
+ * string String to search.
+ * substring Substring to find in string.
+ *
+ * Results: If string contains substring, the return value is the location of
+ * the first matching instance of substring in string. If string doesn't
+ * contain substring, the return value is NULL. Matching is done on an exact
+ * character-for-character basis with no wildcards or special characters.
+ *
+ * Side effects: None.
+ */
+char *
+Str_FindSubstring(const char *string, const char *substring)
+{
+ const char *a, *b;
+
+ /*
+ * First scan quickly through the two strings looking for a single-
+ * character match. When it's found, then compare the rest of the
+ * substring.
+ */
+
+ for (b = substring; *string != 0; string += 1) {
+ if (*string != *b)
+ continue;
+ a = string;
+ for (;;) {
+ if (*b == 0)
+ return UNCONST(string);
+ if (*a++ != *b++)
+ break;
+ }
+ b = substring;
+ }
+ return NULL;
+}
+
+/*
+ * Str_Match --
+ *
+ * See if a particular string matches a particular pattern.
+ *
+ * Results: Non-zero is returned if string matches pattern, 0 otherwise. The
+ * matching operation permits the following special characters in the
+ * pattern: *?\[] (see the man page for details on what these mean).
+ *
+ * XXX this function does not detect or report malformed patterns.
+ *
+ * Side effects: None.
+ */
+int
+Str_Match(const char *string, const char *pattern)
+{
+ char c2;
+
+ for (;;) {
+ /*
+ * See if we're at the end of both the pattern and the
+ * string. If, we succeeded. If we're at the end of the
+ * pattern but not at the end of the string, we failed.
+ */
+ if (*pattern == 0)
+ return(!*string);
+ if (*string == 0 && *pattern != '*')
+ return(0);
+ /*
+ * Check for a "*" as the next pattern character. It matches
+ * any substring. We handle this by calling ourselves
+ * recursively for each postfix of string, until either we
+ * match or we reach the end of the string.
+ */
+ if (*pattern == '*') {
+ pattern += 1;
+ if (*pattern == 0)
+ return(1);
+ while (*string != 0) {
+ if (Str_Match(string, pattern))
+ return(1);
+ ++string;
+ }
+ return(0);
+ }
+ /*
+ * Check for a "?" as the next pattern character. It matches
+ * any single character.
+ */
+ if (*pattern == '?')
+ goto thisCharOK;
+ /*
+ * Check for a "[" as the next pattern character. It is
+ * followed by a list of characters that are acceptable, or
+ * by a range (two characters separated by "-").
+ */
+ if (*pattern == '[') {
+ ++pattern;
+ for (;;) {
+ if ((*pattern == ']') || (*pattern == 0))
+ return(0);
+ if (*pattern == *string)
+ break;
+ if (pattern[1] == '-') {
+ c2 = pattern[2];
+ if (c2 == 0)
+ return(0);
+ if ((*pattern <= *string) &&
+ (c2 >= *string))
+ break;
+ if ((*pattern >= *string) &&
+ (c2 <= *string))
+ break;
+ pattern += 2;
+ }
+ ++pattern;
+ }
+ while ((*pattern != ']') && (*pattern != 0))
+ ++pattern;
+ goto thisCharOK;
+ }
+ /*
+ * If the next pattern character is '/', just strip off the
+ * '/' so we do exact matching on the character that follows.
+ */
+ if (*pattern == '\\') {
+ ++pattern;
+ if (*pattern == 0)
+ return(0);
+ }
+ /*
+ * There's no special character. Just make sure that the
+ * next characters of each string match.
+ */
+ if (*pattern != *string)
+ return(0);
+thisCharOK: ++pattern;
+ ++string;
+ }
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Str_SYSVMatch --
+ * Check word against pattern for a match (% is wild),
+ *
+ * Input:
+ * word Word to examine
+ * pattern Pattern to examine against
+ * len Number of characters to substitute
+ *
+ * Results:
+ * Returns the beginning position of a match or null. The number
+ * of characters matched is returned in len.
+ *
+ * Side Effects:
+ * None
+ *
+ *-----------------------------------------------------------------------
+ */
+char *
+Str_SYSVMatch(const char *word, const char *pattern, int *len)
+{
+ const char *p = pattern;
+ const char *w = word;
+ const char *m;
+
+ if (*p == '\0') {
+ /* Null pattern is the whole string */
+ *len = strlen(w);
+ return UNCONST(w);
+ }
+
+ if ((m = strchr(p, '%')) != NULL) {
+ /* check that the prefix matches */
+ for (; p != m && *w && *w == *p; w++, p++)
+ continue;
+
+ if (p != m)
+ return NULL; /* No match */
+
+ if (*++p == '\0') {
+ /* No more pattern, return the rest of the string */
+ *len = strlen(w);
+ return UNCONST(w);
+ }
+ }
+
+ m = w;
+
+ /* Find a matching tail */
+ do
+ if (strcmp(p, w) == 0) {
+ *len = w - m;
+ return UNCONST(m);
+ }
+ while (*w++ != '\0');
+
+ return NULL;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Str_SYSVSubst --
+ * Substitute '%' on the pattern with len characters from src.
+ * If the pattern does not contain a '%' prepend len characters
+ * from src.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * Places result on buf
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Str_SYSVSubst(Buffer *buf, char *pat, char *src, int len)
+{
+ char *m;
+
+ if ((m = strchr(pat, '%')) != NULL) {
+ /* Copy the prefix */
+ Buf_AddBytes(buf, m - pat, pat);
+ /* skip the % */
+ pat = m + 1;
+ }
+
+ /* Copy the pattern */
+ Buf_AddBytes(buf, len, src);
+
+ /* append the rest */
+ Buf_AddBytes(buf, strlen(pat), pat);
+}
diff --git a/external/bsd/bmake/dist/stresep.c b/external/bsd/bmake/dist/stresep.c
new file mode 100644
index 0000000..b1b5714
--- /dev/null
+++ b/external/bsd/bmake/dist/stresep.c
@@ -0,0 +1,89 @@
+/* $NetBSD: stresep.c,v 1.2 2007/12/06 22:07:07 seb Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/cdefs.h>
+
+#include <assert.h>
+#include <string.h>
+
+#if !defined(HAVE_STRESEP)
+char * stresep(char **stringp, const char *delim, int esc);
+/*
+ * Get next token from string *stringp, where tokens are possibly-empty
+ * strings separated by characters from delim. If esc is not NUL, then
+ * the characters followed by esc are ignored and are not taken into account
+ * when splitting the string.
+ *
+ * Writes NULs into the string at *stringp to end tokens.
+ * delim need not remain constant from call to call.
+ * On return, *stringp points past the last NUL written (if there might
+ * be further tokens), or is NULL (if there are definitely no more tokens).
+ *
+ * If *stringp is NULL, stresep returns NULL.
+ */
+char *
+stresep(char **stringp, const char *delim, int esc)
+{
+ char *s;
+ const char *spanp;
+ int c, sc;
+ char *tok;
+
+ if (stringp == NULL || delim == NULL)
+ return NULL;
+
+ if ((s = *stringp) == NULL)
+ return NULL;
+ for (tok = s;;) {
+ c = *s++;
+ while (esc != '\0' && c == esc) {
+ (void)strcpy(s - 1, s);
+ c = *s++;
+ }
+ spanp = delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *stringp = s;
+ return tok;
+ }
+ } while (sc != 0);
+ }
+}
+#endif
+
diff --git a/external/bsd/bmake/dist/strlcpy.c b/external/bsd/bmake/dist/strlcpy.c
new file mode 100644
index 0000000..b59b2f4
--- /dev/null
+++ b/external/bsd/bmake/dist/strlcpy.c
@@ -0,0 +1,63 @@
+/* $NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */
+/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#ifndef HAVE_STRLCPY
+
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+
+ if (!dst || !src)
+ return 0;
+
+ /* Copy as many bytes as will fit */
+ if (n != 0 && --n != 0) {
+ do {
+ if ((*d++ = *s++) == 0)
+ break;
+ } while (--n != 0);
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if (n == 0) {
+ if (siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while (*s++)
+ ;
+ }
+
+ return(s - src - 1); /* count does not include NUL */
+}
+#endif
diff --git a/external/bsd/bmake/dist/strlist.c b/external/bsd/bmake/dist/strlist.c
new file mode 100644
index 0000000..3fb2f7d
--- /dev/null
+++ b/external/bsd/bmake/dist/strlist.c
@@ -0,0 +1,93 @@
+/* $NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $ */
+
+/*-
+ * Copyright (c) 2008 - 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by David Laight.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $");
+#endif /* not lint */
+#endif
+
+#include <stddef.h>
+#include <stdlib.h>
+#include "strlist.h"
+#include "make_malloc.h"
+
+void
+strlist_init(strlist_t *sl)
+{
+ sl->sl_num = 0;
+ sl->sl_max = 0;
+ sl->sl_items = NULL;
+}
+
+void
+strlist_clean(strlist_t *sl)
+{
+ char *str;
+ int i;
+
+ STRLIST_FOREACH(str, sl, i)
+ free(str);
+ free(sl->sl_items);
+
+ sl->sl_num = 0;
+ sl->sl_max = 0;
+ sl->sl_items = NULL;
+}
+
+void
+strlist_add_str(strlist_t *sl, char *str, unsigned int info)
+{
+ unsigned int n;
+ strlist_item_t *items;
+
+ if (str == NULL)
+ return;
+
+ n = sl->sl_num + 1;
+ sl->sl_num = n;
+ items = sl->sl_items;
+ if (n >= sl->sl_max) {
+ items = bmake_realloc(items, (n + 7) * sizeof *sl->sl_items);
+ sl->sl_items = items;
+ sl->sl_max = n + 6;
+ }
+ items += n - 1;
+ items->si_str = str;
+ items->si_info = info;
+ items[1].si_str = NULL; /* STRLIST_FOREACH() terminator */
+}
diff --git a/external/bsd/bmake/dist/strlist.h b/external/bsd/bmake/dist/strlist.h
new file mode 100644
index 0000000..2fc049e
--- /dev/null
+++ b/external/bsd/bmake/dist/strlist.h
@@ -0,0 +1,62 @@
+/* $NetBSD: strlist.h,v 1.3 2009/01/16 21:15:34 dsl Exp $ */
+
+/*-
+ * Copyright (c) 2008 - 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by David Laight.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _STRLIST_H
+#define _STRLIST_H
+
+typedef struct {
+ char *si_str;
+ unsigned int si_info;
+} strlist_item_t;
+
+typedef struct {
+ unsigned int sl_num;
+ unsigned int sl_max;
+ strlist_item_t *sl_items;
+} strlist_t;
+
+void strlist_init(strlist_t *);
+void strlist_clean(strlist_t *);
+void strlist_add_str(strlist_t *, char *, unsigned int);
+
+#define strlist_num(sl) ((sl)->sl_num)
+#define strlist_str(sl, n) ((sl)->sl_items[n].si_str)
+#define strlist_info(sl, n) ((sl)->sl_items[n].si_info)
+#define strlist_set_info(sl, n, v) ((void)((sl)->sl_items[n].si_info = (v)))
+
+#define STRLIST_FOREACH(v, sl, index) \
+ if ((sl)->sl_items != NULL) \
+ for (index = 0; (v = strlist_str(sl, index)) != NULL; index++)
+
+#endif /* _STRLIST_H */
diff --git a/external/bsd/bmake/dist/suff.c b/external/bsd/bmake/dist/suff.c
new file mode 100644
index 0000000..6abdeb0
--- /dev/null
+++ b/external/bsd/bmake/dist/suff.c
@@ -0,0 +1,2653 @@
+/* $NetBSD: suff.c,v 1.69 2011/09/29 23:38:04 sjg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: suff.c,v 1.69 2011/09/29 23:38:04 sjg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94";
+#else
+__RCSID("$NetBSD: suff.c,v 1.69 2011/09/29 23:38:04 sjg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * suff.c --
+ * Functions to maintain suffix lists and find implicit dependents
+ * using suffix transformation rules
+ *
+ * Interface:
+ * Suff_Init Initialize all things to do with suffixes.
+ *
+ * Suff_End Cleanup the module
+ *
+ * Suff_DoPaths This function is used to make life easier
+ * when searching for a file according to its
+ * suffix. It takes the global search path,
+ * as defined using the .PATH: target, and appends
+ * its directories to the path of each of the
+ * defined suffixes, as specified using
+ * .PATH<suffix>: targets. In addition, all
+ * directories given for suffixes labeled as
+ * include files or libraries, using the .INCLUDES
+ * or .LIBS targets, are played with using
+ * Dir_MakeFlags to create the .INCLUDES and
+ * .LIBS global variables.
+ *
+ * Suff_ClearSuffixes Clear out all the suffixes and defined
+ * transformations.
+ *
+ * Suff_IsTransform Return TRUE if the passed string is the lhs
+ * of a transformation rule.
+ *
+ * Suff_AddSuffix Add the passed string as another known suffix.
+ *
+ * Suff_GetPath Return the search path for the given suffix.
+ *
+ * Suff_AddInclude Mark the given suffix as denoting an include
+ * file.
+ *
+ * Suff_AddLib Mark the given suffix as denoting a library.
+ *
+ * Suff_AddTransform Add another transformation to the suffix
+ * graph. Returns GNode suitable for framing, I
+ * mean, tacking commands, attributes, etc. on.
+ *
+ * Suff_SetNull Define the suffix to consider the suffix of
+ * any file that doesn't have a known one.
+ *
+ * Suff_FindDeps Find implicit sources for and the location of
+ * a target based on its suffix. Returns the
+ * bottom-most node added to the graph or NULL
+ * if the target had no implicit sources.
+ *
+ * Suff_FindPath Return the appropriate path to search in
+ * order to find the node.
+ */
+
+#include <stdio.h>
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+
+static Lst sufflist; /* Lst of suffixes */
+#ifdef CLEANUP
+static Lst suffClean; /* Lst of suffixes to be cleaned */
+#endif
+static Lst srclist; /* Lst of sources */
+static Lst transforms; /* Lst of transformation rules */
+
+static int sNum = 0; /* Counter for assigning suffix numbers */
+
+/*
+ * Structure describing an individual suffix.
+ */
+typedef struct _Suff {
+ char *name; /* The suffix itself */
+ int nameLen; /* Length of the suffix */
+ short flags; /* Type of suffix */
+#define SUFF_INCLUDE 0x01 /* One which is #include'd */
+#define SUFF_LIBRARY 0x02 /* One which contains a library */
+#define SUFF_NULL 0x04 /* The empty suffix */
+ Lst searchPath; /* The path along which files of this suffix
+ * may be found */
+ int sNum; /* The suffix number */
+ int refCount; /* Reference count of list membership */
+ Lst parents; /* Suffixes we have a transformation to */
+ Lst children; /* Suffixes we have a transformation from */
+ Lst ref; /* List of lists this suffix is referenced */
+} Suff;
+
+/*
+ * for SuffSuffIsSuffix
+ */
+typedef struct {
+ char *ename; /* The end of the name */
+ int len; /* Length of the name */
+} SuffixCmpData;
+
+/*
+ * Structure used in the search for implied sources.
+ */
+typedef struct _Src {
+ char *file; /* The file to look for */
+ char *pref; /* Prefix from which file was formed */
+ Suff *suff; /* The suffix on the file */
+ struct _Src *parent; /* The Src for which this is a source */
+ GNode *node; /* The node describing the file */
+ int children; /* Count of existing children (so we don't free
+ * this thing too early or never nuke it) */
+#ifdef DEBUG_SRC
+ Lst cp; /* Debug; children list */
+#endif
+} Src;
+
+/*
+ * A structure for passing more than one argument to the Lst-library-invoked
+ * function...
+ */
+typedef struct {
+ Lst l;
+ Src *s;
+} LstSrc;
+
+typedef struct {
+ GNode **gn;
+ Suff *s;
+ Boolean r;
+} GNodeSuff;
+
+static Suff *suffNull; /* The NULL suffix for this run */
+static Suff *emptySuff; /* The empty suffix required for POSIX
+ * single-suffix transformation rules */
+
+
+static const char *SuffStrIsPrefix(const char *, const char *);
+static char *SuffSuffIsSuffix(const Suff *, const SuffixCmpData *);
+static int SuffSuffIsSuffixP(const void *, const void *);
+static int SuffSuffHasNameP(const void *, const void *);
+static int SuffSuffIsPrefix(const void *, const void *);
+static int SuffGNHasNameP(const void *, const void *);
+static void SuffUnRef(void *, void *);
+static void SuffFree(void *);
+static void SuffInsert(Lst, Suff *);
+static void SuffRemove(Lst, Suff *);
+static Boolean SuffParseTransform(char *, Suff **, Suff **);
+static int SuffRebuildGraph(void *, void *);
+static int SuffScanTargets(void *, void *);
+static int SuffAddSrc(void *, void *);
+static int SuffRemoveSrc(Lst);
+static void SuffAddLevel(Lst, Src *);
+static Src *SuffFindThem(Lst, Lst);
+static Src *SuffFindCmds(Src *, Lst);
+static void SuffExpandChildren(LstNode, GNode *);
+static void SuffExpandWildcards(LstNode, GNode *);
+static Boolean SuffApplyTransform(GNode *, GNode *, Suff *, Suff *);
+static void SuffFindDeps(GNode *, Lst);
+static void SuffFindArchiveDeps(GNode *, Lst);
+static void SuffFindNormalDeps(GNode *, Lst);
+static int SuffPrintName(void *, void *);
+static int SuffPrintSuff(void *, void *);
+static int SuffPrintTrans(void *, void *);
+
+ /*************** Lst Predicates ****************/
+/*-
+ *-----------------------------------------------------------------------
+ * SuffStrIsPrefix --
+ * See if pref is a prefix of str.
+ *
+ * Input:
+ * pref possible prefix
+ * str string to check
+ *
+ * Results:
+ * NULL if it ain't, pointer to character in str after prefix if so
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+static const char *
+SuffStrIsPrefix(const char *pref, const char *str)
+{
+ while (*str && *pref == *str) {
+ pref++;
+ str++;
+ }
+
+ return (*pref ? NULL : str);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffSuffIsSuffix --
+ * See if suff is a suffix of str. sd->ename should point to THE END
+ * of the string to check. (THE END == the null byte)
+ *
+ * Input:
+ * s possible suffix
+ * sd string to examine
+ *
+ * Results:
+ * NULL if it ain't, pointer to character in str before suffix if
+ * it is.
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+static char *
+SuffSuffIsSuffix(const Suff *s, const SuffixCmpData *sd)
+{
+ char *p1; /* Pointer into suffix name */
+ char *p2; /* Pointer into string being examined */
+
+ if (sd->len < s->nameLen)
+ return NULL; /* this string is shorter than the suffix */
+
+ p1 = s->name + s->nameLen;
+ p2 = sd->ename;
+
+ while (p1 >= s->name && *p1 == *p2) {
+ p1--;
+ p2--;
+ }
+
+ return (p1 == s->name - 1 ? p2 : NULL);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffSuffIsSuffixP --
+ * Predicate form of SuffSuffIsSuffix. Passed as the callback function
+ * to Lst_Find.
+ *
+ * Results:
+ * 0 if the suffix is the one desired, non-zero if not.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+SuffSuffIsSuffixP(const void *s, const void *sd)
+{
+ return(!SuffSuffIsSuffix(s, sd));
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffSuffHasNameP --
+ * Callback procedure for finding a suffix based on its name. Used by
+ * Suff_GetPath.
+ *
+ * Input:
+ * s Suffix to check
+ * sd Desired name
+ *
+ * Results:
+ * 0 if the suffix is of the given name. non-zero otherwise.
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+static int
+SuffSuffHasNameP(const void *s, const void *sname)
+{
+ return (strcmp(sname, ((const Suff *)s)->name));
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffSuffIsPrefix --
+ * See if the suffix described by s is a prefix of the string. Care
+ * must be taken when using this to search for transformations and
+ * what-not, since there could well be two suffixes, one of which
+ * is a prefix of the other...
+ *
+ * Input:
+ * s suffix to compare
+ * str string to examine
+ *
+ * Results:
+ * 0 if s is a prefix of str. non-zero otherwise
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+static int
+SuffSuffIsPrefix(const void *s, const void *str)
+{
+ return SuffStrIsPrefix(((const Suff *)s)->name, str) == NULL;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffGNHasNameP --
+ * See if the graph node has the desired name
+ *
+ * Input:
+ * gn current node we're looking at
+ * name name we're looking for
+ *
+ * Results:
+ * 0 if it does. non-zero if it doesn't
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+static int
+SuffGNHasNameP(const void *gn, const void *name)
+{
+ return (strcmp(name, ((const GNode *)gn)->name));
+}
+
+ /*********** Maintenance Functions ************/
+
+static void
+SuffUnRef(void *lp, void *sp)
+{
+ Lst l = (Lst) lp;
+
+ LstNode ln = Lst_Member(l, sp);
+ if (ln != NULL) {
+ Lst_Remove(l, ln);
+ ((Suff *)sp)->refCount--;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffFree --
+ * Free up all memory associated with the given suffix structure.
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * the suffix entry is detroyed
+ *-----------------------------------------------------------------------
+ */
+static void
+SuffFree(void *sp)
+{
+ Suff *s = (Suff *)sp;
+
+ if (s == suffNull)
+ suffNull = NULL;
+
+ if (s == emptySuff)
+ emptySuff = NULL;
+
+#ifdef notdef
+ /* We don't delete suffixes in order, so we cannot use this */
+ if (s->refCount)
+ Punt("Internal error deleting suffix `%s' with refcount = %d", s->name,
+ s->refCount);
+#endif
+
+ Lst_Destroy(s->ref, NULL);
+ Lst_Destroy(s->children, NULL);
+ Lst_Destroy(s->parents, NULL);
+ Lst_Destroy(s->searchPath, Dir_Destroy);
+
+ free(s->name);
+ free(s);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffRemove --
+ * Remove the suffix into the list
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The reference count for the suffix is decremented and the
+ * suffix is possibly freed
+ *-----------------------------------------------------------------------
+ */
+static void
+SuffRemove(Lst l, Suff *s)
+{
+ SuffUnRef(l, s);
+ if (s->refCount == 0) {
+ SuffUnRef(sufflist, s);
+ SuffFree(s);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffInsert --
+ * Insert the suffix into the list keeping the list ordered by suffix
+ * numbers.
+ *
+ * Input:
+ * l the list where in s should be inserted
+ * s the suffix to insert
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The reference count of the suffix is incremented
+ *-----------------------------------------------------------------------
+ */
+static void
+SuffInsert(Lst l, Suff *s)
+{
+ LstNode ln; /* current element in l we're examining */
+ Suff *s2 = NULL; /* the suffix descriptor in this element */
+
+ if (Lst_Open(l) == FAILURE) {
+ return;
+ }
+ while ((ln = Lst_Next(l)) != NULL) {
+ s2 = (Suff *)Lst_Datum(ln);
+ if (s2->sNum >= s->sNum) {
+ break;
+ }
+ }
+
+ Lst_Close(l);
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "inserting %s(%d)...", s->name, s->sNum);
+ }
+ if (ln == NULL) {
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "at end of list\n");
+ }
+ (void)Lst_AtEnd(l, s);
+ s->refCount++;
+ (void)Lst_AtEnd(s->ref, l);
+ } else if (s2->sNum != s->sNum) {
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "before %s(%d)\n", s2->name, s2->sNum);
+ }
+ (void)Lst_InsertBefore(l, ln, s);
+ s->refCount++;
+ (void)Lst_AtEnd(s->ref, l);
+ } else if (DEBUG(SUFF)) {
+ fprintf(debug_file, "already there\n");
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_ClearSuffixes --
+ * This is gross. Nuke the list of suffixes but keep all transformation
+ * rules around. The transformation graph is destroyed in this process,
+ * but we leave the list of rules so when a new graph is formed the rules
+ * will remain.
+ * This function is called from the parse module when a
+ * .SUFFIXES:\n line is encountered.
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * the sufflist and its graph nodes are destroyed
+ *-----------------------------------------------------------------------
+ */
+void
+Suff_ClearSuffixes(void)
+{
+#ifdef CLEANUP
+ Lst_Concat(suffClean, sufflist, LST_CONCLINK);
+#endif
+ sufflist = Lst_Init(FALSE);
+ sNum = 0;
+ suffNull = emptySuff;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffParseTransform --
+ * Parse a transformation string to find its two component suffixes.
+ *
+ * Input:
+ * str String being parsed
+ * srcPtr Place to store source of trans.
+ * targPtr Place to store target of trans.
+ *
+ * Results:
+ * TRUE if the string is a valid transformation and FALSE otherwise.
+ *
+ * Side Effects:
+ * The passed pointers are overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+SuffParseTransform(char *str, Suff **srcPtr, Suff **targPtr)
+{
+ LstNode srcLn; /* element in suffix list of trans source*/
+ Suff *src; /* Source of transformation */
+ LstNode targLn; /* element in suffix list of trans target*/
+ char *str2; /* Extra pointer (maybe target suffix) */
+ LstNode singleLn; /* element in suffix list of any suffix
+ * that exactly matches str */
+ Suff *single = NULL;/* Source of possible transformation to
+ * null suffix */
+
+ srcLn = NULL;
+ singleLn = NULL;
+
+ /*
+ * Loop looking first for a suffix that matches the start of the
+ * string and then for one that exactly matches the rest of it. If
+ * we can find two that meet these criteria, we've successfully
+ * parsed the string.
+ */
+ for (;;) {
+ if (srcLn == NULL) {
+ srcLn = Lst_Find(sufflist, str, SuffSuffIsPrefix);
+ } else {
+ srcLn = Lst_FindFrom(sufflist, Lst_Succ(srcLn), str,
+ SuffSuffIsPrefix);
+ }
+ if (srcLn == NULL) {
+ /*
+ * Ran out of source suffixes -- no such rule
+ */
+ if (singleLn != NULL) {
+ /*
+ * Not so fast Mr. Smith! There was a suffix that encompassed
+ * the entire string, so we assume it was a transformation
+ * to the null suffix (thank you POSIX). We still prefer to
+ * find a double rule over a singleton, hence we leave this
+ * check until the end.
+ *
+ * XXX: Use emptySuff over suffNull?
+ */
+ *srcPtr = single;
+ *targPtr = suffNull;
+ return(TRUE);
+ }
+ return (FALSE);
+ }
+ src = (Suff *)Lst_Datum(srcLn);
+ str2 = str + src->nameLen;
+ if (*str2 == '\0') {
+ single = src;
+ singleLn = srcLn;
+ } else {
+ targLn = Lst_Find(sufflist, str2, SuffSuffHasNameP);
+ if (targLn != NULL) {
+ *srcPtr = src;
+ *targPtr = (Suff *)Lst_Datum(targLn);
+ return (TRUE);
+ }
+ }
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_IsTransform --
+ * Return TRUE if the given string is a transformation rule
+ *
+ *
+ * Input:
+ * str string to check
+ *
+ * Results:
+ * TRUE if the string is a concatenation of two known suffixes.
+ * FALSE otherwise
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Suff_IsTransform(char *str)
+{
+ Suff *src, *targ;
+
+ return (SuffParseTransform(str, &src, &targ));
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_AddTransform --
+ * Add the transformation rule described by the line to the
+ * list of rules and place the transformation itself in the graph
+ *
+ * Input:
+ * line name of transformation to add
+ *
+ * Results:
+ * The node created for the transformation in the transforms list
+ *
+ * Side Effects:
+ * The node is placed on the end of the transforms Lst and links are
+ * made between the two suffixes mentioned in the target name
+ *-----------------------------------------------------------------------
+ */
+GNode *
+Suff_AddTransform(char *line)
+{
+ GNode *gn; /* GNode of transformation rule */
+ Suff *s, /* source suffix */
+ *t; /* target suffix */
+ LstNode ln; /* Node for existing transformation */
+
+ ln = Lst_Find(transforms, line, SuffGNHasNameP);
+ if (ln == NULL) {
+ /*
+ * Make a new graph node for the transformation. It will be filled in
+ * by the Parse module.
+ */
+ gn = Targ_NewGN(line);
+ (void)Lst_AtEnd(transforms, gn);
+ } else {
+ /*
+ * New specification for transformation rule. Just nuke the old list
+ * of commands so they can be filled in again... We don't actually
+ * free the commands themselves, because a given command can be
+ * attached to several different transformations.
+ */
+ gn = (GNode *)Lst_Datum(ln);
+ Lst_Destroy(gn->commands, NULL);
+ Lst_Destroy(gn->children, NULL);
+ gn->commands = Lst_Init(FALSE);
+ gn->children = Lst_Init(FALSE);
+ }
+
+ gn->type = OP_TRANSFORM;
+
+ (void)SuffParseTransform(line, &s, &t);
+
+ /*
+ * link the two together in the proper relationship and order
+ */
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "defining transformation from `%s' to `%s'\n",
+ s->name, t->name);
+ }
+ SuffInsert(t->children, s);
+ SuffInsert(s->parents, t);
+
+ return (gn);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_EndTransform --
+ * Handle the finish of a transformation definition, removing the
+ * transformation from the graph if it has neither commands nor
+ * sources. This is a callback procedure for the Parse module via
+ * Lst_ForEach
+ *
+ * Input:
+ * gnp Node for transformation
+ * dummy Node for transformation
+ *
+ * Results:
+ * === 0
+ *
+ * Side Effects:
+ * If the node has no commands or children, the children and parents
+ * lists of the affected suffixes are altered.
+ *
+ *-----------------------------------------------------------------------
+ */
+int
+Suff_EndTransform(void *gnp, void *dummy)
+{
+ GNode *gn = (GNode *)gnp;
+
+ if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts))
+ gn = (GNode *)Lst_Datum(Lst_Last(gn->cohorts));
+ if ((gn->type & OP_TRANSFORM) && Lst_IsEmpty(gn->commands) &&
+ Lst_IsEmpty(gn->children))
+ {
+ Suff *s, *t;
+
+ /*
+ * SuffParseTransform() may fail for special rules which are not
+ * actual transformation rules. (e.g. .DEFAULT)
+ */
+ if (SuffParseTransform(gn->name, &s, &t)) {
+ Lst p;
+
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "deleting transformation from `%s' to `%s'\n",
+ s->name, t->name);
+ }
+
+ /*
+ * Store s->parents because s could be deleted in SuffRemove
+ */
+ p = s->parents;
+
+ /*
+ * Remove the source from the target's children list. We check for a
+ * nil return to handle a beanhead saying something like
+ * .c.o .c.o:
+ *
+ * We'll be called twice when the next target is seen, but .c and .o
+ * are only linked once...
+ */
+ SuffRemove(t->children, s);
+
+ /*
+ * Remove the target from the source's parents list
+ */
+ SuffRemove(p, t);
+ }
+ } else if ((gn->type & OP_TRANSFORM) && DEBUG(SUFF)) {
+ fprintf(debug_file, "transformation %s complete\n", gn->name);
+ }
+
+ return(dummy ? 0 : 0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffRebuildGraph --
+ * Called from Suff_AddSuffix via Lst_ForEach to search through the
+ * list of existing transformation rules and rebuild the transformation
+ * graph when it has been destroyed by Suff_ClearSuffixes. If the
+ * given rule is a transformation involving this suffix and another,
+ * existing suffix, the proper relationship is established between
+ * the two.
+ *
+ * Input:
+ * transformp Transformation to test
+ * sp Suffix to rebuild
+ *
+ * Results:
+ * Always 0.
+ *
+ * Side Effects:
+ * The appropriate links will be made between this suffix and
+ * others if transformation rules exist for it.
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+SuffRebuildGraph(void *transformp, void *sp)
+{
+ GNode *transform = (GNode *)transformp;
+ Suff *s = (Suff *)sp;
+ char *cp;
+ LstNode ln;
+ Suff *s2;
+ SuffixCmpData sd;
+
+ /*
+ * First see if it is a transformation from this suffix.
+ */
+ cp = UNCONST(SuffStrIsPrefix(s->name, transform->name));
+ if (cp != NULL) {
+ ln = Lst_Find(sufflist, cp, SuffSuffHasNameP);
+ if (ln != NULL) {
+ /*
+ * Found target. Link in and return, since it can't be anything
+ * else.
+ */
+ s2 = (Suff *)Lst_Datum(ln);
+ SuffInsert(s2->children, s);
+ SuffInsert(s->parents, s2);
+ return(0);
+ }
+ }
+
+ /*
+ * Not from, maybe to?
+ */
+ sd.len = strlen(transform->name);
+ sd.ename = transform->name + sd.len;
+ cp = SuffSuffIsSuffix(s, &sd);
+ if (cp != NULL) {
+ /*
+ * Null-terminate the source suffix in order to find it.
+ */
+ cp[1] = '\0';
+ ln = Lst_Find(sufflist, transform->name, SuffSuffHasNameP);
+ /*
+ * Replace the start of the target suffix
+ */
+ cp[1] = s->name[0];
+ if (ln != NULL) {
+ /*
+ * Found it -- establish the proper relationship
+ */
+ s2 = (Suff *)Lst_Datum(ln);
+ SuffInsert(s->children, s2);
+ SuffInsert(s2->parents, s);
+ }
+ }
+ return(0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffScanTargets --
+ * Called from Suff_AddSuffix via Lst_ForEach to search through the
+ * list of existing targets and find if any of the existing targets
+ * can be turned into a transformation rule.
+ *
+ * Results:
+ * 1 if a new main target has been selected, 0 otherwise.
+ *
+ * Side Effects:
+ * If such a target is found and the target is the current main
+ * target, the main target is set to NULL and the next target
+ * examined (if that exists) becomes the main target.
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+SuffScanTargets(void *targetp, void *gsp)
+{
+ GNode *target = (GNode *)targetp;
+ GNodeSuff *gs = (GNodeSuff *)gsp;
+ Suff *s, *t;
+ char *ptr;
+
+ if (*gs->gn == NULL && gs->r && (target->type & OP_NOTARGET) == 0) {
+ *gs->gn = target;
+ Targ_SetMain(target);
+ return 1;
+ }
+
+ if ((unsigned int)target->type == OP_TRANSFORM)
+ return 0;
+
+ if ((ptr = strstr(target->name, gs->s->name)) == NULL ||
+ ptr == target->name)
+ return 0;
+
+ if (SuffParseTransform(target->name, &s, &t)) {
+ if (*gs->gn == target) {
+ gs->r = TRUE;
+ *gs->gn = NULL;
+ Targ_SetMain(NULL);
+ }
+ Lst_Destroy(target->children, NULL);
+ target->children = Lst_Init(FALSE);
+ target->type = OP_TRANSFORM;
+ /*
+ * link the two together in the proper relationship and order
+ */
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "defining transformation from `%s' to `%s'\n",
+ s->name, t->name);
+ }
+ SuffInsert(t->children, s);
+ SuffInsert(s->parents, t);
+ }
+ return 0;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_AddSuffix --
+ * Add the suffix in string to the end of the list of known suffixes.
+ * Should we restructure the suffix graph? Make doesn't...
+ *
+ * Input:
+ * str the name of the suffix to add
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * A GNode is created for the suffix and a Suff structure is created and
+ * added to the suffixes list unless the suffix was already known.
+ * The mainNode passed can be modified if a target mutated into a
+ * transform and that target happened to be the main target.
+ *-----------------------------------------------------------------------
+ */
+void
+Suff_AddSuffix(char *str, GNode **gn)
+{
+ Suff *s; /* new suffix descriptor */
+ LstNode ln;
+ GNodeSuff gs;
+
+ ln = Lst_Find(sufflist, str, SuffSuffHasNameP);
+ if (ln == NULL) {
+ s = bmake_malloc(sizeof(Suff));
+
+ s->name = bmake_strdup(str);
+ s->nameLen = strlen(s->name);
+ s->searchPath = Lst_Init(FALSE);
+ s->children = Lst_Init(FALSE);
+ s->parents = Lst_Init(FALSE);
+ s->ref = Lst_Init(FALSE);
+ s->sNum = sNum++;
+ s->flags = 0;
+ s->refCount = 1;
+
+ (void)Lst_AtEnd(sufflist, s);
+ /*
+ * We also look at our existing targets list to see if adding
+ * this suffix will make one of our current targets mutate into
+ * a suffix rule. This is ugly, but other makes treat all targets
+ * that start with a . as suffix rules.
+ */
+ gs.gn = gn;
+ gs.s = s;
+ gs.r = FALSE;
+ Lst_ForEach(Targ_List(), SuffScanTargets, &gs);
+ /*
+ * Look for any existing transformations from or to this suffix.
+ * XXX: Only do this after a Suff_ClearSuffixes?
+ */
+ Lst_ForEach(transforms, SuffRebuildGraph, s);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_GetPath --
+ * Return the search path for the given suffix, if it's defined.
+ *
+ * Results:
+ * The searchPath for the desired suffix or NULL if the suffix isn't
+ * defined.
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+Lst
+Suff_GetPath(char *sname)
+{
+ LstNode ln;
+ Suff *s;
+
+ ln = Lst_Find(sufflist, sname, SuffSuffHasNameP);
+ if (ln == NULL) {
+ return NULL;
+ } else {
+ s = (Suff *)Lst_Datum(ln);
+ return (s->searchPath);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_DoPaths --
+ * Extend the search paths for all suffixes to include the default
+ * search path.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The searchPath field of all the suffixes is extended by the
+ * directories in dirSearchPath. If paths were specified for the
+ * ".h" suffix, the directories are stuffed into a global variable
+ * called ".INCLUDES" with each directory preceded by a -I. The same
+ * is done for the ".a" suffix, except the variable is called
+ * ".LIBS" and the flag is -L.
+ *-----------------------------------------------------------------------
+ */
+void
+Suff_DoPaths(void)
+{
+ Suff *s;
+ LstNode ln;
+ char *ptr;
+ Lst inIncludes; /* Cumulative .INCLUDES path */
+ Lst inLibs; /* Cumulative .LIBS path */
+
+ if (Lst_Open(sufflist) == FAILURE) {
+ return;
+ }
+
+ inIncludes = Lst_Init(FALSE);
+ inLibs = Lst_Init(FALSE);
+
+ while ((ln = Lst_Next(sufflist)) != NULL) {
+ s = (Suff *)Lst_Datum(ln);
+ if (!Lst_IsEmpty (s->searchPath)) {
+#ifdef INCLUDES
+ if (s->flags & SUFF_INCLUDE) {
+ Dir_Concat(inIncludes, s->searchPath);
+ }
+#endif /* INCLUDES */
+#ifdef LIBRARIES
+ if (s->flags & SUFF_LIBRARY) {
+ Dir_Concat(inLibs, s->searchPath);
+ }
+#endif /* LIBRARIES */
+ Dir_Concat(s->searchPath, dirSearchPath);
+ } else {
+ Lst_Destroy(s->searchPath, Dir_Destroy);
+ s->searchPath = Lst_Duplicate(dirSearchPath, Dir_CopyDir);
+ }
+ }
+
+ Var_Set(".INCLUDES", ptr = Dir_MakeFlags("-I", inIncludes), VAR_GLOBAL, 0);
+ free(ptr);
+ Var_Set(".LIBS", ptr = Dir_MakeFlags("-L", inLibs), VAR_GLOBAL, 0);
+ free(ptr);
+
+ Lst_Destroy(inIncludes, Dir_Destroy);
+ Lst_Destroy(inLibs, Dir_Destroy);
+
+ Lst_Close(sufflist);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_AddInclude --
+ * Add the given suffix as a type of file which gets included.
+ * Called from the parse module when a .INCLUDES line is parsed.
+ * The suffix must have already been defined.
+ *
+ * Input:
+ * sname Name of the suffix to mark
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The SUFF_INCLUDE bit is set in the suffix's flags field
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Suff_AddInclude(char *sname)
+{
+ LstNode ln;
+ Suff *s;
+
+ ln = Lst_Find(sufflist, sname, SuffSuffHasNameP);
+ if (ln != NULL) {
+ s = (Suff *)Lst_Datum(ln);
+ s->flags |= SUFF_INCLUDE;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_AddLib --
+ * Add the given suffix as a type of file which is a library.
+ * Called from the parse module when parsing a .LIBS line. The
+ * suffix must have been defined via .SUFFIXES before this is
+ * called.
+ *
+ * Input:
+ * sname Name of the suffix to mark
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The SUFF_LIBRARY bit is set in the suffix's flags field
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Suff_AddLib(char *sname)
+{
+ LstNode ln;
+ Suff *s;
+
+ ln = Lst_Find(sufflist, sname, SuffSuffHasNameP);
+ if (ln != NULL) {
+ s = (Suff *)Lst_Datum(ln);
+ s->flags |= SUFF_LIBRARY;
+ }
+}
+
+ /********** Implicit Source Search Functions *********/
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffAddSrc --
+ * Add a suffix as a Src structure to the given list with its parent
+ * being the given Src structure. If the suffix is the null suffix,
+ * the prefix is used unaltered as the file name in the Src structure.
+ *
+ * Input:
+ * sp suffix for which to create a Src structure
+ * lsp list and parent for the new Src
+ *
+ * Results:
+ * always returns 0
+ *
+ * Side Effects:
+ * A Src structure is created and tacked onto the end of the list
+ *-----------------------------------------------------------------------
+ */
+static int
+SuffAddSrc(void *sp, void *lsp)
+{
+ Suff *s = (Suff *)sp;
+ LstSrc *ls = (LstSrc *)lsp;
+ Src *s2; /* new Src structure */
+ Src *targ; /* Target structure */
+
+ targ = ls->s;
+
+ if ((s->flags & SUFF_NULL) && (*s->name != '\0')) {
+ /*
+ * If the suffix has been marked as the NULL suffix, also create a Src
+ * structure for a file with no suffix attached. Two birds, and all
+ * that...
+ */
+ s2 = bmake_malloc(sizeof(Src));
+ s2->file = bmake_strdup(targ->pref);
+ s2->pref = targ->pref;
+ s2->parent = targ;
+ s2->node = NULL;
+ s2->suff = s;
+ s->refCount++;
+ s2->children = 0;
+ targ->children += 1;
+ (void)Lst_AtEnd(ls->l, s2);
+#ifdef DEBUG_SRC
+ s2->cp = Lst_Init(FALSE);
+ Lst_AtEnd(targ->cp, s2);
+ fprintf(debug_file, "1 add %x %x to %x:", targ, s2, ls->l);
+ Lst_ForEach(ls->l, PrintAddr, NULL);
+ fprintf(debug_file, "\n");
+#endif
+ }
+ s2 = bmake_malloc(sizeof(Src));
+ s2->file = str_concat(targ->pref, s->name, 0);
+ s2->pref = targ->pref;
+ s2->parent = targ;
+ s2->node = NULL;
+ s2->suff = s;
+ s->refCount++;
+ s2->children = 0;
+ targ->children += 1;
+ (void)Lst_AtEnd(ls->l, s2);
+#ifdef DEBUG_SRC
+ s2->cp = Lst_Init(FALSE);
+ Lst_AtEnd(targ->cp, s2);
+ fprintf(debug_file, "2 add %x %x to %x:", targ, s2, ls->l);
+ Lst_ForEach(ls->l, PrintAddr, NULL);
+ fprintf(debug_file, "\n");
+#endif
+
+ return(0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffAddLevel --
+ * Add all the children of targ as Src structures to the given list
+ *
+ * Input:
+ * l list to which to add the new level
+ * targ Src structure to use as the parent
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * Lots of structures are created and added to the list
+ *-----------------------------------------------------------------------
+ */
+static void
+SuffAddLevel(Lst l, Src *targ)
+{
+ LstSrc ls;
+
+ ls.s = targ;
+ ls.l = l;
+
+ Lst_ForEach(targ->suff->children, SuffAddSrc, &ls);
+}
+
+/*-
+ *----------------------------------------------------------------------
+ * SuffRemoveSrc --
+ * Free all src structures in list that don't have a reference count
+ *
+ * Results:
+ * Ture if an src was removed
+ *
+ * Side Effects:
+ * The memory is free'd.
+ *----------------------------------------------------------------------
+ */
+static int
+SuffRemoveSrc(Lst l)
+{
+ LstNode ln;
+ Src *s;
+ int t = 0;
+
+ if (Lst_Open(l) == FAILURE) {
+ return 0;
+ }
+#ifdef DEBUG_SRC
+ fprintf(debug_file, "cleaning %lx: ", (unsigned long) l);
+ Lst_ForEach(l, PrintAddr, NULL);
+ fprintf(debug_file, "\n");
+#endif
+
+
+ while ((ln = Lst_Next(l)) != NULL) {
+ s = (Src *)Lst_Datum(ln);
+ if (s->children == 0) {
+ free(s->file);
+ if (!s->parent)
+ free(s->pref);
+ else {
+#ifdef DEBUG_SRC
+ LstNode ln = Lst_Member(s->parent->cp, s);
+ if (ln != NULL)
+ Lst_Remove(s->parent->cp, ln);
+#endif
+ --s->parent->children;
+ }
+#ifdef DEBUG_SRC
+ fprintf(debug_file, "free: [l=%x] p=%x %d\n", l, s, s->children);
+ Lst_Destroy(s->cp, NULL);
+#endif
+ Lst_Remove(l, ln);
+ free(s);
+ t |= 1;
+ Lst_Close(l);
+ return TRUE;
+ }
+#ifdef DEBUG_SRC
+ else {
+ fprintf(debug_file, "keep: [l=%x] p=%x %d: ", l, s, s->children);
+ Lst_ForEach(s->cp, PrintAddr, NULL);
+ fprintf(debug_file, "\n");
+ }
+#endif
+ }
+
+ Lst_Close(l);
+
+ return t;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffFindThem --
+ * Find the first existing file/target in the list srcs
+ *
+ * Input:
+ * srcs list of Src structures to search through
+ *
+ * Results:
+ * The lowest structure in the chain of transformations
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+static Src *
+SuffFindThem(Lst srcs, Lst slst)
+{
+ Src *s; /* current Src */
+ Src *rs; /* returned Src */
+ char *ptr;
+
+ rs = NULL;
+
+ while (!Lst_IsEmpty (srcs)) {
+ s = (Src *)Lst_DeQueue(srcs);
+
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "\ttrying %s...", s->file);
+ }
+
+ /*
+ * A file is considered to exist if either a node exists in the
+ * graph for it or the file actually exists.
+ */
+ if (Targ_FindNode(s->file, TARG_NOCREATE) != NULL) {
+#ifdef DEBUG_SRC
+ fprintf(debug_file, "remove %x from %x\n", s, srcs);
+#endif
+ rs = s;
+ break;
+ }
+
+ if ((ptr = Dir_FindFile(s->file, s->suff->searchPath)) != NULL) {
+ rs = s;
+#ifdef DEBUG_SRC
+ fprintf(debug_file, "remove %x from %x\n", s, srcs);
+#endif
+ free(ptr);
+ break;
+ }
+
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "not there\n");
+ }
+
+ SuffAddLevel(srcs, s);
+ Lst_AtEnd(slst, s);
+ }
+
+ if (DEBUG(SUFF) && rs) {
+ fprintf(debug_file, "got it\n");
+ }
+ return (rs);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffFindCmds --
+ * See if any of the children of the target in the Src structure is
+ * one from which the target can be transformed. If there is one,
+ * a Src structure is put together for it and returned.
+ *
+ * Input:
+ * targ Src structure to play with
+ *
+ * Results:
+ * The Src structure of the "winning" child, or NULL if no such beast.
+ *
+ * Side Effects:
+ * A Src structure may be allocated.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Src *
+SuffFindCmds(Src *targ, Lst slst)
+{
+ LstNode ln; /* General-purpose list node */
+ GNode *t, /* Target GNode */
+ *s; /* Source GNode */
+ int prefLen;/* The length of the defined prefix */
+ Suff *suff; /* Suffix on matching beastie */
+ Src *ret; /* Return value */
+ char *cp;
+
+ t = targ->node;
+ (void)Lst_Open(t->children);
+ prefLen = strlen(targ->pref);
+
+ for (;;) {
+ ln = Lst_Next(t->children);
+ if (ln == NULL) {
+ Lst_Close(t->children);
+ return NULL;
+ }
+ s = (GNode *)Lst_Datum(ln);
+
+ if (s->type & OP_OPTIONAL && Lst_IsEmpty(t->commands)) {
+ /*
+ * We haven't looked to see if .OPTIONAL files exist yet, so
+ * don't use one as the implicit source.
+ * This allows us to use .OPTIONAL in .depend files so make won't
+ * complain "don't know how to make xxx.h' when a dependent file
+ * has been moved/deleted.
+ */
+ continue;
+ }
+
+ cp = strrchr(s->name, '/');
+ if (cp == NULL) {
+ cp = s->name;
+ } else {
+ cp++;
+ }
+ if (strncmp(cp, targ->pref, prefLen) != 0)
+ continue;
+ /*
+ * The node matches the prefix ok, see if it has a known
+ * suffix.
+ */
+ ln = Lst_Find(sufflist, &cp[prefLen], SuffSuffHasNameP);
+ if (ln == NULL)
+ continue;
+ /*
+ * It even has a known suffix, see if there's a transformation
+ * defined between the node's suffix and the target's suffix.
+ *
+ * XXX: Handle multi-stage transformations here, too.
+ */
+ suff = (Suff *)Lst_Datum(ln);
+
+ if (Lst_Member(suff->parents, targ->suff) != NULL)
+ break;
+ }
+
+ /*
+ * Hot Damn! Create a new Src structure to describe
+ * this transformation (making sure to duplicate the
+ * source node's name so Suff_FindDeps can free it
+ * again (ick)), and return the new structure.
+ */
+ ret = bmake_malloc(sizeof(Src));
+ ret->file = bmake_strdup(s->name);
+ ret->pref = targ->pref;
+ ret->suff = suff;
+ suff->refCount++;
+ ret->parent = targ;
+ ret->node = s;
+ ret->children = 0;
+ targ->children += 1;
+#ifdef DEBUG_SRC
+ ret->cp = Lst_Init(FALSE);
+ fprintf(debug_file, "3 add %x %x\n", targ, ret);
+ Lst_AtEnd(targ->cp, ret);
+#endif
+ Lst_AtEnd(slst, ret);
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "\tusing existing source %s\n", s->name);
+ }
+ return (ret);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffExpandChildren --
+ * Expand the names of any children of a given node that contain
+ * variable invocations or file wildcards into actual targets.
+ *
+ * Input:
+ * cln Child to examine
+ * pgn Parent node being processed
+ *
+ * Results:
+ * === 0 (continue)
+ *
+ * Side Effects:
+ * The expanded node is removed from the parent's list of children,
+ * and the parent's unmade counter is decremented, but other nodes
+ * may be added.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+SuffExpandChildren(LstNode cln, GNode *pgn)
+{
+ GNode *cgn = (GNode *)Lst_Datum(cln);
+ GNode *gn; /* New source 8) */
+ char *cp; /* Expanded value */
+
+ if (!Lst_IsEmpty(cgn->order_pred) || !Lst_IsEmpty(cgn->order_succ))
+ /* It is all too hard to process the result of .ORDER */
+ return;
+
+ if (cgn->type & OP_WAIT)
+ /* Ignore these (& OP_PHONY ?) */
+ return;
+
+ /*
+ * First do variable expansion -- this takes precedence over
+ * wildcard expansion. If the result contains wildcards, they'll be gotten
+ * to later since the resulting words are tacked on to the end of
+ * the children list.
+ */
+ if (strchr(cgn->name, '$') == NULL) {
+ SuffExpandWildcards(cln, pgn);
+ return;
+ }
+
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "Expanding \"%s\"...", cgn->name);
+ }
+ cp = Var_Subst(NULL, cgn->name, pgn, TRUE);
+
+ if (cp != NULL) {
+ Lst members = Lst_Init(FALSE);
+
+ if (cgn->type & OP_ARCHV) {
+ /*
+ * Node was an archive(member) target, so we want to call
+ * on the Arch module to find the nodes for us, expanding
+ * variables in the parent's context.
+ */
+ char *sacrifice = cp;
+
+ (void)Arch_ParseArchive(&sacrifice, members, pgn);
+ } else {
+ /*
+ * Break the result into a vector of strings whose nodes
+ * we can find, then add those nodes to the members list.
+ * Unfortunately, we can't use brk_string b/c it
+ * doesn't understand about variable specifications with
+ * spaces in them...
+ */
+ char *start;
+ char *initcp = cp; /* For freeing... */
+
+ for (start = cp; *start == ' ' || *start == '\t'; start++)
+ continue;
+ for (cp = start; *cp != '\0'; cp++) {
+ if (*cp == ' ' || *cp == '\t') {
+ /*
+ * White-space -- terminate element, find the node,
+ * add it, skip any further spaces.
+ */
+ *cp++ = '\0';
+ gn = Targ_FindNode(start, TARG_CREATE);
+ (void)Lst_AtEnd(members, gn);
+ while (*cp == ' ' || *cp == '\t') {
+ cp++;
+ }
+ /*
+ * Adjust cp for increment at start of loop, but
+ * set start to first non-space.
+ */
+ start = cp--;
+ } else if (*cp == '$') {
+ /*
+ * Start of a variable spec -- contact variable module
+ * to find the end so we can skip over it.
+ */
+ char *junk;
+ int len;
+ void *freeIt;
+
+ junk = Var_Parse(cp, pgn, TRUE, &len, &freeIt);
+ if (junk != var_Error) {
+ cp += len - 1;
+ }
+
+ if (freeIt)
+ free(freeIt);
+ } else if (*cp == '\\' && *cp != '\0') {
+ /*
+ * Escaped something -- skip over it
+ */
+ cp++;
+ }
+ }
+
+ if (cp != start) {
+ /*
+ * Stuff left over -- add it to the list too
+ */
+ gn = Targ_FindNode(start, TARG_CREATE);
+ (void)Lst_AtEnd(members, gn);
+ }
+ /*
+ * Point cp back at the beginning again so the variable value
+ * can be freed.
+ */
+ cp = initcp;
+ }
+
+ /*
+ * Add all elements of the members list to the parent node.
+ */
+ while(!Lst_IsEmpty(members)) {
+ gn = (GNode *)Lst_DeQueue(members);
+
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "%s...", gn->name);
+ }
+ /* Add gn to the parents child list before the original child */
+ (void)Lst_InsertBefore(pgn->children, cln, gn);
+ (void)Lst_AtEnd(gn->parents, pgn);
+ pgn->unmade++;
+ /* Expand wildcards on new node */
+ SuffExpandWildcards(Lst_Prev(cln), pgn);
+ }
+ Lst_Destroy(members, NULL);
+
+ /*
+ * Free the result
+ */
+ free(cp);
+ }
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "\n");
+ }
+
+ /*
+ * Now the source is expanded, remove it from the list of children to
+ * keep it from being processed.
+ */
+ pgn->unmade--;
+ Lst_Remove(pgn->children, cln);
+ Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn));
+}
+
+static void
+SuffExpandWildcards(LstNode cln, GNode *pgn)
+{
+ GNode *cgn = (GNode *)Lst_Datum(cln);
+ GNode *gn; /* New source 8) */
+ char *cp; /* Expanded value */
+ Lst explist; /* List of expansions */
+
+ if (!Dir_HasWildcards(cgn->name))
+ return;
+
+ /*
+ * Expand the word along the chosen path
+ */
+ explist = Lst_Init(FALSE);
+ Dir_Expand(cgn->name, Suff_FindPath(cgn), explist);
+
+ while (!Lst_IsEmpty(explist)) {
+ /*
+ * Fetch next expansion off the list and find its GNode
+ */
+ cp = (char *)Lst_DeQueue(explist);
+
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "%s...", cp);
+ }
+ gn = Targ_FindNode(cp, TARG_CREATE);
+
+ /* Add gn to the parents child list before the original child */
+ (void)Lst_InsertBefore(pgn->children, cln, gn);
+ (void)Lst_AtEnd(gn->parents, pgn);
+ pgn->unmade++;
+ }
+
+ /*
+ * Nuke what's left of the list
+ */
+ Lst_Destroy(explist, NULL);
+
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "\n");
+ }
+
+ /*
+ * Now the source is expanded, remove it from the list of children to
+ * keep it from being processed.
+ */
+ pgn->unmade--;
+ Lst_Remove(pgn->children, cln);
+ Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn));
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_FindPath --
+ * Find a path along which to expand the node.
+ *
+ * If the word has a known suffix, use that path.
+ * If it has no known suffix, use the default system search path.
+ *
+ * Input:
+ * gn Node being examined
+ *
+ * Results:
+ * The appropriate path to search for the GNode.
+ *
+ * Side Effects:
+ * XXX: We could set the suffix here so that we don't have to scan
+ * again.
+ *
+ *-----------------------------------------------------------------------
+ */
+Lst
+Suff_FindPath(GNode* gn)
+{
+ Suff *suff = gn->suffix;
+
+ if (suff == NULL) {
+ SuffixCmpData sd; /* Search string data */
+ LstNode ln;
+ sd.len = strlen(gn->name);
+ sd.ename = gn->name + sd.len;
+ ln = Lst_Find(sufflist, &sd, SuffSuffIsSuffixP);
+
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "Wildcard expanding \"%s\"...", gn->name);
+ }
+ if (ln != NULL)
+ suff = (Suff *)Lst_Datum(ln);
+ /* XXX: Here we can save the suffix so we don't have to do this again */
+ }
+
+ if (suff != NULL) {
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "suffix is \"%s\"...", suff->name);
+ }
+ return suff->searchPath;
+ } else {
+ /*
+ * Use default search path
+ */
+ return dirSearchPath;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffApplyTransform --
+ * Apply a transformation rule, given the source and target nodes
+ * and suffixes.
+ *
+ * Input:
+ * tGn Target node
+ * sGn Source node
+ * t Target suffix
+ * s Source suffix
+ *
+ * Results:
+ * TRUE if successful, FALSE if not.
+ *
+ * Side Effects:
+ * The source and target are linked and the commands from the
+ * transformation are added to the target node's commands list.
+ * All attributes but OP_DEPMASK and OP_TRANSFORM are applied
+ * to the target. The target also inherits all the sources for
+ * the transformation rule.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+SuffApplyTransform(GNode *tGn, GNode *sGn, Suff *t, Suff *s)
+{
+ LstNode ln, nln; /* General node */
+ char *tname; /* Name of transformation rule */
+ GNode *gn; /* Node for same */
+
+ /*
+ * Form the proper links between the target and source.
+ */
+ (void)Lst_AtEnd(tGn->children, sGn);
+ (void)Lst_AtEnd(sGn->parents, tGn);
+ tGn->unmade += 1;
+
+ /*
+ * Locate the transformation rule itself
+ */
+ tname = str_concat(s->name, t->name, 0);
+ ln = Lst_Find(transforms, tname, SuffGNHasNameP);
+ free(tname);
+
+ if (ln == NULL) {
+ /*
+ * Not really such a transformation rule (can happen when we're
+ * called to link an OP_MEMBER and OP_ARCHV node), so return
+ * FALSE.
+ */
+ return(FALSE);
+ }
+
+ gn = (GNode *)Lst_Datum(ln);
+
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name);
+ }
+
+ /*
+ * Record last child for expansion purposes
+ */
+ ln = Lst_Last(tGn->children);
+
+ /*
+ * Pass the buck to Make_HandleUse to apply the rule
+ */
+ (void)Make_HandleUse(gn, tGn);
+
+ /*
+ * Deal with wildcards and variables in any acquired sources
+ */
+ for (ln = Lst_Succ(ln); ln != NULL; ln = nln) {
+ nln = Lst_Succ(ln);
+ SuffExpandChildren(ln, tGn);
+ }
+
+ /*
+ * Keep track of another parent to which this beast is transformed so
+ * the .IMPSRC variable can be set correctly for the parent.
+ */
+ (void)Lst_AtEnd(sGn->iParents, tGn);
+
+ return(TRUE);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffFindArchiveDeps --
+ * Locate dependencies for an OP_ARCHV node.
+ *
+ * Input:
+ * gn Node for which to locate dependencies
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * Same as Suff_FindDeps
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+SuffFindArchiveDeps(GNode *gn, Lst slst)
+{
+ char *eoarch; /* End of archive portion */
+ char *eoname; /* End of member portion */
+ GNode *mem; /* Node for member */
+ static const char *copy[] = {
+ /* Variables to be copied from the member node */
+ TARGET, /* Must be first */
+ PREFIX, /* Must be second */
+ };
+ int i; /* Index into copy and vals */
+ Suff *ms; /* Suffix descriptor for member */
+ char *name; /* Start of member's name */
+
+ /*
+ * The node is an archive(member) pair. so we must find a
+ * suffix for both of them.
+ */
+ eoarch = strchr(gn->name, '(');
+ eoname = strchr(eoarch, ')');
+
+ *eoname = '\0'; /* Nuke parentheses during suffix search */
+ *eoarch = '\0'; /* So a suffix can be found */
+
+ name = eoarch + 1;
+
+ /*
+ * To simplify things, call Suff_FindDeps recursively on the member now,
+ * so we can simply compare the member's .PREFIX and .TARGET variables
+ * to locate its suffix. This allows us to figure out the suffix to
+ * use for the archive without having to do a quadratic search over the
+ * suffix list, backtracking for each one...
+ */
+ mem = Targ_FindNode(name, TARG_CREATE);
+ SuffFindDeps(mem, slst);
+
+ /*
+ * Create the link between the two nodes right off
+ */
+ (void)Lst_AtEnd(gn->children, mem);
+ (void)Lst_AtEnd(mem->parents, gn);
+ gn->unmade += 1;
+
+ /*
+ * Copy in the variables from the member node to this one.
+ */
+ for (i = (sizeof(copy)/sizeof(copy[0]))-1; i >= 0; i--) {
+ char *p1;
+ Var_Set(copy[i], Var_Value(copy[i], mem, &p1), gn, 0);
+ if (p1)
+ free(p1);
+
+ }
+
+ ms = mem->suffix;
+ if (ms == NULL) {
+ /*
+ * Didn't know what it was -- use .NULL suffix if not in make mode
+ */
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "using null suffix\n");
+ }
+ ms = suffNull;
+ }
+
+
+ /*
+ * Set the other two local variables required for this target.
+ */
+ Var_Set(MEMBER, name, gn, 0);
+ Var_Set(ARCHIVE, gn->name, gn, 0);
+
+ if (ms != NULL) {
+ /*
+ * Member has a known suffix, so look for a transformation rule from
+ * it to a possible suffix of the archive. Rather than searching
+ * through the entire list, we just look at suffixes to which the
+ * member's suffix may be transformed...
+ */
+ LstNode ln;
+ SuffixCmpData sd; /* Search string data */
+
+ /*
+ * Use first matching suffix...
+ */
+ sd.len = eoarch - gn->name;
+ sd.ename = eoarch;
+ ln = Lst_Find(ms->parents, &sd, SuffSuffIsSuffixP);
+
+ if (ln != NULL) {
+ /*
+ * Got one -- apply it
+ */
+ if (!SuffApplyTransform(gn, mem, (Suff *)Lst_Datum(ln), ms) &&
+ DEBUG(SUFF))
+ {
+ fprintf(debug_file, "\tNo transformation from %s -> %s\n",
+ ms->name, ((Suff *)Lst_Datum(ln))->name);
+ }
+ }
+ }
+
+ /*
+ * Replace the opening and closing parens now we've no need of the separate
+ * pieces.
+ */
+ *eoarch = '('; *eoname = ')';
+
+ /*
+ * Pretend gn appeared to the left of a dependency operator so
+ * the user needn't provide a transformation from the member to the
+ * archive.
+ */
+ if (OP_NOP(gn->type)) {
+ gn->type |= OP_DEPENDS;
+ }
+
+ /*
+ * Flag the member as such so we remember to look in the archive for
+ * its modification time.
+ */
+ mem->type |= OP_MEMBER;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffFindNormalDeps --
+ * Locate implicit dependencies for regular targets.
+ *
+ * Input:
+ * gn Node for which to find sources
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Same as Suff_FindDeps...
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+SuffFindNormalDeps(GNode *gn, Lst slst)
+{
+ char *eoname; /* End of name */
+ char *sopref; /* Start of prefix */
+ LstNode ln, nln; /* Next suffix node to check */
+ Lst srcs; /* List of sources at which to look */
+ Lst targs; /* List of targets to which things can be
+ * transformed. They all have the same file,
+ * but different suff and pref fields */
+ Src *bottom; /* Start of found transformation path */
+ Src *src; /* General Src pointer */
+ char *pref; /* Prefix to use */
+ Src *targ; /* General Src target pointer */
+ SuffixCmpData sd; /* Search string data */
+
+
+ sd.len = strlen(gn->name);
+ sd.ename = eoname = gn->name + sd.len;
+
+ sopref = gn->name;
+
+ /*
+ * Begin at the beginning...
+ */
+ ln = Lst_First(sufflist);
+ srcs = Lst_Init(FALSE);
+ targs = Lst_Init(FALSE);
+
+ /*
+ * We're caught in a catch-22 here. On the one hand, we want to use any
+ * transformation implied by the target's sources, but we can't examine
+ * the sources until we've expanded any variables/wildcards they may hold,
+ * and we can't do that until we've set up the target's local variables
+ * and we can't do that until we know what the proper suffix for the
+ * target is (in case there are two suffixes one of which is a suffix of
+ * the other) and we can't know that until we've found its implied
+ * source, which we may not want to use if there's an existing source
+ * that implies a different transformation.
+ *
+ * In an attempt to get around this, which may not work all the time,
+ * but should work most of the time, we look for implied sources first,
+ * checking transformations to all possible suffixes of the target,
+ * use what we find to set the target's local variables, expand the
+ * children, then look for any overriding transformations they imply.
+ * Should we find one, we discard the one we found before.
+ */
+
+ while (ln != NULL) {
+ /*
+ * Look for next possible suffix...
+ */
+ ln = Lst_FindFrom(sufflist, ln, &sd, SuffSuffIsSuffixP);
+
+ if (ln != NULL) {
+ int prefLen; /* Length of the prefix */
+
+ /*
+ * Allocate a Src structure to which things can be transformed
+ */
+ targ = bmake_malloc(sizeof(Src));
+ targ->file = bmake_strdup(gn->name);
+ targ->suff = (Suff *)Lst_Datum(ln);
+ targ->suff->refCount++;
+ targ->node = gn;
+ targ->parent = NULL;
+ targ->children = 0;
+#ifdef DEBUG_SRC
+ targ->cp = Lst_Init(FALSE);
+#endif
+
+ /*
+ * Allocate room for the prefix, whose end is found by subtracting
+ * the length of the suffix from the end of the name.
+ */
+ prefLen = (eoname - targ->suff->nameLen) - sopref;
+ targ->pref = bmake_malloc(prefLen + 1);
+ memcpy(targ->pref, sopref, prefLen);
+ targ->pref[prefLen] = '\0';
+
+ /*
+ * Add nodes from which the target can be made
+ */
+ SuffAddLevel(srcs, targ);
+
+ /*
+ * Record the target so we can nuke it
+ */
+ (void)Lst_AtEnd(targs, targ);
+
+ /*
+ * Search from this suffix's successor...
+ */
+ ln = Lst_Succ(ln);
+ }
+ }
+
+ /*
+ * Handle target of unknown suffix...
+ */
+ if (Lst_IsEmpty(targs) && suffNull != NULL) {
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name);
+ }
+
+ targ = bmake_malloc(sizeof(Src));
+ targ->file = bmake_strdup(gn->name);
+ targ->suff = suffNull;
+ targ->suff->refCount++;
+ targ->node = gn;
+ targ->parent = NULL;
+ targ->children = 0;
+ targ->pref = bmake_strdup(sopref);
+#ifdef DEBUG_SRC
+ targ->cp = Lst_Init(FALSE);
+#endif
+
+ /*
+ * Only use the default suffix rules if we don't have commands
+ * defined for this gnode; traditional make programs used to
+ * not define suffix rules if the gnode had children but we
+ * don't do this anymore.
+ */
+ if (Lst_IsEmpty(gn->commands))
+ SuffAddLevel(srcs, targ);
+ else {
+ if (DEBUG(SUFF))
+ fprintf(debug_file, "not ");
+ }
+
+ if (DEBUG(SUFF))
+ fprintf(debug_file, "adding suffix rules\n");
+
+ (void)Lst_AtEnd(targs, targ);
+ }
+
+ /*
+ * Using the list of possible sources built up from the target suffix(es),
+ * try and find an existing file/target that matches.
+ */
+ bottom = SuffFindThem(srcs, slst);
+
+ if (bottom == NULL) {
+ /*
+ * No known transformations -- use the first suffix found for setting
+ * the local variables.
+ */
+ if (!Lst_IsEmpty(targs)) {
+ targ = (Src *)Lst_Datum(Lst_First(targs));
+ } else {
+ targ = NULL;
+ }
+ } else {
+ /*
+ * Work up the transformation path to find the suffix of the
+ * target to which the transformation was made.
+ */
+ for (targ = bottom; targ->parent != NULL; targ = targ->parent)
+ continue;
+ }
+
+ Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0);
+
+ pref = (targ != NULL) ? targ->pref : gn->name;
+ Var_Set(PREFIX, pref, gn, 0);
+
+ /*
+ * Now we've got the important local variables set, expand any sources
+ * that still contain variables or wildcards in their names.
+ */
+ for (ln = Lst_First(gn->children); ln != NULL; ln = nln) {
+ nln = Lst_Succ(ln);
+ SuffExpandChildren(ln, gn);
+ }
+
+ if (targ == NULL) {
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "\tNo valid suffix on %s\n", gn->name);
+ }
+
+sfnd_abort:
+ /*
+ * Deal with finding the thing on the default search path. We
+ * always do that, not only if the node is only a source (not
+ * on the lhs of a dependency operator or [XXX] it has neither
+ * children or commands) as the old pmake did.
+ */
+ if ((gn->type & (OP_PHONY|OP_NOPATH)) == 0) {
+ free(gn->path);
+ gn->path = Dir_FindFile(gn->name,
+ (targ == NULL ? dirSearchPath :
+ targ->suff->searchPath));
+ if (gn->path != NULL) {
+ char *ptr;
+ Var_Set(TARGET, gn->path, gn, 0);
+
+ if (targ != NULL) {
+ /*
+ * Suffix known for the thing -- trim the suffix off
+ * the path to form the proper .PREFIX variable.
+ */
+ int savep = strlen(gn->path) - targ->suff->nameLen;
+ char savec;
+
+ if (gn->suffix)
+ gn->suffix->refCount--;
+ gn->suffix = targ->suff;
+ gn->suffix->refCount++;
+
+ savec = gn->path[savep];
+ gn->path[savep] = '\0';
+
+ if ((ptr = strrchr(gn->path, '/')) != NULL)
+ ptr++;
+ else
+ ptr = gn->path;
+
+ Var_Set(PREFIX, ptr, gn, 0);
+
+ gn->path[savep] = savec;
+ } else {
+ /*
+ * The .PREFIX gets the full path if the target has
+ * no known suffix.
+ */
+ if (gn->suffix)
+ gn->suffix->refCount--;
+ gn->suffix = NULL;
+
+ if ((ptr = strrchr(gn->path, '/')) != NULL)
+ ptr++;
+ else
+ ptr = gn->path;
+
+ Var_Set(PREFIX, ptr, gn, 0);
+ }
+ }
+ }
+
+ goto sfnd_return;
+ }
+
+ /*
+ * If the suffix indicates that the target is a library, mark that in
+ * the node's type field.
+ */
+ if (targ->suff->flags & SUFF_LIBRARY) {
+ gn->type |= OP_LIB;
+ }
+
+ /*
+ * Check for overriding transformation rule implied by sources
+ */
+ if (!Lst_IsEmpty(gn->children)) {
+ src = SuffFindCmds(targ, slst);
+
+ if (src != NULL) {
+ /*
+ * Free up all the Src structures in the transformation path
+ * up to, but not including, the parent node.
+ */
+ while (bottom && bottom->parent != NULL) {
+ if (Lst_Member(slst, bottom) == NULL) {
+ Lst_AtEnd(slst, bottom);
+ }
+ bottom = bottom->parent;
+ }
+ bottom = src;
+ }
+ }
+
+ if (bottom == NULL) {
+ /*
+ * No idea from where it can come -- return now.
+ */
+ goto sfnd_abort;
+ }
+
+ /*
+ * We now have a list of Src structures headed by 'bottom' and linked via
+ * their 'parent' pointers. What we do next is create links between
+ * source and target nodes (which may or may not have been created)
+ * and set the necessary local variables in each target. The
+ * commands for each target are set from the commands of the
+ * transformation rule used to get from the src suffix to the targ
+ * suffix. Note that this causes the commands list of the original
+ * node, gn, to be replaced by the commands of the final
+ * transformation rule. Also, the unmade field of gn is incremented.
+ * Etc.
+ */
+ if (bottom->node == NULL) {
+ bottom->node = Targ_FindNode(bottom->file, TARG_CREATE);
+ }
+
+ for (src = bottom; src->parent != NULL; src = src->parent) {
+ targ = src->parent;
+
+ if (src->node->suffix)
+ src->node->suffix->refCount--;
+ src->node->suffix = src->suff;
+ src->node->suffix->refCount++;
+
+ if (targ->node == NULL) {
+ targ->node = Targ_FindNode(targ->file, TARG_CREATE);
+ }
+
+ SuffApplyTransform(targ->node, src->node,
+ targ->suff, src->suff);
+
+ if (targ->node != gn) {
+ /*
+ * Finish off the dependency-search process for any nodes
+ * between bottom and gn (no point in questing around the
+ * filesystem for their implicit source when it's already
+ * known). Note that the node can't have any sources that
+ * need expanding, since SuffFindThem will stop on an existing
+ * node, so all we need to do is set the standard and System V
+ * variables.
+ */
+ targ->node->type |= OP_DEPS_FOUND;
+
+ Var_Set(PREFIX, targ->pref, targ->node, 0);
+
+ Var_Set(TARGET, targ->node->name, targ->node, 0);
+ }
+ }
+
+ if (gn->suffix)
+ gn->suffix->refCount--;
+ gn->suffix = src->suff;
+ gn->suffix->refCount++;
+
+ /*
+ * Nuke the transformation path and the Src structures left over in the
+ * two lists.
+ */
+sfnd_return:
+ if (bottom)
+ if (Lst_Member(slst, bottom) == NULL)
+ Lst_AtEnd(slst, bottom);
+
+ while (SuffRemoveSrc(srcs) || SuffRemoveSrc(targs))
+ continue;
+
+ Lst_Concat(slst, srcs, LST_CONCLINK);
+ Lst_Concat(slst, targs, LST_CONCLINK);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_FindDeps --
+ * Find implicit sources for the target described by the graph node
+ * gn
+ *
+ * Results:
+ * Nothing.
+ *
+ * Side Effects:
+ * Nodes are added to the graph below the passed-in node. The nodes
+ * are marked to have their IMPSRC variable filled in. The
+ * PREFIX variable is set for the given node and all its
+ * implied children.
+ *
+ * Notes:
+ * The path found by this target is the shortest path in the
+ * transformation graph, which may pass through non-existent targets,
+ * to an existing target. The search continues on all paths from the
+ * root suffix until a file is found. I.e. if there's a path
+ * .o -> .c -> .l -> .l,v from the root and the .l,v file exists but
+ * the .c and .l files don't, the search will branch out in
+ * all directions from .o and again from all the nodes on the
+ * next level until the .l,v node is encountered.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+void
+Suff_FindDeps(GNode *gn)
+{
+
+ SuffFindDeps(gn, srclist);
+ while (SuffRemoveSrc(srclist))
+ continue;
+}
+
+
+/*
+ * Input:
+ * gn node we're dealing with
+ *
+ */
+static void
+SuffFindDeps(GNode *gn, Lst slst)
+{
+ if (gn->type & OP_DEPS_FOUND) {
+ /*
+ * If dependencies already found, no need to do it again...
+ */
+ return;
+ } else {
+ gn->type |= OP_DEPS_FOUND;
+ }
+ /*
+ * Make sure we have these set, may get revised below.
+ */
+ Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0);
+ Var_Set(PREFIX, gn->name, gn, 0);
+ if (gn->type & OP_PHONY) {
+ /*
+ * If this is a .PHONY target, we do not apply suffix rules.
+ */
+ return;
+ }
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "SuffFindDeps (%s)\n", gn->name);
+ }
+
+ if (gn->type & OP_ARCHV) {
+ SuffFindArchiveDeps(gn, slst);
+ } else if (gn->type & OP_LIB) {
+ /*
+ * If the node is a library, it is the arch module's job to find it
+ * and set the TARGET variable accordingly. We merely provide the
+ * search path, assuming all libraries end in ".a" (if the suffix
+ * hasn't been defined, there's nothing we can do for it, so we just
+ * set the TARGET variable to the node's name in order to give it a
+ * value).
+ */
+ LstNode ln;
+ Suff *s;
+
+ ln = Lst_Find(sufflist, LIBSUFF, SuffSuffHasNameP);
+ if (gn->suffix)
+ gn->suffix->refCount--;
+ if (ln != NULL) {
+ gn->suffix = s = (Suff *)Lst_Datum(ln);
+ gn->suffix->refCount++;
+ Arch_FindLib(gn, s->searchPath);
+ } else {
+ gn->suffix = NULL;
+ Var_Set(TARGET, gn->name, gn, 0);
+ }
+ /*
+ * Because a library (-lfoo) target doesn't follow the standard
+ * filesystem conventions, we don't set the regular variables for
+ * the thing. .PREFIX is simply made empty...
+ */
+ Var_Set(PREFIX, "", gn, 0);
+ } else {
+ SuffFindNormalDeps(gn, slst);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_SetNull --
+ * Define which suffix is the null suffix.
+ *
+ * Input:
+ * name Name of null suffix
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * 'suffNull' is altered.
+ *
+ * Notes:
+ * Need to handle the changing of the null suffix gracefully so the
+ * old transformation rules don't just go away.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Suff_SetNull(char *name)
+{
+ Suff *s;
+ LstNode ln;
+
+ ln = Lst_Find(sufflist, name, SuffSuffHasNameP);
+ if (ln != NULL) {
+ s = (Suff *)Lst_Datum(ln);
+ if (suffNull != NULL) {
+ suffNull->flags &= ~SUFF_NULL;
+ }
+ s->flags |= SUFF_NULL;
+ /*
+ * XXX: Here's where the transformation mangling would take place
+ */
+ suffNull = s;
+ } else {
+ Parse_Error(PARSE_WARNING, "Desired null suffix %s not defined.",
+ name);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Suff_Init --
+ * Initialize suffixes module
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * Many
+ *-----------------------------------------------------------------------
+ */
+void
+Suff_Init(void)
+{
+ sufflist = Lst_Init(FALSE);
+#ifdef CLEANUP
+ suffClean = Lst_Init(FALSE);
+#endif
+ srclist = Lst_Init(FALSE);
+ transforms = Lst_Init(FALSE);
+
+ sNum = 0;
+ /*
+ * Create null suffix for single-suffix rules (POSIX). The thing doesn't
+ * actually go on the suffix list or everyone will think that's its
+ * suffix.
+ */
+ emptySuff = suffNull = bmake_malloc(sizeof(Suff));
+
+ suffNull->name = bmake_strdup("");
+ suffNull->nameLen = 0;
+ suffNull->searchPath = Lst_Init(FALSE);
+ Dir_Concat(suffNull->searchPath, dirSearchPath);
+ suffNull->children = Lst_Init(FALSE);
+ suffNull->parents = Lst_Init(FALSE);
+ suffNull->ref = Lst_Init(FALSE);
+ suffNull->sNum = sNum++;
+ suffNull->flags = SUFF_NULL;
+ suffNull->refCount = 1;
+
+}
+
+
+/*-
+ *----------------------------------------------------------------------
+ * Suff_End --
+ * Cleanup the this module
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The memory is free'd.
+ *----------------------------------------------------------------------
+ */
+
+void
+Suff_End(void)
+{
+#ifdef CLEANUP
+ Lst_Destroy(sufflist, SuffFree);
+ Lst_Destroy(suffClean, SuffFree);
+ if (suffNull)
+ SuffFree(suffNull);
+ Lst_Destroy(srclist, NULL);
+ Lst_Destroy(transforms, NULL);
+#endif
+}
+
+
+/********************* DEBUGGING FUNCTIONS **********************/
+
+static int SuffPrintName(void *s, void *dummy)
+{
+ fprintf(debug_file, "%s ", ((Suff *)s)->name);
+ return (dummy ? 0 : 0);
+}
+
+static int
+SuffPrintSuff(void *sp, void *dummy)
+{
+ Suff *s = (Suff *)sp;
+ int flags;
+ int flag;
+
+ fprintf(debug_file, "# `%s' [%d] ", s->name, s->refCount);
+
+ flags = s->flags;
+ if (flags) {
+ fputs(" (", debug_file);
+ while (flags) {
+ flag = 1 << (ffs(flags) - 1);
+ flags &= ~flag;
+ switch (flag) {
+ case SUFF_NULL:
+ fprintf(debug_file, "NULL");
+ break;
+ case SUFF_INCLUDE:
+ fprintf(debug_file, "INCLUDE");
+ break;
+ case SUFF_LIBRARY:
+ fprintf(debug_file, "LIBRARY");
+ break;
+ }
+ fputc(flags ? '|' : ')', debug_file);
+ }
+ }
+ fputc('\n', debug_file);
+ fprintf(debug_file, "#\tTo: ");
+ Lst_ForEach(s->parents, SuffPrintName, NULL);
+ fputc('\n', debug_file);
+ fprintf(debug_file, "#\tFrom: ");
+ Lst_ForEach(s->children, SuffPrintName, NULL);
+ fputc('\n', debug_file);
+ fprintf(debug_file, "#\tSearch Path: ");
+ Dir_PrintPath(s->searchPath);
+ fputc('\n', debug_file);
+ return (dummy ? 0 : 0);
+}
+
+static int
+SuffPrintTrans(void *tp, void *dummy)
+{
+ GNode *t = (GNode *)tp;
+
+ fprintf(debug_file, "%-16s: ", t->name);
+ Targ_PrintType(t->type);
+ fputc('\n', debug_file);
+ Lst_ForEach(t->commands, Targ_PrintCmd, NULL);
+ fputc('\n', debug_file);
+ return(dummy ? 0 : 0);
+}
+
+void
+Suff_PrintAll(void)
+{
+ fprintf(debug_file, "#*** Suffixes:\n");
+ Lst_ForEach(sufflist, SuffPrintSuff, NULL);
+
+ fprintf(debug_file, "#*** Transformations:\n");
+ Lst_ForEach(transforms, SuffPrintTrans, NULL);
+}
diff --git a/external/bsd/bmake/dist/targ.c b/external/bsd/bmake/dist/targ.c
new file mode 100644
index 0000000..d26b845
--- /dev/null
+++ b/external/bsd/bmake/dist/targ.c
@@ -0,0 +1,848 @@
+/* $NetBSD: targ.c,v 1.57 2012/06/12 19:21:51 joerg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: targ.c,v 1.57 2012/06/12 19:21:51 joerg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94";
+#else
+__RCSID("$NetBSD: targ.c,v 1.57 2012/06/12 19:21:51 joerg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * targ.c --
+ * Functions for maintaining the Lst allTargets. Target nodes are
+ * kept in two structures: a Lst, maintained by the list library, and a
+ * hash table, maintained by the hash library.
+ *
+ * Interface:
+ * Targ_Init Initialization procedure.
+ *
+ * Targ_End Cleanup the module
+ *
+ * Targ_List Return the list of all targets so far.
+ *
+ * Targ_NewGN Create a new GNode for the passed target
+ * (string). The node is *not* placed in the
+ * hash table, though all its fields are
+ * initialized.
+ *
+ * Targ_FindNode Find the node for a given target, creating
+ * and storing it if it doesn't exist and the
+ * flags are right (TARG_CREATE)
+ *
+ * Targ_FindList Given a list of names, find nodes for all
+ * of them. If a name doesn't exist and the
+ * TARG_NOCREATE flag was given, an error message
+ * is printed. Else, if a name doesn't exist,
+ * its node is created.
+ *
+ * Targ_Ignore Return TRUE if errors should be ignored when
+ * creating the given target.
+ *
+ * Targ_Silent Return TRUE if we should be silent when
+ * creating the given target.
+ *
+ * Targ_Precious Return TRUE if the target is precious and
+ * should not be removed if we are interrupted.
+ *
+ * Targ_Propagate Propagate information between related
+ * nodes. Should be called after the
+ * makefiles are parsed but before any
+ * action is taken.
+ *
+ * Debugging:
+ * Targ_PrintGraph Print out the entire graphm all variables
+ * and statistics for the directory cache. Should
+ * print something for suffixes, too, but...
+ */
+
+#include <stdio.h>
+#include <time.h>
+
+#include "make.h"
+#include "hash.h"
+#include "dir.h"
+
+static Lst allTargets; /* the list of all targets found so far */
+#ifdef CLEANUP
+static Lst allGNs; /* List of all the GNodes */
+#endif
+static Hash_Table targets; /* a hash table of same */
+
+#define HTSIZE 191 /* initial size of hash table */
+
+static int TargPrintOnlySrc(void *, void *);
+static int TargPrintName(void *, void *);
+#ifdef CLEANUP
+static void TargFreeGN(void *);
+#endif
+static int TargPropagateCohort(void *, void *);
+static int TargPropagateNode(void *, void *);
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_Init --
+ * Initialize this module
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The allTargets list and the targets hash table are initialized
+ *-----------------------------------------------------------------------
+ */
+void
+Targ_Init(void)
+{
+ allTargets = Lst_Init(FALSE);
+ Hash_InitTable(&targets, HTSIZE);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_End --
+ * Finalize this module
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * All lists and gnodes are cleared
+ *-----------------------------------------------------------------------
+ */
+void
+Targ_End(void)
+{
+#ifdef CLEANUP
+ Lst_Destroy(allTargets, NULL);
+ if (allGNs)
+ Lst_Destroy(allGNs, TargFreeGN);
+ Hash_DeleteTable(&targets);
+#endif
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_List --
+ * Return the list of all targets
+ *
+ * Results:
+ * The list of all targets.
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+Lst
+Targ_List(void)
+{
+ return allTargets;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_NewGN --
+ * Create and initialize a new graph node
+ *
+ * Input:
+ * name the name to stick in the new node
+ *
+ * Results:
+ * An initialized graph node with the name field filled with a copy
+ * of the passed name
+ *
+ * Side Effects:
+ * The gnode is added to the list of all gnodes.
+ *-----------------------------------------------------------------------
+ */
+GNode *
+Targ_NewGN(const char *name)
+{
+ GNode *gn;
+
+ gn = bmake_malloc(sizeof(GNode));
+ gn->name = bmake_strdup(name);
+ gn->uname = NULL;
+ gn->path = NULL;
+ if (name[0] == '-' && name[1] == 'l') {
+ gn->type = OP_LIB;
+ } else {
+ gn->type = 0;
+ }
+ gn->unmade = 0;
+ gn->unmade_cohorts = 0;
+ gn->cohort_num[0] = 0;
+ gn->centurion = NULL;
+ gn->made = UNMADE;
+ gn->flags = 0;
+ gn->checked = 0;
+ gn->mtime = 0;
+ gn->cmgn = NULL;
+ gn->iParents = Lst_Init(FALSE);
+ gn->cohorts = Lst_Init(FALSE);
+ gn->parents = Lst_Init(FALSE);
+ gn->children = Lst_Init(FALSE);
+ gn->order_pred = Lst_Init(FALSE);
+ gn->order_succ = Lst_Init(FALSE);
+ Hash_InitTable(&gn->context, 0);
+ gn->commands = Lst_Init(FALSE);
+ gn->suffix = NULL;
+ gn->lineno = 0;
+ gn->fname = NULL;
+
+#ifdef CLEANUP
+ if (allGNs == NULL)
+ allGNs = Lst_Init(FALSE);
+ Lst_AtEnd(allGNs, gn);
+#endif
+
+ return (gn);
+}
+
+#ifdef CLEANUP
+/*-
+ *-----------------------------------------------------------------------
+ * TargFreeGN --
+ * Destroy a GNode
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+static void
+TargFreeGN(void *gnp)
+{
+ GNode *gn = (GNode *)gnp;
+
+
+ free(gn->name);
+ if (gn->uname)
+ free(gn->uname);
+ if (gn->path)
+ free(gn->path);
+ /* gn->fname points to name allocated when file was opened, don't free */
+
+ Lst_Destroy(gn->iParents, NULL);
+ Lst_Destroy(gn->cohorts, NULL);
+ Lst_Destroy(gn->parents, NULL);
+ Lst_Destroy(gn->children, NULL);
+ Lst_Destroy(gn->order_succ, NULL);
+ Lst_Destroy(gn->order_pred, NULL);
+ Hash_DeleteTable(&gn->context);
+ Lst_Destroy(gn->commands, NULL);
+ free(gn);
+}
+#endif
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_FindNode --
+ * Find a node in the list using the given name for matching
+ *
+ * Input:
+ * name the name to find
+ * flags flags governing events when target not
+ * found
+ *
+ * Results:
+ * The node in the list if it was. If it wasn't, return NULL of
+ * flags was TARG_NOCREATE or the newly created and initialized node
+ * if it was TARG_CREATE
+ *
+ * Side Effects:
+ * Sometimes a node is created and added to the list
+ *-----------------------------------------------------------------------
+ */
+GNode *
+Targ_FindNode(const char *name, int flags)
+{
+ GNode *gn; /* node in that element */
+ Hash_Entry *he = NULL; /* New or used hash entry for node */
+ Boolean isNew; /* Set TRUE if Hash_CreateEntry had to create */
+ /* an entry for the node */
+
+ if (!(flags & (TARG_CREATE | TARG_NOHASH))) {
+ he = Hash_FindEntry(&targets, name);
+ if (he == NULL)
+ return NULL;
+ return (GNode *)Hash_GetValue(he);
+ }
+
+ if (!(flags & TARG_NOHASH)) {
+ he = Hash_CreateEntry(&targets, name, &isNew);
+ if (!isNew)
+ return (GNode *)Hash_GetValue(he);
+ }
+
+ gn = Targ_NewGN(name);
+ if (!(flags & TARG_NOHASH))
+ Hash_SetValue(he, gn);
+ Var_Append(".ALLTARGETS", name, VAR_GLOBAL);
+ (void)Lst_AtEnd(allTargets, gn);
+ if (doing_depend)
+ gn->flags |= FROM_DEPEND;
+ return gn;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_FindList --
+ * Make a complete list of GNodes from the given list of names
+ *
+ * Input:
+ * name list of names to find
+ * flags flags used if no node is found for a given name
+ *
+ * Results:
+ * A complete list of graph nodes corresponding to all instances of all
+ * the names in names.
+ *
+ * Side Effects:
+ * If flags is TARG_CREATE, nodes will be created for all names in
+ * names which do not yet have graph nodes. If flags is TARG_NOCREATE,
+ * an error message will be printed for each name which can't be found.
+ * -----------------------------------------------------------------------
+ */
+Lst
+Targ_FindList(Lst names, int flags)
+{
+ Lst nodes; /* result list */
+ LstNode ln; /* name list element */
+ GNode *gn; /* node in tLn */
+ char *name;
+
+ nodes = Lst_Init(FALSE);
+
+ if (Lst_Open(names) == FAILURE) {
+ return (nodes);
+ }
+ while ((ln = Lst_Next(names)) != NULL) {
+ name = (char *)Lst_Datum(ln);
+ gn = Targ_FindNode(name, flags);
+ if (gn != NULL) {
+ /*
+ * Note: Lst_AtEnd must come before the Lst_Concat so the nodes
+ * are added to the list in the order in which they were
+ * encountered in the makefile.
+ */
+ (void)Lst_AtEnd(nodes, gn);
+ } else if (flags == TARG_NOCREATE) {
+ Error("\"%s\" -- target unknown.", name);
+ }
+ }
+ Lst_Close(names);
+ return (nodes);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_Ignore --
+ * Return true if should ignore errors when creating gn
+ *
+ * Input:
+ * gn node to check for
+ *
+ * Results:
+ * TRUE if should ignore errors
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Targ_Ignore(GNode *gn)
+{
+ if (ignoreErrors || gn->type & OP_IGNORE) {
+ return (TRUE);
+ } else {
+ return (FALSE);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_Silent --
+ * Return true if be silent when creating gn
+ *
+ * Input:
+ * gn node to check for
+ *
+ * Results:
+ * TRUE if should be silent
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Targ_Silent(GNode *gn)
+{
+ if (beSilent || gn->type & OP_SILENT) {
+ return (TRUE);
+ } else {
+ return (FALSE);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_Precious --
+ * See if the given target is precious
+ *
+ * Input:
+ * gn the node to check
+ *
+ * Results:
+ * TRUE if it is precious. FALSE otherwise
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Targ_Precious(GNode *gn)
+{
+ if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP))) {
+ return (TRUE);
+ } else {
+ return (FALSE);
+ }
+}
+
+/******************* DEBUG INFO PRINTING ****************/
+
+static GNode *mainTarg; /* the main target, as set by Targ_SetMain */
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_SetMain --
+ * Set our idea of the main target we'll be creating. Used for
+ * debugging output.
+ *
+ * Input:
+ * gn The main target we'll create
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * "mainTarg" is set to the main target's node.
+ *-----------------------------------------------------------------------
+ */
+void
+Targ_SetMain(GNode *gn)
+{
+ mainTarg = gn;
+}
+
+static int
+TargPrintName(void *gnp, void *pflags MAKE_ATTR_UNUSED)
+{
+ GNode *gn = (GNode *)gnp;
+
+ fprintf(debug_file, "%s%s ", gn->name, gn->cohort_num);
+
+ return 0;
+}
+
+
+int
+Targ_PrintCmd(void *cmd, void *dummy)
+{
+ fprintf(debug_file, "\t%s\n", (char *)cmd);
+ return (dummy ? 0 : 0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_FmtTime --
+ * Format a modification time in some reasonable way and return it.
+ *
+ * Results:
+ * The time reformatted.
+ *
+ * Side Effects:
+ * The time is placed in a static area, so it is overwritten
+ * with each call.
+ *
+ *-----------------------------------------------------------------------
+ */
+char *
+Targ_FmtTime(time_t tm)
+{
+ struct tm *parts;
+ static char buf[128];
+
+ parts = localtime(&tm);
+ (void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts);
+ return(buf);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_PrintType --
+ * Print out a type field giving only those attributes the user can
+ * set.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Targ_PrintType(int type)
+{
+ int tbit;
+
+#define PRINTBIT(attr) case CONCAT(OP_,attr): fprintf(debug_file, "." #attr " "); break
+#define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG))fprintf(debug_file, "." #attr " "); break
+
+ type &= ~OP_OPMASK;
+
+ while (type) {
+ tbit = 1 << (ffs(type) - 1);
+ type &= ~tbit;
+
+ switch(tbit) {
+ PRINTBIT(OPTIONAL);
+ PRINTBIT(USE);
+ PRINTBIT(EXEC);
+ PRINTBIT(IGNORE);
+ PRINTBIT(PRECIOUS);
+ PRINTBIT(SILENT);
+ PRINTBIT(MAKE);
+ PRINTBIT(JOIN);
+ PRINTBIT(INVISIBLE);
+ PRINTBIT(NOTMAIN);
+ PRINTDBIT(LIB);
+ /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */
+ case OP_MEMBER: if (DEBUG(TARG))fprintf(debug_file, ".MEMBER "); break;
+ PRINTDBIT(ARCHV);
+ PRINTDBIT(MADE);
+ PRINTDBIT(PHONY);
+ }
+ }
+}
+
+static const char *
+made_name(enum enum_made made)
+{
+ switch (made) {
+ case UNMADE: return "unmade";
+ case DEFERRED: return "deferred";
+ case REQUESTED: return "requested";
+ case BEINGMADE: return "being made";
+ case MADE: return "made";
+ case UPTODATE: return "up-to-date";
+ case ERROR: return "error when made";
+ case ABORTED: return "aborted";
+ default: return "unknown enum_made value";
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * TargPrintNode --
+ * print the contents of a node
+ *-----------------------------------------------------------------------
+ */
+int
+Targ_PrintNode(void *gnp, void *passp)
+{
+ GNode *gn = (GNode *)gnp;
+ int pass = passp ? *(int *)passp : 0;
+
+ fprintf(debug_file, "# %s%s, flags %x, type %x, made %d\n",
+ gn->name, gn->cohort_num, gn->flags, gn->type, gn->made);
+ if (gn->flags == 0)
+ return 0;
+
+ if (!OP_NOP(gn->type)) {
+ fprintf(debug_file, "#\n");
+ if (gn == mainTarg) {
+ fprintf(debug_file, "# *** MAIN TARGET ***\n");
+ }
+ if (pass >= 2) {
+ if (gn->unmade) {
+ fprintf(debug_file, "# %d unmade children\n", gn->unmade);
+ } else {
+ fprintf(debug_file, "# No unmade children\n");
+ }
+ if (! (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC))) {
+ if (gn->mtime != 0) {
+ fprintf(debug_file, "# last modified %s: %s\n",
+ Targ_FmtTime(gn->mtime),
+ made_name(gn->made));
+ } else if (gn->made != UNMADE) {
+ fprintf(debug_file, "# non-existent (maybe): %s\n",
+ made_name(gn->made));
+ } else {
+ fprintf(debug_file, "# unmade\n");
+ }
+ }
+ if (!Lst_IsEmpty (gn->iParents)) {
+ fprintf(debug_file, "# implicit parents: ");
+ Lst_ForEach(gn->iParents, TargPrintName, NULL);
+ fprintf(debug_file, "\n");
+ }
+ } else {
+ if (gn->unmade)
+ fprintf(debug_file, "# %d unmade children\n", gn->unmade);
+ }
+ if (!Lst_IsEmpty (gn->parents)) {
+ fprintf(debug_file, "# parents: ");
+ Lst_ForEach(gn->parents, TargPrintName, NULL);
+ fprintf(debug_file, "\n");
+ }
+ if (!Lst_IsEmpty (gn->order_pred)) {
+ fprintf(debug_file, "# order_pred: ");
+ Lst_ForEach(gn->order_pred, TargPrintName, NULL);
+ fprintf(debug_file, "\n");
+ }
+ if (!Lst_IsEmpty (gn->order_succ)) {
+ fprintf(debug_file, "# order_succ: ");
+ Lst_ForEach(gn->order_succ, TargPrintName, NULL);
+ fprintf(debug_file, "\n");
+ }
+
+ fprintf(debug_file, "%-16s", gn->name);
+ switch (gn->type & OP_OPMASK) {
+ case OP_DEPENDS:
+ fprintf(debug_file, ": "); break;
+ case OP_FORCE:
+ fprintf(debug_file, "! "); break;
+ case OP_DOUBLEDEP:
+ fprintf(debug_file, ":: "); break;
+ }
+ Targ_PrintType(gn->type);
+ Lst_ForEach(gn->children, TargPrintName, NULL);
+ fprintf(debug_file, "\n");
+ Lst_ForEach(gn->commands, Targ_PrintCmd, NULL);
+ fprintf(debug_file, "\n\n");
+ if (gn->type & OP_DOUBLEDEP) {
+ Lst_ForEach(gn->cohorts, Targ_PrintNode, &pass);
+ }
+ }
+ return (0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * TargPrintOnlySrc --
+ * Print only those targets that are just a source.
+ *
+ * Results:
+ * 0.
+ *
+ * Side Effects:
+ * The name of each file is printed preceded by #\t
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+TargPrintOnlySrc(void *gnp, void *dummy MAKE_ATTR_UNUSED)
+{
+ GNode *gn = (GNode *)gnp;
+ if (!OP_NOP(gn->type))
+ return 0;
+
+ fprintf(debug_file, "#\t%s [%s] ",
+ gn->name, gn->path ? gn->path : gn->name);
+ Targ_PrintType(gn->type);
+ fprintf(debug_file, "\n");
+
+ return 0;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_PrintGraph --
+ * print the entire graph. heh heh
+ *
+ * Input:
+ * pass Which pass this is. 1 => no processing
+ * 2 => processing done
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * lots o' output
+ *-----------------------------------------------------------------------
+ */
+void
+Targ_PrintGraph(int pass)
+{
+ fprintf(debug_file, "#*** Input graph:\n");
+ Lst_ForEach(allTargets, Targ_PrintNode, &pass);
+ fprintf(debug_file, "\n\n");
+ fprintf(debug_file, "#\n# Files that are only sources:\n");
+ Lst_ForEach(allTargets, TargPrintOnlySrc, NULL);
+ fprintf(debug_file, "#*** Global Variables:\n");
+ Var_Dump(VAR_GLOBAL);
+ fprintf(debug_file, "#*** Command-line Variables:\n");
+ Var_Dump(VAR_CMD);
+ fprintf(debug_file, "\n");
+ Dir_PrintDirectories();
+ fprintf(debug_file, "\n");
+ Suff_PrintAll();
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * TargPropagateNode --
+ * Propagate information from a single node to related nodes if
+ * appropriate.
+ *
+ * Input:
+ * gnp The node that we are processing.
+ *
+ * Results:
+ * Always returns 0, for the benefit of Lst_ForEach().
+ *
+ * Side Effects:
+ * Information is propagated from this node to cohort or child
+ * nodes.
+ *
+ * If the node was defined with "::", then TargPropagateCohort()
+ * will be called for each cohort node.
+ *
+ * If the node has recursive predecessors, then
+ * TargPropagateRecpred() will be called for each recursive
+ * predecessor.
+ *-----------------------------------------------------------------------
+ */
+static int
+TargPropagateNode(void *gnp, void *junk MAKE_ATTR_UNUSED)
+{
+ GNode *gn = (GNode *)gnp;
+
+ if (gn->type & OP_DOUBLEDEP)
+ Lst_ForEach(gn->cohorts, TargPropagateCohort, gnp);
+ return (0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * TargPropagateCohort --
+ * Propagate some bits in the type mask from a node to
+ * a related cohort node.
+ *
+ * Input:
+ * cnp The node that we are processing.
+ * gnp Another node that has cnp as a cohort.
+ *
+ * Results:
+ * Always returns 0, for the benefit of Lst_ForEach().
+ *
+ * Side Effects:
+ * cnp's type bitmask is modified to incorporate some of the
+ * bits from gnp's type bitmask. (XXX need a better explanation.)
+ *-----------------------------------------------------------------------
+ */
+static int
+TargPropagateCohort(void *cgnp, void *pgnp)
+{
+ GNode *cgn = (GNode *)cgnp;
+ GNode *pgn = (GNode *)pgnp;
+
+ cgn->type |= pgn->type & ~OP_OPMASK;
+ return (0);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Targ_Propagate --
+ * Propagate information between related nodes. Should be called
+ * after the makefiles are parsed but before any action is taken.
+ *
+ * Results:
+ * none
+ *
+ * Side Effects:
+ * Information is propagated between related nodes throughout the
+ * graph.
+ *-----------------------------------------------------------------------
+ */
+void
+Targ_Propagate(void)
+{
+ Lst_ForEach(allTargets, TargPropagateNode, NULL);
+}
diff --git a/external/bsd/bmake/dist/trace.c b/external/bsd/bmake/dist/trace.c
new file mode 100644
index 0000000..267177f
--- /dev/null
+++ b/external/bsd/bmake/dist/trace.c
@@ -0,0 +1,116 @@
+/* $NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Bill Sommerfeld
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $");
+#endif /* not lint */
+#endif
+
+/*-
+ * trace.c --
+ * handle logging of trace events generated by various parts of make.
+ *
+ * Interface:
+ * Trace_Init Initialize tracing (called once during
+ * the lifetime of the process)
+ *
+ * Trace_End Finalize tracing (called before make exits)
+ *
+ * Trace_Log Log an event about a particular make job.
+ */
+
+#include <sys/time.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "make.h"
+#include "job.h"
+#include "trace.h"
+
+static FILE *trfile;
+static pid_t trpid;
+char *trwd;
+
+static const char *evname[] = {
+ "BEG",
+ "END",
+ "ERR",
+ "JOB",
+ "DON",
+ "INT",
+};
+
+void
+Trace_Init(const char *pathname)
+{
+ char *p1;
+ if (pathname != NULL) {
+ trpid = getpid();
+ trwd = Var_Value(".CURDIR", VAR_GLOBAL, &p1);
+
+ trfile = fopen(pathname, "a");
+ }
+}
+
+void
+Trace_Log(TrEvent event, Job *job)
+{
+ struct timeval rightnow;
+
+ if (trfile == NULL)
+ return;
+
+ gettimeofday(&rightnow, NULL);
+
+ fprintf(trfile, "%lld.%06ld %d %s %d %s",
+ (long long)rightnow.tv_sec, (long)rightnow.tv_usec,
+ jobTokensRunning,
+ evname[event], trpid, trwd);
+ if (job != NULL) {
+ fprintf(trfile, " %s %d %x %x", job->node->name,
+ job->pid, job->flags, job->node->type);
+ }
+ fputc('\n', trfile);
+ fflush(trfile);
+}
+
+void
+Trace_End(void)
+{
+ if (trfile != NULL)
+ fclose(trfile);
+}
diff --git a/external/bsd/bmake/dist/trace.h b/external/bsd/bmake/dist/trace.h
new file mode 100644
index 0000000..dc0fc6c
--- /dev/null
+++ b/external/bsd/bmake/dist/trace.h
@@ -0,0 +1,49 @@
+/* $NetBSD: trace.h,v 1.3 2008/04/28 20:24:14 martin Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Bill Sommerfeld
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * trace.h --
+ * Definitions pertaining to the tracing of jobs in parallel mode.
+ */
+
+typedef enum {
+ MAKESTART,
+ MAKEEND,
+ MAKEERROR,
+ JOBSTART,
+ JOBEND,
+ MAKEINTR
+} TrEvent;
+
+void Trace_Init(const char *);
+void Trace_Log(TrEvent, Job *);
+void Trace_End(void);
+
diff --git a/external/bsd/bmake/dist/unit-tests/Makefile.in b/external/bsd/bmake/dist/unit-tests/Makefile.in
new file mode 100644
index 0000000..4e3592d
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/Makefile.in
@@ -0,0 +1,96 @@
+# $Id: Makefile.in,v 1.38 2012/06/19 23:38:48 sjg Exp $
+#
+# $NetBSD: Makefile,v 1.34 2012/06/19 23:25:53 sjg Exp $
+#
+# Unit tests for make(1)
+# The main targets are:
+#
+# all: run all the tests
+# test: run 'all', capture output and compare to expected results
+# accept: move generated output to expected results
+#
+# Adding a test case.
+# Each feature should get its own set of tests in its own suitably
+# named makefile which should be added to SUBFILES to hook it in.
+#
+
+srcdir= @srcdir@
+
+.MAIN: all
+
+UNIT_TESTS:= ${srcdir}
+
+# Simple sub-makefiles - we run them as a black box
+# keep the list sorted.
+SUBFILES= \
+ comment \
+ cond1 \
+ error \
+ export \
+ export-all \
+ doterror \
+ dotwait \
+ forloop \
+ forsubst \
+ hash \
+ misc \
+ moderrs \
+ modmatch \
+ modmisc \
+ modorder \
+ modts \
+ modword \
+ phony-end \
+ posix \
+ qequals \
+ sysv \
+ ternary \
+ unexport \
+ unexport-env \
+ varcmd
+
+all: ${SUBFILES}
+
+flags.doterror=
+
+# the tests are actually done with sub-makes.
+.PHONY: ${SUBFILES}
+.PRECIOUS: ${SUBFILES}
+${SUBFILES}:
+ -@${.MAKE} ${flags.$@:U-k} -f ${UNIT_TESTS}/$@
+
+clean:
+ rm -f *.out *.fail *.core
+
+.-include <bsd.obj.mk>
+
+TEST_MAKE?= ${.MAKE}
+TOOL_SED?= sed
+TOOL_TR?= tr
+TOOL_DIFF?= diff
+DIFF_FLAGS?= @diff_u@
+
+# ensure consistent results from sort(1)
+LC_ALL= C
+LANG= C
+.export LANG LC_ALL
+
+# The driver.
+# We always pretend .MAKE was called 'make'
+# and strip ${.CURDIR}/ from the output
+# and replace anything after 'stopped in' with unit-tests
+# so the results can be compared.
+test:
+ @echo "${TEST_MAKE} -f ${MAKEFILE} > ${.TARGET}.out 2>&1"
+ @cd ${.OBJDIR} && ${TEST_MAKE} -f ${MAKEFILE} 2>&1 | \
+ ${TOOL_TR} -d '\015' | \
+ ${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}:,make:,' \
+ -e '/stopped/s, /.*, unit-tests,' \
+ -e 's,${.CURDIR:C/\./\\\./g}/,,g' \
+ -e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' > ${.TARGET}.out || { \
+ tail ${.TARGET}.out; mv ${.TARGET}.out ${.TARGET}.fail; exit 1; }
+ ${TOOL_DIFF} ${DIFF_FLAGS} ${UNIT_TESTS}/${.TARGET}.exp ${.TARGET}.out
+
+accept:
+ mv test.out ${srcdir}/test.exp
+
diff --git a/external/bsd/bmake/dist/unit-tests/comment b/external/bsd/bmake/dist/unit-tests/comment
new file mode 100644
index 0000000..7dd7dbb
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/comment
@@ -0,0 +1,31 @@
+# This is a comment
+.if ${MACHINE_ARCH} == something
+FOO=bar
+.endif
+
+#\
+ Multiline comment
+
+BAR=# defined
+FOOBAR= # defined
+
+# This is an escaped comment \
+that keeps going until the end of this line
+
+# Another escaped comment \
+that \
+goes \
+on
+
+# This is NOT an escaped comment due to the double backslashes \\
+all: hi foo bar
+ @echo comment testing done
+
+hi:
+ @echo comment testing start
+
+foo:
+ @echo this is $@
+
+bar:
+ @echo This is how a comment looks: '# comment'
diff --git a/external/bsd/bmake/dist/unit-tests/cond1 b/external/bsd/bmake/dist/unit-tests/cond1
new file mode 100644
index 0000000..c877c3d
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/cond1
@@ -0,0 +1,109 @@
+# $Id: cond1,v 1.1.1.3 2011/03/06 00:04:58 sjg Exp $
+
+# hard code these!
+TEST_UNAME_S= NetBSD
+TEST_UNAME_M= sparc
+TEST_MACHINE= i386
+
+.if ${TEST_UNAME_S}
+Ok=var,
+.endif
+.if ("${TEST_UNAME_S}")
+Ok+=(\"var\"),
+.endif
+.if (${TEST_UNAME_M} != ${TEST_MACHINE})
+Ok+=(var != var),
+.endif
+.if ${TEST_UNAME_M} != ${TEST_MACHINE}
+Ok+= var != var,
+.endif
+.if !((${TEST_UNAME_M} != ${TEST_MACHINE}) && defined(X))
+Ok+= !((var != var) && defined(name)),
+.endif
+# from bsd.obj.mk
+MKOBJ?=no
+.if ${MKOBJ} == "no"
+o= no
+Ok+= var == "quoted",
+.else
+.if defined(notMAKEOBJDIRPREFIX) || defined(norMAKEOBJDIR)
+.if defined(notMAKEOBJDIRPREFIX)
+o=${MAKEOBJDIRPREFIX}${__curdir}
+.else
+o= ${MAKEOBJDIR}
+.endif
+.endif
+o= o
+.endif
+
+# repeat the above to check we get the same result
+.if ${MKOBJ} == "no"
+o2= no
+.else
+.if defined(notMAKEOBJDIRPREFIX) || defined(norMAKEOBJDIR)
+.if defined(notMAKEOBJDIRPREFIX)
+o2=${MAKEOBJDIRPREFIX}${__curdir}
+.else
+o2= ${MAKEOBJDIR}
+.endif
+.endif
+o2= o
+.endif
+
+PRIMES=2 3 5 7 11
+NUMBERS=1 2 3 4 5
+
+n=2
+.if ${PRIMES:M$n} == ""
+X=not
+.else
+X=
+.endif
+
+.if ${MACHINE_ARCH} == no-such
+A=one
+.else
+.if ${MACHINE_ARCH} == not-this
+.if ${MACHINE_ARCH} == something-else
+A=unlikely
+.else
+A=no
+.endif
+.endif
+A=other
+# We expect an extra else warning - we're not skipping here
+.else
+A=this should be an error
+.endif
+
+.if $X != ""
+.if $X == not
+B=one
+.else
+B=other
+# We expect an extra else warning - we are skipping here
+.else
+B=this should be an error
+.endif
+.else
+B=unknown
+.endif
+
+.if "quoted" == quoted
+C=clever
+.else
+C=dim
+.endif
+
+.if defined(nosuch) && ${nosuch:Mx} != ""
+# this should not happen
+.info nosuch is x
+.endif
+
+all:
+ @echo "$n is $X prime"
+ @echo "A='$A' B='$B' C='$C' o='$o,${o2}'"
+ @echo "Passed:${.newline} ${Ok:S/,/${.newline}/}"
+ @echo "${NUMBERS:@n@$n is ${("${PRIMES:M$n}" == ""):?not:} prime${.newline}@}"
+ @echo "${"${DoNotQuoteHere:U0}" > 0:?OK:No}"
+ @echo "${${NoSuchNumber:U42} > 0:?OK:No}"
diff --git a/external/bsd/bmake/dist/unit-tests/doterror b/external/bsd/bmake/dist/unit-tests/doterror
new file mode 100644
index 0000000..75d8920
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/doterror
@@ -0,0 +1,20 @@
+# $Id: doterror,v 1.1.1.1 2010/04/08 17:43:00 sjg Exp $
+
+
+.BEGIN:
+ @echo At first, I am
+
+.END:
+ @echo not reached
+
+.ERROR:
+ @echo "$@: Looks like '${.ERROR_TARGET}' is upset."
+
+all: happy sad
+
+happy:
+ @echo $@
+
+sad:
+ @echo and now: $@; exit 1
+
diff --git a/external/bsd/bmake/dist/unit-tests/dotwait b/external/bsd/bmake/dist/unit-tests/dotwait
new file mode 100644
index 0000000..43706af
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/dotwait
@@ -0,0 +1,61 @@
+# $NetBSD: dotwait,v 1.1 2006/02/26 22:45:46 apb Exp $
+
+THISMAKEFILE:= ${.PARSEDIR}/${.PARSEFILE}
+
+TESTS= simple recursive shared cycle
+PAUSE= sleep 1
+
+# Use a .for loop rather than dependencies here, to ensure
+# that the tests are run one by one, with parallelism
+# only within tests.
+# Ignore "--- target ---" lines printed by parallel make.
+all:
+.for t in ${TESTS}
+ @${.MAKE} -f ${THISMAKEFILE} -j4 $t | grep -v "^--- "
+.endfor
+
+#
+# Within each test, the names of the sub-targets follow these
+# conventions:
+# * If it's expected that two or more targets may be made in parallel,
+# then the target names will differ only in an alphabetic component
+# such as ".a" or ".b".
+# * If it's expected that two or more targets should be made in sequence
+# then the target names will differ in numeric components, such that
+# lexical ordering of the target names matches the expected order
+# in which the targets should be made.
+#
+# Targets may echo ${PARALLEL_TARG} to print a modified version
+# of their own name, in which alphabetic components like ".a" or ".b"
+# are converted to ".*". Two targets that are expected to
+# be made in parallel will thus print the same strings, so that the
+# output is independent of the order in which these targets are made.
+#
+PARALLEL_TARG= ${.TARGET:C/\.[a-z]/.*/g:Q}
+.DEFAULT:
+ @echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG}
+_ECHOUSE: .USE
+ @echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG}
+
+# simple: no recursion, no cycles
+simple: simple.1 .WAIT simple.2
+
+# recursive: all children of the left hand side of the .WAIT
+# must be made before any child of the right hand side.
+recursive: recursive.1.99 .WAIT recursive.2.99
+recursive.1.99: recursive.1.1.a recursive.1.1.b _ECHOUSE
+recursive.2.99: recursive.2.1.a recursive.2.1.b _ECHOUSE
+
+# shared: both shared.1.99 and shared.2.99 depend on shared.0.
+# shared.0 must be made first, even though it is a child of
+# the right hand side of the .WAIT.
+shared: shared.1.99 .WAIT shared.2.99
+shared.1.99: shared.0 _ECHOUSE
+shared.2.99: shared.2.1 shared.0 _ECHOUSE
+
+# cycle: the cyclic dependency must not cause infinite recursion
+# leading to stack overflow and a crash.
+cycle: cycle.1.99 .WAIT cycle.2.99
+cycle.2.99: cycle.2.98 _ECHOUSE
+cycle.2.98: cycle.2.97 _ECHOUSE
+cycle.2.97: cycle.2.99 _ECHOUSE
diff --git a/external/bsd/bmake/dist/unit-tests/error b/external/bsd/bmake/dist/unit-tests/error
new file mode 100644
index 0000000..c0a1403
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/error
@@ -0,0 +1,10 @@
+# $Id: error,v 1.1.1.2 2010/05/24 23:36:03 sjg Exp $
+
+.info just FYI
+.warning this could be serious
+.error this is fatal
+
+all:
+
+.info.html:
+ @echo this should be ignored
diff --git a/external/bsd/bmake/dist/unit-tests/export b/external/bsd/bmake/dist/unit-tests/export
new file mode 100644
index 0000000..3e2ad95
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/export
@@ -0,0 +1,22 @@
+# $Id: export,v 1.1.1.1 2007/10/08 20:30:12 sjg Exp $
+
+UT_TEST=export
+UT_FOO=foo${BAR}
+UT_FU=fubar
+UT_ZOO=hoopie
+UT_NO=all
+# belive it or not, we expect this one to come out with $UT_FU unexpanded.
+UT_DOLLAR= This is $$UT_FU
+
+.export UT_FU UT_FOO
+.export UT_DOLLAR
+# this one will be ignored
+.export .MAKE.PID
+
+BAR=bar is ${UT_FU}
+
+.MAKE.EXPORTED+= UT_ZOO UT_TEST
+
+all:
+ @env | grep '^UT_' | sort
+
diff --git a/external/bsd/bmake/dist/unit-tests/export-all b/external/bsd/bmake/dist/unit-tests/export-all
new file mode 100644
index 0000000..a243fe3
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/export-all
@@ -0,0 +1,23 @@
+# $Id: export-all,v 1.1.1.2 2010/04/21 04:26:14 sjg Exp $
+
+UT_OK=good
+UT_F=fine
+
+# the old way to do :tA
+M_tAbad = C,.*,cd & \&\& 'pwd',:sh
+# the new
+M_tA = tA
+
+here := ${.PARSEDIR}
+
+# this will cause trouble (recursing if we let it)
+UT_BADDIR = ${${here}/../${here:T}:L:${M_tAbad}:T}
+# this will be ok
+UT_OKDIR = ${${here}/../${here:T}:L:${M_tA}:T}
+
+.export
+
+.include "export"
+
+UT_TEST=export-all
+UT_ALL=even this gets exported
diff --git a/external/bsd/bmake/dist/unit-tests/forloop b/external/bsd/bmake/dist/unit-tests/forloop
new file mode 100644
index 0000000..0b50e66
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/forloop
@@ -0,0 +1,45 @@
+# $Id: forloop,v 1.1.1.1 2012/06/19 23:30:49 sjg Exp $
+
+all: for-loop
+
+LIST = one "two and three" four "five"
+
+.if make(for-fail)
+for-fail:
+
+XTRA_LIST = xtra
+.else
+
+.for x in ${LIST}
+X!= echo 'x=$x' >&2; echo
+.endfor
+
+CFL = -I/this -I"This or that" -Ithat "-DTHIS=\"this and that\""
+cfl=
+.for x in ${CFL}
+X!= echo 'x=$x' >&2; echo
+.if empty(cfl)
+cfl= $x
+.else
+cfl+= $x
+.endif
+.endfor
+X!= echo 'cfl=${cfl}' >&2; echo
+
+.if ${cfl} != ${CFL}
+.error ${.newline}'${cfl}' != ${.newline}'${CFL}'
+.endif
+
+.for a b in ${EMPTY}
+X!= echo 'a=$a b=$b' >&2; echo
+.endfor
+.endif
+
+.for a b in ${LIST} ${LIST:tu} ${XTRA_LIST}
+X!= echo 'a=$a b=$b' >&2; echo
+.endfor
+
+for-loop:
+ @echo We expect an error next:
+ @(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} for-fail) && \
+ { echo "Oops that should have failed!"; exit 1; } || echo OK
diff --git a/external/bsd/bmake/dist/unit-tests/forsubst b/external/bsd/bmake/dist/unit-tests/forsubst
new file mode 100644
index 0000000..d3a7de1
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/forsubst
@@ -0,0 +1,10 @@
+# $Id: forsubst,v 1.1.1.1 2009/10/07 18:53:35 sjg Exp $
+
+all: for-subst
+
+here := ${.PARSEDIR}
+# this should not run foul of the parser
+.for file in ${.PARSEFILE}
+for-subst: ${file:S;^;${here}/;g}
+ @echo ".for with :S;... OK"
+.endfor
diff --git a/external/bsd/bmake/dist/unit-tests/hash b/external/bsd/bmake/dist/unit-tests/hash
new file mode 100644
index 0000000..1ed84e7
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/hash
@@ -0,0 +1,18 @@
+STR1=
+STR2= a
+STR3= ab
+STR4= abc
+STR5= abcd
+STR6= abcde
+STR7= abcdef
+STR8= abcdefghijklmnopqrstuvwxyz
+
+all:
+ @echo ${STR1:hash}
+ @echo ${STR2:hash}
+ @echo ${STR3:hash}
+ @echo ${STR4:hash}
+ @echo ${STR5:hash}
+ @echo ${STR6:hash}
+ @echo ${STR7:hash}
+ @echo ${STR8:hash}
diff --git a/external/bsd/bmake/dist/unit-tests/misc b/external/bsd/bmake/dist/unit-tests/misc
new file mode 100644
index 0000000..4ba3655
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/misc
@@ -0,0 +1,16 @@
+# $Id: misc,v 1.1.1.1 2011/03/06 00:04:58 sjg Exp $
+
+.if !exists(${.CURDIR}/)
+.warning ${.CURDIR}/ doesn't exist ?
+.endif
+
+.if !exists(${.CURDIR}/.)
+.warning ${.CURDIR}/. doesn't exist ?
+.endif
+
+.if !exists(${.CURDIR}/..)
+.warning ${.CURDIR}/.. doesn't exist ?
+.endif
+
+all:
+ @: all is well
diff --git a/external/bsd/bmake/dist/unit-tests/moderrs b/external/bsd/bmake/dist/unit-tests/moderrs
new file mode 100644
index 0000000..b8f78ce
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/moderrs
@@ -0,0 +1,31 @@
+# $Id: moderrs,v 1.2 2006/05/11 18:53:39 sjg Exp $
+#
+# various modifier error tests
+
+VAR=TheVariable
+# incase we have to change it ;-)
+MOD_UNKN=Z
+MOD_TERM=S,V,v
+MOD_S:= ${MOD_TERM},
+
+all: modunkn modunknV varterm vartermV modtermV
+
+modunkn:
+ @echo "Expect: Unknown modifier 'Z'"
+ @echo "VAR:Z=${VAR:Z}"
+
+modunknV:
+ @echo "Expect: Unknown modifier 'Z'"
+ @echo "VAR:${MOD_UNKN}=${VAR:${MOD_UNKN}}"
+
+varterm:
+ @echo "Expect: Unclosed variable specification for VAR"
+ @echo VAR:S,V,v,=${VAR:S,V,v,
+
+vartermV:
+ @echo "Expect: Unclosed variable specification for VAR"
+ @echo VAR:${MOD_TERM},=${VAR:${MOD_S}
+
+modtermV:
+ @echo "Expect: Unclosed substitution for VAR (, missing)"
+ -@echo "VAR:${MOD_TERM}=${VAR:${MOD_TERM}}"
diff --git a/external/bsd/bmake/dist/unit-tests/modmatch b/external/bsd/bmake/dist/unit-tests/modmatch
new file mode 100644
index 0000000..48a1bef
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/modmatch
@@ -0,0 +1,25 @@
+
+X=a b c d e
+
+.for x in $X
+LIB${x:tu}=/tmp/lib$x.a
+.endfor
+
+X_LIBS= ${LIBA} ${LIBD} ${LIBE}
+
+LIB?=a
+
+var = head
+res = no
+.if !empty(var:M${:Uhead\:tail:C/:.*//})
+res = OK
+.endif
+
+all:
+ @for x in $X; do ${.MAKE} -f ${MAKEFILE} show LIB=$$x; done
+ @echo "Mscanner=${res}"
+
+show:
+ @echo 'LIB=${LIB} X_LIBS:M$${LIB$${LIB:tu}} is "${X_LIBS:M${LIB${LIB:tu}}}"'
+ @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a is "${X_LIBS:M*/lib${LIB}.a}"'
+ @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a:tu is "${X_LIBS:M*/lib${LIB}.a:tu}"'
diff --git a/external/bsd/bmake/dist/unit-tests/modmisc b/external/bsd/bmake/dist/unit-tests/modmisc
new file mode 100644
index 0000000..d562e46
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/modmisc
@@ -0,0 +1,38 @@
+# $Id: modmisc,v 1.1.1.5 2011/04/11 15:10:32 sjg Exp $
+#
+# miscellaneous modifier tests
+
+# do not put any dirs in this list which exist on some
+# but not all target systems - an exists() check is below.
+path=:/bin:/tmp::/:.:/no/such/dir:.
+# strip cwd from path.
+MOD_NODOT=S/:/ /g:N.:ts:
+# and decorate, note that $'s need to be doubled. Also note that
+# the modifier_variable can be used with other modifiers.
+MOD_NODOTX=S/:/ /g:N.:@d@'$$d'@
+# another mod - pretend it is more interesting
+MOD_HOMES=S,/home/,/homes/,
+MOD_OPT=@d@$${exists($$d):?$$d:$${d:S,/usr,/opt,}}@
+MOD_SEP=S,:, ,g
+
+all: modvar modvarloop modsysv
+
+modsysv:
+ @echo "The answer is ${libfoo.a:L:libfoo.a=42}"
+
+modvar:
+ @echo "path='${path}'"
+ @echo "path='${path:${MOD_NODOT}}'"
+ @echo "path='${path:S,home,homes,:${MOD_NODOT}}'"
+ @echo "path=${path:${MOD_NODOTX}:ts:}"
+ @echo "path=${path:${MOD_HOMES}:${MOD_NODOTX}:ts:}"
+
+.for d in ${path:${MOD_SEP}:N.} /usr/xbin
+path_$d?= ${d:${MOD_OPT}:${MOD_HOMES}}/
+paths+= ${d:${MOD_OPT}:${MOD_HOMES}}
+.endfor
+
+modvarloop:
+ @echo "path_/usr/xbin=${path_/usr/xbin}"
+ @echo "paths=${paths}"
+ @echo "PATHS=${paths:tu}"
diff --git a/external/bsd/bmake/dist/unit-tests/modorder b/external/bsd/bmake/dist/unit-tests/modorder
new file mode 100644
index 0000000..68b66fb
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/modorder
@@ -0,0 +1,22 @@
+# $NetBSD: modorder,v 1.2 2007/10/05 15:27:46 sjg Exp $
+
+LIST= one two three four five six seven eight nine ten
+LISTX= ${LIST:Ox}
+LISTSX:= ${LIST:Ox}
+TEST_RESULT= && echo Ok || echo Failed
+
+# unit-tests have to produce the same results on each run
+# so we cannot actually include :Ox output.
+all:
+ @echo "LIST = ${LIST}"
+ @echo "LIST:O = ${LIST:O}"
+ # Note that 1 in every 10! trials two independently generated
+ # randomized orderings will be the same. The test framework doesn't
+ # support checking probabilistic output, so we accept that the test
+ # will incorrectly fail with probability 2.8E-7.
+ @echo "LIST:Ox = `test '${LIST:Ox}' != '${LIST:Ox}' ${TEST_RESULT}`"
+ @echo "LIST:O:Ox = `test '${LIST:O:Ox}' != '${LIST:O:Ox}' ${TEST_RESULT}`"
+ @echo "LISTX = `test '${LISTX}' != '${LISTX}' ${TEST_RESULT}`"
+ @echo "LISTSX = `test '${LISTSX}' = '${LISTSX}' ${TEST_RESULT}`"
+ @echo "BADMOD 1 = ${LIST:OX}"
+ @echo "BADMOD 2 = ${LIST:OxXX}"
diff --git a/external/bsd/bmake/dist/unit-tests/modts b/external/bsd/bmake/dist/unit-tests/modts
new file mode 100644
index 0000000..616bd89
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/modts
@@ -0,0 +1,43 @@
+
+LIST= one two three
+LIST+= four five six
+
+FU_mod-ts = a / b / cool
+
+AAA= a a a
+B.aaa= Baaa
+
+all: mod-ts
+
+# Use print or printf iff they are builtin.
+# XXX note that this causes problems, when make decides
+# there is no need to use a shell, so avoid where possible.
+.if ${type print 2> /dev/null || echo:L:sh:Mbuiltin} != ""
+PRINT= print -r --
+.elif ${type printf 2> /dev/null || echo:L:sh:Mbuiltin} != ""
+PRINT= printf '%s\n'
+.else
+PRINT= echo
+.endif
+
+mod-ts:
+ @echo 'LIST="${LIST}"'
+ @echo 'LIST:ts,="${LIST:ts,}"'
+ @echo 'LIST:ts/:tu="${LIST:ts/:tu}"'
+ @echo 'LIST:ts::tu="${LIST:ts::tu}"'
+ @echo 'LIST:ts:tu="${LIST:ts:tu}"'
+ @echo 'LIST:tu:ts/="${LIST:tu:ts/}"'
+ @echo 'LIST:ts:="${LIST:ts:}"'
+ @echo 'LIST:ts="${LIST:ts}"'
+ @echo 'LIST:ts:S/two/2/="${LIST:ts:S/two/2/}"'
+ @echo 'LIST:S/two/2/:ts="${LIST:S/two/2/:ts}"'
+ @echo 'LIST:ts/:S/two/2/="${LIST:ts/:S/two/2/}"'
+ @echo "Pretend the '/' in '/n' etc. below are back-slashes."
+ @${PRINT} 'LIST:ts/n="${LIST:ts\n}"'
+ @${PRINT} 'LIST:ts/t="${LIST:ts\t}"'
+ @${PRINT} 'LIST:ts/012:tu="${LIST:ts\012:tu}"'
+ @${PRINT} 'LIST:tx="${LIST:tx}"'
+ @${PRINT} 'LIST:ts/x:tu="${LIST:ts\x:tu}"'
+ @${PRINT} 'FU_$@="${FU_${@:ts}:ts}"'
+ @${PRINT} 'FU_$@:ts:T="${FU_${@:ts}:ts:T}" == cool?'
+ @${PRINT} 'B.$${AAA:ts}="${B.${AAA:ts}}" == Baaa?'
diff --git a/external/bsd/bmake/dist/unit-tests/modword b/external/bsd/bmake/dist/unit-tests/modword
new file mode 100644
index 0000000..39355d7
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/modword
@@ -0,0 +1,151 @@
+# $Id: modword,v 1.1.1.1 2003/09/28 17:01:48 sjg Exp $
+#
+# Test behaviour of new :[] modifier
+
+all: mod-squarebrackets mod-S-W mod-C-W mod-tW-tw
+
+LIST= one two three
+LIST+= four five six
+LONGLIST= 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+
+EMPTY= # the space should be ignored
+ESCAPEDSPACE=\ # escaped space before the '#'
+REALLYSPACE:=${EMPTY:C/^/ /W}
+HASH= \#
+AT= @
+STAR= *
+ZERO= 0
+ONE= 1
+MINUSONE= -1
+
+mod-squarebrackets: mod-squarebrackets-0-star-at \
+ mod-squarebrackets-hash \
+ mod-squarebrackets-n \
+ mod-squarebrackets-start-end \
+ mod-squarebrackets-nested
+
+mod-squarebrackets-0-star-at:
+ @echo 'LIST:[]="${LIST:[]}" is an error'
+ @echo 'LIST:[0]="${LIST:[0]}"'
+ @echo 'LIST:[0x0]="${LIST:[0x0]}"'
+ @echo 'LIST:[000]="${LIST:[000]}"'
+ @echo 'LIST:[*]="${LIST:[*]}"'
+ @echo 'LIST:[@]="${LIST:[@]}"'
+ @echo 'LIST:[0]:C/ /,/="${LIST:[0]:C/ /,/}"'
+ @echo 'LIST:[0]:C/ /,/g="${LIST:[0]:C/ /,/g}"'
+ @echo 'LIST:[0]:C/ /,/1g="${LIST:[0]:C/ /,/1g}"'
+ @echo 'LIST:[*]:C/ /,/="${LIST:[*]:C/ /,/}"'
+ @echo 'LIST:[*]:C/ /,/g="${LIST:[*]:C/ /,/g}"'
+ @echo 'LIST:[*]:C/ /,/1g="${LIST:[*]:C/ /,/1g}"'
+ @echo 'LIST:[@]:C/ /,/="${LIST:[@]:C/ /,/}"'
+ @echo 'LIST:[@]:C/ /,/g="${LIST:[@]:C/ /,/g}"'
+ @echo 'LIST:[@]:C/ /,/1g="${LIST:[@]:C/ /,/1g}"'
+ @echo 'LIST:[@]:[0]:C/ /,/="${LIST:[@]:[0]:C/ /,/}"'
+ @echo 'LIST:[0]:[@]:C/ /,/="${LIST:[0]:[@]:C/ /,/}"'
+ @echo 'LIST:[@]:[*]:C/ /,/="${LIST:[@]:[*]:C/ /,/}"'
+ @echo 'LIST:[*]:[@]:C/ /,/="${LIST:[*]:[@]:C/ /,/}"'
+
+mod-squarebrackets-hash:
+ @echo 'EMPTY="${EMPTY}"'
+ @echo 'EMPTY:[#]="${EMPTY:[#]}" == 1 ?'
+ @echo 'ESCAPEDSPACE="${ESCAPEDSPACE}"'
+ @echo 'ESCAPEDSPACE:[#]="${ESCAPEDSPACE:[#]}" == 1 ?'
+ @echo 'REALLYSPACE="${REALLYSPACE}"'
+ @echo 'REALLYSPACE:[#]="${REALLYSPACE:[#]}" == 1 ?'
+ @echo 'LIST:[#]="${LIST:[#]}"'
+ @echo 'LIST:[0]:[#]="${LIST:[0]:[#]}" == 1 ?'
+ @echo 'LIST:[*]:[#]="${LIST:[*]:[#]}" == 1 ?'
+ @echo 'LIST:[@]:[#]="${LIST:[@]:[#]}"'
+ @echo 'LIST:[1]:[#]="${LIST:[1]:[#]}"'
+ @echo 'LIST:[1..3]:[#]="${LIST:[1..3]:[#]}"'
+
+mod-squarebrackets-n:
+ @echo 'EMPTY:[1]="${EMPTY:[1]}"'
+ @echo 'ESCAPEDSPACE="${ESCAPEDSPACE}"'
+ @echo 'ESCAPEDSPACE:[1]="${ESCAPEDSPACE:[1]}"'
+ @echo 'REALLYSPACE="${REALLYSPACE}"'
+ @echo 'REALLYSPACE:[1]="${REALLYSPACE:[1]}" == "" ?'
+ @echo 'REALLYSPACE:[*]:[1]="${REALLYSPACE:[*]:[1]}" == " " ?'
+ @echo 'LIST:[1]="${LIST:[1]}"'
+ @echo 'LIST:[1.]="${LIST:[1.]}" is an error'
+ @echo 'LIST:[1].="${LIST:[1].}" is an error'
+ @echo 'LIST:[2]="${LIST:[2]}"'
+ @echo 'LIST:[6]="${LIST:[6]}"'
+ @echo 'LIST:[7]="${LIST:[7]}"'
+ @echo 'LIST:[999]="${LIST:[999]}"'
+ @echo 'LIST:[-]="${LIST:[-]}" is an error'
+ @echo 'LIST:[--]="${LIST:[--]}" is an error'
+ @echo 'LIST:[-1]="${LIST:[-1]}"'
+ @echo 'LIST:[-2]="${LIST:[-2]}"'
+ @echo 'LIST:[-6]="${LIST:[-6]}"'
+ @echo 'LIST:[-7]="${LIST:[-7]}"'
+ @echo 'LIST:[-999]="${LIST:[-999]}"'
+ @echo 'LONGLIST:[17]="${LONGLIST:[17]}"'
+ @echo 'LONGLIST:[0x11]="${LONGLIST:[0x11]}"'
+ @echo 'LONGLIST:[021]="${LONGLIST:[021]}"'
+ @echo 'LIST:[0]:[1]="${LIST:[0]:[1]}"'
+ @echo 'LIST:[*]:[1]="${LIST:[*]:[1]}"'
+ @echo 'LIST:[@]:[1]="${LIST:[@]:[1]}"'
+ @echo 'LIST:[0]:[2]="${LIST:[0]:[2]}"'
+ @echo 'LIST:[*]:[2]="${LIST:[*]:[2]}"'
+ @echo 'LIST:[@]:[2]="${LIST:[@]:[2]}"'
+ @echo 'LIST:[*]:C/ /,/:[2]="${LIST:[*]:C/ /,/:[2]}"'
+ @echo 'LIST:[*]:C/ /,/:[*]:[2]="${LIST:[*]:C/ /,/:[*]:[2]}"'
+ @echo 'LIST:[*]:C/ /,/:[@]:[2]="${LIST:[*]:C/ /,/:[@]:[2]}"'
+
+mod-squarebrackets-start-end:
+ @echo 'LIST:[1.]="${LIST:[1.]}" is an error'
+ @echo 'LIST:[1..]="${LIST:[1..]}" is an error'
+ @echo 'LIST:[1..1]="${LIST:[1..1]}"'
+ @echo 'LIST:[1..1.]="${LIST:[1..1.]}" is an error'
+ @echo 'LIST:[1..2]="${LIST:[1..2]}"'
+ @echo 'LIST:[2..1]="${LIST:[2..1]}"'
+ @echo 'LIST:[3..-2]="${LIST:[3..-2]}"'
+ @echo 'LIST:[-4..4]="${LIST:[-4..4]}"'
+ @echo 'LIST:[0..1]="${LIST:[0..1]}" is an error'
+ @echo 'LIST:[-1..0]="${LIST:[-1..0]}" is an error'
+ @echo 'LIST:[-1..1]="${LIST:[-1..1]}"'
+ @echo 'LIST:[0..0]="${LIST:[0..0]}"'
+ @echo 'LIST:[3..99]="${LIST:[3..99]}"'
+ @echo 'LIST:[-3..-99]="${LIST:[-3..-99]}"'
+ @echo 'LIST:[-99..-3]="${LIST:[-99..-3]}"'
+
+mod-squarebrackets-nested:
+ @echo 'HASH="${HASH}" == "#" ?'
+ @echo 'LIST:[$${HASH}]="${LIST:[${HASH}]}"'
+ @echo 'LIST:[$${ZERO}]="${LIST:[${ZERO}]}"'
+ @echo 'LIST:[$${ZERO}x$${ONE}]="${LIST:[${ZERO}x${ONE}]}"'
+ @echo 'LIST:[$${ONE}]="${LIST:[${ONE}]}"'
+ @echo 'LIST:[$${MINUSONE}]="${LIST:[${MINUSONE}]}"'
+ @echo 'LIST:[$${STAR}]="${LIST:[${STAR}]}"'
+ @echo 'LIST:[$${AT}]="${LIST:[${AT}]}"'
+ @echo 'LIST:[$${EMPTY}]="${LIST:[${EMPTY}]}" is an error'
+ @echo 'LIST:[$${LONGLIST:[21]:S/2//}]="${LIST:[${LONGLIST:[21]:S/2//}]}"'
+ @echo 'LIST:[$${LIST:[#]}]="${LIST:[${LIST:[#]}]}"'
+ @echo 'LIST:[$${LIST:[$${HASH}]}]="${LIST:[${LIST:[${HASH}]}]}"'
+
+mod-C-W:
+ @echo 'LIST:C/ /,/="${LIST:C/ /,/}"'
+ @echo 'LIST:C/ /,/W="${LIST:C/ /,/W}"'
+ @echo 'LIST:C/ /,/gW="${LIST:C/ /,/gW}"'
+ @echo 'EMPTY:C/^/,/="${EMPTY:C/^/,/}"'
+ @echo 'EMPTY:C/^/,/W="${EMPTY:C/^/,/W}"'
+
+mod-S-W:
+ @echo 'LIST:S/ /,/="${LIST:S/ /,/}"'
+ @echo 'LIST:S/ /,/W="${LIST:S/ /,/W}"'
+ @echo 'LIST:S/ /,/gW="${LIST:S/ /,/gW}"'
+ @echo 'EMPTY:S/^/,/="${EMPTY:S/^/,/}"'
+ @echo 'EMPTY:S/^/,/W="${EMPTY:S/^/,/W}"'
+
+mod-tW-tw:
+ @echo 'LIST:tW="${LIST:tW}"'
+ @echo 'LIST:tw="${LIST:tw}"'
+ @echo 'LIST:tW:C/ /,/="${LIST:tW:C/ /,/}"'
+ @echo 'LIST:tW:C/ /,/g="${LIST:tW:C/ /,/g}"'
+ @echo 'LIST:tW:C/ /,/1g="${LIST:tW:C/ /,/1g}"'
+ @echo 'LIST:tw:C/ /,/="${LIST:tw:C/ /,/}"'
+ @echo 'LIST:tw:C/ /,/g="${LIST:tw:C/ /,/g}"'
+ @echo 'LIST:tw:C/ /,/1g="${LIST:tw:C/ /,/1g}"'
+ @echo 'LIST:tw:tW:C/ /,/="${LIST:tw:tW:C/ /,/}"'
+ @echo 'LIST:tW:tw:C/ /,/="${LIST:tW:tw:C/ /,/}"'
diff --git a/external/bsd/bmake/dist/unit-tests/phony-end b/external/bsd/bmake/dist/unit-tests/phony-end
new file mode 100644
index 0000000..d61884c
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/phony-end
@@ -0,0 +1,9 @@
+# $Id: phony-end,v 1.1.1.1 2011/10/01 17:19:39 sjg Exp $
+
+all ok also.ok bug phony:
+ @echo '${.TARGET .PREFIX .IMPSRC:L:@v@$v="${$v}"@}'
+
+.END: ok also.ok bug
+
+phony bug: .PHONY
+all: phony
diff --git a/external/bsd/bmake/dist/unit-tests/posix b/external/bsd/bmake/dist/unit-tests/posix
new file mode 100644
index 0000000..48ed7a3
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/posix
@@ -0,0 +1,24 @@
+# $Id: posix,v 1.1.1.1 2004/05/08 16:45:39 sjg Exp $
+
+all: x plus subs err
+
+x:
+ @echo "Posix says we should execute the command as if run by system(3)"
+ @echo "Expect 'Hello,' and 'World!'"
+ @echo Hello,; false; echo "World!"
+
+plus:
+ @echo a command
+ +@echo "a command prefixed by '+' executes even with -n"
+ @echo another command
+
+subs:
+ @echo make -n
+ @${.MAKE} -f ${MAKEFILE} -n plus
+ @echo make -n -j1
+ @${.MAKE} -f ${MAKEFILE} -n -j1 plus
+
+err:
+ @(echo Now we expect an error...; exit 1)
+ @echo "Oops! you shouldn't see this!"
+
diff --git a/external/bsd/bmake/dist/unit-tests/qequals b/external/bsd/bmake/dist/unit-tests/qequals
new file mode 100644
index 0000000..e23078e
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/qequals
@@ -0,0 +1,8 @@
+# $Id: qequals,v 1.1.1.1 2008/03/31 00:13:05 sjg Exp $
+
+M= i386
+V.i386= OK
+V.$M ?= bug
+
+all:
+ @echo 'V.$M ?= ${V.$M}'
diff --git a/external/bsd/bmake/dist/unit-tests/sysv b/external/bsd/bmake/dist/unit-tests/sysv
new file mode 100644
index 0000000..9eedacb
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/sysv
@@ -0,0 +1,26 @@
+# $Id: sysv,v 1.1.1.2 2011/06/05 04:23:49 sjg Exp $
+
+FOO ?=
+FOOBAR = $(FOO:=bar)
+
+_this := ${.PARSEDIR}/${.PARSEFILE}
+
+B = /b
+S = /
+FUN = ${B}${S}fun
+SUN = the Sun
+
+# we expect nothing when FOO is empty
+all: foo fun
+
+foo:
+ @echo FOOBAR = $(FOOBAR)
+.if empty(FOO)
+ @FOO="foo fu" ${.MAKE} -f ${_this} foo
+.endif
+
+fun:
+ @echo ${FUN:T}
+ @echo ${FUN:${B}${S}fun=fun}
+ @echo ${FUN:${B}${S}%=%}
+ @echo ${In:L:%=% ${SUN}}
diff --git a/external/bsd/bmake/dist/unit-tests/ternary b/external/bsd/bmake/dist/unit-tests/ternary
new file mode 100644
index 0000000..77f8349
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/ternary
@@ -0,0 +1,8 @@
+
+all:
+ @for x in "" A= A=42; do ${.MAKE} -f ${MAKEFILE} show $$x; done
+
+show:
+ @echo "The answer is ${A:?known:unknown}"
+ @echo "The answer is ${A:?$A:unknown}"
+ @echo "The answer is ${empty(A):?empty:$A}"
diff --git a/external/bsd/bmake/dist/unit-tests/test.exp b/external/bsd/bmake/dist/unit-tests/test.exp
new file mode 100644
index 0000000..932d84e
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/test.exp
@@ -0,0 +1,369 @@
+comment testing start
+this is foo
+This is how a comment looks: # comment
+comment testing done
+make: "cond1" line 75: warning: extra else
+make: "cond1" line 85: warning: extra else
+2 is prime
+A='other' B='unknown' C='clever' o='no,no'
+Passed:
+ var
+ ("var")
+ (var != var)
+ var != var
+ !((var != var) && defined(name))
+ var == quoted
+
+1 is not prime
+2 is prime
+3 is prime
+4 is not prime
+5 is prime
+
+make: warning: String comparison operator should be either == or !=
+make: Bad conditional expression `"0" > 0' in "0" > 0?OK:No
+
+OK
+make: "error" line 3: just FYI
+make: "error" line 4: warning: this could be serious
+make: "error" line 5: this is fatal
+UT_DOLLAR=This is $UT_FU
+UT_FOO=foobar is fubar
+UT_FU=fubar
+UT_TEST=export
+UT_ZOO=hoopie
+UT_ALL=even this gets exported
+UT_BADDIR=unit-tests
+UT_DOLLAR=This is $UT_FU
+UT_F=fine
+UT_FOO=foobar is fubar
+UT_FU=fubar
+UT_NO=all
+UT_OK=good
+UT_OKDIR=unit-tests
+UT_TEST=export-all
+UT_ZOO=hoopie
+At first, I am
+happy
+and now: sad
+.ERROR: Looks like 'sad' is upset.
+*** Error code 1
+
+Stop.
+make: stopped in unit-tests
+simple.1
+simple.1
+simple.2
+simple.2
+recursive.1.1.*
+recursive.1.1.*
+recursive.1.1.*
+recursive.1.1.*
+recursive.1.99
+recursive.1.99
+recursive.2.1.*
+recursive.2.1.*
+recursive.2.1.*
+recursive.2.1.*
+recursive.2.99
+recursive.2.99
+shared.0
+shared.0
+shared.1.99
+shared.1.99
+shared.2.1
+shared.2.1
+shared.2.99
+shared.2.99
+make: Graph cycles through `cycle.2.99'
+make: Graph cycles through `cycle.2.98'
+make: Graph cycles through `cycle.2.97'
+cycle.1.99
+cycle.1.99
+x=one
+x="two and three"
+x=four
+x="five"
+x=-I/this
+x=-I"This or that"
+x=-Ithat
+x="-DTHIS=\"this and that\""
+cfl=-I/this -I"This or that" -Ithat "-DTHIS=\"this and that\""
+a=one b="two and three"
+a=four b="five"
+a=ONE b="TWO AND THREE"
+a=FOUR b="FIVE"
+We expect an error next:
+make: "forloop" line 38: Wrong number of words (9) in .for substitution list with 2 vars
+make: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+OK
+.for with :S;... OK
+b2af338b
+3360ac65
+7747f046
+9ca87054
+880fe816
+208fcbd3
+d5d376eb
+de41416c
+Expect: Unknown modifier 'Z'
+make: Unknown modifier 'Z'
+VAR:Z=
+Expect: Unknown modifier 'Z'
+make: Unknown modifier 'Z'
+VAR:Z=
+Expect: Unclosed variable specification for VAR
+make: Unclosed variable specification (expecting '}') for "VAR" (value "Thevariable") modifier S
+VAR:S,V,v,=Thevariable
+Expect: Unclosed variable specification for VAR
+make: Unclosed variable specification after complex modifier (expecting '}') for VAR
+VAR:S,V,v,=Thevariable
+Expect: Unclosed substitution for VAR (, missing)
+make: Unclosed substitution for VAR (, missing)
+VAR:S,V,v=
+LIB=a X_LIBS:M${LIB${LIB:tu}} is "/tmp/liba.a"
+LIB=a X_LIBS:M*/lib${LIB}.a is "/tmp/liba.a"
+LIB=a X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBA.A"
+LIB=b X_LIBS:M${LIB${LIB:tu}} is ""
+LIB=b X_LIBS:M*/lib${LIB}.a is ""
+LIB=b X_LIBS:M*/lib${LIB}.a:tu is ""
+LIB=c X_LIBS:M${LIB${LIB:tu}} is ""
+LIB=c X_LIBS:M*/lib${LIB}.a is ""
+LIB=c X_LIBS:M*/lib${LIB}.a:tu is ""
+LIB=d X_LIBS:M${LIB${LIB:tu}} is "/tmp/libd.a"
+LIB=d X_LIBS:M*/lib${LIB}.a is "/tmp/libd.a"
+LIB=d X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBD.A"
+LIB=e X_LIBS:M${LIB${LIB:tu}} is "/tmp/libe.a"
+LIB=e X_LIBS:M*/lib${LIB}.a is "/tmp/libe.a"
+LIB=e X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBE.A"
+Mscanner=OK
+path=':/bin:/tmp::/:.:/no/such/dir:.'
+path='/bin:/tmp:/:/no/such/dir'
+path='/bin:/tmp:/:/no/such/dir'
+path='/bin':'/tmp':'/':'/no/such/dir'
+path='/bin':'/tmp':'/':'/no/such/dir'
+path_/usr/xbin=/opt/xbin/
+paths=/bin /tmp / /no/such/dir /opt/xbin
+PATHS=/BIN /TMP / /NO/SUCH/DIR /OPT/XBIN
+The answer is 42
+LIST = one two three four five six seven eight nine ten
+LIST:O = eight five four nine one seven six ten three two
+LIST:Ox = Ok
+LIST:O:Ox = Ok
+LISTX = Ok
+LISTSX = Ok
+make: Bad modifier `:OX' for LIST
+BADMOD 1 = }
+make: Bad modifier `:OxXX' for LIST
+BADMOD 2 = XX}
+LIST="one two three four five six"
+LIST:ts,="one,two,three,four,five,six"
+LIST:ts/:tu="ONE/TWO/THREE/FOUR/FIVE/SIX"
+LIST:ts::tu="ONE:TWO:THREE:FOUR:FIVE:SIX"
+LIST:ts:tu="ONETWOTHREEFOURFIVESIX"
+LIST:tu:ts/="ONE/TWO/THREE/FOUR/FIVE/SIX"
+LIST:ts:="one:two:three:four:five:six"
+LIST:ts="onetwothreefourfivesix"
+LIST:ts:S/two/2/="one2threefourfivesix"
+LIST:S/two/2/:ts="one2threefourfivesix"
+LIST:ts/:S/two/2/="one/2/three/four/five/six"
+Pretend the '/' in '/n' etc. below are back-slashes.
+LIST:ts/n="one
+two
+three
+four
+five
+six"
+LIST:ts/t="one two three four five six"
+LIST:ts/012:tu="ONE
+TWO
+THREE
+FOUR
+FIVE
+SIX"
+make: Bad modifier `:tx' for LIST
+LIST:tx="}"
+make: Bad modifier `:ts\x' for LIST
+LIST:ts/x:tu="\x:tu}"
+FU_mod-ts="a/b/cool"
+FU_mod-ts:ts:T="cool" == cool?
+B.${AAA:ts}="Baaa" == Baaa?
+make: Bad modifier `:[]' for LIST
+LIST:[]="" is an error
+LIST:[0]="one two three four five six"
+LIST:[0x0]="one two three four five six"
+LIST:[000]="one two three four five six"
+LIST:[*]="one two three four five six"
+LIST:[@]="one two three four five six"
+LIST:[0]:C/ /,/="one,two three four five six"
+LIST:[0]:C/ /,/g="one,two,three,four,five,six"
+LIST:[0]:C/ /,/1g="one,two,three,four,five,six"
+LIST:[*]:C/ /,/="one,two three four five six"
+LIST:[*]:C/ /,/g="one,two,three,four,five,six"
+LIST:[*]:C/ /,/1g="one,two,three,four,five,six"
+LIST:[@]:C/ /,/="one two three four five six"
+LIST:[@]:C/ /,/g="one two three four five six"
+LIST:[@]:C/ /,/1g="one two three four five six"
+LIST:[@]:[0]:C/ /,/="one,two three four five six"
+LIST:[0]:[@]:C/ /,/="one two three four five six"
+LIST:[@]:[*]:C/ /,/="one,two three four five six"
+LIST:[*]:[@]:C/ /,/="one two three four five six"
+EMPTY=""
+EMPTY:[#]="1" == 1 ?
+ESCAPEDSPACE="\ "
+ESCAPEDSPACE:[#]="1" == 1 ?
+REALLYSPACE=" "
+REALLYSPACE:[#]="1" == 1 ?
+LIST:[#]="6"
+LIST:[0]:[#]="1" == 1 ?
+LIST:[*]:[#]="1" == 1 ?
+LIST:[@]:[#]="6"
+LIST:[1]:[#]="1"
+LIST:[1..3]:[#]="3"
+EMPTY:[1]=""
+ESCAPEDSPACE="\ "
+ESCAPEDSPACE:[1]="\ "
+REALLYSPACE=" "
+REALLYSPACE:[1]="" == "" ?
+REALLYSPACE:[*]:[1]=" " == " " ?
+LIST:[1]="one"
+make: Bad modifier `:[1.]' for LIST
+LIST:[1.]="" is an error
+make: Bad modifier `:[1].' for LIST
+LIST:[1].="}" is an error
+LIST:[2]="two"
+LIST:[6]="six"
+LIST:[7]=""
+LIST:[999]=""
+make: Bad modifier `:[-]' for LIST
+LIST:[-]="" is an error
+make: Bad modifier `:[--]' for LIST
+LIST:[--]="" is an error
+LIST:[-1]="six"
+LIST:[-2]="five"
+LIST:[-6]="one"
+LIST:[-7]=""
+LIST:[-999]=""
+LONGLIST:[17]="17"
+LONGLIST:[0x11]="17"
+LONGLIST:[021]="17"
+LIST:[0]:[1]="one two three four five six"
+LIST:[*]:[1]="one two three four five six"
+LIST:[@]:[1]="one"
+LIST:[0]:[2]=""
+LIST:[*]:[2]=""
+LIST:[@]:[2]="two"
+LIST:[*]:C/ /,/:[2]=""
+LIST:[*]:C/ /,/:[*]:[2]=""
+LIST:[*]:C/ /,/:[@]:[2]="three"
+make: Bad modifier `:[1.]' for LIST
+LIST:[1.]="" is an error
+make: Bad modifier `:[1..]' for LIST
+LIST:[1..]="" is an error
+LIST:[1..1]="one"
+make: Bad modifier `:[1..1.]' for LIST
+LIST:[1..1.]="" is an error
+LIST:[1..2]="one two"
+LIST:[2..1]="two one"
+LIST:[3..-2]="three four five"
+LIST:[-4..4]="three four"
+make: Bad modifier `:[0..1]' for LIST
+LIST:[0..1]="" is an error
+make: Bad modifier `:[-1..0]' for LIST
+LIST:[-1..0]="" is an error
+LIST:[-1..1]="six five four three two one"
+LIST:[0..0]="one two three four five six"
+LIST:[3..99]="three four five six"
+LIST:[-3..-99]="four three two one"
+LIST:[-99..-3]="one two three four"
+HASH="#" == "#" ?
+LIST:[${HASH}]="6"
+LIST:[${ZERO}]="one two three four five six"
+LIST:[${ZERO}x${ONE}]="one"
+LIST:[${ONE}]="one"
+LIST:[${MINUSONE}]="six"
+LIST:[${STAR}]="one two three four five six"
+LIST:[${AT}]="one two three four five six"
+make: Bad modifier `:[${EMPTY' for LIST
+LIST:[${EMPTY}]="" is an error
+LIST:[${LONGLIST:[21]:S/2//}]="one"
+LIST:[${LIST:[#]}]="six"
+LIST:[${LIST:[${HASH}]}]="six"
+LIST:S/ /,/="one two three four five six"
+LIST:S/ /,/W="one,two three four five six"
+LIST:S/ /,/gW="one,two,three,four,five,six"
+EMPTY:S/^/,/=","
+EMPTY:S/^/,/W=","
+LIST:C/ /,/="one two three four five six"
+LIST:C/ /,/W="one,two three four five six"
+LIST:C/ /,/gW="one,two,three,four,five,six"
+EMPTY:C/^/,/=","
+EMPTY:C/^/,/W=","
+LIST:tW="one two three four five six"
+LIST:tw="one two three four five six"
+LIST:tW:C/ /,/="one,two three four five six"
+LIST:tW:C/ /,/g="one,two,three,four,five,six"
+LIST:tW:C/ /,/1g="one,two,three,four,five,six"
+LIST:tw:C/ /,/="one two three four five six"
+LIST:tw:C/ /,/g="one two three four five six"
+LIST:tw:C/ /,/1g="one two three four five six"
+LIST:tw:tW:C/ /,/="one,two three four five six"
+LIST:tW:tw:C/ /,/="one two three four five six"
+.TARGET="phony" .PREFIX="phony" .IMPSRC=""
+.TARGET="all" .PREFIX="all" .IMPSRC=""
+.TARGET="ok" .PREFIX="ok" .IMPSRC=""
+.TARGET="also.ok" .PREFIX="also.ok" .IMPSRC=""
+.TARGET="bug" .PREFIX="bug" .IMPSRC=""
+Posix says we should execute the command as if run by system(3)
+Expect 'Hello,' and 'World!'
+Hello,
+World!
+a command
+a command prefixed by '+' executes even with -n
+another command
+make -n
+echo a command
+echo "a command prefixed by '+' executes even with -n"
+a command prefixed by '+' executes even with -n
+echo another command
+make -n -j1
+{ echo a command
+} || exit $?
+echo "a command prefixed by '+' executes even with -n"
+a command prefixed by '+' executes even with -n
+{ echo another command
+} || exit $?
+Now we expect an error...
+*** Error code 1 (continuing)
+`all' not remade because of errors.
+V.i386 ?= OK
+FOOBAR =
+FOOBAR = foobar fubar
+fun
+fun
+fun
+In the Sun
+The answer is unknown
+The answer is unknown
+The answer is empty
+The answer is known
+The answer is
+The answer is empty
+The answer is known
+The answer is 42
+The answer is 42
+UT_DOLLAR=This is $UT_FU
+UT_FU=fubar
+UT_TEST=unexport
+UT_TEST=unexport-env
+default FU=<v>fu</v> FOO=<v>foo</v> VAR=<v></v>
+two FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v>
+three FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v>
+four FU=<v>bar</v> FOO=<v>goo</v> VAR=<v>Internal</v>
+five FU=<v>bar</v> FOO=<v>goo</v> VAR=<v>Internal</v>
+five v=is x k=is x
+six v=is y k=is y
+show-v v=override k=override
+*** Error code 1 (ignored)
+*** Error code 1 (ignored)
diff --git a/external/bsd/bmake/dist/unit-tests/unexport b/external/bsd/bmake/dist/unit-tests/unexport
new file mode 100644
index 0000000..fb40d0c
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/unexport
@@ -0,0 +1,8 @@
+# $Id: unexport,v 1.1.1.1 2009/11/19 00:31:11 sjg Exp $
+
+# pick up a bunch of exported vars
+.include "export"
+
+.unexport UT_ZOO UT_FOO
+
+UT_TEST = unexport
diff --git a/external/bsd/bmake/dist/unit-tests/unexport-env b/external/bsd/bmake/dist/unit-tests/unexport-env
new file mode 100644
index 0000000..f6a2ff9
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/unexport-env
@@ -0,0 +1,14 @@
+# $Id: unexport-env,v 1.1.1.1 2009/11/19 00:31:11 sjg Exp $
+
+# pick up a bunch of exported vars
+.include "export"
+
+# an example of setting up a minimal environment.
+PATH = /bin:/usr/bin:/sbin:/usr/sbin
+
+# now clobber the environment to just PATH and UT_TEST
+UT_TEST = unexport-env
+
+# this removes everything
+.unexport-env
+.export PATH UT_TEST
diff --git a/external/bsd/bmake/dist/unit-tests/varcmd b/external/bsd/bmake/dist/unit-tests/varcmd
new file mode 100644
index 0000000..a58e014
--- /dev/null
+++ b/external/bsd/bmake/dist/unit-tests/varcmd
@@ -0,0 +1,49 @@
+# $Id: varcmd,v 1.3 2008/05/15 04:30:47 sjg Exp $
+#
+# Test behaviour of recursive make and vars set on command line.
+
+FU=fu
+FOO?=foo
+.if !empty(.TARGETS)
+TAG=${.TARGETS}
+.endif
+TAG?=default
+
+all: one
+
+show:
+ @echo "${TAG} FU=<v>${FU}</v> FOO=<v>${FOO}</v> VAR=<v>${VAR}</v>"
+
+one: show
+ @${.MAKE} -f ${MAKEFILE} FU=bar FOO=goo two
+
+two: show
+ @${.MAKE} -f ${MAKEFILE} three
+
+three: show
+ @${.MAKE} -f ${MAKEFILE} four
+
+
+.ifmake four
+VAR=Internal
+.MAKEOVERRIDES+= VAR
+.endif
+
+four: show
+ @${.MAKE} -f ${MAKEFILE} five
+
+M = x
+V.y = is y
+V.x = is x
+V := ${V.$M}
+K := ${V}
+
+show-v:
+ @echo '${TAG} v=${V} k=${K}'
+
+five: show show-v
+ @${.MAKE} -f ${MAKEFILE} M=y six
+
+six: show-v
+ @${.MAKE} -f ${MAKEFILE} V=override show-v
+
diff --git a/external/bsd/bmake/dist/util.c b/external/bsd/bmake/dist/util.c
new file mode 100644
index 0000000..a63fd33
--- /dev/null
+++ b/external/bsd/bmake/dist/util.c
@@ -0,0 +1,619 @@
+/* $NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $ */
+
+/*
+ * Missing stuff from OS's
+ *
+ * $Id: util.c,v 1.32 2012/06/06 20:08:44 sjg Exp $
+ */
+
+#include "make.h"
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $";
+#else
+#ifndef lint
+__RCSID("$NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $");
+#endif
+#endif
+
+#include <errno.h>
+#include <time.h>
+#include <signal.h>
+
+#if !defined(HAVE_STRERROR)
+extern int errno, sys_nerr;
+extern char *sys_errlist[];
+
+char *
+strerror(int e)
+{
+ static char buf[100];
+ if (e < 0 || e >= sys_nerr) {
+ snprintf(buf, sizeof(buf), "Unknown error %d", e);
+ return buf;
+ }
+ else
+ return sys_errlist[e];
+}
+#endif
+
+#if !defined(HAVE_GETENV) || !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV)
+extern char **environ;
+
+static char *
+findenv(const char *name, int *offset)
+{
+ size_t i, len;
+ char *p, *q;
+
+ len = strlen(name);
+ for (i = 0; (q = environ[i]); i++) {
+ p = strchr(q, '=');
+ if (p == NULL || p - q != len)
+ continue;
+ if (strncmp(name, q, len) == 0) {
+ *offset = i;
+ return q + len + 1;
+ }
+ }
+ *offset = i;
+ return NULL;
+}
+
+char *
+getenv(const char *name)
+{
+ int offset;
+
+ return(findenv(name, &offset));
+}
+
+int
+unsetenv(const char *name)
+{
+ char **p;
+ int offset;
+
+ if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ while (findenv(name, &offset)) { /* if set multiple times */
+ for (p = &environ[offset];; ++p)
+ if (!(*p = *(p + 1)))
+ break;
+ }
+ return 0;
+}
+
+int
+setenv(const char *name, const char *value, int rewrite)
+{
+ char *c, **newenv;
+ const char *cc;
+ size_t l_value, size;
+ int offset;
+
+ if (name == NULL || value == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*value == '=') /* no `=' in value */
+ ++value;
+ l_value = strlen(value);
+
+ /* find if already exists */
+ if ((c = findenv(name, &offset))) {
+ if (!rewrite)
+ return 0;
+ if (strlen(c) >= l_value) /* old larger; copy over */
+ goto copy;
+ } else { /* create new slot */
+ size = sizeof(char *) * (offset + 2);
+ if (savedEnv == environ) { /* just increase size */
+ if ((newenv = realloc(savedEnv, size)) == NULL)
+ return -1;
+ savedEnv = newenv;
+ } else { /* get new space */
+ /*
+ * We don't free here because we don't know if
+ * the first allocation is valid on all OS's
+ */
+ if ((savedEnv = malloc(size)) == NULL)
+ return -1;
+ (void)memcpy(savedEnv, environ, size - sizeof(char *));
+ }
+ environ = savedEnv;
+ environ[offset + 1] = NULL;
+ }
+ for (cc = name; *cc && *cc != '='; ++cc) /* no `=' in name */
+ continue;
+ size = cc - name;
+ /* name + `=' + value */
+ if ((environ[offset] = malloc(size + l_value + 2)) == NULL)
+ return -1;
+ c = environ[offset];
+ (void)memcpy(c, name, size);
+ c += size;
+ *c++ = '=';
+copy:
+ (void)memcpy(c, value, l_value + 1);
+ return 0;
+}
+
+#ifdef TEST
+int
+main(int argc, char *argv[])
+{
+ setenv(argv[1], argv[2], 0);
+ printf("%s\n", getenv(argv[1]));
+ unsetenv(argv[1]);
+ printf("%s\n", getenv(argv[1]));
+ return 0;
+}
+#endif
+
+#endif
+
+
+#if defined(__hpux__) || defined(__hpux)
+/* strrcpy():
+ * Like strcpy, going backwards and returning the new pointer
+ */
+static char *
+strrcpy(char *ptr, char *str)
+{
+ int len = strlen(str);
+
+ while (len)
+ *--ptr = str[--len];
+
+ return (ptr);
+} /* end strrcpy */
+
+
+char *sys_siglist[] = {
+ "Signal 0",
+ "Hangup", /* SIGHUP */
+ "Interrupt", /* SIGINT */
+ "Quit", /* SIGQUIT */
+ "Illegal instruction", /* SIGILL */
+ "Trace/BPT trap", /* SIGTRAP */
+ "IOT trap", /* SIGIOT */
+ "EMT trap", /* SIGEMT */
+ "Floating point exception", /* SIGFPE */
+ "Killed", /* SIGKILL */
+ "Bus error", /* SIGBUS */
+ "Segmentation fault", /* SIGSEGV */
+ "Bad system call", /* SIGSYS */
+ "Broken pipe", /* SIGPIPE */
+ "Alarm clock", /* SIGALRM */
+ "Terminated", /* SIGTERM */
+ "User defined signal 1", /* SIGUSR1 */
+ "User defined signal 2", /* SIGUSR2 */
+ "Child exited", /* SIGCLD */
+ "Power-fail restart", /* SIGPWR */
+ "Virtual timer expired", /* SIGVTALRM */
+ "Profiling timer expired", /* SIGPROF */
+ "I/O possible", /* SIGIO */
+ "Window size changes", /* SIGWINDOW */
+ "Stopped (signal)", /* SIGSTOP */
+ "Stopped", /* SIGTSTP */
+ "Continued", /* SIGCONT */
+ "Stopped (tty input)", /* SIGTTIN */
+ "Stopped (tty output)", /* SIGTTOU */
+ "Urgent I/O condition", /* SIGURG */
+ "Remote lock lost (NFS)", /* SIGLOST */
+ "Signal 31", /* reserved */
+ "DIL signal" /* SIGDIL */
+};
+#endif /* __hpux__ || __hpux */
+
+#if defined(__hpux__) || defined(__hpux)
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <sys/signal.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+int
+killpg(int pid, int sig)
+{
+ return kill(-pid, sig);
+}
+
+#if !defined(__hpux__) && !defined(__hpux)
+void
+srandom(long seed)
+{
+ srand48(seed);
+}
+
+long
+random(void)
+{
+ return lrand48();
+}
+#endif
+
+#if !defined(__hpux__) && !defined(__hpux)
+int
+utimes(char *file, struct timeval tvp[2])
+{
+ struct utimbuf t;
+
+ t.actime = tvp[0].tv_sec;
+ t.modtime = tvp[1].tv_sec;
+ return(utime(file, &t));
+}
+#endif
+
+#if !defined(BSD) && !defined(d_fileno)
+# define d_fileno d_ino
+#endif
+
+#ifndef DEV_DEV_COMPARE
+# define DEV_DEV_COMPARE(a, b) ((a) == (b))
+#endif
+#define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/')))
+#define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
+
+char *
+getwd(char *pathname)
+{
+ DIR *dp;
+ struct dirent *d;
+ extern int errno;
+
+ struct stat st_root, st_cur, st_next, st_dotdot;
+ char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
+ char *pathptr, *nextpathptr, *cur_name_add;
+
+ /* find the inode of root */
+ if (stat("/", &st_root) == -1) {
+ (void)sprintf(pathname,
+ "getwd: Cannot stat \"/\" (%s)", strerror(errno));
+ return NULL;
+ }
+ pathbuf[MAXPATHLEN - 1] = '\0';
+ pathptr = &pathbuf[MAXPATHLEN - 1];
+ nextpathbuf[MAXPATHLEN - 1] = '\0';
+ cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
+
+ /* find the inode of the current directory */
+ if (lstat(".", &st_cur) == -1) {
+ (void)sprintf(pathname,
+ "getwd: Cannot stat \".\" (%s)", strerror(errno));
+ return NULL;
+ }
+ nextpathptr = strrcpy(nextpathptr, "../");
+
+ /* Descend to root */
+ for (;;) {
+
+ /* look if we found root yet */
+ if (st_cur.st_ino == st_root.st_ino &&
+ DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
+ (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
+ return (pathname);
+ }
+
+ /* open the parent directory */
+ if (stat(nextpathptr, &st_dotdot) == -1) {
+ (void)sprintf(pathname,
+ "getwd: Cannot stat directory \"%s\" (%s)",
+ nextpathptr, strerror(errno));
+ return NULL;
+ }
+ if ((dp = opendir(nextpathptr)) == NULL) {
+ (void)sprintf(pathname,
+ "getwd: Cannot open directory \"%s\" (%s)",
+ nextpathptr, strerror(errno));
+ return NULL;
+ }
+
+ /* look in the parent for the entry with the same inode */
+ if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
+ /* Parent has same device. No need to stat every member */
+ for (d = readdir(dp); d != NULL; d = readdir(dp))
+ if (d->d_fileno == st_cur.st_ino)
+ break;
+ }
+ else {
+ /*
+ * Parent has a different device. This is a mount point so we
+ * need to stat every member
+ */
+ for (d = readdir(dp); d != NULL; d = readdir(dp)) {
+ if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
+ continue;
+ (void)strcpy(cur_name_add, d->d_name);
+ if (lstat(nextpathptr, &st_next) == -1) {
+ (void)sprintf(pathname,
+ "getwd: Cannot stat \"%s\" (%s)",
+ d->d_name, strerror(errno));
+ (void)closedir(dp);
+ return NULL;
+ }
+ /* check if we found it yet */
+ if (st_next.st_ino == st_cur.st_ino &&
+ DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
+ break;
+ }
+ }
+ if (d == NULL) {
+ (void)sprintf(pathname,
+ "getwd: Cannot find \".\" in \"..\"");
+ (void)closedir(dp);
+ return NULL;
+ }
+ st_cur = st_dotdot;
+ pathptr = strrcpy(pathptr, d->d_name);
+ pathptr = strrcpy(pathptr, "/");
+ nextpathptr = strrcpy(nextpathptr, "../");
+ (void)closedir(dp);
+ *cur_name_add = '\0';
+ }
+} /* end getwd */
+
+#endif /* __hpux */
+
+#if !defined(HAVE_GETCWD)
+char *
+getcwd(path, sz)
+ char *path;
+ int sz;
+{
+ return getwd(path);
+}
+#endif
+
+/* force posix signals */
+void (*
+bmake_signal(int s, void (*a)(int)))(int)
+{
+ struct sigaction sa, osa;
+
+ sa.sa_handler = a;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+
+ if (sigaction(s, &sa, &osa) == -1)
+ return SIG_ERR;
+ else
+ return osa.sa_handler;
+}
+
+#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_VASPRINTF)
+#include <stdarg.h>
+#endif
+
+#if !defined(HAVE_VSNPRINTF)
+#if !defined(__osf__)
+#ifdef _IOSTRG
+#define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */
+#else
+#if 0
+#define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */
+#endif
+#endif /* _IOSTRG */
+#endif /* __osf__ */
+
+int
+vsnprintf(char *s, size_t n, const char *fmt, va_list args)
+{
+#ifdef STRFLAG
+ FILE fakebuf;
+
+ fakebuf._flag = STRFLAG;
+ /*
+ * Some os's are char * _ptr, others are unsigned char *_ptr...
+ * We cast to void * to make everyone happy.
+ */
+ fakebuf._ptr = (void *)s;
+ fakebuf._cnt = n-1;
+ fakebuf._file = -1;
+ _doprnt(fmt, args, &fakebuf);
+ fakebuf._cnt++;
+ putc('\0', &fakebuf);
+ if (fakebuf._cnt<0)
+ fakebuf._cnt = 0;
+ return (n-fakebuf._cnt-1);
+#else
+#ifndef _PATH_DEVNULL
+# define _PATH_DEVNULL "/dev/null"
+#endif
+ /*
+ * Rats... we don't want to clobber anything...
+ * do a printf to /dev/null to see how much space we need.
+ */
+ static FILE *nullfp;
+ int need = 0; /* XXX what's a useful error return? */
+
+ if (!nullfp)
+ nullfp = fopen(_PATH_DEVNULL, "w");
+ if (nullfp) {
+ need = vfprintf(nullfp, fmt, args);
+ if (need < n)
+ (void)vsprintf(s, fmt, args);
+ }
+ return need;
+#endif
+}
+#endif
+
+#if !defined(HAVE_SNPRINTF)
+int
+snprintf(char *s, size_t n, const char *fmt, ...)
+{
+ va_list ap;
+ int rv;
+
+ va_start(ap, fmt);
+ rv = vsnprintf(s, n, fmt, ap);
+ va_end(ap);
+ return rv;
+}
+#endif
+
+#if !defined(HAVE_STRFTIME)
+size_t
+strftime(char *buf, size_t len, const char *fmt, const struct tm *tm)
+{
+ static char months[][4] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+
+ size_t s;
+ char *b = buf;
+
+ while (*fmt) {
+ if (len == 0)
+ return buf - b;
+ if (*fmt != '%') {
+ *buf++ = *fmt++;
+ len--;
+ continue;
+ }
+ switch (*fmt++) {
+ case '%':
+ *buf++ = '%';
+ len--;
+ if (len == 0) return buf - b;
+ /*FALLTHROUGH*/
+ case '\0':
+ *buf = '%';
+ s = 1;
+ break;
+ case 'k':
+ s = snprintf(buf, len, "%d", tm->tm_hour);
+ break;
+ case 'M':
+ s = snprintf(buf, len, "%02d", tm->tm_min);
+ break;
+ case 'S':
+ s = snprintf(buf, len, "%02d", tm->tm_sec);
+ break;
+ case 'b':
+ if (tm->tm_mon >= 12)
+ return buf - b;
+ s = snprintf(buf, len, "%s", months[tm->tm_mon]);
+ break;
+ case 'd':
+ s = snprintf(buf, len, "%02d", tm->tm_mday);
+ break;
+ case 'Y':
+ s = snprintf(buf, len, "%d", 1900 + tm->tm_year);
+ break;
+ default:
+ s = snprintf(buf, len, "Unsupported format %c",
+ fmt[-1]);
+ break;
+ }
+ buf += s;
+ len -= s;
+ }
+}
+#endif
+
+#if !defined(HAVE_KILLPG)
+#if !defined(__hpux__) && !defined(__hpux)
+int
+killpg(int pid, int sig)
+{
+ return kill(-pid, sig);
+}
+#endif
+#endif
+
+#if !defined(HAVE_WARNX)
+static void
+vwarnx(const char *fmt, va_list args)
+{
+ fprintf(stderr, "%s: ", progname);
+ if ((fmt)) {
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, ": ");
+ }
+}
+#endif
+
+#if !defined(HAVE_WARN)
+static void
+vwarn(const char *fmt, va_list args)
+{
+ vwarnx(fmt, args);
+ fprintf(stderr, "%s\n", strerror(errno));
+}
+#endif
+
+#if !defined(HAVE_ERR)
+static void
+verr(int eval, const char *fmt, va_list args)
+{
+ vwarn(fmt, args);
+ exit(eval);
+}
+#endif
+
+#if !defined(HAVE_ERRX)
+static void
+verrx(int eval, const char *fmt, va_list args)
+{
+ vwarnx(fmt, args);
+ exit(eval);
+}
+#endif
+
+#if !defined(HAVE_ERR)
+void
+err(int eval, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ verr(eval, fmt, ap);
+ va_end(ap);
+}
+#endif
+
+#if !defined(HAVE_ERRX)
+void
+errx(int eval, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ verrx(eval, fmt, ap);
+ va_end(ap);
+}
+#endif
+
+#if !defined(HAVE_WARN)
+void
+warn(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwarn(fmt, ap);
+ va_end(ap);
+}
+#endif
+
+#if !defined(HAVE_WARNX)
+void
+warnx(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vwarnx(fmt, ap);
+ va_end(ap);
+}
+#endif
diff --git a/external/bsd/bmake/dist/var.c b/external/bsd/bmake/dist/var.c
new file mode 100644
index 0000000..e958a36
--- /dev/null
+++ b/external/bsd/bmake/dist/var.c
@@ -0,0 +1,4196 @@
+/* $NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1989 by Berkeley Softworks
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Adam de Boor.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MAKE_NATIVE
+static char rcsid[] = "$NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $";
+#else
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
+#else
+__RCSID("$NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $");
+#endif
+#endif /* not lint */
+#endif
+
+/*-
+ * var.c --
+ * Variable-handling functions
+ *
+ * Interface:
+ * Var_Set Set the value of a variable in the given
+ * context. The variable is created if it doesn't
+ * yet exist. The value and variable name need not
+ * be preserved.
+ *
+ * Var_Append Append more characters to an existing variable
+ * in the given context. The variable needn't
+ * exist already -- it will be created if it doesn't.
+ * A space is placed between the old value and the
+ * new one.
+ *
+ * Var_Exists See if a variable exists.
+ *
+ * Var_Value Return the value of a variable in a context or
+ * NULL if the variable is undefined.
+ *
+ * Var_Subst Substitute named variable, or all variables if
+ * NULL in a string using
+ * the given context as the top-most one. If the
+ * third argument is non-zero, Parse_Error is
+ * called if any variables are undefined.
+ *
+ * Var_Parse Parse a variable expansion from a string and
+ * return the result and the number of characters
+ * consumed.
+ *
+ * Var_Delete Delete a variable in a context.
+ *
+ * Var_Init Initialize this module.
+ *
+ * Debugging:
+ * Var_Dump Print out all variables defined in the given
+ * context.
+ *
+ * XXX: There's a lot of duplication in these functions.
+ */
+
+#include <sys/stat.h>
+#ifndef NO_REGEX
+#include <sys/types.h>
+#include <regex.h>
+#endif
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <time.h>
+
+#include "make.h"
+#include "buf.h"
+#include "dir.h"
+#include "job.h"
+
+/*
+ * This lets us tell if we have replaced the original environ
+ * (which we cannot free).
+ */
+char **savedEnv = NULL;
+
+/*
+ * This is a harmless return value for Var_Parse that can be used by Var_Subst
+ * to determine if there was an error in parsing -- easier than returning
+ * a flag, as things outside this module don't give a hoot.
+ */
+char var_Error[] = "";
+
+/*
+ * Similar to var_Error, but returned when the 'errnum' flag for Var_Parse is
+ * set false. Why not just use a constant? Well, gcc likes to condense
+ * identical string instances...
+ */
+static char varNoError[] = "";
+
+/*
+ * Internally, variables are contained in four different contexts.
+ * 1) the environment. They may not be changed. If an environment
+ * variable is appended-to, the result is placed in the global
+ * context.
+ * 2) the global context. Variables set in the Makefile are located in
+ * the global context. It is the penultimate context searched when
+ * substituting.
+ * 3) the command-line context. All variables set on the command line
+ * are placed in this context. They are UNALTERABLE once placed here.
+ * 4) the local context. Each target has associated with it a context
+ * list. On this list are located the structures describing such
+ * local variables as $(@) and $(*)
+ * The four contexts are searched in the reverse order from which they are
+ * listed.
+ */
+GNode *VAR_GLOBAL; /* variables from the makefile */
+GNode *VAR_CMD; /* variables defined on the command-line */
+
+#define FIND_CMD 0x1 /* look in VAR_CMD when searching */
+#define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */
+#define FIND_ENV 0x4 /* look in the environment also */
+
+typedef struct Var {
+ char *name; /* the variable's name */
+ Buffer val; /* its value */
+ int flags; /* miscellaneous status flags */
+#define VAR_IN_USE 1 /* Variable's value currently being used.
+ * Used to avoid recursion */
+#define VAR_FROM_ENV 2 /* Variable comes from the environment */
+#define VAR_JUNK 4 /* Variable is a junk variable that
+ * should be destroyed when done with
+ * it. Used by Var_Parse for undefined,
+ * modified variables */
+#define VAR_KEEP 8 /* Variable is VAR_JUNK, but we found
+ * a use for it in some modifier and
+ * the value is therefore valid */
+#define VAR_EXPORTED 16 /* Variable is exported */
+#define VAR_REEXPORT 32 /* Indicate if var needs re-export.
+ * This would be true if it contains $'s
+ */
+#define VAR_FROM_CMD 64 /* Variable came from command line */
+} Var;
+
+/*
+ * Exporting vars is expensive so skip it if we can
+ */
+#define VAR_EXPORTED_NONE 0
+#define VAR_EXPORTED_YES 1
+#define VAR_EXPORTED_ALL 2
+static int var_exportedVars = VAR_EXPORTED_NONE;
+/*
+ * We pass this to Var_Export when doing the initial export
+ * or after updating an exported var.
+ */
+#define VAR_EXPORT_PARENT 1
+
+/* Var*Pattern flags */
+#define VAR_SUB_GLOBAL 0x01 /* Apply substitution globally */
+#define VAR_SUB_ONE 0x02 /* Apply substitution to one word */
+#define VAR_SUB_MATCHED 0x04 /* There was a match */
+#define VAR_MATCH_START 0x08 /* Match at start of word */
+#define VAR_MATCH_END 0x10 /* Match at end of word */
+#define VAR_NOSUBST 0x20 /* don't expand vars in VarGetPattern */
+
+/* Var_Set flags */
+#define VAR_NO_EXPORT 0x01 /* do not export */
+
+typedef struct {
+ /*
+ * The following fields are set by Var_Parse() when it
+ * encounters modifiers that need to keep state for use by
+ * subsequent modifiers within the same variable expansion.
+ */
+ Byte varSpace; /* Word separator in expansions */
+ Boolean oneBigWord; /* TRUE if we will treat the variable as a
+ * single big word, even if it contains
+ * embedded spaces (as opposed to the
+ * usual behaviour of treating it as
+ * several space-separated words). */
+} Var_Parse_State;
+
+/* struct passed as 'void *' to VarSubstitute() for ":S/lhs/rhs/",
+ * to VarSYSVMatch() for ":lhs=rhs". */
+typedef struct {
+ const char *lhs; /* String to match */
+ int leftLen; /* Length of string */
+ const char *rhs; /* Replacement string (w/ &'s removed) */
+ int rightLen; /* Length of replacement */
+ int flags;
+} VarPattern;
+
+/* struct passed as 'void *' to VarLoopExpand() for ":@tvar@str@" */
+typedef struct {
+ GNode *ctxt; /* variable context */
+ char *tvar; /* name of temp var */
+ int tvarLen;
+ char *str; /* string to expand */
+ int strLen;
+ int errnum; /* errnum for not defined */
+} VarLoop_t;
+
+#ifndef NO_REGEX
+/* struct passed as 'void *' to VarRESubstitute() for ":C///" */
+typedef struct {
+ regex_t re;
+ int nsub;
+ regmatch_t *matches;
+ char *replace;
+ int flags;
+} VarREPattern;
+#endif
+
+/* struct passed to VarSelectWords() for ":[start..end]" */
+typedef struct {
+ int start; /* first word to select */
+ int end; /* last word to select */
+} VarSelectWords_t;
+
+static Var *VarFind(const char *, GNode *, int);
+static void VarAdd(const char *, const char *, GNode *);
+static Boolean VarHead(GNode *, Var_Parse_State *,
+ char *, Boolean, Buffer *, void *);
+static Boolean VarTail(GNode *, Var_Parse_State *,
+ char *, Boolean, Buffer *, void *);
+static Boolean VarSuffix(GNode *, Var_Parse_State *,
+ char *, Boolean, Buffer *, void *);
+static Boolean VarRoot(GNode *, Var_Parse_State *,
+ char *, Boolean, Buffer *, void *);
+static Boolean VarMatch(GNode *, Var_Parse_State *,
+ char *, Boolean, Buffer *, void *);
+#ifdef SYSVVARSUB
+static Boolean VarSYSVMatch(GNode *, Var_Parse_State *,
+ char *, Boolean, Buffer *, void *);
+#endif
+static Boolean VarNoMatch(GNode *, Var_Parse_State *,
+ char *, Boolean, Buffer *, void *);
+#ifndef NO_REGEX
+static void VarREError(int, regex_t *, const char *);
+static Boolean VarRESubstitute(GNode *, Var_Parse_State *,
+ char *, Boolean, Buffer *, void *);
+#endif
+static Boolean VarSubstitute(GNode *, Var_Parse_State *,
+ char *, Boolean, Buffer *, void *);
+static Boolean VarLoopExpand(GNode *, Var_Parse_State *,
+ char *, Boolean, Buffer *, void *);
+static char *VarGetPattern(GNode *, Var_Parse_State *,
+ int, const char **, int, int *, int *,
+ VarPattern *);
+static char *VarQuote(char *);
+static char *VarChangeCase(char *, int);
+static char *VarHash(char *);
+static char *VarModify(GNode *, Var_Parse_State *,
+ const char *,
+ Boolean (*)(GNode *, Var_Parse_State *, char *, Boolean, Buffer *, void *),
+ void *);
+static char *VarOrder(const char *, const char);
+static char *VarUniq(const char *);
+static int VarWordCompare(const void *, const void *);
+static void VarPrintVar(void *);
+
+#define BROPEN '{'
+#define BRCLOSE '}'
+#define PROPEN '('
+#define PRCLOSE ')'
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarFind --
+ * Find the given variable in the given context and any other contexts
+ * indicated.
+ *
+ * Input:
+ * name name to find
+ * ctxt context in which to find it
+ * flags FIND_GLOBAL set means to look in the
+ * VAR_GLOBAL context as well. FIND_CMD set means
+ * to look in the VAR_CMD context also. FIND_ENV
+ * set means to look in the environment
+ *
+ * Results:
+ * A pointer to the structure describing the desired variable or
+ * NULL if the variable does not exist.
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+static Var *
+VarFind(const char *name, GNode *ctxt, int flags)
+{
+ Hash_Entry *var;
+ Var *v;
+
+ /*
+ * If the variable name begins with a '.', it could very well be one of
+ * the local ones. We check the name against all the local variables
+ * and substitute the short version in for 'name' if it matches one of
+ * them.
+ */
+ if (*name == '.' && isupper((unsigned char) name[1]))
+ switch (name[1]) {
+ case 'A':
+ if (!strcmp(name, ".ALLSRC"))
+ name = ALLSRC;
+ if (!strcmp(name, ".ARCHIVE"))
+ name = ARCHIVE;
+ break;
+ case 'I':
+ if (!strcmp(name, ".IMPSRC"))
+ name = IMPSRC;
+ break;
+ case 'M':
+ if (!strcmp(name, ".MEMBER"))
+ name = MEMBER;
+ break;
+ case 'O':
+ if (!strcmp(name, ".OODATE"))
+ name = OODATE;
+ break;
+ case 'P':
+ if (!strcmp(name, ".PREFIX"))
+ name = PREFIX;
+ break;
+ case 'T':
+ if (!strcmp(name, ".TARGET"))
+ name = TARGET;
+ break;
+ }
+#ifdef notyet
+ /* for compatibility with gmake */
+ if (name[0] == '^' && name[1] == '\0')
+ name = ALLSRC;
+#endif
+
+ /*
+ * First look for the variable in the given context. If it's not there,
+ * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
+ * depending on the FIND_* flags in 'flags'
+ */
+ var = Hash_FindEntry(&ctxt->context, name);
+
+ if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) {
+ var = Hash_FindEntry(&VAR_CMD->context, name);
+ }
+ if (!checkEnvFirst && (var == NULL) && (flags & FIND_GLOBAL) &&
+ (ctxt != VAR_GLOBAL))
+ {
+ var = Hash_FindEntry(&VAR_GLOBAL->context, name);
+ }
+ if ((var == NULL) && (flags & FIND_ENV)) {
+ char *env;
+
+ if ((env = getenv(name)) != NULL) {
+ int len;
+
+ v = bmake_malloc(sizeof(Var));
+ v->name = bmake_strdup(name);
+
+ len = strlen(env);
+
+ Buf_Init(&v->val, len + 1);
+ Buf_AddBytes(&v->val, len, env);
+
+ v->flags = VAR_FROM_ENV;
+ return (v);
+ } else if (checkEnvFirst && (flags & FIND_GLOBAL) &&
+ (ctxt != VAR_GLOBAL))
+ {
+ var = Hash_FindEntry(&VAR_GLOBAL->context, name);
+ if (var == NULL) {
+ return NULL;
+ } else {
+ return ((Var *)Hash_GetValue(var));
+ }
+ } else {
+ return NULL;
+ }
+ } else if (var == NULL) {
+ return NULL;
+ } else {
+ return ((Var *)Hash_GetValue(var));
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarFreeEnv --
+ * If the variable is an environment variable, free it
+ *
+ * Input:
+ * v the variable
+ * destroy true if the value buffer should be destroyed.
+ *
+ * Results:
+ * 1 if it is an environment variable 0 ow.
+ *
+ * Side Effects:
+ * The variable is free'ed if it is an environent variable.
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+VarFreeEnv(Var *v, Boolean destroy)
+{
+ if ((v->flags & VAR_FROM_ENV) == 0)
+ return FALSE;
+ free(v->name);
+ Buf_Destroy(&v->val, destroy);
+ free(v);
+ return TRUE;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarAdd --
+ * Add a new variable of name name and value val to the given context
+ *
+ * Input:
+ * name name of variable to add
+ * val value to set it to
+ * ctxt context in which to set it
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The new variable is placed at the front of the given context
+ * The name and val arguments are duplicated so they may
+ * safely be freed.
+ *-----------------------------------------------------------------------
+ */
+static void
+VarAdd(const char *name, const char *val, GNode *ctxt)
+{
+ Var *v;
+ int len;
+ Hash_Entry *h;
+
+ v = bmake_malloc(sizeof(Var));
+
+ len = val ? strlen(val) : 0;
+ Buf_Init(&v->val, len+1);
+ Buf_AddBytes(&v->val, len, val);
+
+ v->flags = 0;
+
+ h = Hash_CreateEntry(&ctxt->context, name, NULL);
+ Hash_SetValue(h, v);
+ v->name = h->name;
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Var_Delete --
+ * Remove a variable from a context.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The Var structure is removed and freed.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Var_Delete(const char *name, GNode *ctxt)
+{
+ Hash_Entry *ln;
+
+ ln = Hash_FindEntry(&ctxt->context, name);
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "%s:delete %s%s\n",
+ ctxt->name, name, ln ? "" : " (not found)");
+ }
+ if (ln != NULL) {
+ Var *v;
+
+ v = (Var *)Hash_GetValue(ln);
+ if ((v->flags & VAR_EXPORTED)) {
+ unsetenv(v->name);
+ }
+ if (strcmp(MAKE_EXPORTED, v->name) == 0) {
+ var_exportedVars = VAR_EXPORTED_NONE;
+ }
+ if (v->name != ln->name)
+ free(v->name);
+ Hash_DeleteEntry(&ctxt->context, ln);
+ Buf_Destroy(&v->val, TRUE);
+ free(v);
+ }
+}
+
+
+/*
+ * Export a var.
+ * We ignore make internal variables (those which start with '.')
+ * Also we jump through some hoops to avoid calling setenv
+ * more than necessary since it can leak.
+ * We only manipulate flags of vars if 'parent' is set.
+ */
+static int
+Var_Export1(const char *name, int parent)
+{
+ char tmp[BUFSIZ];
+ Var *v;
+ char *val = NULL;
+ int n;
+
+ if (*name == '.')
+ return 0; /* skip internals */
+ if (!name[1]) {
+ /*
+ * A single char.
+ * If it is one of the vars that should only appear in
+ * local context, skip it, else we can get Var_Subst
+ * into a loop.
+ */
+ switch (name[0]) {
+ case '@':
+ case '%':
+ case '*':
+ case '!':
+ return 0;
+ }
+ }
+ v = VarFind(name, VAR_GLOBAL, 0);
+ if (v == NULL) {
+ return 0;
+ }
+ if (!parent &&
+ (v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) {
+ return 0; /* nothing to do */
+ }
+ val = Buf_GetAll(&v->val, NULL);
+ if (strchr(val, '$')) {
+ if (parent) {
+ /*
+ * Flag this as something we need to re-export.
+ * No point actually exporting it now though,
+ * the child can do it at the last minute.
+ */
+ v->flags |= (VAR_EXPORTED|VAR_REEXPORT);
+ return 1;
+ }
+ if (v->flags & VAR_IN_USE) {
+ /*
+ * We recursed while exporting in a child.
+ * This isn't going to end well, just skip it.
+ */
+ return 0;
+ }
+ n = snprintf(tmp, sizeof(tmp), "${%s}", name);
+ if (n < (int)sizeof(tmp)) {
+ val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
+ setenv(name, val, 1);
+ free(val);
+ }
+ } else {
+ if (parent) {
+ v->flags &= ~VAR_REEXPORT; /* once will do */
+ }
+ if (parent || !(v->flags & VAR_EXPORTED)) {
+ setenv(name, val, 1);
+ }
+ }
+ /*
+ * This is so Var_Set knows to call Var_Export again...
+ */
+ if (parent) {
+ v->flags |= VAR_EXPORTED;
+ }
+ return 1;
+}
+
+/*
+ * This gets called from our children.
+ */
+void
+Var_ExportVars(void)
+{
+ char tmp[BUFSIZ];
+ Hash_Entry *var;
+ Hash_Search state;
+ Var *v;
+ char *val;
+ int n;
+
+ if (VAR_EXPORTED_NONE == var_exportedVars)
+ return;
+
+ if (VAR_EXPORTED_ALL == var_exportedVars) {
+ /*
+ * Ouch! This is crazy...
+ */
+ for (var = Hash_EnumFirst(&VAR_GLOBAL->context, &state);
+ var != NULL;
+ var = Hash_EnumNext(&state)) {
+ v = (Var *)Hash_GetValue(var);
+ Var_Export1(v->name, 0);
+ }
+ return;
+ }
+ /*
+ * We have a number of exported vars,
+ */
+ n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}");
+ if (n < (int)sizeof(tmp)) {
+ char **av;
+ char *as;
+ int ac;
+ int i;
+
+ val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
+ av = brk_string(val, &ac, FALSE, &as);
+ for (i = 0; i < ac; i++) {
+ Var_Export1(av[i], 0);
+ }
+ free(val);
+ free(as);
+ free(av);
+ }
+}
+
+/*
+ * This is called when .export is seen or
+ * .MAKE.EXPORTED is modified.
+ * It is also called when any exported var is modified.
+ */
+void
+Var_Export(char *str, int isExport)
+{
+ char *name;
+ char *val;
+ char **av;
+ char *as;
+ int track;
+ int ac;
+ int i;
+
+ if (isExport && (!str || !str[0])) {
+ var_exportedVars = VAR_EXPORTED_ALL; /* use with caution! */
+ return;
+ }
+
+ if (strncmp(str, "-env", 4) == 0) {
+ track = 0;
+ str += 4;
+ } else {
+ track = VAR_EXPORT_PARENT;
+ }
+ val = Var_Subst(NULL, str, VAR_GLOBAL, 0);
+ av = brk_string(val, &ac, FALSE, &as);
+ for (i = 0; i < ac; i++) {
+ name = av[i];
+ if (!name[1]) {
+ /*
+ * A single char.
+ * If it is one of the vars that should only appear in
+ * local context, skip it, else we can get Var_Subst
+ * into a loop.
+ */
+ switch (name[0]) {
+ case '@':
+ case '%':
+ case '*':
+ case '!':
+ continue;
+ }
+ }
+ if (Var_Export1(name, track)) {
+ if (VAR_EXPORTED_ALL != var_exportedVars)
+ var_exportedVars = VAR_EXPORTED_YES;
+ if (isExport && track) {
+ Var_Append(MAKE_EXPORTED, name, VAR_GLOBAL);
+ }
+ }
+ }
+ free(val);
+ free(as);
+ free(av);
+}
+
+
+/*
+ * This is called when .unexport[-env] is seen.
+ */
+extern char **environ;
+
+void
+Var_UnExport(char *str)
+{
+ char tmp[BUFSIZ];
+ char *vlist;
+ char *cp;
+ Boolean unexport_env;
+ int n;
+
+ if (!str || !str[0]) {
+ return; /* assert? */
+ }
+
+ vlist = NULL;
+
+ str += 8;
+ unexport_env = (strncmp(str, "-env", 4) == 0);
+ if (unexport_env) {
+ char **newenv;
+
+ cp = getenv(MAKE_LEVEL); /* we should preserve this */
+ if (environ == savedEnv) {
+ /* we have been here before! */
+ newenv = bmake_realloc(environ, 2 * sizeof(char *));
+ } else {
+ if (savedEnv) {
+ free(savedEnv);
+ savedEnv = NULL;
+ }
+ newenv = bmake_malloc(2 * sizeof(char *));
+ }
+ if (!newenv)
+ return;
+ /* Note: we cannot safely free() the original environ. */
+ environ = savedEnv = newenv;
+ newenv[0] = NULL;
+ newenv[1] = NULL;
+ setenv(MAKE_LEVEL, cp, 1);
+#ifdef MAKE_LEVEL_SAFE
+ setenv(MAKE_LEVEL_SAFE, cp, 1);
+#endif
+ } else {
+ for (; *str != '\n' && isspace((unsigned char) *str); str++)
+ continue;
+ if (str[0] && str[0] != '\n') {
+ vlist = str;
+ }
+ }
+
+ if (!vlist) {
+ /* Using .MAKE.EXPORTED */
+ n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}");
+ if (n < (int)sizeof(tmp)) {
+ vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
+ }
+ }
+ if (vlist) {
+ Var *v;
+ char **av;
+ char *as;
+ int ac;
+ int i;
+
+ av = brk_string(vlist, &ac, FALSE, &as);
+ for (i = 0; i < ac; i++) {
+ v = VarFind(av[i], VAR_GLOBAL, 0);
+ if (!v)
+ continue;
+ if (!unexport_env &&
+ (v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) {
+ unsetenv(v->name);
+ }
+ v->flags &= ~(VAR_EXPORTED|VAR_REEXPORT);
+ /*
+ * If we are unexporting a list,
+ * remove each one from .MAKE.EXPORTED.
+ * If we are removing them all,
+ * just delete .MAKE.EXPORTED below.
+ */
+ if (vlist == str) {
+ n = snprintf(tmp, sizeof(tmp),
+ "${" MAKE_EXPORTED ":N%s}", v->name);
+ if (n < (int)sizeof(tmp)) {
+ cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
+ Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL, 0);
+ free(cp);
+ }
+ }
+ }
+ free(as);
+ free(av);
+ if (vlist != str) {
+ Var_Delete(MAKE_EXPORTED, VAR_GLOBAL);
+ free(vlist);
+ }
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Var_Set --
+ * Set the variable name to the value val in the given context.
+ *
+ * Input:
+ * name name of variable to set
+ * val value to give to the variable
+ * ctxt context in which to set it
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * If the variable doesn't yet exist, a new record is created for it.
+ * Else the old value is freed and the new one stuck in its place
+ *
+ * Notes:
+ * The variable is searched for only in its context before being
+ * created in that context. I.e. if the context is VAR_GLOBAL,
+ * only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
+ * VAR_CMD->context is searched. This is done to avoid the literally
+ * thousands of unnecessary strcmp's that used to be done to
+ * set, say, $(@) or $(<).
+ * If the context is VAR_GLOBAL though, we check if the variable
+ * was set in VAR_CMD from the command line and skip it if so.
+ *-----------------------------------------------------------------------
+ */
+void
+Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
+{
+ Var *v;
+ char *expanded_name = NULL;
+
+ /*
+ * We only look for a variable in the given context since anything set
+ * here will override anything in a lower context, so there's not much
+ * point in searching them all just to save a bit of memory...
+ */
+ if (strchr(name, '$') != NULL) {
+ expanded_name = Var_Subst(NULL, name, ctxt, 0);
+ if (expanded_name[0] == 0) {
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) "
+ "name expands to empty string - ignored\n",
+ name, val);
+ }
+ free(expanded_name);
+ return;
+ }
+ name = expanded_name;
+ }
+ if (ctxt == VAR_GLOBAL) {
+ v = VarFind(name, VAR_CMD, 0);
+ if (v != NULL) {
+ if ((v->flags & VAR_FROM_CMD)) {
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "%s:%s = %s ignored!\n", ctxt->name, name, val);
+ }
+ goto out;
+ }
+ VarFreeEnv(v, TRUE);
+ }
+ }
+ v = VarFind(name, ctxt, 0);
+ if (v == NULL) {
+ VarAdd(name, val, ctxt);
+ } else {
+ Buf_Empty(&v->val);
+ Buf_AddBytes(&v->val, strlen(val), val);
+
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
+ }
+ if ((v->flags & VAR_EXPORTED)) {
+ Var_Export1(name, VAR_EXPORT_PARENT);
+ }
+ }
+ /*
+ * Any variables given on the command line are automatically exported
+ * to the environment (as per POSIX standard)
+ */
+ if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
+ if (v == NULL) {
+ /* we just added it */
+ v = VarFind(name, ctxt, 0);
+ }
+ if (v != NULL)
+ v->flags |= VAR_FROM_CMD;
+ /*
+ * If requested, don't export these in the environment
+ * individually. We still put them in MAKEOVERRIDES so
+ * that the command-line settings continue to override
+ * Makefile settings.
+ */
+ if (varNoExportEnv != TRUE)
+ setenv(name, val, 1);
+
+ Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
+ }
+ /*
+ * Another special case.
+ * Several make's support this sort of mechanism for tracking
+ * recursion - but each uses a different name.
+ * We allow the makefiles to update .MAKE.LEVEL and ensure
+ * children see a correctly incremented value.
+ */
+ if (ctxt == VAR_GLOBAL && strcmp(MAKE_LEVEL, name) == 0) {
+ char tmp[64];
+ int level;
+
+ level = atoi(val);
+ snprintf(tmp, sizeof(tmp), "%u", level + 1);
+ setenv(MAKE_LEVEL, tmp, 1);
+#ifdef MAKE_LEVEL_SAFE
+ setenv(MAKE_LEVEL_SAFE, tmp, 1);
+#endif
+ }
+
+
+ out:
+ if (expanded_name != NULL)
+ free(expanded_name);
+ if (v != NULL)
+ VarFreeEnv(v, TRUE);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Var_Append --
+ * The variable of the given name has the given value appended to it in
+ * the given context.
+ *
+ * Input:
+ * name name of variable to modify
+ * val String to append to it
+ * ctxt Context in which this should occur
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * If the variable doesn't exist, it is created. Else the strings
+ * are concatenated (with a space in between).
+ *
+ * Notes:
+ * Only if the variable is being sought in the global context is the
+ * environment searched.
+ * XXX: Knows its calling circumstances in that if called with ctxt
+ * an actual target, it will only search that context since only
+ * a local variable could be being appended to. This is actually
+ * a big win and must be tolerated.
+ *-----------------------------------------------------------------------
+ */
+void
+Var_Append(const char *name, const char *val, GNode *ctxt)
+{
+ Var *v;
+ Hash_Entry *h;
+ char *expanded_name = NULL;
+
+ if (strchr(name, '$') != NULL) {
+ expanded_name = Var_Subst(NULL, name, ctxt, 0);
+ if (expanded_name[0] == 0) {
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) "
+ "name expands to empty string - ignored\n",
+ name, val);
+ }
+ free(expanded_name);
+ return;
+ }
+ name = expanded_name;
+ }
+
+ v = VarFind(name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
+
+ if (v == NULL) {
+ VarAdd(name, val, ctxt);
+ } else {
+ Buf_AddByte(&v->val, ' ');
+ Buf_AddBytes(&v->val, strlen(val), val);
+
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name,
+ Buf_GetAll(&v->val, NULL));
+ }
+
+ if (v->flags & VAR_FROM_ENV) {
+ /*
+ * If the original variable came from the environment, we
+ * have to install it in the global context (we could place
+ * it in the environment, but then we should provide a way to
+ * export other variables...)
+ */
+ v->flags &= ~VAR_FROM_ENV;
+ h = Hash_CreateEntry(&ctxt->context, name, NULL);
+ Hash_SetValue(h, v);
+ }
+ }
+ if (expanded_name != NULL)
+ free(expanded_name);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Var_Exists --
+ * See if the given variable exists.
+ *
+ * Input:
+ * name Variable to find
+ * ctxt Context in which to start search
+ *
+ * Results:
+ * TRUE if it does, FALSE if it doesn't
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Var_Exists(const char *name, GNode *ctxt)
+{
+ Var *v;
+ char *cp;
+
+ if ((cp = strchr(name, '$')) != NULL) {
+ cp = Var_Subst(NULL, name, ctxt, FALSE);
+ }
+ v = VarFind(cp ? cp : name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
+ if (cp != NULL) {
+ free(cp);
+ }
+ if (v == NULL) {
+ return(FALSE);
+ } else {
+ (void)VarFreeEnv(v, TRUE);
+ }
+ return(TRUE);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Var_Value --
+ * Return the value of the named variable in the given context
+ *
+ * Input:
+ * name name to find
+ * ctxt context in which to search for it
+ *
+ * Results:
+ * The value if the variable exists, NULL if it doesn't
+ *
+ * Side Effects:
+ * None
+ *-----------------------------------------------------------------------
+ */
+char *
+Var_Value(const char *name, GNode *ctxt, char **frp)
+{
+ Var *v;
+
+ v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
+ *frp = NULL;
+ if (v != NULL) {
+ char *p = (Buf_GetAll(&v->val, NULL));
+ if (VarFreeEnv(v, FALSE))
+ *frp = p;
+ return p;
+ } else {
+ return NULL;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarHead --
+ * Remove the tail of the given word and place the result in the given
+ * buffer.
+ *
+ * Input:
+ * word Word to trim
+ * addSpace True if need to add a space to the buffer
+ * before sticking in the head
+ * buf Buffer in which to store it
+ *
+ * Results:
+ * TRUE if characters were added to the buffer (a space needs to be
+ * added to the buffer before the next word).
+ *
+ * Side Effects:
+ * The trimmed word is added to the buffer.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+VarHead(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
+ char *word, Boolean addSpace, Buffer *buf,
+ void *dummy)
+{
+ char *slash;
+
+ slash = strrchr(word, '/');
+ if (slash != NULL) {
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+ *slash = '\0';
+ Buf_AddBytes(buf, strlen(word), word);
+ *slash = '/';
+ return (TRUE);
+ } else {
+ /*
+ * If no directory part, give . (q.v. the POSIX standard)
+ */
+ if (addSpace && vpstate->varSpace)
+ Buf_AddByte(buf, vpstate->varSpace);
+ Buf_AddByte(buf, '.');
+ }
+ return(dummy ? TRUE : TRUE);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarTail --
+ * Remove the head of the given word and place the result in the given
+ * buffer.
+ *
+ * Input:
+ * word Word to trim
+ * addSpace True if need to add a space to the buffer
+ * before adding the tail
+ * buf Buffer in which to store it
+ *
+ * Results:
+ * TRUE if characters were added to the buffer (a space needs to be
+ * added to the buffer before the next word).
+ *
+ * Side Effects:
+ * The trimmed word is added to the buffer.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+VarTail(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
+ char *word, Boolean addSpace, Buffer *buf,
+ void *dummy)
+{
+ char *slash;
+
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+
+ slash = strrchr(word, '/');
+ if (slash != NULL) {
+ *slash++ = '\0';
+ Buf_AddBytes(buf, strlen(slash), slash);
+ slash[-1] = '/';
+ } else {
+ Buf_AddBytes(buf, strlen(word), word);
+ }
+ return (dummy ? TRUE : TRUE);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarSuffix --
+ * Place the suffix of the given word in the given buffer.
+ *
+ * Input:
+ * word Word to trim
+ * addSpace TRUE if need to add a space before placing the
+ * suffix in the buffer
+ * buf Buffer in which to store it
+ *
+ * Results:
+ * TRUE if characters were added to the buffer (a space needs to be
+ * added to the buffer before the next word).
+ *
+ * Side Effects:
+ * The suffix from the word is placed in the buffer.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+VarSuffix(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
+ char *word, Boolean addSpace, Buffer *buf,
+ void *dummy)
+{
+ char *dot;
+
+ dot = strrchr(word, '.');
+ if (dot != NULL) {
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+ *dot++ = '\0';
+ Buf_AddBytes(buf, strlen(dot), dot);
+ dot[-1] = '.';
+ addSpace = TRUE;
+ }
+ return (dummy ? addSpace : addSpace);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarRoot --
+ * Remove the suffix of the given word and place the result in the
+ * buffer.
+ *
+ * Input:
+ * word Word to trim
+ * addSpace TRUE if need to add a space to the buffer
+ * before placing the root in it
+ * buf Buffer in which to store it
+ *
+ * Results:
+ * TRUE if characters were added to the buffer (a space needs to be
+ * added to the buffer before the next word).
+ *
+ * Side Effects:
+ * The trimmed word is added to the buffer.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+VarRoot(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
+ char *word, Boolean addSpace, Buffer *buf,
+ void *dummy)
+{
+ char *dot;
+
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+
+ dot = strrchr(word, '.');
+ if (dot != NULL) {
+ *dot = '\0';
+ Buf_AddBytes(buf, strlen(word), word);
+ *dot = '.';
+ } else {
+ Buf_AddBytes(buf, strlen(word), word);
+ }
+ return (dummy ? TRUE : TRUE);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarMatch --
+ * Place the word in the buffer if it matches the given pattern.
+ * Callback function for VarModify to implement the :M modifier.
+ *
+ * Input:
+ * word Word to examine
+ * addSpace TRUE if need to add a space to the buffer
+ * before adding the word, if it matches
+ * buf Buffer in which to store it
+ * pattern Pattern the word must match
+ *
+ * Results:
+ * TRUE if a space should be placed in the buffer before the next
+ * word.
+ *
+ * Side Effects:
+ * The word may be copied to the buffer.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+VarMatch(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
+ char *word, Boolean addSpace, Buffer *buf,
+ void *pattern)
+{
+ if (DEBUG(VAR))
+ fprintf(debug_file, "VarMatch [%s] [%s]\n", word, (char *)pattern);
+ if (Str_Match(word, (char *)pattern)) {
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+ addSpace = TRUE;
+ Buf_AddBytes(buf, strlen(word), word);
+ }
+ return(addSpace);
+}
+
+#ifdef SYSVVARSUB
+/*-
+ *-----------------------------------------------------------------------
+ * VarSYSVMatch --
+ * Place the word in the buffer if it matches the given pattern.
+ * Callback function for VarModify to implement the System V %
+ * modifiers.
+ *
+ * Input:
+ * word Word to examine
+ * addSpace TRUE if need to add a space to the buffer
+ * before adding the word, if it matches
+ * buf Buffer in which to store it
+ * patp Pattern the word must match
+ *
+ * Results:
+ * TRUE if a space should be placed in the buffer before the next
+ * word.
+ *
+ * Side Effects:
+ * The word may be copied to the buffer.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate,
+ char *word, Boolean addSpace, Buffer *buf,
+ void *patp)
+{
+ int len;
+ char *ptr;
+ VarPattern *pat = (VarPattern *)patp;
+ char *varexp;
+
+ if (addSpace && vpstate->varSpace)
+ Buf_AddByte(buf, vpstate->varSpace);
+
+ addSpace = TRUE;
+
+ if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL) {
+ varexp = Var_Subst(NULL, pat->rhs, ctx, 0);
+ Str_SYSVSubst(buf, varexp, ptr, len);
+ free(varexp);
+ } else {
+ Buf_AddBytes(buf, strlen(word), word);
+ }
+
+ return(addSpace);
+}
+#endif
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarNoMatch --
+ * Place the word in the buffer if it doesn't match the given pattern.
+ * Callback function for VarModify to implement the :N modifier.
+ *
+ * Input:
+ * word Word to examine
+ * addSpace TRUE if need to add a space to the buffer
+ * before adding the word, if it matches
+ * buf Buffer in which to store it
+ * pattern Pattern the word must match
+ *
+ * Results:
+ * TRUE if a space should be placed in the buffer before the next
+ * word.
+ *
+ * Side Effects:
+ * The word may be copied to the buffer.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+VarNoMatch(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
+ char *word, Boolean addSpace, Buffer *buf,
+ void *pattern)
+{
+ if (!Str_Match(word, (char *)pattern)) {
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+ addSpace = TRUE;
+ Buf_AddBytes(buf, strlen(word), word);
+ }
+ return(addSpace);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarSubstitute --
+ * Perform a string-substitution on the given word, placing the
+ * result in the passed buffer.
+ *
+ * Input:
+ * word Word to modify
+ * addSpace True if space should be added before
+ * other characters
+ * buf Buffer for result
+ * patternp Pattern for substitution
+ *
+ * Results:
+ * TRUE if a space is needed before more characters are added.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
+ char *word, Boolean addSpace, Buffer *buf,
+ void *patternp)
+{
+ int wordLen; /* Length of word */
+ char *cp; /* General pointer */
+ VarPattern *pattern = (VarPattern *)patternp;
+
+ wordLen = strlen(word);
+ if ((pattern->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) !=
+ (VAR_SUB_ONE|VAR_SUB_MATCHED)) {
+ /*
+ * Still substituting -- break it down into simple anchored cases
+ * and if none of them fits, perform the general substitution case.
+ */
+ if ((pattern->flags & VAR_MATCH_START) &&
+ (strncmp(word, pattern->lhs, pattern->leftLen) == 0)) {
+ /*
+ * Anchored at start and beginning of word matches pattern
+ */
+ if ((pattern->flags & VAR_MATCH_END) &&
+ (wordLen == pattern->leftLen)) {
+ /*
+ * Also anchored at end and matches to the end (word
+ * is same length as pattern) add space and rhs only
+ * if rhs is non-null.
+ */
+ if (pattern->rightLen != 0) {
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+ addSpace = TRUE;
+ Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
+ }
+ pattern->flags |= VAR_SUB_MATCHED;
+ } else if (pattern->flags & VAR_MATCH_END) {
+ /*
+ * Doesn't match to end -- copy word wholesale
+ */
+ goto nosub;
+ } else {
+ /*
+ * Matches at start but need to copy in trailing characters
+ */
+ if ((pattern->rightLen + wordLen - pattern->leftLen) != 0){
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+ addSpace = TRUE;
+ }
+ Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
+ Buf_AddBytes(buf, wordLen - pattern->leftLen,
+ (word + pattern->leftLen));
+ pattern->flags |= VAR_SUB_MATCHED;
+ }
+ } else if (pattern->flags & VAR_MATCH_START) {
+ /*
+ * Had to match at start of word and didn't -- copy whole word.
+ */
+ goto nosub;
+ } else if (pattern->flags & VAR_MATCH_END) {
+ /*
+ * Anchored at end, Find only place match could occur (leftLen
+ * characters from the end of the word) and see if it does. Note
+ * that because the $ will be left at the end of the lhs, we have
+ * to use strncmp.
+ */
+ cp = word + (wordLen - pattern->leftLen);
+ if ((cp >= word) &&
+ (strncmp(cp, pattern->lhs, pattern->leftLen) == 0)) {
+ /*
+ * Match found. If we will place characters in the buffer,
+ * add a space before hand as indicated by addSpace, then
+ * stuff in the initial, unmatched part of the word followed
+ * by the right-hand-side.
+ */
+ if (((cp - word) + pattern->rightLen) != 0) {
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+ addSpace = TRUE;
+ }
+ Buf_AddBytes(buf, cp - word, word);
+ Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
+ pattern->flags |= VAR_SUB_MATCHED;
+ } else {
+ /*
+ * Had to match at end and didn't. Copy entire word.
+ */
+ goto nosub;
+ }
+ } else {
+ /*
+ * Pattern is unanchored: search for the pattern in the word using
+ * String_FindSubstring, copying unmatched portions and the
+ * right-hand-side for each match found, handling non-global
+ * substitutions correctly, etc. When the loop is done, any
+ * remaining part of the word (word and wordLen are adjusted
+ * accordingly through the loop) is copied straight into the
+ * buffer.
+ * addSpace is set FALSE as soon as a space is added to the
+ * buffer.
+ */
+ Boolean done;
+ int origSize;
+
+ done = FALSE;
+ origSize = Buf_Size(buf);
+ while (!done) {
+ cp = Str_FindSubstring(word, pattern->lhs);
+ if (cp != NULL) {
+ if (addSpace && (((cp - word) + pattern->rightLen) != 0)){
+ Buf_AddByte(buf, vpstate->varSpace);
+ addSpace = FALSE;
+ }
+ Buf_AddBytes(buf, cp-word, word);
+ Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
+ wordLen -= (cp - word) + pattern->leftLen;
+ word = cp + pattern->leftLen;
+ if (wordLen == 0) {
+ done = TRUE;
+ }
+ if ((pattern->flags & VAR_SUB_GLOBAL) == 0) {
+ done = TRUE;
+ }
+ pattern->flags |= VAR_SUB_MATCHED;
+ } else {
+ done = TRUE;
+ }
+ }
+ if (wordLen != 0) {
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+ Buf_AddBytes(buf, wordLen, word);
+ }
+ /*
+ * If added characters to the buffer, need to add a space
+ * before we add any more. If we didn't add any, just return
+ * the previous value of addSpace.
+ */
+ return ((Buf_Size(buf) != origSize) || addSpace);
+ }
+ return (addSpace);
+ }
+ nosub:
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+ Buf_AddBytes(buf, wordLen, word);
+ return(TRUE);
+}
+
+#ifndef NO_REGEX
+/*-
+ *-----------------------------------------------------------------------
+ * VarREError --
+ * Print the error caused by a regcomp or regexec call.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * An error gets printed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+VarREError(int errnum, regex_t *pat, const char *str)
+{
+ char *errbuf;
+ int errlen;
+
+ errlen = regerror(errnum, pat, 0, 0);
+ errbuf = bmake_malloc(errlen);
+ regerror(errnum, pat, errbuf, errlen);
+ Error("%s: %s", str, errbuf);
+ free(errbuf);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarRESubstitute --
+ * Perform a regex substitution on the given word, placing the
+ * result in the passed buffer.
+ *
+ * Results:
+ * TRUE if a space is needed before more characters are added.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+VarRESubstitute(GNode *ctx MAKE_ATTR_UNUSED,
+ Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
+ char *word, Boolean addSpace, Buffer *buf,
+ void *patternp)
+{
+ VarREPattern *pat;
+ int xrv;
+ char *wp;
+ char *rp;
+ int added;
+ int flags = 0;
+
+#define MAYBE_ADD_SPACE() \
+ if (addSpace && !added) \
+ Buf_AddByte(buf, ' '); \
+ added = 1
+
+ added = 0;
+ wp = word;
+ pat = patternp;
+
+ if ((pat->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) ==
+ (VAR_SUB_ONE|VAR_SUB_MATCHED))
+ xrv = REG_NOMATCH;
+ else {
+ tryagain:
+ xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags);
+ }
+
+ switch (xrv) {
+ case 0:
+ pat->flags |= VAR_SUB_MATCHED;
+ if (pat->matches[0].rm_so > 0) {
+ MAYBE_ADD_SPACE();
+ Buf_AddBytes(buf, pat->matches[0].rm_so, wp);
+ }
+
+ for (rp = pat->replace; *rp; rp++) {
+ if ((*rp == '\\') && ((rp[1] == '&') || (rp[1] == '\\'))) {
+ MAYBE_ADD_SPACE();
+ Buf_AddByte(buf,rp[1]);
+ rp++;
+ }
+ else if ((*rp == '&') ||
+ ((*rp == '\\') && isdigit((unsigned char)rp[1]))) {
+ int n;
+ const char *subbuf;
+ int sublen;
+ char errstr[3];
+
+ if (*rp == '&') {
+ n = 0;
+ errstr[0] = '&';
+ errstr[1] = '\0';
+ } else {
+ n = rp[1] - '0';
+ errstr[0] = '\\';
+ errstr[1] = rp[1];
+ errstr[2] = '\0';
+ rp++;
+ }
+
+ if (n > pat->nsub) {
+ Error("No subexpression %s", &errstr[0]);
+ subbuf = "";
+ sublen = 0;
+ } else if ((pat->matches[n].rm_so == -1) &&
+ (pat->matches[n].rm_eo == -1)) {
+ Error("No match for subexpression %s", &errstr[0]);
+ subbuf = "";
+ sublen = 0;
+ } else {
+ subbuf = wp + pat->matches[n].rm_so;
+ sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so;
+ }
+
+ if (sublen > 0) {
+ MAYBE_ADD_SPACE();
+ Buf_AddBytes(buf, sublen, subbuf);
+ }
+ } else {
+ MAYBE_ADD_SPACE();
+ Buf_AddByte(buf, *rp);
+ }
+ }
+ wp += pat->matches[0].rm_eo;
+ if (pat->flags & VAR_SUB_GLOBAL) {
+ flags |= REG_NOTBOL;
+ if (pat->matches[0].rm_so == 0 && pat->matches[0].rm_eo == 0) {
+ MAYBE_ADD_SPACE();
+ Buf_AddByte(buf, *wp);
+ wp++;
+
+ }
+ if (*wp)
+ goto tryagain;
+ }
+ if (*wp) {
+ MAYBE_ADD_SPACE();
+ Buf_AddBytes(buf, strlen(wp), wp);
+ }
+ break;
+ default:
+ VarREError(xrv, &pat->re, "Unexpected regex error");
+ /* fall through */
+ case REG_NOMATCH:
+ if (*wp) {
+ MAYBE_ADD_SPACE();
+ Buf_AddBytes(buf,strlen(wp),wp);
+ }
+ break;
+ }
+ return(addSpace||added);
+}
+#endif
+
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarLoopExpand --
+ * Implements the :@<temp>@<string>@ modifier of ODE make.
+ * We set the temp variable named in pattern.lhs to word and expand
+ * pattern.rhs storing the result in the passed buffer.
+ *
+ * Input:
+ * word Word to modify
+ * addSpace True if space should be added before
+ * other characters
+ * buf Buffer for result
+ * pattern Datafor substitution
+ *
+ * Results:
+ * TRUE if a space is needed before more characters are added.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Boolean
+VarLoopExpand(GNode *ctx MAKE_ATTR_UNUSED,
+ Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
+ char *word, Boolean addSpace, Buffer *buf,
+ void *loopp)
+{
+ VarLoop_t *loop = (VarLoop_t *)loopp;
+ char *s;
+ int slen;
+
+ if (word && *word) {
+ Var_Set(loop->tvar, word, loop->ctxt, VAR_NO_EXPORT);
+ s = Var_Subst(NULL, loop->str, loop->ctxt, loop->errnum);
+ if (s != NULL && *s != '\0') {
+ if (addSpace && *s != '\n')
+ Buf_AddByte(buf, ' ');
+ Buf_AddBytes(buf, (slen = strlen(s)), s);
+ addSpace = (slen > 0 && s[slen - 1] != '\n');
+ free(s);
+ }
+ }
+ return addSpace;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarSelectWords --
+ * Implements the :[start..end] modifier.
+ * This is a special case of VarModify since we want to be able
+ * to scan the list backwards if start > end.
+ *
+ * Input:
+ * str String whose words should be trimmed
+ * seldata words to select
+ *
+ * Results:
+ * A string of all the words selected.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static char *
+VarSelectWords(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
+ const char *str, VarSelectWords_t *seldata)
+{
+ Buffer buf; /* Buffer for the new string */
+ Boolean addSpace; /* TRUE if need to add a space to the
+ * buffer before adding the trimmed
+ * word */
+ char **av; /* word list */
+ char *as; /* word list memory */
+ int ac, i;
+ int start, end, step;
+
+ Buf_Init(&buf, 0);
+ addSpace = FALSE;
+
+ if (vpstate->oneBigWord) {
+ /* fake what brk_string() would do if there were only one word */
+ ac = 1;
+ av = bmake_malloc((ac + 1) * sizeof(char *));
+ as = bmake_strdup(str);
+ av[0] = as;
+ av[1] = NULL;
+ } else {
+ av = brk_string(str, &ac, FALSE, &as);
+ }
+
+ /*
+ * Now sanitize seldata.
+ * If seldata->start or seldata->end are negative, convert them to
+ * the positive equivalents (-1 gets converted to argc, -2 gets
+ * converted to (argc-1), etc.).
+ */
+ if (seldata->start < 0)
+ seldata->start = ac + seldata->start + 1;
+ if (seldata->end < 0)
+ seldata->end = ac + seldata->end + 1;
+
+ /*
+ * We avoid scanning more of the list than we need to.
+ */
+ if (seldata->start > seldata->end) {
+ start = MIN(ac, seldata->start) - 1;
+ end = MAX(0, seldata->end - 1);
+ step = -1;
+ } else {
+ start = MAX(0, seldata->start - 1);
+ end = MIN(ac, seldata->end);
+ step = 1;
+ }
+
+ for (i = start;
+ (step < 0 && i >= end) || (step > 0 && i < end);
+ i += step) {
+ if (av[i] && *av[i]) {
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(&buf, vpstate->varSpace);
+ }
+ Buf_AddBytes(&buf, strlen(av[i]), av[i]);
+ addSpace = TRUE;
+ }
+ }
+
+ free(as);
+ free(av);
+
+ return Buf_Destroy(&buf, FALSE);
+}
+
+
+/*-
+ * VarRealpath --
+ * Replace each word with the result of realpath()
+ * if successful.
+ */
+static Boolean
+VarRealpath(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
+ char *word, Boolean addSpace, Buffer *buf,
+ void *patternp MAKE_ATTR_UNUSED)
+{
+ struct stat st;
+ char rbuf[MAXPATHLEN];
+ char *rp;
+
+ if (addSpace && vpstate->varSpace) {
+ Buf_AddByte(buf, vpstate->varSpace);
+ }
+ addSpace = TRUE;
+ rp = realpath(word, rbuf);
+ if (rp && *rp == '/' && stat(rp, &st) == 0)
+ word = rp;
+
+ Buf_AddBytes(buf, strlen(word), word);
+ return(addSpace);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarModify --
+ * Modify each of the words of the passed string using the given
+ * function. Used to implement all modifiers.
+ *
+ * Input:
+ * str String whose words should be trimmed
+ * modProc Function to use to modify them
+ * datum Datum to pass it
+ *
+ * Results:
+ * A string of all the words modified appropriately.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static char *
+VarModify(GNode *ctx, Var_Parse_State *vpstate,
+ const char *str,
+ Boolean (*modProc)(GNode *, Var_Parse_State *, char *,
+ Boolean, Buffer *, void *),
+ void *datum)
+{
+ Buffer buf; /* Buffer for the new string */
+ Boolean addSpace; /* TRUE if need to add a space to the
+ * buffer before adding the trimmed
+ * word */
+ char **av; /* word list */
+ char *as; /* word list memory */
+ int ac, i;
+
+ Buf_Init(&buf, 0);
+ addSpace = FALSE;
+
+ if (vpstate->oneBigWord) {
+ /* fake what brk_string() would do if there were only one word */
+ ac = 1;
+ av = bmake_malloc((ac + 1) * sizeof(char *));
+ as = bmake_strdup(str);
+ av[0] = as;
+ av[1] = NULL;
+ } else {
+ av = brk_string(str, &ac, FALSE, &as);
+ }
+
+ for (i = 0; i < ac; i++) {
+ addSpace = (*modProc)(ctx, vpstate, av[i], addSpace, &buf, datum);
+ }
+
+ free(as);
+ free(av);
+
+ return Buf_Destroy(&buf, FALSE);
+}
+
+
+static int
+VarWordCompare(const void *a, const void *b)
+{
+ int r = strcmp(*(const char * const *)a, *(const char * const *)b);
+ return r;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarOrder --
+ * Order the words in the string.
+ *
+ * Input:
+ * str String whose words should be sorted.
+ * otype How to order: s - sort, x - random.
+ *
+ * Results:
+ * A string containing the words ordered.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static char *
+VarOrder(const char *str, const char otype)
+{
+ Buffer buf; /* Buffer for the new string */
+ char **av; /* word list [first word does not count] */
+ char *as; /* word list memory */
+ int ac, i;
+
+ Buf_Init(&buf, 0);
+
+ av = brk_string(str, &ac, FALSE, &as);
+
+ if (ac > 0)
+ switch (otype) {
+ case 's': /* sort alphabetically */
+ qsort(av, ac, sizeof(char *), VarWordCompare);
+ break;
+ case 'x': /* randomize */
+ {
+ int rndidx;
+ char *t;
+
+ /*
+ * We will use [ac..2] range for mod factors. This will produce
+ * random numbers in [(ac-1)..0] interval, and minimal
+ * reasonable value for mod factor is 2 (the mod 1 will produce
+ * 0 with probability 1).
+ */
+ for (i = ac-1; i > 0; i--) {
+ rndidx = random() % (i + 1);
+ if (i != rndidx) {
+ t = av[i];
+ av[i] = av[rndidx];
+ av[rndidx] = t;
+ }
+ }
+ }
+ } /* end of switch */
+
+ for (i = 0; i < ac; i++) {
+ Buf_AddBytes(&buf, strlen(av[i]), av[i]);
+ if (i != ac - 1)
+ Buf_AddByte(&buf, ' ');
+ }
+
+ free(as);
+ free(av);
+
+ return Buf_Destroy(&buf, FALSE);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarUniq --
+ * Remove adjacent duplicate words.
+ *
+ * Input:
+ * str String whose words should be sorted
+ *
+ * Results:
+ * A string containing the resulting words.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static char *
+VarUniq(const char *str)
+{
+ Buffer buf; /* Buffer for new string */
+ char **av; /* List of words to affect */
+ char *as; /* Word list memory */
+ int ac, i, j;
+
+ Buf_Init(&buf, 0);
+ av = brk_string(str, &ac, FALSE, &as);
+
+ if (ac > 1) {
+ for (j = 0, i = 1; i < ac; i++)
+ if (strcmp(av[i], av[j]) != 0 && (++j != i))
+ av[j] = av[i];
+ ac = j + 1;
+ }
+
+ for (i = 0; i < ac; i++) {
+ Buf_AddBytes(&buf, strlen(av[i]), av[i]);
+ if (i != ac - 1)
+ Buf_AddByte(&buf, ' ');
+ }
+
+ free(as);
+ free(av);
+
+ return Buf_Destroy(&buf, FALSE);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarGetPattern --
+ * Pass through the tstr looking for 1) escaped delimiters,
+ * '$'s and backslashes (place the escaped character in
+ * uninterpreted) and 2) unescaped $'s that aren't before
+ * the delimiter (expand the variable substitution unless flags
+ * has VAR_NOSUBST set).
+ * Return the expanded string or NULL if the delimiter was missing
+ * If pattern is specified, handle escaped ampersands, and replace
+ * unescaped ampersands with the lhs of the pattern.
+ *
+ * Results:
+ * A string of all the words modified appropriately.
+ * If length is specified, return the string length of the buffer
+ * If flags is specified and the last character of the pattern is a
+ * $ set the VAR_MATCH_END bit of flags.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+static char *
+VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
+ int errnum, const char **tstr, int delim, int *flags,
+ int *length, VarPattern *pattern)
+{
+ const char *cp;
+ char *rstr;
+ Buffer buf;
+ int junk;
+
+ Buf_Init(&buf, 0);
+ if (length == NULL)
+ length = &junk;
+
+#define IS_A_MATCH(cp, delim) \
+ ((cp[0] == '\\') && ((cp[1] == delim) || \
+ (cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&'))))
+
+ /*
+ * Skim through until the matching delimiter is found;
+ * pick up variable substitutions on the way. Also allow
+ * backslashes to quote the delimiter, $, and \, but don't
+ * touch other backslashes.
+ */
+ for (cp = *tstr; *cp && (*cp != delim); cp++) {
+ if (IS_A_MATCH(cp, delim)) {
+ Buf_AddByte(&buf, cp[1]);
+ cp++;
+ } else if (*cp == '$') {
+ if (cp[1] == delim) {
+ if (flags == NULL)
+ Buf_AddByte(&buf, *cp);
+ else
+ /*
+ * Unescaped $ at end of pattern => anchor
+ * pattern at end.
+ */
+ *flags |= VAR_MATCH_END;
+ } else {
+ if (flags == NULL || (*flags & VAR_NOSUBST) == 0) {
+ char *cp2;
+ int len;
+ void *freeIt;
+
+ /*
+ * If unescaped dollar sign not before the
+ * delimiter, assume it's a variable
+ * substitution and recurse.
+ */
+ cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt);
+ Buf_AddBytes(&buf, strlen(cp2), cp2);
+ if (freeIt)
+ free(freeIt);
+ cp += len - 1;
+ } else {
+ const char *cp2 = &cp[1];
+
+ if (*cp2 == PROPEN || *cp2 == BROPEN) {
+ /*
+ * Find the end of this variable reference
+ * and suck it in without further ado.
+ * It will be interperated later.
+ */
+ int have = *cp2;
+ int want = (*cp2 == PROPEN) ? PRCLOSE : BRCLOSE;
+ int depth = 1;
+
+ for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
+ if (cp2[-1] != '\\') {
+ if (*cp2 == have)
+ ++depth;
+ if (*cp2 == want)
+ --depth;
+ }
+ }
+ Buf_AddBytes(&buf, cp2 - cp, cp);
+ cp = --cp2;
+ } else
+ Buf_AddByte(&buf, *cp);
+ }
+ }
+ }
+ else if (pattern && *cp == '&')
+ Buf_AddBytes(&buf, pattern->leftLen, pattern->lhs);
+ else
+ Buf_AddByte(&buf, *cp);
+ }
+
+ if (*cp != delim) {
+ *tstr = cp;
+ *length = 0;
+ return NULL;
+ }
+
+ *tstr = ++cp;
+ *length = Buf_Size(&buf);
+ rstr = Buf_Destroy(&buf, FALSE);
+ if (DEBUG(VAR))
+ fprintf(debug_file, "Modifier pattern: \"%s\"\n", rstr);
+ return rstr;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarQuote --
+ * Quote shell meta-characters in the string
+ *
+ * Results:
+ * The quoted string
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static char *
+VarQuote(char *str)
+{
+
+ Buffer buf;
+ /* This should cover most shells :-( */
+ static const char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
+ const char *newline;
+ size_t len, nlen;
+
+ if ((newline = Shell_GetNewline()) == NULL)
+ newline = "\\\n";
+ nlen = strlen(newline);
+
+ Buf_Init(&buf, 0);
+ while (*str != '\0') {
+ if ((len = strcspn(str, meta)) != 0) {
+ Buf_AddBytes(&buf, len, str);
+ str += len;
+ } else if (*str == '\n') {
+ Buf_AddBytes(&buf, nlen, newline);
+ ++str;
+ } else {
+ Buf_AddByte(&buf, '\\');
+ Buf_AddByte(&buf, *str);
+ ++str;
+ }
+ }
+ str = Buf_Destroy(&buf, FALSE);
+ if (DEBUG(VAR))
+ fprintf(debug_file, "QuoteMeta: [%s]\n", str);
+ return str;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarHash --
+ * Hash the string using the MurmurHash3 algorithm.
+ * Output is computed using 32bit Little Endian arithmetic.
+ *
+ * Input:
+ * str String to modify
+ *
+ * Results:
+ * Hash value of str, encoded as 8 hex digits.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static char *
+VarHash(char *str)
+{
+ static const char hexdigits[16] = "0123456789abcdef";
+ Buffer buf;
+ size_t len, len2;
+ unsigned char *ustr = (unsigned char *)str;
+ uint32_t h, k, c1, c2;
+ int done;
+
+ done = 1;
+ h = 0x971e137bU;
+ c1 = 0x95543787U;
+ c2 = 0x2ad7eb25U;
+ len2 = strlen(str);
+
+ for (len = len2; len; ) {
+ k = 0;
+ switch (len) {
+ default:
+ k = (ustr[3] << 24) | (ustr[2] << 16) | (ustr[1] << 8) | ustr[0];
+ len -= 4;
+ ustr += 4;
+ break;
+ case 3:
+ k |= (ustr[2] << 16);
+ case 2:
+ k |= (ustr[1] << 8);
+ case 1:
+ k |= ustr[0];
+ len = 0;
+ }
+ c1 = c1 * 5 + 0x7b7d159cU;
+ c2 = c2 * 5 + 0x6bce6396U;
+ k *= c1;
+ k = (k << 11) ^ (k >> 21);
+ k *= c2;
+ h = (h << 13) ^ (h >> 19);
+ h = h * 5 + 0x52dce729U;
+ h ^= k;
+ } while (!done);
+ h ^= len2;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+
+ Buf_Init(&buf, 0);
+ for (len = 0; len < 8; ++len) {
+ Buf_AddByte(&buf, hexdigits[h & 15]);
+ h >>= 4;
+ }
+
+ return Buf_Destroy(&buf, FALSE);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * VarChangeCase --
+ * Change the string to all uppercase or all lowercase
+ *
+ * Input:
+ * str String to modify
+ * upper TRUE -> uppercase, else lowercase
+ *
+ * Results:
+ * The string with case changed
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+static char *
+VarChangeCase(char *str, int upper)
+{
+ Buffer buf;
+ int (*modProc)(int);
+
+ modProc = (upper ? toupper : tolower);
+ Buf_Init(&buf, 0);
+ for (; *str ; str++) {
+ Buf_AddByte(&buf, modProc(*str));
+ }
+ return Buf_Destroy(&buf, FALSE);
+}
+
+static char *
+VarStrftime(const char *fmt, int zulu)
+{
+ char buf[BUFSIZ];
+ time_t utc;
+
+ time(&utc);
+ if (!*fmt)
+ fmt = "%c";
+ strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&utc) : localtime(&utc));
+
+ buf[sizeof(buf) - 1] = '\0';
+ return bmake_strdup(buf);
+}
+
+/*
+ * Now we need to apply any modifiers the user wants applied.
+ * These are:
+ * :M<pattern> words which match the given <pattern>.
+ * <pattern> is of the standard file
+ * wildcarding form.
+ * :N<pattern> words which do not match the given <pattern>.
+ * :S<d><pat1><d><pat2><d>[1gW]
+ * Substitute <pat2> for <pat1> in the value
+ * :C<d><pat1><d><pat2><d>[1gW]
+ * Substitute <pat2> for regex <pat1> in the value
+ * :H Substitute the head of each word
+ * :T Substitute the tail of each word
+ * :E Substitute the extension (minus '.') of
+ * each word
+ * :R Substitute the root of each word
+ * (pathname minus the suffix).
+ * :O ("Order") Alphabeticaly sort words in variable.
+ * :Ox ("intermiX") Randomize words in variable.
+ * :u ("uniq") Remove adjacent duplicate words.
+ * :tu Converts the variable contents to uppercase.
+ * :tl Converts the variable contents to lowercase.
+ * :ts[c] Sets varSpace - the char used to
+ * separate words to 'c'. If 'c' is
+ * omitted then no separation is used.
+ * :tW Treat the variable contents as a single
+ * word, even if it contains spaces.
+ * (Mnemonic: one big 'W'ord.)
+ * :tw Treat the variable contents as multiple
+ * space-separated words.
+ * (Mnemonic: many small 'w'ords.)
+ * :[index] Select a single word from the value.
+ * :[start..end] Select multiple words from the value.
+ * :[*] or :[0] Select the entire value, as a single
+ * word. Equivalent to :tW.
+ * :[@] Select the entire value, as multiple
+ * words. Undoes the effect of :[*].
+ * Equivalent to :tw.
+ * :[#] Returns the number of words in the value.
+ *
+ * :?<true-value>:<false-value>
+ * If the variable evaluates to true, return
+ * true value, else return the second value.
+ * :lhs=rhs Like :S, but the rhs goes to the end of
+ * the invocation.
+ * :sh Treat the current value as a command
+ * to be run, new value is its output.
+ * The following added so we can handle ODE makefiles.
+ * :@<tmpvar>@<newval>@
+ * Assign a temporary local variable <tmpvar>
+ * to the current value of each word in turn
+ * and replace each word with the result of
+ * evaluating <newval>
+ * :D<newval> Use <newval> as value if variable defined
+ * :U<newval> Use <newval> as value if variable undefined
+ * :L Use the name of the variable as the value.
+ * :P Use the path of the node that has the same
+ * name as the variable as the value. This
+ * basically includes an implied :L so that
+ * the common method of refering to the path
+ * of your dependent 'x' in a rule is to use
+ * the form '${x:P}'.
+ * :!<cmd>! Run cmd much the same as :sh run's the
+ * current value of the variable.
+ * The ::= modifiers, actually assign a value to the variable.
+ * Their main purpose is in supporting modifiers of .for loop
+ * iterators and other obscure uses. They always expand to
+ * nothing. In a target rule that would otherwise expand to an
+ * empty line they can be preceded with @: to keep make happy.
+ * Eg.
+ *
+ * foo: .USE
+ * .for i in ${.TARGET} ${.TARGET:R}.gz
+ * @: ${t::=$i}
+ * @echo blah ${t:T}
+ * .endfor
+ *
+ * ::=<str> Assigns <str> as the new value of variable.
+ * ::?=<str> Assigns <str> as value of variable if
+ * it was not already set.
+ * ::+=<str> Appends <str> to variable.
+ * ::!=<cmd> Assigns output of <cmd> as the new value of
+ * variable.
+ */
+
+/* we now have some modifiers with long names */
+#define STRMOD_MATCH(s, want, n) \
+ (strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':'))
+
+static char *
+ApplyModifiers(char *nstr, const char *tstr,
+ int startc, int endc,
+ Var *v, GNode *ctxt, Boolean errnum,
+ int *lengthPtr, void **freePtr)
+{
+ const char *start;
+ const char *cp; /* Secondary pointer into str (place marker
+ * for tstr) */
+ char *newStr; /* New value to return */
+ char termc; /* Character which terminated scan */
+ int cnt; /* Used to count brace pairs when variable in
+ * in parens or braces */
+ char delim;
+ int modifier; /* that we are processing */
+ Var_Parse_State parsestate; /* Flags passed to helper functions */
+
+ delim = '\0';
+ parsestate.oneBigWord = FALSE;
+ parsestate.varSpace = ' '; /* word separator */
+
+ start = cp = tstr;
+
+ while (*tstr && *tstr != endc) {
+
+ if (*tstr == '$') {
+ /*
+ * We may have some complex modifiers in a variable.
+ */
+ void *freeIt;
+ char *rval;
+ int rlen;
+ int c;
+
+ rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt);
+
+ /*
+ * If we have not parsed up to endc or ':',
+ * we are not interested.
+ */
+ if (rval != NULL && *rval &&
+ (c = tstr[rlen]) != '\0' &&
+ c != ':' &&
+ c != endc) {
+ if (freeIt)
+ free(freeIt);
+ goto apply_mods;
+ }
+
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "Got '%s' from '%.*s'%.*s\n",
+ rval, rlen, tstr, rlen, tstr + rlen);
+ }
+
+ tstr += rlen;
+
+ if (rval != NULL && *rval) {
+ int used;
+
+ nstr = ApplyModifiers(nstr, rval,
+ 0, 0,
+ v, ctxt, errnum, &used, freePtr);
+ if (nstr == var_Error
+ || (nstr == varNoError && errnum == 0)
+ || strlen(rval) != (size_t) used) {
+ if (freeIt)
+ free(freeIt);
+ goto out; /* error already reported */
+ }
+ }
+ if (freeIt)
+ free(freeIt);
+ if (*tstr == ':')
+ tstr++;
+ else if (!*tstr && endc) {
+ Error("Unclosed variable specification after complex modifier (expecting '%c') for %s", endc, v->name);
+ goto out;
+ }
+ continue;
+ }
+ apply_mods:
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "Applying :%c to \"%s\"\n", *tstr, nstr);
+ }
+ newStr = var_Error;
+ switch ((modifier = *tstr)) {
+ case ':':
+ {
+ if (tstr[1] == '=' ||
+ (tstr[2] == '=' &&
+ (tstr[1] == '!' || tstr[1] == '+' || tstr[1] == '?'))) {
+ /*
+ * "::=", "::!=", "::+=", or "::?="
+ */
+ GNode *v_ctxt; /* context where v belongs */
+ const char *emsg;
+ char *sv_name;
+ VarPattern pattern;
+ int how;
+
+ if (v->name[0] == 0)
+ goto bad_modifier;
+
+ v_ctxt = ctxt;
+ sv_name = NULL;
+ ++tstr;
+ if (v->flags & VAR_JUNK) {
+ /*
+ * We need to bmake_strdup() it incase
+ * VarGetPattern() recurses.
+ */
+ sv_name = v->name;
+ v->name = bmake_strdup(v->name);
+ } else if (ctxt != VAR_GLOBAL) {
+ Var *gv = VarFind(v->name, ctxt, 0);
+ if (gv == NULL)
+ v_ctxt = VAR_GLOBAL;
+ else
+ VarFreeEnv(gv, TRUE);
+ }
+
+ switch ((how = *tstr)) {
+ case '+':
+ case '?':
+ case '!':
+ cp = &tstr[2];
+ break;
+ default:
+ cp = ++tstr;
+ break;
+ }
+ delim = startc == PROPEN ? PRCLOSE : BRCLOSE;
+ pattern.flags = 0;
+
+ pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum,
+ &cp, delim, NULL,
+ &pattern.rightLen,
+ NULL);
+ if (v->flags & VAR_JUNK) {
+ /* restore original name */
+ free(v->name);
+ v->name = sv_name;
+ }
+ if (pattern.rhs == NULL)
+ goto cleanup;
+
+ termc = *--cp;
+ delim = '\0';
+
+ switch (how) {
+ case '+':
+ Var_Append(v->name, pattern.rhs, v_ctxt);
+ break;
+ case '!':
+ newStr = Cmd_Exec(pattern.rhs, &emsg);
+ if (emsg)
+ Error(emsg, nstr);
+ else
+ Var_Set(v->name, newStr, v_ctxt, 0);
+ if (newStr)
+ free(newStr);
+ break;
+ case '?':
+ if ((v->flags & VAR_JUNK) == 0)
+ break;
+ /* FALLTHROUGH */
+ default:
+ Var_Set(v->name, pattern.rhs, v_ctxt, 0);
+ break;
+ }
+ free(UNCONST(pattern.rhs));
+ newStr = var_Error;
+ break;
+ }
+ goto default_case; /* "::<unrecognised>" */
+ }
+ case '@':
+ {
+ VarLoop_t loop;
+ int flags = VAR_NOSUBST;
+
+ cp = ++tstr;
+ delim = '@';
+ if ((loop.tvar = VarGetPattern(ctxt, &parsestate, errnum,
+ &cp, delim,
+ &flags, &loop.tvarLen,
+ NULL)) == NULL)
+ goto cleanup;
+
+ if ((loop.str = VarGetPattern(ctxt, &parsestate, errnum,
+ &cp, delim,
+ &flags, &loop.strLen,
+ NULL)) == NULL)
+ goto cleanup;
+
+ termc = *cp;
+ delim = '\0';
+
+ loop.errnum = errnum;
+ loop.ctxt = ctxt;
+ newStr = VarModify(ctxt, &parsestate, nstr, VarLoopExpand,
+ &loop);
+ free(loop.tvar);
+ free(loop.str);
+ break;
+ }
+ case 'D':
+ case 'U':
+ {
+ Buffer buf; /* Buffer for patterns */
+ int wantit; /* want data in buffer */
+
+ /*
+ * Pass through tstr looking for 1) escaped delimiters,
+ * '$'s and backslashes (place the escaped character in
+ * uninterpreted) and 2) unescaped $'s that aren't before
+ * the delimiter (expand the variable substitution).
+ * The result is left in the Buffer buf.
+ */
+ Buf_Init(&buf, 0);
+ for (cp = tstr + 1;
+ *cp != endc && *cp != ':' && *cp != '\0';
+ cp++) {
+ if ((*cp == '\\') &&
+ ((cp[1] == ':') ||
+ (cp[1] == '$') ||
+ (cp[1] == endc) ||
+ (cp[1] == '\\')))
+ {
+ Buf_AddByte(&buf, cp[1]);
+ cp++;
+ } else if (*cp == '$') {
+ /*
+ * If unescaped dollar sign, assume it's a
+ * variable substitution and recurse.
+ */
+ char *cp2;
+ int len;
+ void *freeIt;
+
+ cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt);
+ Buf_AddBytes(&buf, strlen(cp2), cp2);
+ if (freeIt)
+ free(freeIt);
+ cp += len - 1;
+ } else {
+ Buf_AddByte(&buf, *cp);
+ }
+ }
+
+ termc = *cp;
+
+ if (*tstr == 'U')
+ wantit = ((v->flags & VAR_JUNK) != 0);
+ else
+ wantit = ((v->flags & VAR_JUNK) == 0);
+ if ((v->flags & VAR_JUNK) != 0)
+ v->flags |= VAR_KEEP;
+ if (wantit) {
+ newStr = Buf_Destroy(&buf, FALSE);
+ } else {
+ newStr = nstr;
+ Buf_Destroy(&buf, TRUE);
+ }
+ break;
+ }
+ case 'L':
+ {
+ if ((v->flags & VAR_JUNK) != 0)
+ v->flags |= VAR_KEEP;
+ newStr = bmake_strdup(v->name);
+ cp = ++tstr;
+ termc = *tstr;
+ break;
+ }
+ case 'P':
+ {
+ GNode *gn;
+
+ if ((v->flags & VAR_JUNK) != 0)
+ v->flags |= VAR_KEEP;
+ gn = Targ_FindNode(v->name, TARG_NOCREATE);
+ if (gn == NULL || gn->type & OP_NOPATH) {
+ newStr = NULL;
+ } else if (gn->path) {
+ newStr = bmake_strdup(gn->path);
+ } else {
+ newStr = Dir_FindFile(v->name, Suff_FindPath(gn));
+ }
+ if (!newStr) {
+ newStr = bmake_strdup(v->name);
+ }
+ cp = ++tstr;
+ termc = *tstr;
+ break;
+ }
+ case '!':
+ {
+ const char *emsg;
+ VarPattern pattern;
+ pattern.flags = 0;
+
+ delim = '!';
+
+ cp = ++tstr;
+ if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum,
+ &cp, delim,
+ NULL, &pattern.rightLen,
+ NULL)) == NULL)
+ goto cleanup;
+ newStr = Cmd_Exec(pattern.rhs, &emsg);
+ free(UNCONST(pattern.rhs));
+ if (emsg)
+ Error(emsg, nstr);
+ termc = *cp;
+ delim = '\0';
+ if (v->flags & VAR_JUNK) {
+ v->flags |= VAR_KEEP;
+ }
+ break;
+ }
+ case '[':
+ {
+ /*
+ * Look for the closing ']', recursively
+ * expanding any embedded variables.
+ *
+ * estr is a pointer to the expanded result,
+ * which we must free().
+ */
+ char *estr;
+
+ cp = tstr+1; /* point to char after '[' */
+ delim = ']'; /* look for closing ']' */
+ estr = VarGetPattern(ctxt, &parsestate,
+ errnum, &cp, delim,
+ NULL, NULL, NULL);
+ if (estr == NULL)
+ goto cleanup; /* report missing ']' */
+ /* now cp points just after the closing ']' */
+ delim = '\0';
+ if (cp[0] != ':' && cp[0] != endc) {
+ /* Found junk after ']' */
+ free(estr);
+ goto bad_modifier;
+ }
+ if (estr[0] == '\0') {
+ /* Found empty square brackets in ":[]". */
+ free(estr);
+ goto bad_modifier;
+ } else if (estr[0] == '#' && estr[1] == '\0') {
+ /* Found ":[#]" */
+
+ /*
+ * We will need enough space for the decimal
+ * representation of an int. We calculate the
+ * space needed for the octal representation,
+ * and add enough slop to cope with a '-' sign
+ * (which should never be needed) and a '\0'
+ * string terminator.
+ */
+ int newStrSize =
+ (sizeof(int) * CHAR_BIT + 2) / 3 + 2;
+
+ newStr = bmake_malloc(newStrSize);
+ if (parsestate.oneBigWord) {
+ strncpy(newStr, "1", newStrSize);
+ } else {
+ /* XXX: brk_string() is a rather expensive
+ * way of counting words. */
+ char **av;
+ char *as;
+ int ac;
+
+ av = brk_string(nstr, &ac, FALSE, &as);
+ snprintf(newStr, newStrSize, "%d", ac);
+ free(as);
+ free(av);
+ }
+ termc = *cp;
+ free(estr);
+ break;
+ } else if (estr[0] == '*' && estr[1] == '\0') {
+ /* Found ":[*]" */
+ parsestate.oneBigWord = TRUE;
+ newStr = nstr;
+ termc = *cp;
+ free(estr);
+ break;
+ } else if (estr[0] == '@' && estr[1] == '\0') {
+ /* Found ":[@]" */
+ parsestate.oneBigWord = FALSE;
+ newStr = nstr;
+ termc = *cp;
+ free(estr);
+ break;
+ } else {
+ /*
+ * We expect estr to contain a single
+ * integer for :[N], or two integers
+ * separated by ".." for :[start..end].
+ */
+ char *ep;
+
+ VarSelectWords_t seldata = { 0, 0 };
+
+ seldata.start = strtol(estr, &ep, 0);
+ if (ep == estr) {
+ /* Found junk instead of a number */
+ free(estr);
+ goto bad_modifier;
+ } else if (ep[0] == '\0') {
+ /* Found only one integer in :[N] */
+ seldata.end = seldata.start;
+ } else if (ep[0] == '.' && ep[1] == '.' &&
+ ep[2] != '\0') {
+ /* Expecting another integer after ".." */
+ ep += 2;
+ seldata.end = strtol(ep, &ep, 0);
+ if (ep[0] != '\0') {
+ /* Found junk after ".." */
+ free(estr);
+ goto bad_modifier;
+ }
+ } else {
+ /* Found junk instead of ".." */
+ free(estr);
+ goto bad_modifier;
+ }
+ /*
+ * Now seldata is properly filled in,
+ * but we still have to check for 0 as
+ * a special case.
+ */
+ if (seldata.start == 0 && seldata.end == 0) {
+ /* ":[0]" or perhaps ":[0..0]" */
+ parsestate.oneBigWord = TRUE;
+ newStr = nstr;
+ termc = *cp;
+ free(estr);
+ break;
+ } else if (seldata.start == 0 ||
+ seldata.end == 0) {
+ /* ":[0..N]" or ":[N..0]" */
+ free(estr);
+ goto bad_modifier;
+ }
+ /*
+ * Normal case: select the words
+ * described by seldata.
+ */
+ newStr = VarSelectWords(ctxt, &parsestate,
+ nstr, &seldata);
+
+ termc = *cp;
+ free(estr);
+ break;
+ }
+
+ }
+ case 'g':
+ cp = tstr + 1; /* make sure it is set */
+ if (STRMOD_MATCH(tstr, "gmtime", 6)) {
+ newStr = VarStrftime(nstr, 1);
+ cp = tstr + 6;
+ termc = *cp;
+ } else {
+ goto default_case;
+ }
+ break;
+ case 'h':
+ cp = tstr + 1; /* make sure it is set */
+ if (STRMOD_MATCH(tstr, "hash", 4)) {
+ newStr = VarHash(nstr);
+ cp = tstr + 4;
+ termc = *cp;
+ } else {
+ goto default_case;
+ }
+ break;
+ case 'l':
+ cp = tstr + 1; /* make sure it is set */
+ if (STRMOD_MATCH(tstr, "localtime", 9)) {
+ newStr = VarStrftime(nstr, 0);
+ cp = tstr + 9;
+ termc = *cp;
+ } else {
+ goto default_case;
+ }
+ break;
+ case 't':
+ {
+ cp = tstr + 1; /* make sure it is set */
+ if (tstr[1] != endc && tstr[1] != ':') {
+ if (tstr[1] == 's') {
+ /*
+ * Use the char (if any) at tstr[2]
+ * as the word separator.
+ */
+ VarPattern pattern;
+
+ if (tstr[2] != endc &&
+ (tstr[3] == endc || tstr[3] == ':')) {
+ /* ":ts<unrecognised><endc>" or
+ * ":ts<unrecognised>:" */
+ parsestate.varSpace = tstr[2];
+ cp = tstr + 3;
+ } else if (tstr[2] == endc || tstr[2] == ':') {
+ /* ":ts<endc>" or ":ts:" */
+ parsestate.varSpace = 0; /* no separator */
+ cp = tstr + 2;
+ } else if (tstr[2] == '\\') {
+ switch (tstr[3]) {
+ case 'n':
+ parsestate.varSpace = '\n';
+ cp = tstr + 4;
+ break;
+ case 't':
+ parsestate.varSpace = '\t';
+ cp = tstr + 4;
+ break;
+ default:
+ if (isdigit((unsigned char)tstr[3])) {
+ char *ep;
+
+ parsestate.varSpace =
+ strtoul(&tstr[3], &ep, 0);
+ if (*ep != ':' && *ep != endc)
+ goto bad_modifier;
+ cp = ep;
+ } else {
+ /*
+ * ":ts<backslash><unrecognised>".
+ */
+ goto bad_modifier;
+ }
+ break;
+ }
+ } else {
+ /*
+ * Found ":ts<unrecognised><unrecognised>".
+ */
+ goto bad_modifier;
+ }
+
+ termc = *cp;
+
+ /*
+ * We cannot be certain that VarModify
+ * will be used - even if there is a
+ * subsequent modifier, so do a no-op
+ * VarSubstitute now to for str to be
+ * re-expanded without the spaces.
+ */
+ pattern.flags = VAR_SUB_ONE;
+ pattern.lhs = pattern.rhs = "\032";
+ pattern.leftLen = pattern.rightLen = 1;
+
+ newStr = VarModify(ctxt, &parsestate, nstr,
+ VarSubstitute,
+ &pattern);
+ } else if (tstr[2] == endc || tstr[2] == ':') {
+ /*
+ * Check for two-character options:
+ * ":tu", ":tl"
+ */
+ if (tstr[1] == 'A') { /* absolute path */
+ newStr = VarModify(ctxt, &parsestate, nstr,
+ VarRealpath, NULL);
+ cp = tstr + 2;
+ termc = *cp;
+ } else if (tstr[1] == 'u' || tstr[1] == 'l') {
+ newStr = VarChangeCase(nstr, (tstr[1] == 'u'));
+ cp = tstr + 2;
+ termc = *cp;
+ } else if (tstr[1] == 'W' || tstr[1] == 'w') {
+ parsestate.oneBigWord = (tstr[1] == 'W');
+ newStr = nstr;
+ cp = tstr + 2;
+ termc = *cp;
+ } else {
+ /* Found ":t<unrecognised>:" or
+ * ":t<unrecognised><endc>". */
+ goto bad_modifier;
+ }
+ } else {
+ /*
+ * Found ":t<unrecognised><unrecognised>".
+ */
+ goto bad_modifier;
+ }
+ } else {
+ /*
+ * Found ":t<endc>" or ":t:".
+ */
+ goto bad_modifier;
+ }
+ break;
+ }
+ case 'N':
+ case 'M':
+ {
+ char *pattern;
+ const char *endpat; /* points just after end of pattern */
+ char *cp2;
+ Boolean copy; /* pattern should be, or has been, copied */
+ Boolean needSubst;
+ int nest;
+
+ copy = FALSE;
+ needSubst = FALSE;
+ nest = 1;
+ /*
+ * In the loop below, ignore ':' unless we are at
+ * (or back to) the original brace level.
+ * XXX This will likely not work right if $() and ${}
+ * are intermixed.
+ */
+ for (cp = tstr + 1;
+ *cp != '\0' && !(*cp == ':' && nest == 1);
+ cp++)
+ {
+ if (*cp == '\\' &&
+ (cp[1] == ':' ||
+ cp[1] == endc || cp[1] == startc)) {
+ if (!needSubst) {
+ copy = TRUE;
+ }
+ cp++;
+ continue;
+ }
+ if (*cp == '$') {
+ needSubst = TRUE;
+ }
+ if (*cp == '(' || *cp == '{')
+ ++nest;
+ if (*cp == ')' || *cp == '}') {
+ --nest;
+ if (nest == 0)
+ break;
+ }
+ }
+ termc = *cp;
+ endpat = cp;
+ if (copy) {
+ /*
+ * Need to compress the \:'s out of the pattern, so
+ * allocate enough room to hold the uncompressed
+ * pattern (note that cp started at tstr+1, so
+ * cp - tstr takes the null byte into account) and
+ * compress the pattern into the space.
+ */
+ pattern = bmake_malloc(cp - tstr);
+ for (cp2 = pattern, cp = tstr + 1;
+ cp < endpat;
+ cp++, cp2++)
+ {
+ if ((*cp == '\\') && (cp+1 < endpat) &&
+ (cp[1] == ':' || cp[1] == endc)) {
+ cp++;
+ }
+ *cp2 = *cp;
+ }
+ *cp2 = '\0';
+ endpat = cp2;
+ } else {
+ /*
+ * Either Var_Subst or VarModify will need a
+ * nul-terminated string soon, so construct one now.
+ */
+ pattern = bmake_strndup(tstr+1, endpat - (tstr + 1));
+ }
+ if (needSubst) {
+ /*
+ * pattern contains embedded '$', so use Var_Subst to
+ * expand it.
+ */
+ cp2 = pattern;
+ pattern = Var_Subst(NULL, cp2, ctxt, errnum);
+ free(cp2);
+ }
+ if (DEBUG(VAR))
+ fprintf(debug_file, "Pattern for [%s] is [%s]\n", nstr,
+ pattern);
+ if (*tstr == 'M') {
+ newStr = VarModify(ctxt, &parsestate, nstr, VarMatch,
+ pattern);
+ } else {
+ newStr = VarModify(ctxt, &parsestate, nstr, VarNoMatch,
+ pattern);
+ }
+ free(pattern);
+ break;
+ }
+ case 'S':
+ {
+ VarPattern pattern;
+ Var_Parse_State tmpparsestate;
+
+ pattern.flags = 0;
+ tmpparsestate = parsestate;
+ delim = tstr[1];
+ tstr += 2;
+
+ /*
+ * If pattern begins with '^', it is anchored to the
+ * start of the word -- skip over it and flag pattern.
+ */
+ if (*tstr == '^') {
+ pattern.flags |= VAR_MATCH_START;
+ tstr += 1;
+ }
+
+ cp = tstr;
+ if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum,
+ &cp, delim,
+ &pattern.flags,
+ &pattern.leftLen,
+ NULL)) == NULL)
+ goto cleanup;
+
+ if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum,
+ &cp, delim, NULL,
+ &pattern.rightLen,
+ &pattern)) == NULL)
+ goto cleanup;
+
+ /*
+ * Check for global substitution. If 'g' after the final
+ * delimiter, substitution is global and is marked that
+ * way.
+ */
+ for (;; cp++) {
+ switch (*cp) {
+ case 'g':
+ pattern.flags |= VAR_SUB_GLOBAL;
+ continue;
+ case '1':
+ pattern.flags |= VAR_SUB_ONE;
+ continue;
+ case 'W':
+ tmpparsestate.oneBigWord = TRUE;
+ continue;
+ }
+ break;
+ }
+
+ termc = *cp;
+ newStr = VarModify(ctxt, &tmpparsestate, nstr,
+ VarSubstitute,
+ &pattern);
+
+ /*
+ * Free the two strings.
+ */
+ free(UNCONST(pattern.lhs));
+ free(UNCONST(pattern.rhs));
+ delim = '\0';
+ break;
+ }
+ case '?':
+ {
+ VarPattern pattern;
+ Boolean value;
+
+ /* find ':', and then substitute accordingly */
+
+ pattern.flags = 0;
+
+ cp = ++tstr;
+ delim = ':';
+ if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum,
+ &cp, delim, NULL,
+ &pattern.leftLen,
+ NULL)) == NULL)
+ goto cleanup;
+
+ /* BROPEN or PROPEN */
+ delim = endc;
+ if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum,
+ &cp, delim, NULL,
+ &pattern.rightLen,
+ NULL)) == NULL)
+ goto cleanup;
+
+ termc = *--cp;
+ delim = '\0';
+ if (Cond_EvalExpression(NULL, v->name, &value, 0)
+ == COND_INVALID) {
+ Error("Bad conditional expression `%s' in %s?%s:%s",
+ v->name, v->name, pattern.lhs, pattern.rhs);
+ goto cleanup;
+ }
+
+ if (value) {
+ newStr = UNCONST(pattern.lhs);
+ free(UNCONST(pattern.rhs));
+ } else {
+ newStr = UNCONST(pattern.rhs);
+ free(UNCONST(pattern.lhs));
+ }
+ if (v->flags & VAR_JUNK) {
+ v->flags |= VAR_KEEP;
+ }
+ break;
+ }
+#ifndef NO_REGEX
+ case 'C':
+ {
+ VarREPattern pattern;
+ char *re;
+ int error;
+ Var_Parse_State tmpparsestate;
+
+ pattern.flags = 0;
+ tmpparsestate = parsestate;
+ delim = tstr[1];
+ tstr += 2;
+
+ cp = tstr;
+
+ if ((re = VarGetPattern(ctxt, &parsestate, errnum, &cp, delim,
+ NULL, NULL, NULL)) == NULL)
+ goto cleanup;
+
+ if ((pattern.replace = VarGetPattern(ctxt, &parsestate,
+ errnum, &cp, delim, NULL,
+ NULL, NULL)) == NULL){
+ free(re);
+ goto cleanup;
+ }
+
+ for (;; cp++) {
+ switch (*cp) {
+ case 'g':
+ pattern.flags |= VAR_SUB_GLOBAL;
+ continue;
+ case '1':
+ pattern.flags |= VAR_SUB_ONE;
+ continue;
+ case 'W':
+ tmpparsestate.oneBigWord = TRUE;
+ continue;
+ }
+ break;
+ }
+
+ termc = *cp;
+
+ error = regcomp(&pattern.re, re, REG_EXTENDED);
+ free(re);
+ if (error) {
+ *lengthPtr = cp - start + 1;
+ VarREError(error, &pattern.re, "RE substitution error");
+ free(pattern.replace);
+ goto cleanup;
+ }
+
+ pattern.nsub = pattern.re.re_nsub + 1;
+ if (pattern.nsub < 1)
+ pattern.nsub = 1;
+ if (pattern.nsub > 10)
+ pattern.nsub = 10;
+ pattern.matches = bmake_malloc(pattern.nsub *
+ sizeof(regmatch_t));
+ newStr = VarModify(ctxt, &tmpparsestate, nstr,
+ VarRESubstitute,
+ &pattern);
+ regfree(&pattern.re);
+ free(pattern.replace);
+ free(pattern.matches);
+ delim = '\0';
+ break;
+ }
+#endif
+ case 'Q':
+ if (tstr[1] == endc || tstr[1] == ':') {
+ newStr = VarQuote(nstr);
+ cp = tstr + 1;
+ termc = *cp;
+ break;
+ }
+ goto default_case;
+ case 'T':
+ if (tstr[1] == endc || tstr[1] == ':') {
+ newStr = VarModify(ctxt, &parsestate, nstr, VarTail,
+ NULL);
+ cp = tstr + 1;
+ termc = *cp;
+ break;
+ }
+ goto default_case;
+ case 'H':
+ if (tstr[1] == endc || tstr[1] == ':') {
+ newStr = VarModify(ctxt, &parsestate, nstr, VarHead,
+ NULL);
+ cp = tstr + 1;
+ termc = *cp;
+ break;
+ }
+ goto default_case;
+ case 'E':
+ if (tstr[1] == endc || tstr[1] == ':') {
+ newStr = VarModify(ctxt, &parsestate, nstr, VarSuffix,
+ NULL);
+ cp = tstr + 1;
+ termc = *cp;
+ break;
+ }
+ goto default_case;
+ case 'R':
+ if (tstr[1] == endc || tstr[1] == ':') {
+ newStr = VarModify(ctxt, &parsestate, nstr, VarRoot,
+ NULL);
+ cp = tstr + 1;
+ termc = *cp;
+ break;
+ }
+ goto default_case;
+ case 'O':
+ {
+ char otype;
+
+ cp = tstr + 1; /* skip to the rest in any case */
+ if (tstr[1] == endc || tstr[1] == ':') {
+ otype = 's';
+ termc = *cp;
+ } else if ( (tstr[1] == 'x') &&
+ (tstr[2] == endc || tstr[2] == ':') ) {
+ otype = tstr[1];
+ cp = tstr + 2;
+ termc = *cp;
+ } else {
+ goto bad_modifier;
+ }
+ newStr = VarOrder(nstr, otype);
+ break;
+ }
+ case 'u':
+ if (tstr[1] == endc || tstr[1] == ':') {
+ newStr = VarUniq(nstr);
+ cp = tstr + 1;
+ termc = *cp;
+ break;
+ }
+ goto default_case;
+#ifdef SUNSHCMD
+ case 's':
+ if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
+ const char *emsg;
+ newStr = Cmd_Exec(nstr, &emsg);
+ if (emsg)
+ Error(emsg, nstr);
+ cp = tstr + 2;
+ termc = *cp;
+ break;
+ }
+ goto default_case;
+#endif
+ default:
+ default_case:
+ {
+#ifdef SYSVVARSUB
+ /*
+ * This can either be a bogus modifier or a System-V
+ * substitution command.
+ */
+ VarPattern pattern;
+ Boolean eqFound;
+
+ pattern.flags = 0;
+ eqFound = FALSE;
+ /*
+ * First we make a pass through the string trying
+ * to verify it is a SYSV-make-style translation:
+ * it must be: <string1>=<string2>)
+ */
+ cp = tstr;
+ cnt = 1;
+ while (*cp != '\0' && cnt) {
+ if (*cp == '=') {
+ eqFound = TRUE;
+ /* continue looking for endc */
+ }
+ else if (*cp == endc)
+ cnt--;
+ else if (*cp == startc)
+ cnt++;
+ if (cnt)
+ cp++;
+ }
+ if (*cp == endc && eqFound) {
+
+ /*
+ * Now we break this sucker into the lhs and
+ * rhs. We must null terminate them of course.
+ */
+ delim='=';
+ cp = tstr;
+ if ((pattern.lhs = VarGetPattern(ctxt, &parsestate,
+ errnum, &cp, delim, &pattern.flags,
+ &pattern.leftLen, NULL)) == NULL)
+ goto cleanup;
+ delim = endc;
+ if ((pattern.rhs = VarGetPattern(ctxt, &parsestate,
+ errnum, &cp, delim, NULL, &pattern.rightLen,
+ &pattern)) == NULL)
+ goto cleanup;
+
+ /*
+ * SYSV modifications happen through the whole
+ * string. Note the pattern is anchored at the end.
+ */
+ termc = *--cp;
+ delim = '\0';
+ if (pattern.leftLen == 0 && *nstr == '\0') {
+ newStr = nstr; /* special case */
+ } else {
+ newStr = VarModify(ctxt, &parsestate, nstr,
+ VarSYSVMatch,
+ &pattern);
+ }
+ free(UNCONST(pattern.lhs));
+ free(UNCONST(pattern.rhs));
+ } else
+#endif
+ {
+ Error("Unknown modifier '%c'", *tstr);
+ for (cp = tstr+1;
+ *cp != ':' && *cp != endc && *cp != '\0';
+ cp++)
+ continue;
+ termc = *cp;
+ newStr = var_Error;
+ }
+ }
+ }
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "Result of :%c is \"%s\"\n", modifier, newStr);
+ }
+
+ if (newStr != nstr) {
+ if (*freePtr) {
+ free(nstr);
+ *freePtr = NULL;
+ }
+ nstr = newStr;
+ if (nstr != var_Error && nstr != varNoError) {
+ *freePtr = nstr;
+ }
+ }
+ if (termc == '\0' && endc != '\0') {
+ Error("Unclosed variable specification (expecting '%c') for \"%s\" (value \"%s\") modifier %c", endc, v->name, nstr, modifier);
+ } else if (termc == ':') {
+ cp++;
+ }
+ tstr = cp;
+ }
+ out:
+ *lengthPtr = tstr - start;
+ return (nstr);
+
+ bad_modifier:
+ /* "{(" */
+ Error("Bad modifier `:%.*s' for %s", (int)strcspn(tstr, ":)}"), tstr,
+ v->name);
+
+ cleanup:
+ *lengthPtr = cp - start;
+ if (delim != '\0')
+ Error("Unclosed substitution for %s (%c missing)",
+ v->name, delim);
+ if (*freePtr) {
+ free(*freePtr);
+ *freePtr = NULL;
+ }
+ return (var_Error);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Var_Parse --
+ * Given the start of a variable invocation, extract the variable
+ * name and find its value, then modify it according to the
+ * specification.
+ *
+ * Input:
+ * str The string to parse
+ * ctxt The context for the variable
+ * errnum TRUE if undefined variables are an error
+ * lengthPtr OUT: The length of the specification
+ * freePtr OUT: Non-NULL if caller should free *freePtr
+ *
+ * Results:
+ * The (possibly-modified) value of the variable or var_Error if the
+ * specification is invalid. The length of the specification is
+ * placed in *lengthPtr (for invalid specifications, this is just
+ * 2...?).
+ * If *freePtr is non-NULL then it's a pointer that the caller
+ * should pass to free() to free memory used by the result.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* coverity[+alloc : arg-*4] */
+char *
+Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
+ void **freePtr)
+{
+ const char *tstr; /* Pointer into str */
+ Var *v; /* Variable in invocation */
+ Boolean haveModifier;/* TRUE if have modifiers for the variable */
+ char endc; /* Ending character when variable in parens
+ * or braces */
+ char startc; /* Starting character when variable in parens
+ * or braces */
+ int vlen; /* Length of variable name */
+ const char *start; /* Points to original start of str */
+ char *nstr; /* New string, used during expansion */
+ Boolean dynamic; /* TRUE if the variable is local and we're
+ * expanding it in a non-local context. This
+ * is done to support dynamic sources. The
+ * result is just the invocation, unaltered */
+ Var_Parse_State parsestate; /* Flags passed to helper functions */
+ char name[2];
+
+ *freePtr = NULL;
+ dynamic = FALSE;
+ start = str;
+ parsestate.oneBigWord = FALSE;
+ parsestate.varSpace = ' '; /* word separator */
+
+ startc = str[1];
+ if (startc != PROPEN && startc != BROPEN) {
+ /*
+ * If it's not bounded by braces of some sort, life is much simpler.
+ * We just need to check for the first character and return the
+ * value if it exists.
+ */
+
+ /* Error out some really stupid names */
+ if (startc == '\0' || strchr(")}:$", startc)) {
+ *lengthPtr = 1;
+ return var_Error;
+ }
+ name[0] = startc;
+ name[1] = '\0';
+
+ v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
+ if (v == NULL) {
+ *lengthPtr = 2;
+
+ if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
+ /*
+ * If substituting a local variable in a non-local context,
+ * assume it's for dynamic source stuff. We have to handle
+ * this specially and return the longhand for the variable
+ * with the dollar sign escaped so it makes it back to the
+ * caller. Only four of the local variables are treated
+ * specially as they are the only four that will be set
+ * when dynamic sources are expanded.
+ */
+ switch (str[1]) {
+ case '@':
+ return UNCONST("$(.TARGET)");
+ case '%':
+ return UNCONST("$(.ARCHIVE)");
+ case '*':
+ return UNCONST("$(.PREFIX)");
+ case '!':
+ return UNCONST("$(.MEMBER)");
+ }
+ }
+ /*
+ * Error
+ */
+ return (errnum ? var_Error : varNoError);
+ } else {
+ haveModifier = FALSE;
+ tstr = &str[1];
+ endc = str[1];
+ }
+ } else {
+ Buffer buf; /* Holds the variable name */
+
+ endc = startc == PROPEN ? PRCLOSE : BRCLOSE;
+ Buf_Init(&buf, 0);
+
+ /*
+ * Skip to the end character or a colon, whichever comes first.
+ */
+ for (tstr = str + 2;
+ *tstr != '\0' && *tstr != endc && *tstr != ':';
+ tstr++)
+ {
+ /*
+ * A variable inside a variable, expand
+ */
+ if (*tstr == '$') {
+ int rlen;
+ void *freeIt;
+ char *rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt);
+ if (rval != NULL) {
+ Buf_AddBytes(&buf, strlen(rval), rval);
+ }
+ if (freeIt)
+ free(freeIt);
+ tstr += rlen - 1;
+ }
+ else
+ Buf_AddByte(&buf, *tstr);
+ }
+ if (*tstr == ':') {
+ haveModifier = TRUE;
+ } else if (*tstr != '\0') {
+ haveModifier = FALSE;
+ } else {
+ /*
+ * If we never did find the end character, return NULL
+ * right now, setting the length to be the distance to
+ * the end of the string, since that's what make does.
+ */
+ *lengthPtr = tstr - str;
+ Buf_Destroy(&buf, TRUE);
+ return (var_Error);
+ }
+ str = Buf_GetAll(&buf, &vlen);
+
+ /*
+ * At this point, str points into newly allocated memory from
+ * buf, containing only the name of the variable.
+ *
+ * start and tstr point into the const string that was pointed
+ * to by the original value of the str parameter. start points
+ * to the '$' at the beginning of the string, while tstr points
+ * to the char just after the end of the variable name -- this
+ * will be '\0', ':', PRCLOSE, or BRCLOSE.
+ */
+
+ v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
+ /*
+ * Check also for bogus D and F forms of local variables since we're
+ * in a local context and the name is the right length.
+ */
+ if ((v == NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
+ (vlen == 2) && (str[1] == 'F' || str[1] == 'D') &&
+ strchr("@%*!<>", str[0]) != NULL) {
+ /*
+ * Well, it's local -- go look for it.
+ */
+ name[0] = *str;
+ name[1] = '\0';
+ v = VarFind(name, ctxt, 0);
+
+ if (v != NULL) {
+ /*
+ * No need for nested expansion or anything, as we're
+ * the only one who sets these things and we sure don't
+ * but nested invocations in them...
+ */
+ nstr = Buf_GetAll(&v->val, NULL);
+
+ if (str[1] == 'D') {
+ nstr = VarModify(ctxt, &parsestate, nstr, VarHead,
+ NULL);
+ } else {
+ nstr = VarModify(ctxt, &parsestate, nstr, VarTail,
+ NULL);
+ }
+ /*
+ * Resulting string is dynamically allocated, so
+ * tell caller to free it.
+ */
+ *freePtr = nstr;
+ *lengthPtr = tstr-start+1;
+ Buf_Destroy(&buf, TRUE);
+ VarFreeEnv(v, TRUE);
+ return nstr;
+ }
+ }
+
+ if (v == NULL) {
+ if (((vlen == 1) ||
+ (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) &&
+ ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
+ {
+ /*
+ * If substituting a local variable in a non-local context,
+ * assume it's for dynamic source stuff. We have to handle
+ * this specially and return the longhand for the variable
+ * with the dollar sign escaped so it makes it back to the
+ * caller. Only four of the local variables are treated
+ * specially as they are the only four that will be set
+ * when dynamic sources are expanded.
+ */
+ switch (*str) {
+ case '@':
+ case '%':
+ case '*':
+ case '!':
+ dynamic = TRUE;
+ break;
+ }
+ } else if ((vlen > 2) && (*str == '.') &&
+ isupper((unsigned char) str[1]) &&
+ ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
+ {
+ int len;
+
+ len = vlen - 1;
+ if ((strncmp(str, ".TARGET", len) == 0) ||
+ (strncmp(str, ".ARCHIVE", len) == 0) ||
+ (strncmp(str, ".PREFIX", len) == 0) ||
+ (strncmp(str, ".MEMBER", len) == 0))
+ {
+ dynamic = TRUE;
+ }
+ }
+
+ if (!haveModifier) {
+ /*
+ * No modifiers -- have specification length so we can return
+ * now.
+ */
+ *lengthPtr = tstr - start + 1;
+ if (dynamic) {
+ char *pstr = bmake_strndup(start, *lengthPtr);
+ *freePtr = pstr;
+ Buf_Destroy(&buf, TRUE);
+ return(pstr);
+ } else {
+ Buf_Destroy(&buf, TRUE);
+ return (errnum ? var_Error : varNoError);
+ }
+ } else {
+ /*
+ * Still need to get to the end of the variable specification,
+ * so kludge up a Var structure for the modifications
+ */
+ v = bmake_malloc(sizeof(Var));
+ v->name = UNCONST(str);
+ Buf_Init(&v->val, 1);
+ v->flags = VAR_JUNK;
+ Buf_Destroy(&buf, FALSE);
+ }
+ } else
+ Buf_Destroy(&buf, TRUE);
+ }
+
+ if (v->flags & VAR_IN_USE) {
+ Fatal("Variable %s is recursive.", v->name);
+ /*NOTREACHED*/
+ } else {
+ v->flags |= VAR_IN_USE;
+ }
+ /*
+ * Before doing any modification, we have to make sure the value
+ * has been fully expanded. If it looks like recursion might be
+ * necessary (there's a dollar sign somewhere in the variable's value)
+ * we just call Var_Subst to do any other substitutions that are
+ * necessary. Note that the value returned by Var_Subst will have
+ * been dynamically-allocated, so it will need freeing when we
+ * return.
+ */
+ nstr = Buf_GetAll(&v->val, NULL);
+ if (strchr(nstr, '$') != NULL) {
+ nstr = Var_Subst(NULL, nstr, ctxt, errnum);
+ *freePtr = nstr;
+ }
+
+ v->flags &= ~VAR_IN_USE;
+
+ if ((nstr != NULL) && haveModifier) {
+ int used;
+ /*
+ * Skip initial colon.
+ */
+ tstr++;
+
+ nstr = ApplyModifiers(nstr, tstr, startc, endc,
+ v, ctxt, errnum, &used, freePtr);
+ tstr += used;
+ }
+ if (*tstr) {
+ *lengthPtr = tstr - start + 1;
+ } else {
+ *lengthPtr = tstr - start;
+ }
+
+ if (v->flags & VAR_FROM_ENV) {
+ Boolean destroy = FALSE;
+
+ if (nstr != Buf_GetAll(&v->val, NULL)) {
+ destroy = TRUE;
+ } else {
+ /*
+ * Returning the value unmodified, so tell the caller to free
+ * the thing.
+ */
+ *freePtr = nstr;
+ }
+ VarFreeEnv(v, destroy);
+ } else if (v->flags & VAR_JUNK) {
+ /*
+ * Perform any free'ing needed and set *freePtr to NULL so the caller
+ * doesn't try to free a static pointer.
+ * If VAR_KEEP is also set then we want to keep str as is.
+ */
+ if (!(v->flags & VAR_KEEP)) {
+ if (*freePtr) {
+ free(nstr);
+ *freePtr = NULL;
+ }
+ if (dynamic) {
+ nstr = bmake_strndup(start, *lengthPtr);
+ *freePtr = nstr;
+ } else {
+ nstr = errnum ? var_Error : varNoError;
+ }
+ }
+ if (nstr != Buf_GetAll(&v->val, NULL))
+ Buf_Destroy(&v->val, TRUE);
+ free(v->name);
+ free(v);
+ }
+ return (nstr);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Var_Subst --
+ * Substitute for all variables in the given string in the given context
+ * If undefErr is TRUE, Parse_Error will be called when an undefined
+ * variable is encountered.
+ *
+ * Input:
+ * var Named variable || NULL for all
+ * str the string which to substitute
+ * ctxt the context wherein to find variables
+ * undefErr TRUE if undefineds are an error
+ *
+ * Results:
+ * The resulting string.
+ *
+ * Side Effects:
+ * None. The old string must be freed by the caller
+ *-----------------------------------------------------------------------
+ */
+char *
+Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
+{
+ Buffer buf; /* Buffer for forming things */
+ char *val; /* Value to substitute for a variable */
+ int length; /* Length of the variable invocation */
+ Boolean trailingBslash; /* variable ends in \ */
+ void *freeIt = NULL; /* Set if it should be freed */
+ static Boolean errorReported; /* Set true if an error has already
+ * been reported to prevent a plethora
+ * of messages when recursing */
+
+ Buf_Init(&buf, 0);
+ errorReported = FALSE;
+ trailingBslash = FALSE;
+
+ while (*str) {
+ if (*str == '\n' && trailingBslash)
+ Buf_AddByte(&buf, ' ');
+ if (var == NULL && (*str == '$') && (str[1] == '$')) {
+ /*
+ * A dollar sign may be escaped either with another dollar sign.
+ * In such a case, we skip over the escape character and store the
+ * dollar sign into the buffer directly.
+ */
+ str++;
+ Buf_AddByte(&buf, *str);
+ str++;
+ } else if (*str != '$') {
+ /*
+ * Skip as many characters as possible -- either to the end of
+ * the string or to the next dollar sign (variable invocation).
+ */
+ const char *cp;
+
+ for (cp = str++; *str != '$' && *str != '\0'; str++)
+ continue;
+ Buf_AddBytes(&buf, str - cp, cp);
+ } else {
+ if (var != NULL) {
+ int expand;
+ for (;;) {
+ if (str[1] == '\0') {
+ /* A trailing $ is kind of a special case */
+ Buf_AddByte(&buf, str[0]);
+ str++;
+ expand = FALSE;
+ } else if (str[1] != PROPEN && str[1] != BROPEN) {
+ if (str[1] != *var || strlen(var) > 1) {
+ Buf_AddBytes(&buf, 2, str);
+ str += 2;
+ expand = FALSE;
+ }
+ else
+ expand = TRUE;
+ break;
+ }
+ else {
+ const char *p;
+
+ /*
+ * Scan up to the end of the variable name.
+ */
+ for (p = &str[2]; *p &&
+ *p != ':' && *p != PRCLOSE && *p != BRCLOSE; p++)
+ if (*p == '$')
+ break;
+ /*
+ * A variable inside the variable. We cannot expand
+ * the external variable yet, so we try again with
+ * the nested one
+ */
+ if (*p == '$') {
+ Buf_AddBytes(&buf, p - str, str);
+ str = p;
+ continue;
+ }
+
+ if (strncmp(var, str + 2, p - str - 2) != 0 ||
+ var[p - str - 2] != '\0') {
+ /*
+ * Not the variable we want to expand, scan
+ * until the next variable
+ */
+ for (;*p != '$' && *p != '\0'; p++)
+ continue;
+ Buf_AddBytes(&buf, p - str, str);
+ str = p;
+ expand = FALSE;
+ }
+ else
+ expand = TRUE;
+ break;
+ }
+ }
+ if (!expand)
+ continue;
+ }
+
+ val = Var_Parse(str, ctxt, undefErr, &length, &freeIt);
+
+ /*
+ * When we come down here, val should either point to the
+ * value of this variable, suitably modified, or be NULL.
+ * Length should be the total length of the potential
+ * variable invocation (from $ to end character...)
+ */
+ if (val == var_Error || val == varNoError) {
+ /*
+ * If performing old-time variable substitution, skip over
+ * the variable and continue with the substitution. Otherwise,
+ * store the dollar sign and advance str so we continue with
+ * the string...
+ */
+ if (oldVars) {
+ str += length;
+ } else if (undefErr) {
+ /*
+ * If variable is undefined, complain and skip the
+ * variable. The complaint will stop us from doing anything
+ * when the file is parsed.
+ */
+ if (!errorReported) {
+ Parse_Error(PARSE_FATAL,
+ "Undefined variable \"%.*s\"",length,str);
+ }
+ str += length;
+ errorReported = TRUE;
+ } else {
+ Buf_AddByte(&buf, *str);
+ str += 1;
+ }
+ } else {
+ /*
+ * We've now got a variable structure to store in. But first,
+ * advance the string pointer.
+ */
+ str += length;
+
+ /*
+ * Copy all the characters from the variable value straight
+ * into the new string.
+ */
+ length = strlen(val);
+ Buf_AddBytes(&buf, length, val);
+ trailingBslash = length > 0 && val[length - 1] == '\\';
+ }
+ if (freeIt) {
+ free(freeIt);
+ freeIt = NULL;
+ }
+ }
+ }
+
+ return Buf_DestroyCompact(&buf);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Var_GetTail --
+ * Return the tail from each of a list of words. Used to set the
+ * System V local variables.
+ *
+ * Input:
+ * file Filename to modify
+ *
+ * Results:
+ * The resulting string.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+#if 0
+char *
+Var_GetTail(char *file)
+{
+ return(VarModify(file, VarTail, NULL));
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Var_GetHead --
+ * Find the leading components of a (list of) filename(s).
+ * XXX: VarHead does not replace foo by ., as (sun) System V make
+ * does.
+ *
+ * Input:
+ * file Filename to manipulate
+ *
+ * Results:
+ * The leading components.
+ *
+ * Side Effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------
+ */
+char *
+Var_GetHead(char *file)
+{
+ return(VarModify(file, VarHead, NULL));
+}
+#endif
+
+/*-
+ *-----------------------------------------------------------------------
+ * Var_Init --
+ * Initialize the module
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The VAR_CMD and VAR_GLOBAL contexts are created
+ *-----------------------------------------------------------------------
+ */
+void
+Var_Init(void)
+{
+ VAR_GLOBAL = Targ_NewGN("Global");
+ VAR_CMD = Targ_NewGN("Command");
+
+}
+
+
+void
+Var_End(void)
+{
+}
+
+
+/****************** PRINT DEBUGGING INFO *****************/
+static void
+VarPrintVar(void *vp)
+{
+ Var *v = (Var *)vp;
+ fprintf(debug_file, "%-16s = %s\n", v->name, Buf_GetAll(&v->val, NULL));
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Var_Dump --
+ * print all variables in a context
+ *-----------------------------------------------------------------------
+ */
+void
+Var_Dump(GNode *ctxt)
+{
+ Hash_Search search;
+ Hash_Entry *h;
+
+ for (h = Hash_EnumFirst(&ctxt->context, &search);
+ h != NULL;
+ h = Hash_EnumNext(&search)) {
+ VarPrintVar(Hash_GetValue(h));
+ }
+}
diff --git a/external/bsd/bmake/dist/wait.h b/external/bsd/bmake/dist/wait.h
new file mode 100644
index 0000000..7408d15
--- /dev/null
+++ b/external/bsd/bmake/dist/wait.h
@@ -0,0 +1,81 @@
+/* NAME:
+ * wait.h - compensate for what vendors leave out
+ *
+ * AUTHOR:
+ * Simon J. Gerraty <sjg@crufty.net>
+ */
+/*
+ * RCSid:
+ * $Id: wait.h,v 1.6 2002/11/26 07:53:06 sjg Exp $
+ *
+ * @(#)Copyright (c) 1994, Simon J. Gerraty.
+ *
+ * This is free software. It comes with NO WARRANTY.
+ * Permission to use, modify and distribute this source code
+ * is granted subject to the following conditions.
+ * 1/ that the above copyright notice and this notice
+ * are preserved in all copies and that due credit be given
+ * to the author.
+ * 2/ that any changes to this code are clearly commented
+ * as such so that the author does not get blamed for bugs
+ * other than his own.
+ *
+ * Please send copies of changes and bug-fixes to:
+ * sjg@crufty.net
+ */
+
+#include <sys/wait.h>
+
+#ifdef sun386
+# define UNION_WAIT
+# define WEXITSTATUS(x) ((&x)->w_retcode)
+# define WTERMSIG(x) ((&x)->w_termsig)
+# define WSTOPSIG(x) ((&x)->w_stopsig)
+# define HAVE_WAIT4
+#endif
+
+#ifndef WAIT_T
+# ifdef UNION_WAIT
+# define WAIT_T union wait
+# define WAIT_STATUS(x) (x).w_status
+# else
+# define WAIT_T int
+# define WAIT_STATUS(x) x
+# endif
+#endif
+
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(_X) (((int)(_X)>>8)&0377)
+#endif
+#ifndef WSTOPPED
+# define WSTOPPED 0177
+#endif
+#ifndef WSTOPSIG
+# define WSTOPSIG(x) WSTOPPED
+#endif
+
+#ifdef UNION_WAIT
+#ifndef WSET_STOPCODE
+#define WSET_STOPCODE(x, sig) ((&x)->w_stopsig = (sig))
+#endif
+#ifndef WSET_EXITCODE
+#define WSET_EXITCODE(x, ret, sig) ((&x)->w_termsig = (sig), (&x)->w_retcode = (ret))
+#endif
+#else
+#ifndef WSET_STOPCODE
+#define WSET_STOPCODE(x, sig) ((x) = ((sig) << 8) | 0177)
+#endif
+#ifndef WSET_EXITCODE
+#define WSET_EXITCODE(x, ret, sig) ((x) = (ret << 8) | (sig))
+#endif
+#endif
+
+#ifndef HAVE_WAITPID
+# ifdef HAVE_WAIT4
+# define waitpid(pid, statusp, flags) wait4(pid, statusp, flags, (char *)0)
+# else
+# ifdef HAVE_WAIT3
+# define waitpid(pid, statusp, flags) wait3(statusp, flags, (char *)0)
+# endif
+# endif
+#endif
diff --git a/external/bsd/bmake/usr.bin/Makefile b/external/bsd/bmake/usr.bin/Makefile
new file mode 100644
index 0000000..dac316e
--- /dev/null
+++ b/external/bsd/bmake/usr.bin/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= bmake
+
+.include <bsd.subdir.mk>
diff --git a/external/bsd/bmake/usr.bin/bmake/Makefile b/external/bsd/bmake/usr.bin/bmake/Makefile
new file mode 100644
index 0000000..8be2bfa
--- /dev/null
+++ b/external/bsd/bmake/usr.bin/bmake/Makefile
@@ -0,0 +1,210 @@
+# This is a generated file, do NOT edit!
+# See external/bsd/bmake/dist/bsd.after-import.mk
+#
+# $FreeBSD$
+
+SRCTOP?= ${.CURDIR:H:H:H:H:H}
+
+
+# look here first for config.h
+CFLAGS+= -I${.CURDIR}
+
+# $NetBSD: Makefile,v 1.56 2012/05/30 21:54:23 sjg Exp $
+# @(#)Makefile 5.2 (Berkeley) 12/28/90
+
+# $Id: Makefile.in,v 1.168 2012/07/05 04:10:23 sjg Exp $
+
+PROG= bmake
+SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \
+ make.c parse.c str.c suff.c targ.c trace.c var.c util.c
+SRCS+= strlist.c
+SRCS+= make_malloc.c
+SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \
+ lstDatum.c lstDeQueue.c lstDestroy.c lstDupl.c lstEnQueue.c \
+ lstFind.c lstFindFrom.c lstFirst.c lstForEach.c lstForEachFrom.c \
+ lstInit.c lstInsert.c lstIsAtEnd.c lstIsEmpty.c lstLast.c \
+ lstMember.c lstNext.c lstOpen.c lstRemove.c lstReplace.c lstSucc.c
+SRCS += lstPrev.c
+
+# you can use this Makefile if you have an earlier version of bmake.
+prefix= /usr
+srcdir= ${SRCTOP}/external/bsd/bmake/dist
+CC?= gcc
+
+# Base version on src date
+MAKE_VERSION= 20120704
+DEFAULT_SYS_PATH = .../share/mk:/usr/share/mk
+
+CPPFLAGS+=
+CFLAGS+= ${CPPFLAGS}
+CFLAGS+= -D_PATH_DEFSYSPATH=\"${DEFAULT_SYS_PATH}\"
+CFLAGS+= -I. -I${srcdir} -DHAVE_CONFIG_H ${XDEFS} -DMAKE_NATIVE
+CFLAGS+= ${CFLAGS_${.TARGET:T}}
+CFLAGS+= ${COPTS.${.ALLSRC:M*.c:T:u}}
+COPTS.main.c+= "-DMAKE_VERSION=\"${MAKE_VERSION}\""
+LDFLAGS=
+LIBOBJS= ${LIBOBJDIR}stresep$U.o
+LDADD=
+
+.if !empty(LIBOBJS)
+SRCS+= ${LIBOBJS:T:.o=.c}
+.endif
+
+USE_META = yes
+.if ${USE_META} != "no"
+SRCS+= meta.c
+CPPFLAGS+= -DUSE_META
+FILEMON_H ?= /usr/include/dev/filemon/filemon.h
+.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
+COPTS.meta.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
+.endif
+.endif
+
+.PATH: ${srcdir}
+.PATH: ${srcdir}/lst.lib
+
+OS!= uname -s
+ARCH!= uname -p 2>/dev/null || uname -m
+
+# list of OS's which are derrived from BSD4.4
+isBSD44= NetBSD FreeBSD OpenBSD DragonFly
+
+.if ${OS} == "NetBSD"
+# Don't set these for anyone else since we don't know what the effect may be.
+# On FreeBSD WARNS=2 sets a bunch of -W flags that make does not handle.
+WFORMAT= 1
+WARNS=4
+.NOPATH: bmake.cat1
+.if make(install) && exists(${DESTDIR}/usr/share/doc)
+SUBDIR= PSD.doc
+.endif
+.endif
+
+.if empty(isBSD44:M${OS})
+# XXX not sure if we still want this given that configure
+# lets us force or not the definition of MACHINE.
+CFLAGS_main.o+= "-DFORCE_MACHINE=\"${MACHINE}\""
+MANTARGET=cat
+INSTALL?=${srcdir}/install-sh
+.if (${MACHINE} == "sun386")
+# even I don't have one of these anymore :-)
+CFLAGS+= -DPORTAR
+.elif (${MACHINE} != "sunos")
+SRCS+= sigcompat.c
+CFLAGS+= -DSIGNAL_FLAGS=SA_RESTART
+.endif
+.endif
+.if defined(.PARSEDIR)
+.if make(obj) || make(clean)
+SUBDIR+= unit-tests
+.endif
+.endif
+
+# many systems use gcc these days
+CC_IS_GCC=yes
+.if ${CC_IS_GCC} == "yes"
+# problem with gcc3
+CFLAGS_var.o+= -Wno-cast-qual
+.endif
+
+CFLAGS_main.o+= "-DMACHINE=\"${MACHINE}\"" "-DMACHINE_ARCH=\"${MACHINE_ARCH}\""
+
+EXTRACT_MAN=no
+
+MAN=${PROG}.1
+.if (${PROG} != "make")
+${MAN}: make.1
+ @echo making ${PROG}.1
+ @sed -e 's/^.Nx/NetBSD/' -e '/^.Nm/s/make/${PROG}/' -e '/^.Sh HISTORY/,$$d' ${srcdir}/make.1 > $@
+ @(echo ".Sh HISTORY"; \
+ echo ".Nm"; \
+ echo "is derived from NetBSD"; \
+ echo ".Xr make 1 ."; \
+ echo It uses autoconf to facilitate portability to other platforms.) >> $@
+
+.endif
+
+.if !empty(isBSD44:M${OS})
+.if "${OS}" != "NetBSD"
+MAN1=${MAN}
+.endif
+MANTARGET?=man
+.endif
+
+MANTARGET?= cat
+MANDEST?= ${MANDIR}/${MANTARGET}1
+
+.if ${MANTARGET} == "cat"
+_mfromdir=${srcdir}
+.endif
+
+.if exists(${srcdir}/../Makefile.inc)
+.include "${srcdir}/../Makefile.inc"
+.endif
+.sinclude <bsd.prog.mk>
+# sigh, FreeBSD at least includes bsd.subdir.mk via bsd.obj.mk
+# so the inclusion below, results in complaints about re-defined
+# targets. For NetBSD though we need to explicitly include it.
+.if defined(.PARSEDIR)
+.if defined(SUBDIR) && !target(${SUBDIR:[1]})
+.sinclude <bsd.subdir.mk>
+.endif
+.endif
+
+CPPFLAGS+= -DMAKE_NATIVE
+COPTS.var.c += -Wno-cast-qual
+COPTS.job.c += -Wno-format-nonliteral
+COPTS.parse.c += -Wno-format-nonliteral
+COPTS.var.c += -Wno-format-nonliteral
+
+# Force these
+BINDIR= ${prefix}/bin
+MANDIR= ${prefix}/man
+
+arch.o: config.h
+# make sure that MAKE_VERSION gets updated.
+main.o: ${SRCS} ${MAKEFILE}
+
+MK?=${prefix}/share/mk
+MKSRC?=mk
+INSTALL?=${srcdir}/install-sh
+
+beforeinstall:
+ test -d ${DESTDIR}${BINDIR} || ${INSTALL} -m 775 -d ${DESTDIR}${BINDIR}
+ test -d ${DESTDIR}${MANDEST} || ${INSTALL} -m 775 -d ${DESTDIR}${MANDEST}
+
+# latest version of *.mk includes an installer.
+# you should not need to set USE_OS
+install-mk:
+.if exists(${MKSRC}/install-mk)
+ test -d ${DESTDIR}${MK} || ${INSTALL} -m 775 -d ${DESTDIR}${MK}
+ ${MKSRC}/install-mk -v -m 644 ${DESTDIR}${MK} ${USE_OS}
+.else
+ @echo need to unpack mk.tar.gz under ${srcdir} or set MKSRC; false
+.endif
+
+.ifdef TOOLDIR
+# this is a native netbsd build,
+# use libutil rather than the local emalloc etc.
+CPPFLAGS+= -DUSE_EMALLOC
+LDADD+=-lutil
+DPADD+=${LIBUTIL}
+.endif
+
+# A simple unit-test driver to help catch regressions
+accept test:
+ cd ${.CURDIR}/unit-tests && MAKEFLAGS= ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
+
+# override some simple things
+BINDIR= /usr/bin
+MANDIR= /usr/share/man
+
+# make sure we get this
+CFLAGS+= ${COPTS.${.IMPSRC:T}}
+CLEANFILES+= bootstrap
+
+after-import: ${SRCTOP}/external/bsd/bmake/dist/bsd.after-import.mk
+ cd ${.CURDIR} && ${.MAKE} -f ${SRCTOP}/external/bsd/bmake/dist/bsd.after-import.mk
+
+.sinclude "Makefile.inc"
+
diff --git a/external/bsd/bmake/usr.bin/bmake/Makefile.depend b/external/bsd/bmake/usr.bin/bmake/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/external/bsd/bmake/usr.bin/bmake/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/external/bsd/bmake/usr.bin/bmake/Makefile.inc b/external/bsd/bmake/usr.bin/bmake/Makefile.inc
new file mode 100644
index 0000000..090deb7
--- /dev/null
+++ b/external/bsd/bmake/usr.bin/bmake/Makefile.inc
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+.if defined(.PARSEDIR)
+# make sure this is available to unit-tests/Makefile
+.export SRCTOP
+.endif
diff --git a/external/bsd/bmake/usr.bin/bmake/config.h b/external/bsd/bmake/usr.bin/bmake/config.h
new file mode 100644
index 0000000..9cf8c8a
--- /dev/null
+++ b/external/bsd/bmake/usr.bin/bmake/config.h
@@ -0,0 +1,315 @@
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* Path of default shell */
+/* #undef DEFSHELL_CUSTOM */
+
+/* Shell spec to use by default */
+/* #undef DEFSHELL_INDEX */
+
+/* Define to 1 if you have the <ar.h> header file. */
+#define HAVE_AR_H 1
+
+/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
+ don't. */
+#define HAVE_DECL_SYS_SIGLIST 1
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the `dirname' function. */
+#define HAVE_DIRNAME 1
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Define to 1 if you have the `err' function. */
+#define HAVE_ERR 1
+
+/* Define to 1 if you have the `errx' function. */
+#define HAVE_ERRX 1
+
+/* Define to 1 if you have the <err.h> header file. */
+#define HAVE_ERR_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `fork' function. */
+#define HAVE_FORK 1
+
+/* Define to 1 if you have the `getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define to 1 if you have the `getenv' function. */
+#define HAVE_GETENV 1
+
+/* Define to 1 if you have the `getopt' function. */
+#define HAVE_GETOPT 1
+
+/* Define to 1 if you have the `getwd' function. */
+#define HAVE_GETWD 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `killpg' function. */
+#define HAVE_KILLPG 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mmap' function. */
+#define HAVE_MMAP 1
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the <paths.h> header file. */
+#define HAVE_PATHS_H 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#define HAVE_POLL_H 1
+
+/* Define to 1 if you have the `putenv' function. */
+#define HAVE_PUTENV 1
+
+/* Define to 1 if you have the <ranlib.h> header file. */
+#define HAVE_RANLIB_H 1
+
+/* Define to 1 if you have the `realpath' function. */
+#define HAVE_REALPATH 1
+
+/* Define to 1 if you have the `select' function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the `setenv' function. */
+#define HAVE_SETENV 1
+
+/* Define to 1 if you have the `setpgid' function. */
+#define HAVE_SETPGID 1
+
+/* Define to 1 if you have the `setsid' function. */
+#define HAVE_SETSID 1
+
+/* Define to 1 if you have the `sigaction' function. */
+#define HAVE_SIGACTION 1
+
+/* Define to 1 if you have the `sigvec' function. */
+#define HAVE_SIGVEC 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `stresep' function. */
+/* #undef HAVE_STRESEP */
+
+/* Define to 1 if you have the `strftime' function. */
+#define HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+#define HAVE_STRLCPY 1
+
+/* Define to 1 if you have the `strsep' function. */
+#define HAVE_STRSEP 1
+
+/* Define to 1 if you have the `strtod' function. */
+#define HAVE_STRTOD 1
+
+/* Define to 1 if you have the `strtol' function. */
+#define HAVE_STRTOL 1
+
+/* Define to 1 if `struct stat' is a member of `st_rdev'. */
+#define HAVE_STRUCT_STAT_ST_RDEV 1
+
+/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
+ `HAVE_STRUCT_STAT_ST_RDEV' instead. */
+#define HAVE_ST_RDEV 1
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#define HAVE_SYS_MMAN_H 1
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `unsetenv' function. */
+#define HAVE_UNSETENV 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the `vfork' function. */
+#define HAVE_VFORK 1
+
+/* Define to 1 if you have the <vfork.h> header file. */
+/* #undef HAVE_VFORK_H */
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define to 1 if you have the `wait3' function. */
+#define HAVE_WAIT3 1
+
+/* Define to 1 if you have the `wait4' function. */
+#define HAVE_WAIT4 1
+
+/* Define to 1 if you have the `waitpid' function. */
+#define HAVE_WAITPID 1
+
+/* Define to 1 if you have the `warn' function. */
+#define HAVE_WARN 1
+
+/* Define to 1 if you have the `warnx' function. */
+#define HAVE_WARNX 1
+
+/* Define to 1 if `fork' works. */
+#define HAVE_WORKING_FORK 1
+
+/* Define to 1 if `vfork' works. */
+#define HAVE_WORKING_VFORK 1
+
+/* define if your compiler has __attribute__ */
+/* #undef HAVE___ATTRIBUTE__ */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "sjg@NetBSD.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "bmake"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "bmake 20120620"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "bmake"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "20120620"
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* # undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `long int' if <sys/types.h> does not define. */
+/* #undef off_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef pid_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define as `fork' if `vfork' does not work. */
+/* #undef vfork */
diff --git a/external/bsd/bmake/usr.bin/bmake/unit-tests/Makefile b/external/bsd/bmake/usr.bin/bmake/unit-tests/Makefile
new file mode 100644
index 0000000..72259f4
--- /dev/null
+++ b/external/bsd/bmake/usr.bin/bmake/unit-tests/Makefile
@@ -0,0 +1,96 @@
+# $Id: Makefile.in,v 1.38 2012/06/19 23:38:48 sjg Exp $
+#
+# $NetBSD: Makefile,v 1.34 2012/06/19 23:25:53 sjg Exp $
+#
+# Unit tests for make(1)
+# The main targets are:
+#
+# all: run all the tests
+# test: run 'all', capture output and compare to expected results
+# accept: move generated output to expected results
+#
+# Adding a test case.
+# Each feature should get its own set of tests in its own suitably
+# named makefile which should be added to SUBFILES to hook it in.
+#
+
+srcdir= ${SRCTOP}/external/bsd/bmake/dist/unit-tests
+
+.MAIN: all
+
+UNIT_TESTS:= ${srcdir}
+
+# Simple sub-makefiles - we run them as a black box
+# keep the list sorted.
+SUBFILES= \
+ comment \
+ cond1 \
+ error \
+ export \
+ export-all \
+ doterror \
+ dotwait \
+ forloop \
+ forsubst \
+ hash \
+ misc \
+ moderrs \
+ modmatch \
+ modmisc \
+ modorder \
+ modts \
+ modword \
+ phony-end \
+ posix \
+ qequals \
+ sysv \
+ ternary \
+ unexport \
+ unexport-env \
+ varcmd
+
+all: ${SUBFILES}
+
+flags.doterror=
+
+# the tests are actually done with sub-makes.
+.PHONY: ${SUBFILES}
+.PRECIOUS: ${SUBFILES}
+${SUBFILES}:
+ -@${.MAKE} ${flags.$@:U-k} -f ${UNIT_TESTS}/$@
+
+clean:
+ rm -f *.out *.fail *.core
+
+.sinclude <bsd.obj.mk>
+
+TEST_MAKE?= ${.MAKE}
+TOOL_SED?= sed
+TOOL_TR?= tr
+TOOL_DIFF?= diff
+DIFF_FLAGS?= -u
+
+# ensure consistent results from sort(1)
+LC_ALL= C
+LANG= C
+.export LANG LC_ALL
+
+# The driver.
+# We always pretend .MAKE was called 'make'
+# and strip ${.CURDIR}/ from the output
+# and replace anything after 'stopped in' with unit-tests
+# so the results can be compared.
+test:
+ @echo "${TEST_MAKE} -f ${MAKEFILE} > ${.TARGET}.out 2>&1"
+ @cd ${.OBJDIR} && ${TEST_MAKE} -f ${MAKEFILE} 2>&1 | \
+ ${TOOL_TR} -d '\015' | \
+ ${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}:,make:,' \
+ -e '/stopped/s, /.*, unit-tests,' \
+ -e 's,${.CURDIR:C/\./\\\./g}/,,g' \
+ -e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' > ${.TARGET}.out || { \
+ tail ${.TARGET}.out; mv ${.TARGET}.out ${.TARGET}.fail; exit 1; }
+ ${TOOL_DIFF} ${DIFF_FLAGS} ${UNIT_TESTS}/${.TARGET}.exp ${.TARGET}.out
+
+accept:
+ mv test.out ${srcdir}/test.exp
+
diff --git a/games/bcd/Makefile.depend b/games/bcd/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/games/bcd/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/caesar/Makefile.depend b/games/caesar/Makefile.depend
new file mode 100644
index 0000000..d78f7b7
--- /dev/null
+++ b/games/caesar/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/factor/Makefile.depend b/games/factor/Makefile.depend
new file mode 100644
index 0000000..1ae71d9
--- /dev/null
+++ b/games/factor/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/fortune/datfiles/Makefile.depend b/games/fortune/datfiles/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/games/fortune/datfiles/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/fortune/fortune/Makefile.depend b/games/fortune/fortune/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/games/fortune/fortune/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/fortune/strfile/Makefile.depend b/games/fortune/strfile/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/games/fortune/strfile/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/fortune/unstr/Makefile.depend b/games/fortune/unstr/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/games/fortune/unstr/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/grdc/Makefile.depend b/games/grdc/Makefile.depend
new file mode 100644
index 0000000..18bcf60
--- /dev/null
+++ b/games/grdc/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/morse/Makefile.depend b/games/morse/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/games/morse/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/number/Makefile.depend b/games/number/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/games/number/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/pom/Makefile.depend b/games/pom/Makefile.depend
new file mode 100644
index 0000000..d78f7b7
--- /dev/null
+++ b/games/pom/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/ppt/Makefile.depend b/games/ppt/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/games/ppt/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/primes/Makefile.depend b/games/primes/Makefile.depend
new file mode 100644
index 0000000..d78f7b7
--- /dev/null
+++ b/games/primes/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/games/random/Makefile.depend b/games/random/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/games/random/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/lib/csu/Makefile.depend b/gnu/lib/csu/Makefile.depend
new file mode 100644
index 0000000..04f30e7
--- /dev/null
+++ b/gnu/lib/csu/Makefile.depend
@@ -0,0 +1,46 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+crtbegin.o: options.h
+crtbegin.o: tconfig.h
+crtbegin.o: tm.h
+crtbegin.po: options.h
+crtbegin.po: tconfig.h
+crtbegin.po: tm.h
+crtbeginS.o: options.h
+crtbeginS.o: tconfig.h
+crtbeginS.o: tm.h
+crtbeginS.po: options.h
+crtbeginS.po: tconfig.h
+crtbeginS.po: tm.h
+crtbeginT.o: options.h
+crtbeginT.o: tconfig.h
+crtbeginT.o: tm.h
+crtbeginT.po: options.h
+crtbeginT.po: tconfig.h
+crtbeginT.po: tm.h
+crtend.o: options.h
+crtend.o: tconfig.h
+crtend.o: tm.h
+crtend.po: options.h
+crtend.po: tconfig.h
+crtend.po: tm.h
+crtendS.o: options.h
+crtendS.o: tconfig.h
+crtendS.o: tm.h
+crtendS.po: options.h
+crtendS.po: tconfig.h
+crtendS.po: tm.h
+.endif
diff --git a/gnu/lib/libdialog/Makefile.depend b/gnu/lib/libdialog/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/gnu/lib/libdialog/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/lib/libgcc/Makefile.depend b/gnu/lib/libgcc/Makefile.depend
new file mode 100644
index 0000000..3b4ce39
--- /dev/null
+++ b/gnu/lib/libgcc/Makefile.depend
@@ -0,0 +1,281 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+__main.So: options.h
+__main.So: tconfig.h
+__main.So: tm.h
+_absvdi2.So: options.h
+_absvdi2.So: tconfig.h
+_absvdi2.So: tm.h
+_absvsi2.So: options.h
+_absvsi2.So: tconfig.h
+_absvsi2.So: tm.h
+_addvdi3.So: options.h
+_addvdi3.So: tconfig.h
+_addvdi3.So: tm.h
+_addvsi3.So: options.h
+_addvsi3.So: tconfig.h
+_addvsi3.So: tm.h
+_ashldi3.So: options.h
+_ashldi3.So: tconfig.h
+_ashldi3.So: tm.h
+_ashrdi3.So: options.h
+_ashrdi3.So: tconfig.h
+_ashrdi3.So: tm.h
+_clear_cache.So: options.h
+_clear_cache.So: tconfig.h
+_clear_cache.So: tm.h
+_clz.So: options.h
+_clz.So: tconfig.h
+_clz.So: tm.h
+_clzdi2.So: options.h
+_clzdi2.So: tconfig.h
+_clzdi2.So: tm.h
+_clzsi2.So: options.h
+_clzsi2.So: tconfig.h
+_clzsi2.So: tm.h
+_cmpdi2.So: options.h
+_cmpdi2.So: tconfig.h
+_cmpdi2.So: tm.h
+_ctors.So: options.h
+_ctors.So: tconfig.h
+_ctors.So: tm.h
+_ctzdi2.So: options.h
+_ctzdi2.So: tconfig.h
+_ctzdi2.So: tm.h
+_ctzsi2.So: options.h
+_ctzsi2.So: tconfig.h
+_ctzsi2.So: tm.h
+_divdc3.So: options.h
+_divdc3.So: tconfig.h
+_divdc3.So: tm.h
+_divdi3.So: options.h
+_divdi3.So: tconfig.h
+_divdi3.So: tm.h
+_divsc3.So: options.h
+_divsc3.So: tconfig.h
+_divsc3.So: tm.h
+_divtc3.So: options.h
+_divtc3.So: tconfig.h
+_divtc3.So: tm.h
+_divxc3.So: options.h
+_divxc3.So: tconfig.h
+_divxc3.So: tm.h
+_enable_execute_stack.So: options.h
+_enable_execute_stack.So: tconfig.h
+_enable_execute_stack.So: tm.h
+_ffsdi2.So: options.h
+_ffsdi2.So: tconfig.h
+_ffsdi2.So: tm.h
+_ffssi2.So: options.h
+_ffssi2.So: tconfig.h
+_ffssi2.So: tm.h
+_fixdfdi.So: options.h
+_fixdfdi.So: tconfig.h
+_fixdfdi.So: tm.h
+_fixsfdi.So: options.h
+_fixsfdi.So: tconfig.h
+_fixsfdi.So: tm.h
+_fixtfdi.So: options.h
+_fixtfdi.So: tconfig.h
+_fixtfdi.So: tm.h
+_fixunsdfdi.So: options.h
+_fixunsdfdi.So: tconfig.h
+_fixunsdfdi.So: tm.h
+_fixunsdfsi.So: options.h
+_fixunsdfsi.So: tconfig.h
+_fixunsdfsi.So: tm.h
+_fixunssfdi.So: options.h
+_fixunssfdi.So: tconfig.h
+_fixunssfdi.So: tm.h
+_fixunssfsi.So: options.h
+_fixunssfsi.So: tconfig.h
+_fixunssfsi.So: tm.h
+_fixunstfdi.So: options.h
+_fixunstfdi.So: tconfig.h
+_fixunstfdi.So: tm.h
+_fixunsxfdi.So: options.h
+_fixunsxfdi.So: tconfig.h
+_fixunsxfdi.So: tm.h
+_fixunsxfsi.So: options.h
+_fixunsxfsi.So: tconfig.h
+_fixunsxfsi.So: tm.h
+_fixxfdi.So: options.h
+_fixxfdi.So: tconfig.h
+_fixxfdi.So: tm.h
+_floatdidf.So: options.h
+_floatdidf.So: tconfig.h
+_floatdidf.So: tm.h
+_floatdisf.So: options.h
+_floatdisf.So: tconfig.h
+_floatdisf.So: tm.h
+_floatditf.So: options.h
+_floatditf.So: tconfig.h
+_floatditf.So: tm.h
+_floatdixf.So: options.h
+_floatdixf.So: tconfig.h
+_floatdixf.So: tm.h
+_floatundidf.So: options.h
+_floatundidf.So: tconfig.h
+_floatundidf.So: tm.h
+_floatundisf.So: options.h
+_floatundisf.So: tconfig.h
+_floatundisf.So: tm.h
+_floatunditf.So: options.h
+_floatunditf.So: tconfig.h
+_floatunditf.So: tm.h
+_floatundixf.So: options.h
+_floatundixf.So: tconfig.h
+_floatundixf.So: tm.h
+_lshrdi3.So: options.h
+_lshrdi3.So: tconfig.h
+_lshrdi3.So: tm.h
+_moddi3.So: options.h
+_moddi3.So: tconfig.h
+_moddi3.So: tm.h
+_muldc3.So: options.h
+_muldc3.So: tconfig.h
+_muldc3.So: tm.h
+_muldi3.So: options.h
+_muldi3.So: tconfig.h
+_muldi3.So: tm.h
+_mulsc3.So: options.h
+_mulsc3.So: tconfig.h
+_mulsc3.So: tm.h
+_multc3.So: options.h
+_multc3.So: tconfig.h
+_multc3.So: tm.h
+_mulvdi3.So: options.h
+_mulvdi3.So: tconfig.h
+_mulvdi3.So: tm.h
+_mulvsi3.So: options.h
+_mulvsi3.So: tconfig.h
+_mulvsi3.So: tm.h
+_mulxc3.So: options.h
+_mulxc3.So: tconfig.h
+_mulxc3.So: tm.h
+_negdi2.So: options.h
+_negdi2.So: tconfig.h
+_negdi2.So: tm.h
+_negvdi2.So: options.h
+_negvdi2.So: tconfig.h
+_negvdi2.So: tm.h
+_negvsi2.So: options.h
+_negvsi2.So: tconfig.h
+_negvsi2.So: tm.h
+_paritydi2.So: options.h
+_paritydi2.So: tconfig.h
+_paritydi2.So: tm.h
+_paritysi2.So: options.h
+_paritysi2.So: tconfig.h
+_paritysi2.So: tm.h
+_popcount_tab.So: options.h
+_popcount_tab.So: tconfig.h
+_popcount_tab.So: tm.h
+_popcountdi2.So: options.h
+_popcountdi2.So: tconfig.h
+_popcountdi2.So: tm.h
+_popcountsi2.So: options.h
+_popcountsi2.So: tconfig.h
+_popcountsi2.So: tm.h
+_powidf2.So: options.h
+_powidf2.So: tconfig.h
+_powidf2.So: tm.h
+_powisf2.So: options.h
+_powisf2.So: tconfig.h
+_powisf2.So: tm.h
+_powitf2.So: options.h
+_powitf2.So: tconfig.h
+_powitf2.So: tm.h
+_powixf2.So: options.h
+_powixf2.So: tconfig.h
+_powixf2.So: tm.h
+_subvdi3.So: options.h
+_subvdi3.So: tconfig.h
+_subvdi3.So: tm.h
+_subvsi3.So: options.h
+_subvsi3.So: tconfig.h
+_subvsi3.So: tm.h
+_trampoline.So: options.h
+_trampoline.So: tconfig.h
+_trampoline.So: tm.h
+_ucmpdi2.So: options.h
+_ucmpdi2.So: tconfig.h
+_ucmpdi2.So: tm.h
+_udiv_w_sdiv.So: options.h
+_udiv_w_sdiv.So: tconfig.h
+_udiv_w_sdiv.So: tm.h
+_udivdi3.So: options.h
+_udivdi3.So: tconfig.h
+_udivdi3.So: tm.h
+_udivmoddi4.So: options.h
+_udivmoddi4.So: tconfig.h
+_udivmoddi4.So: tm.h
+_umoddi3.So: options.h
+_umoddi3.So: tconfig.h
+_umoddi3.So: tm.h
+unwind-c.So: tconfig.h
+unwind-c.So: unwind.h
+unwind-c.o: tconfig.h
+unwind-c.o: unwind.h
+unwind-c.po: tconfig.h
+unwind-c.po: unwind.h
+unwind-dw2-fde-glibc.So: gthr-default.h
+unwind-dw2-fde-glibc.So: options.h
+unwind-dw2-fde-glibc.So: tconfig.h
+unwind-dw2-fde-glibc.So: tm.h
+unwind-dw2-fde-glibc.So: unwind.h
+unwind-dw2-fde-glibc.o: gthr-default.h
+unwind-dw2-fde-glibc.o: options.h
+unwind-dw2-fde-glibc.o: tconfig.h
+unwind-dw2-fde-glibc.o: tm.h
+unwind-dw2-fde-glibc.o: unwind.h
+unwind-dw2-fde-glibc.po: gthr-default.h
+unwind-dw2-fde-glibc.po: options.h
+unwind-dw2-fde-glibc.po: tconfig.h
+unwind-dw2-fde-glibc.po: tm.h
+unwind-dw2-fde-glibc.po: unwind.h
+unwind-dw2.So: gthr-default.h
+unwind-dw2.So: options.h
+unwind-dw2.So: tconfig.h
+unwind-dw2.So: tm.h
+unwind-dw2.So: unwind.h
+unwind-dw2.o: gthr-default.h
+unwind-dw2.o: options.h
+unwind-dw2.o: tconfig.h
+unwind-dw2.o: tm.h
+unwind-dw2.o: unwind.h
+unwind-dw2.po: gthr-default.h
+unwind-dw2.po: options.h
+unwind-dw2.po: tconfig.h
+unwind-dw2.po: tm.h
+unwind-dw2.po: unwind.h
+unwind-sjlj.So: gthr-default.h
+unwind-sjlj.So: options.h
+unwind-sjlj.So: tconfig.h
+unwind-sjlj.So: tm.h
+unwind-sjlj.So: unwind.h
+unwind-sjlj.o: gthr-default.h
+unwind-sjlj.o: options.h
+unwind-sjlj.o: tconfig.h
+unwind-sjlj.o: tm.h
+unwind-sjlj.o: unwind.h
+unwind-sjlj.po: gthr-default.h
+unwind-sjlj.po: options.h
+unwind-sjlj.po: tconfig.h
+unwind-sjlj.po: tm.h
+unwind-sjlj.po: unwind.h
+.endif
diff --git a/gnu/lib/libgcov/Makefile.depend b/gnu/lib/libgcov/Makefile.depend
new file mode 100644
index 0000000..23b931f
--- /dev/null
+++ b/gnu/lib/libgcov/Makefile.depend
@@ -0,0 +1,128 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+_gcov.o: gcov-iov.h
+_gcov.o: options.h
+_gcov.o: tconfig.h
+_gcov.o: tm.h
+_gcov.po: gcov-iov.h
+_gcov.po: options.h
+_gcov.po: tconfig.h
+_gcov.po: tm.h
+_gcov_execl.o: gcov-iov.h
+_gcov_execl.o: options.h
+_gcov_execl.o: tconfig.h
+_gcov_execl.o: tm.h
+_gcov_execl.po: gcov-iov.h
+_gcov_execl.po: options.h
+_gcov_execl.po: tconfig.h
+_gcov_execl.po: tm.h
+_gcov_execle.o: gcov-iov.h
+_gcov_execle.o: options.h
+_gcov_execle.o: tconfig.h
+_gcov_execle.o: tm.h
+_gcov_execle.po: gcov-iov.h
+_gcov_execle.po: options.h
+_gcov_execle.po: tconfig.h
+_gcov_execle.po: tm.h
+_gcov_execlp.o: gcov-iov.h
+_gcov_execlp.o: options.h
+_gcov_execlp.o: tconfig.h
+_gcov_execlp.o: tm.h
+_gcov_execlp.po: gcov-iov.h
+_gcov_execlp.po: options.h
+_gcov_execlp.po: tconfig.h
+_gcov_execlp.po: tm.h
+_gcov_execv.o: gcov-iov.h
+_gcov_execv.o: options.h
+_gcov_execv.o: tconfig.h
+_gcov_execv.o: tm.h
+_gcov_execv.po: gcov-iov.h
+_gcov_execv.po: options.h
+_gcov_execv.po: tconfig.h
+_gcov_execv.po: tm.h
+_gcov_execve.o: gcov-iov.h
+_gcov_execve.o: options.h
+_gcov_execve.o: tconfig.h
+_gcov_execve.o: tm.h
+_gcov_execve.po: gcov-iov.h
+_gcov_execve.po: options.h
+_gcov_execve.po: tconfig.h
+_gcov_execve.po: tm.h
+_gcov_execvp.o: gcov-iov.h
+_gcov_execvp.o: options.h
+_gcov_execvp.o: tconfig.h
+_gcov_execvp.o: tm.h
+_gcov_execvp.po: gcov-iov.h
+_gcov_execvp.po: options.h
+_gcov_execvp.po: tconfig.h
+_gcov_execvp.po: tm.h
+_gcov_fork.o: gcov-iov.h
+_gcov_fork.o: options.h
+_gcov_fork.o: tconfig.h
+_gcov_fork.o: tm.h
+_gcov_fork.po: gcov-iov.h
+_gcov_fork.po: options.h
+_gcov_fork.po: tconfig.h
+_gcov_fork.po: tm.h
+_gcov_interval_profiler.o: gcov-iov.h
+_gcov_interval_profiler.o: options.h
+_gcov_interval_profiler.o: tconfig.h
+_gcov_interval_profiler.o: tm.h
+_gcov_interval_profiler.po: gcov-iov.h
+_gcov_interval_profiler.po: options.h
+_gcov_interval_profiler.po: tconfig.h
+_gcov_interval_profiler.po: tm.h
+_gcov_merge_add.o: gcov-iov.h
+_gcov_merge_add.o: options.h
+_gcov_merge_add.o: tconfig.h
+_gcov_merge_add.o: tm.h
+_gcov_merge_add.po: gcov-iov.h
+_gcov_merge_add.po: options.h
+_gcov_merge_add.po: tconfig.h
+_gcov_merge_add.po: tm.h
+_gcov_merge_delta.o: gcov-iov.h
+_gcov_merge_delta.o: options.h
+_gcov_merge_delta.o: tconfig.h
+_gcov_merge_delta.o: tm.h
+_gcov_merge_delta.po: gcov-iov.h
+_gcov_merge_delta.po: options.h
+_gcov_merge_delta.po: tconfig.h
+_gcov_merge_delta.po: tm.h
+_gcov_merge_single.o: gcov-iov.h
+_gcov_merge_single.o: options.h
+_gcov_merge_single.o: tconfig.h
+_gcov_merge_single.o: tm.h
+_gcov_merge_single.po: gcov-iov.h
+_gcov_merge_single.po: options.h
+_gcov_merge_single.po: tconfig.h
+_gcov_merge_single.po: tm.h
+_gcov_one_value_profiler.o: gcov-iov.h
+_gcov_one_value_profiler.o: options.h
+_gcov_one_value_profiler.o: tconfig.h
+_gcov_one_value_profiler.o: tm.h
+_gcov_one_value_profiler.po: gcov-iov.h
+_gcov_one_value_profiler.po: options.h
+_gcov_one_value_profiler.po: tconfig.h
+_gcov_one_value_profiler.po: tm.h
+_gcov_pow2_profiler.o: gcov-iov.h
+_gcov_pow2_profiler.o: options.h
+_gcov_pow2_profiler.o: tconfig.h
+_gcov_pow2_profiler.o: tm.h
+_gcov_pow2_profiler.po: gcov-iov.h
+_gcov_pow2_profiler.po: options.h
+_gcov_pow2_profiler.po: tconfig.h
+_gcov_pow2_profiler.po: tm.h
+.endif
diff --git a/gnu/lib/libgomp/Makefile.depend b/gnu/lib/libgomp/Makefile.depend
new file mode 100644
index 0000000..b7fcf38
--- /dev/null
+++ b/gnu/lib/libgomp/Makefile.depend
@@ -0,0 +1,79 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+alloc.So: gstdint.h
+alloc.o: gstdint.h
+alloc.po: gstdint.h
+bar.So: gstdint.h
+bar.o: gstdint.h
+bar.po: gstdint.h
+barrier.So: gstdint.h
+barrier.o: gstdint.h
+barrier.po: gstdint.h
+critical.So: gstdint.h
+critical.o: gstdint.h
+critical.po: gstdint.h
+env.So: gstdint.h
+env.So: libgomp_f.h
+env.o: gstdint.h
+env.o: libgomp_f.h
+env.po: gstdint.h
+env.po: libgomp_f.h
+error.So: gstdint.h
+error.o: gstdint.h
+error.po: gstdint.h
+fortran.So: gstdint.h
+fortran.So: libgomp_f.h
+fortran.o: gstdint.h
+fortran.o: libgomp_f.h
+fortran.po: gstdint.h
+fortran.po: libgomp_f.h
+iter.So: gstdint.h
+iter.o: gstdint.h
+iter.po: gstdint.h
+lock.So: gstdint.h
+lock.o: gstdint.h
+lock.po: gstdint.h
+loop.So: gstdint.h
+loop.o: gstdint.h
+loop.po: gstdint.h
+ordered.So: gstdint.h
+ordered.o: gstdint.h
+ordered.po: gstdint.h
+parallel.So: gstdint.h
+parallel.o: gstdint.h
+parallel.po: gstdint.h
+proc.So: gstdint.h
+proc.o: gstdint.h
+proc.po: gstdint.h
+sections.So: gstdint.h
+sections.o: gstdint.h
+sections.po: gstdint.h
+sem.So: gstdint.h
+sem.o: gstdint.h
+sem.po: gstdint.h
+single.So: gstdint.h
+single.o: gstdint.h
+single.po: gstdint.h
+team.So: gstdint.h
+team.o: gstdint.h
+team.po: gstdint.h
+time.So: gstdint.h
+time.o: gstdint.h
+time.po: gstdint.h
+work.So: gstdint.h
+work.o: gstdint.h
+work.po: gstdint.h
+.endif
diff --git a/gnu/lib/libreadline/history/Makefile.depend b/gnu/lib/libreadline/history/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/gnu/lib/libreadline/history/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/lib/libreadline/readline/Makefile.depend b/gnu/lib/libreadline/readline/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/gnu/lib/libreadline/readline/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/lib/libregex/Makefile.depend b/gnu/lib/libregex/Makefile.depend
new file mode 100644
index 0000000..9ac344f
--- /dev/null
+++ b/gnu/lib/libregex/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+gnuregex.So: gnuregex.c
+gnuregex.o: gnuregex.c
+gnuregex.po: gnuregex.c
+.endif
diff --git a/gnu/lib/libssp/Makefile.depend b/gnu/lib/libssp/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/gnu/lib/libssp/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/lib/libssp/libssp_nonshared/Makefile.depend b/gnu/lib/libssp/libssp_nonshared/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/lib/libssp/libssp_nonshared/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/lib/libstdc++/Makefile.depend b/gnu/lib/libstdc++/Makefile.depend
new file mode 100644
index 0000000..5473296
--- /dev/null
+++ b/gnu/lib/libstdc++/Makefile.depend
@@ -0,0 +1,65 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+atomicity.So: atomicity.cc
+atomicity.o: atomicity.cc
+atomicity.po: atomicity.cc
+eh_alloc.So: unwind.h
+eh_alloc.o: unwind.h
+eh_alloc.po: unwind.h
+eh_arm.So: unwind.h
+eh_arm.o: unwind.h
+eh_arm.po: unwind.h
+eh_aux_runtime.So: unwind.h
+eh_aux_runtime.o: unwind.h
+eh_aux_runtime.po: unwind.h
+eh_call.So: unwind.h
+eh_call.o: unwind.h
+eh_call.po: unwind.h
+eh_catch.So: unwind.h
+eh_catch.o: unwind.h
+eh_catch.po: unwind.h
+eh_exception.So: unwind.h
+eh_exception.o: unwind.h
+eh_exception.po: unwind.h
+eh_globals.So: unwind.h
+eh_globals.o: unwind.h
+eh_globals.po: unwind.h
+eh_personality.So: unwind.h
+eh_personality.o: unwind.h
+eh_personality.po: unwind.h
+eh_term_handler.So: unwind.h
+eh_term_handler.o: unwind.h
+eh_term_handler.po: unwind.h
+eh_terminate.So: unwind.h
+eh_terminate.o: unwind.h
+eh_terminate.po: unwind.h
+eh_throw.So: unwind.h
+eh_throw.o: unwind.h
+eh_throw.po: unwind.h
+eh_type.So: unwind.h
+eh_type.o: unwind.h
+eh_type.po: unwind.h
+eh_unex_handler.So: unwind.h
+eh_unex_handler.o: unwind.h
+eh_unex_handler.po: unwind.h
+pure.So: unwind.h
+pure.o: unwind.h
+pure.po: unwind.h
+vec.So: unwind.h
+vec.o: unwind.h
+vec.po: unwind.h
+.endif
diff --git a/gnu/lib/libsupc++/Makefile.depend b/gnu/lib/libsupc++/Makefile.depend
new file mode 100644
index 0000000..ff26147
--- /dev/null
+++ b/gnu/lib/libsupc++/Makefile.depend
@@ -0,0 +1,61 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+eh_alloc.So: unwind.h
+eh_alloc.o: unwind.h
+eh_alloc.po: unwind.h
+eh_arm.So: unwind.h
+eh_arm.o: unwind.h
+eh_arm.po: unwind.h
+eh_aux_runtime.So: unwind.h
+eh_aux_runtime.o: unwind.h
+eh_aux_runtime.po: unwind.h
+eh_call.So: unwind.h
+eh_call.o: unwind.h
+eh_call.po: unwind.h
+eh_catch.So: unwind.h
+eh_catch.o: unwind.h
+eh_catch.po: unwind.h
+eh_exception.So: unwind.h
+eh_exception.o: unwind.h
+eh_exception.po: unwind.h
+eh_globals.So: unwind.h
+eh_globals.o: unwind.h
+eh_globals.po: unwind.h
+eh_personality.So: unwind.h
+eh_personality.o: unwind.h
+eh_personality.po: unwind.h
+eh_term_handler.So: unwind.h
+eh_term_handler.o: unwind.h
+eh_term_handler.po: unwind.h
+eh_terminate.So: unwind.h
+eh_terminate.o: unwind.h
+eh_terminate.po: unwind.h
+eh_throw.So: unwind.h
+eh_throw.o: unwind.h
+eh_throw.po: unwind.h
+eh_type.So: unwind.h
+eh_type.o: unwind.h
+eh_type.po: unwind.h
+eh_unex_handler.So: unwind.h
+eh_unex_handler.o: unwind.h
+eh_unex_handler.po: unwind.h
+pure.So: unwind.h
+pure.o: unwind.h
+pure.po: unwind.h
+vec.So: unwind.h
+vec.o: unwind.h
+vec.po: unwind.h
+.endif
diff --git a/gnu/usr.bin/binutils/addr2line/Makefile.depend b/gnu/usr.bin/binutils/addr2line/Makefile.depend
new file mode 100644
index 0000000..18e8388
--- /dev/null
+++ b/gnu/usr.bin/binutils/addr2line/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libbinutils \
+ gnu/usr.bin/binutils/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/ar/Makefile.depend b/gnu/usr.bin/binutils/ar/Makefile.depend
new file mode 100644
index 0000000..c4f26d4
--- /dev/null
+++ b/gnu/usr.bin/binutils/ar/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libbinutils \
+ gnu/usr.bin/binutils/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/as/Makefile.depend b/gnu/usr.bin/binutils/as/Makefile.depend
new file mode 100644
index 0000000..ee36db7
--- /dev/null
+++ b/gnu/usr.bin/binutils/as/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libiberty \
+ gnu/usr.bin/binutils/libopcodes \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/ld/Makefile.depend b/gnu/usr.bin/binutils/ld/Makefile.depend
new file mode 100644
index 0000000..24e5a8b
--- /dev/null
+++ b/gnu/usr.bin/binutils/ld/Makefile.depend
@@ -0,0 +1,50 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+eelf_i386_fbsd.o: eelf_i386_fbsd.c
+eelf_i386_fbsd.o: ldgram.h
+eelf_i386_fbsd.po: eelf_i386_fbsd.c
+eelf_i386_fbsd.po: ldgram.h
+ldctor.o: ldgram.h
+ldctor.po: ldgram.h
+ldemul.o: ldemul-list.h
+ldemul.po: ldemul-list.h
+ldexp.o: ldgram.h
+ldexp.po: ldgram.h
+ldfile.o: ldgram.h
+ldfile.po: ldgram.h
+ldgram.o: ldgram.c
+ldgram.po: ldgram.c
+ldlang.o: ldgram.h
+ldlang.po: ldgram.h
+ldlex.o: ldgram.h
+ldlex.o: ldlex.c
+ldlex.po: ldgram.h
+ldlex.po: ldlex.c
+ldmain.o: ldgram.h
+ldmain.po: ldgram.h
+ldmisc.o: ldgram.h
+ldmisc.po: ldgram.h
+ldwrite.o: ldgram.h
+ldwrite.po: ldgram.h
+lexsup.o: ldgram.h
+lexsup.po: ldgram.h
+mri.o: ldgram.h
+mri.po: ldgram.h
+.endif
diff --git a/gnu/usr.bin/binutils/libbfd/Makefile.depend b/gnu/usr.bin/binutils/libbfd/Makefile.depend
new file mode 100644
index 0000000..be067af
--- /dev/null
+++ b/gnu/usr.bin/binutils/libbfd/Makefile.depend
@@ -0,0 +1,104 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+archive.o: config.h
+archive.po: config.h
+archive64.o: config.h
+archive64.po: config.h
+archures.o: config.h
+archures.po: config.h
+bfd.o: bfdver.h
+bfd.o: config.h
+bfd.po: bfdver.h
+bfd.po: config.h
+bfdio.o: config.h
+bfdio.po: config.h
+bfdwin.o: config.h
+bfdwin.po: config.h
+binary.o: config.h
+binary.po: config.h
+cache.o: config.h
+cache.po: config.h
+coffgen.o: config.h
+coffgen.po: config.h
+cofflink.o: config.h
+cofflink.po: config.h
+corefile.o: config.h
+corefile.po: config.h
+cpu-i386.o: config.h
+cpu-i386.po: config.h
+dwarf1.o: config.h
+dwarf1.po: config.h
+dwarf2.o: config.h
+dwarf2.po: config.h
+efi-app-ia32.o: config.h
+efi-app-ia32.po: config.h
+elf-attrs.o: config.h
+elf-attrs.po: config.h
+elf-eh-frame.o: config.h
+elf-eh-frame.po: config.h
+elf-strtab.o: config.h
+elf-strtab.po: config.h
+elf-vxworks.o: config.h
+elf-vxworks.po: config.h
+elf.o: config.h
+elf.po: config.h
+elf32-i386.o: config.h
+elf32-i386.o: elf32-target.h
+elf32-i386.po: config.h
+elf32-i386.po: elf32-target.h
+elf32.o: config.h
+elf32.po: config.h
+elflink.o: config.h
+elflink.po: config.h
+format.o: config.h
+format.po: config.h
+hash.o: config.h
+hash.po: config.h
+ihex.o: config.h
+ihex.po: config.h
+init.o: config.h
+init.po: config.h
+libbfd.o: config.h
+libbfd.po: config.h
+linker.o: config.h
+linker.po: config.h
+merge.o: config.h
+merge.po: config.h
+opncls.o: config.h
+opncls.po: config.h
+peigen.o: config.h
+peigen.o: peigen.c
+peigen.po: config.h
+peigen.po: peigen.c
+reloc.o: config.h
+reloc.po: config.h
+section.o: config.h
+section.po: config.h
+simple.o: config.h
+simple.po: config.h
+srec.o: config.h
+srec.po: config.h
+stabs.o: config.h
+stabs.po: config.h
+syms.o: config.h
+syms.po: config.h
+targets.o: config.h
+targets.o: targmatch.h
+targets.po: config.h
+targets.po: targmatch.h
+tekhex.o: config.h
+tekhex.po: config.h
+.endif
diff --git a/gnu/usr.bin/binutils/libbinutils/Makefile.depend b/gnu/usr.bin/binutils/libbinutils/Makefile.depend
new file mode 100644
index 0000000..c3c4756
--- /dev/null
+++ b/gnu/usr.bin/binutils/libbinutils/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/usr.bin/binutils/libbfd \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+arlex.o: arlex.c
+arlex.o: arparse.h
+arlex.po: arlex.c
+arlex.po: arparse.h
+arparse.o: arparse.c
+arparse.po: arparse.c
+.endif
diff --git a/gnu/usr.bin/binutils/libiberty/Makefile.depend b/gnu/usr.bin/binutils/libiberty/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/gnu/usr.bin/binutils/libiberty/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/libopcodes/Makefile.depend b/gnu/usr.bin/binutils/libopcodes/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/gnu/usr.bin/binutils/libopcodes/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/nm/Makefile.depend b/gnu/usr.bin/binutils/nm/Makefile.depend
new file mode 100644
index 0000000..18e8388
--- /dev/null
+++ b/gnu/usr.bin/binutils/nm/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libbinutils \
+ gnu/usr.bin/binutils/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/objcopy/Makefile.depend b/gnu/usr.bin/binutils/objcopy/Makefile.depend
new file mode 100644
index 0000000..18e8388
--- /dev/null
+++ b/gnu/usr.bin/binutils/objcopy/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libbinutils \
+ gnu/usr.bin/binutils/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/objdump/Makefile.depend b/gnu/usr.bin/binutils/objdump/Makefile.depend
new file mode 100644
index 0000000..ba1a3be
--- /dev/null
+++ b/gnu/usr.bin/binutils/objdump/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libbinutils \
+ gnu/usr.bin/binutils/libiberty \
+ gnu/usr.bin/binutils/libopcodes \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/ranlib/Makefile.depend b/gnu/usr.bin/binutils/ranlib/Makefile.depend
new file mode 100644
index 0000000..c4f26d4
--- /dev/null
+++ b/gnu/usr.bin/binutils/ranlib/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libbinutils \
+ gnu/usr.bin/binutils/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/readelf/Makefile.depend b/gnu/usr.bin/binutils/readelf/Makefile.depend
new file mode 100644
index 0000000..18e8388
--- /dev/null
+++ b/gnu/usr.bin/binutils/readelf/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libbinutils \
+ gnu/usr.bin/binutils/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/size/Makefile.depend b/gnu/usr.bin/binutils/size/Makefile.depend
new file mode 100644
index 0000000..18e8388
--- /dev/null
+++ b/gnu/usr.bin/binutils/size/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libbinutils \
+ gnu/usr.bin/binutils/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/strings/Makefile.depend b/gnu/usr.bin/binutils/strings/Makefile.depend
new file mode 100644
index 0000000..18e8388
--- /dev/null
+++ b/gnu/usr.bin/binutils/strings/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libbinutils \
+ gnu/usr.bin/binutils/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/binutils/strip/Makefile.depend b/gnu/usr.bin/binutils/strip/Makefile.depend
new file mode 100644
index 0000000..18e8388
--- /dev/null
+++ b/gnu/usr.bin/binutils/strip/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libbinutils \
+ gnu/usr.bin/binutils/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cc/c++/Makefile.depend b/gnu/usr.bin/cc/c++/Makefile.depend
new file mode 100644
index 0000000..e0c846e
--- /dev/null
+++ b/gnu/usr.bin/cc/c++/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/cc/cc_tools \
+ gnu/usr.bin/cc/libcpp \
+ gnu/usr.bin/cc/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cc/c++filt/Makefile.depend b/gnu/usr.bin/cc/c++filt/Makefile.depend
new file mode 100644
index 0000000..763be51
--- /dev/null
+++ b/gnu/usr.bin/cc/c++filt/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/cc/cc_tools \
+ gnu/usr.bin/cc/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cc/cc/Makefile.depend b/gnu/usr.bin/cc/cc/Makefile.depend
new file mode 100644
index 0000000..ce7738d
--- /dev/null
+++ b/gnu/usr.bin/cc/cc/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/usr.bin/cc/cc_tools \
+ gnu/usr.bin/cc/libcpp \
+ gnu/usr.bin/cc/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cc/cc1/Makefile.depend b/gnu/usr.bin/cc/cc1/Makefile.depend
new file mode 100644
index 0000000..2e76ab7
--- /dev/null
+++ b/gnu/usr.bin/cc/cc1/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/usr.bin/cc/cc_int \
+ gnu/usr.bin/cc/cc_tools \
+ gnu/usr.bin/cc/libcpp \
+ gnu/usr.bin/cc/libdecnumber \
+ gnu/usr.bin/cc/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+cc1-checksum.o: cc1-checksum.c
+cc1-checksum.po: cc1-checksum.c
+.endif
diff --git a/gnu/usr.bin/cc/cc1plus/Makefile.depend b/gnu/usr.bin/cc/cc1plus/Makefile.depend
new file mode 100644
index 0000000..4d868989
--- /dev/null
+++ b/gnu/usr.bin/cc/cc1plus/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/usr.bin/cc/cc_int \
+ gnu/usr.bin/cc/cc_tools \
+ gnu/usr.bin/cc/libcpp \
+ gnu/usr.bin/cc/libdecnumber \
+ gnu/usr.bin/cc/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+cc1plus-checksum.o: cc1plus-checksum.c
+cc1plus-checksum.po: cc1plus-checksum.c
+except.o: cfns.h
+except.po: cfns.h
+.endif
diff --git a/gnu/usr.bin/cc/cc_int/Makefile.depend b/gnu/usr.bin/cc/cc_int/Makefile.depend
new file mode 100644
index 0000000..e722b39
--- /dev/null
+++ b/gnu/usr.bin/cc/cc_int/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/usr.bin/cc/cc_tools \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cc/cc_tools/Makefile.depend b/gnu/usr.bin/cc/cc_tools/Makefile.depend
new file mode 100644
index 0000000..4e41c5b
--- /dev/null
+++ b/gnu/usr.bin/cc/cc_tools/Makefile.depend
@@ -0,0 +1,247 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+errors.o: bconfig.h
+errors.po: bconfig.h
+genattr.o: bconfig.h
+genattr.o: insn-modes.h
+genattr.o: options.h
+genattr.o: tm.h
+genattr.po: bconfig.h
+genattr.po: insn-modes.h
+genattr.po: options.h
+genattr.po: tm.h
+genattrtab.o: bconfig.h
+genattrtab.o: insn-modes.h
+genattrtab.o: options.h
+genattrtab.o: tm.h
+genattrtab.po: bconfig.h
+genattrtab.po: insn-modes.h
+genattrtab.po: options.h
+genattrtab.po: tm.h
+genautomata.o: bconfig.h
+genautomata.o: insn-modes.h
+genautomata.o: options.h
+genautomata.o: tm.h
+genautomata.po: bconfig.h
+genautomata.po: insn-modes.h
+genautomata.po: options.h
+genautomata.po: tm.h
+gencheck.o: bconfig.h
+gencheck.o: gencheck.h
+gencheck.o: options.h
+gencheck.o: tm.h
+gencheck.po: bconfig.h
+gencheck.po: gencheck.h
+gencheck.po: options.h
+gencheck.po: tm.h
+genchecksum.o: bconfig.h
+genchecksum.po: bconfig.h
+gencodes.o: bconfig.h
+gencodes.o: insn-modes.h
+gencodes.o: options.h
+gencodes.o: tm.h
+gencodes.po: bconfig.h
+gencodes.po: insn-modes.h
+gencodes.po: options.h
+gencodes.po: tm.h
+genconditions.o: bconfig.h
+genconditions.o: insn-modes.h
+genconditions.o: options.h
+genconditions.o: tm.h
+genconditions.po: bconfig.h
+genconditions.po: insn-modes.h
+genconditions.po: options.h
+genconditions.po: tm.h
+gencondmd.o: bconfig.h
+gencondmd.o: gencondmd.c
+gencondmd.o: insn-constants.h
+gencondmd.o: insn-modes.h
+gencondmd.o: options.h
+gencondmd.o: tm-constrs.h
+gencondmd.o: tm-preds.h
+gencondmd.o: tm.h
+gencondmd.o: tm_p.h
+gencondmd.o: tree-check.h
+gencondmd.po: bconfig.h
+gencondmd.po: gencondmd.c
+gencondmd.po: insn-constants.h
+gencondmd.po: insn-modes.h
+gencondmd.po: options.h
+gencondmd.po: tm-constrs.h
+gencondmd.po: tm-preds.h
+gencondmd.po: tm.h
+gencondmd.po: tm_p.h
+gencondmd.po: tree-check.h
+genconfig.o: bconfig.h
+genconfig.o: insn-modes.h
+genconfig.o: options.h
+genconfig.o: tm.h
+genconfig.po: bconfig.h
+genconfig.po: insn-modes.h
+genconfig.po: options.h
+genconfig.po: tm.h
+genconstants.o: bconfig.h
+genconstants.o: insn-modes.h
+genconstants.o: options.h
+genconstants.o: tm.h
+genconstants.po: bconfig.h
+genconstants.po: insn-modes.h
+genconstants.po: options.h
+genconstants.po: tm.h
+genemit.o: bconfig.h
+genemit.o: insn-modes.h
+genemit.o: options.h
+genemit.o: tm.h
+genemit.po: bconfig.h
+genemit.po: insn-modes.h
+genemit.po: options.h
+genemit.po: tm.h
+genextract.o: bconfig.h
+genextract.o: insn-modes.h
+genextract.o: options.h
+genextract.o: tm.h
+genextract.po: bconfig.h
+genextract.po: insn-modes.h
+genextract.po: options.h
+genextract.po: tm.h
+genflags.o: bconfig.h
+genflags.o: insn-modes.h
+genflags.o: options.h
+genflags.o: tm.h
+genflags.po: bconfig.h
+genflags.po: insn-modes.h
+genflags.po: options.h
+genflags.po: tm.h
+gengenrtl.o: bconfig.h
+gengenrtl.po: bconfig.h
+gengtype-lex.o: bconfig.h
+gengtype-lex.o: gengtype-lex.c
+gengtype-lex.o: gengtype-yacc.h
+gengtype-lex.po: bconfig.h
+gengtype-lex.po: gengtype-lex.c
+gengtype-lex.po: gengtype-yacc.h
+gengtype-yacc+%DIKED.o: bconfig.h
+gengtype-yacc+%DIKED.o: gengtype-yacc+%DIKED.c
+gengtype-yacc+%DIKED.o: options.h
+gengtype-yacc+%DIKED.o: tm.h
+gengtype-yacc+%DIKED.po: bconfig.h
+gengtype-yacc+%DIKED.po: gengtype-yacc+%DIKED.c
+gengtype-yacc+%DIKED.po: options.h
+gengtype-yacc+%DIKED.po: tm.h
+gengtype.o: bconfig.h
+gengtype.o: gtyp-gen.h
+gengtype.o: options.h
+gengtype.o: tm.h
+gengtype.po: bconfig.h
+gengtype.po: gtyp-gen.h
+gengtype.po: options.h
+gengtype.po: tm.h
+genmodes.o: bconfig.h
+genmodes.po: bconfig.h
+genopinit.o: bconfig.h
+genopinit.o: insn-modes.h
+genopinit.o: options.h
+genopinit.o: tm.h
+genopinit.po: bconfig.h
+genopinit.po: insn-modes.h
+genopinit.po: options.h
+genopinit.po: tm.h
+genoutput.o: bconfig.h
+genoutput.o: insn-modes.h
+genoutput.o: options.h
+genoutput.o: tm.h
+genoutput.po: bconfig.h
+genoutput.po: insn-modes.h
+genoutput.po: options.h
+genoutput.po: tm.h
+genpeep.o: bconfig.h
+genpeep.o: insn-modes.h
+genpeep.o: options.h
+genpeep.o: tm.h
+genpeep.po: bconfig.h
+genpeep.po: insn-modes.h
+genpeep.po: options.h
+genpeep.po: tm.h
+genpreds.o: bconfig.h
+genpreds.o: insn-modes.h
+genpreds.o: options.h
+genpreds.o: tm.h
+genpreds.po: bconfig.h
+genpreds.po: insn-modes.h
+genpreds.po: options.h
+genpreds.po: tm.h
+genrecog.o: bconfig.h
+genrecog.o: insn-modes.h
+genrecog.o: options.h
+genrecog.o: tm.h
+genrecog.po: bconfig.h
+genrecog.po: insn-modes.h
+genrecog.po: options.h
+genrecog.po: tm.h
+gensupport.o: bconfig.h
+gensupport.o: insn-modes.h
+gensupport.o: options.h
+gensupport.o: tm.h
+gensupport.po: bconfig.h
+gensupport.po: insn-modes.h
+gensupport.po: options.h
+gensupport.po: tm.h
+ggc-none.o: bconfig.h
+ggc-none.o: gtype-desc.h
+ggc-none.po: bconfig.h
+ggc-none.po: gtype-desc.h
+min-insn-modes.o: bconfig.h
+min-insn-modes.o: insn-modes.h
+min-insn-modes.o: min-insn-modes.c
+min-insn-modes.po: bconfig.h
+min-insn-modes.po: insn-modes.h
+min-insn-modes.po: min-insn-modes.c
+print-rtl.o: bconfig.h
+print-rtl.o: insn-modes.h
+print-rtl.o: options.h
+print-rtl.o: tm.h
+print-rtl.po: bconfig.h
+print-rtl.po: insn-modes.h
+print-rtl.po: options.h
+print-rtl.po: tm.h
+read-rtl.o: bconfig.h
+read-rtl.o: insn-modes.h
+read-rtl.o: options.h
+read-rtl.o: tm.h
+read-rtl.po: bconfig.h
+read-rtl.po: insn-modes.h
+read-rtl.po: options.h
+read-rtl.po: tm.h
+rtl.o: bconfig.h
+rtl.o: gtype-desc.h
+rtl.o: insn-modes.h
+rtl.o: options.h
+rtl.o: tm.h
+rtl.po: bconfig.h
+rtl.po: gtype-desc.h
+rtl.po: insn-modes.h
+rtl.po: options.h
+rtl.po: tm.h
+vec.o: bconfig.h
+vec.o: gtype-desc.h
+vec.o: insn-modes.h
+vec.o: tree-check.h
+vec.po: bconfig.h
+vec.po: gtype-desc.h
+vec.po: insn-modes.h
+vec.po: tree-check.h
+.endif
diff --git a/gnu/usr.bin/cc/cpp/Makefile.depend b/gnu/usr.bin/cc/cpp/Makefile.depend
new file mode 100644
index 0000000..e0c846e
--- /dev/null
+++ b/gnu/usr.bin/cc/cpp/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/cc/cc_tools \
+ gnu/usr.bin/cc/libcpp \
+ gnu/usr.bin/cc/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cc/gcov/Makefile.depend b/gnu/usr.bin/cc/gcov/Makefile.depend
new file mode 100644
index 0000000..763be51
--- /dev/null
+++ b/gnu/usr.bin/cc/gcov/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/cc/cc_tools \
+ gnu/usr.bin/cc/libiberty \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cc/include/Makefile.depend b/gnu/usr.bin/cc/include/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/cc/include/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cc/libcpp/Makefile.depend b/gnu/usr.bin/cc/libcpp/Makefile.depend
new file mode 100644
index 0000000..85a412b
--- /dev/null
+++ b/gnu/usr.bin/cc/libcpp/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+init.o: localedir.h
+init.po: localedir.h
+.endif
diff --git a/gnu/usr.bin/cc/libdecnumber/Makefile.depend b/gnu/usr.bin/cc/libdecnumber/Makefile.depend
new file mode 100644
index 0000000..e722b39
--- /dev/null
+++ b/gnu/usr.bin/cc/libdecnumber/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/usr.bin/cc/cc_tools \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cc/libiberty/Makefile.depend b/gnu/usr.bin/cc/libiberty/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/gnu/usr.bin/cc/libiberty/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cvs/cvs/Makefile.depend b/gnu/usr.bin/cvs/cvs/Makefile.depend
new file mode 100644
index 0000000..710302c
--- /dev/null
+++ b/gnu/usr.bin/cvs/cvs/Makefile.depend
@@ -0,0 +1,34 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libregex \
+ gnu/usr.bin/cvs/lib \
+ gnu/usr.bin/cvs/libdiff \
+ include \
+ include/arpa \
+ include/gssapi \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libgssapi \
+ lib/libmd \
+ lib/libz \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cvs/cvsbug/Makefile.depend b/gnu/usr.bin/cvs/cvsbug/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/cvs/cvsbug/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/cvs/lib/Makefile.depend b/gnu/usr.bin/cvs/lib/Makefile.depend
new file mode 100644
index 0000000..0840c69
--- /dev/null
+++ b/gnu/usr.bin/cvs/lib/Makefile.depend
@@ -0,0 +1,38 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+argmatch.o: config.h
+argmatch.po: config.h
+getdate.o: config.h
+getdate.o: getdate.c
+getdate.po: config.h
+getdate.po: getdate.c
+getline.o: config.h
+getline.po: config.h
+getopt.o: config.h
+getopt.po: config.h
+getopt1.o: config.h
+getopt1.po: config.h
+savecwd.o: config.h
+savecwd.po: config.h
+sighandle.o: config.h
+sighandle.po: config.h
+stripslash.o: config.h
+stripslash.po: config.h
+xgetwd.o: config.h
+xgetwd.po: config.h
+yesno.o: config.h
+yesno.po: config.h
+.endif
diff --git a/gnu/usr.bin/cvs/libdiff/Makefile.depend b/gnu/usr.bin/cvs/libdiff/Makefile.depend
new file mode 100644
index 0000000..393ce87
--- /dev/null
+++ b/gnu/usr.bin/cvs/libdiff/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libregex \
+ gnu/usr.bin/cvs/lib \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/dialog/Makefile.depend b/gnu/usr.bin/dialog/Makefile.depend
new file mode 100644
index 0000000..3f1092b
--- /dev/null
+++ b/gnu/usr.bin/dialog/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libdialog \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/diff/Makefile.depend b/gnu/usr.bin/diff/Makefile.depend
new file mode 100644
index 0000000..361b8e1
--- /dev/null
+++ b/gnu/usr.bin/diff/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libregex \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+context.o: context.c
+context.po: context.c
+diff.o: diff.c
+diff.po: diff.c
+.endif
diff --git a/gnu/usr.bin/diff3/Makefile.depend b/gnu/usr.bin/diff3/Makefile.depend
new file mode 100644
index 0000000..8f37034
--- /dev/null
+++ b/gnu/usr.bin/diff3/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+diff3.o: diff3.c
+diff3.po: diff3.c
+.endif
diff --git a/gnu/usr.bin/dtc/Makefile.depend b/gnu/usr.bin/dtc/Makefile.depend
new file mode 100644
index 0000000..ce49d22
--- /dev/null
+++ b/gnu/usr.bin/dtc/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+dtc-lexer.lex.o: dtc-lexer.lex.c
+dtc-lexer.lex.o: dtc-parser.tab.h
+dtc-lexer.lex.po: dtc-lexer.lex.c
+dtc-lexer.lex.po: dtc-parser.tab.h
+dtc-parser.tab.o: dtc-parser.tab.c
+dtc-parser.tab.po: dtc-parser.tab.c
+dtc.o: version_gen.h
+dtc.po: version_gen.h
+.endif
diff --git a/gnu/usr.bin/gdb/gdb/Makefile.depend b/gnu/usr.bin/gdb/gdb/Makefile.depend
new file mode 100644
index 0000000..f4044c2
--- /dev/null
+++ b/gnu/usr.bin/gdb/gdb/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libreadline/readline \
+ gnu/lib/libregex \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libiberty \
+ gnu/usr.bin/binutils/libopcodes \
+ gnu/usr.bin/gdb/libgdb \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+gdb.o: nm.h
+gdb.o: tm.h
+gdb.o: xm.h
+gdb.po: nm.h
+gdb.po: tm.h
+gdb.po: xm.h
+.endif
diff --git a/gnu/usr.bin/gdb/gdbserver/Makefile.depend b/gnu/usr.bin/gdb/gdbserver/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/gnu/usr.bin/gdb/gdbserver/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/gdb/gdbtui/Makefile.depend b/gnu/usr.bin/gdb/gdbtui/Makefile.depend
new file mode 100644
index 0000000..1ced473
--- /dev/null
+++ b/gnu/usr.bin/gdb/gdbtui/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libreadline/readline \
+ gnu/lib/libregex \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libiberty \
+ gnu/usr.bin/binutils/libopcodes \
+ gnu/usr.bin/gdb/libgdb \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+tui-main.o: nm.h
+tui-main.o: tm.h
+tui-main.o: xm.h
+tui-main.po: nm.h
+tui-main.po: tm.h
+tui-main.po: xm.h
+.endif
diff --git a/gnu/usr.bin/gdb/kgdb/Makefile.depend b/gnu/usr.bin/gdb/kgdb/Makefile.depend
new file mode 100644
index 0000000..1658b2d
--- /dev/null
+++ b/gnu/usr.bin/gdb/kgdb/Makefile.depend
@@ -0,0 +1,58 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libreadline/readline \
+ gnu/lib/libregex \
+ gnu/usr.bin/binutils/libbfd \
+ gnu/usr.bin/binutils/libiberty \
+ gnu/usr.bin/binutils/libopcodes \
+ gnu/usr.bin/gdb/libgdb \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ lib/msun \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+kld.o: nm.h
+kld.o: tm.h
+kld.o: xm.h
+kld.po: nm.h
+kld.po: tm.h
+kld.po: xm.h
+kthr.o: nm.h
+kthr.o: tm.h
+kthr.o: xm.h
+kthr.po: nm.h
+kthr.po: tm.h
+kthr.po: xm.h
+main.o: nm.h
+main.o: tm.h
+main.o: xm.h
+main.po: nm.h
+main.po: tm.h
+main.po: xm.h
+trgt.o: nm.h
+trgt.o: tm.h
+trgt.o: xm.h
+trgt.po: nm.h
+trgt.po: tm.h
+trgt.po: xm.h
+trgt_i386.o: nm.h
+trgt_i386.o: tm.h
+trgt_i386.o: xm.h
+trgt_i386.po: nm.h
+trgt_i386.po: tm.h
+trgt_i386.po: xm.h
+.endif
diff --git a/gnu/usr.bin/gdb/libgdb/Makefile.depend b/gnu/usr.bin/gdb/libgdb/Makefile.depend
new file mode 100644
index 0000000..182e7b4
--- /dev/null
+++ b/gnu/usr.bin/gdb/libgdb/Makefile.depend
@@ -0,0 +1,1201 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libreadline/readline \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+annotate.o: nm.h
+annotate.o: tm.h
+annotate.o: xm.h
+annotate.po: nm.h
+annotate.po: tm.h
+annotate.po: xm.h
+arch-utils.o: nm.h
+arch-utils.o: tm.h
+arch-utils.o: xm.h
+arch-utils.po: nm.h
+arch-utils.po: tm.h
+arch-utils.po: xm.h
+auxv.o: nm.h
+auxv.o: tm.h
+auxv.o: xm.h
+auxv.po: nm.h
+auxv.po: tm.h
+auxv.po: xm.h
+ax-gdb.o: nm.h
+ax-gdb.o: tm.h
+ax-gdb.o: xm.h
+ax-gdb.po: nm.h
+ax-gdb.po: tm.h
+ax-gdb.po: xm.h
+ax-general.o: nm.h
+ax-general.o: tm.h
+ax-general.o: xm.h
+ax-general.po: nm.h
+ax-general.po: tm.h
+ax-general.po: xm.h
+bcache.o: nm.h
+bcache.o: tm.h
+bcache.o: xm.h
+bcache.po: nm.h
+bcache.po: tm.h
+bcache.po: xm.h
+bfd-target.o: nm.h
+bfd-target.o: tm.h
+bfd-target.o: xm.h
+bfd-target.po: nm.h
+bfd-target.po: tm.h
+bfd-target.po: xm.h
+block.o: nm.h
+block.o: tm.h
+block.o: xm.h
+block.po: nm.h
+block.po: tm.h
+block.po: xm.h
+blockframe.o: nm.h
+blockframe.o: tm.h
+blockframe.o: xm.h
+blockframe.po: nm.h
+blockframe.po: tm.h
+blockframe.po: xm.h
+breakpoint.o: nm.h
+breakpoint.o: tm.h
+breakpoint.o: xm.h
+breakpoint.po: nm.h
+breakpoint.po: tm.h
+breakpoint.po: xm.h
+buildsym.o: nm.h
+buildsym.o: tm.h
+buildsym.o: xm.h
+buildsym.po: nm.h
+buildsym.po: tm.h
+buildsym.po: xm.h
+c-exp.o: c-exp.c
+c-exp.o: nm.h
+c-exp.o: tm.h
+c-exp.o: xm.h
+c-exp.po: c-exp.c
+c-exp.po: nm.h
+c-exp.po: tm.h
+c-exp.po: xm.h
+c-lang.o: nm.h
+c-lang.o: tm.h
+c-lang.o: xm.h
+c-lang.po: nm.h
+c-lang.po: tm.h
+c-lang.po: xm.h
+c-typeprint.o: nm.h
+c-typeprint.o: tm.h
+c-typeprint.o: xm.h
+c-typeprint.po: nm.h
+c-typeprint.po: tm.h
+c-typeprint.po: xm.h
+c-valprint.o: nm.h
+c-valprint.o: tm.h
+c-valprint.o: xm.h
+c-valprint.po: nm.h
+c-valprint.po: tm.h
+c-valprint.po: xm.h
+charset.o: nm.h
+charset.o: tm.h
+charset.o: xm.h
+charset.po: nm.h
+charset.po: tm.h
+charset.po: xm.h
+cli-cmds.o: nm.h
+cli-cmds.o: tm.h
+cli-cmds.o: xm.h
+cli-cmds.po: nm.h
+cli-cmds.po: tm.h
+cli-cmds.po: xm.h
+cli-decode.o: nm.h
+cli-decode.o: tm.h
+cli-decode.o: xm.h
+cli-decode.po: nm.h
+cli-decode.po: tm.h
+cli-decode.po: xm.h
+cli-dump.o: nm.h
+cli-dump.o: tm.h
+cli-dump.o: xm.h
+cli-dump.po: nm.h
+cli-dump.po: tm.h
+cli-dump.po: xm.h
+cli-interp.o: nm.h
+cli-interp.o: tm.h
+cli-interp.o: xm.h
+cli-interp.po: nm.h
+cli-interp.po: tm.h
+cli-interp.po: xm.h
+cli-logging.o: nm.h
+cli-logging.o: tm.h
+cli-logging.o: xm.h
+cli-logging.po: nm.h
+cli-logging.po: tm.h
+cli-logging.po: xm.h
+cli-out.o: nm.h
+cli-out.o: tm.h
+cli-out.o: xm.h
+cli-out.po: nm.h
+cli-out.po: tm.h
+cli-out.po: xm.h
+cli-script.o: nm.h
+cli-script.o: tm.h
+cli-script.o: xm.h
+cli-script.po: nm.h
+cli-script.po: tm.h
+cli-script.po: xm.h
+cli-setshow.o: nm.h
+cli-setshow.o: tm.h
+cli-setshow.o: xm.h
+cli-setshow.po: nm.h
+cli-setshow.po: tm.h
+cli-setshow.po: xm.h
+cli-utils.o: nm.h
+cli-utils.o: tm.h
+cli-utils.o: xm.h
+cli-utils.po: nm.h
+cli-utils.po: tm.h
+cli-utils.po: xm.h
+coff-pe-read.o: nm.h
+coff-pe-read.o: tm.h
+coff-pe-read.o: xm.h
+coff-pe-read.po: nm.h
+coff-pe-read.po: tm.h
+coff-pe-read.po: xm.h
+coffread.o: nm.h
+coffread.o: tm.h
+coffread.o: xm.h
+coffread.po: nm.h
+coffread.po: tm.h
+coffread.po: xm.h
+complaints.o: nm.h
+complaints.o: tm.h
+complaints.o: xm.h
+complaints.po: nm.h
+complaints.po: tm.h
+complaints.po: xm.h
+completer.o: nm.h
+completer.o: tm.h
+completer.o: xm.h
+completer.po: nm.h
+completer.po: tm.h
+completer.po: xm.h
+copying.o: nm.h
+copying.o: tm.h
+copying.o: xm.h
+copying.po: nm.h
+copying.po: tm.h
+copying.po: xm.h
+corefile.o: nm.h
+corefile.o: tm.h
+corefile.o: xm.h
+corefile.po: nm.h
+corefile.po: tm.h
+corefile.po: xm.h
+corelow.o: nm.h
+corelow.o: tm.h
+corelow.o: xm.h
+corelow.po: nm.h
+corelow.po: tm.h
+corelow.po: xm.h
+cp-abi.o: nm.h
+cp-abi.o: tm.h
+cp-abi.o: xm.h
+cp-abi.po: nm.h
+cp-abi.po: tm.h
+cp-abi.po: xm.h
+cp-namespace.o: nm.h
+cp-namespace.o: tm.h
+cp-namespace.o: xm.h
+cp-namespace.po: nm.h
+cp-namespace.po: tm.h
+cp-namespace.po: xm.h
+cp-support.o: nm.h
+cp-support.o: tm.h
+cp-support.o: xm.h
+cp-support.po: nm.h
+cp-support.po: tm.h
+cp-support.po: xm.h
+cp-valprint.o: nm.h
+cp-valprint.o: tm.h
+cp-valprint.o: xm.h
+cp-valprint.po: nm.h
+cp-valprint.po: tm.h
+cp-valprint.po: xm.h
+dbxread.o: nm.h
+dbxread.o: tm.h
+dbxread.o: xm.h
+dbxread.po: nm.h
+dbxread.po: tm.h
+dbxread.po: xm.h
+dcache.o: nm.h
+dcache.o: tm.h
+dcache.o: xm.h
+dcache.po: nm.h
+dcache.po: tm.h
+dcache.po: xm.h
+demangle.o: nm.h
+demangle.o: tm.h
+demangle.o: xm.h
+demangle.po: nm.h
+demangle.po: tm.h
+demangle.po: xm.h
+dictionary.o: nm.h
+dictionary.o: tm.h
+dictionary.o: xm.h
+dictionary.po: nm.h
+dictionary.po: tm.h
+dictionary.po: xm.h
+disasm.o: nm.h
+disasm.o: tm.h
+disasm.o: xm.h
+disasm.po: nm.h
+disasm.po: tm.h
+disasm.po: xm.h
+doublest.o: nm.h
+doublest.o: tm.h
+doublest.o: xm.h
+doublest.po: nm.h
+doublest.po: tm.h
+doublest.po: xm.h
+dummy-frame.o: nm.h
+dummy-frame.o: tm.h
+dummy-frame.o: xm.h
+dummy-frame.po: nm.h
+dummy-frame.po: tm.h
+dummy-frame.po: xm.h
+dwarf2-frame.o: nm.h
+dwarf2-frame.o: tm.h
+dwarf2-frame.o: xm.h
+dwarf2-frame.po: nm.h
+dwarf2-frame.po: tm.h
+dwarf2-frame.po: xm.h
+dwarf2expr.o: nm.h
+dwarf2expr.o: tm.h
+dwarf2expr.o: xm.h
+dwarf2expr.po: nm.h
+dwarf2expr.po: tm.h
+dwarf2expr.po: xm.h
+dwarf2loc.o: nm.h
+dwarf2loc.o: tm.h
+dwarf2loc.o: xm.h
+dwarf2loc.po: nm.h
+dwarf2loc.po: tm.h
+dwarf2loc.po: xm.h
+dwarf2read.o: nm.h
+dwarf2read.o: tm.h
+dwarf2read.o: xm.h
+dwarf2read.po: nm.h
+dwarf2read.po: tm.h
+dwarf2read.po: xm.h
+dwarfread.o: nm.h
+dwarfread.o: tm.h
+dwarfread.o: xm.h
+dwarfread.po: nm.h
+dwarfread.po: tm.h
+dwarfread.po: xm.h
+elfread.o: nm.h
+elfread.o: tm.h
+elfread.o: xm.h
+elfread.po: nm.h
+elfread.po: tm.h
+elfread.po: xm.h
+environ.o: nm.h
+environ.o: tm.h
+environ.o: xm.h
+environ.po: nm.h
+environ.po: tm.h
+environ.po: xm.h
+eval.o: nm.h
+eval.o: tm.h
+eval.o: xm.h
+eval.po: nm.h
+eval.po: tm.h
+eval.po: xm.h
+event-loop.o: nm.h
+event-loop.o: tm.h
+event-loop.o: xm.h
+event-loop.po: nm.h
+event-loop.po: tm.h
+event-loop.po: xm.h
+event-top.o: nm.h
+event-top.o: tm.h
+event-top.o: xm.h
+event-top.po: nm.h
+event-top.po: tm.h
+event-top.po: xm.h
+exec.o: nm.h
+exec.o: tm.h
+exec.o: xm.h
+exec.po: nm.h
+exec.po: tm.h
+exec.po: xm.h
+expprint.o: nm.h
+expprint.o: tm.h
+expprint.o: xm.h
+expprint.po: nm.h
+expprint.po: tm.h
+expprint.po: xm.h
+f-exp.o: f-exp.c
+f-exp.o: nm.h
+f-exp.o: tm.h
+f-exp.o: xm.h
+f-exp.po: f-exp.c
+f-exp.po: nm.h
+f-exp.po: tm.h
+f-exp.po: xm.h
+f-lang.o: nm.h
+f-lang.o: tm.h
+f-lang.o: xm.h
+f-lang.po: nm.h
+f-lang.po: tm.h
+f-lang.po: xm.h
+f-typeprint.o: nm.h
+f-typeprint.o: tm.h
+f-typeprint.o: xm.h
+f-typeprint.po: nm.h
+f-typeprint.po: tm.h
+f-typeprint.po: xm.h
+f-valprint.o: nm.h
+f-valprint.o: tm.h
+f-valprint.o: xm.h
+f-valprint.po: nm.h
+f-valprint.po: tm.h
+f-valprint.po: xm.h
+fbsd-proc.o: nm.h
+fbsd-proc.o: tm.h
+fbsd-proc.o: xm.h
+fbsd-proc.po: nm.h
+fbsd-proc.po: tm.h
+fbsd-proc.po: xm.h
+fbsd-threads.o: nm.h
+fbsd-threads.o: tm.h
+fbsd-threads.o: xm.h
+fbsd-threads.po: nm.h
+fbsd-threads.po: tm.h
+fbsd-threads.po: xm.h
+findvar.o: nm.h
+findvar.o: tm.h
+findvar.o: xm.h
+findvar.po: nm.h
+findvar.po: tm.h
+findvar.po: xm.h
+fork-child.o: nm.h
+fork-child.o: tm.h
+fork-child.o: xm.h
+fork-child.po: nm.h
+fork-child.po: tm.h
+fork-child.po: xm.h
+frame-base.o: nm.h
+frame-base.o: tm.h
+frame-base.o: xm.h
+frame-base.po: nm.h
+frame-base.po: tm.h
+frame-base.po: xm.h
+frame-unwind-kluge.o: frame-unwind-kluge.c
+frame-unwind-kluge.o: nm.h
+frame-unwind-kluge.o: tm.h
+frame-unwind-kluge.o: xm.h
+frame-unwind-kluge.po: frame-unwind-kluge.c
+frame-unwind-kluge.po: nm.h
+frame-unwind-kluge.po: tm.h
+frame-unwind-kluge.po: xm.h
+frame.o: nm.h
+frame.o: tm.h
+frame.o: xm.h
+frame.po: nm.h
+frame.po: tm.h
+frame.po: xm.h
+gcore.o: nm.h
+gcore.o: tm.h
+gcore.o: xm.h
+gcore.po: nm.h
+gcore.po: tm.h
+gcore.po: xm.h
+gdb-events.o: nm.h
+gdb-events.o: tm.h
+gdb-events.o: xm.h
+gdb-events.po: nm.h
+gdb-events.po: tm.h
+gdb-events.po: xm.h
+gdbarch.o: nm.h
+gdbarch.o: tm.h
+gdbarch.o: xm.h
+gdbarch.po: nm.h
+gdbarch.po: tm.h
+gdbarch.po: xm.h
+gdbtypes.o: nm.h
+gdbtypes.o: tm.h
+gdbtypes.o: xm.h
+gdbtypes.po: nm.h
+gdbtypes.po: tm.h
+gdbtypes.po: xm.h
+gnu-v2-abi.o: nm.h
+gnu-v2-abi.o: tm.h
+gnu-v2-abi.o: xm.h
+gnu-v2-abi.po: nm.h
+gnu-v2-abi.po: tm.h
+gnu-v2-abi.po: xm.h
+gnu-v3-abi.o: nm.h
+gnu-v3-abi.o: tm.h
+gnu-v3-abi.o: xm.h
+gnu-v3-abi.po: nm.h
+gnu-v3-abi.po: tm.h
+gnu-v3-abi.po: xm.h
+hpacc-abi.o: nm.h
+hpacc-abi.o: tm.h
+hpacc-abi.o: xm.h
+hpacc-abi.po: nm.h
+hpacc-abi.po: tm.h
+hpacc-abi.po: xm.h
+i386-nat.o: nm.h
+i386-nat.o: tm.h
+i386-nat.o: xm.h
+i386-nat.po: nm.h
+i386-nat.po: tm.h
+i386-nat.po: xm.h
+i386-tdep.o: nm.h
+i386-tdep.o: tm.h
+i386-tdep.o: xm.h
+i386-tdep.po: nm.h
+i386-tdep.po: tm.h
+i386-tdep.po: xm.h
+i386bsd-nat.o: nm.h
+i386bsd-nat.o: tm.h
+i386bsd-nat.o: xm.h
+i386bsd-nat.po: nm.h
+i386bsd-nat.po: tm.h
+i386bsd-nat.po: xm.h
+i386bsd-tdep.o: nm.h
+i386bsd-tdep.o: tm.h
+i386bsd-tdep.o: xm.h
+i386bsd-tdep.po: nm.h
+i386bsd-tdep.po: tm.h
+i386bsd-tdep.po: xm.h
+i386fbsd-nat.o: nm.h
+i386fbsd-nat.o: tm.h
+i386fbsd-nat.o: xm.h
+i386fbsd-nat.po: nm.h
+i386fbsd-nat.po: tm.h
+i386fbsd-nat.po: xm.h
+i386fbsd-tdep-fixed.o: i386fbsd-tdep-fixed.c
+i386fbsd-tdep-fixed.o: nm.h
+i386fbsd-tdep-fixed.o: tm.h
+i386fbsd-tdep-fixed.o: xm.h
+i386fbsd-tdep-fixed.po: i386fbsd-tdep-fixed.c
+i386fbsd-tdep-fixed.po: nm.h
+i386fbsd-tdep-fixed.po: tm.h
+i386fbsd-tdep-fixed.po: xm.h
+i387-tdep.o: nm.h
+i387-tdep.o: tm.h
+i387-tdep.o: xm.h
+i387-tdep.po: nm.h
+i387-tdep.po: tm.h
+i387-tdep.po: xm.h
+inf-loop.o: nm.h
+inf-loop.o: tm.h
+inf-loop.o: xm.h
+inf-loop.po: nm.h
+inf-loop.po: tm.h
+inf-loop.po: xm.h
+infcall.o: nm.h
+infcall.o: tm.h
+infcall.o: xm.h
+infcall.po: nm.h
+infcall.po: tm.h
+infcall.po: xm.h
+infcmd.o: nm.h
+infcmd.o: tm.h
+infcmd.o: xm.h
+infcmd.po: nm.h
+infcmd.po: tm.h
+infcmd.po: xm.h
+inflow.o: nm.h
+inflow.o: tm.h
+inflow.o: xm.h
+inflow.po: nm.h
+inflow.po: tm.h
+inflow.po: xm.h
+infptrace.o: nm.h
+infptrace.o: tm.h
+infptrace.o: xm.h
+infptrace.po: nm.h
+infptrace.po: tm.h
+infptrace.po: xm.h
+infrun.o: nm.h
+infrun.o: tm.h
+infrun.o: xm.h
+infrun.po: nm.h
+infrun.po: tm.h
+infrun.po: xm.h
+inftarg.o: nm.h
+inftarg.o: tm.h
+inftarg.o: xm.h
+inftarg.po: nm.h
+inftarg.po: tm.h
+inftarg.po: xm.h
+init.o: nm.h
+init.o: tm.h
+init.o: xm.h
+init.po: nm.h
+init.po: tm.h
+init.po: xm.h
+interps.o: nm.h
+interps.o: tm.h
+interps.o: xm.h
+interps.po: nm.h
+interps.po: tm.h
+interps.po: xm.h
+jv-exp.o: jv-exp.c
+jv-exp.o: nm.h
+jv-exp.o: tm.h
+jv-exp.o: xm.h
+jv-exp.po: jv-exp.c
+jv-exp.po: nm.h
+jv-exp.po: tm.h
+jv-exp.po: xm.h
+jv-lang.o: nm.h
+jv-lang.o: tm.h
+jv-lang.o: xm.h
+jv-lang.po: nm.h
+jv-lang.po: tm.h
+jv-lang.po: xm.h
+jv-typeprint.o: nm.h
+jv-typeprint.o: tm.h
+jv-typeprint.o: xm.h
+jv-typeprint.po: nm.h
+jv-typeprint.po: tm.h
+jv-typeprint.po: xm.h
+jv-valprint.o: nm.h
+jv-valprint.o: tm.h
+jv-valprint.o: xm.h
+jv-valprint.po: nm.h
+jv-valprint.po: tm.h
+jv-valprint.po: xm.h
+kod-cisco.o: nm.h
+kod-cisco.o: tm.h
+kod-cisco.o: xm.h
+kod-cisco.po: nm.h
+kod-cisco.po: tm.h
+kod-cisco.po: xm.h
+kod.o: nm.h
+kod.o: tm.h
+kod.o: xm.h
+kod.po: nm.h
+kod.po: tm.h
+kod.po: xm.h
+language.o: nm.h
+language.o: tm.h
+language.o: xm.h
+language.po: nm.h
+language.po: tm.h
+language.po: xm.h
+linespec.o: nm.h
+linespec.o: tm.h
+linespec.o: xm.h
+linespec.po: nm.h
+linespec.po: tm.h
+linespec.po: xm.h
+m2-exp.o: m2-exp.c
+m2-exp.o: nm.h
+m2-exp.o: tm.h
+m2-exp.o: xm.h
+m2-exp.po: m2-exp.c
+m2-exp.po: nm.h
+m2-exp.po: tm.h
+m2-exp.po: xm.h
+m2-lang.o: nm.h
+m2-lang.o: tm.h
+m2-lang.o: xm.h
+m2-lang.po: nm.h
+m2-lang.po: tm.h
+m2-lang.po: xm.h
+m2-typeprint.o: nm.h
+m2-typeprint.o: tm.h
+m2-typeprint.o: xm.h
+m2-typeprint.po: nm.h
+m2-typeprint.po: tm.h
+m2-typeprint.po: xm.h
+m2-valprint.o: nm.h
+m2-valprint.o: tm.h
+m2-valprint.o: xm.h
+m2-valprint.po: nm.h
+m2-valprint.po: tm.h
+m2-valprint.po: xm.h
+macrocmd.o: nm.h
+macrocmd.o: tm.h
+macrocmd.o: xm.h
+macrocmd.po: nm.h
+macrocmd.po: tm.h
+macrocmd.po: xm.h
+macroexp.o: nm.h
+macroexp.o: tm.h
+macroexp.o: xm.h
+macroexp.po: nm.h
+macroexp.po: tm.h
+macroexp.po: xm.h
+macroscope.o: nm.h
+macroscope.o: tm.h
+macroscope.o: xm.h
+macroscope.po: nm.h
+macroscope.po: tm.h
+macroscope.po: xm.h
+macrotab.o: nm.h
+macrotab.o: tm.h
+macrotab.o: xm.h
+macrotab.po: nm.h
+macrotab.po: tm.h
+macrotab.po: xm.h
+main.o: nm.h
+main.o: tm.h
+main.o: xm.h
+main.po: nm.h
+main.po: tm.h
+main.po: xm.h
+maint.o: nm.h
+maint.o: tm.h
+maint.o: xm.h
+maint.po: nm.h
+maint.po: tm.h
+maint.po: xm.h
+mdebugread.o: nm.h
+mdebugread.o: tm.h
+mdebugread.o: xm.h
+mdebugread.po: nm.h
+mdebugread.po: tm.h
+mdebugread.po: xm.h
+mem-break.o: nm.h
+mem-break.o: tm.h
+mem-break.o: xm.h
+mem-break.po: nm.h
+mem-break.po: tm.h
+mem-break.po: xm.h
+memattr.o: nm.h
+memattr.o: tm.h
+memattr.o: xm.h
+memattr.po: nm.h
+memattr.po: tm.h
+memattr.po: xm.h
+mi-cmd-break.o: nm.h
+mi-cmd-break.o: tm.h
+mi-cmd-break.o: xm.h
+mi-cmd-break.po: nm.h
+mi-cmd-break.po: tm.h
+mi-cmd-break.po: xm.h
+mi-cmd-disas.o: nm.h
+mi-cmd-disas.o: tm.h
+mi-cmd-disas.o: xm.h
+mi-cmd-disas.po: nm.h
+mi-cmd-disas.po: tm.h
+mi-cmd-disas.po: xm.h
+mi-cmd-env.o: nm.h
+mi-cmd-env.o: tm.h
+mi-cmd-env.o: xm.h
+mi-cmd-env.po: nm.h
+mi-cmd-env.po: tm.h
+mi-cmd-env.po: xm.h
+mi-cmd-file.o: nm.h
+mi-cmd-file.o: tm.h
+mi-cmd-file.o: xm.h
+mi-cmd-file.po: nm.h
+mi-cmd-file.po: tm.h
+mi-cmd-file.po: xm.h
+mi-cmd-stack.o: nm.h
+mi-cmd-stack.o: tm.h
+mi-cmd-stack.o: xm.h
+mi-cmd-stack.po: nm.h
+mi-cmd-stack.po: tm.h
+mi-cmd-stack.po: xm.h
+mi-cmd-var.o: nm.h
+mi-cmd-var.o: tm.h
+mi-cmd-var.o: xm.h
+mi-cmd-var.po: nm.h
+mi-cmd-var.po: tm.h
+mi-cmd-var.po: xm.h
+mi-cmds.o: nm.h
+mi-cmds.o: tm.h
+mi-cmds.o: xm.h
+mi-cmds.po: nm.h
+mi-cmds.po: tm.h
+mi-cmds.po: xm.h
+mi-console.o: nm.h
+mi-console.o: tm.h
+mi-console.o: xm.h
+mi-console.po: nm.h
+mi-console.po: tm.h
+mi-console.po: xm.h
+mi-getopt.o: nm.h
+mi-getopt.o: tm.h
+mi-getopt.o: xm.h
+mi-getopt.po: nm.h
+mi-getopt.po: tm.h
+mi-getopt.po: xm.h
+mi-interp.o: nm.h
+mi-interp.o: tm.h
+mi-interp.o: xm.h
+mi-interp.po: nm.h
+mi-interp.po: tm.h
+mi-interp.po: xm.h
+mi-main.o: nm.h
+mi-main.o: tm.h
+mi-main.o: xm.h
+mi-main.po: nm.h
+mi-main.po: tm.h
+mi-main.po: xm.h
+mi-out.o: nm.h
+mi-out.o: tm.h
+mi-out.o: xm.h
+mi-out.po: nm.h
+mi-out.po: tm.h
+mi-out.po: xm.h
+mi-parse.o: nm.h
+mi-parse.o: tm.h
+mi-parse.o: xm.h
+mi-parse.po: nm.h
+mi-parse.po: tm.h
+mi-parse.po: xm.h
+mi-symbol-cmds.o: nm.h
+mi-symbol-cmds.o: tm.h
+mi-symbol-cmds.o: xm.h
+mi-symbol-cmds.po: nm.h
+mi-symbol-cmds.po: tm.h
+mi-symbol-cmds.po: xm.h
+minsyms.o: nm.h
+minsyms.o: tm.h
+minsyms.o: xm.h
+minsyms.po: nm.h
+minsyms.po: tm.h
+minsyms.po: xm.h
+mipsread.o: nm.h
+mipsread.o: tm.h
+mipsread.o: xm.h
+mipsread.po: nm.h
+mipsread.po: tm.h
+mipsread.po: xm.h
+nlmread.o: nm.h
+nlmread.o: tm.h
+nlmread.o: xm.h
+nlmread.po: nm.h
+nlmread.po: tm.h
+nlmread.po: xm.h
+objc-exp.o: nm.h
+objc-exp.o: objc-exp.c
+objc-exp.o: tm.h
+objc-exp.o: xm.h
+objc-exp.po: nm.h
+objc-exp.po: objc-exp.c
+objc-exp.po: tm.h
+objc-exp.po: xm.h
+objc-lang.o: nm.h
+objc-lang.o: tm.h
+objc-lang.o: xm.h
+objc-lang.po: nm.h
+objc-lang.po: tm.h
+objc-lang.po: xm.h
+objfiles.o: nm.h
+objfiles.o: tm.h
+objfiles.o: xm.h
+objfiles.po: nm.h
+objfiles.po: tm.h
+objfiles.po: xm.h
+observer.o: nm.h
+observer.o: tm.h
+observer.o: xm.h
+observer.po: nm.h
+observer.po: tm.h
+observer.po: xm.h
+osabi.o: nm.h
+osabi.o: tm.h
+osabi.o: xm.h
+osabi.po: nm.h
+osabi.po: tm.h
+osabi.po: xm.h
+p-exp.o: nm.h
+p-exp.o: p-exp.c
+p-exp.o: tm.h
+p-exp.o: xm.h
+p-exp.po: nm.h
+p-exp.po: p-exp.c
+p-exp.po: tm.h
+p-exp.po: xm.h
+p-lang.o: nm.h
+p-lang.o: tm.h
+p-lang.o: xm.h
+p-lang.po: nm.h
+p-lang.po: tm.h
+p-lang.po: xm.h
+p-typeprint.o: nm.h
+p-typeprint.o: tm.h
+p-typeprint.o: xm.h
+p-typeprint.po: nm.h
+p-typeprint.po: tm.h
+p-typeprint.po: xm.h
+p-valprint.o: nm.h
+p-valprint.o: tm.h
+p-valprint.o: xm.h
+p-valprint.po: nm.h
+p-valprint.po: tm.h
+p-valprint.po: xm.h
+parse.o: nm.h
+parse.o: tm.h
+parse.o: xm.h
+parse.po: nm.h
+parse.po: tm.h
+parse.po: xm.h
+printcmd.o: nm.h
+printcmd.o: tm.h
+printcmd.o: xm.h
+printcmd.po: nm.h
+printcmd.po: tm.h
+printcmd.po: xm.h
+regcache.o: nm.h
+regcache.o: tm.h
+regcache.o: xm.h
+regcache.po: nm.h
+regcache.po: tm.h
+regcache.po: xm.h
+reggroups.o: nm.h
+reggroups.o: tm.h
+reggroups.o: xm.h
+reggroups.po: nm.h
+reggroups.po: tm.h
+reggroups.po: xm.h
+remote-fileio.o: nm.h
+remote-fileio.o: tm.h
+remote-fileio.o: xm.h
+remote-fileio.po: nm.h
+remote-fileio.po: tm.h
+remote-fileio.po: xm.h
+remote-utils.o: nm.h
+remote-utils.o: tm.h
+remote-utils.o: xm.h
+remote-utils.po: nm.h
+remote-utils.po: tm.h
+remote-utils.po: xm.h
+remote.o: nm.h
+remote.o: tm.h
+remote.o: xm.h
+remote.po: nm.h
+remote.po: tm.h
+remote.po: xm.h
+scm-exp.o: nm.h
+scm-exp.o: tm.h
+scm-exp.o: xm.h
+scm-exp.po: nm.h
+scm-exp.po: tm.h
+scm-exp.po: xm.h
+scm-lang.o: nm.h
+scm-lang.o: tm.h
+scm-lang.o: xm.h
+scm-lang.po: nm.h
+scm-lang.po: tm.h
+scm-lang.po: xm.h
+scm-valprint.o: nm.h
+scm-valprint.o: tm.h
+scm-valprint.o: xm.h
+scm-valprint.po: nm.h
+scm-valprint.po: tm.h
+scm-valprint.po: xm.h
+sentinel-frame.o: nm.h
+sentinel-frame.o: tm.h
+sentinel-frame.o: xm.h
+sentinel-frame.po: nm.h
+sentinel-frame.po: tm.h
+sentinel-frame.po: xm.h
+ser-pipe.o: nm.h
+ser-pipe.o: tm.h
+ser-pipe.o: xm.h
+ser-pipe.po: nm.h
+ser-pipe.po: tm.h
+ser-pipe.po: xm.h
+ser-tcp.o: nm.h
+ser-tcp.o: tm.h
+ser-tcp.o: xm.h
+ser-tcp.po: nm.h
+ser-tcp.po: tm.h
+ser-tcp.po: xm.h
+ser-unix.o: nm.h
+ser-unix.o: tm.h
+ser-unix.o: xm.h
+ser-unix.po: nm.h
+ser-unix.po: tm.h
+ser-unix.po: xm.h
+serial.o: nm.h
+serial.o: tm.h
+serial.o: xm.h
+serial.po: nm.h
+serial.po: tm.h
+serial.po: xm.h
+signals.o: nm.h
+signals.o: tm.h
+signals.o: xm.h
+signals.po: nm.h
+signals.po: tm.h
+signals.po: xm.h
+solib-svr4.o: nm.h
+solib-svr4.o: tm.h
+solib-svr4.o: xm.h
+solib-svr4.po: nm.h
+solib-svr4.po: tm.h
+solib-svr4.po: xm.h
+solib.o: nm.h
+solib.o: tm.h
+solib.o: xm.h
+solib.po: nm.h
+solib.po: tm.h
+solib.po: xm.h
+source.o: nm.h
+source.o: tm.h
+source.o: xm.h
+source.po: nm.h
+source.po: tm.h
+source.po: xm.h
+stabsread.o: nm.h
+stabsread.o: tm.h
+stabsread.o: xm.h
+stabsread.po: nm.h
+stabsread.po: tm.h
+stabsread.po: xm.h
+stack.o: nm.h
+stack.o: tm.h
+stack.o: xm.h
+stack.po: nm.h
+stack.po: tm.h
+stack.po: xm.h
+std-regs.o: nm.h
+std-regs.o: tm.h
+std-regs.o: xm.h
+std-regs.po: nm.h
+std-regs.po: tm.h
+std-regs.po: xm.h
+symfile.o: nm.h
+symfile.o: tm.h
+symfile.o: xm.h
+symfile.po: nm.h
+symfile.po: tm.h
+symfile.po: xm.h
+symmisc.o: nm.h
+symmisc.o: tm.h
+symmisc.o: xm.h
+symmisc.po: nm.h
+symmisc.po: tm.h
+symmisc.po: xm.h
+symtab.o: nm.h
+symtab.o: tm.h
+symtab.o: xm.h
+symtab.po: nm.h
+symtab.po: tm.h
+symtab.po: xm.h
+target.o: nm.h
+target.o: tm.h
+target.o: xm.h
+target.po: nm.h
+target.po: tm.h
+target.po: xm.h
+thread.o: nm.h
+thread.o: tm.h
+thread.o: xm.h
+thread.po: nm.h
+thread.po: tm.h
+thread.po: xm.h
+top.o: nm.h
+top.o: tm.h
+top.o: xm.h
+top.po: nm.h
+top.po: tm.h
+top.po: xm.h
+tracepoint.o: nm.h
+tracepoint.o: tm.h
+tracepoint.o: xm.h
+tracepoint.po: nm.h
+tracepoint.po: tm.h
+tracepoint.po: xm.h
+trad-frame.o: nm.h
+trad-frame.o: tm.h
+trad-frame.o: xm.h
+trad-frame.po: nm.h
+trad-frame.po: tm.h
+trad-frame.po: xm.h
+tui-command.o: nm.h
+tui-command.o: tm.h
+tui-command.o: xm.h
+tui-command.po: nm.h
+tui-command.po: tm.h
+tui-command.po: xm.h
+tui-data.o: nm.h
+tui-data.o: tm.h
+tui-data.o: xm.h
+tui-data.po: nm.h
+tui-data.po: tm.h
+tui-data.po: xm.h
+tui-disasm.o: nm.h
+tui-disasm.o: tm.h
+tui-disasm.o: xm.h
+tui-disasm.po: nm.h
+tui-disasm.po: tm.h
+tui-disasm.po: xm.h
+tui-file.o: nm.h
+tui-file.o: tm.h
+tui-file.o: xm.h
+tui-file.po: nm.h
+tui-file.po: tm.h
+tui-file.po: xm.h
+tui-hooks.o: nm.h
+tui-hooks.o: tm.h
+tui-hooks.o: xm.h
+tui-hooks.po: nm.h
+tui-hooks.po: tm.h
+tui-hooks.po: xm.h
+tui-interp.o: nm.h
+tui-interp.o: tm.h
+tui-interp.o: xm.h
+tui-interp.po: nm.h
+tui-interp.po: tm.h
+tui-interp.po: xm.h
+tui-io.o: nm.h
+tui-io.o: tm.h
+tui-io.o: xm.h
+tui-io.po: nm.h
+tui-io.po: tm.h
+tui-io.po: xm.h
+tui-layout.o: nm.h
+tui-layout.o: tm.h
+tui-layout.o: xm.h
+tui-layout.po: nm.h
+tui-layout.po: tm.h
+tui-layout.po: xm.h
+tui-out.o: nm.h
+tui-out.o: tm.h
+tui-out.o: xm.h
+tui-out.po: nm.h
+tui-out.po: tm.h
+tui-out.po: xm.h
+tui-regs.o: nm.h
+tui-regs.o: tm.h
+tui-regs.o: xm.h
+tui-regs.po: nm.h
+tui-regs.po: tm.h
+tui-regs.po: xm.h
+tui-source.o: nm.h
+tui-source.o: tm.h
+tui-source.o: xm.h
+tui-source.po: nm.h
+tui-source.po: tm.h
+tui-source.po: xm.h
+tui-stack.o: nm.h
+tui-stack.o: tm.h
+tui-stack.o: xm.h
+tui-stack.po: nm.h
+tui-stack.po: tm.h
+tui-stack.po: xm.h
+tui-win.o: nm.h
+tui-win.o: tm.h
+tui-win.o: xm.h
+tui-win.po: nm.h
+tui-win.po: tm.h
+tui-win.po: xm.h
+tui-windata.o: nm.h
+tui-windata.o: tm.h
+tui-windata.o: xm.h
+tui-windata.po: nm.h
+tui-windata.po: tm.h
+tui-windata.po: xm.h
+tui-wingeneral.o: nm.h
+tui-wingeneral.o: tm.h
+tui-wingeneral.o: xm.h
+tui-wingeneral.po: nm.h
+tui-wingeneral.po: tm.h
+tui-wingeneral.po: xm.h
+tui-winsource.o: nm.h
+tui-winsource.o: tm.h
+tui-winsource.o: xm.h
+tui-winsource.po: nm.h
+tui-winsource.po: tm.h
+tui-winsource.po: xm.h
+tui.o: nm.h
+tui.o: tm.h
+tui.o: xm.h
+tui.po: nm.h
+tui.po: tm.h
+tui.po: xm.h
+typeprint.o: nm.h
+typeprint.o: tm.h
+typeprint.o: xm.h
+typeprint.po: nm.h
+typeprint.po: tm.h
+typeprint.po: xm.h
+ui-file.o: nm.h
+ui-file.o: tm.h
+ui-file.o: xm.h
+ui-file.po: nm.h
+ui-file.po: tm.h
+ui-file.po: xm.h
+ui-out.o: nm.h
+ui-out.o: tm.h
+ui-out.o: xm.h
+ui-out.po: nm.h
+ui-out.po: tm.h
+ui-out.po: xm.h
+user-regs.o: nm.h
+user-regs.o: tm.h
+user-regs.o: xm.h
+user-regs.po: nm.h
+user-regs.po: tm.h
+user-regs.po: xm.h
+utils.o: nm.h
+utils.o: tm.h
+utils.o: xm.h
+utils.po: nm.h
+utils.po: tm.h
+utils.po: xm.h
+valarith.o: nm.h
+valarith.o: tm.h
+valarith.o: xm.h
+valarith.po: nm.h
+valarith.po: tm.h
+valarith.po: xm.h
+valops.o: nm.h
+valops.o: tm.h
+valops.o: xm.h
+valops.po: nm.h
+valops.po: tm.h
+valops.po: xm.h
+valprint.o: nm.h
+valprint.o: tm.h
+valprint.o: xm.h
+valprint.po: nm.h
+valprint.po: tm.h
+valprint.po: xm.h
+values.o: nm.h
+values.o: tm.h
+values.o: xm.h
+values.po: nm.h
+values.po: tm.h
+values.po: xm.h
+varobj.o: nm.h
+varobj.o: tm.h
+varobj.o: xm.h
+varobj.po: nm.h
+varobj.po: tm.h
+varobj.po: xm.h
+version.o: version.c
+version.po: version.c
+wrapper.o: nm.h
+wrapper.o: tm.h
+wrapper.o: xm.h
+wrapper.po: nm.h
+wrapper.po: tm.h
+wrapper.po: xm.h
+.endif
diff --git a/gnu/usr.bin/gperf/Makefile.depend b/gnu/usr.bin/gperf/Makefile.depend
new file mode 100644
index 0000000..14a7272
--- /dev/null
+++ b/gnu/usr.bin/gperf/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/grep/Makefile.depend b/gnu/usr.bin/grep/Makefile.depend
new file mode 100644
index 0000000..3f9e676
--- /dev/null
+++ b/gnu/usr.bin/grep/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libregex \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbz2 \
+ lib/libc \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devX100-12/Makefile.depend b/gnu/usr.bin/groff/font/devX100-12/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devX100-12/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devX100/Makefile.depend b/gnu/usr.bin/groff/font/devX100/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devX100/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devX75-12/Makefile.depend b/gnu/usr.bin/groff/font/devX75-12/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devX75-12/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devX75/Makefile.depend b/gnu/usr.bin/groff/font/devX75/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devX75/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devascii/Makefile.depend b/gnu/usr.bin/groff/font/devascii/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devascii/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devcp1047/Makefile.depend b/gnu/usr.bin/groff/font/devcp1047/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devcp1047/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devdvi/Makefile.depend b/gnu/usr.bin/groff/font/devdvi/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devdvi/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devhtml/Makefile.depend b/gnu/usr.bin/groff/font/devhtml/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devhtml/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devkoi8-r/Makefile.depend b/gnu/usr.bin/groff/font/devkoi8-r/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devkoi8-r/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devlatin1/Makefile.depend b/gnu/usr.bin/groff/font/devlatin1/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devlatin1/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devlbp/Makefile.depend b/gnu/usr.bin/groff/font/devlbp/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devlbp/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devlj4/Makefile.depend b/gnu/usr.bin/groff/font/devlj4/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devlj4/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devps/Makefile.depend b/gnu/usr.bin/groff/font/devps/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devps/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/font/devutf8/Makefile.depend b/gnu/usr.bin/groff/font/devutf8/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/font/devutf8/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/man/Makefile.depend b/gnu/usr.bin/groff/man/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/man/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/devices/grodvi/Makefile.depend b/gnu/usr.bin/groff/src/devices/grodvi/Makefile.depend
new file mode 100644
index 0000000..a5c44b5
--- /dev/null
+++ b/gnu/usr.bin/groff/src/devices/grodvi/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libdriver \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/devices/grohtml/Makefile.depend b/gnu/usr.bin/groff/src/devices/grohtml/Makefile.depend
new file mode 100644
index 0000000..a5c44b5
--- /dev/null
+++ b/gnu/usr.bin/groff/src/devices/grohtml/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libdriver \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/devices/grolbp/Makefile.depend b/gnu/usr.bin/groff/src/devices/grolbp/Makefile.depend
new file mode 100644
index 0000000..a5c44b5
--- /dev/null
+++ b/gnu/usr.bin/groff/src/devices/grolbp/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libdriver \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/devices/grolj4/Makefile.depend b/gnu/usr.bin/groff/src/devices/grolj4/Makefile.depend
new file mode 100644
index 0000000..a5c44b5
--- /dev/null
+++ b/gnu/usr.bin/groff/src/devices/grolj4/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libdriver \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/devices/grops/Makefile.depend b/gnu/usr.bin/groff/src/devices/grops/Makefile.depend
new file mode 100644
index 0000000..a5c44b5
--- /dev/null
+++ b/gnu/usr.bin/groff/src/devices/grops/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libdriver \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/devices/grotty/Makefile.depend b/gnu/usr.bin/groff/src/devices/grotty/Makefile.depend
new file mode 100644
index 0000000..a5c44b5
--- /dev/null
+++ b/gnu/usr.bin/groff/src/devices/grotty/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libdriver \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/libs/libbib/Makefile.depend b/gnu/usr.bin/groff/src/libs/libbib/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/gnu/usr.bin/groff/src/libs/libbib/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/libs/libdriver/Makefile.depend b/gnu/usr.bin/groff/src/libs/libdriver/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/gnu/usr.bin/groff/src/libs/libdriver/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/libs/libgroff/Makefile.depend b/gnu/usr.bin/groff/src/libs/libgroff/Makefile.depend
new file mode 100644
index 0000000..8ed89d7
--- /dev/null
+++ b/gnu/usr.bin/groff/src/libs/libgroff/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+version.o: version.cpp
+version.po: version.cpp
+.endif
diff --git a/gnu/usr.bin/groff/src/preproc/eqn/Makefile.depend b/gnu/usr.bin/groff/src/preproc/eqn/Makefile.depend
new file mode 100644
index 0000000..971bd95
--- /dev/null
+++ b/gnu/usr.bin/groff/src/preproc/eqn/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+eqn.o: eqn.cpp
+eqn.po: eqn.cpp
+lex.o: eqn_tab.h
+lex.po: eqn_tab.h
+.endif
diff --git a/gnu/usr.bin/groff/src/preproc/grn/Makefile.depend b/gnu/usr.bin/groff/src/preproc/grn/Makefile.depend
new file mode 100644
index 0000000..6536586
--- /dev/null
+++ b/gnu/usr.bin/groff/src/preproc/grn/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/preproc/html/Makefile.depend b/gnu/usr.bin/groff/src/preproc/html/Makefile.depend
new file mode 100644
index 0000000..6536586
--- /dev/null
+++ b/gnu/usr.bin/groff/src/preproc/html/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/preproc/pic/Makefile.depend b/gnu/usr.bin/groff/src/preproc/pic/Makefile.depend
new file mode 100644
index 0000000..769449c
--- /dev/null
+++ b/gnu/usr.bin/groff/src/preproc/pic/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+lex.o: pic_tab.h
+lex.po: pic_tab.h
+pic.o: pic.cpp
+pic.po: pic.cpp
+.endif
diff --git a/gnu/usr.bin/groff/src/preproc/refer/Makefile.depend b/gnu/usr.bin/groff/src/preproc/refer/Makefile.depend
new file mode 100644
index 0000000..e026f84
--- /dev/null
+++ b/gnu/usr.bin/groff/src/preproc/refer/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libbib \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+label.o: label.cpp
+label.po: label.cpp
+.endif
diff --git a/gnu/usr.bin/groff/src/preproc/soelim/Makefile.depend b/gnu/usr.bin/groff/src/preproc/soelim/Makefile.depend
new file mode 100644
index 0000000..6536586
--- /dev/null
+++ b/gnu/usr.bin/groff/src/preproc/soelim/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/preproc/tbl/Makefile.depend b/gnu/usr.bin/groff/src/preproc/tbl/Makefile.depend
new file mode 100644
index 0000000..6536586
--- /dev/null
+++ b/gnu/usr.bin/groff/src/preproc/tbl/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/roff/groff/Makefile.depend b/gnu/usr.bin/groff/src/roff/groff/Makefile.depend
new file mode 100644
index 0000000..6536586
--- /dev/null
+++ b/gnu/usr.bin/groff/src/roff/groff/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/roff/grog/Makefile.depend b/gnu/usr.bin/groff/src/roff/grog/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/src/roff/grog/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/roff/nroff/Makefile.depend b/gnu/usr.bin/groff/src/roff/nroff/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/src/roff/nroff/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/roff/psroff/Makefile.depend b/gnu/usr.bin/groff/src/roff/psroff/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/src/roff/psroff/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/roff/troff/Makefile.depend b/gnu/usr.bin/groff/src/roff/troff/Makefile.depend
new file mode 100644
index 0000000..fbf42cf
--- /dev/null
+++ b/gnu/usr.bin/groff/src/roff/troff/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+majorminor.o: majorminor.cpp
+majorminor.po: majorminor.cpp
+.endif
diff --git a/gnu/usr.bin/groff/src/utils/addftinfo/Makefile.depend b/gnu/usr.bin/groff/src/utils/addftinfo/Makefile.depend
new file mode 100644
index 0000000..6536586
--- /dev/null
+++ b/gnu/usr.bin/groff/src/utils/addftinfo/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/utils/afmtodit/Makefile.depend b/gnu/usr.bin/groff/src/utils/afmtodit/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/src/utils/afmtodit/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/utils/hpftodit/Makefile.depend b/gnu/usr.bin/groff/src/utils/hpftodit/Makefile.depend
new file mode 100644
index 0000000..6536586
--- /dev/null
+++ b/gnu/usr.bin/groff/src/utils/hpftodit/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/utils/indxbib/Makefile.depend b/gnu/usr.bin/groff/src/utils/indxbib/Makefile.depend
new file mode 100644
index 0000000..339cc48
--- /dev/null
+++ b/gnu/usr.bin/groff/src/utils/indxbib/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libbib \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/utils/lkbib/Makefile.depend b/gnu/usr.bin/groff/src/utils/lkbib/Makefile.depend
new file mode 100644
index 0000000..339cc48
--- /dev/null
+++ b/gnu/usr.bin/groff/src/utils/lkbib/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libbib \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/utils/lookbib/Makefile.depend b/gnu/usr.bin/groff/src/utils/lookbib/Makefile.depend
new file mode 100644
index 0000000..339cc48
--- /dev/null
+++ b/gnu/usr.bin/groff/src/utils/lookbib/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libbib \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/utils/pfbtops/Makefile.depend b/gnu/usr.bin/groff/src/utils/pfbtops/Makefile.depend
new file mode 100644
index 0000000..c9e6df1
--- /dev/null
+++ b/gnu/usr.bin/groff/src/utils/pfbtops/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/src/utils/tfmtodit/Makefile.depend b/gnu/usr.bin/groff/src/utils/tfmtodit/Makefile.depend
new file mode 100644
index 0000000..6536586
--- /dev/null
+++ b/gnu/usr.bin/groff/src/utils/tfmtodit/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ gnu/usr.bin/groff/src/libs/libgroff \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/groff/tmac/Makefile.depend b/gnu/usr.bin/groff/tmac/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/groff/tmac/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/patch/Makefile.depend b/gnu/usr.bin/patch/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/gnu/usr.bin/patch/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/rcs/ci/Makefile.depend b/gnu/usr.bin/rcs/ci/Makefile.depend
new file mode 100644
index 0000000..42c5411
--- /dev/null
+++ b/gnu/usr.bin/rcs/ci/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/rcs/lib \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/rcs/co/Makefile.depend b/gnu/usr.bin/rcs/co/Makefile.depend
new file mode 100644
index 0000000..42c5411
--- /dev/null
+++ b/gnu/usr.bin/rcs/co/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/rcs/lib \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/rcs/ident/Makefile.depend b/gnu/usr.bin/rcs/ident/Makefile.depend
new file mode 100644
index 0000000..42c5411
--- /dev/null
+++ b/gnu/usr.bin/rcs/ident/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/rcs/lib \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/rcs/lib/Makefile.depend b/gnu/usr.bin/rcs/lib/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/gnu/usr.bin/rcs/lib/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/rcs/merge/Makefile.depend b/gnu/usr.bin/rcs/merge/Makefile.depend
new file mode 100644
index 0000000..42c5411
--- /dev/null
+++ b/gnu/usr.bin/rcs/merge/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/rcs/lib \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/rcs/rcs/Makefile.depend b/gnu/usr.bin/rcs/rcs/Makefile.depend
new file mode 100644
index 0000000..42c5411
--- /dev/null
+++ b/gnu/usr.bin/rcs/rcs/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/rcs/lib \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/rcs/rcsclean/Makefile.depend b/gnu/usr.bin/rcs/rcsclean/Makefile.depend
new file mode 100644
index 0000000..42c5411
--- /dev/null
+++ b/gnu/usr.bin/rcs/rcsclean/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/rcs/lib \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/rcs/rcsdiff/Makefile.depend b/gnu/usr.bin/rcs/rcsdiff/Makefile.depend
new file mode 100644
index 0000000..42c5411
--- /dev/null
+++ b/gnu/usr.bin/rcs/rcsdiff/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/rcs/lib \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/rcs/rcsfreeze/Makefile.depend b/gnu/usr.bin/rcs/rcsfreeze/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/rcs/rcsfreeze/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/rcs/rcsmerge/Makefile.depend b/gnu/usr.bin/rcs/rcsmerge/Makefile.depend
new file mode 100644
index 0000000..42c5411
--- /dev/null
+++ b/gnu/usr.bin/rcs/rcsmerge/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/rcs/lib \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/rcs/rlog/Makefile.depend b/gnu/usr.bin/rcs/rlog/Makefile.depend
new file mode 100644
index 0000000..42c5411
--- /dev/null
+++ b/gnu/usr.bin/rcs/rlog/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/rcs/lib \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/sdiff/Makefile.depend b/gnu/usr.bin/sdiff/Makefile.depend
new file mode 100644
index 0000000..a90cb9a
--- /dev/null
+++ b/gnu/usr.bin/sdiff/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+sdiff.o: sdiff.c
+sdiff.po: sdiff.c
+.endif
diff --git a/gnu/usr.bin/send-pr/Makefile.depend b/gnu/usr.bin/send-pr/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/gnu/usr.bin/send-pr/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/sort/Makefile b/gnu/usr.bin/sort/Makefile
new file mode 100644
index 0000000..bf193bc
--- /dev/null
+++ b/gnu/usr.bin/sort/Makefile
@@ -0,0 +1,46 @@
+# $FreeBSD$
+
+SORTDIR= ${.CURDIR}/../../../contrib/gnu-sort
+.PATH: ${SORTDIR}/lib ${SORTDIR}/src ${SORTDIR}/man
+
+.include <bsd.own.mk>
+
+.if ${MK_GNU_SORT} == "yes"
+PROG= sort
+.else
+PROG= gnusort
+
+CLEANFILES+= gnusort.1
+gnusort.1: sort.1
+ cp ${.ALLSRC} ${.TARGET}
+.endif
+
+SRCS= sort.c \
+ __fpending.c \
+ argmatch.c \
+ closeout.c \
+ dup-safer.c \
+ error.c \
+ exitfail.c \
+ fopen-safer.c \
+ hard-locale.c \
+ human.c \
+ long-options.c \
+ memcoll.c \
+ physmem.c \
+ posixver.c \
+ quote.c \
+ quotearg.c \
+ strnlen.c \
+ umaxtostr.c \
+ version-etc.c \
+ xalloc-die.c \
+ xmalloc.c \
+ xmemcoll.c \
+ xstrtoul.c \
+ xstrtoumax.c
+
+CFLAGS+=-DHAVE_CONFIG_H -DHAVE_LANGINFO_H=1 -DHAVE_NL_LANGINFO=1 \
+ -I${.CURDIR} -I${SORTDIR}/lib
+
+.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/sort/Makefile.depend b/gnu/usr.bin/sort/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/gnu/usr.bin/sort/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/sort/alloca.h b/gnu/usr.bin/sort/alloca.h
new file mode 100644
index 0000000..59a1309
--- /dev/null
+++ b/gnu/usr.bin/sort/alloca.h
@@ -0,0 +1,2 @@
+/* $FreeBSD$ */
+extern void *alloca(size_t size);
diff --git a/gnu/usr.bin/sort/config.h b/gnu/usr.bin/sort/config.h
new file mode 100644
index 0000000..601b368
--- /dev/null
+++ b/gnu/usr.bin/sort/config.h
@@ -0,0 +1,1519 @@
+/* $FreeBSD$ */
+/* config.h. Generated by configure. */
+/* config.hin. Generated from configure.ac by autoheader. */
+
+/* Define if you have the Andrew File System. */
+/* #undef AFS */
+
+/* Define to the function xargmatch calls on failures. */
+#define ARGMATCH_DIE usage (1)
+
+/* Define to the declaration of the xargmatch failure function. */
+#define ARGMATCH_DIE_DECL extern void usage ()
+
+/* Define to 1 if the `closedir' function returns void instead of `int'. */
+/* #undef CLOSEDIR_VOID */
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Define to 1 if using `getloadavg.c'. */
+/* #undef C_GETLOADAVG */
+
+/* Define the default level of POSIX conformance. The value is of the form
+ YYYYMM, specifying the year and month the standard was adopted. If not
+ defined here, it defaults to the value of _POSIX2_VERSION in <unistd.h>.
+ Define to 199209 to default to POSIX 1003.2-1992, which makes standard
+ programs like `head', `tail', and `sort' accept obsolete options like `+10'
+ and `-10'. Define to 200112 to default to POSIX 1003.1-2001, which makes
+ these standard programs treat leading-`+' operands as file names and
+ require modern usages like `-n 10' instead of `-10'. Whether defined here
+ or not, the default can be overridden at run time via the _POSIX2_VERSION
+ environment variable. */
+/* #undef DEFAULT_POSIX2_VERSION */
+
+/* Define to 1 for DGUX with <sys/dg_sys_info.h>. */
+/* #undef DGUX */
+
+/* the name of the file descriptor member of DIR */
+/* #undef DIR_FD_MEMBER_NAME */
+
+#ifdef DIR_FD_MEMBER_NAME
+# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME)
+#else
+# define DIR_TO_FD(Dir_p) -1
+#endif
+
+
+
+/* Define if there is a member named d_ino in the struct describing directory
+ headers. */
+#define D_INO_IN_DIRENT 1
+
+/* Define to 1 if translation of program messages to the user's native
+ language is requested. */
+/* #undef ENABLE_NLS */
+
+/* Define on systems for which file names may have a so-called `drive letter'
+ prefix, define this to compute the length of that prefix, including the
+ colon. */
+#define FILESYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX 0
+
+/* Define if the backslash character may also serve as a file name component
+ separator. */
+#define FILESYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR 0
+
+#if FILESYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
+# define FILESYSTEM_PREFIX_LEN(Filename) \
+ ((Filename)[0] && (Filename)[1] == ':' ? 2 : 0)
+#else
+# define FILESYSTEM_PREFIX_LEN(Filename) 0
+#endif
+
+/* Define to the type of elements in the array set by `getgroups'. Usually
+ this is either `int' or `gid_t'. */
+#define GETGROUPS_T gid_t
+
+/* Define to 1 if the `getloadavg' function needs to be run setuid or setgid.
+ */
+/* #undef GETLOADAVG_PRIVILEGED */
+
+/* Define if gettimeofday clobbers localtime's static buffer. */
+/* #undef GETTIMEOFDAY_CLOBBERS_LOCALTIME_BUFFER */
+
+/* The concatenation of the strings `GNU ', and PACKAGE. */
+#define GNU_PACKAGE "GNU coreutils"
+
+/* Define if your system defines TIOCGWINSZ in sys/ioctl.h. */
+/* #undef GWINSZ_IN_SYS_IOCTL */
+
+/* Define if your system defines TIOCGWINSZ in sys/pty.h. */
+/* #undef GWINSZ_IN_SYS_PTY */
+
+/* Define to 1 if you have the `acl' function. */
+/* #undef HAVE_ACL */
+
+/* Define to 1 if you have the `alarm' function. */
+#define HAVE_ALARM 1
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the `atexit' function. */
+#define HAVE_ATEXIT 1
+
+/* Define to 1 if you have the <bp-sym.h> header file. */
+/* #undef HAVE_BP_SYM_H */
+
+/* Define to 1 if you have the `btowc' function. */
+#define HAVE_BTOWC 1
+
+/* Define to 1 if your system has a working `chown' function. */
+#define HAVE_CHOWN 1
+
+/* Define to 1 if you have the `chroot' function. */
+#define HAVE_CHROOT 1
+
+/* Define to 1 if you have the `chsize' function. */
+/* #undef HAVE_CHSIZE */
+
+/* Define to 1 if you have the `clock_gettime' function. */
+#define HAVE_CLOCK_GETTIME 1
+
+/* Define to 1 if you have the `clock_settime' function. */
+#define HAVE_CLOCK_SETTIME 1
+
+/* FIXME */
+/* #undef HAVE_C_LINE */
+
+/* Define if the GNU dcgettext() function is already present or preinstalled.
+ */
+/* #undef HAVE_DCGETTEXT */
+
+/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_CLEARERR_UNLOCKED 1
+
+/* Define to 1 if you have the declaration of `dirfd', and to 0 if you don't.
+ */
+#define HAVE_DECL_DIRFD 1
+
+/* Define to 1 if you have the declaration of `euidaccess', and to 0 if you
+ don't. */
+#define HAVE_DECL_EUIDACCESS 0
+
+/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you
+ don't. */
+#define HAVE_DECL_FEOF_UNLOCKED 1
+
+/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_FERROR_UNLOCKED 1
+
+/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_FFLUSH_UNLOCKED 0
+
+/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_FGETS_UNLOCKED 0
+
+/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_FPUTC_UNLOCKED 0
+
+/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_FPUTS_UNLOCKED 0
+
+/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_FREAD_UNLOCKED 0
+
+/* Define to 1 if you have the declaration of `free', and to 0 if you don't.
+ */
+#define HAVE_DECL_FREE 1
+
+/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_FWRITE_UNLOCKED 0
+
+/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_GETCHAR_UNLOCKED 1
+
+/* Define to 1 if you have the declaration of `getcwd', and to 0 if you don't.
+ */
+#define HAVE_DECL_GETCWD 1
+
+/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
+ don't. */
+#define HAVE_DECL_GETC_UNLOCKED 1
+
+/* Define to 1 if you have the declaration of `getenv', and to 0 if you don't.
+ */
+#define HAVE_DECL_GETENV 1
+
+/* Define to 1 if you have the declaration of `geteuid', and to 0 if you
+ don't. */
+#define HAVE_DECL_GETEUID 1
+
+/* Define to 1 if you have the declaration of `getgrgid', and to 0 if you
+ don't. */
+#define HAVE_DECL_GETGRGID 1
+
+/* Define to 1 if you have the declaration of `getlogin', and to 0 if you
+ don't. */
+#define HAVE_DECL_GETLOGIN 1
+
+/* Define to 1 if you have the declaration of `getpwuid', and to 0 if you
+ don't. */
+#define HAVE_DECL_GETPWUID 1
+
+/* Define to 1 if you have the declaration of `getuid', and to 0 if you don't.
+ */
+#define HAVE_DECL_GETUID 1
+
+/* Define to 1 if you have the declaration of `getutent', and to 0 if you
+ don't. */
+#define HAVE_DECL_GETUTENT 0
+
+/* Define to 1 if you have the declaration of `lseek', and to 0 if you don't.
+ */
+#define HAVE_DECL_LSEEK 1
+
+/* Define to 1 if you have the declaration of `malloc', and to 0 if you don't.
+ */
+#define HAVE_DECL_MALLOC 1
+
+/* Define to 1 if you have the declaration of `memchr', and to 0 if you don't.
+ */
+#define HAVE_DECL_MEMCHR 1
+
+/* Define to 1 if you have the declaration of `memrchr', and to 0 if you
+ don't. */
+#define HAVE_DECL_MEMRCHR 0
+
+/* Define to 1 if you have the declaration of `nanosleep', and to 0 if you
+ don't. */
+#define HAVE_DECL_NANOSLEEP 1
+
+/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if
+ you don't. */
+#define HAVE_DECL_PUTCHAR_UNLOCKED 1
+
+/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you
+ don't. */
+#define HAVE_DECL_PUTC_UNLOCKED 1
+
+/* Define to 1 if you have the declaration of `realloc', and to 0 if you
+ don't. */
+#define HAVE_DECL_REALLOC 1
+
+/* Define to 1 if you have the declaration of `stpcpy', and to 0 if you don't.
+ */
+#define HAVE_DECL_STPCPY 1
+
+/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRERROR_R 1
+
+/* Define to 1 if you have the declaration of `strndup', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRNDUP 0
+
+/* Define to 1 if you have the declaration of `strnlen', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRNLEN 0
+
+/* Define to 1 if you have the declaration of `strsignal', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRSIGNAL 1
+
+/* Define to 1 if you have the declaration of `strstr', and to 0 if you don't.
+ */
+#define HAVE_DECL_STRSTR 1
+
+/* Define to 1 if you have the declaration of `strtoimax', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRTOIMAX 1
+
+/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
+ don't. */
+/* #undef HAVE_DECL_STRTOLL */
+
+/* Define to 1 if you have the declaration of `strtoul', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRTOUL 1
+
+/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRTOULL 1
+
+/* Define to 1 if you have the declaration of `strtoumax', and to 0 if you
+ don't. */
+#define HAVE_DECL_STRTOUMAX 1
+
+/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
+ don't. */
+#define HAVE_DECL_SYS_SIGLIST 1
+
+/* Define to 1 if you have the declaration of `ttyname', and to 0 if you
+ don't. */
+#define HAVE_DECL_TTYNAME 1
+
+/* Define to 1 if you have the declaration of wcwidth(), and to 0 otherwise.
+ */
+#define HAVE_DECL_WCWIDTH 1
+
+/* Define to 1 if you have the declaration of `_sys_siglist', and to 0 if you
+ don't. */
+#define HAVE_DECL__SYS_SIGLIST 0
+
+/* Define to 1 if you have the declaration of `__fpending', and to 0 if you
+ don't. */
+#define HAVE_DECL___FPENDING 0
+
+/* Define to 1 if you have the declaration of `__sys_siglist', and to 0 if you
+ don't. */
+#define HAVE_DECL___SYS_SIGLIST 0
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the `dirfd' function. */
+/* #undef HAVE_DIRFD */
+
+/* Define to 1 if you have the `dup2' function. */
+#define HAVE_DUP2 1
+
+/* Define to 1 if you have the <dustat.h> header file. */
+/* #undef HAVE_DUSTAT_H */
+
+/* Define to 1 if you have the `endgrent' function. */
+#define HAVE_ENDGRENT 1
+
+/* Define to 1 if you have the `endpwent' function. */
+#define HAVE_ENDPWENT 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the `euidaccess' function. */
+/* #undef HAVE_EUIDACCESS */
+
+/* Define to 1 if you have the `fchdir' function. */
+#define HAVE_FCHDIR 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `fdatasync' function. */
+/* #undef HAVE_FDATASYNC */
+
+/* Define to 1 if you have the `fesetround' function. */
+/* #undef HAVE_FESETROUND */
+
+/* Define to 1 if you have the <float.h> header file. */
+#define HAVE_FLOAT_H 1
+
+/* Define to 1 if you have the `floor' function. */
+#define HAVE_FLOOR 1
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#define HAVE_FSEEKO 1
+
+/* Define to 1 if you have the <fs_info.h> header file. */
+/* #undef HAVE_FS_INFO_H */
+
+/* Define to 1 if you have the `fs_stat_dev' function. */
+/* #undef HAVE_FS_STAT_DEV */
+
+/* Define to 1 if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define if struct statfs has the f_fstypename member. */
+#define HAVE_F_FSTYPENAME_IN_STATFS 1
+
+/* Define to 1 if you have the `getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define if getcwd (NULL, 0) allocates memory for result. */
+#define HAVE_GETCWD_NULL 1
+
+/* Define to 1 if you have the `getdelim' function. */
+/* #undef HAVE_GETDELIM */
+
+/* Define to 1 if your system has a working `getgroups' function. */
+#define HAVE_GETGROUPS 1
+
+/* Define to 1 if you have the `gethostbyaddr' function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* Define to 1 if you have the `gethostbyname' function. */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the `gethostid' function. */
+#define HAVE_GETHOSTID 1
+
+/* Define to 1 if you have the `gethostname' function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define to 1 if you have the `gethrtime' function. */
+/* #undef HAVE_GETHRTIME */
+
+/* Define to 1 if you have the `getloadavg' function. */
+#define HAVE_GETLOADAVG 1
+
+/* Define to 1 if you have the `getmntent' function. */
+/* #undef HAVE_GETMNTENT */
+
+/* Define to 1 if you have the `getmntinfo' function. */
+#define HAVE_GETMNTINFO 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define to 1 if you have the `getpass' function. */
+#define HAVE_GETPASS 1
+
+/* Define to 1 if you have the `getspnam' function. */
+/* #undef HAVE_GETSPNAM */
+
+/* Define to 1 if you have the `getsysinfo' function. */
+/* #undef HAVE_GETSYSINFO */
+
+/* Define if the GNU gettext() function is already present or preinstalled. */
+/* #undef HAVE_GETTEXT */
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `getusershell' function. */
+#define HAVE_GETUSERSHELL 1
+
+/* Define to 1 if you have the <grp.h> header file. */
+#define HAVE_GRP_H 1
+
+/* Define to 1 if you have the `hasmntopt' function. */
+/* #undef HAVE_HASMNTOPT */
+
+/* Define to 1 if you have the <hurd.h> header file. */
+/* #undef HAVE_HURD_H */
+
+/* Define if you have the iconv() function. */
+/* #undef HAVE_ICONV */
+
+/* Define to 1 if you have the `inet_ntoa' function. */
+#define HAVE_INET_NTOA 1
+
+/* Define to 1 if you have the `initgroups' function. */
+#define HAVE_INITGROUPS 1
+
+/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
+#define HAVE_INTMAX_T 1
+
+/* Define if <inttypes.h> exists and doesn't clash with <sys/types.h>. */
+#define HAVE_INTTYPES_H 1
+
+/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
+ declares uintmax_t. */
+#define HAVE_INTTYPES_H_WITH_UINTMAX 1
+
+/* Define to 1 if you have the `isascii' function. */
+#define HAVE_ISASCII 1
+
+/* Define to 1 if you have the `iswcntrl' function. */
+#define HAVE_ISWCNTRL 1
+
+/* Define to 1 if you have the `iswprint' function. */
+#define HAVE_ISWPRINT 1
+
+/* Define to 1 if you have the `iswspace' function. */
+#define HAVE_ISWSPACE 1
+
+/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
+#define HAVE_LANGINFO_CODESET 1
+
+/* Define to 1 if you have the `lchown' function. */
+#define HAVE_LCHOWN 1
+
+/* Define to 1 if you have the `dgc' library (-ldgc). */
+/* #undef HAVE_LIBDGC */
+
+/* Define to 1 if you have the `kstat' library (-lkstat). */
+/* #undef HAVE_LIBKSTAT */
+
+/* Define to 1 if you have the `ldgc' library (-lldgc). */
+/* #undef HAVE_LIBLDGC */
+
+/* Define to 1 if you have the `os' library (-los). */
+/* #undef HAVE_LIBOS */
+
+/* Define to 1 if you have the `ypsec' library (-lypsec). */
+/* #undef HAVE_LIBYPSEC */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the `listmntent' function. */
+/* #undef HAVE_LISTMNTENT */
+
+/* Define to 1 if you have the `localeconv' function. */
+#define HAVE_LOCALECONV 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define if you have the 'long double' type. */
+#define HAVE_LONG_DOUBLE 1
+
+/* Define to 1 if you support file names longer than 14 characters. */
+#define HAVE_LONG_FILE_NAMES 1
+
+/* Define if you have the 'long long' type. */
+#define HAVE_LONG_LONG 1
+
+/* Define to 1 if `lstat' has the bug that it succeeds when given the
+ zero-length file name argument. */
+/* #undef HAVE_LSTAT_EMPTY_STRING_BUG */
+
+/* Define to 1 if you have the <machine/hal_sysinfo.h> header file. */
+/* #undef HAVE_MACHINE_HAL_SYSINFO_H */
+
+/* Define to 1 if you have the <mach/mach.h> header file. */
+/* #undef HAVE_MACH_MACH_H */
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+ to 0 otherwise. */
+#define HAVE_MALLOC 1
+
+/* Define to 1 if you have the `mblen' function. */
+#define HAVE_MBLEN 1
+
+/* Define to 1 if you have the `mbrlen' function. */
+#define HAVE_MBRLEN 1
+
+/* Define to 1 if mbrtowc and mbstate_t are properly declared. */
+#define HAVE_MBRTOWC 1
+
+/* Define to 1 if you have the `mbsinit' function. */
+#define HAVE_MBSINIT 1
+
+/* Define to 1 if you have the `mbsrtowcs' function. */
+#define HAVE_MBSRTOWCS 1
+
+/* Define to 1 if <wchar.h> declares mbstate_t. */
+#define HAVE_MBSTATE_T 1
+
+/* Define to 1 if you have the `memchr' function. */
+#define HAVE_MEMCHR 1
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mempcpy' function. */
+/* #undef HAVE_MEMPCPY */
+
+/* Define to 1 if you have the `memrchr' function. */
+/* #undef HAVE_MEMRCHR */
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Define to 1 if you have the `mkfifo' function. */
+#define HAVE_MKFIFO 1
+
+/* Define to 1 if you have the `mkstemp' function. */
+#define HAVE_MKSTEMP 1
+
+/* Define to 1 if you have the <mntent.h> header file. */
+/* #undef HAVE_MNTENT_H */
+
+/* Define to 1 if you have the <mnttab.h> header file. */
+/* #undef HAVE_MNTTAB_H */
+
+/* Define to 1 if you have the `modf' function. */
+#define HAVE_MODF 1
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the `next_dev' function. */
+/* #undef HAVE_NEXT_DEV */
+
+/* Define to 1 if you have the <nfs/nfs_clnt.h> header file. */
+/* #undef HAVE_NFS_NFS_CLNT_H */
+
+/* Define to 1 if you have the <nfs/vfs.h> header file. */
+/* #undef HAVE_NFS_VFS_H */
+
+/* Define to 1 if you have the <nlist.h> header file. */
+/* #undef HAVE_NLIST_H */
+
+/* Define to 1 if libc includes obstacks. */
+/* #undef HAVE_OBSTACK */
+
+/* Define to 1 if you have the <OS.h> header file. */
+/* #undef HAVE_OS_H */
+
+/* Define to 1 if you have the `pathconf' function. */
+#define HAVE_PATHCONF 1
+
+/* Define to 1 if you have the <paths.h> header file. */
+#define HAVE_PATHS_H 1
+
+/* Define if your system has the /proc/uptime special file. */
+/* #undef HAVE_PROC_UPTIME */
+
+/* Define to 1 if you have the `pstat_getdynamic' function. */
+/* #undef HAVE_PSTAT_GETDYNAMIC */
+
+/* Define to 1 if you have the `pstat_getstatic' function. */
+/* #undef HAVE_PSTAT_GETSTATIC */
+
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#define HAVE_PTRDIFF_T 1
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define to 1 if you have the `raise' function. */
+#define HAVE_RAISE 1
+
+/* Define to 1 if you have the `readlink' function. */
+#define HAVE_READLINK 1
+
+/* Define to 1 if your system has a GNU libc compatible `realloc' function,
+ and to 0 otherwise. */
+#define HAVE_REALLOC 1
+
+/* Define to 1 if you have the `realpath' function. */
+#define HAVE_REALPATH 1
+
+/* Define to 1 if you have the `resolvepath' function. */
+/* #undef HAVE_RESOLVEPATH */
+
+/* Define to 1 if you have the `rint' function. */
+#define HAVE_RINT 1
+
+/* Define to 1 if you have the `rmdir' function. */
+#define HAVE_RMDIR 1
+
+/* Define to 1 if you have the `rpmatch' function. */
+/* #undef HAVE_RPMATCH */
+
+/* Define to 1 if you have run the test for working tzset. */
+#define HAVE_RUN_TZSET_TEST 1
+
+/* Define to 1 if you have the `sethostname' function. */
+#define HAVE_SETHOSTNAME 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `setregid' function. */
+#define HAVE_SETREGID 1
+
+/* Define to 1 if you have the `setreuid' function. */
+#define HAVE_SETREUID 1
+
+/* Define to 1 if you have the <shadow.h> header file. */
+/* #undef HAVE_SHADOW_H */
+
+/* Define to 1 if you have the `sig2str' function. */
+/* #undef HAVE_SIG2STR */
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the `sqrt' function. */
+/* #undef HAVE_SQRT */
+
+/* Define to 1 if you have the `statvfs' function. */
+#define HAVE_STATVFS 1
+
+/* Define to 1 if `stat' has the bug that it succeeds when given the
+ zero-length file name argument. */
+/* #undef HAVE_STAT_EMPTY_STRING_BUG */
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
+ uintmax_t. */
+#define HAVE_STDINT_H_WITH_UINTMAX 1
+
+/* Define to 1 if you have the <stdio_ext.h> header file. */
+/* #undef HAVE_STDIO_EXT_H */
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `stpcpy' function. */
+#define HAVE_STPCPY 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strcoll' function and it is properly defined.
+ */
+#define HAVE_STRCOLL 1
+
+/* Define to 1 if you have the `strcspn' function. */
+#define HAVE_STRCSPN 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strerror_r' function. */
+#define HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the `strftime' function. */
+#define HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the `strndup' function. */
+#define HAVE_STRNDUP 1
+
+/* Define to 1 if you have the `strpbrk' function. */
+#define HAVE_STRPBRK 1
+
+/* Define to 1 if you have the `strrchr' function. */
+#define HAVE_STRRCHR 1
+
+/* Define to 1 if you have the `strstr' function. */
+#define HAVE_STRSTR 1
+
+/* Define to 1 if you have the `strtoimax' function. */
+#define HAVE_STRTOIMAX 1
+
+/* Define to 1 if you have the `strtol' function. */
+#define HAVE_STRTOL 1
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* Define to 1 if you have the `strtoul' function. */
+#define HAVE_STRTOUL 1
+
+/* Define to 1 if you have the `strtoull' function. */
+#define HAVE_STRTOULL 1
+
+/* Define to 1 if you have the `strtoumax' function. */
+#define HAVE_STRTOUMAX 1
+
+/* Define if there is a member named d_type in the struct describing directory
+ headers. */
+#define HAVE_STRUCT_DIRENT_D_TYPE 1
+
+/* Define to 1 if `f_fstypename' is member of `struct fsstat'. */
+/* #undef HAVE_STRUCT_FSSTAT_F_FSTYPENAME */
+
+/* Define to 1 if `n_un.n_name' is member of `struct nlist'. */
+/* #undef HAVE_STRUCT_NLIST_N_UN_N_NAME */
+
+/* Define to 1 if `sp_pwdp' is member of `struct spwd'. */
+/* #undef HAVE_STRUCT_SPWD_SP_PWDP */
+
+/* Define to 1 if `f_basetype' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_BASETYPE */
+
+/* Define to 1 if `f_fsid.__val' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_FSID___VAL */
+
+/* Define to 1 if `f_fstypename' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_FSTYPENAME */
+
+/* Define to 1 if `f_namelen' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_NAMELEN */
+
+/* Define to 1 if `f_namemax' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_NAMEMAX */
+
+/* Define to 1 if `f_type' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_TYPE */
+
+/* Define to 1 if `f_basetype' is member of `struct statvfs'. */
+/* #undef HAVE_STRUCT_STATVFS_F_BASETYPE */
+
+/* Define to 1 if `f_fsid.__val' is member of `struct statvfs'. */
+/* #undef HAVE_STRUCT_STATVFS_F_FSID___VAL */
+
+/* Define to 1 if `f_namelen' is member of `struct statvfs'. */
+/* #undef HAVE_STRUCT_STATVFS_F_NAMELEN */
+
+/* Define to 1 if `f_namemax' is member of `struct statvfs'. */
+#define HAVE_STRUCT_STATVFS_F_NAMEMAX 1
+
+/* Define to 1 if `f_type' is member of `struct statvfs'. */
+/* #undef HAVE_STRUCT_STATVFS_F_TYPE */
+
+/* Define to 1 if `st_author' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_AUTHOR */
+
+/* Define to 1 if `st_blksize' is member of `struct stat'. */
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+
+/* Define to 1 if `st_blocks' is member of `struct stat'. */
+#define HAVE_STRUCT_STAT_ST_BLOCKS 1
+
+/* Define if struct timespec is declared in <time.h>. */
+#define HAVE_STRUCT_TIMESPEC 1
+
+/* Define to 1 if `tm_zone' is member of `struct tm'. */
+#define HAVE_STRUCT_TM_TM_ZONE 1
+
+/* Define if struct utimbuf is declared -- usually in <utime.h>. Some systems
+ have utime.h but don't declare the struct anywhere. */
+#define HAVE_STRUCT_UTIMBUF 1
+
+/* Define to 1 if `ut_exit' is member of `struct utmpx'. */
+/* #undef HAVE_STRUCT_UTMPX_UT_EXIT */
+
+/* Define to 1 if `ut_exit.e_exit' is member of `struct utmpx'. */
+/* #undef HAVE_STRUCT_UTMPX_UT_EXIT_E_EXIT */
+
+/* Define to 1 if `ut_exit.e_termination' is member of `struct utmpx'. */
+/* #undef HAVE_STRUCT_UTMPX_UT_EXIT_E_TERMINATION */
+
+/* Define to 1 if `ut_exit.ut_exit' is member of `struct utmpx'. */
+/* #undef HAVE_STRUCT_UTMPX_UT_EXIT_UT_EXIT */
+
+/* Define to 1 if `ut_exit.ut_termination' is member of `struct utmpx'. */
+/* #undef HAVE_STRUCT_UTMPX_UT_EXIT_UT_TERMINATION */
+
+/* Define to 1 if `ut_id' is member of `struct utmpx'. */
+/* #undef HAVE_STRUCT_UTMPX_UT_ID */
+
+/* Define to 1 if `ut_name' is member of `struct utmpx'. */
+/* #undef HAVE_STRUCT_UTMPX_UT_NAME */
+
+/* Define to 1 if `ut_pid' is member of `struct utmpx'. */
+/* #undef HAVE_STRUCT_UTMPX_UT_PID */
+
+/* Define to 1 if `ut_type' is member of `struct utmpx'. */
+/* #undef HAVE_STRUCT_UTMPX_UT_TYPE */
+
+/* Define to 1 if `ut_user' is member of `struct utmpx'. */
+/* #undef HAVE_STRUCT_UTMPX_UT_USER */
+
+/* Define to 1 if `ut_exit' is member of `struct utmp'. */
+/* #undef HAVE_STRUCT_UTMP_UT_EXIT */
+
+/* Define to 1 if `ut_exit.e_exit' is member of `struct utmp'. */
+/* #undef HAVE_STRUCT_UTMP_UT_EXIT_E_EXIT */
+
+/* Define to 1 if `ut_exit.e_termination' is member of `struct utmp'. */
+/* #undef HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION */
+
+/* Define to 1 if `ut_exit.ut_exit' is member of `struct utmp'. */
+/* #undef HAVE_STRUCT_UTMP_UT_EXIT_UT_EXIT */
+
+/* Define to 1 if `ut_exit.ut_termination' is member of `struct utmp'. */
+/* #undef HAVE_STRUCT_UTMP_UT_EXIT_UT_TERMINATION */
+
+/* Define to 1 if `ut_id' is member of `struct utmp'. */
+/* #undef HAVE_STRUCT_UTMP_UT_ID */
+
+/* Define to 1 if `ut_name' is member of `struct utmp'. */
+#define HAVE_STRUCT_UTMP_UT_NAME 1
+
+/* Define to 1 if `ut_pid' is member of `struct utmp'. */
+/* #undef HAVE_STRUCT_UTMP_UT_PID */
+
+/* Define to 1 if `ut_type' is member of `struct utmp'. */
+/* #undef HAVE_STRUCT_UTMP_UT_TYPE */
+
+/* Define to 1 if `ut_user' is member of `struct utmp'. */
+/* #undef HAVE_STRUCT_UTMP_UT_USER */
+
+/* Define to 1 if you have the `strverscmp' function. */
+/* #undef HAVE_STRVERSCMP */
+
+/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use
+ `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
+#define HAVE_ST_BLOCKS 1
+
+/* Define if struct stat has an st_dm_mode member. */
+/* #undef HAVE_ST_DM_MODE */
+
+/* Define to 1 if you have the `sysctl' function. */
+#define HAVE_SYSCTL 1
+
+/* Define to 1 if you have the `sysinfo' function. */
+/* #undef HAVE_SYSINFO */
+
+/* FIXME */
+#define HAVE_SYSLOG 1
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define to 1 if you have the `sysmp' function. */
+/* #undef HAVE_SYSMP */
+
+/* Define to 1 if you have the <sys/acl.h> header file. */
+#define HAVE_SYS_ACL_H 1
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/filsys.h> header file. */
+/* #undef HAVE_SYS_FILSYS_H */
+
+/* Define to 1 if you have the <sys/fstyp.h> header file. */
+/* #undef HAVE_SYS_FSTYP_H */
+
+/* Define to 1 if you have the <sys/fs/s5param.h> header file. */
+/* #undef HAVE_SYS_FS_S5PARAM_H */
+
+/* Define to 1 if you have the <sys/fs_types.h> header file. */
+/* #undef HAVE_SYS_FS_TYPES_H */
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/mntent.h> header file. */
+/* #undef HAVE_SYS_MNTENT_H */
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#define HAVE_SYS_MOUNT_H 1
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/pstat.h> header file. */
+/* #undef HAVE_SYS_PSTAT_H */
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/statfs.h> header file. */
+/* #undef HAVE_SYS_STATFS_H */
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+#define HAVE_SYS_STATVFS_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+#define HAVE_SYS_SYSCTL_H 1
+
+/* Define to 1 if you have the <sys/sysinfo.h> header file. */
+/* #undef HAVE_SYS_SYSINFO_H */
+
+/* Define to 1 if you have the <sys/sysmacros.h> header file. */
+/* #undef HAVE_SYS_SYSMACROS_H */
+
+/* Define to 1 if you have the <sys/sysmp.h> header file. */
+/* #undef HAVE_SYS_SYSMP_H */
+
+/* Define to 1 if you have the <sys/systemcfg.h> header file. */
+/* #undef HAVE_SYS_SYSTEMCFG_H */
+
+/* Define to 1 if you have the <sys/systeminfo.h> header file. */
+/* #undef HAVE_SYS_SYSTEMINFO_H */
+
+/* Define to 1 if you have the <sys/table.h> header file. */
+/* #undef HAVE_SYS_TABLE_H */
+
+/* Define to 1 if you have the <sys/timeb.h> header file. */
+#define HAVE_SYS_TIMEB_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/ucred.h> header file. */
+/* #undef HAVE_SYS_UCRED_H */
+
+/* Define to 1 if you have the <sys/vfs.h> header file. */
+/* #undef HAVE_SYS_VFS_H */
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the `table' function. */
+/* #undef HAVE_TABLE */
+
+/* Define to 1 if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define if struct tm has the tm_gmtoff member. */
+#define HAVE_TM_GMTOFF 1
+
+/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
+ `HAVE_STRUCT_TM_TM_ZONE' instead. */
+#define HAVE_TM_ZONE 1
+
+/* Define to 1 if you don't have `tm_zone' but do have the external array
+ `tzname'. */
+/* #undef HAVE_TZNAME */
+
+/* Define to 1 if you have the `tzset' function. */
+#define HAVE_TZSET 1
+
+/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */
+#define HAVE_UINTMAX_T 1
+
+/* Define to 1 if you have the `uname' function. */
+#define HAVE_UNAME 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the 'unsigned long long' type. */
+#define HAVE_UNSIGNED_LONG_LONG 1
+
+/* Define if utimes accepts a null argument */
+/* #undef HAVE_UTIMES_NULL */
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */
+#define HAVE_UTIME_NULL 1
+
+/* Define to 1 if you have the `utmpname' function. */
+/* #undef HAVE_UTMPNAME */
+
+/* Define to 1 if you have the `utmpxname' function. */
+/* #undef HAVE_UTMPXNAME */
+
+/* FIXME */
+/* #undef HAVE_UTMPX_H */
+
+/* Define to 1 if you have the <utmp.h> header file. */
+#define HAVE_UTMP_H 1
+
+/* FIXME */
+#define HAVE_UT_HOST 1
+
+/* Define to 1 if you have the <values.h> header file. */
+/* #undef HAVE_VALUES_H */
+
+/* Define to 1 if you have the `vasnprintf' function. */
+/* #undef HAVE_VASNPRINTF */
+
+/* Define to 1 if you have the `vasprintf' function. */
+#define HAVE_VASPRINTF 1
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define if you have the 'wchar_t' type. */
+#define HAVE_WCHAR_T 1
+
+/* Define to 1 if you have the `wcrtomb' function. */
+#define HAVE_WCRTOMB 1
+
+/* Define to 1 if you have the `wcslen' function. */
+#define HAVE_WCSLEN 1
+
+/* Define to 1 if you have the <wctype.h> header file. */
+#define HAVE_WCTYPE_H 1
+
+/* Define to 1 if you have the `wcwidth' function. */
+#define HAVE_WCWIDTH 1
+
+/* Define if you have the 'wint_t' type. */
+#define HAVE_WINT_T 1
+
+/* Define to 1 if you have the `wmempcpy' function. */
+/* #undef HAVE_WMEMPCPY */
+
+/* Define if readdir is found to work properly in some unusual cases. */
+#define HAVE_WORKING_READDIR 1
+
+/* Define if utimes works properly. */
+#define HAVE_WORKING_UTIMES 1
+
+/* Define to 1 if the system has the type `_Bool'. */
+#define HAVE__BOOL 1
+
+/* Define to 1 if you have the external variable, _system_configuration with a
+ member named physmem. */
+/* #undef HAVE__SYSTEM_CONFIGURATION */
+
+/* Define to 1 if you have the `__fpending' function. */
+/* #undef HAVE___FPENDING */
+
+/* Define to 1 if you have the `__secure_getenv' function. */
+/* #undef HAVE___SECURE_GETENV */
+
+/* The host operating system. */
+#define HOST_OPERATING_SYSTEM "FreeBSD"
+
+/* Define as const if the declaration of iconv() needs const. */
+/* #undef ICONV_CONST */
+
+#if FILESYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+#else
+# define ISSLASH(C) ((C) == '/')
+#endif
+
+/* Define if `link(2)' dereferences symbolic links. */
+#define LINK_FOLLOWS_SYMLINKS 1
+
+/* FIXME */
+#define LOCALTIME_CACHE 1
+
+/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
+ slash. */
+/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
+ */
+/* #undef MAJOR_IN_MKDEV */
+
+/* Define to 1 if `major', `minor', and `makedev' are declared in
+ <sysmacros.h>. */
+/* #undef MAJOR_IN_SYSMACROS */
+
+/* Define if there is no specific function for reading the list of mounted
+ filesystems. fread will be used to read /etc/mnttab. (SVR2) */
+/* #undef MOUNTED_FREAD */
+
+/* Define if (like SVR2) there is no specific function for reading the list of
+ mounted filesystems, and your system has these header files: <sys/fstyp.h>
+ and <sys/statfs.h>. (SVR3) */
+/* #undef MOUNTED_FREAD_FSTYP */
+
+/* Define if there are functions named next_dev and fs_stat_dev for reading
+ the list of mounted filesystems. (BeOS) */
+/* #undef MOUNTED_FS_STAT_DEV */
+
+/* Define if there is a function named getfsstat for reading the list of
+ mounted filesystems. (DEC Alpha running OSF/1) */
+/* #undef MOUNTED_GETFSSTAT */
+
+/* Define if there is a function named getmnt for reading the list of mounted
+ filesystems. (Ultrix) */
+/* #undef MOUNTED_GETMNT */
+
+/* Define if there is a function named getmntent for reading the list of
+ mounted filesystems, and that function takes a single argument. (4.3BSD,
+ SunOS, HP-UX, Dynix, Irix) */
+/* #undef MOUNTED_GETMNTENT1 */
+
+/* Define if there is a function named getmntent for reading the list of
+ mounted filesystems, and that function takes two arguments. (SVR4) */
+/* #undef MOUNTED_GETMNTENT2 */
+
+/* Define if there is a function named getmntinfo for reading the list of
+ mounted filesystems. (4.4BSD, Darwin) */
+#define MOUNTED_GETMNTINFO 1
+
+/* Define if there is a function named listmntent that can be used to list all
+ mounted filesystems. (UNICOS) */
+/* #undef MOUNTED_LISTMNTENT */
+
+/* Define if there is a function named mntctl that can be used to read the
+ list of mounted filesystems, and there is a system header file that
+ declares `struct vmount.' (AIX) */
+/* #undef MOUNTED_VMOUNT */
+
+/* Define to 1 if assertions should be disabled. */
+/* #undef NDEBUG */
+
+/* FIXME */
+/* #undef NICE_PRIORITY */
+
+/* Define to 1 if your `struct nlist' has an `n_un' member. Obsolete, depend
+ on `HAVE_STRUCT_NLIST_N_UN_N_NAME */
+/* #undef NLIST_NAME_UNION */
+
+/* Name of package */
+#define PACKAGE "coreutils"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "bug-coreutils@gnu.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "GNU coreutils"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "GNU coreutils 5.3.0-20040812-FreeBSD"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "coreutils"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "5.3.0-20040812-FreeBSD"
+
+/* the number of pending output bytes on stream `fp' */
+#define PENDING_OUTPUT_N_BYTES fp->_p - fp->_bf._base
+
+/* Define if <inttypes.h> exists and defines unusable PRI* macros. */
+/* #undef PRI_MACROS_BROKEN */
+
+/* Define to 1 if the C compiler supports function prototypes. */
+#define PROTOTYPES 1
+
+/* Define if rename does not work for source paths with a trailing slash, like
+ the one from SunOS 4.1.1_U1. */
+/* #undef RENAME_TRAILING_SLASH_BUG */
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* the value to which errno is set when rmdir fails on a nonempty directory */
+#define RMDIR_ERRNO_NOT_EMPTY 66
+
+/* Define to 1 if the `setvbuf' function takes the buffering type as its
+ second argument and the buffer pointer as the third, as on System V before
+ release 3. */
+/* #undef SETVBUF_REVERSED */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+/* #undef STACK_DIRECTION */
+
+/* Define if the block counts reported by statfs may be truncated to 2GB and
+ the correct values may be stored in the f_spare array. (SunOS 4.1.2, 4.1.3,
+ and 4.1.3_U1 are reported to have this problem. SunOS 4.1.1 seems not to be
+ affected.) */
+/* #undef STATFS_TRUNCATES_BLOCK_COUNTS */
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define if there is no specific function for reading filesystems usage
+ information and you have the <sys/filsys.h> header file. (SVR2) */
+/* #undef STAT_READ_FILSYS */
+
+/* Define if statfs takes 2 args and struct statfs has a field named f_bsize.
+ (4.3BSD, SunOS 4, HP-UX, AIX PS/2) */
+/* #undef STAT_STATFS2_BSIZE */
+
+/* Define if statfs takes 2 args and struct statfs has a field named f_fsize.
+ (4.4BSD, NetBSD) */
+/* #undef STAT_STATFS2_FSIZE */
+
+/* Define if statfs takes 2 args and the second argument has type struct
+ fs_data. (Ultrix) */
+/* #undef STAT_STATFS2_FS_DATA */
+
+/* Define if statfs takes 3 args. (DEC Alpha running OSF/1) */
+/* #undef STAT_STATFS3_OSF1 */
+
+/* Define if statfs takes 4 args. (SVR3, Dynix, Irix, Dolphin) */
+/* #undef STAT_STATFS4 */
+
+/* Define if there is a function named statvfs. (SVR4) */
+#define STAT_STATVFS 1
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if strerror_r returns char *. */
+/* #undef STRERROR_R_CHAR_P */
+
+/* Define to be the nanoseconds member of struct stat's st_mtim, if it exists.
+ */
+/* #undef ST_MTIM_NSEC */
+
+/* Define to 1 on System V Release 4. */
+/* #undef SVR4 */
+
+/* FIXME */
+/* #undef TERMIOS_NEEDS_XOPEN_SOURCE */
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define if tzset clobbers localtime's static buffer. */
+/* #undef TZSET_CLOBBERS_LOCALTIME_BUFFER */
+
+/* Define to 1 for Encore UMAX. */
+/* #undef UMAX */
+
+/* Define to 1 for Encore UMAX 4.3 that has <inq_status/cpustats.h> instead of
+ <sys/cpustats.h>. */
+/* #undef UMAX4_3 */
+
+/* Version number of package */
+#define VERSION "5.3.0-20040812-FreeBSD"
+
+/* Define if sys/ptem.h is required for struct winsize. */
+/* #undef WINSIZE_IN_PTEM */
+
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define to 1 if on AIX 3.
+ System headers sometimes define this.
+ We just want to avoid a redefinition error message. */
+#ifndef _ALL_SOURCE
+/* # undef _ALL_SOURCE */
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+/* #undef _LARGEFILE_SOURCE */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Enable extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+
+/* Define like PROTOTYPES; this can be used by system headers. */
+#define __PROTOTYPES 1
+
+/* Define to rpl_chown if the replacement function should be used. */
+/* #undef chown */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to a replacement function name for fnmatch(). */
+/* #undef fnmatch */
+
+/* Define to rpl_free if the replacement function should be used. */
+/* #undef free */
+
+/* Define to rpl_getcwd if the wrapper function should be used. */
+/* #undef getcwd */
+
+/* Define as rpl_getgroups if getgroups doesn't work right. */
+/* #undef getgroups */
+
+/* Define to a replacement function name for getline(). */
+/* #undef getline */
+
+/* Define to rpl_gettimeofday if the replacement function should be used. */
+/* #undef gettimeofday */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
+/* Define to rpl_gmtime if the replacement function should be used. */
+/* #undef gmtime */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `unsigned long int' if <sys/types.h> does not define. */
+/* #undef ino_t */
+
+/* Define to long or long long if <stdint.h> and <inttypes.h> don't define. */
+/* #undef intmax_t */
+
+/* Define to rpl_localtime if the replacement function should be used. */
+/* #undef localtime */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#define major_t unsigned int
+
+/* Define to rpl_malloc if the replacement function should be used. */
+/* #undef malloc */
+
+/* Define to a type if <wchar.h> does not define. */
+/* #undef mbstate_t */
+
+/* Define to rpl_memcmp if the replacement function should be used. */
+/* #undef memcmp */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#define minor_t unsigned int
+
+/* Define to rpl_mkdir if the replacement function should be used. */
+/* #undef mkdir */
+
+/* Define to rpl_mkstemp if the replacement function should be used. */
+/* #undef mkstemp */
+
+/* Define to rpl_mktime if the replacement function should be used. */
+/* #undef mktime */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef mode_t */
+
+/* Define to the name of the strftime replacement function. */
+#define my_strftime nstrftime
+
+/* Define to rpl_nanosleep if the replacement function should be used. */
+/* #undef nanosleep */
+
+/* Define to `long' if <sys/types.h> does not define. */
+/* #undef off_t */
+
+/* Define to `int' if <sys/types.h> does not define. */
+/* #undef pid_t */
+
+/* Define to rpl_putenv if the replacement function should be used. */
+/* #undef putenv */
+
+/* Define to rpl_realloc if the replacement function should be used. */
+/* #undef realloc */
+
+/* Define to rpl_rename if the replacement function should be used. */
+/* #undef rename */
+
+/* Define to equivalent of C99 restrict keyword, or to nothing if this is not
+ supported. Do not define if restrict is supported directly. */
+#define restrict __restrict
+
+/* Define to empty if the C compiler doesn't support this keyword. */
+/* #undef signed */
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define as a signed type of the same size as size_t. */
+/* #undef ssize_t */
+
+/* Define to rpl_strnlen if the replacement function should be used. */
+#define strnlen rpl_strnlen
+
+/* Define to rpl_strtod if the replacement function should be used. */
+/* #undef strtod */
+
+/* Define to rpl_tzset if the wrapper function should be used. */
+/* #undef tzset */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
+
+/* Define to unsigned long or unsigned long long if <stdint.h> and
+ <inttypes.h> don't define. */
+/* #undef uintmax_t */
+
+/* Define to `size_t' if <sys/types.h> does not define. */
+/* #undef uintptr_t */
+
+/* Define to rpl_utime if the replacement function should be used. */
+/* #undef utime */
+
+/* Define to empty if the keyword `volatile' does not work. Warning: valid
+ code using `volatile' can become incorrect without. Disable with care. */
+/* #undef volatile */
diff --git a/gnu/usr.bin/sort/localedir.h b/gnu/usr.bin/sort/localedir.h
new file mode 100644
index 0000000..f119a5f
--- /dev/null
+++ b/gnu/usr.bin/sort/localedir.h
@@ -0,0 +1,2 @@
+/* $FreeBSD$ */
+#define LOCALEDIR ""
diff --git a/gnu/usr.bin/sort/unlocked-io.h b/gnu/usr.bin/sort/unlocked-io.h
new file mode 100644
index 0000000..3c7a476
--- /dev/null
+++ b/gnu/usr.bin/sort/unlocked-io.h
@@ -0,0 +1,2 @@
+/* $FreeBSD$ */
+/* Dummy file for trimmed down sort */
diff --git a/gnu/usr.bin/texinfo/info/Makefile.depend b/gnu/usr.bin/texinfo/info/Makefile.depend
new file mode 100644
index 0000000..a9061f1
--- /dev/null
+++ b/gnu/usr.bin/texinfo/info/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/texinfo/libtxi \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/texinfo/infokey/Makefile.depend b/gnu/usr.bin/texinfo/infokey/Makefile.depend
new file mode 100644
index 0000000..cdde7ce
--- /dev/null
+++ b/gnu/usr.bin/texinfo/infokey/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/texinfo/libtxi \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/texinfo/install-info/Makefile.depend b/gnu/usr.bin/texinfo/install-info/Makefile.depend
new file mode 100644
index 0000000..cdde7ce
--- /dev/null
+++ b/gnu/usr.bin/texinfo/install-info/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/texinfo/libtxi \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/texinfo/libtxi/Makefile.depend b/gnu/usr.bin/texinfo/libtxi/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/gnu/usr.bin/texinfo/libtxi/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/texinfo/makeinfo/Makefile.depend b/gnu/usr.bin/texinfo/makeinfo/Makefile.depend
new file mode 100644
index 0000000..cdde7ce
--- /dev/null
+++ b/gnu/usr.bin/texinfo/makeinfo/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/texinfo/libtxi \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/gnu/usr.bin/texinfo/texindex/Makefile.depend b/gnu/usr.bin/texinfo/texindex/Makefile.depend
new file mode 100644
index 0000000..cdde7ce
--- /dev/null
+++ b/gnu/usr.bin/texinfo/texindex/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/usr.bin/texinfo/libtxi \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/include/Makefile b/include/Makefile
index 161dcf0..49e1cfc 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -120,8 +120,38 @@ _MARCHS= ${MACHINE_CPUARCH}
_MARCHS+= x86
.endif
+.if ${MK_STAGING} != "no"
+# tell bsd.incs.mk that we have it covered
+stage_includes:
+.endif
+
.include <bsd.prog.mk>
+.if ${MK_STAGING} != "no" && !defined(_SKIP_BUILD)
+.if make(all)
+DESTDIR= ${STAGE_OBJTOP}
+# we want to keep this separate from the folk who
+# do staging "normally"
+INCLUDEDIR= /include
+
+all: stage_includes
+installincludes: buildincludes
+buildincludes: stage_prep
+
+stage_prep:
+ @mkdir -p ${DESTDIR}${INCLUDEDIR}
+ @touch $@
+
+stage_includes: .dirdep installincludes
+ @find ${DESTDIR}${INCLUDEDIR} -type d | while read d; do \
+ rm -f $$d/.dirdep; \
+ { ln .dirdep $$d/.dirdep 2> /dev/null || \
+ cp -p .dirdep $$d/.dirdep; }; \
+ done
+ @touch $@
+.endif
+.endif
+
installincludes: ${SHARED}
${SHARED}: compat
@@ -134,11 +164,11 @@ compat:
.endfor
mtree -deU ${MTREE_FOLLOWS_SYMLINKS} \
-f ${.CURDIR}/../etc/mtree/BSD.include.dist \
- -p ${DESTDIR}${INCLUDEDIR}
+ -p ${DESTDIR}${INCLUDEDIR} > /dev/null
.if ${MK_BIND_LIBS} != "no"
mtree -deU ${MTREE_FOLLOWS_SYMLINKS} \
-f ${.CURDIR}/../etc/mtree/BIND.include.dist \
- -p ${DESTDIR}${INCLUDEDIR}
+ -p ${DESTDIR}${INCLUDEDIR} > /dev/null
.endif
copies:
diff --git a/include/Makefile.depend b/include/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/include/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/include/arpa/Makefile b/include/arpa/Makefile
index a480b31..94c84e3 100644
--- a/include/arpa/Makefile
+++ b/include/arpa/Makefile
@@ -1,6 +1,5 @@
# $FreeBSD$
-NO_OBJ=
INCS= ftp.h inet.h nameser.h nameser_compat.h telnet.h tftp.h
INCSDIR=${INCLUDEDIR}/arpa
diff --git a/include/arpa/Makefile.depend b/include/arpa/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/include/arpa/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/include/gssapi/Makefile b/include/gssapi/Makefile
index 8fb643f..b8b8dde 100644
--- a/include/gssapi/Makefile
+++ b/include/gssapi/Makefile
@@ -1,6 +1,5 @@
# $FreeBSD$
-NO_OBJ=
INCS= gssapi.h
INCSDIR= ${INCLUDEDIR}/gssapi
diff --git a/include/gssapi/Makefile.depend b/include/gssapi/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/include/gssapi/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/include/protocols/Makefile b/include/protocols/Makefile
index ddd8f21..a41f354 100644
--- a/include/protocols/Makefile
+++ b/include/protocols/Makefile
@@ -1,6 +1,5 @@
# $FreeBSD$
-NO_OBJ=
INCS= dumprestore.h routed.h rwhod.h talkd.h timed.h
INCSDIR=${INCLUDEDIR}/protocols
diff --git a/include/protocols/Makefile.depend b/include/protocols/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/include/protocols/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/include/rpc/Makefile.depend b/include/rpc/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/include/rpc/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/include/rpcsvc/Makefile.depend b/include/rpcsvc/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/include/rpcsvc/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/include/xlocale/Makefile b/include/xlocale/Makefile
index e45ddca..ed494f3 100644
--- a/include/xlocale/Makefile
+++ b/include/xlocale/Makefile
@@ -1,6 +1,5 @@
# $FreeBSD$
-NO_OBJ=
INCS= _ctype.h _inttypes.h _langinfo.h _locale.h _monetary.h _stdio.h\
_stdlib.h _string.h _time.h _wchar.h
INCSDIR=${INCLUDEDIR}/xlocale
diff --git a/include/xlocale/Makefile.depend b/include/xlocale/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/include/xlocale/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/lib/libasn1/Makefile.depend b/kerberos5/lib/libasn1/Makefile.depend
new file mode 100644
index 0000000..92a4197
--- /dev/null
+++ b/kerberos5/lib/libasn1/Makefile.depend
@@ -0,0 +1,189 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libcom_err \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+asn1_cms_asn1.So: asn1_cms_asn1.c
+asn1_cms_asn1.So: asn1_err.h
+asn1_cms_asn1.So: cms_asn1-priv.h
+asn1_cms_asn1.So: cms_asn1.h
+asn1_cms_asn1.So: rfc2459_asn1.h
+asn1_cms_asn1.o: asn1_cms_asn1.c
+asn1_cms_asn1.o: asn1_err.h
+asn1_cms_asn1.o: cms_asn1-priv.h
+asn1_cms_asn1.o: cms_asn1.h
+asn1_cms_asn1.o: rfc2459_asn1.h
+asn1_cms_asn1.po: asn1_cms_asn1.c
+asn1_cms_asn1.po: asn1_err.h
+asn1_cms_asn1.po: cms_asn1-priv.h
+asn1_cms_asn1.po: cms_asn1.h
+asn1_cms_asn1.po: rfc2459_asn1.h
+asn1_digest_asn1.So: asn1_digest_asn1.c
+asn1_digest_asn1.So: asn1_err.h
+asn1_digest_asn1.So: digest_asn1-priv.h
+asn1_digest_asn1.So: digest_asn1.h
+asn1_digest_asn1.So: krb5_asn1.h
+asn1_digest_asn1.o: asn1_digest_asn1.c
+asn1_digest_asn1.o: asn1_err.h
+asn1_digest_asn1.o: digest_asn1-priv.h
+asn1_digest_asn1.o: digest_asn1.h
+asn1_digest_asn1.o: krb5_asn1.h
+asn1_digest_asn1.po: asn1_digest_asn1.c
+asn1_digest_asn1.po: asn1_err.h
+asn1_digest_asn1.po: digest_asn1-priv.h
+asn1_digest_asn1.po: digest_asn1.h
+asn1_digest_asn1.po: krb5_asn1.h
+asn1_err.So: asn1_err.c
+asn1_err.So: asn1_err.h
+asn1_err.o: asn1_err.c
+asn1_err.o: asn1_err.h
+asn1_err.po: asn1_err.c
+asn1_err.po: asn1_err.h
+asn1_krb5_asn1.So: asn1_err.h
+asn1_krb5_asn1.So: asn1_krb5_asn1.c
+asn1_krb5_asn1.So: krb5_asn1-priv.h
+asn1_krb5_asn1.So: krb5_asn1.h
+asn1_krb5_asn1.o: asn1_err.h
+asn1_krb5_asn1.o: asn1_krb5_asn1.c
+asn1_krb5_asn1.o: krb5_asn1-priv.h
+asn1_krb5_asn1.o: krb5_asn1.h
+asn1_krb5_asn1.po: asn1_err.h
+asn1_krb5_asn1.po: asn1_krb5_asn1.c
+asn1_krb5_asn1.po: krb5_asn1-priv.h
+asn1_krb5_asn1.po: krb5_asn1.h
+asn1_kx509_asn1.So: asn1_err.h
+asn1_kx509_asn1.So: asn1_kx509_asn1.c
+asn1_kx509_asn1.So: kx509_asn1-priv.h
+asn1_kx509_asn1.So: kx509_asn1.h
+asn1_kx509_asn1.o: asn1_err.h
+asn1_kx509_asn1.o: asn1_kx509_asn1.c
+asn1_kx509_asn1.o: kx509_asn1-priv.h
+asn1_kx509_asn1.o: kx509_asn1.h
+asn1_kx509_asn1.po: asn1_err.h
+asn1_kx509_asn1.po: asn1_kx509_asn1.c
+asn1_kx509_asn1.po: kx509_asn1-priv.h
+asn1_kx509_asn1.po: kx509_asn1.h
+asn1_pkcs12_asn1.So: asn1_err.h
+asn1_pkcs12_asn1.So: asn1_pkcs12_asn1.c
+asn1_pkcs12_asn1.So: cms_asn1.h
+asn1_pkcs12_asn1.So: pkcs12_asn1-priv.h
+asn1_pkcs12_asn1.So: pkcs12_asn1.h
+asn1_pkcs12_asn1.So: rfc2459_asn1.h
+asn1_pkcs12_asn1.o: asn1_err.h
+asn1_pkcs12_asn1.o: asn1_pkcs12_asn1.c
+asn1_pkcs12_asn1.o: cms_asn1.h
+asn1_pkcs12_asn1.o: pkcs12_asn1-priv.h
+asn1_pkcs12_asn1.o: pkcs12_asn1.h
+asn1_pkcs12_asn1.o: rfc2459_asn1.h
+asn1_pkcs12_asn1.po: asn1_err.h
+asn1_pkcs12_asn1.po: asn1_pkcs12_asn1.c
+asn1_pkcs12_asn1.po: cms_asn1.h
+asn1_pkcs12_asn1.po: pkcs12_asn1-priv.h
+asn1_pkcs12_asn1.po: pkcs12_asn1.h
+asn1_pkcs12_asn1.po: rfc2459_asn1.h
+asn1_pkcs8_asn1.So: asn1_err.h
+asn1_pkcs8_asn1.So: asn1_pkcs8_asn1.c
+asn1_pkcs8_asn1.So: pkcs8_asn1-priv.h
+asn1_pkcs8_asn1.So: pkcs8_asn1.h
+asn1_pkcs8_asn1.So: rfc2459_asn1.h
+asn1_pkcs8_asn1.o: asn1_err.h
+asn1_pkcs8_asn1.o: asn1_pkcs8_asn1.c
+asn1_pkcs8_asn1.o: pkcs8_asn1-priv.h
+asn1_pkcs8_asn1.o: pkcs8_asn1.h
+asn1_pkcs8_asn1.o: rfc2459_asn1.h
+asn1_pkcs8_asn1.po: asn1_err.h
+asn1_pkcs8_asn1.po: asn1_pkcs8_asn1.c
+asn1_pkcs8_asn1.po: pkcs8_asn1-priv.h
+asn1_pkcs8_asn1.po: pkcs8_asn1.h
+asn1_pkcs8_asn1.po: rfc2459_asn1.h
+asn1_pkcs9_asn1.So: asn1_err.h
+asn1_pkcs9_asn1.So: asn1_pkcs9_asn1.c
+asn1_pkcs9_asn1.So: pkcs9_asn1-priv.h
+asn1_pkcs9_asn1.So: pkcs9_asn1.h
+asn1_pkcs9_asn1.o: asn1_err.h
+asn1_pkcs9_asn1.o: asn1_pkcs9_asn1.c
+asn1_pkcs9_asn1.o: pkcs9_asn1-priv.h
+asn1_pkcs9_asn1.o: pkcs9_asn1.h
+asn1_pkcs9_asn1.po: asn1_err.h
+asn1_pkcs9_asn1.po: asn1_pkcs9_asn1.c
+asn1_pkcs9_asn1.po: pkcs9_asn1-priv.h
+asn1_pkcs9_asn1.po: pkcs9_asn1.h
+asn1_pkinit_asn1.So: asn1_err.h
+asn1_pkinit_asn1.So: asn1_pkinit_asn1.c
+asn1_pkinit_asn1.So: cms_asn1.h
+asn1_pkinit_asn1.So: krb5_asn1.h
+asn1_pkinit_asn1.So: pkinit_asn1-priv.h
+asn1_pkinit_asn1.So: pkinit_asn1.h
+asn1_pkinit_asn1.So: rfc2459_asn1.h
+asn1_pkinit_asn1.o: asn1_err.h
+asn1_pkinit_asn1.o: asn1_pkinit_asn1.c
+asn1_pkinit_asn1.o: cms_asn1.h
+asn1_pkinit_asn1.o: krb5_asn1.h
+asn1_pkinit_asn1.o: pkinit_asn1-priv.h
+asn1_pkinit_asn1.o: pkinit_asn1.h
+asn1_pkinit_asn1.o: rfc2459_asn1.h
+asn1_pkinit_asn1.po: asn1_err.h
+asn1_pkinit_asn1.po: asn1_pkinit_asn1.c
+asn1_pkinit_asn1.po: cms_asn1.h
+asn1_pkinit_asn1.po: krb5_asn1.h
+asn1_pkinit_asn1.po: pkinit_asn1-priv.h
+asn1_pkinit_asn1.po: pkinit_asn1.h
+asn1_pkinit_asn1.po: rfc2459_asn1.h
+asn1_rfc2459_asn1.So: asn1_err.h
+asn1_rfc2459_asn1.So: asn1_rfc2459_asn1.c
+asn1_rfc2459_asn1.So: rfc2459_asn1-priv.h
+asn1_rfc2459_asn1.So: rfc2459_asn1.h
+asn1_rfc2459_asn1.o: asn1_err.h
+asn1_rfc2459_asn1.o: asn1_rfc2459_asn1.c
+asn1_rfc2459_asn1.o: rfc2459_asn1-priv.h
+asn1_rfc2459_asn1.o: rfc2459_asn1.h
+asn1_rfc2459_asn1.po: asn1_err.h
+asn1_rfc2459_asn1.po: asn1_rfc2459_asn1.c
+asn1_rfc2459_asn1.po: rfc2459_asn1-priv.h
+asn1_rfc2459_asn1.po: rfc2459_asn1.h
+der.So: asn1_err.h
+der.o: asn1_err.h
+der.po: asn1_err.h
+der_cmp.So: asn1_err.h
+der_cmp.o: asn1_err.h
+der_cmp.po: asn1_err.h
+der_copy.So: asn1_err.h
+der_copy.o: asn1_err.h
+der_copy.po: asn1_err.h
+der_format.So: asn1_err.h
+der_format.o: asn1_err.h
+der_format.po: asn1_err.h
+der_free.So: asn1_err.h
+der_free.o: asn1_err.h
+der_free.po: asn1_err.h
+der_get.So: asn1_err.h
+der_get.o: asn1_err.h
+der_get.po: asn1_err.h
+der_length.So: asn1_err.h
+der_length.o: asn1_err.h
+der_length.po: asn1_err.h
+der_put.So: asn1_err.h
+der_put.o: asn1_err.h
+der_put.po: asn1_err.h
+extra.So: asn1_err.h
+extra.o: asn1_err.h
+extra.po: asn1_err.h
+template.So: asn1_err.h
+template.o: asn1_err.h
+template.po: asn1_err.h
+timegm.So: asn1_err.h
+timegm.o: asn1_err.h
+timegm.po: asn1_err.h
+.endif
diff --git a/kerberos5/lib/libgssapi_krb5/Makefile.depend b/kerberos5/lib/libgssapi_krb5/Makefile.depend
new file mode 100644
index 0000000..09b8d99
--- /dev/null
+++ b/kerberos5/lib/libgssapi_krb5/Makefile.depend
@@ -0,0 +1,181 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ lib/libcom_err \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+8003.So: gkrb5_err.h
+8003.o: gkrb5_err.h
+8003.po: gkrb5_err.h
+accept_sec_context.So: gkrb5_err.h
+accept_sec_context.o: gkrb5_err.h
+accept_sec_context.po: gkrb5_err.h
+acquire_cred.So: gkrb5_err.h
+acquire_cred.o: gkrb5_err.h
+acquire_cred.po: gkrb5_err.h
+add_cred.So: gkrb5_err.h
+add_cred.o: gkrb5_err.h
+add_cred.po: gkrb5_err.h
+address_to_krb5addr.So: gkrb5_err.h
+address_to_krb5addr.o: gkrb5_err.h
+address_to_krb5addr.po: gkrb5_err.h
+aeap.So: gkrb5_err.h
+aeap.o: gkrb5_err.h
+aeap.po: gkrb5_err.h
+arcfour.So: gkrb5_err.h
+arcfour.o: gkrb5_err.h
+arcfour.po: gkrb5_err.h
+authorize_localname.So: gkrb5_err.h
+authorize_localname.o: gkrb5_err.h
+authorize_localname.po: gkrb5_err.h
+canonicalize_name.So: gkrb5_err.h
+canonicalize_name.o: gkrb5_err.h
+canonicalize_name.po: gkrb5_err.h
+ccache_name.So: gkrb5_err.h
+ccache_name.o: gkrb5_err.h
+ccache_name.po: gkrb5_err.h
+cfx.So: gkrb5_err.h
+cfx.o: gkrb5_err.h
+cfx.po: gkrb5_err.h
+compare_name.So: gkrb5_err.h
+compare_name.o: gkrb5_err.h
+compare_name.po: gkrb5_err.h
+compat.So: gkrb5_err.h
+compat.o: gkrb5_err.h
+compat.po: gkrb5_err.h
+context_time.So: gkrb5_err.h
+context_time.o: gkrb5_err.h
+context_time.po: gkrb5_err.h
+copy_ccache.So: gkrb5_err.h
+copy_ccache.o: gkrb5_err.h
+copy_ccache.po: gkrb5_err.h
+creds.So: gkrb5_err.h
+creds.o: gkrb5_err.h
+creds.po: gkrb5_err.h
+decapsulate.So: gkrb5_err.h
+decapsulate.o: gkrb5_err.h
+decapsulate.po: gkrb5_err.h
+delete_sec_context.So: gkrb5_err.h
+delete_sec_context.o: gkrb5_err.h
+delete_sec_context.po: gkrb5_err.h
+display_name.So: gkrb5_err.h
+display_name.o: gkrb5_err.h
+display_name.po: gkrb5_err.h
+display_status.So: gkrb5_err.h
+display_status.o: gkrb5_err.h
+display_status.po: gkrb5_err.h
+duplicate_name.So: gkrb5_err.h
+duplicate_name.o: gkrb5_err.h
+duplicate_name.po: gkrb5_err.h
+encapsulate.So: gkrb5_err.h
+encapsulate.o: gkrb5_err.h
+encapsulate.po: gkrb5_err.h
+export_name.So: gkrb5_err.h
+export_name.o: gkrb5_err.h
+export_name.po: gkrb5_err.h
+export_sec_context.So: gkrb5_err.h
+export_sec_context.o: gkrb5_err.h
+export_sec_context.po: gkrb5_err.h
+external.So: gkrb5_err.h
+external.o: gkrb5_err.h
+external.po: gkrb5_err.h
+get_mic.So: gkrb5_err.h
+get_mic.o: gkrb5_err.h
+get_mic.po: gkrb5_err.h
+gkrb5_err.So: gkrb5_err.c
+gkrb5_err.So: gkrb5_err.h
+gkrb5_err.o: gkrb5_err.c
+gkrb5_err.o: gkrb5_err.h
+gkrb5_err.po: gkrb5_err.c
+gkrb5_err.po: gkrb5_err.h
+import_name.So: gkrb5_err.h
+import_name.o: gkrb5_err.h
+import_name.po: gkrb5_err.h
+import_sec_context.So: gkrb5_err.h
+import_sec_context.o: gkrb5_err.h
+import_sec_context.po: gkrb5_err.h
+indicate_mechs.So: gkrb5_err.h
+indicate_mechs.o: gkrb5_err.h
+indicate_mechs.po: gkrb5_err.h
+init.So: gkrb5_err.h
+init.o: gkrb5_err.h
+init.po: gkrb5_err.h
+init_sec_context.So: gkrb5_err.h
+init_sec_context.o: gkrb5_err.h
+init_sec_context.po: gkrb5_err.h
+inquire_context.So: gkrb5_err.h
+inquire_context.o: gkrb5_err.h
+inquire_context.po: gkrb5_err.h
+inquire_cred.So: gkrb5_err.h
+inquire_cred.o: gkrb5_err.h
+inquire_cred.po: gkrb5_err.h
+inquire_cred_by_mech.So: gkrb5_err.h
+inquire_cred_by_mech.o: gkrb5_err.h
+inquire_cred_by_mech.po: gkrb5_err.h
+inquire_cred_by_oid.So: gkrb5_err.h
+inquire_cred_by_oid.o: gkrb5_err.h
+inquire_cred_by_oid.po: gkrb5_err.h
+inquire_mechs_for_name.So: gkrb5_err.h
+inquire_mechs_for_name.o: gkrb5_err.h
+inquire_mechs_for_name.po: gkrb5_err.h
+inquire_names_for_mech.So: gkrb5_err.h
+inquire_names_for_mech.o: gkrb5_err.h
+inquire_names_for_mech.po: gkrb5_err.h
+inquire_sec_context_by_oid.So: gkrb5_err.h
+inquire_sec_context_by_oid.o: gkrb5_err.h
+inquire_sec_context_by_oid.po: gkrb5_err.h
+pname_to_uid.So: gkrb5_err.h
+pname_to_uid.o: gkrb5_err.h
+pname_to_uid.po: gkrb5_err.h
+prf.So: gkrb5_err.h
+prf.o: gkrb5_err.h
+prf.po: gkrb5_err.h
+process_context_token.So: gkrb5_err.h
+process_context_token.o: gkrb5_err.h
+process_context_token.po: gkrb5_err.h
+release_buffer.So: gkrb5_err.h
+release_buffer.o: gkrb5_err.h
+release_buffer.po: gkrb5_err.h
+release_cred.So: gkrb5_err.h
+release_cred.o: gkrb5_err.h
+release_cred.po: gkrb5_err.h
+release_name.So: gkrb5_err.h
+release_name.o: gkrb5_err.h
+release_name.po: gkrb5_err.h
+sequence.So: gkrb5_err.h
+sequence.o: gkrb5_err.h
+sequence.po: gkrb5_err.h
+set_cred_option.So: gkrb5_err.h
+set_cred_option.o: gkrb5_err.h
+set_cred_option.po: gkrb5_err.h
+set_sec_context_option.So: gkrb5_err.h
+set_sec_context_option.o: gkrb5_err.h
+set_sec_context_option.po: gkrb5_err.h
+store_cred.So: gkrb5_err.h
+store_cred.o: gkrb5_err.h
+store_cred.po: gkrb5_err.h
+ticket_flags.So: gkrb5_err.h
+ticket_flags.o: gkrb5_err.h
+ticket_flags.po: gkrb5_err.h
+unwrap.So: gkrb5_err.h
+unwrap.o: gkrb5_err.h
+unwrap.po: gkrb5_err.h
+verify_mic.So: gkrb5_err.h
+verify_mic.o: gkrb5_err.h
+verify_mic.po: gkrb5_err.h
+wrap.So: gkrb5_err.h
+wrap.o: gkrb5_err.h
+wrap.po: gkrb5_err.h
+.endif
diff --git a/kerberos5/lib/libgssapi_ntlm/Makefile.depend b/kerberos5/lib/libgssapi_ntlm/Makefile.depend
new file mode 100644
index 0000000..8939113
--- /dev/null
+++ b/kerberos5/lib/libgssapi_ntlm/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/lib/libgssapi_spnego/Makefile.depend b/kerberos5/lib/libgssapi_spnego/Makefile.depend
new file mode 100644
index 0000000..98e977d
--- /dev/null
+++ b/kerberos5/lib/libgssapi_spnego/Makefile.depend
@@ -0,0 +1,117 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+accept_sec_context.So: spnego_asn1.h
+accept_sec_context.o: spnego_asn1.h
+accept_sec_context.po: spnego_asn1.h
+asn1_ContextFlags.So: asn1_ContextFlags.c
+asn1_ContextFlags.So: spnego_asn1-priv.h
+asn1_ContextFlags.So: spnego_asn1.h
+asn1_ContextFlags.o: asn1_ContextFlags.c
+asn1_ContextFlags.o: spnego_asn1-priv.h
+asn1_ContextFlags.o: spnego_asn1.h
+asn1_ContextFlags.po: asn1_ContextFlags.c
+asn1_ContextFlags.po: spnego_asn1-priv.h
+asn1_ContextFlags.po: spnego_asn1.h
+asn1_MechType.So: asn1_MechType.c
+asn1_MechType.So: spnego_asn1-priv.h
+asn1_MechType.So: spnego_asn1.h
+asn1_MechType.o: asn1_MechType.c
+asn1_MechType.o: spnego_asn1-priv.h
+asn1_MechType.o: spnego_asn1.h
+asn1_MechType.po: asn1_MechType.c
+asn1_MechType.po: spnego_asn1-priv.h
+asn1_MechType.po: spnego_asn1.h
+asn1_MechTypeList.So: asn1_MechTypeList.c
+asn1_MechTypeList.So: spnego_asn1-priv.h
+asn1_MechTypeList.So: spnego_asn1.h
+asn1_MechTypeList.o: asn1_MechTypeList.c
+asn1_MechTypeList.o: spnego_asn1-priv.h
+asn1_MechTypeList.o: spnego_asn1.h
+asn1_MechTypeList.po: asn1_MechTypeList.c
+asn1_MechTypeList.po: spnego_asn1-priv.h
+asn1_MechTypeList.po: spnego_asn1.h
+asn1_NegHints.So: asn1_NegHints.c
+asn1_NegHints.So: spnego_asn1-priv.h
+asn1_NegHints.So: spnego_asn1.h
+asn1_NegHints.o: asn1_NegHints.c
+asn1_NegHints.o: spnego_asn1-priv.h
+asn1_NegHints.o: spnego_asn1.h
+asn1_NegHints.po: asn1_NegHints.c
+asn1_NegHints.po: spnego_asn1-priv.h
+asn1_NegHints.po: spnego_asn1.h
+asn1_NegTokenInit.So: asn1_NegTokenInit.c
+asn1_NegTokenInit.So: spnego_asn1-priv.h
+asn1_NegTokenInit.So: spnego_asn1.h
+asn1_NegTokenInit.o: asn1_NegTokenInit.c
+asn1_NegTokenInit.o: spnego_asn1-priv.h
+asn1_NegTokenInit.o: spnego_asn1.h
+asn1_NegTokenInit.po: asn1_NegTokenInit.c
+asn1_NegTokenInit.po: spnego_asn1-priv.h
+asn1_NegTokenInit.po: spnego_asn1.h
+asn1_NegTokenInitWin.So: asn1_NegTokenInitWin.c
+asn1_NegTokenInitWin.So: spnego_asn1-priv.h
+asn1_NegTokenInitWin.So: spnego_asn1.h
+asn1_NegTokenInitWin.o: asn1_NegTokenInitWin.c
+asn1_NegTokenInitWin.o: spnego_asn1-priv.h
+asn1_NegTokenInitWin.o: spnego_asn1.h
+asn1_NegTokenInitWin.po: asn1_NegTokenInitWin.c
+asn1_NegTokenInitWin.po: spnego_asn1-priv.h
+asn1_NegTokenInitWin.po: spnego_asn1.h
+asn1_NegTokenResp.So: asn1_NegTokenResp.c
+asn1_NegTokenResp.So: spnego_asn1-priv.h
+asn1_NegTokenResp.So: spnego_asn1.h
+asn1_NegTokenResp.o: asn1_NegTokenResp.c
+asn1_NegTokenResp.o: spnego_asn1-priv.h
+asn1_NegTokenResp.o: spnego_asn1.h
+asn1_NegTokenResp.po: asn1_NegTokenResp.c
+asn1_NegTokenResp.po: spnego_asn1-priv.h
+asn1_NegTokenResp.po: spnego_asn1.h
+asn1_NegotiationToken.So: asn1_NegotiationToken.c
+asn1_NegotiationToken.So: spnego_asn1-priv.h
+asn1_NegotiationToken.So: spnego_asn1.h
+asn1_NegotiationToken.o: asn1_NegotiationToken.c
+asn1_NegotiationToken.o: spnego_asn1-priv.h
+asn1_NegotiationToken.o: spnego_asn1.h
+asn1_NegotiationToken.po: asn1_NegotiationToken.c
+asn1_NegotiationToken.po: spnego_asn1-priv.h
+asn1_NegotiationToken.po: spnego_asn1.h
+asn1_NegotiationTokenWin.So: asn1_NegotiationTokenWin.c
+asn1_NegotiationTokenWin.So: spnego_asn1-priv.h
+asn1_NegotiationTokenWin.So: spnego_asn1.h
+asn1_NegotiationTokenWin.o: asn1_NegotiationTokenWin.c
+asn1_NegotiationTokenWin.o: spnego_asn1-priv.h
+asn1_NegotiationTokenWin.o: spnego_asn1.h
+asn1_NegotiationTokenWin.po: asn1_NegotiationTokenWin.c
+asn1_NegotiationTokenWin.po: spnego_asn1-priv.h
+asn1_NegotiationTokenWin.po: spnego_asn1.h
+compat.So: spnego_asn1.h
+compat.o: spnego_asn1.h
+compat.po: spnego_asn1.h
+context_stubs.So: spnego_asn1.h
+context_stubs.o: spnego_asn1.h
+context_stubs.po: spnego_asn1.h
+cred_stubs.So: spnego_asn1.h
+cred_stubs.o: spnego_asn1.h
+cred_stubs.po: spnego_asn1.h
+external.So: spnego_asn1.h
+external.o: spnego_asn1.h
+external.po: spnego_asn1.h
+init_sec_context.So: spnego_asn1.h
+init_sec_context.o: spnego_asn1.h
+init_sec_context.po: spnego_asn1.h
+.endif
diff --git a/kerberos5/lib/libhdb/Makefile.depend b/kerberos5/lib/libhdb/Makefile.depend
new file mode 100644
index 0000000..1748958
--- /dev/null
+++ b/kerberos5/lib/libhdb/Makefile.depend
@@ -0,0 +1,268 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ lib/libcom_err \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+asn1_Event.So: asn1_Event.c
+asn1_Event.So: hdb_asn1-priv.h
+asn1_Event.So: hdb_asn1.h
+asn1_Event.o: asn1_Event.c
+asn1_Event.o: hdb_asn1-priv.h
+asn1_Event.o: hdb_asn1.h
+asn1_Event.po: asn1_Event.c
+asn1_Event.po: hdb_asn1-priv.h
+asn1_Event.po: hdb_asn1.h
+asn1_GENERATION.So: asn1_GENERATION.c
+asn1_GENERATION.So: hdb_asn1-priv.h
+asn1_GENERATION.So: hdb_asn1.h
+asn1_GENERATION.o: asn1_GENERATION.c
+asn1_GENERATION.o: hdb_asn1-priv.h
+asn1_GENERATION.o: hdb_asn1.h
+asn1_GENERATION.po: asn1_GENERATION.c
+asn1_GENERATION.po: hdb_asn1-priv.h
+asn1_GENERATION.po: hdb_asn1.h
+asn1_HDBFlags.So: asn1_HDBFlags.c
+asn1_HDBFlags.So: hdb_asn1-priv.h
+asn1_HDBFlags.So: hdb_asn1.h
+asn1_HDBFlags.o: asn1_HDBFlags.c
+asn1_HDBFlags.o: hdb_asn1-priv.h
+asn1_HDBFlags.o: hdb_asn1.h
+asn1_HDBFlags.po: asn1_HDBFlags.c
+asn1_HDBFlags.po: hdb_asn1-priv.h
+asn1_HDBFlags.po: hdb_asn1.h
+asn1_HDB_Ext_Aliases.So: asn1_HDB_Ext_Aliases.c
+asn1_HDB_Ext_Aliases.So: hdb_asn1-priv.h
+asn1_HDB_Ext_Aliases.So: hdb_asn1.h
+asn1_HDB_Ext_Aliases.o: asn1_HDB_Ext_Aliases.c
+asn1_HDB_Ext_Aliases.o: hdb_asn1-priv.h
+asn1_HDB_Ext_Aliases.o: hdb_asn1.h
+asn1_HDB_Ext_Aliases.po: asn1_HDB_Ext_Aliases.c
+asn1_HDB_Ext_Aliases.po: hdb_asn1-priv.h
+asn1_HDB_Ext_Aliases.po: hdb_asn1.h
+asn1_HDB_Ext_Constrained_delegation_acl.So: asn1_HDB_Ext_Constrained_delegation_acl.c
+asn1_HDB_Ext_Constrained_delegation_acl.So: hdb_asn1-priv.h
+asn1_HDB_Ext_Constrained_delegation_acl.So: hdb_asn1.h
+asn1_HDB_Ext_Constrained_delegation_acl.o: asn1_HDB_Ext_Constrained_delegation_acl.c
+asn1_HDB_Ext_Constrained_delegation_acl.o: hdb_asn1-priv.h
+asn1_HDB_Ext_Constrained_delegation_acl.o: hdb_asn1.h
+asn1_HDB_Ext_Constrained_delegation_acl.po: asn1_HDB_Ext_Constrained_delegation_acl.c
+asn1_HDB_Ext_Constrained_delegation_acl.po: hdb_asn1-priv.h
+asn1_HDB_Ext_Constrained_delegation_acl.po: hdb_asn1.h
+asn1_HDB_Ext_Lan_Manager_OWF.So: asn1_HDB_Ext_Lan_Manager_OWF.c
+asn1_HDB_Ext_Lan_Manager_OWF.So: hdb_asn1-priv.h
+asn1_HDB_Ext_Lan_Manager_OWF.So: hdb_asn1.h
+asn1_HDB_Ext_Lan_Manager_OWF.o: asn1_HDB_Ext_Lan_Manager_OWF.c
+asn1_HDB_Ext_Lan_Manager_OWF.o: hdb_asn1-priv.h
+asn1_HDB_Ext_Lan_Manager_OWF.o: hdb_asn1.h
+asn1_HDB_Ext_Lan_Manager_OWF.po: asn1_HDB_Ext_Lan_Manager_OWF.c
+asn1_HDB_Ext_Lan_Manager_OWF.po: hdb_asn1-priv.h
+asn1_HDB_Ext_Lan_Manager_OWF.po: hdb_asn1.h
+asn1_HDB_Ext_PKINIT_acl.So: asn1_HDB_Ext_PKINIT_acl.c
+asn1_HDB_Ext_PKINIT_acl.So: hdb_asn1-priv.h
+asn1_HDB_Ext_PKINIT_acl.So: hdb_asn1.h
+asn1_HDB_Ext_PKINIT_acl.o: asn1_HDB_Ext_PKINIT_acl.c
+asn1_HDB_Ext_PKINIT_acl.o: hdb_asn1-priv.h
+asn1_HDB_Ext_PKINIT_acl.o: hdb_asn1.h
+asn1_HDB_Ext_PKINIT_acl.po: asn1_HDB_Ext_PKINIT_acl.c
+asn1_HDB_Ext_PKINIT_acl.po: hdb_asn1-priv.h
+asn1_HDB_Ext_PKINIT_acl.po: hdb_asn1.h
+asn1_HDB_Ext_PKINIT_cert.So: asn1_HDB_Ext_PKINIT_cert.c
+asn1_HDB_Ext_PKINIT_cert.So: hdb_asn1-priv.h
+asn1_HDB_Ext_PKINIT_cert.So: hdb_asn1.h
+asn1_HDB_Ext_PKINIT_cert.o: asn1_HDB_Ext_PKINIT_cert.c
+asn1_HDB_Ext_PKINIT_cert.o: hdb_asn1-priv.h
+asn1_HDB_Ext_PKINIT_cert.o: hdb_asn1.h
+asn1_HDB_Ext_PKINIT_cert.po: asn1_HDB_Ext_PKINIT_cert.c
+asn1_HDB_Ext_PKINIT_cert.po: hdb_asn1-priv.h
+asn1_HDB_Ext_PKINIT_cert.po: hdb_asn1.h
+asn1_HDB_Ext_PKINIT_hash.So: asn1_HDB_Ext_PKINIT_hash.c
+asn1_HDB_Ext_PKINIT_hash.So: hdb_asn1-priv.h
+asn1_HDB_Ext_PKINIT_hash.So: hdb_asn1.h
+asn1_HDB_Ext_PKINIT_hash.o: asn1_HDB_Ext_PKINIT_hash.c
+asn1_HDB_Ext_PKINIT_hash.o: hdb_asn1-priv.h
+asn1_HDB_Ext_PKINIT_hash.o: hdb_asn1.h
+asn1_HDB_Ext_PKINIT_hash.po: asn1_HDB_Ext_PKINIT_hash.c
+asn1_HDB_Ext_PKINIT_hash.po: hdb_asn1-priv.h
+asn1_HDB_Ext_PKINIT_hash.po: hdb_asn1.h
+asn1_HDB_Ext_Password.So: asn1_HDB_Ext_Password.c
+asn1_HDB_Ext_Password.So: hdb_asn1-priv.h
+asn1_HDB_Ext_Password.So: hdb_asn1.h
+asn1_HDB_Ext_Password.o: asn1_HDB_Ext_Password.c
+asn1_HDB_Ext_Password.o: hdb_asn1-priv.h
+asn1_HDB_Ext_Password.o: hdb_asn1.h
+asn1_HDB_Ext_Password.po: asn1_HDB_Ext_Password.c
+asn1_HDB_Ext_Password.po: hdb_asn1-priv.h
+asn1_HDB_Ext_Password.po: hdb_asn1.h
+asn1_HDB_extension.So: asn1_HDB_extension.c
+asn1_HDB_extension.So: hdb_asn1-priv.h
+asn1_HDB_extension.So: hdb_asn1.h
+asn1_HDB_extension.o: asn1_HDB_extension.c
+asn1_HDB_extension.o: hdb_asn1-priv.h
+asn1_HDB_extension.o: hdb_asn1.h
+asn1_HDB_extension.po: asn1_HDB_extension.c
+asn1_HDB_extension.po: hdb_asn1-priv.h
+asn1_HDB_extension.po: hdb_asn1.h
+asn1_HDB_extensions.So: asn1_HDB_extensions.c
+asn1_HDB_extensions.So: hdb_asn1-priv.h
+asn1_HDB_extensions.So: hdb_asn1.h
+asn1_HDB_extensions.o: asn1_HDB_extensions.c
+asn1_HDB_extensions.o: hdb_asn1-priv.h
+asn1_HDB_extensions.o: hdb_asn1.h
+asn1_HDB_extensions.po: asn1_HDB_extensions.c
+asn1_HDB_extensions.po: hdb_asn1-priv.h
+asn1_HDB_extensions.po: hdb_asn1.h
+asn1_Key.So: asn1_Key.c
+asn1_Key.So: hdb_asn1-priv.h
+asn1_Key.So: hdb_asn1.h
+asn1_Key.o: asn1_Key.c
+asn1_Key.o: hdb_asn1-priv.h
+asn1_Key.o: hdb_asn1.h
+asn1_Key.po: asn1_Key.c
+asn1_Key.po: hdb_asn1-priv.h
+asn1_Key.po: hdb_asn1.h
+asn1_Salt.So: asn1_Salt.c
+asn1_Salt.So: hdb_asn1-priv.h
+asn1_Salt.So: hdb_asn1.h
+asn1_Salt.o: asn1_Salt.c
+asn1_Salt.o: hdb_asn1-priv.h
+asn1_Salt.o: hdb_asn1.h
+asn1_Salt.po: asn1_Salt.c
+asn1_Salt.po: hdb_asn1-priv.h
+asn1_Salt.po: hdb_asn1.h
+asn1_hdb_entry.So: asn1_hdb_entry.c
+asn1_hdb_entry.So: hdb_asn1-priv.h
+asn1_hdb_entry.So: hdb_asn1.h
+asn1_hdb_entry.o: asn1_hdb_entry.c
+asn1_hdb_entry.o: hdb_asn1-priv.h
+asn1_hdb_entry.o: hdb_asn1.h
+asn1_hdb_entry.po: asn1_hdb_entry.c
+asn1_hdb_entry.po: hdb_asn1-priv.h
+asn1_hdb_entry.po: hdb_asn1.h
+asn1_hdb_entry_alias.So: asn1_hdb_entry_alias.c
+asn1_hdb_entry_alias.So: hdb_asn1-priv.h
+asn1_hdb_entry_alias.So: hdb_asn1.h
+asn1_hdb_entry_alias.o: asn1_hdb_entry_alias.c
+asn1_hdb_entry_alias.o: hdb_asn1-priv.h
+asn1_hdb_entry_alias.o: hdb_asn1.h
+asn1_hdb_entry_alias.po: asn1_hdb_entry_alias.c
+asn1_hdb_entry_alias.po: hdb_asn1-priv.h
+asn1_hdb_entry_alias.po: hdb_asn1.h
+asn1_hdb_keyset.So: asn1_hdb_keyset.c
+asn1_hdb_keyset.So: hdb_asn1-priv.h
+asn1_hdb_keyset.So: hdb_asn1.h
+asn1_hdb_keyset.o: asn1_hdb_keyset.c
+asn1_hdb_keyset.o: hdb_asn1-priv.h
+asn1_hdb_keyset.o: hdb_asn1.h
+asn1_hdb_keyset.po: asn1_hdb_keyset.c
+asn1_hdb_keyset.po: hdb_asn1-priv.h
+asn1_hdb_keyset.po: hdb_asn1.h
+common.So: hdb_asn1.h
+common.So: hdb_err.h
+common.o: hdb_asn1.h
+common.o: hdb_err.h
+common.po: hdb_asn1.h
+common.po: hdb_err.h
+db.So: hdb_asn1.h
+db.So: hdb_err.h
+db.o: hdb_asn1.h
+db.o: hdb_err.h
+db.po: hdb_asn1.h
+db.po: hdb_err.h
+db3.So: hdb_asn1.h
+db3.So: hdb_err.h
+db3.o: hdb_asn1.h
+db3.o: hdb_err.h
+db3.po: hdb_asn1.h
+db3.po: hdb_err.h
+dbinfo.So: hdb_asn1.h
+dbinfo.So: hdb_err.h
+dbinfo.o: hdb_asn1.h
+dbinfo.o: hdb_err.h
+dbinfo.po: hdb_asn1.h
+dbinfo.po: hdb_err.h
+ext.So: hdb_asn1.h
+ext.So: hdb_err.h
+ext.o: hdb_asn1.h
+ext.o: hdb_err.h
+ext.po: hdb_asn1.h
+ext.po: hdb_err.h
+hdb-keytab.So: hdb_asn1.h
+hdb-keytab.So: hdb_err.h
+hdb-keytab.o: hdb_asn1.h
+hdb-keytab.o: hdb_err.h
+hdb-keytab.po: hdb_asn1.h
+hdb-keytab.po: hdb_err.h
+hdb-ldap.So: hdb_asn1.h
+hdb-ldap.So: hdb_err.h
+hdb-ldap.o: hdb_asn1.h
+hdb-ldap.o: hdb_err.h
+hdb-ldap.po: hdb_asn1.h
+hdb-ldap.po: hdb_err.h
+hdb-mitdb.So: hdb_asn1.h
+hdb-mitdb.So: hdb_err.h
+hdb-mitdb.o: hdb_asn1.h
+hdb-mitdb.o: hdb_err.h
+hdb-mitdb.po: hdb_asn1.h
+hdb-mitdb.po: hdb_err.h
+hdb-sqlite.So: hdb_asn1.h
+hdb-sqlite.So: hdb_err.h
+hdb-sqlite.o: hdb_asn1.h
+hdb-sqlite.o: hdb_err.h
+hdb-sqlite.po: hdb_asn1.h
+hdb-sqlite.po: hdb_err.h
+hdb.So: hdb_asn1.h
+hdb.So: hdb_err.h
+hdb.o: hdb_asn1.h
+hdb.o: hdb_err.h
+hdb.po: hdb_asn1.h
+hdb.po: hdb_err.h
+hdb_err.So: hdb_err.c
+hdb_err.So: hdb_err.h
+hdb_err.o: hdb_err.c
+hdb_err.o: hdb_err.h
+hdb_err.po: hdb_err.c
+hdb_err.po: hdb_err.h
+keys.So: hdb_asn1.h
+keys.So: hdb_err.h
+keys.o: hdb_asn1.h
+keys.o: hdb_err.h
+keys.po: hdb_asn1.h
+keys.po: hdb_err.h
+keytab.So: hdb_asn1.h
+keytab.So: hdb_err.h
+keytab.o: hdb_asn1.h
+keytab.o: hdb_err.h
+keytab.po: hdb_asn1.h
+keytab.po: hdb_err.h
+mkey.So: hdb_asn1.h
+mkey.So: hdb_err.h
+mkey.o: hdb_asn1.h
+mkey.o: hdb_err.h
+mkey.po: hdb_asn1.h
+mkey.po: hdb_err.h
+ndbm.So: hdb_asn1.h
+ndbm.So: hdb_err.h
+ndbm.o: hdb_asn1.h
+ndbm.o: hdb_err.h
+ndbm.po: hdb_asn1.h
+ndbm.po: hdb_err.h
+print.So: hdb_asn1.h
+print.So: hdb_err.h
+print.o: hdb_asn1.h
+print.o: hdb_err.h
+print.po: hdb_asn1.h
+print.po: hdb_err.h
+.endif
diff --git a/kerberos5/lib/libheimbase/Makefile.depend b/kerberos5/lib/libheimbase/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/kerberos5/lib/libheimbase/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/lib/libheimipcc/Makefile.depend b/kerberos5/lib/libheimipcc/Makefile.depend
new file mode 100644
index 0000000..8939113
--- /dev/null
+++ b/kerberos5/lib/libheimipcc/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/lib/libheimipcs/Makefile.depend b/kerberos5/lib/libheimipcs/Makefile.depend
new file mode 100644
index 0000000..8939113
--- /dev/null
+++ b/kerberos5/lib/libheimipcs/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/lib/libheimntlm/Makefile.depend b/kerberos5/lib/libheimntlm/Makefile.depend
new file mode 100644
index 0000000..a746ba0
--- /dev/null
+++ b/kerberos5/lib/libheimntlm/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ lib/libcom_err \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ntlm_err.So: ntlm_err.c
+ntlm_err.So: ntlm_err.h
+ntlm_err.o: ntlm_err.c
+ntlm_err.o: ntlm_err.h
+ntlm_err.po: ntlm_err.c
+ntlm_err.po: ntlm_err.h
+.endif
diff --git a/kerberos5/lib/libheimsqlite/Makefile.depend b/kerberos5/lib/libheimsqlite/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/kerberos5/lib/libheimsqlite/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/lib/libhx509/Makefile.depend b/kerberos5/lib/libhx509/Makefile.depend
new file mode 100644
index 0000000..5270ad1
--- /dev/null
+++ b/kerberos5/lib/libhx509/Makefile.depend
@@ -0,0 +1,439 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ lib/libcom_err \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+asn1_CertificationRequest.So: asn1_CertificationRequest.c
+asn1_CertificationRequest.So: pkcs10_asn1-priv.h
+asn1_CertificationRequest.So: pkcs10_asn1.h
+asn1_CertificationRequest.o: asn1_CertificationRequest.c
+asn1_CertificationRequest.o: pkcs10_asn1-priv.h
+asn1_CertificationRequest.o: pkcs10_asn1.h
+asn1_CertificationRequest.po: asn1_CertificationRequest.c
+asn1_CertificationRequest.po: pkcs10_asn1-priv.h
+asn1_CertificationRequest.po: pkcs10_asn1.h
+asn1_CertificationRequestInfo.So: asn1_CertificationRequestInfo.c
+asn1_CertificationRequestInfo.So: pkcs10_asn1-priv.h
+asn1_CertificationRequestInfo.So: pkcs10_asn1.h
+asn1_CertificationRequestInfo.o: asn1_CertificationRequestInfo.c
+asn1_CertificationRequestInfo.o: pkcs10_asn1-priv.h
+asn1_CertificationRequestInfo.o: pkcs10_asn1.h
+asn1_CertificationRequestInfo.po: asn1_CertificationRequestInfo.c
+asn1_CertificationRequestInfo.po: pkcs10_asn1-priv.h
+asn1_CertificationRequestInfo.po: pkcs10_asn1.h
+asn1_OCSPBasicOCSPResponse.So: asn1_OCSPBasicOCSPResponse.c
+asn1_OCSPBasicOCSPResponse.So: ocsp_asn1-priv.h
+asn1_OCSPBasicOCSPResponse.So: ocsp_asn1.h
+asn1_OCSPBasicOCSPResponse.o: asn1_OCSPBasicOCSPResponse.c
+asn1_OCSPBasicOCSPResponse.o: ocsp_asn1-priv.h
+asn1_OCSPBasicOCSPResponse.o: ocsp_asn1.h
+asn1_OCSPBasicOCSPResponse.po: asn1_OCSPBasicOCSPResponse.c
+asn1_OCSPBasicOCSPResponse.po: ocsp_asn1-priv.h
+asn1_OCSPBasicOCSPResponse.po: ocsp_asn1.h
+asn1_OCSPCertID.So: asn1_OCSPCertID.c
+asn1_OCSPCertID.So: ocsp_asn1-priv.h
+asn1_OCSPCertID.So: ocsp_asn1.h
+asn1_OCSPCertID.o: asn1_OCSPCertID.c
+asn1_OCSPCertID.o: ocsp_asn1-priv.h
+asn1_OCSPCertID.o: ocsp_asn1.h
+asn1_OCSPCertID.po: asn1_OCSPCertID.c
+asn1_OCSPCertID.po: ocsp_asn1-priv.h
+asn1_OCSPCertID.po: ocsp_asn1.h
+asn1_OCSPCertStatus.So: asn1_OCSPCertStatus.c
+asn1_OCSPCertStatus.So: ocsp_asn1-priv.h
+asn1_OCSPCertStatus.So: ocsp_asn1.h
+asn1_OCSPCertStatus.o: asn1_OCSPCertStatus.c
+asn1_OCSPCertStatus.o: ocsp_asn1-priv.h
+asn1_OCSPCertStatus.o: ocsp_asn1.h
+asn1_OCSPCertStatus.po: asn1_OCSPCertStatus.c
+asn1_OCSPCertStatus.po: ocsp_asn1-priv.h
+asn1_OCSPCertStatus.po: ocsp_asn1.h
+asn1_OCSPInnerRequest.So: asn1_OCSPInnerRequest.c
+asn1_OCSPInnerRequest.So: ocsp_asn1-priv.h
+asn1_OCSPInnerRequest.So: ocsp_asn1.h
+asn1_OCSPInnerRequest.o: asn1_OCSPInnerRequest.c
+asn1_OCSPInnerRequest.o: ocsp_asn1-priv.h
+asn1_OCSPInnerRequest.o: ocsp_asn1.h
+asn1_OCSPInnerRequest.po: asn1_OCSPInnerRequest.c
+asn1_OCSPInnerRequest.po: ocsp_asn1-priv.h
+asn1_OCSPInnerRequest.po: ocsp_asn1.h
+asn1_OCSPKeyHash.So: asn1_OCSPKeyHash.c
+asn1_OCSPKeyHash.So: ocsp_asn1-priv.h
+asn1_OCSPKeyHash.So: ocsp_asn1.h
+asn1_OCSPKeyHash.o: asn1_OCSPKeyHash.c
+asn1_OCSPKeyHash.o: ocsp_asn1-priv.h
+asn1_OCSPKeyHash.o: ocsp_asn1.h
+asn1_OCSPKeyHash.po: asn1_OCSPKeyHash.c
+asn1_OCSPKeyHash.po: ocsp_asn1-priv.h
+asn1_OCSPKeyHash.po: ocsp_asn1.h
+asn1_OCSPRequest.So: asn1_OCSPRequest.c
+asn1_OCSPRequest.So: ocsp_asn1-priv.h
+asn1_OCSPRequest.So: ocsp_asn1.h
+asn1_OCSPRequest.o: asn1_OCSPRequest.c
+asn1_OCSPRequest.o: ocsp_asn1-priv.h
+asn1_OCSPRequest.o: ocsp_asn1.h
+asn1_OCSPRequest.po: asn1_OCSPRequest.c
+asn1_OCSPRequest.po: ocsp_asn1-priv.h
+asn1_OCSPRequest.po: ocsp_asn1.h
+asn1_OCSPResponderID.So: asn1_OCSPResponderID.c
+asn1_OCSPResponderID.So: ocsp_asn1-priv.h
+asn1_OCSPResponderID.So: ocsp_asn1.h
+asn1_OCSPResponderID.o: asn1_OCSPResponderID.c
+asn1_OCSPResponderID.o: ocsp_asn1-priv.h
+asn1_OCSPResponderID.o: ocsp_asn1.h
+asn1_OCSPResponderID.po: asn1_OCSPResponderID.c
+asn1_OCSPResponderID.po: ocsp_asn1-priv.h
+asn1_OCSPResponderID.po: ocsp_asn1.h
+asn1_OCSPResponse.So: asn1_OCSPResponse.c
+asn1_OCSPResponse.So: ocsp_asn1-priv.h
+asn1_OCSPResponse.So: ocsp_asn1.h
+asn1_OCSPResponse.o: asn1_OCSPResponse.c
+asn1_OCSPResponse.o: ocsp_asn1-priv.h
+asn1_OCSPResponse.o: ocsp_asn1.h
+asn1_OCSPResponse.po: asn1_OCSPResponse.c
+asn1_OCSPResponse.po: ocsp_asn1-priv.h
+asn1_OCSPResponse.po: ocsp_asn1.h
+asn1_OCSPResponseBytes.So: asn1_OCSPResponseBytes.c
+asn1_OCSPResponseBytes.So: ocsp_asn1-priv.h
+asn1_OCSPResponseBytes.So: ocsp_asn1.h
+asn1_OCSPResponseBytes.o: asn1_OCSPResponseBytes.c
+asn1_OCSPResponseBytes.o: ocsp_asn1-priv.h
+asn1_OCSPResponseBytes.o: ocsp_asn1.h
+asn1_OCSPResponseBytes.po: asn1_OCSPResponseBytes.c
+asn1_OCSPResponseBytes.po: ocsp_asn1-priv.h
+asn1_OCSPResponseBytes.po: ocsp_asn1.h
+asn1_OCSPResponseData.So: asn1_OCSPResponseData.c
+asn1_OCSPResponseData.So: ocsp_asn1-priv.h
+asn1_OCSPResponseData.So: ocsp_asn1.h
+asn1_OCSPResponseData.o: asn1_OCSPResponseData.c
+asn1_OCSPResponseData.o: ocsp_asn1-priv.h
+asn1_OCSPResponseData.o: ocsp_asn1.h
+asn1_OCSPResponseData.po: asn1_OCSPResponseData.c
+asn1_OCSPResponseData.po: ocsp_asn1-priv.h
+asn1_OCSPResponseData.po: ocsp_asn1.h
+asn1_OCSPResponseStatus.So: asn1_OCSPResponseStatus.c
+asn1_OCSPResponseStatus.So: ocsp_asn1-priv.h
+asn1_OCSPResponseStatus.So: ocsp_asn1.h
+asn1_OCSPResponseStatus.o: asn1_OCSPResponseStatus.c
+asn1_OCSPResponseStatus.o: ocsp_asn1-priv.h
+asn1_OCSPResponseStatus.o: ocsp_asn1.h
+asn1_OCSPResponseStatus.po: asn1_OCSPResponseStatus.c
+asn1_OCSPResponseStatus.po: ocsp_asn1-priv.h
+asn1_OCSPResponseStatus.po: ocsp_asn1.h
+asn1_OCSPSignature.So: asn1_OCSPSignature.c
+asn1_OCSPSignature.So: ocsp_asn1-priv.h
+asn1_OCSPSignature.So: ocsp_asn1.h
+asn1_OCSPSignature.o: asn1_OCSPSignature.c
+asn1_OCSPSignature.o: ocsp_asn1-priv.h
+asn1_OCSPSignature.o: ocsp_asn1.h
+asn1_OCSPSignature.po: asn1_OCSPSignature.c
+asn1_OCSPSignature.po: ocsp_asn1-priv.h
+asn1_OCSPSignature.po: ocsp_asn1.h
+asn1_OCSPSingleResponse.So: asn1_OCSPSingleResponse.c
+asn1_OCSPSingleResponse.So: ocsp_asn1-priv.h
+asn1_OCSPSingleResponse.So: ocsp_asn1.h
+asn1_OCSPSingleResponse.o: asn1_OCSPSingleResponse.c
+asn1_OCSPSingleResponse.o: ocsp_asn1-priv.h
+asn1_OCSPSingleResponse.o: ocsp_asn1.h
+asn1_OCSPSingleResponse.po: asn1_OCSPSingleResponse.c
+asn1_OCSPSingleResponse.po: ocsp_asn1-priv.h
+asn1_OCSPSingleResponse.po: ocsp_asn1.h
+asn1_OCSPTBSRequest.So: asn1_OCSPTBSRequest.c
+asn1_OCSPTBSRequest.So: ocsp_asn1-priv.h
+asn1_OCSPTBSRequest.So: ocsp_asn1.h
+asn1_OCSPTBSRequest.o: asn1_OCSPTBSRequest.c
+asn1_OCSPTBSRequest.o: ocsp_asn1-priv.h
+asn1_OCSPTBSRequest.o: ocsp_asn1.h
+asn1_OCSPTBSRequest.po: asn1_OCSPTBSRequest.c
+asn1_OCSPTBSRequest.po: ocsp_asn1-priv.h
+asn1_OCSPTBSRequest.po: ocsp_asn1.h
+asn1_OCSPVersion.So: asn1_OCSPVersion.c
+asn1_OCSPVersion.So: ocsp_asn1-priv.h
+asn1_OCSPVersion.So: ocsp_asn1.h
+asn1_OCSPVersion.o: asn1_OCSPVersion.c
+asn1_OCSPVersion.o: ocsp_asn1-priv.h
+asn1_OCSPVersion.o: ocsp_asn1.h
+asn1_OCSPVersion.po: asn1_OCSPVersion.c
+asn1_OCSPVersion.po: ocsp_asn1-priv.h
+asn1_OCSPVersion.po: ocsp_asn1.h
+asn1_id_pkix_ocsp.So: asn1_id_pkix_ocsp.c
+asn1_id_pkix_ocsp.So: ocsp_asn1-priv.h
+asn1_id_pkix_ocsp.So: ocsp_asn1.h
+asn1_id_pkix_ocsp.o: asn1_id_pkix_ocsp.c
+asn1_id_pkix_ocsp.o: ocsp_asn1-priv.h
+asn1_id_pkix_ocsp.o: ocsp_asn1.h
+asn1_id_pkix_ocsp.po: asn1_id_pkix_ocsp.c
+asn1_id_pkix_ocsp.po: ocsp_asn1-priv.h
+asn1_id_pkix_ocsp.po: ocsp_asn1.h
+asn1_id_pkix_ocsp_basic.So: asn1_id_pkix_ocsp_basic.c
+asn1_id_pkix_ocsp_basic.So: ocsp_asn1-priv.h
+asn1_id_pkix_ocsp_basic.So: ocsp_asn1.h
+asn1_id_pkix_ocsp_basic.o: asn1_id_pkix_ocsp_basic.c
+asn1_id_pkix_ocsp_basic.o: ocsp_asn1-priv.h
+asn1_id_pkix_ocsp_basic.o: ocsp_asn1.h
+asn1_id_pkix_ocsp_basic.po: asn1_id_pkix_ocsp_basic.c
+asn1_id_pkix_ocsp_basic.po: ocsp_asn1-priv.h
+asn1_id_pkix_ocsp_basic.po: ocsp_asn1.h
+asn1_id_pkix_ocsp_nonce.So: asn1_id_pkix_ocsp_nonce.c
+asn1_id_pkix_ocsp_nonce.So: ocsp_asn1-priv.h
+asn1_id_pkix_ocsp_nonce.So: ocsp_asn1.h
+asn1_id_pkix_ocsp_nonce.o: asn1_id_pkix_ocsp_nonce.c
+asn1_id_pkix_ocsp_nonce.o: ocsp_asn1-priv.h
+asn1_id_pkix_ocsp_nonce.o: ocsp_asn1.h
+asn1_id_pkix_ocsp_nonce.po: asn1_id_pkix_ocsp_nonce.c
+asn1_id_pkix_ocsp_nonce.po: ocsp_asn1-priv.h
+asn1_id_pkix_ocsp_nonce.po: ocsp_asn1.h
+ca.So: hx509_err.h
+ca.So: ocsp_asn1.h
+ca.So: pkcs10_asn1.h
+ca.o: hx509_err.h
+ca.o: ocsp_asn1.h
+ca.o: pkcs10_asn1.h
+ca.po: hx509_err.h
+ca.po: ocsp_asn1.h
+ca.po: pkcs10_asn1.h
+cert.So: hx509_err.h
+cert.So: ocsp_asn1.h
+cert.So: pkcs10_asn1.h
+cert.o: hx509_err.h
+cert.o: ocsp_asn1.h
+cert.o: pkcs10_asn1.h
+cert.po: hx509_err.h
+cert.po: ocsp_asn1.h
+cert.po: pkcs10_asn1.h
+cms.So: hx509_err.h
+cms.So: ocsp_asn1.h
+cms.So: pkcs10_asn1.h
+cms.o: hx509_err.h
+cms.o: ocsp_asn1.h
+cms.o: pkcs10_asn1.h
+cms.po: hx509_err.h
+cms.po: ocsp_asn1.h
+cms.po: pkcs10_asn1.h
+collector.So: hx509_err.h
+collector.So: ocsp_asn1.h
+collector.So: pkcs10_asn1.h
+collector.o: hx509_err.h
+collector.o: ocsp_asn1.h
+collector.o: pkcs10_asn1.h
+collector.po: hx509_err.h
+collector.po: ocsp_asn1.h
+collector.po: pkcs10_asn1.h
+crypto.So: hx509_err.h
+crypto.So: ocsp_asn1.h
+crypto.So: pkcs10_asn1.h
+crypto.o: hx509_err.h
+crypto.o: ocsp_asn1.h
+crypto.o: pkcs10_asn1.h
+crypto.po: hx509_err.h
+crypto.po: ocsp_asn1.h
+crypto.po: pkcs10_asn1.h
+env.So: hx509_err.h
+env.So: ocsp_asn1.h
+env.So: pkcs10_asn1.h
+env.o: hx509_err.h
+env.o: ocsp_asn1.h
+env.o: pkcs10_asn1.h
+env.po: hx509_err.h
+env.po: ocsp_asn1.h
+env.po: pkcs10_asn1.h
+error.So: hx509_err.h
+error.So: ocsp_asn1.h
+error.So: pkcs10_asn1.h
+error.o: hx509_err.h
+error.o: ocsp_asn1.h
+error.o: pkcs10_asn1.h
+error.po: hx509_err.h
+error.po: ocsp_asn1.h
+error.po: pkcs10_asn1.h
+file.So: hx509_err.h
+file.So: ocsp_asn1.h
+file.So: pkcs10_asn1.h
+file.o: hx509_err.h
+file.o: ocsp_asn1.h
+file.o: pkcs10_asn1.h
+file.po: hx509_err.h
+file.po: ocsp_asn1.h
+file.po: pkcs10_asn1.h
+hx509_err.So: hx509_err.c
+hx509_err.So: hx509_err.h
+hx509_err.o: hx509_err.c
+hx509_err.o: hx509_err.h
+hx509_err.po: hx509_err.c
+hx509_err.po: hx509_err.h
+keyset.So: hx509_err.h
+keyset.So: ocsp_asn1.h
+keyset.So: pkcs10_asn1.h
+keyset.o: hx509_err.h
+keyset.o: ocsp_asn1.h
+keyset.o: pkcs10_asn1.h
+keyset.po: hx509_err.h
+keyset.po: ocsp_asn1.h
+keyset.po: pkcs10_asn1.h
+ks_dir.So: hx509_err.h
+ks_dir.So: ocsp_asn1.h
+ks_dir.So: pkcs10_asn1.h
+ks_dir.o: hx509_err.h
+ks_dir.o: ocsp_asn1.h
+ks_dir.o: pkcs10_asn1.h
+ks_dir.po: hx509_err.h
+ks_dir.po: ocsp_asn1.h
+ks_dir.po: pkcs10_asn1.h
+ks_file.So: hx509_err.h
+ks_file.So: ocsp_asn1.h
+ks_file.So: pkcs10_asn1.h
+ks_file.o: hx509_err.h
+ks_file.o: ocsp_asn1.h
+ks_file.o: pkcs10_asn1.h
+ks_file.po: hx509_err.h
+ks_file.po: ocsp_asn1.h
+ks_file.po: pkcs10_asn1.h
+ks_keychain.So: hx509_err.h
+ks_keychain.So: ocsp_asn1.h
+ks_keychain.So: pkcs10_asn1.h
+ks_keychain.o: hx509_err.h
+ks_keychain.o: ocsp_asn1.h
+ks_keychain.o: pkcs10_asn1.h
+ks_keychain.po: hx509_err.h
+ks_keychain.po: ocsp_asn1.h
+ks_keychain.po: pkcs10_asn1.h
+ks_mem.So: hx509_err.h
+ks_mem.So: ocsp_asn1.h
+ks_mem.So: pkcs10_asn1.h
+ks_mem.o: hx509_err.h
+ks_mem.o: ocsp_asn1.h
+ks_mem.o: pkcs10_asn1.h
+ks_mem.po: hx509_err.h
+ks_mem.po: ocsp_asn1.h
+ks_mem.po: pkcs10_asn1.h
+ks_null.So: hx509_err.h
+ks_null.So: ocsp_asn1.h
+ks_null.So: pkcs10_asn1.h
+ks_null.o: hx509_err.h
+ks_null.o: ocsp_asn1.h
+ks_null.o: pkcs10_asn1.h
+ks_null.po: hx509_err.h
+ks_null.po: ocsp_asn1.h
+ks_null.po: pkcs10_asn1.h
+ks_p11.So: hx509_err.h
+ks_p11.So: ocsp_asn1.h
+ks_p11.So: pkcs10_asn1.h
+ks_p11.o: hx509_err.h
+ks_p11.o: ocsp_asn1.h
+ks_p11.o: pkcs10_asn1.h
+ks_p11.po: hx509_err.h
+ks_p11.po: ocsp_asn1.h
+ks_p11.po: pkcs10_asn1.h
+ks_p12.So: hx509_err.h
+ks_p12.So: ocsp_asn1.h
+ks_p12.So: pkcs10_asn1.h
+ks_p12.o: hx509_err.h
+ks_p12.o: ocsp_asn1.h
+ks_p12.o: pkcs10_asn1.h
+ks_p12.po: hx509_err.h
+ks_p12.po: ocsp_asn1.h
+ks_p12.po: pkcs10_asn1.h
+lock.So: hx509_err.h
+lock.So: ocsp_asn1.h
+lock.So: pkcs10_asn1.h
+lock.o: hx509_err.h
+lock.o: ocsp_asn1.h
+lock.o: pkcs10_asn1.h
+lock.po: hx509_err.h
+lock.po: ocsp_asn1.h
+lock.po: pkcs10_asn1.h
+name.So: hx509_err.h
+name.So: ocsp_asn1.h
+name.So: pkcs10_asn1.h
+name.o: hx509_err.h
+name.o: ocsp_asn1.h
+name.o: pkcs10_asn1.h
+name.po: hx509_err.h
+name.po: ocsp_asn1.h
+name.po: pkcs10_asn1.h
+peer.So: hx509_err.h
+peer.So: ocsp_asn1.h
+peer.So: pkcs10_asn1.h
+peer.o: hx509_err.h
+peer.o: ocsp_asn1.h
+peer.o: pkcs10_asn1.h
+peer.po: hx509_err.h
+peer.po: ocsp_asn1.h
+peer.po: pkcs10_asn1.h
+print.So: hx509_err.h
+print.So: ocsp_asn1.h
+print.So: pkcs10_asn1.h
+print.o: hx509_err.h
+print.o: ocsp_asn1.h
+print.o: pkcs10_asn1.h
+print.po: hx509_err.h
+print.po: ocsp_asn1.h
+print.po: pkcs10_asn1.h
+req.So: hx509_err.h
+req.So: ocsp_asn1.h
+req.So: pkcs10_asn1.h
+req.o: hx509_err.h
+req.o: ocsp_asn1.h
+req.o: pkcs10_asn1.h
+req.po: hx509_err.h
+req.po: ocsp_asn1.h
+req.po: pkcs10_asn1.h
+revoke.So: hx509_err.h
+revoke.So: ocsp_asn1.h
+revoke.So: pkcs10_asn1.h
+revoke.o: hx509_err.h
+revoke.o: ocsp_asn1.h
+revoke.o: pkcs10_asn1.h
+revoke.po: hx509_err.h
+revoke.po: ocsp_asn1.h
+revoke.po: pkcs10_asn1.h
+sel-gram.So: hx509_err.h
+sel-gram.So: ocsp_asn1.h
+sel-gram.So: pkcs10_asn1.h
+sel-gram.So: sel-gram.c
+sel-gram.o: hx509_err.h
+sel-gram.o: ocsp_asn1.h
+sel-gram.o: pkcs10_asn1.h
+sel-gram.o: sel-gram.c
+sel-gram.po: hx509_err.h
+sel-gram.po: ocsp_asn1.h
+sel-gram.po: pkcs10_asn1.h
+sel-gram.po: sel-gram.c
+sel-lex.So: sel-gram.h
+sel-lex.So: sel-lex.c
+sel-lex.o: sel-gram.h
+sel-lex.o: sel-lex.c
+sel-lex.po: sel-gram.h
+sel-lex.po: sel-lex.c
+sel.So: hx509_err.h
+sel.So: ocsp_asn1.h
+sel.So: pkcs10_asn1.h
+sel.o: hx509_err.h
+sel.o: ocsp_asn1.h
+sel.o: pkcs10_asn1.h
+sel.po: hx509_err.h
+sel.po: ocsp_asn1.h
+sel.po: pkcs10_asn1.h
+softp11.So: hx509_err.h
+softp11.So: ocsp_asn1.h
+softp11.So: pkcs10_asn1.h
+softp11.o: hx509_err.h
+softp11.o: ocsp_asn1.h
+softp11.o: pkcs10_asn1.h
+softp11.po: hx509_err.h
+softp11.po: ocsp_asn1.h
+softp11.po: pkcs10_asn1.h
+.endif
diff --git a/kerberos5/lib/libkadm5clnt/Makefile.depend b/kerberos5/lib/libkadm5clnt/Makefile.depend
new file mode 100644
index 0000000..e95d176
--- /dev/null
+++ b/kerberos5/lib/libkadm5clnt/Makefile.depend
@@ -0,0 +1,80 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ lib/libcom_err \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ad.So: kadm5_err.h
+ad.o: kadm5_err.h
+ad.po: kadm5_err.h
+chpass_c.So: kadm5_err.h
+chpass_c.o: kadm5_err.h
+chpass_c.po: kadm5_err.h
+client_glue.So: kadm5_err.h
+client_glue.o: kadm5_err.h
+client_glue.po: kadm5_err.h
+common_glue.So: kadm5_err.h
+common_glue.o: kadm5_err.h
+common_glue.po: kadm5_err.h
+create_c.So: kadm5_err.h
+create_c.o: kadm5_err.h
+create_c.po: kadm5_err.h
+delete_c.So: kadm5_err.h
+delete_c.o: kadm5_err.h
+delete_c.po: kadm5_err.h
+destroy_c.So: kadm5_err.h
+destroy_c.o: kadm5_err.h
+destroy_c.po: kadm5_err.h
+flush_c.So: kadm5_err.h
+flush_c.o: kadm5_err.h
+flush_c.po: kadm5_err.h
+free.So: kadm5_err.h
+free.o: kadm5_err.h
+free.po: kadm5_err.h
+get_c.So: kadm5_err.h
+get_c.o: kadm5_err.h
+get_c.po: kadm5_err.h
+get_princs_c.So: kadm5_err.h
+get_princs_c.o: kadm5_err.h
+get_princs_c.po: kadm5_err.h
+init_c.So: kadm5_err.h
+init_c.o: kadm5_err.h
+init_c.po: kadm5_err.h
+kadm5_err.So: kadm5_err.c
+kadm5_err.So: kadm5_err.h
+kadm5_err.o: kadm5_err.c
+kadm5_err.o: kadm5_err.h
+kadm5_err.po: kadm5_err.c
+kadm5_err.po: kadm5_err.h
+marshall.So: kadm5_err.h
+marshall.o: kadm5_err.h
+marshall.po: kadm5_err.h
+modify_c.So: kadm5_err.h
+modify_c.o: kadm5_err.h
+modify_c.po: kadm5_err.h
+privs_c.So: kadm5_err.h
+privs_c.o: kadm5_err.h
+privs_c.po: kadm5_err.h
+randkey_c.So: kadm5_err.h
+randkey_c.o: kadm5_err.h
+randkey_c.po: kadm5_err.h
+rename_c.So: kadm5_err.h
+rename_c.o: kadm5_err.h
+rename_c.po: kadm5_err.h
+send_recv.So: kadm5_err.h
+send_recv.o: kadm5_err.h
+send_recv.po: kadm5_err.h
+.endif
diff --git a/kerberos5/lib/libkadm5srv/Makefile.depend b/kerberos5/lib/libkadm5srv/Makefile.depend
new file mode 100644
index 0000000..0db4314
--- /dev/null
+++ b/kerberos5/lib/libkadm5srv/Makefile.depend
@@ -0,0 +1,104 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ lib/libcom_err \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+acl.So: kadm5_err.h
+acl.o: kadm5_err.h
+acl.po: kadm5_err.h
+bump_pw_expire.So: kadm5_err.h
+bump_pw_expire.o: kadm5_err.h
+bump_pw_expire.po: kadm5_err.h
+chpass_s.So: kadm5_err.h
+chpass_s.o: kadm5_err.h
+chpass_s.po: kadm5_err.h
+common_glue.So: kadm5_err.h
+common_glue.o: kadm5_err.h
+common_glue.po: kadm5_err.h
+context_s.So: kadm5_err.h
+context_s.o: kadm5_err.h
+context_s.po: kadm5_err.h
+create_s.So: kadm5_err.h
+create_s.o: kadm5_err.h
+create_s.po: kadm5_err.h
+delete_s.So: kadm5_err.h
+delete_s.o: kadm5_err.h
+delete_s.po: kadm5_err.h
+destroy_s.So: kadm5_err.h
+destroy_s.o: kadm5_err.h
+destroy_s.po: kadm5_err.h
+ent_setup.So: kadm5_err.h
+ent_setup.o: kadm5_err.h
+ent_setup.po: kadm5_err.h
+error.So: kadm5_err.h
+error.o: kadm5_err.h
+error.po: kadm5_err.h
+flush_s.So: kadm5_err.h
+flush_s.o: kadm5_err.h
+flush_s.po: kadm5_err.h
+free.So: kadm5_err.h
+free.o: kadm5_err.h
+free.po: kadm5_err.h
+get_princs_s.So: kadm5_err.h
+get_princs_s.o: kadm5_err.h
+get_princs_s.po: kadm5_err.h
+get_s.So: kadm5_err.h
+get_s.o: kadm5_err.h
+get_s.po: kadm5_err.h
+init_s.So: kadm5_err.h
+init_s.o: kadm5_err.h
+init_s.po: kadm5_err.h
+kadm5_err.So: kadm5_err.c
+kadm5_err.So: kadm5_err.h
+kadm5_err.o: kadm5_err.c
+kadm5_err.o: kadm5_err.h
+kadm5_err.po: kadm5_err.c
+kadm5_err.po: kadm5_err.h
+keys.So: kadm5_err.h
+keys.o: kadm5_err.h
+keys.po: kadm5_err.h
+log.So: kadm5_err.h
+log.o: kadm5_err.h
+log.po: kadm5_err.h
+marshall.So: kadm5_err.h
+marshall.o: kadm5_err.h
+marshall.po: kadm5_err.h
+modify_s.So: kadm5_err.h
+modify_s.o: kadm5_err.h
+modify_s.po: kadm5_err.h
+password_quality.So: kadm5_err.h
+password_quality.o: kadm5_err.h
+password_quality.po: kadm5_err.h
+privs_s.So: kadm5_err.h
+privs_s.o: kadm5_err.h
+privs_s.po: kadm5_err.h
+randkey_s.So: kadm5_err.h
+randkey_s.o: kadm5_err.h
+randkey_s.po: kadm5_err.h
+rename_s.So: kadm5_err.h
+rename_s.o: kadm5_err.h
+rename_s.po: kadm5_err.h
+server_glue.So: kadm5_err.h
+server_glue.o: kadm5_err.h
+server_glue.po: kadm5_err.h
+set_keys.So: kadm5_err.h
+set_keys.o: kadm5_err.h
+set_keys.po: kadm5_err.h
+set_modifier.So: kadm5_err.h
+set_modifier.o: kadm5_err.h
+set_modifier.po: kadm5_err.h
+.endif
diff --git a/kerberos5/lib/libkafs5/Makefile.depend b/kerberos5/lib/libkafs5/Makefile.depend
new file mode 100644
index 0000000..8939113
--- /dev/null
+++ b/kerberos5/lib/libkafs5/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/lib/libkdc/Makefile.depend b/kerberos5/lib/libkdc/Makefile.depend
new file mode 100644
index 0000000..bbba09e
--- /dev/null
+++ b/kerberos5/lib/libkdc/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libheimbase \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkrb5 \
+ lib/libcom_err \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/lib/libkrb5/Makefile.depend b/kerberos5/lib/libkrb5/Makefile.depend
new file mode 100644
index 0000000..6ec997b
--- /dev/null
+++ b/kerberos5/lib/libkrb5/Makefile.depend
@@ -0,0 +1,1094 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libheimipcc \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libwind \
+ lib/libcom_err \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+acache.So: heim_err.h
+acache.So: k524_err.h
+acache.So: krb5_err.h
+acache.o: heim_err.h
+acache.o: k524_err.h
+acache.o: krb5_err.h
+acache.po: heim_err.h
+acache.po: k524_err.h
+acache.po: krb5_err.h
+acl.So: heim_err.h
+acl.So: k524_err.h
+acl.So: krb5_err.h
+acl.o: heim_err.h
+acl.o: k524_err.h
+acl.o: krb5_err.h
+acl.po: heim_err.h
+acl.po: k524_err.h
+acl.po: krb5_err.h
+add_et_list.So: heim_err.h
+add_et_list.So: k524_err.h
+add_et_list.So: krb5_err.h
+add_et_list.o: heim_err.h
+add_et_list.o: k524_err.h
+add_et_list.o: krb5_err.h
+add_et_list.po: heim_err.h
+add_et_list.po: k524_err.h
+add_et_list.po: krb5_err.h
+addr_families.So: heim_err.h
+addr_families.So: k524_err.h
+addr_families.So: krb5_err.h
+addr_families.o: heim_err.h
+addr_families.o: k524_err.h
+addr_families.o: krb5_err.h
+addr_families.po: heim_err.h
+addr_families.po: k524_err.h
+addr_families.po: krb5_err.h
+aname_to_localname.So: heim_err.h
+aname_to_localname.So: k524_err.h
+aname_to_localname.So: krb5_err.h
+aname_to_localname.o: heim_err.h
+aname_to_localname.o: k524_err.h
+aname_to_localname.o: krb5_err.h
+aname_to_localname.po: heim_err.h
+aname_to_localname.po: k524_err.h
+aname_to_localname.po: krb5_err.h
+appdefault.So: heim_err.h
+appdefault.So: k524_err.h
+appdefault.So: krb5_err.h
+appdefault.o: heim_err.h
+appdefault.o: k524_err.h
+appdefault.o: krb5_err.h
+appdefault.po: heim_err.h
+appdefault.po: k524_err.h
+appdefault.po: krb5_err.h
+asn1_glue.So: heim_err.h
+asn1_glue.So: k524_err.h
+asn1_glue.So: krb5_err.h
+asn1_glue.o: heim_err.h
+asn1_glue.o: k524_err.h
+asn1_glue.o: krb5_err.h
+asn1_glue.po: heim_err.h
+asn1_glue.po: k524_err.h
+asn1_glue.po: krb5_err.h
+auth_context.So: heim_err.h
+auth_context.So: k524_err.h
+auth_context.So: krb5_err.h
+auth_context.o: heim_err.h
+auth_context.o: k524_err.h
+auth_context.o: krb5_err.h
+auth_context.po: heim_err.h
+auth_context.po: k524_err.h
+auth_context.po: krb5_err.h
+build_ap_req.So: heim_err.h
+build_ap_req.So: k524_err.h
+build_ap_req.So: krb5_err.h
+build_ap_req.o: heim_err.h
+build_ap_req.o: k524_err.h
+build_ap_req.o: krb5_err.h
+build_ap_req.po: heim_err.h
+build_ap_req.po: k524_err.h
+build_ap_req.po: krb5_err.h
+build_auth.So: heim_err.h
+build_auth.So: k524_err.h
+build_auth.So: krb5_err.h
+build_auth.o: heim_err.h
+build_auth.o: k524_err.h
+build_auth.o: krb5_err.h
+build_auth.po: heim_err.h
+build_auth.po: k524_err.h
+build_auth.po: krb5_err.h
+cache.So: heim_err.h
+cache.So: k524_err.h
+cache.So: krb5_err.h
+cache.o: heim_err.h
+cache.o: k524_err.h
+cache.o: krb5_err.h
+cache.po: heim_err.h
+cache.po: k524_err.h
+cache.po: krb5_err.h
+changepw.So: heim_err.h
+changepw.So: k524_err.h
+changepw.So: krb5_err.h
+changepw.o: heim_err.h
+changepw.o: k524_err.h
+changepw.o: krb5_err.h
+changepw.po: heim_err.h
+changepw.po: k524_err.h
+changepw.po: krb5_err.h
+codec.So: heim_err.h
+codec.So: k524_err.h
+codec.So: krb5_err.h
+codec.o: heim_err.h
+codec.o: k524_err.h
+codec.o: krb5_err.h
+codec.po: heim_err.h
+codec.po: k524_err.h
+codec.po: krb5_err.h
+config_file.So: heim_err.h
+config_file.So: k524_err.h
+config_file.So: krb5_err.h
+config_file.o: heim_err.h
+config_file.o: k524_err.h
+config_file.o: krb5_err.h
+config_file.po: heim_err.h
+config_file.po: k524_err.h
+config_file.po: krb5_err.h
+constants.So: heim_err.h
+constants.So: k524_err.h
+constants.So: krb5_err.h
+constants.o: heim_err.h
+constants.o: k524_err.h
+constants.o: krb5_err.h
+constants.po: heim_err.h
+constants.po: k524_err.h
+constants.po: krb5_err.h
+context.So: heim_err.h
+context.So: k524_err.h
+context.So: krb5_err.h
+context.o: heim_err.h
+context.o: k524_err.h
+context.o: krb5_err.h
+context.po: heim_err.h
+context.po: k524_err.h
+context.po: krb5_err.h
+convert_creds.So: heim_err.h
+convert_creds.So: k524_err.h
+convert_creds.So: krb5_err.h
+convert_creds.So: krb_err.h
+convert_creds.o: heim_err.h
+convert_creds.o: k524_err.h
+convert_creds.o: krb5_err.h
+convert_creds.o: krb_err.h
+convert_creds.po: heim_err.h
+convert_creds.po: k524_err.h
+convert_creds.po: krb5_err.h
+convert_creds.po: krb_err.h
+copy_host_realm.So: heim_err.h
+copy_host_realm.So: k524_err.h
+copy_host_realm.So: krb5_err.h
+copy_host_realm.o: heim_err.h
+copy_host_realm.o: k524_err.h
+copy_host_realm.o: krb5_err.h
+copy_host_realm.po: heim_err.h
+copy_host_realm.po: k524_err.h
+copy_host_realm.po: krb5_err.h
+crc.So: heim_err.h
+crc.So: k524_err.h
+crc.So: krb5_err.h
+crc.o: heim_err.h
+crc.o: k524_err.h
+crc.o: krb5_err.h
+crc.po: heim_err.h
+crc.po: k524_err.h
+crc.po: krb5_err.h
+creds.So: heim_err.h
+creds.So: k524_err.h
+creds.So: krb5_err.h
+creds.o: heim_err.h
+creds.o: k524_err.h
+creds.o: krb5_err.h
+creds.po: heim_err.h
+creds.po: k524_err.h
+creds.po: krb5_err.h
+crypto-aes.So: heim_err.h
+crypto-aes.So: k524_err.h
+crypto-aes.So: krb5_err.h
+crypto-aes.o: heim_err.h
+crypto-aes.o: k524_err.h
+crypto-aes.o: krb5_err.h
+crypto-aes.po: heim_err.h
+crypto-aes.po: k524_err.h
+crypto-aes.po: krb5_err.h
+crypto-algs.So: heim_err.h
+crypto-algs.So: k524_err.h
+crypto-algs.So: krb5_err.h
+crypto-algs.o: heim_err.h
+crypto-algs.o: k524_err.h
+crypto-algs.o: krb5_err.h
+crypto-algs.po: heim_err.h
+crypto-algs.po: k524_err.h
+crypto-algs.po: krb5_err.h
+crypto-arcfour.So: heim_err.h
+crypto-arcfour.So: k524_err.h
+crypto-arcfour.So: krb5_err.h
+crypto-arcfour.o: heim_err.h
+crypto-arcfour.o: k524_err.h
+crypto-arcfour.o: krb5_err.h
+crypto-arcfour.po: heim_err.h
+crypto-arcfour.po: k524_err.h
+crypto-arcfour.po: krb5_err.h
+crypto-des-common.So: heim_err.h
+crypto-des-common.So: k524_err.h
+crypto-des-common.So: krb5_err.h
+crypto-des-common.o: heim_err.h
+crypto-des-common.o: k524_err.h
+crypto-des-common.o: krb5_err.h
+crypto-des-common.po: heim_err.h
+crypto-des-common.po: k524_err.h
+crypto-des-common.po: krb5_err.h
+crypto-des.So: heim_err.h
+crypto-des.So: k524_err.h
+crypto-des.So: krb5_err.h
+crypto-des.o: heim_err.h
+crypto-des.o: k524_err.h
+crypto-des.o: krb5_err.h
+crypto-des.po: heim_err.h
+crypto-des.po: k524_err.h
+crypto-des.po: krb5_err.h
+crypto-des3.So: heim_err.h
+crypto-des3.So: k524_err.h
+crypto-des3.So: krb5_err.h
+crypto-des3.o: heim_err.h
+crypto-des3.o: k524_err.h
+crypto-des3.o: krb5_err.h
+crypto-des3.po: heim_err.h
+crypto-des3.po: k524_err.h
+crypto-des3.po: krb5_err.h
+crypto-evp.So: heim_err.h
+crypto-evp.So: k524_err.h
+crypto-evp.So: krb5_err.h
+crypto-evp.o: heim_err.h
+crypto-evp.o: k524_err.h
+crypto-evp.o: krb5_err.h
+crypto-evp.po: heim_err.h
+crypto-evp.po: k524_err.h
+crypto-evp.po: krb5_err.h
+crypto-null.So: heim_err.h
+crypto-null.So: k524_err.h
+crypto-null.So: krb5_err.h
+crypto-null.o: heim_err.h
+crypto-null.o: k524_err.h
+crypto-null.o: krb5_err.h
+crypto-null.po: heim_err.h
+crypto-null.po: k524_err.h
+crypto-null.po: krb5_err.h
+crypto-pk.So: heim_err.h
+crypto-pk.So: k524_err.h
+crypto-pk.So: krb5_err.h
+crypto-pk.o: heim_err.h
+crypto-pk.o: k524_err.h
+crypto-pk.o: krb5_err.h
+crypto-pk.po: heim_err.h
+crypto-pk.po: k524_err.h
+crypto-pk.po: krb5_err.h
+crypto-rand.So: heim_err.h
+crypto-rand.So: k524_err.h
+crypto-rand.So: krb5_err.h
+crypto-rand.o: heim_err.h
+crypto-rand.o: k524_err.h
+crypto-rand.o: krb5_err.h
+crypto-rand.po: heim_err.h
+crypto-rand.po: k524_err.h
+crypto-rand.po: krb5_err.h
+crypto.So: heim_err.h
+crypto.So: k524_err.h
+crypto.So: krb5_err.h
+crypto.o: heim_err.h
+crypto.o: k524_err.h
+crypto.o: krb5_err.h
+crypto.po: heim_err.h
+crypto.po: k524_err.h
+crypto.po: krb5_err.h
+data.So: heim_err.h
+data.So: k524_err.h
+data.So: krb5_err.h
+data.o: heim_err.h
+data.o: k524_err.h
+data.o: krb5_err.h
+data.po: heim_err.h
+data.po: k524_err.h
+data.po: krb5_err.h
+deprecated.So: heim_err.h
+deprecated.So: k524_err.h
+deprecated.So: krb5_err.h
+deprecated.o: heim_err.h
+deprecated.o: k524_err.h
+deprecated.o: krb5_err.h
+deprecated.po: heim_err.h
+deprecated.po: k524_err.h
+deprecated.po: krb5_err.h
+digest.So: heim_err.h
+digest.So: k524_err.h
+digest.So: krb5_err.h
+digest.o: heim_err.h
+digest.o: k524_err.h
+digest.o: krb5_err.h
+digest.po: heim_err.h
+digest.po: k524_err.h
+digest.po: krb5_err.h
+doxygen.So: heim_err.h
+doxygen.So: k524_err.h
+doxygen.So: krb5_err.h
+doxygen.o: heim_err.h
+doxygen.o: k524_err.h
+doxygen.o: krb5_err.h
+doxygen.po: heim_err.h
+doxygen.po: k524_err.h
+doxygen.po: krb5_err.h
+eai_to_heim_errno.So: heim_err.h
+eai_to_heim_errno.So: k524_err.h
+eai_to_heim_errno.So: krb5_err.h
+eai_to_heim_errno.o: heim_err.h
+eai_to_heim_errno.o: k524_err.h
+eai_to_heim_errno.o: krb5_err.h
+eai_to_heim_errno.po: heim_err.h
+eai_to_heim_errno.po: k524_err.h
+eai_to_heim_errno.po: krb5_err.h
+error_string.So: heim_err.h
+error_string.So: k524_err.h
+error_string.So: krb5_err.h
+error_string.o: heim_err.h
+error_string.o: k524_err.h
+error_string.o: krb5_err.h
+error_string.po: heim_err.h
+error_string.po: k524_err.h
+error_string.po: krb5_err.h
+expand_hostname.So: heim_err.h
+expand_hostname.So: k524_err.h
+expand_hostname.So: krb5_err.h
+expand_hostname.o: heim_err.h
+expand_hostname.o: k524_err.h
+expand_hostname.o: krb5_err.h
+expand_hostname.po: heim_err.h
+expand_hostname.po: k524_err.h
+expand_hostname.po: krb5_err.h
+expand_path.So: heim_err.h
+expand_path.So: k524_err.h
+expand_path.So: krb5_err.h
+expand_path.o: heim_err.h
+expand_path.o: k524_err.h
+expand_path.o: krb5_err.h
+expand_path.po: heim_err.h
+expand_path.po: k524_err.h
+expand_path.po: krb5_err.h
+fcache.So: heim_err.h
+fcache.So: k524_err.h
+fcache.So: krb5_err.h
+fcache.o: heim_err.h
+fcache.o: k524_err.h
+fcache.o: krb5_err.h
+fcache.po: heim_err.h
+fcache.po: k524_err.h
+fcache.po: krb5_err.h
+free.So: heim_err.h
+free.So: k524_err.h
+free.So: krb5_err.h
+free.o: heim_err.h
+free.o: k524_err.h
+free.o: krb5_err.h
+free.po: heim_err.h
+free.po: k524_err.h
+free.po: krb5_err.h
+free_host_realm.So: heim_err.h
+free_host_realm.So: k524_err.h
+free_host_realm.So: krb5_err.h
+free_host_realm.o: heim_err.h
+free_host_realm.o: k524_err.h
+free_host_realm.o: krb5_err.h
+free_host_realm.po: heim_err.h
+free_host_realm.po: k524_err.h
+free_host_realm.po: krb5_err.h
+generate_seq_number.So: heim_err.h
+generate_seq_number.So: k524_err.h
+generate_seq_number.So: krb5_err.h
+generate_seq_number.o: heim_err.h
+generate_seq_number.o: k524_err.h
+generate_seq_number.o: krb5_err.h
+generate_seq_number.po: heim_err.h
+generate_seq_number.po: k524_err.h
+generate_seq_number.po: krb5_err.h
+generate_subkey.So: heim_err.h
+generate_subkey.So: k524_err.h
+generate_subkey.So: krb5_err.h
+generate_subkey.o: heim_err.h
+generate_subkey.o: k524_err.h
+generate_subkey.o: krb5_err.h
+generate_subkey.po: heim_err.h
+generate_subkey.po: k524_err.h
+generate_subkey.po: krb5_err.h
+get_addrs.So: heim_err.h
+get_addrs.So: k524_err.h
+get_addrs.So: krb5_err.h
+get_addrs.o: heim_err.h
+get_addrs.o: k524_err.h
+get_addrs.o: krb5_err.h
+get_addrs.po: heim_err.h
+get_addrs.po: k524_err.h
+get_addrs.po: krb5_err.h
+get_cred.So: heim_err.h
+get_cred.So: k524_err.h
+get_cred.So: krb5_err.h
+get_cred.o: heim_err.h
+get_cred.o: k524_err.h
+get_cred.o: krb5_err.h
+get_cred.po: heim_err.h
+get_cred.po: k524_err.h
+get_cred.po: krb5_err.h
+get_default_principal.So: heim_err.h
+get_default_principal.So: k524_err.h
+get_default_principal.So: krb5_err.h
+get_default_principal.o: heim_err.h
+get_default_principal.o: k524_err.h
+get_default_principal.o: krb5_err.h
+get_default_principal.po: heim_err.h
+get_default_principal.po: k524_err.h
+get_default_principal.po: krb5_err.h
+get_default_realm.So: heim_err.h
+get_default_realm.So: k524_err.h
+get_default_realm.So: krb5_err.h
+get_default_realm.o: heim_err.h
+get_default_realm.o: k524_err.h
+get_default_realm.o: krb5_err.h
+get_default_realm.po: heim_err.h
+get_default_realm.po: k524_err.h
+get_default_realm.po: krb5_err.h
+get_for_creds.So: heim_err.h
+get_for_creds.So: k524_err.h
+get_for_creds.So: krb5_err.h
+get_for_creds.o: heim_err.h
+get_for_creds.o: k524_err.h
+get_for_creds.o: krb5_err.h
+get_for_creds.po: heim_err.h
+get_for_creds.po: k524_err.h
+get_for_creds.po: krb5_err.h
+get_host_realm.So: heim_err.h
+get_host_realm.So: k524_err.h
+get_host_realm.So: krb5_err.h
+get_host_realm.o: heim_err.h
+get_host_realm.o: k524_err.h
+get_host_realm.o: krb5_err.h
+get_host_realm.po: heim_err.h
+get_host_realm.po: k524_err.h
+get_host_realm.po: krb5_err.h
+get_in_tkt.So: heim_err.h
+get_in_tkt.So: k524_err.h
+get_in_tkt.So: krb5_err.h
+get_in_tkt.o: heim_err.h
+get_in_tkt.o: k524_err.h
+get_in_tkt.o: krb5_err.h
+get_in_tkt.po: heim_err.h
+get_in_tkt.po: k524_err.h
+get_in_tkt.po: krb5_err.h
+get_port.So: heim_err.h
+get_port.So: k524_err.h
+get_port.So: krb5_err.h
+get_port.o: heim_err.h
+get_port.o: k524_err.h
+get_port.o: krb5_err.h
+get_port.po: heim_err.h
+get_port.po: k524_err.h
+get_port.po: krb5_err.h
+heim_err.So: heim_err.c
+heim_err.So: heim_err.h
+heim_err.o: heim_err.c
+heim_err.o: heim_err.h
+heim_err.po: heim_err.c
+heim_err.po: heim_err.h
+init_creds.So: heim_err.h
+init_creds.So: k524_err.h
+init_creds.So: krb5_err.h
+init_creds.o: heim_err.h
+init_creds.o: k524_err.h
+init_creds.o: krb5_err.h
+init_creds.po: heim_err.h
+init_creds.po: k524_err.h
+init_creds.po: krb5_err.h
+init_creds_pw.So: heim_err.h
+init_creds_pw.So: k524_err.h
+init_creds_pw.So: krb5_err.h
+init_creds_pw.o: heim_err.h
+init_creds_pw.o: k524_err.h
+init_creds_pw.o: krb5_err.h
+init_creds_pw.po: heim_err.h
+init_creds_pw.po: k524_err.h
+init_creds_pw.po: krb5_err.h
+k524_err.So: k524_err.c
+k524_err.So: k524_err.h
+k524_err.o: k524_err.c
+k524_err.o: k524_err.h
+k524_err.po: k524_err.c
+k524_err.po: k524_err.h
+kcm.So: heim_err.h
+kcm.So: k524_err.h
+kcm.So: krb5_err.h
+kcm.o: heim_err.h
+kcm.o: k524_err.h
+kcm.o: krb5_err.h
+kcm.po: heim_err.h
+kcm.po: k524_err.h
+kcm.po: krb5_err.h
+keyblock.So: heim_err.h
+keyblock.So: k524_err.h
+keyblock.So: krb5_err.h
+keyblock.o: heim_err.h
+keyblock.o: k524_err.h
+keyblock.o: krb5_err.h
+keyblock.po: heim_err.h
+keyblock.po: k524_err.h
+keyblock.po: krb5_err.h
+keytab.So: heim_err.h
+keytab.So: k524_err.h
+keytab.So: krb5_err.h
+keytab.o: heim_err.h
+keytab.o: k524_err.h
+keytab.o: krb5_err.h
+keytab.po: heim_err.h
+keytab.po: k524_err.h
+keytab.po: krb5_err.h
+keytab_any.So: heim_err.h
+keytab_any.So: k524_err.h
+keytab_any.So: krb5_err.h
+keytab_any.o: heim_err.h
+keytab_any.o: k524_err.h
+keytab_any.o: krb5_err.h
+keytab_any.po: heim_err.h
+keytab_any.po: k524_err.h
+keytab_any.po: krb5_err.h
+keytab_file.So: heim_err.h
+keytab_file.So: k524_err.h
+keytab_file.So: krb5_err.h
+keytab_file.o: heim_err.h
+keytab_file.o: k524_err.h
+keytab_file.o: krb5_err.h
+keytab_file.po: heim_err.h
+keytab_file.po: k524_err.h
+keytab_file.po: krb5_err.h
+keytab_keyfile.So: heim_err.h
+keytab_keyfile.So: k524_err.h
+keytab_keyfile.So: krb5_err.h
+keytab_keyfile.o: heim_err.h
+keytab_keyfile.o: k524_err.h
+keytab_keyfile.o: krb5_err.h
+keytab_keyfile.po: heim_err.h
+keytab_keyfile.po: k524_err.h
+keytab_keyfile.po: krb5_err.h
+keytab_memory.So: heim_err.h
+keytab_memory.So: k524_err.h
+keytab_memory.So: krb5_err.h
+keytab_memory.o: heim_err.h
+keytab_memory.o: k524_err.h
+keytab_memory.o: krb5_err.h
+keytab_memory.po: heim_err.h
+keytab_memory.po: k524_err.h
+keytab_memory.po: krb5_err.h
+krb5_err.So: krb5_err.c
+krb5_err.So: krb5_err.h
+krb5_err.o: krb5_err.c
+krb5_err.o: krb5_err.h
+krb5_err.po: krb5_err.c
+krb5_err.po: krb5_err.h
+krb_err.So: krb_err.c
+krb_err.So: krb_err.h
+krb_err.o: krb_err.c
+krb_err.o: krb_err.h
+krb_err.po: krb_err.c
+krb_err.po: krb_err.h
+krbhst.So: heim_err.h
+krbhst.So: k524_err.h
+krbhst.So: krb5_err.h
+krbhst.o: heim_err.h
+krbhst.o: k524_err.h
+krbhst.o: krb5_err.h
+krbhst.po: heim_err.h
+krbhst.po: k524_err.h
+krbhst.po: krb5_err.h
+kuserok.So: heim_err.h
+kuserok.So: k524_err.h
+kuserok.So: krb5_err.h
+kuserok.o: heim_err.h
+kuserok.o: k524_err.h
+kuserok.o: krb5_err.h
+kuserok.po: heim_err.h
+kuserok.po: k524_err.h
+kuserok.po: krb5_err.h
+log.So: heim_err.h
+log.So: k524_err.h
+log.So: krb5_err.h
+log.o: heim_err.h
+log.o: k524_err.h
+log.o: krb5_err.h
+log.po: heim_err.h
+log.po: k524_err.h
+log.po: krb5_err.h
+mcache.So: heim_err.h
+mcache.So: k524_err.h
+mcache.So: krb5_err.h
+mcache.o: heim_err.h
+mcache.o: k524_err.h
+mcache.o: krb5_err.h
+mcache.po: heim_err.h
+mcache.po: k524_err.h
+mcache.po: krb5_err.h
+misc.So: heim_err.h
+misc.So: k524_err.h
+misc.So: krb5_err.h
+misc.o: heim_err.h
+misc.o: k524_err.h
+misc.o: krb5_err.h
+misc.po: heim_err.h
+misc.po: k524_err.h
+misc.po: krb5_err.h
+mit_glue.So: heim_err.h
+mit_glue.So: k524_err.h
+mit_glue.So: krb5_err.h
+mit_glue.o: heim_err.h
+mit_glue.o: k524_err.h
+mit_glue.o: krb5_err.h
+mit_glue.po: heim_err.h
+mit_glue.po: k524_err.h
+mit_glue.po: krb5_err.h
+mk_error.So: heim_err.h
+mk_error.So: k524_err.h
+mk_error.So: krb5_err.h
+mk_error.o: heim_err.h
+mk_error.o: k524_err.h
+mk_error.o: krb5_err.h
+mk_error.po: heim_err.h
+mk_error.po: k524_err.h
+mk_error.po: krb5_err.h
+mk_priv.So: heim_err.h
+mk_priv.So: k524_err.h
+mk_priv.So: krb5_err.h
+mk_priv.o: heim_err.h
+mk_priv.o: k524_err.h
+mk_priv.o: krb5_err.h
+mk_priv.po: heim_err.h
+mk_priv.po: k524_err.h
+mk_priv.po: krb5_err.h
+mk_rep.So: heim_err.h
+mk_rep.So: k524_err.h
+mk_rep.So: krb5_err.h
+mk_rep.o: heim_err.h
+mk_rep.o: k524_err.h
+mk_rep.o: krb5_err.h
+mk_rep.po: heim_err.h
+mk_rep.po: k524_err.h
+mk_rep.po: krb5_err.h
+mk_req.So: heim_err.h
+mk_req.So: k524_err.h
+mk_req.So: krb5_err.h
+mk_req.o: heim_err.h
+mk_req.o: k524_err.h
+mk_req.o: krb5_err.h
+mk_req.po: heim_err.h
+mk_req.po: k524_err.h
+mk_req.po: krb5_err.h
+mk_req_ext.So: heim_err.h
+mk_req_ext.So: k524_err.h
+mk_req_ext.So: krb5_err.h
+mk_req_ext.o: heim_err.h
+mk_req_ext.o: k524_err.h
+mk_req_ext.o: krb5_err.h
+mk_req_ext.po: heim_err.h
+mk_req_ext.po: k524_err.h
+mk_req_ext.po: krb5_err.h
+mk_safe.So: heim_err.h
+mk_safe.So: k524_err.h
+mk_safe.So: krb5_err.h
+mk_safe.o: heim_err.h
+mk_safe.o: k524_err.h
+mk_safe.o: krb5_err.h
+mk_safe.po: heim_err.h
+mk_safe.po: k524_err.h
+mk_safe.po: krb5_err.h
+n-fold.So: heim_err.h
+n-fold.So: k524_err.h
+n-fold.So: krb5_err.h
+n-fold.o: heim_err.h
+n-fold.o: k524_err.h
+n-fold.o: krb5_err.h
+n-fold.po: heim_err.h
+n-fold.po: k524_err.h
+n-fold.po: krb5_err.h
+net_read.So: heim_err.h
+net_read.So: k524_err.h
+net_read.So: krb5_err.h
+net_read.o: heim_err.h
+net_read.o: k524_err.h
+net_read.o: krb5_err.h
+net_read.po: heim_err.h
+net_read.po: k524_err.h
+net_read.po: krb5_err.h
+net_write.So: heim_err.h
+net_write.So: k524_err.h
+net_write.So: krb5_err.h
+net_write.o: heim_err.h
+net_write.o: k524_err.h
+net_write.o: krb5_err.h
+net_write.po: heim_err.h
+net_write.po: k524_err.h
+net_write.po: krb5_err.h
+pac.So: heim_err.h
+pac.So: k524_err.h
+pac.So: krb5_err.h
+pac.o: heim_err.h
+pac.o: k524_err.h
+pac.o: krb5_err.h
+pac.po: heim_err.h
+pac.po: k524_err.h
+pac.po: krb5_err.h
+padata.So: heim_err.h
+padata.So: k524_err.h
+padata.So: krb5_err.h
+padata.o: heim_err.h
+padata.o: k524_err.h
+padata.o: krb5_err.h
+padata.po: heim_err.h
+padata.po: k524_err.h
+padata.po: krb5_err.h
+pcache.So: heim_err.h
+pcache.So: k524_err.h
+pcache.So: krb5_err.h
+pcache.o: heim_err.h
+pcache.o: k524_err.h
+pcache.o: krb5_err.h
+pcache.po: heim_err.h
+pcache.po: k524_err.h
+pcache.po: krb5_err.h
+pkinit.So: heim_err.h
+pkinit.So: k524_err.h
+pkinit.So: krb5_err.h
+pkinit.o: heim_err.h
+pkinit.o: k524_err.h
+pkinit.o: krb5_err.h
+pkinit.po: heim_err.h
+pkinit.po: k524_err.h
+pkinit.po: krb5_err.h
+plugin.So: heim_err.h
+plugin.So: k524_err.h
+plugin.So: krb5_err.h
+plugin.o: heim_err.h
+plugin.o: k524_err.h
+plugin.o: krb5_err.h
+plugin.po: heim_err.h
+plugin.po: k524_err.h
+plugin.po: krb5_err.h
+principal.So: heim_err.h
+principal.So: k524_err.h
+principal.So: krb5_err.h
+principal.o: heim_err.h
+principal.o: k524_err.h
+principal.o: krb5_err.h
+principal.po: heim_err.h
+principal.po: k524_err.h
+principal.po: krb5_err.h
+prog_setup.So: heim_err.h
+prog_setup.So: k524_err.h
+prog_setup.So: krb5_err.h
+prog_setup.o: heim_err.h
+prog_setup.o: k524_err.h
+prog_setup.o: krb5_err.h
+prog_setup.po: heim_err.h
+prog_setup.po: k524_err.h
+prog_setup.po: krb5_err.h
+prompter_posix.So: heim_err.h
+prompter_posix.So: k524_err.h
+prompter_posix.So: krb5_err.h
+prompter_posix.o: heim_err.h
+prompter_posix.o: k524_err.h
+prompter_posix.o: krb5_err.h
+prompter_posix.po: heim_err.h
+prompter_posix.po: k524_err.h
+prompter_posix.po: krb5_err.h
+rd_cred.So: heim_err.h
+rd_cred.So: k524_err.h
+rd_cred.So: krb5_err.h
+rd_cred.o: heim_err.h
+rd_cred.o: k524_err.h
+rd_cred.o: krb5_err.h
+rd_cred.po: heim_err.h
+rd_cred.po: k524_err.h
+rd_cred.po: krb5_err.h
+rd_error.So: heim_err.h
+rd_error.So: k524_err.h
+rd_error.So: krb5_err.h
+rd_error.o: heim_err.h
+rd_error.o: k524_err.h
+rd_error.o: krb5_err.h
+rd_error.po: heim_err.h
+rd_error.po: k524_err.h
+rd_error.po: krb5_err.h
+rd_priv.So: heim_err.h
+rd_priv.So: k524_err.h
+rd_priv.So: krb5_err.h
+rd_priv.o: heim_err.h
+rd_priv.o: k524_err.h
+rd_priv.o: krb5_err.h
+rd_priv.po: heim_err.h
+rd_priv.po: k524_err.h
+rd_priv.po: krb5_err.h
+rd_rep.So: heim_err.h
+rd_rep.So: k524_err.h
+rd_rep.So: krb5_err.h
+rd_rep.o: heim_err.h
+rd_rep.o: k524_err.h
+rd_rep.o: krb5_err.h
+rd_rep.po: heim_err.h
+rd_rep.po: k524_err.h
+rd_rep.po: krb5_err.h
+rd_req.So: heim_err.h
+rd_req.So: k524_err.h
+rd_req.So: krb5_err.h
+rd_req.o: heim_err.h
+rd_req.o: k524_err.h
+rd_req.o: krb5_err.h
+rd_req.po: heim_err.h
+rd_req.po: k524_err.h
+rd_req.po: krb5_err.h
+rd_safe.So: heim_err.h
+rd_safe.So: k524_err.h
+rd_safe.So: krb5_err.h
+rd_safe.o: heim_err.h
+rd_safe.o: k524_err.h
+rd_safe.o: krb5_err.h
+rd_safe.po: heim_err.h
+rd_safe.po: k524_err.h
+rd_safe.po: krb5_err.h
+read_message.So: heim_err.h
+read_message.So: k524_err.h
+read_message.So: krb5_err.h
+read_message.o: heim_err.h
+read_message.o: k524_err.h
+read_message.o: krb5_err.h
+read_message.po: heim_err.h
+read_message.po: k524_err.h
+read_message.po: krb5_err.h
+recvauth.So: heim_err.h
+recvauth.So: k524_err.h
+recvauth.So: krb5_err.h
+recvauth.o: heim_err.h
+recvauth.o: k524_err.h
+recvauth.o: krb5_err.h
+recvauth.po: heim_err.h
+recvauth.po: k524_err.h
+recvauth.po: krb5_err.h
+replay.So: heim_err.h
+replay.So: k524_err.h
+replay.So: krb5_err.h
+replay.o: heim_err.h
+replay.o: k524_err.h
+replay.o: krb5_err.h
+replay.po: heim_err.h
+replay.po: k524_err.h
+replay.po: krb5_err.h
+salt-aes.So: heim_err.h
+salt-aes.So: k524_err.h
+salt-aes.So: krb5_err.h
+salt-aes.o: heim_err.h
+salt-aes.o: k524_err.h
+salt-aes.o: krb5_err.h
+salt-aes.po: heim_err.h
+salt-aes.po: k524_err.h
+salt-aes.po: krb5_err.h
+salt-arcfour.So: heim_err.h
+salt-arcfour.So: k524_err.h
+salt-arcfour.So: krb5_err.h
+salt-arcfour.o: heim_err.h
+salt-arcfour.o: k524_err.h
+salt-arcfour.o: krb5_err.h
+salt-arcfour.po: heim_err.h
+salt-arcfour.po: k524_err.h
+salt-arcfour.po: krb5_err.h
+salt-des.So: heim_err.h
+salt-des.So: k524_err.h
+salt-des.So: krb5_err.h
+salt-des.o: heim_err.h
+salt-des.o: k524_err.h
+salt-des.o: krb5_err.h
+salt-des.po: heim_err.h
+salt-des.po: k524_err.h
+salt-des.po: krb5_err.h
+salt-des3.So: heim_err.h
+salt-des3.So: k524_err.h
+salt-des3.So: krb5_err.h
+salt-des3.o: heim_err.h
+salt-des3.o: k524_err.h
+salt-des3.o: krb5_err.h
+salt-des3.po: heim_err.h
+salt-des3.po: k524_err.h
+salt-des3.po: krb5_err.h
+salt.So: heim_err.h
+salt.So: k524_err.h
+salt.So: krb5_err.h
+salt.o: heim_err.h
+salt.o: k524_err.h
+salt.o: krb5_err.h
+salt.po: heim_err.h
+salt.po: k524_err.h
+salt.po: krb5_err.h
+scache.So: heim_err.h
+scache.So: k524_err.h
+scache.So: krb5_err.h
+scache.o: heim_err.h
+scache.o: k524_err.h
+scache.o: krb5_err.h
+scache.po: heim_err.h
+scache.po: k524_err.h
+scache.po: krb5_err.h
+send_to_kdc.So: heim_err.h
+send_to_kdc.So: k524_err.h
+send_to_kdc.So: krb5_err.h
+send_to_kdc.o: heim_err.h
+send_to_kdc.o: k524_err.h
+send_to_kdc.o: krb5_err.h
+send_to_kdc.po: heim_err.h
+send_to_kdc.po: k524_err.h
+send_to_kdc.po: krb5_err.h
+sendauth.So: heim_err.h
+sendauth.So: k524_err.h
+sendauth.So: krb5_err.h
+sendauth.o: heim_err.h
+sendauth.o: k524_err.h
+sendauth.o: krb5_err.h
+sendauth.po: heim_err.h
+sendauth.po: k524_err.h
+sendauth.po: krb5_err.h
+set_default_realm.So: heim_err.h
+set_default_realm.So: k524_err.h
+set_default_realm.So: krb5_err.h
+set_default_realm.o: heim_err.h
+set_default_realm.o: k524_err.h
+set_default_realm.o: krb5_err.h
+set_default_realm.po: heim_err.h
+set_default_realm.po: k524_err.h
+set_default_realm.po: krb5_err.h
+sock_principal.So: heim_err.h
+sock_principal.So: k524_err.h
+sock_principal.So: krb5_err.h
+sock_principal.o: heim_err.h
+sock_principal.o: k524_err.h
+sock_principal.o: krb5_err.h
+sock_principal.po: heim_err.h
+sock_principal.po: k524_err.h
+sock_principal.po: krb5_err.h
+store-int.So: heim_err.h
+store-int.So: k524_err.h
+store-int.So: krb5_err.h
+store-int.o: heim_err.h
+store-int.o: k524_err.h
+store-int.o: krb5_err.h
+store-int.po: heim_err.h
+store-int.po: k524_err.h
+store-int.po: krb5_err.h
+store.So: heim_err.h
+store.So: k524_err.h
+store.So: krb5_err.h
+store.o: heim_err.h
+store.o: k524_err.h
+store.o: krb5_err.h
+store.po: heim_err.h
+store.po: k524_err.h
+store.po: krb5_err.h
+store_emem.So: heim_err.h
+store_emem.So: k524_err.h
+store_emem.So: krb5_err.h
+store_emem.o: heim_err.h
+store_emem.o: k524_err.h
+store_emem.o: krb5_err.h
+store_emem.po: heim_err.h
+store_emem.po: k524_err.h
+store_emem.po: krb5_err.h
+store_fd.So: heim_err.h
+store_fd.So: k524_err.h
+store_fd.So: krb5_err.h
+store_fd.o: heim_err.h
+store_fd.o: k524_err.h
+store_fd.o: krb5_err.h
+store_fd.po: heim_err.h
+store_fd.po: k524_err.h
+store_fd.po: krb5_err.h
+store_mem.So: heim_err.h
+store_mem.So: k524_err.h
+store_mem.So: krb5_err.h
+store_mem.o: heim_err.h
+store_mem.o: k524_err.h
+store_mem.o: krb5_err.h
+store_mem.po: heim_err.h
+store_mem.po: k524_err.h
+store_mem.po: krb5_err.h
+ticket.So: heim_err.h
+ticket.So: k524_err.h
+ticket.So: krb5_err.h
+ticket.o: heim_err.h
+ticket.o: k524_err.h
+ticket.o: krb5_err.h
+ticket.po: heim_err.h
+ticket.po: k524_err.h
+ticket.po: krb5_err.h
+time.So: heim_err.h
+time.So: k524_err.h
+time.So: krb5_err.h
+time.o: heim_err.h
+time.o: k524_err.h
+time.o: krb5_err.h
+time.po: heim_err.h
+time.po: k524_err.h
+time.po: krb5_err.h
+transited.So: heim_err.h
+transited.So: k524_err.h
+transited.So: krb5_err.h
+transited.o: heim_err.h
+transited.o: k524_err.h
+transited.o: krb5_err.h
+transited.po: heim_err.h
+transited.po: k524_err.h
+transited.po: krb5_err.h
+verify_init.So: heim_err.h
+verify_init.So: k524_err.h
+verify_init.So: krb5_err.h
+verify_init.o: heim_err.h
+verify_init.o: k524_err.h
+verify_init.o: krb5_err.h
+verify_init.po: heim_err.h
+verify_init.po: k524_err.h
+verify_init.po: krb5_err.h
+verify_user.So: heim_err.h
+verify_user.So: k524_err.h
+verify_user.So: krb5_err.h
+verify_user.o: heim_err.h
+verify_user.o: k524_err.h
+verify_user.o: krb5_err.h
+verify_user.po: heim_err.h
+verify_user.po: k524_err.h
+verify_user.po: krb5_err.h
+version.So: heim_err.h
+version.So: k524_err.h
+version.So: krb5_err.h
+version.o: heim_err.h
+version.o: k524_err.h
+version.o: krb5_err.h
+version.po: heim_err.h
+version.po: k524_err.h
+version.po: krb5_err.h
+warn.So: heim_err.h
+warn.So: k524_err.h
+warn.So: krb5_err.h
+warn.o: heim_err.h
+warn.o: k524_err.h
+warn.o: krb5_err.h
+warn.po: heim_err.h
+warn.po: k524_err.h
+warn.po: krb5_err.h
+write_message.So: heim_err.h
+write_message.So: k524_err.h
+write_message.So: krb5_err.h
+write_message.o: heim_err.h
+write_message.o: k524_err.h
+write_message.o: krb5_err.h
+write_message.po: heim_err.h
+write_message.po: k524_err.h
+write_message.po: krb5_err.h
+.endif
diff --git a/kerberos5/lib/libroken/Makefile.depend b/kerberos5/lib/libroken/Makefile.depend
new file mode 100644
index 0000000..310aeb9
--- /dev/null
+++ b/kerberos5/lib/libroken/Makefile.depend
@@ -0,0 +1,173 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+bswap.So: roken.h
+bswap.o: roken.h
+bswap.po: roken.h
+cloexec.So: roken.h
+cloexec.o: roken.h
+cloexec.po: roken.h
+concat.So: roken.h
+concat.o: roken.h
+concat.po: roken.h
+copyhostent.So: roken.h
+copyhostent.o: roken.h
+copyhostent.po: roken.h
+ct.So: roken.h
+ct.o: roken.h
+ct.po: roken.h
+dumpdata.So: roken.h
+dumpdata.o: roken.h
+dumpdata.po: roken.h
+ecalloc.So: roken.h
+ecalloc.o: roken.h
+ecalloc.po: roken.h
+emalloc.So: roken.h
+emalloc.o: roken.h
+emalloc.po: roken.h
+environment.So: roken.h
+environment.o: roken.h
+environment.po: roken.h
+eread.So: roken.h
+eread.o: roken.h
+eread.po: roken.h
+erealloc.So: roken.h
+erealloc.o: roken.h
+erealloc.po: roken.h
+esetenv.So: roken.h
+esetenv.o: roken.h
+esetenv.po: roken.h
+estrdup.So: roken.h
+estrdup.o: roken.h
+estrdup.po: roken.h
+ewrite.So: roken.h
+ewrite.o: roken.h
+ewrite.po: roken.h
+get_default_username.So: roken.h
+get_default_username.o: roken.h
+get_default_username.po: roken.h
+get_window_size.So: roken.h
+get_window_size.o: roken.h
+get_window_size.po: roken.h
+getaddrinfo_hostspec.So: roken.h
+getaddrinfo_hostspec.o: roken.h
+getaddrinfo_hostspec.po: roken.h
+getarg.So: roken.h
+getarg.o: roken.h
+getarg.po: roken.h
+getnameinfo_verified.So: roken.h
+getnameinfo_verified.o: roken.h
+getnameinfo_verified.po: roken.h
+getprogname.So: roken.h
+getprogname.o: roken.h
+getprogname.po: roken.h
+hex.So: roken.h
+hex.o: roken.h
+hex.po: roken.h
+hostent_find_fqdn.So: roken.h
+hostent_find_fqdn.o: roken.h
+hostent_find_fqdn.po: roken.h
+issuid.So: roken.h
+issuid.o: roken.h
+issuid.po: roken.h
+k_getpwnam.So: roken.h
+k_getpwnam.o: roken.h
+k_getpwnam.po: roken.h
+k_getpwuid.So: roken.h
+k_getpwuid.o: roken.h
+k_getpwuid.po: roken.h
+mini_inetd.So: roken.h
+mini_inetd.o: roken.h
+mini_inetd.po: roken.h
+net_read.So: roken.h
+net_read.o: roken.h
+net_read.po: roken.h
+net_write.So: roken.h
+net_write.o: roken.h
+net_write.po: roken.h
+parse_units.So: roken.h
+parse_units.o: roken.h
+parse_units.po: roken.h
+rand.So: roken.h
+rand.o: roken.h
+rand.po: roken.h
+realloc.So: roken.h
+realloc.o: roken.h
+realloc.po: roken.h
+resolve.So: roken.h
+resolve.o: roken.h
+resolve.po: roken.h
+roken_gethostby.So: roken.h
+roken_gethostby.o: roken.h
+roken_gethostby.po: roken.h
+rtbl.So: roken.h
+rtbl.o: roken.h
+rtbl.po: roken.h
+setprogname.So: roken.h
+setprogname.o: roken.h
+setprogname.po: roken.h
+signal.So: roken.h
+signal.o: roken.h
+signal.po: roken.h
+simple_exec.So: roken.h
+simple_exec.o: roken.h
+simple_exec.po: roken.h
+snprintf.So: roken.h
+snprintf.o: roken.h
+snprintf.po: roken.h
+socket.So: roken.h
+socket.o: roken.h
+socket.po: roken.h
+strcollect.So: roken.h
+strcollect.o: roken.h
+strcollect.po: roken.h
+strlwr.So: roken.h
+strlwr.o: roken.h
+strlwr.po: roken.h
+strpool.So: roken.h
+strpool.o: roken.h
+strpool.po: roken.h
+strsep_copy.So: roken.h
+strsep_copy.o: roken.h
+strsep_copy.po: roken.h
+strupr.So: roken.h
+strupr.o: roken.h
+strupr.po: roken.h
+timeval.So: roken.h
+timeval.o: roken.h
+timeval.po: roken.h
+tm2time.So: roken.h
+tm2time.o: roken.h
+tm2time.po: roken.h
+unvis.So: roken.h
+unvis.o: roken.h
+unvis.po: roken.h
+verify.So: roken.h
+verify.o: roken.h
+verify.po: roken.h
+vis.So: roken.h
+vis.o: roken.h
+vis.po: roken.h
+warnerr.So: roken.h
+warnerr.o: roken.h
+warnerr.po: roken.h
+write_pid.So: roken.h
+write_pid.o: roken.h
+write_pid.po: roken.h
+xfree.So: roken.h
+xfree.o: roken.h
+xfree.po: roken.h
+.endif
diff --git a/kerberos5/lib/libsl/Makefile.depend b/kerberos5/lib/libsl/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/kerberos5/lib/libsl/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/lib/libvers/Makefile.depend b/kerberos5/lib/libvers/Makefile.depend
new file mode 100644
index 0000000..c42b0d7
--- /dev/null
+++ b/kerberos5/lib/libvers/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+print_version.o: roken.h
+print_version.po: roken.h
+.endif
diff --git a/kerberos5/lib/libwind/Makefile.depend b/kerberos5/lib/libwind/Makefile.depend
new file mode 100644
index 0000000..0c6ce77
--- /dev/null
+++ b/kerberos5/lib/libwind/Makefile.depend
@@ -0,0 +1,57 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libcom_err \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+bidi.So: wind_err.h
+bidi.o: wind_err.h
+bidi.po: wind_err.h
+combining.So: wind_err.h
+combining.o: wind_err.h
+combining.po: wind_err.h
+errorlist.So: wind_err.h
+errorlist.o: wind_err.h
+errorlist.po: wind_err.h
+errorlist_table.So: wind_err.h
+errorlist_table.o: wind_err.h
+errorlist_table.po: wind_err.h
+ldap.So: wind_err.h
+ldap.o: wind_err.h
+ldap.po: wind_err.h
+map.So: wind_err.h
+map.o: wind_err.h
+map.po: wind_err.h
+map_table.So: wind_err.h
+map_table.o: wind_err.h
+map_table.po: wind_err.h
+normalize.So: wind_err.h
+normalize.o: wind_err.h
+normalize.po: wind_err.h
+punycode.So: wind_err.h
+punycode.o: wind_err.h
+punycode.po: wind_err.h
+stringprep.So: wind_err.h
+stringprep.o: wind_err.h
+stringprep.po: wind_err.h
+utf8.So: wind_err.h
+utf8.o: wind_err.h
+utf8.po: wind_err.h
+wind_err.So: wind_err.c
+wind_err.So: wind_err.h
+wind_err.o: wind_err.c
+wind_err.o: wind_err.h
+wind_err.po: wind_err.c
+wind_err.po: wind_err.h
+.endif
diff --git a/kerberos5/libexec/digest-service/Makefile.depend b/kerberos5/libexec/digest-service/Makefile.depend
new file mode 100644
index 0000000..6accfea
--- /dev/null
+++ b/kerberos5/libexec/digest-service/Makefile.depend
@@ -0,0 +1,35 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libheimbase \
+ kerberos5/lib/libheimipcs \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkdc \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ kerberos5/lib/libwind \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/libexec/hprop/Makefile.depend b/kerberos5/libexec/hprop/Makefile.depend
new file mode 100644
index 0000000..c0d0cd8
--- /dev/null
+++ b/kerberos5/libexec/hprop/Makefile.depend
@@ -0,0 +1,34 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libheimbase \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkadm5clnt \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ kerberos5/lib/libwind \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/libexec/hpropd/Makefile.depend b/kerberos5/libexec/hpropd/Makefile.depend
new file mode 100644
index 0000000..339a029
--- /dev/null
+++ b/kerberos5/libexec/hpropd/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libheimbase \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ kerberos5/lib/libwind \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/libexec/ipropd-master/Makefile.depend b/kerberos5/libexec/ipropd-master/Makefile.depend
new file mode 100644
index 0000000..efca2cb
--- /dev/null
+++ b/kerberos5/libexec/ipropd-master/Makefile.depend
@@ -0,0 +1,34 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkadm5srv \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ipropd_common.o: kadm5_err.h
+ipropd_common.po: kadm5_err.h
+ipropd_master.o: kadm5_err.h
+ipropd_master.po: kadm5_err.h
+.endif
diff --git a/kerberos5/libexec/ipropd-slave/Makefile.depend b/kerberos5/libexec/ipropd-slave/Makefile.depend
new file mode 100644
index 0000000..d781849
--- /dev/null
+++ b/kerberos5/libexec/ipropd-slave/Makefile.depend
@@ -0,0 +1,34 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkadm5srv \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ipropd_common.o: kadm5_err.h
+ipropd_common.po: kadm5_err.h
+ipropd_slave.o: kadm5_err.h
+ipropd_slave.po: kadm5_err.h
+.endif
diff --git a/kerberos5/libexec/kadmind/Makefile.depend b/kerberos5/libexec/kadmind/Makefile.depend
new file mode 100644
index 0000000..6ce5fa7
--- /dev/null
+++ b/kerberos5/libexec/kadmind/Makefile.depend
@@ -0,0 +1,36 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/gssapi \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libheimbase \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkadm5clnt \
+ kerberos5/lib/libkadm5srv \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ kerberos5/lib/libwind \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libgssapi \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/libexec/kcm/Makefile.depend b/kerberos5/libexec/kcm/Makefile.depend
new file mode 100644
index 0000000..68fb1c8
--- /dev/null
+++ b/kerberos5/libexec/kcm/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libheimipcs \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/libexec/kdc/Makefile.depend b/kerberos5/libexec/kdc/Makefile.depend
new file mode 100644
index 0000000..657a9c8
--- /dev/null
+++ b/kerberos5/libexec/kdc/Makefile.depend
@@ -0,0 +1,34 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libheimbase \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkdc \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ kerberos5/lib/libwind \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/libexec/kdigest/Makefile.depend b/kerberos5/libexec/kdigest/Makefile.depend
new file mode 100644
index 0000000..507b0dd
--- /dev/null
+++ b/kerberos5/libexec/kdigest/Makefile.depend
@@ -0,0 +1,36 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libkafs5 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libsl \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libedit \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+kdigest-commands.o: kdigest-commands.c
+kdigest-commands.o: kdigest-commands.h
+kdigest-commands.po: kdigest-commands.c
+kdigest-commands.po: kdigest-commands.h
+kdigest.o: kdigest-commands.h
+kdigest.po: kdigest-commands.h
+.endif
diff --git a/kerberos5/libexec/kfd/Makefile.depend b/kerberos5/libexec/kfd/Makefile.depend
new file mode 100644
index 0000000..12d14d0
--- /dev/null
+++ b/kerberos5/libexec/kfd/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/libexec/kimpersonate/Makefile.depend b/kerberos5/libexec/kimpersonate/Makefile.depend
new file mode 100644
index 0000000..d7dceac
--- /dev/null
+++ b/kerberos5/libexec/kimpersonate/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libkafs5 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/libexec/kpasswdd/Makefile.depend b/kerberos5/libexec/kpasswdd/Makefile.depend
new file mode 100644
index 0000000..4670d04
--- /dev/null
+++ b/kerberos5/libexec/kpasswdd/Makefile.depend
@@ -0,0 +1,32 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkadm5clnt \
+ kerberos5/lib/libkadm5srv \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/tools/asn1_compile/Makefile.depend b/kerberos5/tools/asn1_compile/Makefile.depend
new file mode 100644
index 0000000..a7637fb
--- /dev/null
+++ b/kerberos5/tools/asn1_compile/Makefile.depend
@@ -0,0 +1,56 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+asn1parse.o: asn1parse.c
+asn1parse.o: roken.h
+asn1parse.po: asn1parse.c
+asn1parse.po: roken.h
+gen.o: roken.h
+gen.po: roken.h
+gen_copy.o: roken.h
+gen_copy.po: roken.h
+gen_decode.o: roken.h
+gen_decode.po: roken.h
+gen_encode.o: roken.h
+gen_encode.po: roken.h
+gen_free.o: roken.h
+gen_free.po: roken.h
+gen_glue.o: roken.h
+gen_glue.po: roken.h
+gen_length.o: roken.h
+gen_length.po: roken.h
+gen_seq.o: roken.h
+gen_seq.po: roken.h
+gen_template.o: roken.h
+gen_template.po: roken.h
+hash.o: roken.h
+hash.po: roken.h
+lex.o: asn1parse.h
+lex.o: lex.c
+lex.o: roken.h
+lex.po: asn1parse.h
+lex.po: lex.c
+lex.po: roken.h
+main.o: roken.h
+main.po: roken.h
+symbol.o: roken.h
+symbol.po: roken.h
+.endif
diff --git a/kerberos5/tools/make-roken/Makefile.depend b/kerberos5/tools/make-roken/Makefile.depend
new file mode 100644
index 0000000..d0e44c1
--- /dev/null
+++ b/kerberos5/tools/make-roken/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+make-roken.o: make-roken.c
+make-roken.po: make-roken.c
+.endif
diff --git a/kerberos5/tools/slc/Makefile.depend b/kerberos5/tools/slc/Makefile.depend
new file mode 100644
index 0000000..55e399c
--- /dev/null
+++ b/kerberos5/tools/slc/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+slc-gram.o: roken.h
+slc-gram.o: slc-gram.c
+slc-gram.po: roken.h
+slc-gram.po: slc-gram.c
+slc-lex.o: slc-gram.h
+slc-lex.o: slc-lex.c
+slc-lex.po: slc-gram.h
+slc-lex.po: slc-lex.c
+.endif
diff --git a/kerberos5/usr.bin/hxtool/Makefile.depend b/kerberos5/usr.bin/hxtool/Makefile.depend
new file mode 100644
index 0000000..ba8c2c0
--- /dev/null
+++ b/kerberos5/usr.bin/hxtool/Makefile.depend
@@ -0,0 +1,35 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libsl \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libedit \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+hxtool-commands.o: hxtool-commands.c
+hxtool-commands.o: hxtool-commands.h
+hxtool-commands.po: hxtool-commands.c
+hxtool-commands.po: hxtool-commands.h
+hxtool.o: hxtool-commands.h
+hxtool.po: hxtool-commands.h
+.endif
diff --git a/kerberos5/usr.bin/kadmin/Makefile.depend b/kerberos5/usr.bin/kadmin/Makefile.depend
new file mode 100644
index 0000000..c52f7bb
--- /dev/null
+++ b/kerberos5/usr.bin/kadmin/Makefile.depend
@@ -0,0 +1,73 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libheimbase \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkadm5clnt \
+ kerberos5/lib/libkadm5srv \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libsl \
+ kerberos5/lib/libvers \
+ kerberos5/lib/libwind \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libedit \
+ lib/libutil \
+ lib/ncurses/ncurses \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+add_enctype.o: kadmin-commands.h
+add_enctype.po: kadmin-commands.h
+ank.o: kadmin-commands.h
+ank.po: kadmin-commands.h
+check.o: kadmin-commands.h
+check.po: kadmin-commands.h
+cpw.o: kadmin-commands.h
+cpw.po: kadmin-commands.h
+del.o: kadmin-commands.h
+del.po: kadmin-commands.h
+del_enctype.o: kadmin-commands.h
+del_enctype.po: kadmin-commands.h
+dump.o: kadmin-commands.h
+dump.po: kadmin-commands.h
+ext.o: kadmin-commands.h
+ext.po: kadmin-commands.h
+get.o: kadmin-commands.h
+get.po: kadmin-commands.h
+init.o: kadmin-commands.h
+init.po: kadmin-commands.h
+kadmin-commands.o: kadmin-commands.c
+kadmin-commands.o: kadmin-commands.h
+kadmin-commands.po: kadmin-commands.c
+kadmin-commands.po: kadmin-commands.h
+kadmin.o: kadmin-commands.h
+kadmin.po: kadmin-commands.h
+load.o: kadmin-commands.h
+load.po: kadmin-commands.h
+mod.o: kadmin-commands.h
+mod.po: kadmin-commands.h
+pw_quality.o: kadmin-commands.h
+pw_quality.po: kadmin-commands.h
+rename.o: kadmin-commands.h
+rename.po: kadmin-commands.h
+stash.o: kadmin-commands.h
+stash.po: kadmin-commands.h
+.endif
diff --git a/kerberos5/usr.bin/kcc/Makefile.depend b/kerberos5/usr.bin/kcc/Makefile.depend
new file mode 100644
index 0000000..afb519d
--- /dev/null
+++ b/kerberos5/usr.bin/kcc/Makefile.depend
@@ -0,0 +1,42 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libkafs5 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libsl \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libedit \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+copy_cred_cache.o: kcc-commands.h
+copy_cred_cache.po: kcc-commands.h
+kcc-commands.o: kcc-commands.c
+kcc-commands.o: kcc-commands.h
+kcc-commands.po: kcc-commands.c
+kcc-commands.po: kcc-commands.h
+kcc.o: kcc-commands.h
+kcc.po: kcc-commands.h
+klist.o: kcc-commands.h
+klist.po: kcc-commands.h
+kswitch.o: kcc-commands.h
+kswitch.po: kcc-commands.h
+.endif
diff --git a/kerberos5/usr.bin/kdestroy/Makefile.depend b/kerberos5/usr.bin/kdestroy/Makefile.depend
new file mode 100644
index 0000000..d7dceac
--- /dev/null
+++ b/kerberos5/usr.bin/kdestroy/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libkafs5 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/usr.bin/kf/Makefile.depend b/kerberos5/usr.bin/kf/Makefile.depend
new file mode 100644
index 0000000..12d14d0
--- /dev/null
+++ b/kerberos5/usr.bin/kf/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/usr.bin/kgetcred/Makefile.depend b/kerberos5/usr.bin/kgetcred/Makefile.depend
new file mode 100644
index 0000000..127ffd0
--- /dev/null
+++ b/kerberos5/usr.bin/kgetcred/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libkafs5 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/usr.bin/kinit/Makefile.depend b/kerberos5/usr.bin/kinit/Makefile.depend
new file mode 100644
index 0000000..103c896
--- /dev/null
+++ b/kerberos5/usr.bin/kinit/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libkafs5 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/usr.bin/kpasswd/Makefile.depend b/kerberos5/usr.bin/kpasswd/Makefile.depend
new file mode 100644
index 0000000..8c8f335
--- /dev/null
+++ b/kerberos5/usr.bin/kpasswd/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/usr.bin/krb5-config/Makefile.depend b/kerberos5/usr.bin/krb5-config/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/kerberos5/usr.bin/krb5-config/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/usr.bin/ksu/Makefile.depend b/kerberos5/usr.bin/ksu/Makefile.depend
new file mode 100644
index 0000000..4bb43fa
--- /dev/null
+++ b/kerberos5/usr.bin/ksu/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkafs5 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/usr.bin/string2key/Makefile.depend b/kerberos5/usr.bin/string2key/Makefile.depend
new file mode 100644
index 0000000..339a029
--- /dev/null
+++ b/kerberos5/usr.bin/string2key/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libheimbase \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ kerberos5/lib/libwind \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/usr.bin/verify_krb5_conf/Makefile.depend b/kerberos5/usr.bin/verify_krb5_conf/Makefile.depend
new file mode 100644
index 0000000..a5015d7
--- /dev/null
+++ b/kerberos5/usr.bin/verify_krb5_conf/Makefile.depend
@@ -0,0 +1,31 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libheimbase \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkafs5 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ kerberos5/lib/libwind \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/usr.sbin/iprop-log/Makefile.depend b/kerberos5/usr.sbin/iprop-log/Makefile.depend
new file mode 100644
index 0000000..85d7298
--- /dev/null
+++ b/kerberos5/usr.sbin/iprop-log/Makefile.depend
@@ -0,0 +1,38 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libkadm5srv \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libsl \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libedit \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+iprop-commands.o: iprop-commands.c
+iprop-commands.o: iprop-commands.h
+iprop-commands.po: iprop-commands.c
+iprop-commands.po: iprop-commands.h
+iprop-log.o: iprop-commands.h
+iprop-log.o: kadm5_err.h
+iprop-log.po: iprop-commands.h
+iprop-log.po: kadm5_err.h
+.endif
diff --git a/kerberos5/usr.sbin/kstash/Makefile.depend b/kerberos5/usr.sbin/kstash/Makefile.depend
new file mode 100644
index 0000000..339a029
--- /dev/null
+++ b/kerberos5/usr.sbin/kstash/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhdb \
+ kerberos5/lib/libheimbase \
+ kerberos5/lib/libheimntlm \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ kerberos5/lib/libwind \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/kerberos5/usr.sbin/ktutil/Makefile.depend b/kerberos5/usr.sbin/ktutil/Makefile.depend
new file mode 100644
index 0000000..bb8333d
--- /dev/null
+++ b/kerberos5/usr.sbin/ktutil/Makefile.depend
@@ -0,0 +1,53 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libkadm5clnt \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libsl \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libedit \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+add.o: ktutil-commands.h
+add.po: ktutil-commands.h
+change.o: ktutil-commands.h
+change.po: ktutil-commands.h
+copy.o: ktutil-commands.h
+copy.po: ktutil-commands.h
+destroy.o: ktutil-commands.h
+destroy.po: ktutil-commands.h
+get.o: ktutil-commands.h
+get.po: ktutil-commands.h
+ktutil-commands.o: ktutil-commands.c
+ktutil-commands.o: ktutil-commands.h
+ktutil-commands.po: ktutil-commands.c
+ktutil-commands.po: ktutil-commands.h
+ktutil.o: ktutil-commands.h
+ktutil.po: ktutil-commands.h
+list.o: ktutil-commands.h
+list.po: ktutil-commands.h
+purge.o: ktutil-commands.h
+purge.po: ktutil-commands.h
+remove.o: ktutil-commands.h
+remove.po: ktutil-commands.h
+rename.o: ktutil-commands.h
+rename.po: ktutil-commands.h
+.endif
diff --git a/lib/bind/bind9/Makefile.depend b/lib/bind/bind9/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/bind/bind9/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/bind/dns/Makefile.depend b/lib/bind/dns/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/bind/dns/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/bind/isc/Makefile.depend b/lib/bind/isc/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/bind/isc/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/bind/isccc/Makefile.depend b/lib/bind/isccc/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/bind/isccc/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/bind/isccfg/Makefile.depend b/lib/bind/isccfg/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/bind/isccfg/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/bind/lwres/Makefile.depend b/lib/bind/lwres/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/bind/lwres/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/include/Makefile.depend b/lib/clang/include/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/lib/clang/include/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libclanganalysis/Makefile.depend b/lib/clang/libclanganalysis/Makefile.depend
new file mode 100644
index 0000000..372e3ca
--- /dev/null
+++ b/lib/clang/libclanganalysis/Makefile.depend
@@ -0,0 +1,179 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+AnalysisDeclContext.o: AttrList.inc.h
+AnalysisDeclContext.o: Attrs.inc.h
+AnalysisDeclContext.o: DeclNodes.inc.h
+AnalysisDeclContext.o: DiagnosticCommonKinds.inc.h
+AnalysisDeclContext.o: StmtNodes.inc.h
+AnalysisDeclContext.po: AttrList.inc.h
+AnalysisDeclContext.po: Attrs.inc.h
+AnalysisDeclContext.po: DeclNodes.inc.h
+AnalysisDeclContext.po: DiagnosticCommonKinds.inc.h
+AnalysisDeclContext.po: StmtNodes.inc.h
+CFG.o: AttrList.inc.h
+CFG.o: Attrs.inc.h
+CFG.o: DeclNodes.inc.h
+CFG.o: DiagnosticCommonKinds.inc.h
+CFG.o: StmtNodes.inc.h
+CFG.po: AttrList.inc.h
+CFG.po: Attrs.inc.h
+CFG.po: DeclNodes.inc.h
+CFG.po: DiagnosticCommonKinds.inc.h
+CFG.po: StmtNodes.inc.h
+CFGReachabilityAnalysis.o: AttrList.inc.h
+CFGReachabilityAnalysis.o: Attrs.inc.h
+CFGReachabilityAnalysis.o: DeclNodes.inc.h
+CFGReachabilityAnalysis.o: DiagnosticCommonKinds.inc.h
+CFGReachabilityAnalysis.o: StmtNodes.inc.h
+CFGReachabilityAnalysis.po: AttrList.inc.h
+CFGReachabilityAnalysis.po: Attrs.inc.h
+CFGReachabilityAnalysis.po: DeclNodes.inc.h
+CFGReachabilityAnalysis.po: DiagnosticCommonKinds.inc.h
+CFGReachabilityAnalysis.po: StmtNodes.inc.h
+CFGStmtMap.o: AttrList.inc.h
+CFGStmtMap.o: Attrs.inc.h
+CFGStmtMap.o: DeclNodes.inc.h
+CFGStmtMap.o: DiagnosticCommonKinds.inc.h
+CFGStmtMap.o: StmtNodes.inc.h
+CFGStmtMap.po: AttrList.inc.h
+CFGStmtMap.po: Attrs.inc.h
+CFGStmtMap.po: DeclNodes.inc.h
+CFGStmtMap.po: DiagnosticCommonKinds.inc.h
+CFGStmtMap.po: StmtNodes.inc.h
+CallGraph.o: AttrList.inc.h
+CallGraph.o: Attrs.inc.h
+CallGraph.o: DeclNodes.inc.h
+CallGraph.o: DiagnosticCommonKinds.inc.h
+CallGraph.o: StmtNodes.inc.h
+CallGraph.po: AttrList.inc.h
+CallGraph.po: Attrs.inc.h
+CallGraph.po: DeclNodes.inc.h
+CallGraph.po: DiagnosticCommonKinds.inc.h
+CallGraph.po: StmtNodes.inc.h
+CocoaConventions.o: AttrList.inc.h
+CocoaConventions.o: Attrs.inc.h
+CocoaConventions.o: DeclNodes.inc.h
+CocoaConventions.o: DiagnosticCommonKinds.inc.h
+CocoaConventions.po: AttrList.inc.h
+CocoaConventions.po: Attrs.inc.h
+CocoaConventions.po: DeclNodes.inc.h
+CocoaConventions.po: DiagnosticCommonKinds.inc.h
+Dominators.o: AttrList.inc.h
+Dominators.o: Attrs.inc.h
+Dominators.o: DeclNodes.inc.h
+Dominators.o: DiagnosticCommonKinds.inc.h
+Dominators.o: StmtNodes.inc.h
+Dominators.po: AttrList.inc.h
+Dominators.po: Attrs.inc.h
+Dominators.po: DeclNodes.inc.h
+Dominators.po: DiagnosticCommonKinds.inc.h
+Dominators.po: StmtNodes.inc.h
+FormatString.o: AttrList.inc.h
+FormatString.o: Attrs.inc.h
+FormatString.o: DeclNodes.inc.h
+FormatString.o: DiagnosticCommonKinds.inc.h
+FormatString.po: AttrList.inc.h
+FormatString.po: Attrs.inc.h
+FormatString.po: DeclNodes.inc.h
+FormatString.po: DiagnosticCommonKinds.inc.h
+LiveVariables.o: AttrList.inc.h
+LiveVariables.o: Attrs.inc.h
+LiveVariables.o: DeclNodes.inc.h
+LiveVariables.o: DiagnosticCommonKinds.inc.h
+LiveVariables.o: StmtNodes.inc.h
+LiveVariables.po: AttrList.inc.h
+LiveVariables.po: Attrs.inc.h
+LiveVariables.po: DeclNodes.inc.h
+LiveVariables.po: DiagnosticCommonKinds.inc.h
+LiveVariables.po: StmtNodes.inc.h
+PostOrderCFGView.o: AttrList.inc.h
+PostOrderCFGView.o: Attrs.inc.h
+PostOrderCFGView.o: DeclNodes.inc.h
+PostOrderCFGView.o: DiagnosticCommonKinds.inc.h
+PostOrderCFGView.o: StmtNodes.inc.h
+PostOrderCFGView.po: AttrList.inc.h
+PostOrderCFGView.po: Attrs.inc.h
+PostOrderCFGView.po: DeclNodes.inc.h
+PostOrderCFGView.po: DiagnosticCommonKinds.inc.h
+PostOrderCFGView.po: StmtNodes.inc.h
+PrintfFormatString.o: AttrList.inc.h
+PrintfFormatString.o: Attrs.inc.h
+PrintfFormatString.o: DeclNodes.inc.h
+PrintfFormatString.o: DiagnosticCommonKinds.inc.h
+PrintfFormatString.po: AttrList.inc.h
+PrintfFormatString.po: Attrs.inc.h
+PrintfFormatString.po: DeclNodes.inc.h
+PrintfFormatString.po: DiagnosticCommonKinds.inc.h
+ProgramPoint.o: AttrList.inc.h
+ProgramPoint.o: Attrs.inc.h
+ProgramPoint.o: DeclNodes.inc.h
+ProgramPoint.o: DiagnosticCommonKinds.inc.h
+ProgramPoint.o: StmtNodes.inc.h
+ProgramPoint.po: AttrList.inc.h
+ProgramPoint.po: Attrs.inc.h
+ProgramPoint.po: DeclNodes.inc.h
+ProgramPoint.po: DiagnosticCommonKinds.inc.h
+ProgramPoint.po: StmtNodes.inc.h
+PseudoConstantAnalysis.o: AttrList.inc.h
+PseudoConstantAnalysis.o: Attrs.inc.h
+PseudoConstantAnalysis.o: DeclNodes.inc.h
+PseudoConstantAnalysis.o: DiagnosticCommonKinds.inc.h
+PseudoConstantAnalysis.o: StmtNodes.inc.h
+PseudoConstantAnalysis.po: AttrList.inc.h
+PseudoConstantAnalysis.po: Attrs.inc.h
+PseudoConstantAnalysis.po: DeclNodes.inc.h
+PseudoConstantAnalysis.po: DiagnosticCommonKinds.inc.h
+PseudoConstantAnalysis.po: StmtNodes.inc.h
+ReachableCode.o: AttrList.inc.h
+ReachableCode.o: Attrs.inc.h
+ReachableCode.o: DeclNodes.inc.h
+ReachableCode.o: DiagnosticCommonKinds.inc.h
+ReachableCode.o: StmtNodes.inc.h
+ReachableCode.po: AttrList.inc.h
+ReachableCode.po: Attrs.inc.h
+ReachableCode.po: DeclNodes.inc.h
+ReachableCode.po: DiagnosticCommonKinds.inc.h
+ReachableCode.po: StmtNodes.inc.h
+ScanfFormatString.o: AttrList.inc.h
+ScanfFormatString.o: Attrs.inc.h
+ScanfFormatString.o: DeclNodes.inc.h
+ScanfFormatString.o: DiagnosticCommonKinds.inc.h
+ScanfFormatString.po: AttrList.inc.h
+ScanfFormatString.po: Attrs.inc.h
+ScanfFormatString.po: DeclNodes.inc.h
+ScanfFormatString.po: DiagnosticCommonKinds.inc.h
+ThreadSafety.o: AttrList.inc.h
+ThreadSafety.o: Attrs.inc.h
+ThreadSafety.o: DeclNodes.inc.h
+ThreadSafety.o: DiagnosticCommonKinds.inc.h
+ThreadSafety.o: StmtNodes.inc.h
+ThreadSafety.po: AttrList.inc.h
+ThreadSafety.po: Attrs.inc.h
+ThreadSafety.po: DeclNodes.inc.h
+ThreadSafety.po: DiagnosticCommonKinds.inc.h
+ThreadSafety.po: StmtNodes.inc.h
+UninitializedValues.o: AttrList.inc.h
+UninitializedValues.o: Attrs.inc.h
+UninitializedValues.o: DeclNodes.inc.h
+UninitializedValues.o: DiagnosticCommonKinds.inc.h
+UninitializedValues.o: StmtNodes.inc.h
+UninitializedValues.po: AttrList.inc.h
+UninitializedValues.po: Attrs.inc.h
+UninitializedValues.po: DeclNodes.inc.h
+UninitializedValues.po: DiagnosticCommonKinds.inc.h
+UninitializedValues.po: StmtNodes.inc.h
+.endif
diff --git a/lib/clang/libclangarcmigrate/Makefile.depend b/lib/clang/libclangarcmigrate/Makefile.depend
new file mode 100644
index 0000000..ba37a31c
--- /dev/null
+++ b/lib/clang/libclangarcmigrate/Makefile.depend
@@ -0,0 +1,209 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ARCMT.o: AttrList.inc.h
+ARCMT.o: AttrParsedAttrList.inc.h
+ARCMT.o: Attrs.inc.h
+ARCMT.o: DeclNodes.inc.h
+ARCMT.o: DiagnosticCommonKinds.inc.h
+ARCMT.o: DiagnosticGroups.inc.h
+ARCMT.o: DiagnosticSemaKinds.inc.h
+ARCMT.o: StmtNodes.inc.h
+ARCMT.po: AttrList.inc.h
+ARCMT.po: AttrParsedAttrList.inc.h
+ARCMT.po: Attrs.inc.h
+ARCMT.po: DeclNodes.inc.h
+ARCMT.po: DiagnosticCommonKinds.inc.h
+ARCMT.po: DiagnosticGroups.inc.h
+ARCMT.po: DiagnosticSemaKinds.inc.h
+ARCMT.po: StmtNodes.inc.h
+ARCMTActions.o: DiagnosticCommonKinds.inc.h
+ARCMTActions.po: DiagnosticCommonKinds.inc.h
+FileRemapper.o: DiagnosticCommonKinds.inc.h
+FileRemapper.po: DiagnosticCommonKinds.inc.h
+ObjCMT.o: AttrList.inc.h
+ObjCMT.o: Attrs.inc.h
+ObjCMT.o: DeclNodes.inc.h
+ObjCMT.o: DiagnosticCommonKinds.inc.h
+ObjCMT.o: StmtNodes.inc.h
+ObjCMT.po: AttrList.inc.h
+ObjCMT.po: Attrs.inc.h
+ObjCMT.po: DeclNodes.inc.h
+ObjCMT.po: DiagnosticCommonKinds.inc.h
+ObjCMT.po: StmtNodes.inc.h
+PlistReporter.o: DiagnosticCommonKinds.inc.h
+PlistReporter.po: DiagnosticCommonKinds.inc.h
+TransAPIUses.o: AttrList.inc.h
+TransAPIUses.o: Attrs.inc.h
+TransAPIUses.o: DeclNodes.inc.h
+TransAPIUses.o: DiagnosticCommonKinds.inc.h
+TransAPIUses.o: DiagnosticSemaKinds.inc.h
+TransAPIUses.o: StmtNodes.inc.h
+TransAPIUses.po: AttrList.inc.h
+TransAPIUses.po: Attrs.inc.h
+TransAPIUses.po: DeclNodes.inc.h
+TransAPIUses.po: DiagnosticCommonKinds.inc.h
+TransAPIUses.po: DiagnosticSemaKinds.inc.h
+TransAPIUses.po: StmtNodes.inc.h
+TransARCAssign.o: AttrList.inc.h
+TransARCAssign.o: Attrs.inc.h
+TransARCAssign.o: DeclNodes.inc.h
+TransARCAssign.o: DiagnosticCommonKinds.inc.h
+TransARCAssign.o: DiagnosticSemaKinds.inc.h
+TransARCAssign.o: StmtNodes.inc.h
+TransARCAssign.po: AttrList.inc.h
+TransARCAssign.po: Attrs.inc.h
+TransARCAssign.po: DeclNodes.inc.h
+TransARCAssign.po: DiagnosticCommonKinds.inc.h
+TransARCAssign.po: DiagnosticSemaKinds.inc.h
+TransARCAssign.po: StmtNodes.inc.h
+TransAutoreleasePool.o: AttrList.inc.h
+TransAutoreleasePool.o: Attrs.inc.h
+TransAutoreleasePool.o: DeclNodes.inc.h
+TransAutoreleasePool.o: DiagnosticCommonKinds.inc.h
+TransAutoreleasePool.o: DiagnosticSemaKinds.inc.h
+TransAutoreleasePool.o: StmtNodes.inc.h
+TransAutoreleasePool.po: AttrList.inc.h
+TransAutoreleasePool.po: Attrs.inc.h
+TransAutoreleasePool.po: DeclNodes.inc.h
+TransAutoreleasePool.po: DiagnosticCommonKinds.inc.h
+TransAutoreleasePool.po: DiagnosticSemaKinds.inc.h
+TransAutoreleasePool.po: StmtNodes.inc.h
+TransBlockObjCVariable.o: AttrList.inc.h
+TransBlockObjCVariable.o: Attrs.inc.h
+TransBlockObjCVariable.o: DeclNodes.inc.h
+TransBlockObjCVariable.o: DiagnosticCommonKinds.inc.h
+TransBlockObjCVariable.o: StmtNodes.inc.h
+TransBlockObjCVariable.po: AttrList.inc.h
+TransBlockObjCVariable.po: Attrs.inc.h
+TransBlockObjCVariable.po: DeclNodes.inc.h
+TransBlockObjCVariable.po: DiagnosticCommonKinds.inc.h
+TransBlockObjCVariable.po: StmtNodes.inc.h
+TransEmptyStatementsAndDealloc.o: AttrList.inc.h
+TransEmptyStatementsAndDealloc.o: Attrs.inc.h
+TransEmptyStatementsAndDealloc.o: DeclNodes.inc.h
+TransEmptyStatementsAndDealloc.o: DiagnosticCommonKinds.inc.h
+TransEmptyStatementsAndDealloc.o: StmtNodes.inc.h
+TransEmptyStatementsAndDealloc.po: AttrList.inc.h
+TransEmptyStatementsAndDealloc.po: Attrs.inc.h
+TransEmptyStatementsAndDealloc.po: DeclNodes.inc.h
+TransEmptyStatementsAndDealloc.po: DiagnosticCommonKinds.inc.h
+TransEmptyStatementsAndDealloc.po: StmtNodes.inc.h
+TransGCAttrs.o: AttrList.inc.h
+TransGCAttrs.o: Attrs.inc.h
+TransGCAttrs.o: DeclNodes.inc.h
+TransGCAttrs.o: DiagnosticCommonKinds.inc.h
+TransGCAttrs.o: DiagnosticSemaKinds.inc.h
+TransGCAttrs.o: StmtNodes.inc.h
+TransGCAttrs.po: AttrList.inc.h
+TransGCAttrs.po: Attrs.inc.h
+TransGCAttrs.po: DeclNodes.inc.h
+TransGCAttrs.po: DiagnosticCommonKinds.inc.h
+TransGCAttrs.po: DiagnosticSemaKinds.inc.h
+TransGCAttrs.po: StmtNodes.inc.h
+TransGCCalls.o: AttrList.inc.h
+TransGCCalls.o: Attrs.inc.h
+TransGCCalls.o: DeclNodes.inc.h
+TransGCCalls.o: DiagnosticCommonKinds.inc.h
+TransGCCalls.o: DiagnosticSemaKinds.inc.h
+TransGCCalls.o: StmtNodes.inc.h
+TransGCCalls.po: AttrList.inc.h
+TransGCCalls.po: Attrs.inc.h
+TransGCCalls.po: DeclNodes.inc.h
+TransGCCalls.po: DiagnosticCommonKinds.inc.h
+TransGCCalls.po: DiagnosticSemaKinds.inc.h
+TransGCCalls.po: StmtNodes.inc.h
+TransProperties.o: AttrList.inc.h
+TransProperties.o: Attrs.inc.h
+TransProperties.o: DeclNodes.inc.h
+TransProperties.o: DiagnosticCommonKinds.inc.h
+TransProperties.o: DiagnosticSemaKinds.inc.h
+TransProperties.o: StmtNodes.inc.h
+TransProperties.po: AttrList.inc.h
+TransProperties.po: Attrs.inc.h
+TransProperties.po: DeclNodes.inc.h
+TransProperties.po: DiagnosticCommonKinds.inc.h
+TransProperties.po: DiagnosticSemaKinds.inc.h
+TransProperties.po: StmtNodes.inc.h
+TransRetainReleaseDealloc.o: AttrList.inc.h
+TransRetainReleaseDealloc.o: Attrs.inc.h
+TransRetainReleaseDealloc.o: DeclNodes.inc.h
+TransRetainReleaseDealloc.o: DiagnosticCommonKinds.inc.h
+TransRetainReleaseDealloc.o: DiagnosticSemaKinds.inc.h
+TransRetainReleaseDealloc.o: StmtNodes.inc.h
+TransRetainReleaseDealloc.po: AttrList.inc.h
+TransRetainReleaseDealloc.po: Attrs.inc.h
+TransRetainReleaseDealloc.po: DeclNodes.inc.h
+TransRetainReleaseDealloc.po: DiagnosticCommonKinds.inc.h
+TransRetainReleaseDealloc.po: DiagnosticSemaKinds.inc.h
+TransRetainReleaseDealloc.po: StmtNodes.inc.h
+TransUnbridgedCasts.o: AttrList.inc.h
+TransUnbridgedCasts.o: Attrs.inc.h
+TransUnbridgedCasts.o: DeclNodes.inc.h
+TransUnbridgedCasts.o: DiagnosticCommonKinds.inc.h
+TransUnbridgedCasts.o: DiagnosticSemaKinds.inc.h
+TransUnbridgedCasts.o: StmtNodes.inc.h
+TransUnbridgedCasts.po: AttrList.inc.h
+TransUnbridgedCasts.po: Attrs.inc.h
+TransUnbridgedCasts.po: DeclNodes.inc.h
+TransUnbridgedCasts.po: DiagnosticCommonKinds.inc.h
+TransUnbridgedCasts.po: DiagnosticSemaKinds.inc.h
+TransUnbridgedCasts.po: StmtNodes.inc.h
+TransUnusedInitDelegate.o: AttrList.inc.h
+TransUnusedInitDelegate.o: Attrs.inc.h
+TransUnusedInitDelegate.o: DeclNodes.inc.h
+TransUnusedInitDelegate.o: DiagnosticCommonKinds.inc.h
+TransUnusedInitDelegate.o: DiagnosticSemaKinds.inc.h
+TransUnusedInitDelegate.o: StmtNodes.inc.h
+TransUnusedInitDelegate.po: AttrList.inc.h
+TransUnusedInitDelegate.po: Attrs.inc.h
+TransUnusedInitDelegate.po: DeclNodes.inc.h
+TransUnusedInitDelegate.po: DiagnosticCommonKinds.inc.h
+TransUnusedInitDelegate.po: DiagnosticSemaKinds.inc.h
+TransUnusedInitDelegate.po: StmtNodes.inc.h
+TransZeroOutPropsInDealloc.o: AttrList.inc.h
+TransZeroOutPropsInDealloc.o: Attrs.inc.h
+TransZeroOutPropsInDealloc.o: DeclNodes.inc.h
+TransZeroOutPropsInDealloc.o: DiagnosticCommonKinds.inc.h
+TransZeroOutPropsInDealloc.o: StmtNodes.inc.h
+TransZeroOutPropsInDealloc.po: AttrList.inc.h
+TransZeroOutPropsInDealloc.po: Attrs.inc.h
+TransZeroOutPropsInDealloc.po: DeclNodes.inc.h
+TransZeroOutPropsInDealloc.po: DiagnosticCommonKinds.inc.h
+TransZeroOutPropsInDealloc.po: StmtNodes.inc.h
+TransformActions.o: AttrList.inc.h
+TransformActions.o: Attrs.inc.h
+TransformActions.o: DeclNodes.inc.h
+TransformActions.o: DiagnosticCommonKinds.inc.h
+TransformActions.o: StmtNodes.inc.h
+TransformActions.po: AttrList.inc.h
+TransformActions.po: Attrs.inc.h
+TransformActions.po: DeclNodes.inc.h
+TransformActions.po: DiagnosticCommonKinds.inc.h
+TransformActions.po: StmtNodes.inc.h
+Transforms.o: AttrList.inc.h
+Transforms.o: Attrs.inc.h
+Transforms.o: DeclNodes.inc.h
+Transforms.o: DiagnosticCommonKinds.inc.h
+Transforms.o: DiagnosticSemaKinds.inc.h
+Transforms.o: StmtNodes.inc.h
+Transforms.po: AttrList.inc.h
+Transforms.po: Attrs.inc.h
+Transforms.po: DeclNodes.inc.h
+Transforms.po: DiagnosticCommonKinds.inc.h
+Transforms.po: DiagnosticSemaKinds.inc.h
+Transforms.po: StmtNodes.inc.h
+.endif
diff --git a/lib/clang/libclangast/Makefile.depend b/lib/clang/libclangast/Makefile.depend
new file mode 100644
index 0000000..b15ee05
--- /dev/null
+++ b/lib/clang/libclangast/Makefile.depend
@@ -0,0 +1,489 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+APValue.o: AttrList.inc.h
+APValue.o: Attrs.inc.h
+APValue.o: DeclNodes.inc.h
+APValue.o: DiagnosticCommonKinds.inc.h
+APValue.o: StmtNodes.inc.h
+APValue.po: AttrList.inc.h
+APValue.po: Attrs.inc.h
+APValue.po: DeclNodes.inc.h
+APValue.po: DiagnosticCommonKinds.inc.h
+APValue.po: StmtNodes.inc.h
+ASTContext.o: AttrList.inc.h
+ASTContext.o: Attrs.inc.h
+ASTContext.o: DeclNodes.inc.h
+ASTContext.o: DiagnosticCommonKinds.inc.h
+ASTContext.o: StmtNodes.inc.h
+ASTContext.po: AttrList.inc.h
+ASTContext.po: Attrs.inc.h
+ASTContext.po: DeclNodes.inc.h
+ASTContext.po: DiagnosticCommonKinds.inc.h
+ASTContext.po: StmtNodes.inc.h
+ASTDiagnostic.o: AttrList.inc.h
+ASTDiagnostic.o: Attrs.inc.h
+ASTDiagnostic.o: DeclNodes.inc.h
+ASTDiagnostic.o: DiagnosticASTKinds.inc.h
+ASTDiagnostic.o: DiagnosticCommonKinds.inc.h
+ASTDiagnostic.po: AttrList.inc.h
+ASTDiagnostic.po: Attrs.inc.h
+ASTDiagnostic.po: DeclNodes.inc.h
+ASTDiagnostic.po: DiagnosticASTKinds.inc.h
+ASTDiagnostic.po: DiagnosticCommonKinds.inc.h
+ASTImporter.o: AttrList.inc.h
+ASTImporter.o: Attrs.inc.h
+ASTImporter.o: DeclNodes.inc.h
+ASTImporter.o: DiagnosticASTKinds.inc.h
+ASTImporter.o: DiagnosticCommonKinds.inc.h
+ASTImporter.o: StmtNodes.inc.h
+ASTImporter.po: AttrList.inc.h
+ASTImporter.po: Attrs.inc.h
+ASTImporter.po: DeclNodes.inc.h
+ASTImporter.po: DiagnosticASTKinds.inc.h
+ASTImporter.po: DiagnosticCommonKinds.inc.h
+ASTImporter.po: StmtNodes.inc.h
+AttrImpl.o: AttrImpl.inc.h
+AttrImpl.o: AttrList.inc.h
+AttrImpl.o: Attrs.inc.h
+AttrImpl.o: DeclNodes.inc.h
+AttrImpl.o: DiagnosticCommonKinds.inc.h
+AttrImpl.o: StmtNodes.inc.h
+AttrImpl.po: AttrImpl.inc.h
+AttrImpl.po: AttrList.inc.h
+AttrImpl.po: Attrs.inc.h
+AttrImpl.po: DeclNodes.inc.h
+AttrImpl.po: DiagnosticCommonKinds.inc.h
+AttrImpl.po: StmtNodes.inc.h
+CXXInheritance.o: AttrList.inc.h
+CXXInheritance.o: Attrs.inc.h
+CXXInheritance.o: DeclNodes.inc.h
+CXXInheritance.o: DiagnosticCommonKinds.inc.h
+CXXInheritance.o: StmtNodes.inc.h
+CXXInheritance.po: AttrList.inc.h
+CXXInheritance.po: Attrs.inc.h
+CXXInheritance.po: DeclNodes.inc.h
+CXXInheritance.po: DiagnosticCommonKinds.inc.h
+CXXInheritance.po: StmtNodes.inc.h
+Decl.o: AttrList.inc.h
+Decl.o: Attrs.inc.h
+Decl.o: DeclNodes.inc.h
+Decl.o: DiagnosticCommonKinds.inc.h
+Decl.o: StmtNodes.inc.h
+Decl.po: AttrList.inc.h
+Decl.po: Attrs.inc.h
+Decl.po: DeclNodes.inc.h
+Decl.po: DiagnosticCommonKinds.inc.h
+Decl.po: StmtNodes.inc.h
+DeclBase.o: AttrList.inc.h
+DeclBase.o: Attrs.inc.h
+DeclBase.o: DeclNodes.inc.h
+DeclBase.o: DiagnosticCommonKinds.inc.h
+DeclBase.o: StmtNodes.inc.h
+DeclBase.po: AttrList.inc.h
+DeclBase.po: Attrs.inc.h
+DeclBase.po: DeclNodes.inc.h
+DeclBase.po: DiagnosticCommonKinds.inc.h
+DeclBase.po: StmtNodes.inc.h
+DeclCXX.o: AttrList.inc.h
+DeclCXX.o: Attrs.inc.h
+DeclCXX.o: DeclNodes.inc.h
+DeclCXX.o: DiagnosticCommonKinds.inc.h
+DeclCXX.o: StmtNodes.inc.h
+DeclCXX.po: AttrList.inc.h
+DeclCXX.po: Attrs.inc.h
+DeclCXX.po: DeclNodes.inc.h
+DeclCXX.po: DiagnosticCommonKinds.inc.h
+DeclCXX.po: StmtNodes.inc.h
+DeclFriend.o: AttrList.inc.h
+DeclFriend.o: Attrs.inc.h
+DeclFriend.o: DeclNodes.inc.h
+DeclFriend.o: DiagnosticCommonKinds.inc.h
+DeclFriend.o: StmtNodes.inc.h
+DeclFriend.po: AttrList.inc.h
+DeclFriend.po: Attrs.inc.h
+DeclFriend.po: DeclNodes.inc.h
+DeclFriend.po: DiagnosticCommonKinds.inc.h
+DeclFriend.po: StmtNodes.inc.h
+DeclGroup.o: AttrList.inc.h
+DeclGroup.o: Attrs.inc.h
+DeclGroup.o: DeclNodes.inc.h
+DeclGroup.o: DiagnosticCommonKinds.inc.h
+DeclGroup.po: AttrList.inc.h
+DeclGroup.po: Attrs.inc.h
+DeclGroup.po: DeclNodes.inc.h
+DeclGroup.po: DiagnosticCommonKinds.inc.h
+DeclObjC.o: AttrList.inc.h
+DeclObjC.o: Attrs.inc.h
+DeclObjC.o: DeclNodes.inc.h
+DeclObjC.o: DiagnosticCommonKinds.inc.h
+DeclObjC.o: StmtNodes.inc.h
+DeclObjC.po: AttrList.inc.h
+DeclObjC.po: Attrs.inc.h
+DeclObjC.po: DeclNodes.inc.h
+DeclObjC.po: DiagnosticCommonKinds.inc.h
+DeclObjC.po: StmtNodes.inc.h
+DeclPrinter.o: AttrList.inc.h
+DeclPrinter.o: Attrs.inc.h
+DeclPrinter.o: DeclNodes.inc.h
+DeclPrinter.o: DiagnosticCommonKinds.inc.h
+DeclPrinter.o: StmtNodes.inc.h
+DeclPrinter.po: AttrList.inc.h
+DeclPrinter.po: Attrs.inc.h
+DeclPrinter.po: DeclNodes.inc.h
+DeclPrinter.po: DiagnosticCommonKinds.inc.h
+DeclPrinter.po: StmtNodes.inc.h
+DeclTemplate.o: AttrList.inc.h
+DeclTemplate.o: Attrs.inc.h
+DeclTemplate.o: DeclNodes.inc.h
+DeclTemplate.o: DiagnosticCommonKinds.inc.h
+DeclTemplate.o: StmtNodes.inc.h
+DeclTemplate.po: AttrList.inc.h
+DeclTemplate.po: Attrs.inc.h
+DeclTemplate.po: DeclNodes.inc.h
+DeclTemplate.po: DiagnosticCommonKinds.inc.h
+DeclTemplate.po: StmtNodes.inc.h
+DeclarationName.o: AttrList.inc.h
+DeclarationName.o: Attrs.inc.h
+DeclarationName.o: DeclNodes.inc.h
+DeclarationName.o: DiagnosticCommonKinds.inc.h
+DeclarationName.po: AttrList.inc.h
+DeclarationName.po: Attrs.inc.h
+DeclarationName.po: DeclNodes.inc.h
+DeclarationName.po: DiagnosticCommonKinds.inc.h
+DumpXML.o: AttrList.inc.h
+DumpXML.o: Attrs.inc.h
+DumpXML.o: DeclNodes.inc.h
+DumpXML.o: DiagnosticCommonKinds.inc.h
+DumpXML.o: StmtNodes.inc.h
+DumpXML.po: AttrList.inc.h
+DumpXML.po: Attrs.inc.h
+DumpXML.po: DeclNodes.inc.h
+DumpXML.po: DiagnosticCommonKinds.inc.h
+DumpXML.po: StmtNodes.inc.h
+Expr.o: AttrList.inc.h
+Expr.o: Attrs.inc.h
+Expr.o: DeclNodes.inc.h
+Expr.o: DiagnosticCommonKinds.inc.h
+Expr.o: DiagnosticSemaKinds.inc.h
+Expr.o: StmtNodes.inc.h
+Expr.po: AttrList.inc.h
+Expr.po: Attrs.inc.h
+Expr.po: DeclNodes.inc.h
+Expr.po: DiagnosticCommonKinds.inc.h
+Expr.po: DiagnosticSemaKinds.inc.h
+Expr.po: StmtNodes.inc.h
+ExprCXX.o: AttrList.inc.h
+ExprCXX.o: Attrs.inc.h
+ExprCXX.o: DeclNodes.inc.h
+ExprCXX.o: DiagnosticCommonKinds.inc.h
+ExprCXX.o: StmtNodes.inc.h
+ExprCXX.po: AttrList.inc.h
+ExprCXX.po: Attrs.inc.h
+ExprCXX.po: DeclNodes.inc.h
+ExprCXX.po: DiagnosticCommonKinds.inc.h
+ExprCXX.po: StmtNodes.inc.h
+ExprClassification.o: AttrList.inc.h
+ExprClassification.o: Attrs.inc.h
+ExprClassification.o: DeclNodes.inc.h
+ExprClassification.o: DiagnosticCommonKinds.inc.h
+ExprClassification.o: StmtNodes.inc.h
+ExprClassification.po: AttrList.inc.h
+ExprClassification.po: Attrs.inc.h
+ExprClassification.po: DeclNodes.inc.h
+ExprClassification.po: DiagnosticCommonKinds.inc.h
+ExprClassification.po: StmtNodes.inc.h
+ExprConstant.o: AttrList.inc.h
+ExprConstant.o: Attrs.inc.h
+ExprConstant.o: DeclNodes.inc.h
+ExprConstant.o: DiagnosticASTKinds.inc.h
+ExprConstant.o: DiagnosticCommonKinds.inc.h
+ExprConstant.o: StmtNodes.inc.h
+ExprConstant.po: AttrList.inc.h
+ExprConstant.po: Attrs.inc.h
+ExprConstant.po: DeclNodes.inc.h
+ExprConstant.po: DiagnosticASTKinds.inc.h
+ExprConstant.po: DiagnosticCommonKinds.inc.h
+ExprConstant.po: StmtNodes.inc.h
+ExternalASTSource.o: AttrList.inc.h
+ExternalASTSource.o: Attrs.inc.h
+ExternalASTSource.o: DeclNodes.inc.h
+ExternalASTSource.o: DiagnosticCommonKinds.inc.h
+ExternalASTSource.po: AttrList.inc.h
+ExternalASTSource.po: Attrs.inc.h
+ExternalASTSource.po: DeclNodes.inc.h
+ExternalASTSource.po: DiagnosticCommonKinds.inc.h
+InheritViz.o: AttrList.inc.h
+InheritViz.o: Attrs.inc.h
+InheritViz.o: DeclNodes.inc.h
+InheritViz.o: DiagnosticCommonKinds.inc.h
+InheritViz.o: StmtNodes.inc.h
+InheritViz.po: AttrList.inc.h
+InheritViz.po: Attrs.inc.h
+InheritViz.po: DeclNodes.inc.h
+InheritViz.po: DiagnosticCommonKinds.inc.h
+InheritViz.po: StmtNodes.inc.h
+ItaniumCXXABI.o: AttrList.inc.h
+ItaniumCXXABI.o: Attrs.inc.h
+ItaniumCXXABI.o: DeclNodes.inc.h
+ItaniumCXXABI.o: DiagnosticCommonKinds.inc.h
+ItaniumCXXABI.o: StmtNodes.inc.h
+ItaniumCXXABI.po: AttrList.inc.h
+ItaniumCXXABI.po: Attrs.inc.h
+ItaniumCXXABI.po: DeclNodes.inc.h
+ItaniumCXXABI.po: DiagnosticCommonKinds.inc.h
+ItaniumCXXABI.po: StmtNodes.inc.h
+ItaniumMangle.o: AttrList.inc.h
+ItaniumMangle.o: Attrs.inc.h
+ItaniumMangle.o: DeclNodes.inc.h
+ItaniumMangle.o: DiagnosticCommonKinds.inc.h
+ItaniumMangle.o: StmtNodes.inc.h
+ItaniumMangle.po: AttrList.inc.h
+ItaniumMangle.po: Attrs.inc.h
+ItaniumMangle.po: DeclNodes.inc.h
+ItaniumMangle.po: DiagnosticCommonKinds.inc.h
+ItaniumMangle.po: StmtNodes.inc.h
+LambdaMangleContext.o: AttrList.inc.h
+LambdaMangleContext.o: Attrs.inc.h
+LambdaMangleContext.o: DeclNodes.inc.h
+LambdaMangleContext.o: DiagnosticCommonKinds.inc.h
+LambdaMangleContext.o: StmtNodes.inc.h
+LambdaMangleContext.po: AttrList.inc.h
+LambdaMangleContext.po: Attrs.inc.h
+LambdaMangleContext.po: DeclNodes.inc.h
+LambdaMangleContext.po: DiagnosticCommonKinds.inc.h
+LambdaMangleContext.po: StmtNodes.inc.h
+Mangle.o: AttrList.inc.h
+Mangle.o: Attrs.inc.h
+Mangle.o: DeclNodes.inc.h
+Mangle.o: DiagnosticCommonKinds.inc.h
+Mangle.o: StmtNodes.inc.h
+Mangle.po: AttrList.inc.h
+Mangle.po: Attrs.inc.h
+Mangle.po: DeclNodes.inc.h
+Mangle.po: DiagnosticCommonKinds.inc.h
+Mangle.po: StmtNodes.inc.h
+MicrosoftCXXABI.o: AttrList.inc.h
+MicrosoftCXXABI.o: Attrs.inc.h
+MicrosoftCXXABI.o: DeclNodes.inc.h
+MicrosoftCXXABI.o: DiagnosticCommonKinds.inc.h
+MicrosoftCXXABI.o: StmtNodes.inc.h
+MicrosoftCXXABI.po: AttrList.inc.h
+MicrosoftCXXABI.po: Attrs.inc.h
+MicrosoftCXXABI.po: DeclNodes.inc.h
+MicrosoftCXXABI.po: DiagnosticCommonKinds.inc.h
+MicrosoftCXXABI.po: StmtNodes.inc.h
+MicrosoftMangle.o: AttrList.inc.h
+MicrosoftMangle.o: Attrs.inc.h
+MicrosoftMangle.o: DeclNodes.inc.h
+MicrosoftMangle.o: DiagnosticCommonKinds.inc.h
+MicrosoftMangle.o: StmtNodes.inc.h
+MicrosoftMangle.po: AttrList.inc.h
+MicrosoftMangle.po: Attrs.inc.h
+MicrosoftMangle.po: DeclNodes.inc.h
+MicrosoftMangle.po: DiagnosticCommonKinds.inc.h
+MicrosoftMangle.po: StmtNodes.inc.h
+NSAPI.o: AttrList.inc.h
+NSAPI.o: Attrs.inc.h
+NSAPI.o: DeclNodes.inc.h
+NSAPI.o: DiagnosticCommonKinds.inc.h
+NSAPI.po: AttrList.inc.h
+NSAPI.po: Attrs.inc.h
+NSAPI.po: DeclNodes.inc.h
+NSAPI.po: DiagnosticCommonKinds.inc.h
+NestedNameSpecifier.o: AttrList.inc.h
+NestedNameSpecifier.o: Attrs.inc.h
+NestedNameSpecifier.o: DeclNodes.inc.h
+NestedNameSpecifier.o: DiagnosticCommonKinds.inc.h
+NestedNameSpecifier.o: StmtNodes.inc.h
+NestedNameSpecifier.po: AttrList.inc.h
+NestedNameSpecifier.po: Attrs.inc.h
+NestedNameSpecifier.po: DeclNodes.inc.h
+NestedNameSpecifier.po: DiagnosticCommonKinds.inc.h
+NestedNameSpecifier.po: StmtNodes.inc.h
+ParentMap.o: AttrList.inc.h
+ParentMap.o: Attrs.inc.h
+ParentMap.o: DeclNodes.inc.h
+ParentMap.o: DiagnosticCommonKinds.inc.h
+ParentMap.o: StmtNodes.inc.h
+ParentMap.po: AttrList.inc.h
+ParentMap.po: Attrs.inc.h
+ParentMap.po: DeclNodes.inc.h
+ParentMap.po: DiagnosticCommonKinds.inc.h
+ParentMap.po: StmtNodes.inc.h
+RecordLayout.o: AttrList.inc.h
+RecordLayout.o: Attrs.inc.h
+RecordLayout.o: DeclNodes.inc.h
+RecordLayout.o: DiagnosticCommonKinds.inc.h
+RecordLayout.o: StmtNodes.inc.h
+RecordLayout.po: AttrList.inc.h
+RecordLayout.po: Attrs.inc.h
+RecordLayout.po: DeclNodes.inc.h
+RecordLayout.po: DiagnosticCommonKinds.inc.h
+RecordLayout.po: StmtNodes.inc.h
+RecordLayoutBuilder.o: AttrList.inc.h
+RecordLayoutBuilder.o: Attrs.inc.h
+RecordLayoutBuilder.o: DeclNodes.inc.h
+RecordLayoutBuilder.o: DiagnosticCommonKinds.inc.h
+RecordLayoutBuilder.o: DiagnosticSemaKinds.inc.h
+RecordLayoutBuilder.o: StmtNodes.inc.h
+RecordLayoutBuilder.po: AttrList.inc.h
+RecordLayoutBuilder.po: Attrs.inc.h
+RecordLayoutBuilder.po: DeclNodes.inc.h
+RecordLayoutBuilder.po: DiagnosticCommonKinds.inc.h
+RecordLayoutBuilder.po: DiagnosticSemaKinds.inc.h
+RecordLayoutBuilder.po: StmtNodes.inc.h
+SelectorLocationsKind.o: AttrList.inc.h
+SelectorLocationsKind.o: Attrs.inc.h
+SelectorLocationsKind.o: DeclNodes.inc.h
+SelectorLocationsKind.o: DiagnosticCommonKinds.inc.h
+SelectorLocationsKind.o: StmtNodes.inc.h
+SelectorLocationsKind.po: AttrList.inc.h
+SelectorLocationsKind.po: Attrs.inc.h
+SelectorLocationsKind.po: DeclNodes.inc.h
+SelectorLocationsKind.po: DiagnosticCommonKinds.inc.h
+SelectorLocationsKind.po: StmtNodes.inc.h
+Stmt.o: AttrList.inc.h
+Stmt.o: Attrs.inc.h
+Stmt.o: DeclNodes.inc.h
+Stmt.o: DiagnosticASTKinds.inc.h
+Stmt.o: DiagnosticCommonKinds.inc.h
+Stmt.o: StmtNodes.inc.h
+Stmt.po: AttrList.inc.h
+Stmt.po: Attrs.inc.h
+Stmt.po: DeclNodes.inc.h
+Stmt.po: DiagnosticASTKinds.inc.h
+Stmt.po: DiagnosticCommonKinds.inc.h
+Stmt.po: StmtNodes.inc.h
+StmtDumper.o: AttrList.inc.h
+StmtDumper.o: Attrs.inc.h
+StmtDumper.o: DeclNodes.inc.h
+StmtDumper.o: DiagnosticCommonKinds.inc.h
+StmtDumper.o: StmtNodes.inc.h
+StmtDumper.po: AttrList.inc.h
+StmtDumper.po: Attrs.inc.h
+StmtDumper.po: DeclNodes.inc.h
+StmtDumper.po: DiagnosticCommonKinds.inc.h
+StmtDumper.po: StmtNodes.inc.h
+StmtIterator.o: AttrList.inc.h
+StmtIterator.o: Attrs.inc.h
+StmtIterator.o: DeclNodes.inc.h
+StmtIterator.o: DiagnosticCommonKinds.inc.h
+StmtIterator.po: AttrList.inc.h
+StmtIterator.po: Attrs.inc.h
+StmtIterator.po: DeclNodes.inc.h
+StmtIterator.po: DiagnosticCommonKinds.inc.h
+StmtPrinter.o: AttrList.inc.h
+StmtPrinter.o: Attrs.inc.h
+StmtPrinter.o: DeclNodes.inc.h
+StmtPrinter.o: DiagnosticCommonKinds.inc.h
+StmtPrinter.o: StmtNodes.inc.h
+StmtPrinter.po: AttrList.inc.h
+StmtPrinter.po: Attrs.inc.h
+StmtPrinter.po: DeclNodes.inc.h
+StmtPrinter.po: DiagnosticCommonKinds.inc.h
+StmtPrinter.po: StmtNodes.inc.h
+StmtProfile.o: AttrList.inc.h
+StmtProfile.o: Attrs.inc.h
+StmtProfile.o: DeclNodes.inc.h
+StmtProfile.o: DiagnosticCommonKinds.inc.h
+StmtProfile.o: StmtNodes.inc.h
+StmtProfile.po: AttrList.inc.h
+StmtProfile.po: Attrs.inc.h
+StmtProfile.po: DeclNodes.inc.h
+StmtProfile.po: DiagnosticCommonKinds.inc.h
+StmtProfile.po: StmtNodes.inc.h
+StmtViz.o: AttrList.inc.h
+StmtViz.o: Attrs.inc.h
+StmtViz.o: DeclNodes.inc.h
+StmtViz.o: DiagnosticCommonKinds.inc.h
+StmtViz.o: StmtNodes.inc.h
+StmtViz.po: AttrList.inc.h
+StmtViz.po: Attrs.inc.h
+StmtViz.po: DeclNodes.inc.h
+StmtViz.po: DiagnosticCommonKinds.inc.h
+StmtViz.po: StmtNodes.inc.h
+TemplateBase.o: AttrList.inc.h
+TemplateBase.o: Attrs.inc.h
+TemplateBase.o: DeclNodes.inc.h
+TemplateBase.o: DiagnosticCommonKinds.inc.h
+TemplateBase.o: StmtNodes.inc.h
+TemplateBase.po: AttrList.inc.h
+TemplateBase.po: Attrs.inc.h
+TemplateBase.po: DeclNodes.inc.h
+TemplateBase.po: DiagnosticCommonKinds.inc.h
+TemplateBase.po: StmtNodes.inc.h
+TemplateName.o: AttrList.inc.h
+TemplateName.o: Attrs.inc.h
+TemplateName.o: DeclNodes.inc.h
+TemplateName.o: DiagnosticCommonKinds.inc.h
+TemplateName.o: StmtNodes.inc.h
+TemplateName.po: AttrList.inc.h
+TemplateName.po: Attrs.inc.h
+TemplateName.po: DeclNodes.inc.h
+TemplateName.po: DiagnosticCommonKinds.inc.h
+TemplateName.po: StmtNodes.inc.h
+Type.o: AttrList.inc.h
+Type.o: Attrs.inc.h
+Type.o: DeclNodes.inc.h
+Type.o: DiagnosticCommonKinds.inc.h
+Type.o: StmtNodes.inc.h
+Type.po: AttrList.inc.h
+Type.po: Attrs.inc.h
+Type.po: DeclNodes.inc.h
+Type.po: DiagnosticCommonKinds.inc.h
+Type.po: StmtNodes.inc.h
+TypeLoc.o: AttrList.inc.h
+TypeLoc.o: Attrs.inc.h
+TypeLoc.o: DeclNodes.inc.h
+TypeLoc.o: DiagnosticCommonKinds.inc.h
+TypeLoc.o: StmtNodes.inc.h
+TypeLoc.po: AttrList.inc.h
+TypeLoc.po: Attrs.inc.h
+TypeLoc.po: DeclNodes.inc.h
+TypeLoc.po: DiagnosticCommonKinds.inc.h
+TypeLoc.po: StmtNodes.inc.h
+TypePrinter.o: AttrList.inc.h
+TypePrinter.o: Attrs.inc.h
+TypePrinter.o: DeclNodes.inc.h
+TypePrinter.o: DiagnosticCommonKinds.inc.h
+TypePrinter.o: StmtNodes.inc.h
+TypePrinter.po: AttrList.inc.h
+TypePrinter.po: Attrs.inc.h
+TypePrinter.po: DeclNodes.inc.h
+TypePrinter.po: DiagnosticCommonKinds.inc.h
+TypePrinter.po: StmtNodes.inc.h
+VTTBuilder.o: AttrList.inc.h
+VTTBuilder.o: Attrs.inc.h
+VTTBuilder.o: DeclNodes.inc.h
+VTTBuilder.o: DiagnosticCommonKinds.inc.h
+VTTBuilder.o: StmtNodes.inc.h
+VTTBuilder.po: AttrList.inc.h
+VTTBuilder.po: Attrs.inc.h
+VTTBuilder.po: DeclNodes.inc.h
+VTTBuilder.po: DiagnosticCommonKinds.inc.h
+VTTBuilder.po: StmtNodes.inc.h
+VTableBuilder.o: AttrList.inc.h
+VTableBuilder.o: Attrs.inc.h
+VTableBuilder.o: DeclNodes.inc.h
+VTableBuilder.o: DiagnosticCommonKinds.inc.h
+VTableBuilder.o: StmtNodes.inc.h
+VTableBuilder.po: AttrList.inc.h
+VTableBuilder.po: Attrs.inc.h
+VTableBuilder.po: DeclNodes.inc.h
+VTableBuilder.po: DiagnosticCommonKinds.inc.h
+VTableBuilder.po: StmtNodes.inc.h
+.endif
diff --git a/lib/clang/libclangbasic/Makefile.depend b/lib/clang/libclangbasic/Makefile.depend
new file mode 100644
index 0000000..2c92226
--- /dev/null
+++ b/lib/clang/libclangbasic/Makefile.depend
@@ -0,0 +1,45 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+Diagnostic.o: DiagnosticCommonKinds.inc.h
+Diagnostic.po: DiagnosticCommonKinds.inc.h
+DiagnosticIDs.o: DiagnosticASTKinds.inc.h
+DiagnosticIDs.o: DiagnosticAnalysisKinds.inc.h
+DiagnosticIDs.o: DiagnosticCommonKinds.inc.h
+DiagnosticIDs.o: DiagnosticDriverKinds.inc.h
+DiagnosticIDs.o: DiagnosticFrontendKinds.inc.h
+DiagnosticIDs.o: DiagnosticGroups.inc.h
+DiagnosticIDs.o: DiagnosticLexKinds.inc.h
+DiagnosticIDs.o: DiagnosticParseKinds.inc.h
+DiagnosticIDs.o: DiagnosticSemaKinds.inc.h
+DiagnosticIDs.o: DiagnosticSerializationKinds.inc.h
+DiagnosticIDs.po: DiagnosticASTKinds.inc.h
+DiagnosticIDs.po: DiagnosticAnalysisKinds.inc.h
+DiagnosticIDs.po: DiagnosticCommonKinds.inc.h
+DiagnosticIDs.po: DiagnosticDriverKinds.inc.h
+DiagnosticIDs.po: DiagnosticFrontendKinds.inc.h
+DiagnosticIDs.po: DiagnosticGroups.inc.h
+DiagnosticIDs.po: DiagnosticLexKinds.inc.h
+DiagnosticIDs.po: DiagnosticParseKinds.inc.h
+DiagnosticIDs.po: DiagnosticSemaKinds.inc.h
+DiagnosticIDs.po: DiagnosticSerializationKinds.inc.h
+SourceManager.o: DiagnosticCommonKinds.inc.h
+SourceManager.po: DiagnosticCommonKinds.inc.h
+Targets.o: DiagnosticCommonKinds.inc.h
+Targets.o: arm_neon.inc.h
+Targets.po: DiagnosticCommonKinds.inc.h
+Targets.po: arm_neon.inc.h
+.endif
diff --git a/lib/clang/libclangcodegen/Makefile.depend b/lib/clang/libclangcodegen/Makefile.depend
new file mode 100644
index 0000000..9ed7af2
--- /dev/null
+++ b/lib/clang/libclangcodegen/Makefile.depend
@@ -0,0 +1,431 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+BackendUtil.o: DiagnosticCommonKinds.inc.h
+BackendUtil.o: DiagnosticFrontendKinds.inc.h
+BackendUtil.po: DiagnosticCommonKinds.inc.h
+BackendUtil.po: DiagnosticFrontendKinds.inc.h
+CGBlocks.o: AttrList.inc.h
+CGBlocks.o: Attrs.inc.h
+CGBlocks.o: DeclNodes.inc.h
+CGBlocks.o: DiagnosticCommonKinds.inc.h
+CGBlocks.o: StmtNodes.inc.h
+CGBlocks.po: AttrList.inc.h
+CGBlocks.po: Attrs.inc.h
+CGBlocks.po: DeclNodes.inc.h
+CGBlocks.po: DiagnosticCommonKinds.inc.h
+CGBlocks.po: StmtNodes.inc.h
+CGBuiltin.o: AttrList.inc.h
+CGBuiltin.o: Attrs.inc.h
+CGBuiltin.o: DeclNodes.inc.h
+CGBuiltin.o: DiagnosticCommonKinds.inc.h
+CGBuiltin.o: Intrinsics.inc.h
+CGBuiltin.o: StmtNodes.inc.h
+CGBuiltin.o: arm_neon.inc.h
+CGBuiltin.po: AttrList.inc.h
+CGBuiltin.po: Attrs.inc.h
+CGBuiltin.po: DeclNodes.inc.h
+CGBuiltin.po: DiagnosticCommonKinds.inc.h
+CGBuiltin.po: Intrinsics.inc.h
+CGBuiltin.po: StmtNodes.inc.h
+CGBuiltin.po: arm_neon.inc.h
+CGCUDANV.o: AttrList.inc.h
+CGCUDANV.o: Attrs.inc.h
+CGCUDANV.o: DeclNodes.inc.h
+CGCUDANV.o: DiagnosticCommonKinds.inc.h
+CGCUDANV.o: StmtNodes.inc.h
+CGCUDANV.po: AttrList.inc.h
+CGCUDANV.po: Attrs.inc.h
+CGCUDANV.po: DeclNodes.inc.h
+CGCUDANV.po: DiagnosticCommonKinds.inc.h
+CGCUDANV.po: StmtNodes.inc.h
+CGCUDARuntime.o: AttrList.inc.h
+CGCUDARuntime.o: Attrs.inc.h
+CGCUDARuntime.o: DeclNodes.inc.h
+CGCUDARuntime.o: DiagnosticCommonKinds.inc.h
+CGCUDARuntime.o: StmtNodes.inc.h
+CGCUDARuntime.po: AttrList.inc.h
+CGCUDARuntime.po: Attrs.inc.h
+CGCUDARuntime.po: DeclNodes.inc.h
+CGCUDARuntime.po: DiagnosticCommonKinds.inc.h
+CGCUDARuntime.po: StmtNodes.inc.h
+CGCXX.o: AttrList.inc.h
+CGCXX.o: Attrs.inc.h
+CGCXX.o: DeclNodes.inc.h
+CGCXX.o: DiagnosticCommonKinds.inc.h
+CGCXX.o: StmtNodes.inc.h
+CGCXX.po: AttrList.inc.h
+CGCXX.po: Attrs.inc.h
+CGCXX.po: DeclNodes.inc.h
+CGCXX.po: DiagnosticCommonKinds.inc.h
+CGCXX.po: StmtNodes.inc.h
+CGCXXABI.o: AttrList.inc.h
+CGCXXABI.o: Attrs.inc.h
+CGCXXABI.o: DeclNodes.inc.h
+CGCXXABI.o: DiagnosticCommonKinds.inc.h
+CGCXXABI.o: StmtNodes.inc.h
+CGCXXABI.po: AttrList.inc.h
+CGCXXABI.po: Attrs.inc.h
+CGCXXABI.po: DeclNodes.inc.h
+CGCXXABI.po: DiagnosticCommonKinds.inc.h
+CGCXXABI.po: StmtNodes.inc.h
+CGCall.o: AttrList.inc.h
+CGCall.o: Attrs.inc.h
+CGCall.o: DeclNodes.inc.h
+CGCall.o: DiagnosticCommonKinds.inc.h
+CGCall.o: StmtNodes.inc.h
+CGCall.po: AttrList.inc.h
+CGCall.po: Attrs.inc.h
+CGCall.po: DeclNodes.inc.h
+CGCall.po: DiagnosticCommonKinds.inc.h
+CGCall.po: StmtNodes.inc.h
+CGClass.o: AttrList.inc.h
+CGClass.o: Attrs.inc.h
+CGClass.o: DeclNodes.inc.h
+CGClass.o: DiagnosticCommonKinds.inc.h
+CGClass.o: StmtNodes.inc.h
+CGClass.po: AttrList.inc.h
+CGClass.po: Attrs.inc.h
+CGClass.po: DeclNodes.inc.h
+CGClass.po: DiagnosticCommonKinds.inc.h
+CGClass.po: StmtNodes.inc.h
+CGCleanup.o: AttrList.inc.h
+CGCleanup.o: Attrs.inc.h
+CGCleanup.o: DeclNodes.inc.h
+CGCleanup.o: DiagnosticCommonKinds.inc.h
+CGCleanup.o: StmtNodes.inc.h
+CGCleanup.po: AttrList.inc.h
+CGCleanup.po: Attrs.inc.h
+CGCleanup.po: DeclNodes.inc.h
+CGCleanup.po: DiagnosticCommonKinds.inc.h
+CGCleanup.po: StmtNodes.inc.h
+CGDebugInfo.o: AttrList.inc.h
+CGDebugInfo.o: Attrs.inc.h
+CGDebugInfo.o: DeclNodes.inc.h
+CGDebugInfo.o: DiagnosticCommonKinds.inc.h
+CGDebugInfo.o: Intrinsics.inc.h
+CGDebugInfo.o: StmtNodes.inc.h
+CGDebugInfo.po: AttrList.inc.h
+CGDebugInfo.po: Attrs.inc.h
+CGDebugInfo.po: DeclNodes.inc.h
+CGDebugInfo.po: DiagnosticCommonKinds.inc.h
+CGDebugInfo.po: Intrinsics.inc.h
+CGDebugInfo.po: StmtNodes.inc.h
+CGDecl.o: AttrList.inc.h
+CGDecl.o: Attrs.inc.h
+CGDecl.o: DeclNodes.inc.h
+CGDecl.o: DiagnosticCommonKinds.inc.h
+CGDecl.o: Intrinsics.inc.h
+CGDecl.o: StmtNodes.inc.h
+CGDecl.po: AttrList.inc.h
+CGDecl.po: Attrs.inc.h
+CGDecl.po: DeclNodes.inc.h
+CGDecl.po: DiagnosticCommonKinds.inc.h
+CGDecl.po: Intrinsics.inc.h
+CGDecl.po: StmtNodes.inc.h
+CGDeclCXX.o: AttrList.inc.h
+CGDeclCXX.o: Attrs.inc.h
+CGDeclCXX.o: DeclNodes.inc.h
+CGDeclCXX.o: DiagnosticCommonKinds.inc.h
+CGDeclCXX.o: Intrinsics.inc.h
+CGDeclCXX.o: StmtNodes.inc.h
+CGDeclCXX.po: AttrList.inc.h
+CGDeclCXX.po: Attrs.inc.h
+CGDeclCXX.po: DeclNodes.inc.h
+CGDeclCXX.po: DiagnosticCommonKinds.inc.h
+CGDeclCXX.po: Intrinsics.inc.h
+CGDeclCXX.po: StmtNodes.inc.h
+CGException.o: AttrList.inc.h
+CGException.o: Attrs.inc.h
+CGException.o: DeclNodes.inc.h
+CGException.o: DiagnosticCommonKinds.inc.h
+CGException.o: Intrinsics.inc.h
+CGException.o: StmtNodes.inc.h
+CGException.po: AttrList.inc.h
+CGException.po: Attrs.inc.h
+CGException.po: DeclNodes.inc.h
+CGException.po: DiagnosticCommonKinds.inc.h
+CGException.po: Intrinsics.inc.h
+CGException.po: StmtNodes.inc.h
+CGExpr.o: AttrList.inc.h
+CGExpr.o: Attrs.inc.h
+CGExpr.o: DeclNodes.inc.h
+CGExpr.o: DiagnosticCommonKinds.inc.h
+CGExpr.o: Intrinsics.inc.h
+CGExpr.o: StmtNodes.inc.h
+CGExpr.po: AttrList.inc.h
+CGExpr.po: Attrs.inc.h
+CGExpr.po: DeclNodes.inc.h
+CGExpr.po: DiagnosticCommonKinds.inc.h
+CGExpr.po: Intrinsics.inc.h
+CGExpr.po: StmtNodes.inc.h
+CGExprAgg.o: AttrList.inc.h
+CGExprAgg.o: Attrs.inc.h
+CGExprAgg.o: DeclNodes.inc.h
+CGExprAgg.o: DiagnosticCommonKinds.inc.h
+CGExprAgg.o: Intrinsics.inc.h
+CGExprAgg.o: StmtNodes.inc.h
+CGExprAgg.po: AttrList.inc.h
+CGExprAgg.po: Attrs.inc.h
+CGExprAgg.po: DeclNodes.inc.h
+CGExprAgg.po: DiagnosticCommonKinds.inc.h
+CGExprAgg.po: Intrinsics.inc.h
+CGExprAgg.po: StmtNodes.inc.h
+CGExprCXX.o: AttrList.inc.h
+CGExprCXX.o: Attrs.inc.h
+CGExprCXX.o: DeclNodes.inc.h
+CGExprCXX.o: DiagnosticCommonKinds.inc.h
+CGExprCXX.o: Intrinsics.inc.h
+CGExprCXX.o: StmtNodes.inc.h
+CGExprCXX.po: AttrList.inc.h
+CGExprCXX.po: Attrs.inc.h
+CGExprCXX.po: DeclNodes.inc.h
+CGExprCXX.po: DiagnosticCommonKinds.inc.h
+CGExprCXX.po: Intrinsics.inc.h
+CGExprCXX.po: StmtNodes.inc.h
+CGExprComplex.o: AttrList.inc.h
+CGExprComplex.o: Attrs.inc.h
+CGExprComplex.o: DeclNodes.inc.h
+CGExprComplex.o: DiagnosticCommonKinds.inc.h
+CGExprComplex.o: StmtNodes.inc.h
+CGExprComplex.po: AttrList.inc.h
+CGExprComplex.po: Attrs.inc.h
+CGExprComplex.po: DeclNodes.inc.h
+CGExprComplex.po: DiagnosticCommonKinds.inc.h
+CGExprComplex.po: StmtNodes.inc.h
+CGExprConstant.o: AttrList.inc.h
+CGExprConstant.o: Attrs.inc.h
+CGExprConstant.o: DeclNodes.inc.h
+CGExprConstant.o: DiagnosticCommonKinds.inc.h
+CGExprConstant.o: StmtNodes.inc.h
+CGExprConstant.po: AttrList.inc.h
+CGExprConstant.po: Attrs.inc.h
+CGExprConstant.po: DeclNodes.inc.h
+CGExprConstant.po: DiagnosticCommonKinds.inc.h
+CGExprConstant.po: StmtNodes.inc.h
+CGExprScalar.o: AttrList.inc.h
+CGExprScalar.o: Attrs.inc.h
+CGExprScalar.o: DeclNodes.inc.h
+CGExprScalar.o: DiagnosticCommonKinds.inc.h
+CGExprScalar.o: Intrinsics.inc.h
+CGExprScalar.o: StmtNodes.inc.h
+CGExprScalar.po: AttrList.inc.h
+CGExprScalar.po: Attrs.inc.h
+CGExprScalar.po: DeclNodes.inc.h
+CGExprScalar.po: DiagnosticCommonKinds.inc.h
+CGExprScalar.po: Intrinsics.inc.h
+CGExprScalar.po: StmtNodes.inc.h
+CGObjC.o: AttrList.inc.h
+CGObjC.o: Attrs.inc.h
+CGObjC.o: DeclNodes.inc.h
+CGObjC.o: DiagnosticCommonKinds.inc.h
+CGObjC.o: StmtNodes.inc.h
+CGObjC.po: AttrList.inc.h
+CGObjC.po: Attrs.inc.h
+CGObjC.po: DeclNodes.inc.h
+CGObjC.po: DiagnosticCommonKinds.inc.h
+CGObjC.po: StmtNodes.inc.h
+CGObjCGNU.o: AttrList.inc.h
+CGObjCGNU.o: Attrs.inc.h
+CGObjCGNU.o: DeclNodes.inc.h
+CGObjCGNU.o: DiagnosticCommonKinds.inc.h
+CGObjCGNU.o: Intrinsics.inc.h
+CGObjCGNU.o: StmtNodes.inc.h
+CGObjCGNU.po: AttrList.inc.h
+CGObjCGNU.po: Attrs.inc.h
+CGObjCGNU.po: DeclNodes.inc.h
+CGObjCGNU.po: DiagnosticCommonKinds.inc.h
+CGObjCGNU.po: Intrinsics.inc.h
+CGObjCGNU.po: StmtNodes.inc.h
+CGObjCMac.o: AttrList.inc.h
+CGObjCMac.o: Attrs.inc.h
+CGObjCMac.o: DeclNodes.inc.h
+CGObjCMac.o: DiagnosticCommonKinds.inc.h
+CGObjCMac.o: Intrinsics.inc.h
+CGObjCMac.o: StmtNodes.inc.h
+CGObjCMac.po: AttrList.inc.h
+CGObjCMac.po: Attrs.inc.h
+CGObjCMac.po: DeclNodes.inc.h
+CGObjCMac.po: DiagnosticCommonKinds.inc.h
+CGObjCMac.po: Intrinsics.inc.h
+CGObjCMac.po: StmtNodes.inc.h
+CGObjCRuntime.o: AttrList.inc.h
+CGObjCRuntime.o: Attrs.inc.h
+CGObjCRuntime.o: DeclNodes.inc.h
+CGObjCRuntime.o: DiagnosticCommonKinds.inc.h
+CGObjCRuntime.o: StmtNodes.inc.h
+CGObjCRuntime.po: AttrList.inc.h
+CGObjCRuntime.po: Attrs.inc.h
+CGObjCRuntime.po: DeclNodes.inc.h
+CGObjCRuntime.po: DiagnosticCommonKinds.inc.h
+CGObjCRuntime.po: StmtNodes.inc.h
+CGOpenCLRuntime.o: AttrList.inc.h
+CGOpenCLRuntime.o: Attrs.inc.h
+CGOpenCLRuntime.o: DeclNodes.inc.h
+CGOpenCLRuntime.o: DiagnosticCommonKinds.inc.h
+CGOpenCLRuntime.o: StmtNodes.inc.h
+CGOpenCLRuntime.po: AttrList.inc.h
+CGOpenCLRuntime.po: Attrs.inc.h
+CGOpenCLRuntime.po: DeclNodes.inc.h
+CGOpenCLRuntime.po: DiagnosticCommonKinds.inc.h
+CGOpenCLRuntime.po: StmtNodes.inc.h
+CGRTTI.o: AttrList.inc.h
+CGRTTI.o: Attrs.inc.h
+CGRTTI.o: DeclNodes.inc.h
+CGRTTI.o: DiagnosticCommonKinds.inc.h
+CGRTTI.o: StmtNodes.inc.h
+CGRTTI.po: AttrList.inc.h
+CGRTTI.po: Attrs.inc.h
+CGRTTI.po: DeclNodes.inc.h
+CGRTTI.po: DiagnosticCommonKinds.inc.h
+CGRTTI.po: StmtNodes.inc.h
+CGRecordLayoutBuilder.o: AttrList.inc.h
+CGRecordLayoutBuilder.o: Attrs.inc.h
+CGRecordLayoutBuilder.o: DeclNodes.inc.h
+CGRecordLayoutBuilder.o: DiagnosticCommonKinds.inc.h
+CGRecordLayoutBuilder.o: StmtNodes.inc.h
+CGRecordLayoutBuilder.po: AttrList.inc.h
+CGRecordLayoutBuilder.po: Attrs.inc.h
+CGRecordLayoutBuilder.po: DeclNodes.inc.h
+CGRecordLayoutBuilder.po: DiagnosticCommonKinds.inc.h
+CGRecordLayoutBuilder.po: StmtNodes.inc.h
+CGStmt.o: AttrList.inc.h
+CGStmt.o: Attrs.inc.h
+CGStmt.o: DeclNodes.inc.h
+CGStmt.o: DiagnosticCommonKinds.inc.h
+CGStmt.o: Intrinsics.inc.h
+CGStmt.o: StmtNodes.inc.h
+CGStmt.po: AttrList.inc.h
+CGStmt.po: Attrs.inc.h
+CGStmt.po: DeclNodes.inc.h
+CGStmt.po: DiagnosticCommonKinds.inc.h
+CGStmt.po: Intrinsics.inc.h
+CGStmt.po: StmtNodes.inc.h
+CGVTT.o: AttrList.inc.h
+CGVTT.o: Attrs.inc.h
+CGVTT.o: DeclNodes.inc.h
+CGVTT.o: DiagnosticCommonKinds.inc.h
+CGVTT.o: StmtNodes.inc.h
+CGVTT.po: AttrList.inc.h
+CGVTT.po: Attrs.inc.h
+CGVTT.po: DeclNodes.inc.h
+CGVTT.po: DiagnosticCommonKinds.inc.h
+CGVTT.po: StmtNodes.inc.h
+CGVTables.o: AttrList.inc.h
+CGVTables.o: Attrs.inc.h
+CGVTables.o: DeclNodes.inc.h
+CGVTables.o: DiagnosticCommonKinds.inc.h
+CGVTables.o: StmtNodes.inc.h
+CGVTables.po: AttrList.inc.h
+CGVTables.po: Attrs.inc.h
+CGVTables.po: DeclNodes.inc.h
+CGVTables.po: DiagnosticCommonKinds.inc.h
+CGVTables.po: StmtNodes.inc.h
+CodeGenAction.o: AttrList.inc.h
+CodeGenAction.o: Attrs.inc.h
+CodeGenAction.o: DeclNodes.inc.h
+CodeGenAction.o: DiagnosticCommonKinds.inc.h
+CodeGenAction.o: DiagnosticFrontendKinds.inc.h
+CodeGenAction.po: AttrList.inc.h
+CodeGenAction.po: Attrs.inc.h
+CodeGenAction.po: DeclNodes.inc.h
+CodeGenAction.po: DiagnosticCommonKinds.inc.h
+CodeGenAction.po: DiagnosticFrontendKinds.inc.h
+CodeGenFunction.o: AttrList.inc.h
+CodeGenFunction.o: Attrs.inc.h
+CodeGenFunction.o: DeclNodes.inc.h
+CodeGenFunction.o: DiagnosticCommonKinds.inc.h
+CodeGenFunction.o: Intrinsics.inc.h
+CodeGenFunction.o: StmtNodes.inc.h
+CodeGenFunction.po: AttrList.inc.h
+CodeGenFunction.po: Attrs.inc.h
+CodeGenFunction.po: DeclNodes.inc.h
+CodeGenFunction.po: DiagnosticCommonKinds.inc.h
+CodeGenFunction.po: Intrinsics.inc.h
+CodeGenFunction.po: StmtNodes.inc.h
+CodeGenModule.o: AttrList.inc.h
+CodeGenModule.o: Attrs.inc.h
+CodeGenModule.o: DeclNodes.inc.h
+CodeGenModule.o: DiagnosticCommonKinds.inc.h
+CodeGenModule.o: Intrinsics.inc.h
+CodeGenModule.o: StmtNodes.inc.h
+CodeGenModule.po: AttrList.inc.h
+CodeGenModule.po: Attrs.inc.h
+CodeGenModule.po: DeclNodes.inc.h
+CodeGenModule.po: DiagnosticCommonKinds.inc.h
+CodeGenModule.po: Intrinsics.inc.h
+CodeGenModule.po: StmtNodes.inc.h
+CodeGenTBAA.o: AttrList.inc.h
+CodeGenTBAA.o: Attrs.inc.h
+CodeGenTBAA.o: DeclNodes.inc.h
+CodeGenTBAA.o: DiagnosticCommonKinds.inc.h
+CodeGenTBAA.po: AttrList.inc.h
+CodeGenTBAA.po: Attrs.inc.h
+CodeGenTBAA.po: DeclNodes.inc.h
+CodeGenTBAA.po: DiagnosticCommonKinds.inc.h
+CodeGenTypes.o: AttrList.inc.h
+CodeGenTypes.o: Attrs.inc.h
+CodeGenTypes.o: DeclNodes.inc.h
+CodeGenTypes.o: DiagnosticCommonKinds.inc.h
+CodeGenTypes.o: StmtNodes.inc.h
+CodeGenTypes.po: AttrList.inc.h
+CodeGenTypes.po: Attrs.inc.h
+CodeGenTypes.po: DeclNodes.inc.h
+CodeGenTypes.po: DiagnosticCommonKinds.inc.h
+CodeGenTypes.po: StmtNodes.inc.h
+ItaniumCXXABI.o: AttrList.inc.h
+ItaniumCXXABI.o: Attrs.inc.h
+ItaniumCXXABI.o: DeclNodes.inc.h
+ItaniumCXXABI.o: DiagnosticCommonKinds.inc.h
+ItaniumCXXABI.o: Intrinsics.inc.h
+ItaniumCXXABI.o: StmtNodes.inc.h
+ItaniumCXXABI.po: AttrList.inc.h
+ItaniumCXXABI.po: Attrs.inc.h
+ItaniumCXXABI.po: DeclNodes.inc.h
+ItaniumCXXABI.po: DiagnosticCommonKinds.inc.h
+ItaniumCXXABI.po: Intrinsics.inc.h
+ItaniumCXXABI.po: StmtNodes.inc.h
+MicrosoftCXXABI.o: AttrList.inc.h
+MicrosoftCXXABI.o: Attrs.inc.h
+MicrosoftCXXABI.o: DeclNodes.inc.h
+MicrosoftCXXABI.o: DiagnosticCommonKinds.inc.h
+MicrosoftCXXABI.o: StmtNodes.inc.h
+MicrosoftCXXABI.po: AttrList.inc.h
+MicrosoftCXXABI.po: Attrs.inc.h
+MicrosoftCXXABI.po: DeclNodes.inc.h
+MicrosoftCXXABI.po: DiagnosticCommonKinds.inc.h
+MicrosoftCXXABI.po: StmtNodes.inc.h
+ModuleBuilder.o: AttrList.inc.h
+ModuleBuilder.o: Attrs.inc.h
+ModuleBuilder.o: DeclNodes.inc.h
+ModuleBuilder.o: DiagnosticCommonKinds.inc.h
+ModuleBuilder.o: StmtNodes.inc.h
+ModuleBuilder.po: AttrList.inc.h
+ModuleBuilder.po: Attrs.inc.h
+ModuleBuilder.po: DeclNodes.inc.h
+ModuleBuilder.po: DiagnosticCommonKinds.inc.h
+ModuleBuilder.po: StmtNodes.inc.h
+TargetInfo.o: AttrList.inc.h
+TargetInfo.o: Attrs.inc.h
+TargetInfo.o: DeclNodes.inc.h
+TargetInfo.o: DiagnosticCommonKinds.inc.h
+TargetInfo.o: StmtNodes.inc.h
+TargetInfo.po: AttrList.inc.h
+TargetInfo.po: Attrs.inc.h
+TargetInfo.po: DeclNodes.inc.h
+TargetInfo.po: DiagnosticCommonKinds.inc.h
+TargetInfo.po: StmtNodes.inc.h
+.endif
diff --git a/lib/clang/libclangdriver/Makefile.depend b/lib/clang/libclangdriver/Makefile.depend
new file mode 100644
index 0000000..dab9912
--- /dev/null
+++ b/lib/clang/libclangdriver/Makefile.depend
@@ -0,0 +1,61 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ArgList.o: DiagnosticCommonKinds.inc.h
+ArgList.o: DiagnosticDriverKinds.inc.h
+ArgList.po: DiagnosticCommonKinds.inc.h
+ArgList.po: DiagnosticDriverKinds.inc.h
+CC1AsOptions.o: CC1AsOptions.inc.h
+CC1AsOptions.po: CC1AsOptions.inc.h
+CC1Options.o: CC1Options.inc.h
+CC1Options.po: CC1Options.inc.h
+Compilation.o: DiagnosticCommonKinds.inc.h
+Compilation.o: DiagnosticDriverKinds.inc.h
+Compilation.o: Options.inc.h
+Compilation.po: DiagnosticCommonKinds.inc.h
+Compilation.po: DiagnosticDriverKinds.inc.h
+Compilation.po: Options.inc.h
+Driver.o: DiagnosticCommonKinds.inc.h
+Driver.o: DiagnosticDriverKinds.inc.h
+Driver.o: Options.inc.h
+Driver.po: DiagnosticCommonKinds.inc.h
+Driver.po: DiagnosticDriverKinds.inc.h
+Driver.po: Options.inc.h
+DriverOptions.o: Options.inc.h
+DriverOptions.po: Options.inc.h
+ToolChain.o: DiagnosticCommonKinds.inc.h
+ToolChain.o: DiagnosticDriverKinds.inc.h
+ToolChain.o: Options.inc.h
+ToolChain.po: DiagnosticCommonKinds.inc.h
+ToolChain.po: DiagnosticDriverKinds.inc.h
+ToolChain.po: Options.inc.h
+ToolChains.o: DiagnosticCommonKinds.inc.h
+ToolChains.o: DiagnosticDriverKinds.inc.h
+ToolChains.o: Options.inc.h
+ToolChains.po: DiagnosticCommonKinds.inc.h
+ToolChains.po: DiagnosticDriverKinds.inc.h
+ToolChains.po: Options.inc.h
+Tools.o: DiagnosticCommonKinds.inc.h
+Tools.o: DiagnosticDriverKinds.inc.h
+Tools.o: Options.inc.h
+Tools.po: DiagnosticCommonKinds.inc.h
+Tools.po: DiagnosticDriverKinds.inc.h
+Tools.po: Options.inc.h
+WindowsToolChain.o: DiagnosticCommonKinds.inc.h
+WindowsToolChain.o: Options.inc.h
+WindowsToolChain.po: DiagnosticCommonKinds.inc.h
+WindowsToolChain.po: Options.inc.h
+.endif
diff --git a/lib/clang/libclangedit/Makefile.depend b/lib/clang/libclangedit/Makefile.depend
new file mode 100644
index 0000000..9c2823c
--- /dev/null
+++ b/lib/clang/libclangedit/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+Commit.o: DiagnosticCommonKinds.inc.h
+Commit.po: DiagnosticCommonKinds.inc.h
+RewriteObjCFoundationAPI.o: AttrList.inc.h
+RewriteObjCFoundationAPI.o: Attrs.inc.h
+RewriteObjCFoundationAPI.o: DeclNodes.inc.h
+RewriteObjCFoundationAPI.o: DiagnosticCommonKinds.inc.h
+RewriteObjCFoundationAPI.o: StmtNodes.inc.h
+RewriteObjCFoundationAPI.po: AttrList.inc.h
+RewriteObjCFoundationAPI.po: Attrs.inc.h
+RewriteObjCFoundationAPI.po: DeclNodes.inc.h
+RewriteObjCFoundationAPI.po: DiagnosticCommonKinds.inc.h
+RewriteObjCFoundationAPI.po: StmtNodes.inc.h
+.endif
diff --git a/lib/clang/libclangfrontend/Makefile.depend b/lib/clang/libclangfrontend/Makefile.depend
new file mode 100644
index 0000000..a9a8a2a
--- /dev/null
+++ b/lib/clang/libclangfrontend/Makefile.depend
@@ -0,0 +1,189 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ASTConsumers.o: AttrList.inc.h
+ASTConsumers.o: Attrs.inc.h
+ASTConsumers.o: DeclNodes.inc.h
+ASTConsumers.o: DiagnosticCommonKinds.inc.h
+ASTConsumers.o: StmtNodes.inc.h
+ASTConsumers.po: AttrList.inc.h
+ASTConsumers.po: Attrs.inc.h
+ASTConsumers.po: DeclNodes.inc.h
+ASTConsumers.po: DiagnosticCommonKinds.inc.h
+ASTConsumers.po: StmtNodes.inc.h
+ASTMerge.o: AttrList.inc.h
+ASTMerge.o: AttrParsedAttrList.inc.h
+ASTMerge.o: Attrs.inc.h
+ASTMerge.o: DeclNodes.inc.h
+ASTMerge.o: DiagnosticASTKinds.inc.h
+ASTMerge.o: DiagnosticCommonKinds.inc.h
+ASTMerge.o: StmtNodes.inc.h
+ASTMerge.po: AttrList.inc.h
+ASTMerge.po: AttrParsedAttrList.inc.h
+ASTMerge.po: Attrs.inc.h
+ASTMerge.po: DeclNodes.inc.h
+ASTMerge.po: DiagnosticASTKinds.inc.h
+ASTMerge.po: DiagnosticCommonKinds.inc.h
+ASTMerge.po: StmtNodes.inc.h
+ASTUnit.o: AttrList.inc.h
+ASTUnit.o: AttrParsedAttrList.inc.h
+ASTUnit.o: Attrs.inc.h
+ASTUnit.o: DeclNodes.inc.h
+ASTUnit.o: DiagnosticCommonKinds.inc.h
+ASTUnit.o: DiagnosticFrontendKinds.inc.h
+ASTUnit.o: Options.inc.h
+ASTUnit.o: StmtNodes.inc.h
+ASTUnit.po: AttrList.inc.h
+ASTUnit.po: AttrParsedAttrList.inc.h
+ASTUnit.po: Attrs.inc.h
+ASTUnit.po: DeclNodes.inc.h
+ASTUnit.po: DiagnosticCommonKinds.inc.h
+ASTUnit.po: DiagnosticFrontendKinds.inc.h
+ASTUnit.po: Options.inc.h
+ASTUnit.po: StmtNodes.inc.h
+CacheTokens.o: DiagnosticCommonKinds.inc.h
+CacheTokens.po: DiagnosticCommonKinds.inc.h
+ChainedDiagnosticConsumer.o: DiagnosticCommonKinds.inc.h
+ChainedDiagnosticConsumer.po: DiagnosticCommonKinds.inc.h
+ChainedIncludesSource.o: AttrList.inc.h
+ChainedIncludesSource.o: AttrParsedAttrList.inc.h
+ChainedIncludesSource.o: Attrs.inc.h
+ChainedIncludesSource.o: DeclNodes.inc.h
+ChainedIncludesSource.o: DiagnosticCommonKinds.inc.h
+ChainedIncludesSource.o: StmtNodes.inc.h
+ChainedIncludesSource.po: AttrList.inc.h
+ChainedIncludesSource.po: AttrParsedAttrList.inc.h
+ChainedIncludesSource.po: Attrs.inc.h
+ChainedIncludesSource.po: DeclNodes.inc.h
+ChainedIncludesSource.po: DiagnosticCommonKinds.inc.h
+ChainedIncludesSource.po: StmtNodes.inc.h
+CompilerInstance.o: AttrList.inc.h
+CompilerInstance.o: AttrParsedAttrList.inc.h
+CompilerInstance.o: Attrs.inc.h
+CompilerInstance.o: DeclNodes.inc.h
+CompilerInstance.o: DiagnosticCommonKinds.inc.h
+CompilerInstance.o: DiagnosticFrontendKinds.inc.h
+CompilerInstance.o: StmtNodes.inc.h
+CompilerInstance.po: AttrList.inc.h
+CompilerInstance.po: AttrParsedAttrList.inc.h
+CompilerInstance.po: Attrs.inc.h
+CompilerInstance.po: DeclNodes.inc.h
+CompilerInstance.po: DiagnosticCommonKinds.inc.h
+CompilerInstance.po: DiagnosticFrontendKinds.inc.h
+CompilerInstance.po: StmtNodes.inc.h
+CompilerInvocation.o: AttrList.inc.h
+CompilerInvocation.o: Attrs.inc.h
+CompilerInvocation.o: CC1Options.inc.h
+CompilerInvocation.o: DeclNodes.inc.h
+CompilerInvocation.o: DiagnosticCommonKinds.inc.h
+CompilerInvocation.o: DiagnosticDriverKinds.inc.h
+CompilerInvocation.po: AttrList.inc.h
+CompilerInvocation.po: Attrs.inc.h
+CompilerInvocation.po: CC1Options.inc.h
+CompilerInvocation.po: DeclNodes.inc.h
+CompilerInvocation.po: DiagnosticCommonKinds.inc.h
+CompilerInvocation.po: DiagnosticDriverKinds.inc.h
+CreateInvocationFromCommandLine.o: DiagnosticCommonKinds.inc.h
+CreateInvocationFromCommandLine.o: DiagnosticFrontendKinds.inc.h
+CreateInvocationFromCommandLine.o: Options.inc.h
+CreateInvocationFromCommandLine.po: DiagnosticCommonKinds.inc.h
+CreateInvocationFromCommandLine.po: DiagnosticFrontendKinds.inc.h
+CreateInvocationFromCommandLine.po: Options.inc.h
+DependencyFile.o: DiagnosticCommonKinds.inc.h
+DependencyFile.o: DiagnosticFrontendKinds.inc.h
+DependencyFile.o: DiagnosticLexKinds.inc.h
+DependencyFile.po: DiagnosticCommonKinds.inc.h
+DependencyFile.po: DiagnosticFrontendKinds.inc.h
+DependencyFile.po: DiagnosticLexKinds.inc.h
+DependencyGraph.o: DiagnosticCommonKinds.inc.h
+DependencyGraph.o: DiagnosticFrontendKinds.inc.h
+DependencyGraph.po: DiagnosticCommonKinds.inc.h
+DependencyGraph.po: DiagnosticFrontendKinds.inc.h
+DiagnosticRenderer.o: DiagnosticCommonKinds.inc.h
+DiagnosticRenderer.po: DiagnosticCommonKinds.inc.h
+FrontendAction.o: AttrList.inc.h
+FrontendAction.o: AttrParsedAttrList.inc.h
+FrontendAction.o: Attrs.inc.h
+FrontendAction.o: DeclNodes.inc.h
+FrontendAction.o: DiagnosticCommonKinds.inc.h
+FrontendAction.o: DiagnosticFrontendKinds.inc.h
+FrontendAction.o: StmtNodes.inc.h
+FrontendAction.po: AttrList.inc.h
+FrontendAction.po: AttrParsedAttrList.inc.h
+FrontendAction.po: Attrs.inc.h
+FrontendAction.po: DeclNodes.inc.h
+FrontendAction.po: DiagnosticCommonKinds.inc.h
+FrontendAction.po: DiagnosticFrontendKinds.inc.h
+FrontendAction.po: StmtNodes.inc.h
+FrontendActions.o: AttrList.inc.h
+FrontendActions.o: AttrParsedAttrList.inc.h
+FrontendActions.o: Attrs.inc.h
+FrontendActions.o: DeclNodes.inc.h
+FrontendActions.o: DiagnosticCommonKinds.inc.h
+FrontendActions.o: DiagnosticFrontendKinds.inc.h
+FrontendActions.o: StmtNodes.inc.h
+FrontendActions.po: AttrList.inc.h
+FrontendActions.po: AttrParsedAttrList.inc.h
+FrontendActions.po: Attrs.inc.h
+FrontendActions.po: DeclNodes.inc.h
+FrontendActions.po: DiagnosticCommonKinds.inc.h
+FrontendActions.po: DiagnosticFrontendKinds.inc.h
+FrontendActions.po: StmtNodes.inc.h
+HeaderIncludeGen.o: DiagnosticCommonKinds.inc.h
+HeaderIncludeGen.o: DiagnosticFrontendKinds.inc.h
+HeaderIncludeGen.po: DiagnosticCommonKinds.inc.h
+HeaderIncludeGen.po: DiagnosticFrontendKinds.inc.h
+InitHeaderSearch.o: DiagnosticCommonKinds.inc.h
+InitHeaderSearch.po: DiagnosticCommonKinds.inc.h
+InitPreprocessor.o: DiagnosticCommonKinds.inc.h
+InitPreprocessor.o: DiagnosticFrontendKinds.inc.h
+InitPreprocessor.po: DiagnosticCommonKinds.inc.h
+InitPreprocessor.po: DiagnosticFrontendKinds.inc.h
+LayoutOverrideSource.o: AttrList.inc.h
+LayoutOverrideSource.o: Attrs.inc.h
+LayoutOverrideSource.o: DeclNodes.inc.h
+LayoutOverrideSource.o: DiagnosticCommonKinds.inc.h
+LayoutOverrideSource.po: AttrList.inc.h
+LayoutOverrideSource.po: Attrs.inc.h
+LayoutOverrideSource.po: DeclNodes.inc.h
+LayoutOverrideSource.po: DiagnosticCommonKinds.inc.h
+LogDiagnosticPrinter.o: DiagnosticCommonKinds.inc.h
+LogDiagnosticPrinter.po: DiagnosticCommonKinds.inc.h
+MultiplexConsumer.o: DiagnosticCommonKinds.inc.h
+MultiplexConsumer.po: DiagnosticCommonKinds.inc.h
+PrintPreprocessedOutput.o: DiagnosticCommonKinds.inc.h
+PrintPreprocessedOutput.po: DiagnosticCommonKinds.inc.h
+SerializedDiagnosticPrinter.o: DiagnosticCommonKinds.inc.h
+SerializedDiagnosticPrinter.po: DiagnosticCommonKinds.inc.h
+TextDiagnostic.o: DiagnosticCommonKinds.inc.h
+TextDiagnostic.po: DiagnosticCommonKinds.inc.h
+TextDiagnosticBuffer.o: DiagnosticCommonKinds.inc.h
+TextDiagnosticBuffer.po: DiagnosticCommonKinds.inc.h
+TextDiagnosticPrinter.o: DiagnosticCommonKinds.inc.h
+TextDiagnosticPrinter.po: DiagnosticCommonKinds.inc.h
+VerifyDiagnosticConsumer.o: DiagnosticCommonKinds.inc.h
+VerifyDiagnosticConsumer.o: DiagnosticFrontendKinds.inc.h
+VerifyDiagnosticConsumer.po: DiagnosticCommonKinds.inc.h
+VerifyDiagnosticConsumer.po: DiagnosticFrontendKinds.inc.h
+Warnings.o: DiagnosticCommonKinds.inc.h
+Warnings.o: DiagnosticFrontendKinds.inc.h
+Warnings.o: DiagnosticLexKinds.inc.h
+Warnings.o: DiagnosticSemaKinds.inc.h
+Warnings.po: DiagnosticCommonKinds.inc.h
+Warnings.po: DiagnosticFrontendKinds.inc.h
+Warnings.po: DiagnosticLexKinds.inc.h
+Warnings.po: DiagnosticSemaKinds.inc.h
+.endif
diff --git a/lib/clang/libclangfrontendtool/Makefile.depend b/lib/clang/libclangfrontendtool/Makefile.depend
new file mode 100644
index 0000000..0c4a02d
--- /dev/null
+++ b/lib/clang/libclangfrontendtool/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ExecuteCompilerInvocation.o: CC1Options.inc.h
+ExecuteCompilerInvocation.o: DiagnosticCommonKinds.inc.h
+ExecuteCompilerInvocation.o: DiagnosticFrontendKinds.inc.h
+ExecuteCompilerInvocation.po: CC1Options.inc.h
+ExecuteCompilerInvocation.po: DiagnosticCommonKinds.inc.h
+ExecuteCompilerInvocation.po: DiagnosticFrontendKinds.inc.h
+.endif
diff --git a/lib/clang/libclanglex/Makefile.depend b/lib/clang/libclanglex/Makefile.depend
new file mode 100644
index 0000000..b0b30a1
--- /dev/null
+++ b/lib/clang/libclanglex/Makefile.depend
@@ -0,0 +1,83 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+HeaderSearch.o: DiagnosticCommonKinds.inc.h
+HeaderSearch.po: DiagnosticCommonKinds.inc.h
+Lexer.o: DiagnosticCommonKinds.inc.h
+Lexer.o: DiagnosticLexKinds.inc.h
+Lexer.po: DiagnosticCommonKinds.inc.h
+Lexer.po: DiagnosticLexKinds.inc.h
+LiteralSupport.o: DiagnosticCommonKinds.inc.h
+LiteralSupport.o: DiagnosticLexKinds.inc.h
+LiteralSupport.po: DiagnosticCommonKinds.inc.h
+LiteralSupport.po: DiagnosticLexKinds.inc.h
+MacroArgs.o: DiagnosticCommonKinds.inc.h
+MacroArgs.o: DiagnosticLexKinds.inc.h
+MacroArgs.po: DiagnosticCommonKinds.inc.h
+MacroArgs.po: DiagnosticLexKinds.inc.h
+MacroInfo.o: DiagnosticCommonKinds.inc.h
+MacroInfo.po: DiagnosticCommonKinds.inc.h
+ModuleMap.o: DiagnosticCommonKinds.inc.h
+ModuleMap.o: DiagnosticLexKinds.inc.h
+ModuleMap.po: DiagnosticCommonKinds.inc.h
+ModuleMap.po: DiagnosticLexKinds.inc.h
+PPCaching.o: DiagnosticCommonKinds.inc.h
+PPCaching.po: DiagnosticCommonKinds.inc.h
+PPCallbacks.o: DiagnosticCommonKinds.inc.h
+PPCallbacks.po: DiagnosticCommonKinds.inc.h
+PPDirectives.o: DiagnosticCommonKinds.inc.h
+PPDirectives.o: DiagnosticLexKinds.inc.h
+PPDirectives.po: DiagnosticCommonKinds.inc.h
+PPDirectives.po: DiagnosticLexKinds.inc.h
+PPExpressions.o: DiagnosticCommonKinds.inc.h
+PPExpressions.o: DiagnosticLexKinds.inc.h
+PPExpressions.po: DiagnosticCommonKinds.inc.h
+PPExpressions.po: DiagnosticLexKinds.inc.h
+PPLexerChange.o: DiagnosticCommonKinds.inc.h
+PPLexerChange.o: DiagnosticLexKinds.inc.h
+PPLexerChange.po: DiagnosticCommonKinds.inc.h
+PPLexerChange.po: DiagnosticLexKinds.inc.h
+PPMacroExpansion.o: AttrSpellings.inc.h
+PPMacroExpansion.o: DiagnosticCommonKinds.inc.h
+PPMacroExpansion.o: DiagnosticLexKinds.inc.h
+PPMacroExpansion.po: AttrSpellings.inc.h
+PPMacroExpansion.po: DiagnosticCommonKinds.inc.h
+PPMacroExpansion.po: DiagnosticLexKinds.inc.h
+PTHLexer.o: DiagnosticCommonKinds.inc.h
+PTHLexer.o: DiagnosticLexKinds.inc.h
+PTHLexer.po: DiagnosticCommonKinds.inc.h
+PTHLexer.po: DiagnosticLexKinds.inc.h
+Pragma.o: DiagnosticCommonKinds.inc.h
+Pragma.o: DiagnosticLexKinds.inc.h
+Pragma.po: DiagnosticCommonKinds.inc.h
+Pragma.po: DiagnosticLexKinds.inc.h
+PreprocessingRecord.o: DiagnosticCommonKinds.inc.h
+PreprocessingRecord.po: DiagnosticCommonKinds.inc.h
+Preprocessor.o: DiagnosticCommonKinds.inc.h
+Preprocessor.o: DiagnosticLexKinds.inc.h
+Preprocessor.po: DiagnosticCommonKinds.inc.h
+Preprocessor.po: DiagnosticLexKinds.inc.h
+PreprocessorLexer.o: DiagnosticCommonKinds.inc.h
+PreprocessorLexer.o: DiagnosticLexKinds.inc.h
+PreprocessorLexer.po: DiagnosticCommonKinds.inc.h
+PreprocessorLexer.po: DiagnosticLexKinds.inc.h
+TokenConcatenation.o: DiagnosticCommonKinds.inc.h
+TokenConcatenation.po: DiagnosticCommonKinds.inc.h
+TokenLexer.o: DiagnosticCommonKinds.inc.h
+TokenLexer.o: DiagnosticLexKinds.inc.h
+TokenLexer.po: DiagnosticCommonKinds.inc.h
+TokenLexer.po: DiagnosticLexKinds.inc.h
+.endif
diff --git a/lib/clang/libclangparse/Makefile.depend b/lib/clang/libclangparse/Makefile.depend
new file mode 100644
index 0000000..ebf96ff
--- /dev/null
+++ b/lib/clang/libclangparse/Makefile.depend
@@ -0,0 +1,199 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ParseAST.o: AttrList.inc.h
+ParseAST.o: AttrParsedAttrList.inc.h
+ParseAST.o: Attrs.inc.h
+ParseAST.o: DeclNodes.inc.h
+ParseAST.o: DiagnosticCommonKinds.inc.h
+ParseAST.o: StmtNodes.inc.h
+ParseAST.po: AttrList.inc.h
+ParseAST.po: AttrParsedAttrList.inc.h
+ParseAST.po: Attrs.inc.h
+ParseAST.po: DeclNodes.inc.h
+ParseAST.po: DiagnosticCommonKinds.inc.h
+ParseAST.po: StmtNodes.inc.h
+ParseCXXInlineMethods.o: AttrList.inc.h
+ParseCXXInlineMethods.o: AttrParsedAttrList.inc.h
+ParseCXXInlineMethods.o: Attrs.inc.h
+ParseCXXInlineMethods.o: DeclNodes.inc.h
+ParseCXXInlineMethods.o: DiagnosticCommonKinds.inc.h
+ParseCXXInlineMethods.o: DiagnosticParseKinds.inc.h
+ParseCXXInlineMethods.o: StmtNodes.inc.h
+ParseCXXInlineMethods.po: AttrList.inc.h
+ParseCXXInlineMethods.po: AttrParsedAttrList.inc.h
+ParseCXXInlineMethods.po: Attrs.inc.h
+ParseCXXInlineMethods.po: DeclNodes.inc.h
+ParseCXXInlineMethods.po: DiagnosticCommonKinds.inc.h
+ParseCXXInlineMethods.po: DiagnosticParseKinds.inc.h
+ParseCXXInlineMethods.po: StmtNodes.inc.h
+ParseDecl.o: AttrLateParsed.inc.h
+ParseDecl.o: AttrList.inc.h
+ParseDecl.o: AttrParsedAttrList.inc.h
+ParseDecl.o: Attrs.inc.h
+ParseDecl.o: DeclNodes.inc.h
+ParseDecl.o: DiagnosticCommonKinds.inc.h
+ParseDecl.o: DiagnosticParseKinds.inc.h
+ParseDecl.o: StmtNodes.inc.h
+ParseDecl.po: AttrLateParsed.inc.h
+ParseDecl.po: AttrList.inc.h
+ParseDecl.po: AttrParsedAttrList.inc.h
+ParseDecl.po: Attrs.inc.h
+ParseDecl.po: DeclNodes.inc.h
+ParseDecl.po: DiagnosticCommonKinds.inc.h
+ParseDecl.po: DiagnosticParseKinds.inc.h
+ParseDecl.po: StmtNodes.inc.h
+ParseDeclCXX.o: AttrList.inc.h
+ParseDeclCXX.o: AttrParsedAttrList.inc.h
+ParseDeclCXX.o: Attrs.inc.h
+ParseDeclCXX.o: DeclNodes.inc.h
+ParseDeclCXX.o: DiagnosticCommonKinds.inc.h
+ParseDeclCXX.o: DiagnosticParseKinds.inc.h
+ParseDeclCXX.o: StmtNodes.inc.h
+ParseDeclCXX.po: AttrList.inc.h
+ParseDeclCXX.po: AttrParsedAttrList.inc.h
+ParseDeclCXX.po: Attrs.inc.h
+ParseDeclCXX.po: DeclNodes.inc.h
+ParseDeclCXX.po: DiagnosticCommonKinds.inc.h
+ParseDeclCXX.po: DiagnosticParseKinds.inc.h
+ParseDeclCXX.po: StmtNodes.inc.h
+ParseExpr.o: AttrList.inc.h
+ParseExpr.o: AttrParsedAttrList.inc.h
+ParseExpr.o: Attrs.inc.h
+ParseExpr.o: DeclNodes.inc.h
+ParseExpr.o: DiagnosticCommonKinds.inc.h
+ParseExpr.o: DiagnosticParseKinds.inc.h
+ParseExpr.o: StmtNodes.inc.h
+ParseExpr.po: AttrList.inc.h
+ParseExpr.po: AttrParsedAttrList.inc.h
+ParseExpr.po: Attrs.inc.h
+ParseExpr.po: DeclNodes.inc.h
+ParseExpr.po: DiagnosticCommonKinds.inc.h
+ParseExpr.po: DiagnosticParseKinds.inc.h
+ParseExpr.po: StmtNodes.inc.h
+ParseExprCXX.o: AttrList.inc.h
+ParseExprCXX.o: AttrParsedAttrList.inc.h
+ParseExprCXX.o: Attrs.inc.h
+ParseExprCXX.o: DeclNodes.inc.h
+ParseExprCXX.o: DiagnosticCommonKinds.inc.h
+ParseExprCXX.o: DiagnosticParseKinds.inc.h
+ParseExprCXX.o: StmtNodes.inc.h
+ParseExprCXX.po: AttrList.inc.h
+ParseExprCXX.po: AttrParsedAttrList.inc.h
+ParseExprCXX.po: Attrs.inc.h
+ParseExprCXX.po: DeclNodes.inc.h
+ParseExprCXX.po: DiagnosticCommonKinds.inc.h
+ParseExprCXX.po: DiagnosticParseKinds.inc.h
+ParseExprCXX.po: StmtNodes.inc.h
+ParseInit.o: AttrList.inc.h
+ParseInit.o: AttrParsedAttrList.inc.h
+ParseInit.o: Attrs.inc.h
+ParseInit.o: DeclNodes.inc.h
+ParseInit.o: DiagnosticCommonKinds.inc.h
+ParseInit.o: DiagnosticParseKinds.inc.h
+ParseInit.o: StmtNodes.inc.h
+ParseInit.po: AttrList.inc.h
+ParseInit.po: AttrParsedAttrList.inc.h
+ParseInit.po: Attrs.inc.h
+ParseInit.po: DeclNodes.inc.h
+ParseInit.po: DiagnosticCommonKinds.inc.h
+ParseInit.po: DiagnosticParseKinds.inc.h
+ParseInit.po: StmtNodes.inc.h
+ParseObjc.o: AttrList.inc.h
+ParseObjc.o: AttrParsedAttrList.inc.h
+ParseObjc.o: Attrs.inc.h
+ParseObjc.o: DeclNodes.inc.h
+ParseObjc.o: DiagnosticCommonKinds.inc.h
+ParseObjc.o: DiagnosticParseKinds.inc.h
+ParseObjc.o: StmtNodes.inc.h
+ParseObjc.po: AttrList.inc.h
+ParseObjc.po: AttrParsedAttrList.inc.h
+ParseObjc.po: Attrs.inc.h
+ParseObjc.po: DeclNodes.inc.h
+ParseObjc.po: DiagnosticCommonKinds.inc.h
+ParseObjc.po: DiagnosticParseKinds.inc.h
+ParseObjc.po: StmtNodes.inc.h
+ParsePragma.o: AttrList.inc.h
+ParsePragma.o: AttrParsedAttrList.inc.h
+ParsePragma.o: Attrs.inc.h
+ParsePragma.o: DeclNodes.inc.h
+ParsePragma.o: DiagnosticCommonKinds.inc.h
+ParsePragma.o: DiagnosticParseKinds.inc.h
+ParsePragma.o: StmtNodes.inc.h
+ParsePragma.po: AttrList.inc.h
+ParsePragma.po: AttrParsedAttrList.inc.h
+ParsePragma.po: Attrs.inc.h
+ParsePragma.po: DeclNodes.inc.h
+ParsePragma.po: DiagnosticCommonKinds.inc.h
+ParsePragma.po: DiagnosticParseKinds.inc.h
+ParsePragma.po: StmtNodes.inc.h
+ParseStmt.o: AttrList.inc.h
+ParseStmt.o: AttrParsedAttrList.inc.h
+ParseStmt.o: Attrs.inc.h
+ParseStmt.o: DeclNodes.inc.h
+ParseStmt.o: DiagnosticCommonKinds.inc.h
+ParseStmt.o: DiagnosticParseKinds.inc.h
+ParseStmt.o: StmtNodes.inc.h
+ParseStmt.po: AttrList.inc.h
+ParseStmt.po: AttrParsedAttrList.inc.h
+ParseStmt.po: Attrs.inc.h
+ParseStmt.po: DeclNodes.inc.h
+ParseStmt.po: DiagnosticCommonKinds.inc.h
+ParseStmt.po: DiagnosticParseKinds.inc.h
+ParseStmt.po: StmtNodes.inc.h
+ParseTemplate.o: AttrList.inc.h
+ParseTemplate.o: AttrParsedAttrList.inc.h
+ParseTemplate.o: Attrs.inc.h
+ParseTemplate.o: DeclNodes.inc.h
+ParseTemplate.o: DiagnosticCommonKinds.inc.h
+ParseTemplate.o: DiagnosticParseKinds.inc.h
+ParseTemplate.o: StmtNodes.inc.h
+ParseTemplate.po: AttrList.inc.h
+ParseTemplate.po: AttrParsedAttrList.inc.h
+ParseTemplate.po: Attrs.inc.h
+ParseTemplate.po: DeclNodes.inc.h
+ParseTemplate.po: DiagnosticCommonKinds.inc.h
+ParseTemplate.po: DiagnosticParseKinds.inc.h
+ParseTemplate.po: StmtNodes.inc.h
+ParseTentative.o: AttrList.inc.h
+ParseTentative.o: AttrParsedAttrList.inc.h
+ParseTentative.o: Attrs.inc.h
+ParseTentative.o: DeclNodes.inc.h
+ParseTentative.o: DiagnosticCommonKinds.inc.h
+ParseTentative.o: DiagnosticParseKinds.inc.h
+ParseTentative.o: StmtNodes.inc.h
+ParseTentative.po: AttrList.inc.h
+ParseTentative.po: AttrParsedAttrList.inc.h
+ParseTentative.po: Attrs.inc.h
+ParseTentative.po: DeclNodes.inc.h
+ParseTentative.po: DiagnosticCommonKinds.inc.h
+ParseTentative.po: DiagnosticParseKinds.inc.h
+ParseTentative.po: StmtNodes.inc.h
+Parser.o: AttrList.inc.h
+Parser.o: AttrParsedAttrList.inc.h
+Parser.o: Attrs.inc.h
+Parser.o: DeclNodes.inc.h
+Parser.o: DiagnosticCommonKinds.inc.h
+Parser.o: DiagnosticParseKinds.inc.h
+Parser.o: StmtNodes.inc.h
+Parser.po: AttrList.inc.h
+Parser.po: AttrParsedAttrList.inc.h
+Parser.po: Attrs.inc.h
+Parser.po: DeclNodes.inc.h
+Parser.po: DiagnosticCommonKinds.inc.h
+Parser.po: DiagnosticParseKinds.inc.h
+Parser.po: StmtNodes.inc.h
+.endif
diff --git a/lib/clang/libclangrewrite/Makefile.depend b/lib/clang/libclangrewrite/Makefile.depend
new file mode 100644
index 0000000..ea0e441
--- /dev/null
+++ b/lib/clang/libclangrewrite/Makefile.depend
@@ -0,0 +1,79 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+FixItRewriter.o: DiagnosticCommonKinds.inc.h
+FixItRewriter.o: DiagnosticFrontendKinds.inc.h
+FixItRewriter.po: DiagnosticCommonKinds.inc.h
+FixItRewriter.po: DiagnosticFrontendKinds.inc.h
+FrontendActions.o: AttrList.inc.h
+FrontendActions.o: AttrParsedAttrList.inc.h
+FrontendActions.o: Attrs.inc.h
+FrontendActions.o: DeclNodes.inc.h
+FrontendActions.o: DiagnosticCommonKinds.inc.h
+FrontendActions.o: DiagnosticFrontendKinds.inc.h
+FrontendActions.o: StmtNodes.inc.h
+FrontendActions.po: AttrList.inc.h
+FrontendActions.po: AttrParsedAttrList.inc.h
+FrontendActions.po: Attrs.inc.h
+FrontendActions.po: DeclNodes.inc.h
+FrontendActions.po: DiagnosticCommonKinds.inc.h
+FrontendActions.po: DiagnosticFrontendKinds.inc.h
+FrontendActions.po: StmtNodes.inc.h
+HTMLPrint.o: AttrList.inc.h
+HTMLPrint.o: Attrs.inc.h
+HTMLPrint.o: DeclNodes.inc.h
+HTMLPrint.o: DiagnosticCommonKinds.inc.h
+HTMLPrint.po: AttrList.inc.h
+HTMLPrint.po: Attrs.inc.h
+HTMLPrint.po: DeclNodes.inc.h
+HTMLPrint.po: DiagnosticCommonKinds.inc.h
+HTMLRewrite.o: DiagnosticCommonKinds.inc.h
+HTMLRewrite.po: DiagnosticCommonKinds.inc.h
+RewriteMacros.o: DiagnosticCommonKinds.inc.h
+RewriteMacros.po: DiagnosticCommonKinds.inc.h
+RewriteModernObjC.o: AttrList.inc.h
+RewriteModernObjC.o: Attrs.inc.h
+RewriteModernObjC.o: DeclNodes.inc.h
+RewriteModernObjC.o: DiagnosticCommonKinds.inc.h
+RewriteModernObjC.o: StmtNodes.inc.h
+RewriteModernObjC.po: AttrList.inc.h
+RewriteModernObjC.po: Attrs.inc.h
+RewriteModernObjC.po: DeclNodes.inc.h
+RewriteModernObjC.po: DiagnosticCommonKinds.inc.h
+RewriteModernObjC.po: StmtNodes.inc.h
+RewriteObjC.o: AttrList.inc.h
+RewriteObjC.o: Attrs.inc.h
+RewriteObjC.o: DeclNodes.inc.h
+RewriteObjC.o: DiagnosticCommonKinds.inc.h
+RewriteObjC.o: StmtNodes.inc.h
+RewriteObjC.po: AttrList.inc.h
+RewriteObjC.po: Attrs.inc.h
+RewriteObjC.po: DeclNodes.inc.h
+RewriteObjC.po: DiagnosticCommonKinds.inc.h
+RewriteObjC.po: StmtNodes.inc.h
+RewriteTest.o: DiagnosticCommonKinds.inc.h
+RewriteTest.po: DiagnosticCommonKinds.inc.h
+Rewriter.o: AttrList.inc.h
+Rewriter.o: Attrs.inc.h
+Rewriter.o: DeclNodes.inc.h
+Rewriter.o: DiagnosticCommonKinds.inc.h
+Rewriter.o: StmtNodes.inc.h
+Rewriter.po: AttrList.inc.h
+Rewriter.po: Attrs.inc.h
+Rewriter.po: DeclNodes.inc.h
+Rewriter.po: DiagnosticCommonKinds.inc.h
+Rewriter.po: StmtNodes.inc.h
+.endif
diff --git a/lib/clang/libclangsema/Makefile.depend b/lib/clang/libclangsema/Makefile.depend
new file mode 100644
index 0000000..d33e42f
--- /dev/null
+++ b/lib/clang/libclangsema/Makefile.depend
@@ -0,0 +1,563 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+AnalysisBasedWarnings.o: AttrList.inc.h
+AnalysisBasedWarnings.o: AttrParsedAttrList.inc.h
+AnalysisBasedWarnings.o: Attrs.inc.h
+AnalysisBasedWarnings.o: DeclNodes.inc.h
+AnalysisBasedWarnings.o: DiagnosticCommonKinds.inc.h
+AnalysisBasedWarnings.o: DiagnosticSemaKinds.inc.h
+AnalysisBasedWarnings.o: StmtNodes.inc.h
+AnalysisBasedWarnings.po: AttrList.inc.h
+AnalysisBasedWarnings.po: AttrParsedAttrList.inc.h
+AnalysisBasedWarnings.po: Attrs.inc.h
+AnalysisBasedWarnings.po: DeclNodes.inc.h
+AnalysisBasedWarnings.po: DiagnosticCommonKinds.inc.h
+AnalysisBasedWarnings.po: DiagnosticSemaKinds.inc.h
+AnalysisBasedWarnings.po: StmtNodes.inc.h
+AttributeList.o: AttrList.inc.h
+AttributeList.o: AttrParsedAttrKinds.inc.h
+AttributeList.o: AttrParsedAttrList.inc.h
+AttributeList.o: Attrs.inc.h
+AttributeList.o: DeclNodes.inc.h
+AttributeList.o: DiagnosticCommonKinds.inc.h
+AttributeList.o: StmtNodes.inc.h
+AttributeList.po: AttrList.inc.h
+AttributeList.po: AttrParsedAttrKinds.inc.h
+AttributeList.po: AttrParsedAttrList.inc.h
+AttributeList.po: Attrs.inc.h
+AttributeList.po: DeclNodes.inc.h
+AttributeList.po: DiagnosticCommonKinds.inc.h
+AttributeList.po: StmtNodes.inc.h
+CodeCompleteConsumer.o: AttrList.inc.h
+CodeCompleteConsumer.o: AttrParsedAttrList.inc.h
+CodeCompleteConsumer.o: Attrs.inc.h
+CodeCompleteConsumer.o: DeclNodes.inc.h
+CodeCompleteConsumer.o: DiagnosticCommonKinds.inc.h
+CodeCompleteConsumer.o: StmtNodes.inc.h
+CodeCompleteConsumer.po: AttrList.inc.h
+CodeCompleteConsumer.po: AttrParsedAttrList.inc.h
+CodeCompleteConsumer.po: Attrs.inc.h
+CodeCompleteConsumer.po: DeclNodes.inc.h
+CodeCompleteConsumer.po: DiagnosticCommonKinds.inc.h
+CodeCompleteConsumer.po: StmtNodes.inc.h
+DeclSpec.o: AttrList.inc.h
+DeclSpec.o: AttrParsedAttrList.inc.h
+DeclSpec.o: Attrs.inc.h
+DeclSpec.o: DeclNodes.inc.h
+DeclSpec.o: DiagnosticCommonKinds.inc.h
+DeclSpec.o: DiagnosticParseKinds.inc.h
+DeclSpec.o: DiagnosticSemaKinds.inc.h
+DeclSpec.o: StmtNodes.inc.h
+DeclSpec.po: AttrList.inc.h
+DeclSpec.po: AttrParsedAttrList.inc.h
+DeclSpec.po: Attrs.inc.h
+DeclSpec.po: DeclNodes.inc.h
+DeclSpec.po: DiagnosticCommonKinds.inc.h
+DeclSpec.po: DiagnosticParseKinds.inc.h
+DeclSpec.po: DiagnosticSemaKinds.inc.h
+DeclSpec.po: StmtNodes.inc.h
+DelayedDiagnostic.o: AttrList.inc.h
+DelayedDiagnostic.o: Attrs.inc.h
+DelayedDiagnostic.o: DeclNodes.inc.h
+DelayedDiagnostic.o: DiagnosticCommonKinds.inc.h
+DelayedDiagnostic.o: StmtNodes.inc.h
+DelayedDiagnostic.po: AttrList.inc.h
+DelayedDiagnostic.po: Attrs.inc.h
+DelayedDiagnostic.po: DeclNodes.inc.h
+DelayedDiagnostic.po: DiagnosticCommonKinds.inc.h
+DelayedDiagnostic.po: StmtNodes.inc.h
+IdentifierResolver.o: AttrList.inc.h
+IdentifierResolver.o: Attrs.inc.h
+IdentifierResolver.o: DeclNodes.inc.h
+IdentifierResolver.o: DiagnosticCommonKinds.inc.h
+IdentifierResolver.po: AttrList.inc.h
+IdentifierResolver.po: Attrs.inc.h
+IdentifierResolver.po: DeclNodes.inc.h
+IdentifierResolver.po: DiagnosticCommonKinds.inc.h
+JumpDiagnostics.o: AttrList.inc.h
+JumpDiagnostics.o: AttrParsedAttrList.inc.h
+JumpDiagnostics.o: Attrs.inc.h
+JumpDiagnostics.o: DeclNodes.inc.h
+JumpDiagnostics.o: DiagnosticCommonKinds.inc.h
+JumpDiagnostics.o: DiagnosticSemaKinds.inc.h
+JumpDiagnostics.o: StmtNodes.inc.h
+JumpDiagnostics.po: AttrList.inc.h
+JumpDiagnostics.po: AttrParsedAttrList.inc.h
+JumpDiagnostics.po: Attrs.inc.h
+JumpDiagnostics.po: DeclNodes.inc.h
+JumpDiagnostics.po: DiagnosticCommonKinds.inc.h
+JumpDiagnostics.po: DiagnosticSemaKinds.inc.h
+JumpDiagnostics.po: StmtNodes.inc.h
+Scope.o: DiagnosticCommonKinds.inc.h
+Scope.po: DiagnosticCommonKinds.inc.h
+Sema.o: AttrList.inc.h
+Sema.o: AttrParsedAttrList.inc.h
+Sema.o: Attrs.inc.h
+Sema.o: DeclNodes.inc.h
+Sema.o: DiagnosticASTKinds.inc.h
+Sema.o: DiagnosticCommonKinds.inc.h
+Sema.o: DiagnosticSemaKinds.inc.h
+Sema.o: StmtNodes.inc.h
+Sema.po: AttrList.inc.h
+Sema.po: AttrParsedAttrList.inc.h
+Sema.po: Attrs.inc.h
+Sema.po: DeclNodes.inc.h
+Sema.po: DiagnosticASTKinds.inc.h
+Sema.po: DiagnosticCommonKinds.inc.h
+Sema.po: DiagnosticSemaKinds.inc.h
+Sema.po: StmtNodes.inc.h
+SemaAccess.o: AttrList.inc.h
+SemaAccess.o: AttrParsedAttrList.inc.h
+SemaAccess.o: Attrs.inc.h
+SemaAccess.o: DeclNodes.inc.h
+SemaAccess.o: DiagnosticCommonKinds.inc.h
+SemaAccess.o: DiagnosticSemaKinds.inc.h
+SemaAccess.o: StmtNodes.inc.h
+SemaAccess.po: AttrList.inc.h
+SemaAccess.po: AttrParsedAttrList.inc.h
+SemaAccess.po: Attrs.inc.h
+SemaAccess.po: DeclNodes.inc.h
+SemaAccess.po: DiagnosticCommonKinds.inc.h
+SemaAccess.po: DiagnosticSemaKinds.inc.h
+SemaAccess.po: StmtNodes.inc.h
+SemaAttr.o: AttrList.inc.h
+SemaAttr.o: AttrParsedAttrList.inc.h
+SemaAttr.o: Attrs.inc.h
+SemaAttr.o: DeclNodes.inc.h
+SemaAttr.o: DiagnosticCommonKinds.inc.h
+SemaAttr.o: DiagnosticSemaKinds.inc.h
+SemaAttr.o: StmtNodes.inc.h
+SemaAttr.po: AttrList.inc.h
+SemaAttr.po: AttrParsedAttrList.inc.h
+SemaAttr.po: Attrs.inc.h
+SemaAttr.po: DeclNodes.inc.h
+SemaAttr.po: DiagnosticCommonKinds.inc.h
+SemaAttr.po: DiagnosticSemaKinds.inc.h
+SemaAttr.po: StmtNodes.inc.h
+SemaCXXScopeSpec.o: AttrList.inc.h
+SemaCXXScopeSpec.o: AttrParsedAttrList.inc.h
+SemaCXXScopeSpec.o: Attrs.inc.h
+SemaCXXScopeSpec.o: DeclNodes.inc.h
+SemaCXXScopeSpec.o: DiagnosticCommonKinds.inc.h
+SemaCXXScopeSpec.o: DiagnosticSemaKinds.inc.h
+SemaCXXScopeSpec.o: StmtNodes.inc.h
+SemaCXXScopeSpec.po: AttrList.inc.h
+SemaCXXScopeSpec.po: AttrParsedAttrList.inc.h
+SemaCXXScopeSpec.po: Attrs.inc.h
+SemaCXXScopeSpec.po: DeclNodes.inc.h
+SemaCXXScopeSpec.po: DiagnosticCommonKinds.inc.h
+SemaCXXScopeSpec.po: DiagnosticSemaKinds.inc.h
+SemaCXXScopeSpec.po: StmtNodes.inc.h
+SemaCast.o: AttrList.inc.h
+SemaCast.o: AttrParsedAttrList.inc.h
+SemaCast.o: Attrs.inc.h
+SemaCast.o: DeclNodes.inc.h
+SemaCast.o: DiagnosticCommonKinds.inc.h
+SemaCast.o: DiagnosticSemaKinds.inc.h
+SemaCast.o: StmtNodes.inc.h
+SemaCast.po: AttrList.inc.h
+SemaCast.po: AttrParsedAttrList.inc.h
+SemaCast.po: Attrs.inc.h
+SemaCast.po: DeclNodes.inc.h
+SemaCast.po: DiagnosticCommonKinds.inc.h
+SemaCast.po: DiagnosticSemaKinds.inc.h
+SemaCast.po: StmtNodes.inc.h
+SemaChecking.o: AttrList.inc.h
+SemaChecking.o: AttrParsedAttrList.inc.h
+SemaChecking.o: Attrs.inc.h
+SemaChecking.o: DeclNodes.inc.h
+SemaChecking.o: DiagnosticCommonKinds.inc.h
+SemaChecking.o: DiagnosticSemaKinds.inc.h
+SemaChecking.o: StmtNodes.inc.h
+SemaChecking.o: arm_neon.inc.h
+SemaChecking.po: AttrList.inc.h
+SemaChecking.po: AttrParsedAttrList.inc.h
+SemaChecking.po: Attrs.inc.h
+SemaChecking.po: DeclNodes.inc.h
+SemaChecking.po: DiagnosticCommonKinds.inc.h
+SemaChecking.po: DiagnosticSemaKinds.inc.h
+SemaChecking.po: StmtNodes.inc.h
+SemaChecking.po: arm_neon.inc.h
+SemaCodeComplete.o: AttrList.inc.h
+SemaCodeComplete.o: AttrParsedAttrList.inc.h
+SemaCodeComplete.o: Attrs.inc.h
+SemaCodeComplete.o: DeclNodes.inc.h
+SemaCodeComplete.o: DiagnosticCommonKinds.inc.h
+SemaCodeComplete.o: DiagnosticSemaKinds.inc.h
+SemaCodeComplete.o: StmtNodes.inc.h
+SemaCodeComplete.po: AttrList.inc.h
+SemaCodeComplete.po: AttrParsedAttrList.inc.h
+SemaCodeComplete.po: Attrs.inc.h
+SemaCodeComplete.po: DeclNodes.inc.h
+SemaCodeComplete.po: DiagnosticCommonKinds.inc.h
+SemaCodeComplete.po: DiagnosticSemaKinds.inc.h
+SemaCodeComplete.po: StmtNodes.inc.h
+SemaDecl.o: AttrList.inc.h
+SemaDecl.o: AttrParsedAttrList.inc.h
+SemaDecl.o: Attrs.inc.h
+SemaDecl.o: DeclNodes.inc.h
+SemaDecl.o: DiagnosticCommonKinds.inc.h
+SemaDecl.o: DiagnosticParseKinds.inc.h
+SemaDecl.o: DiagnosticSemaKinds.inc.h
+SemaDecl.o: StmtNodes.inc.h
+SemaDecl.po: AttrList.inc.h
+SemaDecl.po: AttrParsedAttrList.inc.h
+SemaDecl.po: Attrs.inc.h
+SemaDecl.po: DeclNodes.inc.h
+SemaDecl.po: DiagnosticCommonKinds.inc.h
+SemaDecl.po: DiagnosticParseKinds.inc.h
+SemaDecl.po: DiagnosticSemaKinds.inc.h
+SemaDecl.po: StmtNodes.inc.h
+SemaDeclAttr.o: AttrList.inc.h
+SemaDeclAttr.o: AttrParsedAttrList.inc.h
+SemaDeclAttr.o: Attrs.inc.h
+SemaDeclAttr.o: DeclNodes.inc.h
+SemaDeclAttr.o: DiagnosticCommonKinds.inc.h
+SemaDeclAttr.o: DiagnosticSemaKinds.inc.h
+SemaDeclAttr.o: StmtNodes.inc.h
+SemaDeclAttr.po: AttrList.inc.h
+SemaDeclAttr.po: AttrParsedAttrList.inc.h
+SemaDeclAttr.po: Attrs.inc.h
+SemaDeclAttr.po: DeclNodes.inc.h
+SemaDeclAttr.po: DiagnosticCommonKinds.inc.h
+SemaDeclAttr.po: DiagnosticSemaKinds.inc.h
+SemaDeclAttr.po: StmtNodes.inc.h
+SemaDeclCXX.o: AttrList.inc.h
+SemaDeclCXX.o: AttrParsedAttrList.inc.h
+SemaDeclCXX.o: Attrs.inc.h
+SemaDeclCXX.o: DeclNodes.inc.h
+SemaDeclCXX.o: DiagnosticCommonKinds.inc.h
+SemaDeclCXX.o: DiagnosticSemaKinds.inc.h
+SemaDeclCXX.o: StmtNodes.inc.h
+SemaDeclCXX.po: AttrList.inc.h
+SemaDeclCXX.po: AttrParsedAttrList.inc.h
+SemaDeclCXX.po: Attrs.inc.h
+SemaDeclCXX.po: DeclNodes.inc.h
+SemaDeclCXX.po: DiagnosticCommonKinds.inc.h
+SemaDeclCXX.po: DiagnosticSemaKinds.inc.h
+SemaDeclCXX.po: StmtNodes.inc.h
+SemaDeclObjC.o: AttrList.inc.h
+SemaDeclObjC.o: AttrParsedAttrList.inc.h
+SemaDeclObjC.o: Attrs.inc.h
+SemaDeclObjC.o: DeclNodes.inc.h
+SemaDeclObjC.o: DiagnosticCommonKinds.inc.h
+SemaDeclObjC.o: DiagnosticSemaKinds.inc.h
+SemaDeclObjC.o: StmtNodes.inc.h
+SemaDeclObjC.po: AttrList.inc.h
+SemaDeclObjC.po: AttrParsedAttrList.inc.h
+SemaDeclObjC.po: Attrs.inc.h
+SemaDeclObjC.po: DeclNodes.inc.h
+SemaDeclObjC.po: DiagnosticCommonKinds.inc.h
+SemaDeclObjC.po: DiagnosticSemaKinds.inc.h
+SemaDeclObjC.po: StmtNodes.inc.h
+SemaExceptionSpec.o: AttrList.inc.h
+SemaExceptionSpec.o: AttrParsedAttrList.inc.h
+SemaExceptionSpec.o: Attrs.inc.h
+SemaExceptionSpec.o: DeclNodes.inc.h
+SemaExceptionSpec.o: DiagnosticCommonKinds.inc.h
+SemaExceptionSpec.o: DiagnosticSemaKinds.inc.h
+SemaExceptionSpec.o: StmtNodes.inc.h
+SemaExceptionSpec.po: AttrList.inc.h
+SemaExceptionSpec.po: AttrParsedAttrList.inc.h
+SemaExceptionSpec.po: Attrs.inc.h
+SemaExceptionSpec.po: DeclNodes.inc.h
+SemaExceptionSpec.po: DiagnosticCommonKinds.inc.h
+SemaExceptionSpec.po: DiagnosticSemaKinds.inc.h
+SemaExceptionSpec.po: StmtNodes.inc.h
+SemaExpr.o: AttrList.inc.h
+SemaExpr.o: AttrParsedAttrList.inc.h
+SemaExpr.o: Attrs.inc.h
+SemaExpr.o: DeclNodes.inc.h
+SemaExpr.o: DiagnosticCommonKinds.inc.h
+SemaExpr.o: DiagnosticSemaKinds.inc.h
+SemaExpr.o: StmtNodes.inc.h
+SemaExpr.po: AttrList.inc.h
+SemaExpr.po: AttrParsedAttrList.inc.h
+SemaExpr.po: Attrs.inc.h
+SemaExpr.po: DeclNodes.inc.h
+SemaExpr.po: DiagnosticCommonKinds.inc.h
+SemaExpr.po: DiagnosticSemaKinds.inc.h
+SemaExpr.po: StmtNodes.inc.h
+SemaExprCXX.o: AttrList.inc.h
+SemaExprCXX.o: AttrParsedAttrList.inc.h
+SemaExprCXX.o: Attrs.inc.h
+SemaExprCXX.o: DeclNodes.inc.h
+SemaExprCXX.o: DiagnosticCommonKinds.inc.h
+SemaExprCXX.o: DiagnosticSemaKinds.inc.h
+SemaExprCXX.o: StmtNodes.inc.h
+SemaExprCXX.po: AttrList.inc.h
+SemaExprCXX.po: AttrParsedAttrList.inc.h
+SemaExprCXX.po: Attrs.inc.h
+SemaExprCXX.po: DeclNodes.inc.h
+SemaExprCXX.po: DiagnosticCommonKinds.inc.h
+SemaExprCXX.po: DiagnosticSemaKinds.inc.h
+SemaExprCXX.po: StmtNodes.inc.h
+SemaExprMember.o: AttrList.inc.h
+SemaExprMember.o: AttrParsedAttrList.inc.h
+SemaExprMember.o: Attrs.inc.h
+SemaExprMember.o: DeclNodes.inc.h
+SemaExprMember.o: DiagnosticCommonKinds.inc.h
+SemaExprMember.o: DiagnosticSemaKinds.inc.h
+SemaExprMember.o: StmtNodes.inc.h
+SemaExprMember.po: AttrList.inc.h
+SemaExprMember.po: AttrParsedAttrList.inc.h
+SemaExprMember.po: Attrs.inc.h
+SemaExprMember.po: DeclNodes.inc.h
+SemaExprMember.po: DiagnosticCommonKinds.inc.h
+SemaExprMember.po: DiagnosticSemaKinds.inc.h
+SemaExprMember.po: StmtNodes.inc.h
+SemaExprObjC.o: AttrList.inc.h
+SemaExprObjC.o: AttrParsedAttrList.inc.h
+SemaExprObjC.o: Attrs.inc.h
+SemaExprObjC.o: DeclNodes.inc.h
+SemaExprObjC.o: DiagnosticCommonKinds.inc.h
+SemaExprObjC.o: DiagnosticSemaKinds.inc.h
+SemaExprObjC.o: StmtNodes.inc.h
+SemaExprObjC.po: AttrList.inc.h
+SemaExprObjC.po: AttrParsedAttrList.inc.h
+SemaExprObjC.po: Attrs.inc.h
+SemaExprObjC.po: DeclNodes.inc.h
+SemaExprObjC.po: DiagnosticCommonKinds.inc.h
+SemaExprObjC.po: DiagnosticSemaKinds.inc.h
+SemaExprObjC.po: StmtNodes.inc.h
+SemaFixItUtils.o: AttrList.inc.h
+SemaFixItUtils.o: AttrParsedAttrList.inc.h
+SemaFixItUtils.o: Attrs.inc.h
+SemaFixItUtils.o: DeclNodes.inc.h
+SemaFixItUtils.o: DiagnosticCommonKinds.inc.h
+SemaFixItUtils.o: StmtNodes.inc.h
+SemaFixItUtils.po: AttrList.inc.h
+SemaFixItUtils.po: AttrParsedAttrList.inc.h
+SemaFixItUtils.po: Attrs.inc.h
+SemaFixItUtils.po: DeclNodes.inc.h
+SemaFixItUtils.po: DiagnosticCommonKinds.inc.h
+SemaFixItUtils.po: StmtNodes.inc.h
+SemaInit.o: AttrList.inc.h
+SemaInit.o: AttrParsedAttrList.inc.h
+SemaInit.o: Attrs.inc.h
+SemaInit.o: DeclNodes.inc.h
+SemaInit.o: DiagnosticCommonKinds.inc.h
+SemaInit.o: DiagnosticSemaKinds.inc.h
+SemaInit.o: StmtNodes.inc.h
+SemaInit.po: AttrList.inc.h
+SemaInit.po: AttrParsedAttrList.inc.h
+SemaInit.po: Attrs.inc.h
+SemaInit.po: DeclNodes.inc.h
+SemaInit.po: DiagnosticCommonKinds.inc.h
+SemaInit.po: DiagnosticSemaKinds.inc.h
+SemaInit.po: StmtNodes.inc.h
+SemaLambda.o: AttrList.inc.h
+SemaLambda.o: AttrParsedAttrList.inc.h
+SemaLambda.o: Attrs.inc.h
+SemaLambda.o: DeclNodes.inc.h
+SemaLambda.o: DiagnosticCommonKinds.inc.h
+SemaLambda.o: DiagnosticSemaKinds.inc.h
+SemaLambda.o: StmtNodes.inc.h
+SemaLambda.po: AttrList.inc.h
+SemaLambda.po: AttrParsedAttrList.inc.h
+SemaLambda.po: Attrs.inc.h
+SemaLambda.po: DeclNodes.inc.h
+SemaLambda.po: DiagnosticCommonKinds.inc.h
+SemaLambda.po: DiagnosticSemaKinds.inc.h
+SemaLambda.po: StmtNodes.inc.h
+SemaLookup.o: AttrList.inc.h
+SemaLookup.o: AttrParsedAttrList.inc.h
+SemaLookup.o: Attrs.inc.h
+SemaLookup.o: DeclNodes.inc.h
+SemaLookup.o: DiagnosticCommonKinds.inc.h
+SemaLookup.o: DiagnosticSemaKinds.inc.h
+SemaLookup.o: StmtNodes.inc.h
+SemaLookup.po: AttrList.inc.h
+SemaLookup.po: AttrParsedAttrList.inc.h
+SemaLookup.po: Attrs.inc.h
+SemaLookup.po: DeclNodes.inc.h
+SemaLookup.po: DiagnosticCommonKinds.inc.h
+SemaLookup.po: DiagnosticSemaKinds.inc.h
+SemaLookup.po: StmtNodes.inc.h
+SemaObjCProperty.o: AttrList.inc.h
+SemaObjCProperty.o: AttrParsedAttrList.inc.h
+SemaObjCProperty.o: Attrs.inc.h
+SemaObjCProperty.o: DeclNodes.inc.h
+SemaObjCProperty.o: DiagnosticCommonKinds.inc.h
+SemaObjCProperty.o: DiagnosticSemaKinds.inc.h
+SemaObjCProperty.o: StmtNodes.inc.h
+SemaObjCProperty.po: AttrList.inc.h
+SemaObjCProperty.po: AttrParsedAttrList.inc.h
+SemaObjCProperty.po: Attrs.inc.h
+SemaObjCProperty.po: DeclNodes.inc.h
+SemaObjCProperty.po: DiagnosticCommonKinds.inc.h
+SemaObjCProperty.po: DiagnosticSemaKinds.inc.h
+SemaObjCProperty.po: StmtNodes.inc.h
+SemaOverload.o: AttrList.inc.h
+SemaOverload.o: AttrParsedAttrList.inc.h
+SemaOverload.o: Attrs.inc.h
+SemaOverload.o: DeclNodes.inc.h
+SemaOverload.o: DiagnosticCommonKinds.inc.h
+SemaOverload.o: DiagnosticSemaKinds.inc.h
+SemaOverload.o: StmtNodes.inc.h
+SemaOverload.po: AttrList.inc.h
+SemaOverload.po: AttrParsedAttrList.inc.h
+SemaOverload.po: Attrs.inc.h
+SemaOverload.po: DeclNodes.inc.h
+SemaOverload.po: DiagnosticCommonKinds.inc.h
+SemaOverload.po: DiagnosticSemaKinds.inc.h
+SemaOverload.po: StmtNodes.inc.h
+SemaPseudoObject.o: AttrList.inc.h
+SemaPseudoObject.o: AttrParsedAttrList.inc.h
+SemaPseudoObject.o: Attrs.inc.h
+SemaPseudoObject.o: DeclNodes.inc.h
+SemaPseudoObject.o: DiagnosticCommonKinds.inc.h
+SemaPseudoObject.o: DiagnosticSemaKinds.inc.h
+SemaPseudoObject.o: StmtNodes.inc.h
+SemaPseudoObject.po: AttrList.inc.h
+SemaPseudoObject.po: AttrParsedAttrList.inc.h
+SemaPseudoObject.po: Attrs.inc.h
+SemaPseudoObject.po: DeclNodes.inc.h
+SemaPseudoObject.po: DiagnosticCommonKinds.inc.h
+SemaPseudoObject.po: DiagnosticSemaKinds.inc.h
+SemaPseudoObject.po: StmtNodes.inc.h
+SemaStmt.o: AttrList.inc.h
+SemaStmt.o: AttrParsedAttrList.inc.h
+SemaStmt.o: Attrs.inc.h
+SemaStmt.o: DeclNodes.inc.h
+SemaStmt.o: DiagnosticCommonKinds.inc.h
+SemaStmt.o: DiagnosticSemaKinds.inc.h
+SemaStmt.o: StmtNodes.inc.h
+SemaStmt.po: AttrList.inc.h
+SemaStmt.po: AttrParsedAttrList.inc.h
+SemaStmt.po: Attrs.inc.h
+SemaStmt.po: DeclNodes.inc.h
+SemaStmt.po: DiagnosticCommonKinds.inc.h
+SemaStmt.po: DiagnosticSemaKinds.inc.h
+SemaStmt.po: StmtNodes.inc.h
+SemaStmtAttr.o: AttrList.inc.h
+SemaStmtAttr.o: AttrParsedAttrList.inc.h
+SemaStmtAttr.o: Attrs.inc.h
+SemaStmtAttr.o: DeclNodes.inc.h
+SemaStmtAttr.o: DiagnosticCommonKinds.inc.h
+SemaStmtAttr.o: DiagnosticSemaKinds.inc.h
+SemaStmtAttr.o: StmtNodes.inc.h
+SemaStmtAttr.po: AttrList.inc.h
+SemaStmtAttr.po: AttrParsedAttrList.inc.h
+SemaStmtAttr.po: Attrs.inc.h
+SemaStmtAttr.po: DeclNodes.inc.h
+SemaStmtAttr.po: DiagnosticCommonKinds.inc.h
+SemaStmtAttr.po: DiagnosticSemaKinds.inc.h
+SemaStmtAttr.po: StmtNodes.inc.h
+SemaTemplate.o: AttrList.inc.h
+SemaTemplate.o: AttrParsedAttrList.inc.h
+SemaTemplate.o: Attrs.inc.h
+SemaTemplate.o: DeclNodes.inc.h
+SemaTemplate.o: DiagnosticCommonKinds.inc.h
+SemaTemplate.o: DiagnosticSemaKinds.inc.h
+SemaTemplate.o: StmtNodes.inc.h
+SemaTemplate.po: AttrList.inc.h
+SemaTemplate.po: AttrParsedAttrList.inc.h
+SemaTemplate.po: Attrs.inc.h
+SemaTemplate.po: DeclNodes.inc.h
+SemaTemplate.po: DiagnosticCommonKinds.inc.h
+SemaTemplate.po: DiagnosticSemaKinds.inc.h
+SemaTemplate.po: StmtNodes.inc.h
+SemaTemplateDeduction.o: AttrList.inc.h
+SemaTemplateDeduction.o: AttrParsedAttrList.inc.h
+SemaTemplateDeduction.o: Attrs.inc.h
+SemaTemplateDeduction.o: DeclNodes.inc.h
+SemaTemplateDeduction.o: DiagnosticCommonKinds.inc.h
+SemaTemplateDeduction.o: DiagnosticSemaKinds.inc.h
+SemaTemplateDeduction.o: StmtNodes.inc.h
+SemaTemplateDeduction.po: AttrList.inc.h
+SemaTemplateDeduction.po: AttrParsedAttrList.inc.h
+SemaTemplateDeduction.po: Attrs.inc.h
+SemaTemplateDeduction.po: DeclNodes.inc.h
+SemaTemplateDeduction.po: DiagnosticCommonKinds.inc.h
+SemaTemplateDeduction.po: DiagnosticSemaKinds.inc.h
+SemaTemplateDeduction.po: StmtNodes.inc.h
+SemaTemplateInstantiate.o: AttrList.inc.h
+SemaTemplateInstantiate.o: AttrParsedAttrList.inc.h
+SemaTemplateInstantiate.o: Attrs.inc.h
+SemaTemplateInstantiate.o: DeclNodes.inc.h
+SemaTemplateInstantiate.o: DiagnosticCommonKinds.inc.h
+SemaTemplateInstantiate.o: DiagnosticSemaKinds.inc.h
+SemaTemplateInstantiate.o: StmtNodes.inc.h
+SemaTemplateInstantiate.po: AttrList.inc.h
+SemaTemplateInstantiate.po: AttrParsedAttrList.inc.h
+SemaTemplateInstantiate.po: Attrs.inc.h
+SemaTemplateInstantiate.po: DeclNodes.inc.h
+SemaTemplateInstantiate.po: DiagnosticCommonKinds.inc.h
+SemaTemplateInstantiate.po: DiagnosticSemaKinds.inc.h
+SemaTemplateInstantiate.po: StmtNodes.inc.h
+SemaTemplateInstantiateDecl.o: AttrList.inc.h
+SemaTemplateInstantiateDecl.o: AttrParsedAttrList.inc.h
+SemaTemplateInstantiateDecl.o: AttrTemplateInstantiate.inc.h
+SemaTemplateInstantiateDecl.o: Attrs.inc.h
+SemaTemplateInstantiateDecl.o: DeclNodes.inc.h
+SemaTemplateInstantiateDecl.o: DiagnosticCommonKinds.inc.h
+SemaTemplateInstantiateDecl.o: DiagnosticSemaKinds.inc.h
+SemaTemplateInstantiateDecl.o: StmtNodes.inc.h
+SemaTemplateInstantiateDecl.po: AttrList.inc.h
+SemaTemplateInstantiateDecl.po: AttrParsedAttrList.inc.h
+SemaTemplateInstantiateDecl.po: AttrTemplateInstantiate.inc.h
+SemaTemplateInstantiateDecl.po: Attrs.inc.h
+SemaTemplateInstantiateDecl.po: DeclNodes.inc.h
+SemaTemplateInstantiateDecl.po: DiagnosticCommonKinds.inc.h
+SemaTemplateInstantiateDecl.po: DiagnosticSemaKinds.inc.h
+SemaTemplateInstantiateDecl.po: StmtNodes.inc.h
+SemaTemplateVariadic.o: AttrList.inc.h
+SemaTemplateVariadic.o: AttrParsedAttrList.inc.h
+SemaTemplateVariadic.o: Attrs.inc.h
+SemaTemplateVariadic.o: DeclNodes.inc.h
+SemaTemplateVariadic.o: DiagnosticCommonKinds.inc.h
+SemaTemplateVariadic.o: DiagnosticSemaKinds.inc.h
+SemaTemplateVariadic.o: StmtNodes.inc.h
+SemaTemplateVariadic.po: AttrList.inc.h
+SemaTemplateVariadic.po: AttrParsedAttrList.inc.h
+SemaTemplateVariadic.po: Attrs.inc.h
+SemaTemplateVariadic.po: DeclNodes.inc.h
+SemaTemplateVariadic.po: DiagnosticCommonKinds.inc.h
+SemaTemplateVariadic.po: DiagnosticSemaKinds.inc.h
+SemaTemplateVariadic.po: StmtNodes.inc.h
+SemaType.o: AttrList.inc.h
+SemaType.o: AttrParsedAttrList.inc.h
+SemaType.o: Attrs.inc.h
+SemaType.o: DeclNodes.inc.h
+SemaType.o: DiagnosticCommonKinds.inc.h
+SemaType.o: DiagnosticParseKinds.inc.h
+SemaType.o: DiagnosticSemaKinds.inc.h
+SemaType.o: StmtNodes.inc.h
+SemaType.po: AttrList.inc.h
+SemaType.po: AttrParsedAttrList.inc.h
+SemaType.po: Attrs.inc.h
+SemaType.po: DeclNodes.inc.h
+SemaType.po: DiagnosticCommonKinds.inc.h
+SemaType.po: DiagnosticParseKinds.inc.h
+SemaType.po: DiagnosticSemaKinds.inc.h
+SemaType.po: StmtNodes.inc.h
+TargetAttributesSema.o: AttrList.inc.h
+TargetAttributesSema.o: AttrParsedAttrList.inc.h
+TargetAttributesSema.o: Attrs.inc.h
+TargetAttributesSema.o: DeclNodes.inc.h
+TargetAttributesSema.o: DiagnosticCommonKinds.inc.h
+TargetAttributesSema.o: DiagnosticSemaKinds.inc.h
+TargetAttributesSema.o: StmtNodes.inc.h
+TargetAttributesSema.po: AttrList.inc.h
+TargetAttributesSema.po: AttrParsedAttrList.inc.h
+TargetAttributesSema.po: Attrs.inc.h
+TargetAttributesSema.po: DeclNodes.inc.h
+TargetAttributesSema.po: DiagnosticCommonKinds.inc.h
+TargetAttributesSema.po: DiagnosticSemaKinds.inc.h
+TargetAttributesSema.po: StmtNodes.inc.h
+.endif
diff --git a/lib/clang/libclangserialization/Makefile.depend b/lib/clang/libclangserialization/Makefile.depend
new file mode 100644
index 0000000..96ace89
--- /dev/null
+++ b/lib/clang/libclangserialization/Makefile.depend
@@ -0,0 +1,111 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ASTCommon.o: AttrList.inc.h
+ASTCommon.o: Attrs.inc.h
+ASTCommon.o: DeclNodes.inc.h
+ASTCommon.o: DiagnosticCommonKinds.inc.h
+ASTCommon.po: AttrList.inc.h
+ASTCommon.po: Attrs.inc.h
+ASTCommon.po: DeclNodes.inc.h
+ASTCommon.po: DiagnosticCommonKinds.inc.h
+ASTReader.o: AttrList.inc.h
+ASTReader.o: AttrParsedAttrList.inc.h
+ASTReader.o: Attrs.inc.h
+ASTReader.o: DeclNodes.inc.h
+ASTReader.o: DiagnosticCommonKinds.inc.h
+ASTReader.o: DiagnosticSerializationKinds.inc.h
+ASTReader.o: StmtNodes.inc.h
+ASTReader.po: AttrList.inc.h
+ASTReader.po: AttrParsedAttrList.inc.h
+ASTReader.po: Attrs.inc.h
+ASTReader.po: DeclNodes.inc.h
+ASTReader.po: DiagnosticCommonKinds.inc.h
+ASTReader.po: DiagnosticSerializationKinds.inc.h
+ASTReader.po: StmtNodes.inc.h
+ASTReaderDecl.o: AttrList.inc.h
+ASTReaderDecl.o: AttrPCHRead.inc.h
+ASTReaderDecl.o: AttrParsedAttrList.inc.h
+ASTReaderDecl.o: Attrs.inc.h
+ASTReaderDecl.o: DeclNodes.inc.h
+ASTReaderDecl.o: DiagnosticCommonKinds.inc.h
+ASTReaderDecl.o: DiagnosticSemaKinds.inc.h
+ASTReaderDecl.o: StmtNodes.inc.h
+ASTReaderDecl.po: AttrList.inc.h
+ASTReaderDecl.po: AttrPCHRead.inc.h
+ASTReaderDecl.po: AttrParsedAttrList.inc.h
+ASTReaderDecl.po: Attrs.inc.h
+ASTReaderDecl.po: DeclNodes.inc.h
+ASTReaderDecl.po: DiagnosticCommonKinds.inc.h
+ASTReaderDecl.po: DiagnosticSemaKinds.inc.h
+ASTReaderDecl.po: StmtNodes.inc.h
+ASTReaderStmt.o: AttrList.inc.h
+ASTReaderStmt.o: Attrs.inc.h
+ASTReaderStmt.o: DeclNodes.inc.h
+ASTReaderStmt.o: DiagnosticCommonKinds.inc.h
+ASTReaderStmt.o: StmtNodes.inc.h
+ASTReaderStmt.po: AttrList.inc.h
+ASTReaderStmt.po: Attrs.inc.h
+ASTReaderStmt.po: DeclNodes.inc.h
+ASTReaderStmt.po: DiagnosticCommonKinds.inc.h
+ASTReaderStmt.po: StmtNodes.inc.h
+ASTWriter.o: AttrList.inc.h
+ASTWriter.o: AttrPCHWrite.inc.h
+ASTWriter.o: AttrParsedAttrList.inc.h
+ASTWriter.o: Attrs.inc.h
+ASTWriter.o: DeclNodes.inc.h
+ASTWriter.o: DiagnosticCommonKinds.inc.h
+ASTWriter.o: StmtNodes.inc.h
+ASTWriter.po: AttrList.inc.h
+ASTWriter.po: AttrPCHWrite.inc.h
+ASTWriter.po: AttrParsedAttrList.inc.h
+ASTWriter.po: Attrs.inc.h
+ASTWriter.po: DeclNodes.inc.h
+ASTWriter.po: DiagnosticCommonKinds.inc.h
+ASTWriter.po: StmtNodes.inc.h
+ASTWriterDecl.o: AttrList.inc.h
+ASTWriterDecl.o: Attrs.inc.h
+ASTWriterDecl.o: DeclNodes.inc.h
+ASTWriterDecl.o: DiagnosticCommonKinds.inc.h
+ASTWriterDecl.o: StmtNodes.inc.h
+ASTWriterDecl.po: AttrList.inc.h
+ASTWriterDecl.po: Attrs.inc.h
+ASTWriterDecl.po: DeclNodes.inc.h
+ASTWriterDecl.po: DiagnosticCommonKinds.inc.h
+ASTWriterDecl.po: StmtNodes.inc.h
+ASTWriterStmt.o: AttrList.inc.h
+ASTWriterStmt.o: Attrs.inc.h
+ASTWriterStmt.o: DeclNodes.inc.h
+ASTWriterStmt.o: DiagnosticCommonKinds.inc.h
+ASTWriterStmt.o: StmtNodes.inc.h
+ASTWriterStmt.po: AttrList.inc.h
+ASTWriterStmt.po: Attrs.inc.h
+ASTWriterStmt.po: DeclNodes.inc.h
+ASTWriterStmt.po: DiagnosticCommonKinds.inc.h
+ASTWriterStmt.po: StmtNodes.inc.h
+GeneratePCH.o: AttrList.inc.h
+GeneratePCH.o: Attrs.inc.h
+GeneratePCH.o: DeclNodes.inc.h
+GeneratePCH.o: DiagnosticCommonKinds.inc.h
+GeneratePCH.po: AttrList.inc.h
+GeneratePCH.po: Attrs.inc.h
+GeneratePCH.po: DeclNodes.inc.h
+GeneratePCH.po: DiagnosticCommonKinds.inc.h
+Module.o: DiagnosticCommonKinds.inc.h
+Module.po: DiagnosticCommonKinds.inc.h
+ModuleManager.o: DiagnosticCommonKinds.inc.h
+ModuleManager.po: DiagnosticCommonKinds.inc.h
+.endif
diff --git a/lib/clang/libclangstaticanalyzercheckers/Makefile.depend b/lib/clang/libclangstaticanalyzercheckers/Makefile.depend
new file mode 100644
index 0000000..d287f2b
--- /dev/null
+++ b/lib/clang/libclangstaticanalyzercheckers/Makefile.depend
@@ -0,0 +1,749 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+AdjustedReturnValueChecker.o: AttrList.inc.h
+AdjustedReturnValueChecker.o: Attrs.inc.h
+AdjustedReturnValueChecker.o: Checkers.inc.h
+AdjustedReturnValueChecker.o: DeclNodes.inc.h
+AdjustedReturnValueChecker.o: DiagnosticCommonKinds.inc.h
+AdjustedReturnValueChecker.o: StmtNodes.inc.h
+AdjustedReturnValueChecker.po: AttrList.inc.h
+AdjustedReturnValueChecker.po: Attrs.inc.h
+AdjustedReturnValueChecker.po: Checkers.inc.h
+AdjustedReturnValueChecker.po: DeclNodes.inc.h
+AdjustedReturnValueChecker.po: DiagnosticCommonKinds.inc.h
+AdjustedReturnValueChecker.po: StmtNodes.inc.h
+AnalyzerStatsChecker.o: AttrList.inc.h
+AnalyzerStatsChecker.o: Attrs.inc.h
+AnalyzerStatsChecker.o: Checkers.inc.h
+AnalyzerStatsChecker.o: DeclNodes.inc.h
+AnalyzerStatsChecker.o: DiagnosticCommonKinds.inc.h
+AnalyzerStatsChecker.o: StmtNodes.inc.h
+AnalyzerStatsChecker.po: AttrList.inc.h
+AnalyzerStatsChecker.po: Attrs.inc.h
+AnalyzerStatsChecker.po: Checkers.inc.h
+AnalyzerStatsChecker.po: DeclNodes.inc.h
+AnalyzerStatsChecker.po: DiagnosticCommonKinds.inc.h
+AnalyzerStatsChecker.po: StmtNodes.inc.h
+ArrayBoundChecker.o: AttrList.inc.h
+ArrayBoundChecker.o: Attrs.inc.h
+ArrayBoundChecker.o: Checkers.inc.h
+ArrayBoundChecker.o: DeclNodes.inc.h
+ArrayBoundChecker.o: DiagnosticCommonKinds.inc.h
+ArrayBoundChecker.o: StmtNodes.inc.h
+ArrayBoundChecker.po: AttrList.inc.h
+ArrayBoundChecker.po: Attrs.inc.h
+ArrayBoundChecker.po: Checkers.inc.h
+ArrayBoundChecker.po: DeclNodes.inc.h
+ArrayBoundChecker.po: DiagnosticCommonKinds.inc.h
+ArrayBoundChecker.po: StmtNodes.inc.h
+ArrayBoundCheckerV2.o: AttrList.inc.h
+ArrayBoundCheckerV2.o: Attrs.inc.h
+ArrayBoundCheckerV2.o: Checkers.inc.h
+ArrayBoundCheckerV2.o: DeclNodes.inc.h
+ArrayBoundCheckerV2.o: DiagnosticCommonKinds.inc.h
+ArrayBoundCheckerV2.o: StmtNodes.inc.h
+ArrayBoundCheckerV2.po: AttrList.inc.h
+ArrayBoundCheckerV2.po: Attrs.inc.h
+ArrayBoundCheckerV2.po: Checkers.inc.h
+ArrayBoundCheckerV2.po: DeclNodes.inc.h
+ArrayBoundCheckerV2.po: DiagnosticCommonKinds.inc.h
+ArrayBoundCheckerV2.po: StmtNodes.inc.h
+AttrNonNullChecker.o: AttrList.inc.h
+AttrNonNullChecker.o: Attrs.inc.h
+AttrNonNullChecker.o: Checkers.inc.h
+AttrNonNullChecker.o: DeclNodes.inc.h
+AttrNonNullChecker.o: DiagnosticCommonKinds.inc.h
+AttrNonNullChecker.o: StmtNodes.inc.h
+AttrNonNullChecker.po: AttrList.inc.h
+AttrNonNullChecker.po: Attrs.inc.h
+AttrNonNullChecker.po: Checkers.inc.h
+AttrNonNullChecker.po: DeclNodes.inc.h
+AttrNonNullChecker.po: DiagnosticCommonKinds.inc.h
+AttrNonNullChecker.po: StmtNodes.inc.h
+BasicObjCFoundationChecks.o: AttrList.inc.h
+BasicObjCFoundationChecks.o: Attrs.inc.h
+BasicObjCFoundationChecks.o: Checkers.inc.h
+BasicObjCFoundationChecks.o: DeclNodes.inc.h
+BasicObjCFoundationChecks.o: DiagnosticCommonKinds.inc.h
+BasicObjCFoundationChecks.o: StmtNodes.inc.h
+BasicObjCFoundationChecks.po: AttrList.inc.h
+BasicObjCFoundationChecks.po: Attrs.inc.h
+BasicObjCFoundationChecks.po: Checkers.inc.h
+BasicObjCFoundationChecks.po: DeclNodes.inc.h
+BasicObjCFoundationChecks.po: DiagnosticCommonKinds.inc.h
+BasicObjCFoundationChecks.po: StmtNodes.inc.h
+BoolAssignmentChecker.o: AttrList.inc.h
+BoolAssignmentChecker.o: Attrs.inc.h
+BoolAssignmentChecker.o: Checkers.inc.h
+BoolAssignmentChecker.o: DeclNodes.inc.h
+BoolAssignmentChecker.o: DiagnosticCommonKinds.inc.h
+BoolAssignmentChecker.o: StmtNodes.inc.h
+BoolAssignmentChecker.po: AttrList.inc.h
+BoolAssignmentChecker.po: Attrs.inc.h
+BoolAssignmentChecker.po: Checkers.inc.h
+BoolAssignmentChecker.po: DeclNodes.inc.h
+BoolAssignmentChecker.po: DiagnosticCommonKinds.inc.h
+BoolAssignmentChecker.po: StmtNodes.inc.h
+BuiltinFunctionChecker.o: AttrList.inc.h
+BuiltinFunctionChecker.o: Attrs.inc.h
+BuiltinFunctionChecker.o: Checkers.inc.h
+BuiltinFunctionChecker.o: DeclNodes.inc.h
+BuiltinFunctionChecker.o: DiagnosticCommonKinds.inc.h
+BuiltinFunctionChecker.o: StmtNodes.inc.h
+BuiltinFunctionChecker.po: AttrList.inc.h
+BuiltinFunctionChecker.po: Attrs.inc.h
+BuiltinFunctionChecker.po: Checkers.inc.h
+BuiltinFunctionChecker.po: DeclNodes.inc.h
+BuiltinFunctionChecker.po: DiagnosticCommonKinds.inc.h
+BuiltinFunctionChecker.po: StmtNodes.inc.h
+CStringChecker.o: AttrList.inc.h
+CStringChecker.o: Attrs.inc.h
+CStringChecker.o: Checkers.inc.h
+CStringChecker.o: DeclNodes.inc.h
+CStringChecker.o: DiagnosticCommonKinds.inc.h
+CStringChecker.o: StmtNodes.inc.h
+CStringChecker.po: AttrList.inc.h
+CStringChecker.po: Attrs.inc.h
+CStringChecker.po: Checkers.inc.h
+CStringChecker.po: DeclNodes.inc.h
+CStringChecker.po: DiagnosticCommonKinds.inc.h
+CStringChecker.po: StmtNodes.inc.h
+CStringSyntaxChecker.o: AttrList.inc.h
+CStringSyntaxChecker.o: Attrs.inc.h
+CStringSyntaxChecker.o: Checkers.inc.h
+CStringSyntaxChecker.o: DeclNodes.inc.h
+CStringSyntaxChecker.o: DiagnosticCommonKinds.inc.h
+CStringSyntaxChecker.o: StmtNodes.inc.h
+CStringSyntaxChecker.po: AttrList.inc.h
+CStringSyntaxChecker.po: Attrs.inc.h
+CStringSyntaxChecker.po: Checkers.inc.h
+CStringSyntaxChecker.po: DeclNodes.inc.h
+CStringSyntaxChecker.po: DiagnosticCommonKinds.inc.h
+CStringSyntaxChecker.po: StmtNodes.inc.h
+CallAndMessageChecker.o: AttrList.inc.h
+CallAndMessageChecker.o: Attrs.inc.h
+CallAndMessageChecker.o: Checkers.inc.h
+CallAndMessageChecker.o: DeclNodes.inc.h
+CallAndMessageChecker.o: DiagnosticCommonKinds.inc.h
+CallAndMessageChecker.o: StmtNodes.inc.h
+CallAndMessageChecker.po: AttrList.inc.h
+CallAndMessageChecker.po: Attrs.inc.h
+CallAndMessageChecker.po: Checkers.inc.h
+CallAndMessageChecker.po: DeclNodes.inc.h
+CallAndMessageChecker.po: DiagnosticCommonKinds.inc.h
+CallAndMessageChecker.po: StmtNodes.inc.h
+CastSizeChecker.o: AttrList.inc.h
+CastSizeChecker.o: Attrs.inc.h
+CastSizeChecker.o: Checkers.inc.h
+CastSizeChecker.o: DeclNodes.inc.h
+CastSizeChecker.o: DiagnosticCommonKinds.inc.h
+CastSizeChecker.o: StmtNodes.inc.h
+CastSizeChecker.po: AttrList.inc.h
+CastSizeChecker.po: Attrs.inc.h
+CastSizeChecker.po: Checkers.inc.h
+CastSizeChecker.po: DeclNodes.inc.h
+CastSizeChecker.po: DiagnosticCommonKinds.inc.h
+CastSizeChecker.po: StmtNodes.inc.h
+CastToStructChecker.o: AttrList.inc.h
+CastToStructChecker.o: Attrs.inc.h
+CastToStructChecker.o: Checkers.inc.h
+CastToStructChecker.o: DeclNodes.inc.h
+CastToStructChecker.o: DiagnosticCommonKinds.inc.h
+CastToStructChecker.o: StmtNodes.inc.h
+CastToStructChecker.po: AttrList.inc.h
+CastToStructChecker.po: Attrs.inc.h
+CastToStructChecker.po: Checkers.inc.h
+CastToStructChecker.po: DeclNodes.inc.h
+CastToStructChecker.po: DiagnosticCommonKinds.inc.h
+CastToStructChecker.po: StmtNodes.inc.h
+CheckObjCDealloc.o: AttrList.inc.h
+CheckObjCDealloc.o: Attrs.inc.h
+CheckObjCDealloc.o: Checkers.inc.h
+CheckObjCDealloc.o: DeclNodes.inc.h
+CheckObjCDealloc.o: DiagnosticCommonKinds.inc.h
+CheckObjCDealloc.o: StmtNodes.inc.h
+CheckObjCDealloc.po: AttrList.inc.h
+CheckObjCDealloc.po: Attrs.inc.h
+CheckObjCDealloc.po: Checkers.inc.h
+CheckObjCDealloc.po: DeclNodes.inc.h
+CheckObjCDealloc.po: DiagnosticCommonKinds.inc.h
+CheckObjCDealloc.po: StmtNodes.inc.h
+CheckObjCInstMethSignature.o: AttrList.inc.h
+CheckObjCInstMethSignature.o: Attrs.inc.h
+CheckObjCInstMethSignature.o: Checkers.inc.h
+CheckObjCInstMethSignature.o: DeclNodes.inc.h
+CheckObjCInstMethSignature.o: DiagnosticCommonKinds.inc.h
+CheckObjCInstMethSignature.o: StmtNodes.inc.h
+CheckObjCInstMethSignature.po: AttrList.inc.h
+CheckObjCInstMethSignature.po: Attrs.inc.h
+CheckObjCInstMethSignature.po: Checkers.inc.h
+CheckObjCInstMethSignature.po: DeclNodes.inc.h
+CheckObjCInstMethSignature.po: DiagnosticCommonKinds.inc.h
+CheckObjCInstMethSignature.po: StmtNodes.inc.h
+CheckSecuritySyntaxOnly.o: AttrList.inc.h
+CheckSecuritySyntaxOnly.o: Attrs.inc.h
+CheckSecuritySyntaxOnly.o: Checkers.inc.h
+CheckSecuritySyntaxOnly.o: DeclNodes.inc.h
+CheckSecuritySyntaxOnly.o: DiagnosticCommonKinds.inc.h
+CheckSecuritySyntaxOnly.o: StmtNodes.inc.h
+CheckSecuritySyntaxOnly.po: AttrList.inc.h
+CheckSecuritySyntaxOnly.po: Attrs.inc.h
+CheckSecuritySyntaxOnly.po: Checkers.inc.h
+CheckSecuritySyntaxOnly.po: DeclNodes.inc.h
+CheckSecuritySyntaxOnly.po: DiagnosticCommonKinds.inc.h
+CheckSecuritySyntaxOnly.po: StmtNodes.inc.h
+CheckSizeofPointer.o: AttrList.inc.h
+CheckSizeofPointer.o: Attrs.inc.h
+CheckSizeofPointer.o: Checkers.inc.h
+CheckSizeofPointer.o: DeclNodes.inc.h
+CheckSizeofPointer.o: DiagnosticCommonKinds.inc.h
+CheckSizeofPointer.o: StmtNodes.inc.h
+CheckSizeofPointer.po: AttrList.inc.h
+CheckSizeofPointer.po: Attrs.inc.h
+CheckSizeofPointer.po: Checkers.inc.h
+CheckSizeofPointer.po: DeclNodes.inc.h
+CheckSizeofPointer.po: DiagnosticCommonKinds.inc.h
+CheckSizeofPointer.po: StmtNodes.inc.h
+CheckerDocumentation.o: AttrList.inc.h
+CheckerDocumentation.o: Attrs.inc.h
+CheckerDocumentation.o: Checkers.inc.h
+CheckerDocumentation.o: DeclNodes.inc.h
+CheckerDocumentation.o: DiagnosticCommonKinds.inc.h
+CheckerDocumentation.o: StmtNodes.inc.h
+CheckerDocumentation.po: AttrList.inc.h
+CheckerDocumentation.po: Attrs.inc.h
+CheckerDocumentation.po: Checkers.inc.h
+CheckerDocumentation.po: DeclNodes.inc.h
+CheckerDocumentation.po: DiagnosticCommonKinds.inc.h
+CheckerDocumentation.po: StmtNodes.inc.h
+ChrootChecker.o: AttrList.inc.h
+ChrootChecker.o: Attrs.inc.h
+ChrootChecker.o: Checkers.inc.h
+ChrootChecker.o: DeclNodes.inc.h
+ChrootChecker.o: DiagnosticCommonKinds.inc.h
+ChrootChecker.o: StmtNodes.inc.h
+ChrootChecker.po: AttrList.inc.h
+ChrootChecker.po: Attrs.inc.h
+ChrootChecker.po: Checkers.inc.h
+ChrootChecker.po: DeclNodes.inc.h
+ChrootChecker.po: DiagnosticCommonKinds.inc.h
+ChrootChecker.po: StmtNodes.inc.h
+ClangCheckers.o: AttrList.inc.h
+ClangCheckers.o: Attrs.inc.h
+ClangCheckers.o: Checkers.inc.h
+ClangCheckers.o: DeclNodes.inc.h
+ClangCheckers.o: DiagnosticCommonKinds.inc.h
+ClangCheckers.o: StmtNodes.inc.h
+ClangCheckers.po: AttrList.inc.h
+ClangCheckers.po: Attrs.inc.h
+ClangCheckers.po: Checkers.inc.h
+ClangCheckers.po: DeclNodes.inc.h
+ClangCheckers.po: DiagnosticCommonKinds.inc.h
+ClangCheckers.po: StmtNodes.inc.h
+DeadStoresChecker.o: AttrList.inc.h
+DeadStoresChecker.o: Attrs.inc.h
+DeadStoresChecker.o: Checkers.inc.h
+DeadStoresChecker.o: DeclNodes.inc.h
+DeadStoresChecker.o: DiagnosticCommonKinds.inc.h
+DeadStoresChecker.o: StmtNodes.inc.h
+DeadStoresChecker.po: AttrList.inc.h
+DeadStoresChecker.po: Attrs.inc.h
+DeadStoresChecker.po: Checkers.inc.h
+DeadStoresChecker.po: DeclNodes.inc.h
+DeadStoresChecker.po: DiagnosticCommonKinds.inc.h
+DeadStoresChecker.po: StmtNodes.inc.h
+DebugCheckers.o: AttrList.inc.h
+DebugCheckers.o: Attrs.inc.h
+DebugCheckers.o: Checkers.inc.h
+DebugCheckers.o: DeclNodes.inc.h
+DebugCheckers.o: DiagnosticCommonKinds.inc.h
+DebugCheckers.o: StmtNodes.inc.h
+DebugCheckers.po: AttrList.inc.h
+DebugCheckers.po: Attrs.inc.h
+DebugCheckers.po: Checkers.inc.h
+DebugCheckers.po: DeclNodes.inc.h
+DebugCheckers.po: DiagnosticCommonKinds.inc.h
+DebugCheckers.po: StmtNodes.inc.h
+DereferenceChecker.o: AttrList.inc.h
+DereferenceChecker.o: Attrs.inc.h
+DereferenceChecker.o: Checkers.inc.h
+DereferenceChecker.o: DeclNodes.inc.h
+DereferenceChecker.o: DiagnosticCommonKinds.inc.h
+DereferenceChecker.o: StmtNodes.inc.h
+DereferenceChecker.po: AttrList.inc.h
+DereferenceChecker.po: Attrs.inc.h
+DereferenceChecker.po: Checkers.inc.h
+DereferenceChecker.po: DeclNodes.inc.h
+DereferenceChecker.po: DiagnosticCommonKinds.inc.h
+DereferenceChecker.po: StmtNodes.inc.h
+DivZeroChecker.o: AttrList.inc.h
+DivZeroChecker.o: Attrs.inc.h
+DivZeroChecker.o: Checkers.inc.h
+DivZeroChecker.o: DeclNodes.inc.h
+DivZeroChecker.o: DiagnosticCommonKinds.inc.h
+DivZeroChecker.o: StmtNodes.inc.h
+DivZeroChecker.po: AttrList.inc.h
+DivZeroChecker.po: Attrs.inc.h
+DivZeroChecker.po: Checkers.inc.h
+DivZeroChecker.po: DeclNodes.inc.h
+DivZeroChecker.po: DiagnosticCommonKinds.inc.h
+DivZeroChecker.po: StmtNodes.inc.h
+FixedAddressChecker.o: AttrList.inc.h
+FixedAddressChecker.o: Attrs.inc.h
+FixedAddressChecker.o: Checkers.inc.h
+FixedAddressChecker.o: DeclNodes.inc.h
+FixedAddressChecker.o: DiagnosticCommonKinds.inc.h
+FixedAddressChecker.o: StmtNodes.inc.h
+FixedAddressChecker.po: AttrList.inc.h
+FixedAddressChecker.po: Attrs.inc.h
+FixedAddressChecker.po: Checkers.inc.h
+FixedAddressChecker.po: DeclNodes.inc.h
+FixedAddressChecker.po: DiagnosticCommonKinds.inc.h
+FixedAddressChecker.po: StmtNodes.inc.h
+GenericTaintChecker.o: AttrList.inc.h
+GenericTaintChecker.o: Attrs.inc.h
+GenericTaintChecker.o: Checkers.inc.h
+GenericTaintChecker.o: DeclNodes.inc.h
+GenericTaintChecker.o: DiagnosticCommonKinds.inc.h
+GenericTaintChecker.o: StmtNodes.inc.h
+GenericTaintChecker.po: AttrList.inc.h
+GenericTaintChecker.po: Attrs.inc.h
+GenericTaintChecker.po: Checkers.inc.h
+GenericTaintChecker.po: DeclNodes.inc.h
+GenericTaintChecker.po: DiagnosticCommonKinds.inc.h
+GenericTaintChecker.po: StmtNodes.inc.h
+IdempotentOperationChecker.o: AttrList.inc.h
+IdempotentOperationChecker.o: Attrs.inc.h
+IdempotentOperationChecker.o: Checkers.inc.h
+IdempotentOperationChecker.o: DeclNodes.inc.h
+IdempotentOperationChecker.o: DiagnosticCommonKinds.inc.h
+IdempotentOperationChecker.o: StmtNodes.inc.h
+IdempotentOperationChecker.po: AttrList.inc.h
+IdempotentOperationChecker.po: Attrs.inc.h
+IdempotentOperationChecker.po: Checkers.inc.h
+IdempotentOperationChecker.po: DeclNodes.inc.h
+IdempotentOperationChecker.po: DiagnosticCommonKinds.inc.h
+IdempotentOperationChecker.po: StmtNodes.inc.h
+IteratorsChecker.o: AttrList.inc.h
+IteratorsChecker.o: Attrs.inc.h
+IteratorsChecker.o: Checkers.inc.h
+IteratorsChecker.o: DeclNodes.inc.h
+IteratorsChecker.o: DiagnosticCommonKinds.inc.h
+IteratorsChecker.o: StmtNodes.inc.h
+IteratorsChecker.po: AttrList.inc.h
+IteratorsChecker.po: Attrs.inc.h
+IteratorsChecker.po: Checkers.inc.h
+IteratorsChecker.po: DeclNodes.inc.h
+IteratorsChecker.po: DiagnosticCommonKinds.inc.h
+IteratorsChecker.po: StmtNodes.inc.h
+LLVMConventionsChecker.o: AttrList.inc.h
+LLVMConventionsChecker.o: Attrs.inc.h
+LLVMConventionsChecker.o: Checkers.inc.h
+LLVMConventionsChecker.o: DeclNodes.inc.h
+LLVMConventionsChecker.o: DiagnosticCommonKinds.inc.h
+LLVMConventionsChecker.o: StmtNodes.inc.h
+LLVMConventionsChecker.po: AttrList.inc.h
+LLVMConventionsChecker.po: Attrs.inc.h
+LLVMConventionsChecker.po: Checkers.inc.h
+LLVMConventionsChecker.po: DeclNodes.inc.h
+LLVMConventionsChecker.po: DiagnosticCommonKinds.inc.h
+LLVMConventionsChecker.po: StmtNodes.inc.h
+MacOSKeychainAPIChecker.o: AttrList.inc.h
+MacOSKeychainAPIChecker.o: Attrs.inc.h
+MacOSKeychainAPIChecker.o: Checkers.inc.h
+MacOSKeychainAPIChecker.o: DeclNodes.inc.h
+MacOSKeychainAPIChecker.o: DiagnosticCommonKinds.inc.h
+MacOSKeychainAPIChecker.o: StmtNodes.inc.h
+MacOSKeychainAPIChecker.po: AttrList.inc.h
+MacOSKeychainAPIChecker.po: Attrs.inc.h
+MacOSKeychainAPIChecker.po: Checkers.inc.h
+MacOSKeychainAPIChecker.po: DeclNodes.inc.h
+MacOSKeychainAPIChecker.po: DiagnosticCommonKinds.inc.h
+MacOSKeychainAPIChecker.po: StmtNodes.inc.h
+MacOSXAPIChecker.o: AttrList.inc.h
+MacOSXAPIChecker.o: Attrs.inc.h
+MacOSXAPIChecker.o: Checkers.inc.h
+MacOSXAPIChecker.o: DeclNodes.inc.h
+MacOSXAPIChecker.o: DiagnosticCommonKinds.inc.h
+MacOSXAPIChecker.o: StmtNodes.inc.h
+MacOSXAPIChecker.po: AttrList.inc.h
+MacOSXAPIChecker.po: Attrs.inc.h
+MacOSXAPIChecker.po: Checkers.inc.h
+MacOSXAPIChecker.po: DeclNodes.inc.h
+MacOSXAPIChecker.po: DiagnosticCommonKinds.inc.h
+MacOSXAPIChecker.po: StmtNodes.inc.h
+MallocChecker.o: AttrList.inc.h
+MallocChecker.o: Attrs.inc.h
+MallocChecker.o: Checkers.inc.h
+MallocChecker.o: DeclNodes.inc.h
+MallocChecker.o: DiagnosticCommonKinds.inc.h
+MallocChecker.o: StmtNodes.inc.h
+MallocChecker.po: AttrList.inc.h
+MallocChecker.po: Attrs.inc.h
+MallocChecker.po: Checkers.inc.h
+MallocChecker.po: DeclNodes.inc.h
+MallocChecker.po: DiagnosticCommonKinds.inc.h
+MallocChecker.po: StmtNodes.inc.h
+MallocOverflowSecurityChecker.o: AttrList.inc.h
+MallocOverflowSecurityChecker.o: Attrs.inc.h
+MallocOverflowSecurityChecker.o: Checkers.inc.h
+MallocOverflowSecurityChecker.o: DeclNodes.inc.h
+MallocOverflowSecurityChecker.o: DiagnosticCommonKinds.inc.h
+MallocOverflowSecurityChecker.o: StmtNodes.inc.h
+MallocOverflowSecurityChecker.po: AttrList.inc.h
+MallocOverflowSecurityChecker.po: Attrs.inc.h
+MallocOverflowSecurityChecker.po: Checkers.inc.h
+MallocOverflowSecurityChecker.po: DeclNodes.inc.h
+MallocOverflowSecurityChecker.po: DiagnosticCommonKinds.inc.h
+MallocOverflowSecurityChecker.po: StmtNodes.inc.h
+MallocSizeofChecker.o: AttrList.inc.h
+MallocSizeofChecker.o: Attrs.inc.h
+MallocSizeofChecker.o: Checkers.inc.h
+MallocSizeofChecker.o: DeclNodes.inc.h
+MallocSizeofChecker.o: DiagnosticCommonKinds.inc.h
+MallocSizeofChecker.o: StmtNodes.inc.h
+MallocSizeofChecker.po: AttrList.inc.h
+MallocSizeofChecker.po: Attrs.inc.h
+MallocSizeofChecker.po: Checkers.inc.h
+MallocSizeofChecker.po: DeclNodes.inc.h
+MallocSizeofChecker.po: DiagnosticCommonKinds.inc.h
+MallocSizeofChecker.po: StmtNodes.inc.h
+NSAutoreleasePoolChecker.o: AttrList.inc.h
+NSAutoreleasePoolChecker.o: Attrs.inc.h
+NSAutoreleasePoolChecker.o: Checkers.inc.h
+NSAutoreleasePoolChecker.o: DeclNodes.inc.h
+NSAutoreleasePoolChecker.o: DiagnosticCommonKinds.inc.h
+NSAutoreleasePoolChecker.o: StmtNodes.inc.h
+NSAutoreleasePoolChecker.po: AttrList.inc.h
+NSAutoreleasePoolChecker.po: Attrs.inc.h
+NSAutoreleasePoolChecker.po: Checkers.inc.h
+NSAutoreleasePoolChecker.po: DeclNodes.inc.h
+NSAutoreleasePoolChecker.po: DiagnosticCommonKinds.inc.h
+NSAutoreleasePoolChecker.po: StmtNodes.inc.h
+NSErrorChecker.o: AttrList.inc.h
+NSErrorChecker.o: Attrs.inc.h
+NSErrorChecker.o: Checkers.inc.h
+NSErrorChecker.o: DeclNodes.inc.h
+NSErrorChecker.o: DiagnosticCommonKinds.inc.h
+NSErrorChecker.o: StmtNodes.inc.h
+NSErrorChecker.po: AttrList.inc.h
+NSErrorChecker.po: Attrs.inc.h
+NSErrorChecker.po: Checkers.inc.h
+NSErrorChecker.po: DeclNodes.inc.h
+NSErrorChecker.po: DiagnosticCommonKinds.inc.h
+NSErrorChecker.po: StmtNodes.inc.h
+NoReturnFunctionChecker.o: AttrList.inc.h
+NoReturnFunctionChecker.o: Attrs.inc.h
+NoReturnFunctionChecker.o: Checkers.inc.h
+NoReturnFunctionChecker.o: DeclNodes.inc.h
+NoReturnFunctionChecker.o: DiagnosticCommonKinds.inc.h
+NoReturnFunctionChecker.o: StmtNodes.inc.h
+NoReturnFunctionChecker.po: AttrList.inc.h
+NoReturnFunctionChecker.po: Attrs.inc.h
+NoReturnFunctionChecker.po: Checkers.inc.h
+NoReturnFunctionChecker.po: DeclNodes.inc.h
+NoReturnFunctionChecker.po: DiagnosticCommonKinds.inc.h
+NoReturnFunctionChecker.po: StmtNodes.inc.h
+OSAtomicChecker.o: AttrList.inc.h
+OSAtomicChecker.o: Attrs.inc.h
+OSAtomicChecker.o: Checkers.inc.h
+OSAtomicChecker.o: DeclNodes.inc.h
+OSAtomicChecker.o: DiagnosticCommonKinds.inc.h
+OSAtomicChecker.o: StmtNodes.inc.h
+OSAtomicChecker.po: AttrList.inc.h
+OSAtomicChecker.po: Attrs.inc.h
+OSAtomicChecker.po: Checkers.inc.h
+OSAtomicChecker.po: DeclNodes.inc.h
+OSAtomicChecker.po: DiagnosticCommonKinds.inc.h
+OSAtomicChecker.po: StmtNodes.inc.h
+ObjCAtSyncChecker.o: AttrList.inc.h
+ObjCAtSyncChecker.o: Attrs.inc.h
+ObjCAtSyncChecker.o: Checkers.inc.h
+ObjCAtSyncChecker.o: DeclNodes.inc.h
+ObjCAtSyncChecker.o: DiagnosticCommonKinds.inc.h
+ObjCAtSyncChecker.o: StmtNodes.inc.h
+ObjCAtSyncChecker.po: AttrList.inc.h
+ObjCAtSyncChecker.po: Attrs.inc.h
+ObjCAtSyncChecker.po: Checkers.inc.h
+ObjCAtSyncChecker.po: DeclNodes.inc.h
+ObjCAtSyncChecker.po: DiagnosticCommonKinds.inc.h
+ObjCAtSyncChecker.po: StmtNodes.inc.h
+ObjCContainersASTChecker.o: AttrList.inc.h
+ObjCContainersASTChecker.o: Attrs.inc.h
+ObjCContainersASTChecker.o: Checkers.inc.h
+ObjCContainersASTChecker.o: DeclNodes.inc.h
+ObjCContainersASTChecker.o: DiagnosticCommonKinds.inc.h
+ObjCContainersASTChecker.o: StmtNodes.inc.h
+ObjCContainersASTChecker.po: AttrList.inc.h
+ObjCContainersASTChecker.po: Attrs.inc.h
+ObjCContainersASTChecker.po: Checkers.inc.h
+ObjCContainersASTChecker.po: DeclNodes.inc.h
+ObjCContainersASTChecker.po: DiagnosticCommonKinds.inc.h
+ObjCContainersASTChecker.po: StmtNodes.inc.h
+ObjCContainersChecker.o: AttrList.inc.h
+ObjCContainersChecker.o: Attrs.inc.h
+ObjCContainersChecker.o: Checkers.inc.h
+ObjCContainersChecker.o: DeclNodes.inc.h
+ObjCContainersChecker.o: DiagnosticCommonKinds.inc.h
+ObjCContainersChecker.o: StmtNodes.inc.h
+ObjCContainersChecker.po: AttrList.inc.h
+ObjCContainersChecker.po: Attrs.inc.h
+ObjCContainersChecker.po: Checkers.inc.h
+ObjCContainersChecker.po: DeclNodes.inc.h
+ObjCContainersChecker.po: DiagnosticCommonKinds.inc.h
+ObjCContainersChecker.po: StmtNodes.inc.h
+ObjCSelfInitChecker.o: AttrList.inc.h
+ObjCSelfInitChecker.o: Attrs.inc.h
+ObjCSelfInitChecker.o: Checkers.inc.h
+ObjCSelfInitChecker.o: DeclNodes.inc.h
+ObjCSelfInitChecker.o: DiagnosticCommonKinds.inc.h
+ObjCSelfInitChecker.o: StmtNodes.inc.h
+ObjCSelfInitChecker.po: AttrList.inc.h
+ObjCSelfInitChecker.po: Attrs.inc.h
+ObjCSelfInitChecker.po: Checkers.inc.h
+ObjCSelfInitChecker.po: DeclNodes.inc.h
+ObjCSelfInitChecker.po: DiagnosticCommonKinds.inc.h
+ObjCSelfInitChecker.po: StmtNodes.inc.h
+ObjCUnusedIVarsChecker.o: AttrList.inc.h
+ObjCUnusedIVarsChecker.o: Attrs.inc.h
+ObjCUnusedIVarsChecker.o: Checkers.inc.h
+ObjCUnusedIVarsChecker.o: DeclNodes.inc.h
+ObjCUnusedIVarsChecker.o: DiagnosticCommonKinds.inc.h
+ObjCUnusedIVarsChecker.o: StmtNodes.inc.h
+ObjCUnusedIVarsChecker.po: AttrList.inc.h
+ObjCUnusedIVarsChecker.po: Attrs.inc.h
+ObjCUnusedIVarsChecker.po: Checkers.inc.h
+ObjCUnusedIVarsChecker.po: DeclNodes.inc.h
+ObjCUnusedIVarsChecker.po: DiagnosticCommonKinds.inc.h
+ObjCUnusedIVarsChecker.po: StmtNodes.inc.h
+PointerArithChecker.o: AttrList.inc.h
+PointerArithChecker.o: Attrs.inc.h
+PointerArithChecker.o: Checkers.inc.h
+PointerArithChecker.o: DeclNodes.inc.h
+PointerArithChecker.o: DiagnosticCommonKinds.inc.h
+PointerArithChecker.o: StmtNodes.inc.h
+PointerArithChecker.po: AttrList.inc.h
+PointerArithChecker.po: Attrs.inc.h
+PointerArithChecker.po: Checkers.inc.h
+PointerArithChecker.po: DeclNodes.inc.h
+PointerArithChecker.po: DiagnosticCommonKinds.inc.h
+PointerArithChecker.po: StmtNodes.inc.h
+PointerSubChecker.o: AttrList.inc.h
+PointerSubChecker.o: Attrs.inc.h
+PointerSubChecker.o: Checkers.inc.h
+PointerSubChecker.o: DeclNodes.inc.h
+PointerSubChecker.o: DiagnosticCommonKinds.inc.h
+PointerSubChecker.o: StmtNodes.inc.h
+PointerSubChecker.po: AttrList.inc.h
+PointerSubChecker.po: Attrs.inc.h
+PointerSubChecker.po: Checkers.inc.h
+PointerSubChecker.po: DeclNodes.inc.h
+PointerSubChecker.po: DiagnosticCommonKinds.inc.h
+PointerSubChecker.po: StmtNodes.inc.h
+PthreadLockChecker.o: AttrList.inc.h
+PthreadLockChecker.o: Attrs.inc.h
+PthreadLockChecker.o: Checkers.inc.h
+PthreadLockChecker.o: DeclNodes.inc.h
+PthreadLockChecker.o: DiagnosticCommonKinds.inc.h
+PthreadLockChecker.o: StmtNodes.inc.h
+PthreadLockChecker.po: AttrList.inc.h
+PthreadLockChecker.po: Attrs.inc.h
+PthreadLockChecker.po: Checkers.inc.h
+PthreadLockChecker.po: DeclNodes.inc.h
+PthreadLockChecker.po: DiagnosticCommonKinds.inc.h
+PthreadLockChecker.po: StmtNodes.inc.h
+RetainCountChecker.o: AttrList.inc.h
+RetainCountChecker.o: Attrs.inc.h
+RetainCountChecker.o: Checkers.inc.h
+RetainCountChecker.o: DeclNodes.inc.h
+RetainCountChecker.o: DiagnosticCommonKinds.inc.h
+RetainCountChecker.o: StmtNodes.inc.h
+RetainCountChecker.po: AttrList.inc.h
+RetainCountChecker.po: Attrs.inc.h
+RetainCountChecker.po: Checkers.inc.h
+RetainCountChecker.po: DeclNodes.inc.h
+RetainCountChecker.po: DiagnosticCommonKinds.inc.h
+RetainCountChecker.po: StmtNodes.inc.h
+ReturnPointerRangeChecker.o: AttrList.inc.h
+ReturnPointerRangeChecker.o: Attrs.inc.h
+ReturnPointerRangeChecker.o: Checkers.inc.h
+ReturnPointerRangeChecker.o: DeclNodes.inc.h
+ReturnPointerRangeChecker.o: DiagnosticCommonKinds.inc.h
+ReturnPointerRangeChecker.o: StmtNodes.inc.h
+ReturnPointerRangeChecker.po: AttrList.inc.h
+ReturnPointerRangeChecker.po: Attrs.inc.h
+ReturnPointerRangeChecker.po: Checkers.inc.h
+ReturnPointerRangeChecker.po: DeclNodes.inc.h
+ReturnPointerRangeChecker.po: DiagnosticCommonKinds.inc.h
+ReturnPointerRangeChecker.po: StmtNodes.inc.h
+ReturnUndefChecker.o: AttrList.inc.h
+ReturnUndefChecker.o: Attrs.inc.h
+ReturnUndefChecker.o: Checkers.inc.h
+ReturnUndefChecker.o: DeclNodes.inc.h
+ReturnUndefChecker.o: DiagnosticCommonKinds.inc.h
+ReturnUndefChecker.o: StmtNodes.inc.h
+ReturnUndefChecker.po: AttrList.inc.h
+ReturnUndefChecker.po: Attrs.inc.h
+ReturnUndefChecker.po: Checkers.inc.h
+ReturnUndefChecker.po: DeclNodes.inc.h
+ReturnUndefChecker.po: DiagnosticCommonKinds.inc.h
+ReturnUndefChecker.po: StmtNodes.inc.h
+StackAddrEscapeChecker.o: AttrList.inc.h
+StackAddrEscapeChecker.o: Attrs.inc.h
+StackAddrEscapeChecker.o: Checkers.inc.h
+StackAddrEscapeChecker.o: DeclNodes.inc.h
+StackAddrEscapeChecker.o: DiagnosticCommonKinds.inc.h
+StackAddrEscapeChecker.o: StmtNodes.inc.h
+StackAddrEscapeChecker.po: AttrList.inc.h
+StackAddrEscapeChecker.po: Attrs.inc.h
+StackAddrEscapeChecker.po: Checkers.inc.h
+StackAddrEscapeChecker.po: DeclNodes.inc.h
+StackAddrEscapeChecker.po: DiagnosticCommonKinds.inc.h
+StackAddrEscapeChecker.po: StmtNodes.inc.h
+StreamChecker.o: AttrList.inc.h
+StreamChecker.o: Attrs.inc.h
+StreamChecker.o: Checkers.inc.h
+StreamChecker.o: DeclNodes.inc.h
+StreamChecker.o: DiagnosticCommonKinds.inc.h
+StreamChecker.o: StmtNodes.inc.h
+StreamChecker.po: AttrList.inc.h
+StreamChecker.po: Attrs.inc.h
+StreamChecker.po: Checkers.inc.h
+StreamChecker.po: DeclNodes.inc.h
+StreamChecker.po: DiagnosticCommonKinds.inc.h
+StreamChecker.po: StmtNodes.inc.h
+TaintTesterChecker.o: AttrList.inc.h
+TaintTesterChecker.o: Attrs.inc.h
+TaintTesterChecker.o: Checkers.inc.h
+TaintTesterChecker.o: DeclNodes.inc.h
+TaintTesterChecker.o: DiagnosticCommonKinds.inc.h
+TaintTesterChecker.o: StmtNodes.inc.h
+TaintTesterChecker.po: AttrList.inc.h
+TaintTesterChecker.po: Attrs.inc.h
+TaintTesterChecker.po: Checkers.inc.h
+TaintTesterChecker.po: DeclNodes.inc.h
+TaintTesterChecker.po: DiagnosticCommonKinds.inc.h
+TaintTesterChecker.po: StmtNodes.inc.h
+UndefBranchChecker.o: AttrList.inc.h
+UndefBranchChecker.o: Attrs.inc.h
+UndefBranchChecker.o: Checkers.inc.h
+UndefBranchChecker.o: DeclNodes.inc.h
+UndefBranchChecker.o: DiagnosticCommonKinds.inc.h
+UndefBranchChecker.o: StmtNodes.inc.h
+UndefBranchChecker.po: AttrList.inc.h
+UndefBranchChecker.po: Attrs.inc.h
+UndefBranchChecker.po: Checkers.inc.h
+UndefBranchChecker.po: DeclNodes.inc.h
+UndefBranchChecker.po: DiagnosticCommonKinds.inc.h
+UndefBranchChecker.po: StmtNodes.inc.h
+UndefCapturedBlockVarChecker.o: AttrList.inc.h
+UndefCapturedBlockVarChecker.o: Attrs.inc.h
+UndefCapturedBlockVarChecker.o: Checkers.inc.h
+UndefCapturedBlockVarChecker.o: DeclNodes.inc.h
+UndefCapturedBlockVarChecker.o: DiagnosticCommonKinds.inc.h
+UndefCapturedBlockVarChecker.o: StmtNodes.inc.h
+UndefCapturedBlockVarChecker.po: AttrList.inc.h
+UndefCapturedBlockVarChecker.po: Attrs.inc.h
+UndefCapturedBlockVarChecker.po: Checkers.inc.h
+UndefCapturedBlockVarChecker.po: DeclNodes.inc.h
+UndefCapturedBlockVarChecker.po: DiagnosticCommonKinds.inc.h
+UndefCapturedBlockVarChecker.po: StmtNodes.inc.h
+UndefResultChecker.o: AttrList.inc.h
+UndefResultChecker.o: Attrs.inc.h
+UndefResultChecker.o: Checkers.inc.h
+UndefResultChecker.o: DeclNodes.inc.h
+UndefResultChecker.o: DiagnosticCommonKinds.inc.h
+UndefResultChecker.o: StmtNodes.inc.h
+UndefResultChecker.po: AttrList.inc.h
+UndefResultChecker.po: Attrs.inc.h
+UndefResultChecker.po: Checkers.inc.h
+UndefResultChecker.po: DeclNodes.inc.h
+UndefResultChecker.po: DiagnosticCommonKinds.inc.h
+UndefResultChecker.po: StmtNodes.inc.h
+UndefinedArraySubscriptChecker.o: AttrList.inc.h
+UndefinedArraySubscriptChecker.o: Attrs.inc.h
+UndefinedArraySubscriptChecker.o: Checkers.inc.h
+UndefinedArraySubscriptChecker.o: DeclNodes.inc.h
+UndefinedArraySubscriptChecker.o: DiagnosticCommonKinds.inc.h
+UndefinedArraySubscriptChecker.o: StmtNodes.inc.h
+UndefinedArraySubscriptChecker.po: AttrList.inc.h
+UndefinedArraySubscriptChecker.po: Attrs.inc.h
+UndefinedArraySubscriptChecker.po: Checkers.inc.h
+UndefinedArraySubscriptChecker.po: DeclNodes.inc.h
+UndefinedArraySubscriptChecker.po: DiagnosticCommonKinds.inc.h
+UndefinedArraySubscriptChecker.po: StmtNodes.inc.h
+UndefinedAssignmentChecker.o: AttrList.inc.h
+UndefinedAssignmentChecker.o: Attrs.inc.h
+UndefinedAssignmentChecker.o: Checkers.inc.h
+UndefinedAssignmentChecker.o: DeclNodes.inc.h
+UndefinedAssignmentChecker.o: DiagnosticCommonKinds.inc.h
+UndefinedAssignmentChecker.o: StmtNodes.inc.h
+UndefinedAssignmentChecker.po: AttrList.inc.h
+UndefinedAssignmentChecker.po: Attrs.inc.h
+UndefinedAssignmentChecker.po: Checkers.inc.h
+UndefinedAssignmentChecker.po: DeclNodes.inc.h
+UndefinedAssignmentChecker.po: DiagnosticCommonKinds.inc.h
+UndefinedAssignmentChecker.po: StmtNodes.inc.h
+UnixAPIChecker.o: AttrList.inc.h
+UnixAPIChecker.o: Attrs.inc.h
+UnixAPIChecker.o: Checkers.inc.h
+UnixAPIChecker.o: DeclNodes.inc.h
+UnixAPIChecker.o: DiagnosticCommonKinds.inc.h
+UnixAPIChecker.o: StmtNodes.inc.h
+UnixAPIChecker.po: AttrList.inc.h
+UnixAPIChecker.po: Attrs.inc.h
+UnixAPIChecker.po: Checkers.inc.h
+UnixAPIChecker.po: DeclNodes.inc.h
+UnixAPIChecker.po: DiagnosticCommonKinds.inc.h
+UnixAPIChecker.po: StmtNodes.inc.h
+UnreachableCodeChecker.o: AttrList.inc.h
+UnreachableCodeChecker.o: Attrs.inc.h
+UnreachableCodeChecker.o: Checkers.inc.h
+UnreachableCodeChecker.o: DeclNodes.inc.h
+UnreachableCodeChecker.o: DiagnosticCommonKinds.inc.h
+UnreachableCodeChecker.o: StmtNodes.inc.h
+UnreachableCodeChecker.po: AttrList.inc.h
+UnreachableCodeChecker.po: Attrs.inc.h
+UnreachableCodeChecker.po: Checkers.inc.h
+UnreachableCodeChecker.po: DeclNodes.inc.h
+UnreachableCodeChecker.po: DiagnosticCommonKinds.inc.h
+UnreachableCodeChecker.po: StmtNodes.inc.h
+VLASizeChecker.o: AttrList.inc.h
+VLASizeChecker.o: Attrs.inc.h
+VLASizeChecker.o: Checkers.inc.h
+VLASizeChecker.o: DeclNodes.inc.h
+VLASizeChecker.o: DiagnosticCommonKinds.inc.h
+VLASizeChecker.o: StmtNodes.inc.h
+VLASizeChecker.po: AttrList.inc.h
+VLASizeChecker.po: Attrs.inc.h
+VLASizeChecker.po: Checkers.inc.h
+VLASizeChecker.po: DeclNodes.inc.h
+VLASizeChecker.po: DiagnosticCommonKinds.inc.h
+VLASizeChecker.po: StmtNodes.inc.h
+VirtualCallChecker.o: AttrList.inc.h
+VirtualCallChecker.o: Attrs.inc.h
+VirtualCallChecker.o: Checkers.inc.h
+VirtualCallChecker.o: DeclNodes.inc.h
+VirtualCallChecker.o: DiagnosticCommonKinds.inc.h
+VirtualCallChecker.o: StmtNodes.inc.h
+VirtualCallChecker.po: AttrList.inc.h
+VirtualCallChecker.po: Attrs.inc.h
+VirtualCallChecker.po: Checkers.inc.h
+VirtualCallChecker.po: DeclNodes.inc.h
+VirtualCallChecker.po: DiagnosticCommonKinds.inc.h
+VirtualCallChecker.po: StmtNodes.inc.h
+.endif
diff --git a/lib/clang/libclangstaticanalyzercore/Makefile.depend b/lib/clang/libclangstaticanalyzercore/Makefile.depend
new file mode 100644
index 0000000..846f776
--- /dev/null
+++ b/lib/clang/libclangstaticanalyzercore/Makefile.depend
@@ -0,0 +1,365 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+AnalysisManager.o: AttrList.inc.h
+AnalysisManager.o: Attrs.inc.h
+AnalysisManager.o: DeclNodes.inc.h
+AnalysisManager.o: DiagnosticCommonKinds.inc.h
+AnalysisManager.o: StmtNodes.inc.h
+AnalysisManager.po: AttrList.inc.h
+AnalysisManager.po: Attrs.inc.h
+AnalysisManager.po: DeclNodes.inc.h
+AnalysisManager.po: DiagnosticCommonKinds.inc.h
+AnalysisManager.po: StmtNodes.inc.h
+BasicConstraintManager.o: AttrList.inc.h
+BasicConstraintManager.o: Attrs.inc.h
+BasicConstraintManager.o: DeclNodes.inc.h
+BasicConstraintManager.o: DiagnosticCommonKinds.inc.h
+BasicConstraintManager.o: StmtNodes.inc.h
+BasicConstraintManager.po: AttrList.inc.h
+BasicConstraintManager.po: Attrs.inc.h
+BasicConstraintManager.po: DeclNodes.inc.h
+BasicConstraintManager.po: DiagnosticCommonKinds.inc.h
+BasicConstraintManager.po: StmtNodes.inc.h
+BasicValueFactory.o: AttrList.inc.h
+BasicValueFactory.o: Attrs.inc.h
+BasicValueFactory.o: DeclNodes.inc.h
+BasicValueFactory.o: DiagnosticCommonKinds.inc.h
+BasicValueFactory.o: StmtNodes.inc.h
+BasicValueFactory.po: AttrList.inc.h
+BasicValueFactory.po: Attrs.inc.h
+BasicValueFactory.po: DeclNodes.inc.h
+BasicValueFactory.po: DiagnosticCommonKinds.inc.h
+BasicValueFactory.po: StmtNodes.inc.h
+BugReporter.o: AttrList.inc.h
+BugReporter.o: Attrs.inc.h
+BugReporter.o: DeclNodes.inc.h
+BugReporter.o: DiagnosticCommonKinds.inc.h
+BugReporter.o: StmtNodes.inc.h
+BugReporter.po: AttrList.inc.h
+BugReporter.po: Attrs.inc.h
+BugReporter.po: DeclNodes.inc.h
+BugReporter.po: DiagnosticCommonKinds.inc.h
+BugReporter.po: StmtNodes.inc.h
+BugReporterVisitors.o: AttrList.inc.h
+BugReporterVisitors.o: Attrs.inc.h
+BugReporterVisitors.o: DeclNodes.inc.h
+BugReporterVisitors.o: DiagnosticCommonKinds.inc.h
+BugReporterVisitors.o: StmtNodes.inc.h
+BugReporterVisitors.po: AttrList.inc.h
+BugReporterVisitors.po: Attrs.inc.h
+BugReporterVisitors.po: DeclNodes.inc.h
+BugReporterVisitors.po: DiagnosticCommonKinds.inc.h
+BugReporterVisitors.po: StmtNodes.inc.h
+Checker.o: AttrList.inc.h
+Checker.o: Attrs.inc.h
+Checker.o: DeclNodes.inc.h
+Checker.o: DiagnosticCommonKinds.inc.h
+Checker.o: StmtNodes.inc.h
+Checker.po: AttrList.inc.h
+Checker.po: Attrs.inc.h
+Checker.po: DeclNodes.inc.h
+Checker.po: DiagnosticCommonKinds.inc.h
+Checker.po: StmtNodes.inc.h
+CheckerContext.o: AttrList.inc.h
+CheckerContext.o: Attrs.inc.h
+CheckerContext.o: DeclNodes.inc.h
+CheckerContext.o: DiagnosticCommonKinds.inc.h
+CheckerContext.o: StmtNodes.inc.h
+CheckerContext.po: AttrList.inc.h
+CheckerContext.po: Attrs.inc.h
+CheckerContext.po: DeclNodes.inc.h
+CheckerContext.po: DiagnosticCommonKinds.inc.h
+CheckerContext.po: StmtNodes.inc.h
+CheckerHelpers.o: AttrList.inc.h
+CheckerHelpers.o: Attrs.inc.h
+CheckerHelpers.o: DeclNodes.inc.h
+CheckerHelpers.o: DiagnosticCommonKinds.inc.h
+CheckerHelpers.o: StmtNodes.inc.h
+CheckerHelpers.po: AttrList.inc.h
+CheckerHelpers.po: Attrs.inc.h
+CheckerHelpers.po: DeclNodes.inc.h
+CheckerHelpers.po: DiagnosticCommonKinds.inc.h
+CheckerHelpers.po: StmtNodes.inc.h
+CheckerManager.o: AttrList.inc.h
+CheckerManager.o: Attrs.inc.h
+CheckerManager.o: DeclNodes.inc.h
+CheckerManager.o: DiagnosticCommonKinds.inc.h
+CheckerManager.o: StmtNodes.inc.h
+CheckerManager.po: AttrList.inc.h
+CheckerManager.po: Attrs.inc.h
+CheckerManager.po: DeclNodes.inc.h
+CheckerManager.po: DiagnosticCommonKinds.inc.h
+CheckerManager.po: StmtNodes.inc.h
+CheckerRegistry.o: AttrList.inc.h
+CheckerRegistry.o: Attrs.inc.h
+CheckerRegistry.o: DeclNodes.inc.h
+CheckerRegistry.o: DiagnosticCommonKinds.inc.h
+CheckerRegistry.o: StmtNodes.inc.h
+CheckerRegistry.po: AttrList.inc.h
+CheckerRegistry.po: Attrs.inc.h
+CheckerRegistry.po: DeclNodes.inc.h
+CheckerRegistry.po: DiagnosticCommonKinds.inc.h
+CheckerRegistry.po: StmtNodes.inc.h
+CoreEngine.o: AttrList.inc.h
+CoreEngine.o: Attrs.inc.h
+CoreEngine.o: DeclNodes.inc.h
+CoreEngine.o: DiagnosticCommonKinds.inc.h
+CoreEngine.o: StmtNodes.inc.h
+CoreEngine.po: AttrList.inc.h
+CoreEngine.po: Attrs.inc.h
+CoreEngine.po: DeclNodes.inc.h
+CoreEngine.po: DiagnosticCommonKinds.inc.h
+CoreEngine.po: StmtNodes.inc.h
+Environment.o: AttrList.inc.h
+Environment.o: Attrs.inc.h
+Environment.o: DeclNodes.inc.h
+Environment.o: DiagnosticCommonKinds.inc.h
+Environment.o: StmtNodes.inc.h
+Environment.po: AttrList.inc.h
+Environment.po: Attrs.inc.h
+Environment.po: DeclNodes.inc.h
+Environment.po: DiagnosticCommonKinds.inc.h
+Environment.po: StmtNodes.inc.h
+ExplodedGraph.o: AttrList.inc.h
+ExplodedGraph.o: Attrs.inc.h
+ExplodedGraph.o: DeclNodes.inc.h
+ExplodedGraph.o: DiagnosticCommonKinds.inc.h
+ExplodedGraph.o: StmtNodes.inc.h
+ExplodedGraph.po: AttrList.inc.h
+ExplodedGraph.po: Attrs.inc.h
+ExplodedGraph.po: DeclNodes.inc.h
+ExplodedGraph.po: DiagnosticCommonKinds.inc.h
+ExplodedGraph.po: StmtNodes.inc.h
+ExprEngine.o: AttrList.inc.h
+ExprEngine.o: Attrs.inc.h
+ExprEngine.o: DeclNodes.inc.h
+ExprEngine.o: DiagnosticCommonKinds.inc.h
+ExprEngine.o: StmtNodes.inc.h
+ExprEngine.po: AttrList.inc.h
+ExprEngine.po: Attrs.inc.h
+ExprEngine.po: DeclNodes.inc.h
+ExprEngine.po: DiagnosticCommonKinds.inc.h
+ExprEngine.po: StmtNodes.inc.h
+ExprEngineC.o: AttrList.inc.h
+ExprEngineC.o: Attrs.inc.h
+ExprEngineC.o: DeclNodes.inc.h
+ExprEngineC.o: DiagnosticCommonKinds.inc.h
+ExprEngineC.o: StmtNodes.inc.h
+ExprEngineC.po: AttrList.inc.h
+ExprEngineC.po: Attrs.inc.h
+ExprEngineC.po: DeclNodes.inc.h
+ExprEngineC.po: DiagnosticCommonKinds.inc.h
+ExprEngineC.po: StmtNodes.inc.h
+ExprEngineCXX.o: AttrList.inc.h
+ExprEngineCXX.o: Attrs.inc.h
+ExprEngineCXX.o: DeclNodes.inc.h
+ExprEngineCXX.o: DiagnosticCommonKinds.inc.h
+ExprEngineCXX.o: StmtNodes.inc.h
+ExprEngineCXX.po: AttrList.inc.h
+ExprEngineCXX.po: Attrs.inc.h
+ExprEngineCXX.po: DeclNodes.inc.h
+ExprEngineCXX.po: DiagnosticCommonKinds.inc.h
+ExprEngineCXX.po: StmtNodes.inc.h
+ExprEngineCallAndReturn.o: AttrList.inc.h
+ExprEngineCallAndReturn.o: Attrs.inc.h
+ExprEngineCallAndReturn.o: DeclNodes.inc.h
+ExprEngineCallAndReturn.o: DiagnosticCommonKinds.inc.h
+ExprEngineCallAndReturn.o: StmtNodes.inc.h
+ExprEngineCallAndReturn.po: AttrList.inc.h
+ExprEngineCallAndReturn.po: Attrs.inc.h
+ExprEngineCallAndReturn.po: DeclNodes.inc.h
+ExprEngineCallAndReturn.po: DiagnosticCommonKinds.inc.h
+ExprEngineCallAndReturn.po: StmtNodes.inc.h
+ExprEngineObjC.o: AttrList.inc.h
+ExprEngineObjC.o: Attrs.inc.h
+ExprEngineObjC.o: DeclNodes.inc.h
+ExprEngineObjC.o: DiagnosticCommonKinds.inc.h
+ExprEngineObjC.o: StmtNodes.inc.h
+ExprEngineObjC.po: AttrList.inc.h
+ExprEngineObjC.po: Attrs.inc.h
+ExprEngineObjC.po: DeclNodes.inc.h
+ExprEngineObjC.po: DiagnosticCommonKinds.inc.h
+ExprEngineObjC.po: StmtNodes.inc.h
+FunctionSummary.o: AttrList.inc.h
+FunctionSummary.o: Attrs.inc.h
+FunctionSummary.o: DeclNodes.inc.h
+FunctionSummary.o: DiagnosticCommonKinds.inc.h
+FunctionSummary.po: AttrList.inc.h
+FunctionSummary.po: Attrs.inc.h
+FunctionSummary.po: DeclNodes.inc.h
+FunctionSummary.po: DiagnosticCommonKinds.inc.h
+HTMLDiagnostics.o: AttrList.inc.h
+HTMLDiagnostics.o: Attrs.inc.h
+HTMLDiagnostics.o: DeclNodes.inc.h
+HTMLDiagnostics.o: DiagnosticCommonKinds.inc.h
+HTMLDiagnostics.o: StmtNodes.inc.h
+HTMLDiagnostics.po: AttrList.inc.h
+HTMLDiagnostics.po: Attrs.inc.h
+HTMLDiagnostics.po: DeclNodes.inc.h
+HTMLDiagnostics.po: DiagnosticCommonKinds.inc.h
+HTMLDiagnostics.po: StmtNodes.inc.h
+MemRegion.o: AttrList.inc.h
+MemRegion.o: Attrs.inc.h
+MemRegion.o: DeclNodes.inc.h
+MemRegion.o: DiagnosticCommonKinds.inc.h
+MemRegion.o: StmtNodes.inc.h
+MemRegion.po: AttrList.inc.h
+MemRegion.po: Attrs.inc.h
+MemRegion.po: DeclNodes.inc.h
+MemRegion.po: DiagnosticCommonKinds.inc.h
+MemRegion.po: StmtNodes.inc.h
+ObjCMessage.o: AttrList.inc.h
+ObjCMessage.o: Attrs.inc.h
+ObjCMessage.o: DeclNodes.inc.h
+ObjCMessage.o: DiagnosticCommonKinds.inc.h
+ObjCMessage.o: StmtNodes.inc.h
+ObjCMessage.po: AttrList.inc.h
+ObjCMessage.po: Attrs.inc.h
+ObjCMessage.po: DeclNodes.inc.h
+ObjCMessage.po: DiagnosticCommonKinds.inc.h
+ObjCMessage.po: StmtNodes.inc.h
+PathDiagnostic.o: AttrList.inc.h
+PathDiagnostic.o: Attrs.inc.h
+PathDiagnostic.o: DeclNodes.inc.h
+PathDiagnostic.o: DiagnosticCommonKinds.inc.h
+PathDiagnostic.o: StmtNodes.inc.h
+PathDiagnostic.po: AttrList.inc.h
+PathDiagnostic.po: Attrs.inc.h
+PathDiagnostic.po: DeclNodes.inc.h
+PathDiagnostic.po: DiagnosticCommonKinds.inc.h
+PathDiagnostic.po: StmtNodes.inc.h
+PlistDiagnostics.o: AttrList.inc.h
+PlistDiagnostics.o: Attrs.inc.h
+PlistDiagnostics.o: DeclNodes.inc.h
+PlistDiagnostics.o: DiagnosticCommonKinds.inc.h
+PlistDiagnostics.o: StmtNodes.inc.h
+PlistDiagnostics.po: AttrList.inc.h
+PlistDiagnostics.po: Attrs.inc.h
+PlistDiagnostics.po: DeclNodes.inc.h
+PlistDiagnostics.po: DiagnosticCommonKinds.inc.h
+PlistDiagnostics.po: StmtNodes.inc.h
+ProgramState.o: AttrList.inc.h
+ProgramState.o: Attrs.inc.h
+ProgramState.o: DeclNodes.inc.h
+ProgramState.o: DiagnosticCommonKinds.inc.h
+ProgramState.o: StmtNodes.inc.h
+ProgramState.po: AttrList.inc.h
+ProgramState.po: Attrs.inc.h
+ProgramState.po: DeclNodes.inc.h
+ProgramState.po: DiagnosticCommonKinds.inc.h
+ProgramState.po: StmtNodes.inc.h
+RangeConstraintManager.o: AttrList.inc.h
+RangeConstraintManager.o: Attrs.inc.h
+RangeConstraintManager.o: DeclNodes.inc.h
+RangeConstraintManager.o: DiagnosticCommonKinds.inc.h
+RangeConstraintManager.o: StmtNodes.inc.h
+RangeConstraintManager.po: AttrList.inc.h
+RangeConstraintManager.po: Attrs.inc.h
+RangeConstraintManager.po: DeclNodes.inc.h
+RangeConstraintManager.po: DiagnosticCommonKinds.inc.h
+RangeConstraintManager.po: StmtNodes.inc.h
+RegionStore.o: AttrList.inc.h
+RegionStore.o: Attrs.inc.h
+RegionStore.o: DeclNodes.inc.h
+RegionStore.o: DiagnosticCommonKinds.inc.h
+RegionStore.o: StmtNodes.inc.h
+RegionStore.po: AttrList.inc.h
+RegionStore.po: Attrs.inc.h
+RegionStore.po: DeclNodes.inc.h
+RegionStore.po: DiagnosticCommonKinds.inc.h
+RegionStore.po: StmtNodes.inc.h
+SValBuilder.o: AttrList.inc.h
+SValBuilder.o: Attrs.inc.h
+SValBuilder.o: DeclNodes.inc.h
+SValBuilder.o: DiagnosticCommonKinds.inc.h
+SValBuilder.o: StmtNodes.inc.h
+SValBuilder.po: AttrList.inc.h
+SValBuilder.po: Attrs.inc.h
+SValBuilder.po: DeclNodes.inc.h
+SValBuilder.po: DiagnosticCommonKinds.inc.h
+SValBuilder.po: StmtNodes.inc.h
+SVals.o: AttrList.inc.h
+SVals.o: Attrs.inc.h
+SVals.o: DeclNodes.inc.h
+SVals.o: DiagnosticCommonKinds.inc.h
+SVals.o: StmtNodes.inc.h
+SVals.po: AttrList.inc.h
+SVals.po: Attrs.inc.h
+SVals.po: DeclNodes.inc.h
+SVals.po: DiagnosticCommonKinds.inc.h
+SVals.po: StmtNodes.inc.h
+SimpleConstraintManager.o: AttrList.inc.h
+SimpleConstraintManager.o: Attrs.inc.h
+SimpleConstraintManager.o: DeclNodes.inc.h
+SimpleConstraintManager.o: DiagnosticCommonKinds.inc.h
+SimpleConstraintManager.o: StmtNodes.inc.h
+SimpleConstraintManager.po: AttrList.inc.h
+SimpleConstraintManager.po: Attrs.inc.h
+SimpleConstraintManager.po: DeclNodes.inc.h
+SimpleConstraintManager.po: DiagnosticCommonKinds.inc.h
+SimpleConstraintManager.po: StmtNodes.inc.h
+SimpleSValBuilder.o: AttrList.inc.h
+SimpleSValBuilder.o: Attrs.inc.h
+SimpleSValBuilder.o: DeclNodes.inc.h
+SimpleSValBuilder.o: DiagnosticCommonKinds.inc.h
+SimpleSValBuilder.o: StmtNodes.inc.h
+SimpleSValBuilder.po: AttrList.inc.h
+SimpleSValBuilder.po: Attrs.inc.h
+SimpleSValBuilder.po: DeclNodes.inc.h
+SimpleSValBuilder.po: DiagnosticCommonKinds.inc.h
+SimpleSValBuilder.po: StmtNodes.inc.h
+Store.o: AttrList.inc.h
+Store.o: Attrs.inc.h
+Store.o: DeclNodes.inc.h
+Store.o: DiagnosticCommonKinds.inc.h
+Store.o: StmtNodes.inc.h
+Store.po: AttrList.inc.h
+Store.po: Attrs.inc.h
+Store.po: DeclNodes.inc.h
+Store.po: DiagnosticCommonKinds.inc.h
+Store.po: StmtNodes.inc.h
+SubEngine.o: AttrList.inc.h
+SubEngine.o: Attrs.inc.h
+SubEngine.o: DeclNodes.inc.h
+SubEngine.o: DiagnosticCommonKinds.inc.h
+SubEngine.o: StmtNodes.inc.h
+SubEngine.po: AttrList.inc.h
+SubEngine.po: Attrs.inc.h
+SubEngine.po: DeclNodes.inc.h
+SubEngine.po: DiagnosticCommonKinds.inc.h
+SubEngine.po: StmtNodes.inc.h
+SymbolManager.o: AttrList.inc.h
+SymbolManager.o: Attrs.inc.h
+SymbolManager.o: DeclNodes.inc.h
+SymbolManager.o: DiagnosticCommonKinds.inc.h
+SymbolManager.o: StmtNodes.inc.h
+SymbolManager.po: AttrList.inc.h
+SymbolManager.po: Attrs.inc.h
+SymbolManager.po: DeclNodes.inc.h
+SymbolManager.po: DiagnosticCommonKinds.inc.h
+SymbolManager.po: StmtNodes.inc.h
+TextPathDiagnostics.o: AttrList.inc.h
+TextPathDiagnostics.o: Attrs.inc.h
+TextPathDiagnostics.o: DeclNodes.inc.h
+TextPathDiagnostics.o: DiagnosticCommonKinds.inc.h
+TextPathDiagnostics.o: StmtNodes.inc.h
+TextPathDiagnostics.po: AttrList.inc.h
+TextPathDiagnostics.po: Attrs.inc.h
+TextPathDiagnostics.po: DeclNodes.inc.h
+TextPathDiagnostics.po: DiagnosticCommonKinds.inc.h
+TextPathDiagnostics.po: StmtNodes.inc.h
+.endif
diff --git a/lib/clang/libclangstaticanalyzerfrontend/Makefile.depend b/lib/clang/libclangstaticanalyzerfrontend/Makefile.depend
new file mode 100644
index 0000000..bcae1ef
--- /dev/null
+++ b/lib/clang/libclangstaticanalyzerfrontend/Makefile.depend
@@ -0,0 +1,41 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+AnalysisConsumer.o: AttrList.inc.h
+AnalysisConsumer.o: Attrs.inc.h
+AnalysisConsumer.o: DeclNodes.inc.h
+AnalysisConsumer.o: DiagnosticCommonKinds.inc.h
+AnalysisConsumer.o: StmtNodes.inc.h
+AnalysisConsumer.po: AttrList.inc.h
+AnalysisConsumer.po: Attrs.inc.h
+AnalysisConsumer.po: DeclNodes.inc.h
+AnalysisConsumer.po: DiagnosticCommonKinds.inc.h
+AnalysisConsumer.po: StmtNodes.inc.h
+CheckerRegistration.o: AttrList.inc.h
+CheckerRegistration.o: Attrs.inc.h
+CheckerRegistration.o: DeclNodes.inc.h
+CheckerRegistration.o: DiagnosticCommonKinds.inc.h
+CheckerRegistration.o: DiagnosticFrontendKinds.inc.h
+CheckerRegistration.o: StmtNodes.inc.h
+CheckerRegistration.po: AttrList.inc.h
+CheckerRegistration.po: Attrs.inc.h
+CheckerRegistration.po: DeclNodes.inc.h
+CheckerRegistration.po: DiagnosticCommonKinds.inc.h
+CheckerRegistration.po: DiagnosticFrontendKinds.inc.h
+CheckerRegistration.po: StmtNodes.inc.h
+FrontendActions.o: DiagnosticCommonKinds.inc.h
+FrontendActions.po: DiagnosticCommonKinds.inc.h
+.endif
diff --git a/lib/clang/libllvmanalysis/Makefile.depend b/lib/clang/libllvmanalysis/Makefile.depend
new file mode 100644
index 0000000..be777d8
--- /dev/null
+++ b/lib/clang/libllvmanalysis/Makefile.depend
@@ -0,0 +1,47 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+AliasAnalysis.o: Intrinsics.inc.h
+AliasAnalysis.po: Intrinsics.inc.h
+AliasSetTracker.o: Intrinsics.inc.h
+AliasSetTracker.po: Intrinsics.inc.h
+BasicAliasAnalysis.o: Intrinsics.inc.h
+BasicAliasAnalysis.po: Intrinsics.inc.h
+CodeMetrics.o: Intrinsics.inc.h
+CodeMetrics.po: Intrinsics.inc.h
+ConstantFolding.o: Intrinsics.inc.h
+ConstantFolding.po: Intrinsics.inc.h
+DIBuilder.o: Intrinsics.inc.h
+DIBuilder.po: Intrinsics.inc.h
+DbgInfoPrinter.o: Intrinsics.inc.h
+DbgInfoPrinter.po: Intrinsics.inc.h
+DebugInfo.o: Intrinsics.inc.h
+DebugInfo.po: Intrinsics.inc.h
+InlineCost.o: Intrinsics.inc.h
+InlineCost.po: Intrinsics.inc.h
+LazyValueInfo.o: Intrinsics.inc.h
+LazyValueInfo.po: Intrinsics.inc.h
+Lint.o: Intrinsics.inc.h
+Lint.po: Intrinsics.inc.h
+Loads.o: Intrinsics.inc.h
+Loads.po: Intrinsics.inc.h
+MemoryDependenceAnalysis.o: Intrinsics.inc.h
+MemoryDependenceAnalysis.po: Intrinsics.inc.h
+ScalarEvolutionExpander.o: Intrinsics.inc.h
+ScalarEvolutionExpander.po: Intrinsics.inc.h
+ValueTracking.o: Intrinsics.inc.h
+ValueTracking.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvmarchive/Makefile.depend b/lib/clang/libllvmarchive/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmarchive/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmarmasmparser/Makefile.depend b/lib/clang/libllvmarmasmparser/Makefile.depend
new file mode 100644
index 0000000..d4e4af4
--- /dev/null
+++ b/lib/clang/libllvmarmasmparser/Makefile.depend
@@ -0,0 +1,31 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ARMAsmLexer.o: ARMGenInstrInfo.inc.h
+ARMAsmLexer.o: ARMGenRegisterInfo.inc.h
+ARMAsmLexer.o: ARMGenSubtargetInfo.inc.h
+ARMAsmLexer.po: ARMGenInstrInfo.inc.h
+ARMAsmLexer.po: ARMGenRegisterInfo.inc.h
+ARMAsmLexer.po: ARMGenSubtargetInfo.inc.h
+ARMAsmParser.o: ARMGenAsmMatcher.inc.h
+ARMAsmParser.o: ARMGenInstrInfo.inc.h
+ARMAsmParser.o: ARMGenRegisterInfo.inc.h
+ARMAsmParser.o: ARMGenSubtargetInfo.inc.h
+ARMAsmParser.po: ARMGenAsmMatcher.inc.h
+ARMAsmParser.po: ARMGenInstrInfo.inc.h
+ARMAsmParser.po: ARMGenRegisterInfo.inc.h
+ARMAsmParser.po: ARMGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmarmcodegen/Makefile.depend b/lib/clang/libllvmarmcodegen/Makefile.depend
new file mode 100644
index 0000000..abc1e04
--- /dev/null
+++ b/lib/clang/libllvmarmcodegen/Makefile.depend
@@ -0,0 +1,209 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ARMAsmPrinter.o: ARMGenInstrInfo.inc.h
+ARMAsmPrinter.o: ARMGenMCPseudoLowering.inc.h
+ARMAsmPrinter.o: ARMGenRegisterInfo.inc.h
+ARMAsmPrinter.o: ARMGenSubtargetInfo.inc.h
+ARMAsmPrinter.po: ARMGenInstrInfo.inc.h
+ARMAsmPrinter.po: ARMGenMCPseudoLowering.inc.h
+ARMAsmPrinter.po: ARMGenRegisterInfo.inc.h
+ARMAsmPrinter.po: ARMGenSubtargetInfo.inc.h
+ARMBaseInstrInfo.o: ARMGenInstrInfo.inc.h
+ARMBaseInstrInfo.o: ARMGenRegisterInfo.inc.h
+ARMBaseInstrInfo.o: ARMGenSubtargetInfo.inc.h
+ARMBaseInstrInfo.po: ARMGenInstrInfo.inc.h
+ARMBaseInstrInfo.po: ARMGenRegisterInfo.inc.h
+ARMBaseInstrInfo.po: ARMGenSubtargetInfo.inc.h
+ARMBaseRegisterInfo.o: ARMGenInstrInfo.inc.h
+ARMBaseRegisterInfo.o: ARMGenRegisterInfo.inc.h
+ARMBaseRegisterInfo.o: ARMGenSubtargetInfo.inc.h
+ARMBaseRegisterInfo.po: ARMGenInstrInfo.inc.h
+ARMBaseRegisterInfo.po: ARMGenRegisterInfo.inc.h
+ARMBaseRegisterInfo.po: ARMGenSubtargetInfo.inc.h
+ARMCodeEmitter.o: ARMGenCodeEmitter.inc.h
+ARMCodeEmitter.o: ARMGenInstrInfo.inc.h
+ARMCodeEmitter.o: ARMGenRegisterInfo.inc.h
+ARMCodeEmitter.o: ARMGenSubtargetInfo.inc.h
+ARMCodeEmitter.po: ARMGenCodeEmitter.inc.h
+ARMCodeEmitter.po: ARMGenInstrInfo.inc.h
+ARMCodeEmitter.po: ARMGenRegisterInfo.inc.h
+ARMCodeEmitter.po: ARMGenSubtargetInfo.inc.h
+ARMConstantIslandPass.o: ARMGenInstrInfo.inc.h
+ARMConstantIslandPass.o: ARMGenRegisterInfo.inc.h
+ARMConstantIslandPass.o: ARMGenSubtargetInfo.inc.h
+ARMConstantIslandPass.po: ARMGenInstrInfo.inc.h
+ARMConstantIslandPass.po: ARMGenRegisterInfo.inc.h
+ARMConstantIslandPass.po: ARMGenSubtargetInfo.inc.h
+ARMExpandPseudoInsts.o: ARMGenInstrInfo.inc.h
+ARMExpandPseudoInsts.o: ARMGenRegisterInfo.inc.h
+ARMExpandPseudoInsts.o: ARMGenSubtargetInfo.inc.h
+ARMExpandPseudoInsts.po: ARMGenInstrInfo.inc.h
+ARMExpandPseudoInsts.po: ARMGenRegisterInfo.inc.h
+ARMExpandPseudoInsts.po: ARMGenSubtargetInfo.inc.h
+ARMFastISel.o: ARMGenCallingConv.inc.h
+ARMFastISel.o: ARMGenFastISel.inc.h
+ARMFastISel.o: ARMGenInstrInfo.inc.h
+ARMFastISel.o: ARMGenRegisterInfo.inc.h
+ARMFastISel.o: ARMGenSubtargetInfo.inc.h
+ARMFastISel.o: Intrinsics.inc.h
+ARMFastISel.po: ARMGenCallingConv.inc.h
+ARMFastISel.po: ARMGenFastISel.inc.h
+ARMFastISel.po: ARMGenInstrInfo.inc.h
+ARMFastISel.po: ARMGenRegisterInfo.inc.h
+ARMFastISel.po: ARMGenSubtargetInfo.inc.h
+ARMFastISel.po: Intrinsics.inc.h
+ARMFrameLowering.o: ARMGenInstrInfo.inc.h
+ARMFrameLowering.o: ARMGenRegisterInfo.inc.h
+ARMFrameLowering.o: ARMGenSubtargetInfo.inc.h
+ARMFrameLowering.po: ARMGenInstrInfo.inc.h
+ARMFrameLowering.po: ARMGenRegisterInfo.inc.h
+ARMFrameLowering.po: ARMGenSubtargetInfo.inc.h
+ARMHazardRecognizer.o: ARMGenInstrInfo.inc.h
+ARMHazardRecognizer.o: ARMGenRegisterInfo.inc.h
+ARMHazardRecognizer.o: ARMGenSubtargetInfo.inc.h
+ARMHazardRecognizer.po: ARMGenInstrInfo.inc.h
+ARMHazardRecognizer.po: ARMGenRegisterInfo.inc.h
+ARMHazardRecognizer.po: ARMGenSubtargetInfo.inc.h
+ARMISelDAGToDAG.o: ARMGenDAGISel.inc.h
+ARMISelDAGToDAG.o: ARMGenInstrInfo.inc.h
+ARMISelDAGToDAG.o: ARMGenRegisterInfo.inc.h
+ARMISelDAGToDAG.o: ARMGenSubtargetInfo.inc.h
+ARMISelDAGToDAG.o: Intrinsics.inc.h
+ARMISelDAGToDAG.po: ARMGenDAGISel.inc.h
+ARMISelDAGToDAG.po: ARMGenInstrInfo.inc.h
+ARMISelDAGToDAG.po: ARMGenRegisterInfo.inc.h
+ARMISelDAGToDAG.po: ARMGenSubtargetInfo.inc.h
+ARMISelDAGToDAG.po: Intrinsics.inc.h
+ARMISelLowering.o: ARMGenCallingConv.inc.h
+ARMISelLowering.o: ARMGenInstrInfo.inc.h
+ARMISelLowering.o: ARMGenRegisterInfo.inc.h
+ARMISelLowering.o: ARMGenSubtargetInfo.inc.h
+ARMISelLowering.o: Intrinsics.inc.h
+ARMISelLowering.po: ARMGenCallingConv.inc.h
+ARMISelLowering.po: ARMGenInstrInfo.inc.h
+ARMISelLowering.po: ARMGenRegisterInfo.inc.h
+ARMISelLowering.po: ARMGenSubtargetInfo.inc.h
+ARMISelLowering.po: Intrinsics.inc.h
+ARMInstrInfo.o: ARMGenInstrInfo.inc.h
+ARMInstrInfo.o: ARMGenRegisterInfo.inc.h
+ARMInstrInfo.o: ARMGenSubtargetInfo.inc.h
+ARMInstrInfo.po: ARMGenInstrInfo.inc.h
+ARMInstrInfo.po: ARMGenRegisterInfo.inc.h
+ARMInstrInfo.po: ARMGenSubtargetInfo.inc.h
+ARMJITInfo.o: ARMGenInstrInfo.inc.h
+ARMJITInfo.o: ARMGenRegisterInfo.inc.h
+ARMJITInfo.o: ARMGenSubtargetInfo.inc.h
+ARMJITInfo.po: ARMGenInstrInfo.inc.h
+ARMJITInfo.po: ARMGenRegisterInfo.inc.h
+ARMJITInfo.po: ARMGenSubtargetInfo.inc.h
+ARMLoadStoreOptimizer.o: ARMGenInstrInfo.inc.h
+ARMLoadStoreOptimizer.o: ARMGenRegisterInfo.inc.h
+ARMLoadStoreOptimizer.o: ARMGenSubtargetInfo.inc.h
+ARMLoadStoreOptimizer.po: ARMGenInstrInfo.inc.h
+ARMLoadStoreOptimizer.po: ARMGenRegisterInfo.inc.h
+ARMLoadStoreOptimizer.po: ARMGenSubtargetInfo.inc.h
+ARMMCInstLower.o: ARMGenInstrInfo.inc.h
+ARMMCInstLower.o: ARMGenRegisterInfo.inc.h
+ARMMCInstLower.o: ARMGenSubtargetInfo.inc.h
+ARMMCInstLower.po: ARMGenInstrInfo.inc.h
+ARMMCInstLower.po: ARMGenRegisterInfo.inc.h
+ARMMCInstLower.po: ARMGenSubtargetInfo.inc.h
+ARMMachineFunctionInfo.o: ARMGenInstrInfo.inc.h
+ARMMachineFunctionInfo.o: ARMGenRegisterInfo.inc.h
+ARMMachineFunctionInfo.o: ARMGenSubtargetInfo.inc.h
+ARMMachineFunctionInfo.po: ARMGenInstrInfo.inc.h
+ARMMachineFunctionInfo.po: ARMGenRegisterInfo.inc.h
+ARMMachineFunctionInfo.po: ARMGenSubtargetInfo.inc.h
+ARMRegisterInfo.o: ARMGenInstrInfo.inc.h
+ARMRegisterInfo.o: ARMGenRegisterInfo.inc.h
+ARMRegisterInfo.o: ARMGenSubtargetInfo.inc.h
+ARMRegisterInfo.po: ARMGenInstrInfo.inc.h
+ARMRegisterInfo.po: ARMGenRegisterInfo.inc.h
+ARMRegisterInfo.po: ARMGenSubtargetInfo.inc.h
+ARMSelectionDAGInfo.o: ARMGenInstrInfo.inc.h
+ARMSelectionDAGInfo.o: ARMGenRegisterInfo.inc.h
+ARMSelectionDAGInfo.o: ARMGenSubtargetInfo.inc.h
+ARMSelectionDAGInfo.po: ARMGenInstrInfo.inc.h
+ARMSelectionDAGInfo.po: ARMGenRegisterInfo.inc.h
+ARMSelectionDAGInfo.po: ARMGenSubtargetInfo.inc.h
+ARMSubtarget.o: ARMGenInstrInfo.inc.h
+ARMSubtarget.o: ARMGenRegisterInfo.inc.h
+ARMSubtarget.o: ARMGenSubtargetInfo.inc.h
+ARMSubtarget.po: ARMGenInstrInfo.inc.h
+ARMSubtarget.po: ARMGenRegisterInfo.inc.h
+ARMSubtarget.po: ARMGenSubtargetInfo.inc.h
+ARMTargetMachine.o: ARMGenInstrInfo.inc.h
+ARMTargetMachine.o: ARMGenRegisterInfo.inc.h
+ARMTargetMachine.o: ARMGenSubtargetInfo.inc.h
+ARMTargetMachine.po: ARMGenInstrInfo.inc.h
+ARMTargetMachine.po: ARMGenRegisterInfo.inc.h
+ARMTargetMachine.po: ARMGenSubtargetInfo.inc.h
+ARMTargetObjectFile.o: ARMGenInstrInfo.inc.h
+ARMTargetObjectFile.o: ARMGenRegisterInfo.inc.h
+ARMTargetObjectFile.o: ARMGenSubtargetInfo.inc.h
+ARMTargetObjectFile.po: ARMGenInstrInfo.inc.h
+ARMTargetObjectFile.po: ARMGenRegisterInfo.inc.h
+ARMTargetObjectFile.po: ARMGenSubtargetInfo.inc.h
+MLxExpansionPass.o: ARMGenInstrInfo.inc.h
+MLxExpansionPass.o: ARMGenRegisterInfo.inc.h
+MLxExpansionPass.o: ARMGenSubtargetInfo.inc.h
+MLxExpansionPass.po: ARMGenInstrInfo.inc.h
+MLxExpansionPass.po: ARMGenRegisterInfo.inc.h
+MLxExpansionPass.po: ARMGenSubtargetInfo.inc.h
+Thumb1FrameLowering.o: ARMGenInstrInfo.inc.h
+Thumb1FrameLowering.o: ARMGenRegisterInfo.inc.h
+Thumb1FrameLowering.o: ARMGenSubtargetInfo.inc.h
+Thumb1FrameLowering.po: ARMGenInstrInfo.inc.h
+Thumb1FrameLowering.po: ARMGenRegisterInfo.inc.h
+Thumb1FrameLowering.po: ARMGenSubtargetInfo.inc.h
+Thumb1InstrInfo.o: ARMGenInstrInfo.inc.h
+Thumb1InstrInfo.o: ARMGenRegisterInfo.inc.h
+Thumb1InstrInfo.o: ARMGenSubtargetInfo.inc.h
+Thumb1InstrInfo.po: ARMGenInstrInfo.inc.h
+Thumb1InstrInfo.po: ARMGenRegisterInfo.inc.h
+Thumb1InstrInfo.po: ARMGenSubtargetInfo.inc.h
+Thumb1RegisterInfo.o: ARMGenInstrInfo.inc.h
+Thumb1RegisterInfo.o: ARMGenRegisterInfo.inc.h
+Thumb1RegisterInfo.o: ARMGenSubtargetInfo.inc.h
+Thumb1RegisterInfo.po: ARMGenInstrInfo.inc.h
+Thumb1RegisterInfo.po: ARMGenRegisterInfo.inc.h
+Thumb1RegisterInfo.po: ARMGenSubtargetInfo.inc.h
+Thumb2ITBlockPass.o: ARMGenInstrInfo.inc.h
+Thumb2ITBlockPass.o: ARMGenRegisterInfo.inc.h
+Thumb2ITBlockPass.o: ARMGenSubtargetInfo.inc.h
+Thumb2ITBlockPass.po: ARMGenInstrInfo.inc.h
+Thumb2ITBlockPass.po: ARMGenRegisterInfo.inc.h
+Thumb2ITBlockPass.po: ARMGenSubtargetInfo.inc.h
+Thumb2InstrInfo.o: ARMGenInstrInfo.inc.h
+Thumb2InstrInfo.o: ARMGenRegisterInfo.inc.h
+Thumb2InstrInfo.o: ARMGenSubtargetInfo.inc.h
+Thumb2InstrInfo.po: ARMGenInstrInfo.inc.h
+Thumb2InstrInfo.po: ARMGenRegisterInfo.inc.h
+Thumb2InstrInfo.po: ARMGenSubtargetInfo.inc.h
+Thumb2RegisterInfo.o: ARMGenInstrInfo.inc.h
+Thumb2RegisterInfo.o: ARMGenRegisterInfo.inc.h
+Thumb2RegisterInfo.o: ARMGenSubtargetInfo.inc.h
+Thumb2RegisterInfo.po: ARMGenInstrInfo.inc.h
+Thumb2RegisterInfo.po: ARMGenRegisterInfo.inc.h
+Thumb2RegisterInfo.po: ARMGenSubtargetInfo.inc.h
+Thumb2SizeReduction.o: ARMGenInstrInfo.inc.h
+Thumb2SizeReduction.o: ARMGenRegisterInfo.inc.h
+Thumb2SizeReduction.o: ARMGenSubtargetInfo.inc.h
+Thumb2SizeReduction.po: ARMGenInstrInfo.inc.h
+Thumb2SizeReduction.po: ARMGenRegisterInfo.inc.h
+Thumb2SizeReduction.po: ARMGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmarmdesc/Makefile.depend b/lib/clang/libllvmarmdesc/Makefile.depend
new file mode 100644
index 0000000..1f4c165
--- /dev/null
+++ b/lib/clang/libllvmarmdesc/Makefile.depend
@@ -0,0 +1,49 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ARMAsmBackend.o: ARMGenInstrInfo.inc.h
+ARMAsmBackend.o: ARMGenRegisterInfo.inc.h
+ARMAsmBackend.o: ARMGenSubtargetInfo.inc.h
+ARMAsmBackend.po: ARMGenInstrInfo.inc.h
+ARMAsmBackend.po: ARMGenRegisterInfo.inc.h
+ARMAsmBackend.po: ARMGenSubtargetInfo.inc.h
+ARMELFObjectWriter.o: ARMGenInstrInfo.inc.h
+ARMELFObjectWriter.o: ARMGenRegisterInfo.inc.h
+ARMELFObjectWriter.o: ARMGenSubtargetInfo.inc.h
+ARMELFObjectWriter.po: ARMGenInstrInfo.inc.h
+ARMELFObjectWriter.po: ARMGenRegisterInfo.inc.h
+ARMELFObjectWriter.po: ARMGenSubtargetInfo.inc.h
+ARMMCCodeEmitter.o: ARMGenInstrInfo.inc.h
+ARMMCCodeEmitter.o: ARMGenMCCodeEmitter.inc.h
+ARMMCCodeEmitter.o: ARMGenRegisterInfo.inc.h
+ARMMCCodeEmitter.o: ARMGenSubtargetInfo.inc.h
+ARMMCCodeEmitter.po: ARMGenInstrInfo.inc.h
+ARMMCCodeEmitter.po: ARMGenMCCodeEmitter.inc.h
+ARMMCCodeEmitter.po: ARMGenRegisterInfo.inc.h
+ARMMCCodeEmitter.po: ARMGenSubtargetInfo.inc.h
+ARMMCTargetDesc.o: ARMGenInstrInfo.inc.h
+ARMMCTargetDesc.o: ARMGenRegisterInfo.inc.h
+ARMMCTargetDesc.o: ARMGenSubtargetInfo.inc.h
+ARMMCTargetDesc.po: ARMGenInstrInfo.inc.h
+ARMMCTargetDesc.po: ARMGenRegisterInfo.inc.h
+ARMMCTargetDesc.po: ARMGenSubtargetInfo.inc.h
+ARMMachObjectWriter.o: ARMGenInstrInfo.inc.h
+ARMMachObjectWriter.o: ARMGenRegisterInfo.inc.h
+ARMMachObjectWriter.o: ARMGenSubtargetInfo.inc.h
+ARMMachObjectWriter.po: ARMGenInstrInfo.inc.h
+ARMMachObjectWriter.po: ARMGenRegisterInfo.inc.h
+ARMMachObjectWriter.po: ARMGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmarmdisassembler/Makefile.depend b/lib/clang/libllvmarmdisassembler/Makefile.depend
new file mode 100644
index 0000000..0e79928
--- /dev/null
+++ b/lib/clang/libllvmarmdisassembler/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ARMDisassembler.o: ARMGenDisassemblerTables.inc.h
+ARMDisassembler.o: ARMGenEDInfo.inc.h
+ARMDisassembler.o: ARMGenInstrInfo.inc.h
+ARMDisassembler.o: ARMGenRegisterInfo.inc.h
+ARMDisassembler.o: ARMGenSubtargetInfo.inc.h
+ARMDisassembler.po: ARMGenDisassemblerTables.inc.h
+ARMDisassembler.po: ARMGenEDInfo.inc.h
+ARMDisassembler.po: ARMGenInstrInfo.inc.h
+ARMDisassembler.po: ARMGenRegisterInfo.inc.h
+ARMDisassembler.po: ARMGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmarminfo/Makefile.depend b/lib/clang/libllvmarminfo/Makefile.depend
new file mode 100644
index 0000000..06b4fd9
--- /dev/null
+++ b/lib/clang/libllvmarminfo/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ARMTargetInfo.o: ARMGenInstrInfo.inc.h
+ARMTargetInfo.o: ARMGenRegisterInfo.inc.h
+ARMTargetInfo.o: ARMGenSubtargetInfo.inc.h
+ARMTargetInfo.po: ARMGenInstrInfo.inc.h
+ARMTargetInfo.po: ARMGenRegisterInfo.inc.h
+ARMTargetInfo.po: ARMGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmarminstprinter/Makefile.depend b/lib/clang/libllvmarminstprinter/Makefile.depend
new file mode 100644
index 0000000..9bcf0c7
--- /dev/null
+++ b/lib/clang/libllvmarminstprinter/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ARMInstPrinter.o: ARMGenAsmWriter.inc.h
+ARMInstPrinter.o: ARMGenInstrInfo.inc.h
+ARMInstPrinter.o: ARMGenRegisterInfo.inc.h
+ARMInstPrinter.o: ARMGenSubtargetInfo.inc.h
+ARMInstPrinter.po: ARMGenAsmWriter.inc.h
+ARMInstPrinter.po: ARMGenInstrInfo.inc.h
+ARMInstPrinter.po: ARMGenRegisterInfo.inc.h
+ARMInstPrinter.po: ARMGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmasmparser/Makefile.depend b/lib/clang/libllvmasmparser/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmasmparser/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmasmprinter/Makefile.depend b/lib/clang/libllvmasmprinter/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmasmprinter/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmbitreader/Makefile.depend b/lib/clang/libllvmbitreader/Makefile.depend
new file mode 100644
index 0000000..97f57a5
--- /dev/null
+++ b/lib/clang/libllvmbitreader/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+BitcodeReader.o: Intrinsics.inc.h
+BitcodeReader.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvmbitwriter/Makefile.depend b/lib/clang/libllvmbitwriter/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmbitwriter/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmcodegen/Makefile.depend b/lib/clang/libllvmcodegen/Makefile.depend
new file mode 100644
index 0000000..026d1de
--- /dev/null
+++ b/lib/clang/libllvmcodegen/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+Analysis.o: Intrinsics.inc.h
+Analysis.po: Intrinsics.inc.h
+DwarfEHPrepare.o: Intrinsics.inc.h
+DwarfEHPrepare.po: Intrinsics.inc.h
+GCStrategy.o: Intrinsics.inc.h
+GCStrategy.po: Intrinsics.inc.h
+IntrinsicLowering.o: Intrinsics.inc.h
+IntrinsicLowering.po: Intrinsics.inc.h
+LocalStackSlotAllocation.o: Intrinsics.inc.h
+LocalStackSlotAllocation.po: Intrinsics.inc.h
+ShadowStackGC.o: Intrinsics.inc.h
+ShadowStackGC.po: Intrinsics.inc.h
+SjLjEHPrepare.o: Intrinsics.inc.h
+SjLjEHPrepare.po: Intrinsics.inc.h
+StackProtector.o: Intrinsics.inc.h
+StackProtector.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvmcore/Makefile.depend b/lib/clang/libllvmcore/Makefile.depend
new file mode 100644
index 0000000..cdb4373
--- /dev/null
+++ b/lib/clang/libllvmcore/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+AsmWriter.o: Intrinsics.inc.h
+AsmWriter.po: Intrinsics.inc.h
+AutoUpgrade.o: Intrinsics.inc.h
+AutoUpgrade.po: Intrinsics.inc.h
+BasicBlock.o: Intrinsics.inc.h
+BasicBlock.po: Intrinsics.inc.h
+Core.o: Intrinsics.inc.h
+Core.po: Intrinsics.inc.h
+Function.o: Intrinsics.inc.h
+Function.po: Intrinsics.inc.h
+IRBuilder.o: Intrinsics.inc.h
+IRBuilder.po: Intrinsics.inc.h
+IntrinsicInst.o: Intrinsics.inc.h
+IntrinsicInst.po: Intrinsics.inc.h
+Verifier.o: Intrinsics.inc.h
+Verifier.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvmdebuginfo/Makefile.depend b/lib/clang/libllvmdebuginfo/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmdebuginfo/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmexecutionengine/Makefile.depend b/lib/clang/libllvmexecutionengine/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmexecutionengine/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvminstcombine/Makefile.depend b/lib/clang/libllvminstcombine/Makefile.depend
new file mode 100644
index 0000000..27d7724
--- /dev/null
+++ b/lib/clang/libllvminstcombine/Makefile.depend
@@ -0,0 +1,43 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+InstCombineAddSub.o: Intrinsics.inc.h
+InstCombineAddSub.po: Intrinsics.inc.h
+InstCombineAndOrXor.o: Intrinsics.inc.h
+InstCombineAndOrXor.po: Intrinsics.inc.h
+InstCombineCalls.o: Intrinsics.inc.h
+InstCombineCalls.po: Intrinsics.inc.h
+InstCombineCasts.o: Intrinsics.inc.h
+InstCombineCasts.po: Intrinsics.inc.h
+InstCombineCompares.o: Intrinsics.inc.h
+InstCombineCompares.po: Intrinsics.inc.h
+InstCombineLoadStoreAlloca.o: Intrinsics.inc.h
+InstCombineLoadStoreAlloca.po: Intrinsics.inc.h
+InstCombineMulDivRem.o: Intrinsics.inc.h
+InstCombineMulDivRem.po: Intrinsics.inc.h
+InstCombinePHI.o: Intrinsics.inc.h
+InstCombinePHI.po: Intrinsics.inc.h
+InstCombineSelect.o: Intrinsics.inc.h
+InstCombineSelect.po: Intrinsics.inc.h
+InstCombineShifts.o: Intrinsics.inc.h
+InstCombineShifts.po: Intrinsics.inc.h
+InstCombineSimplifyDemanded.o: Intrinsics.inc.h
+InstCombineSimplifyDemanded.po: Intrinsics.inc.h
+InstCombineVectorOps.o: Intrinsics.inc.h
+InstCombineVectorOps.po: Intrinsics.inc.h
+InstructionCombining.o: Intrinsics.inc.h
+InstructionCombining.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvminstrumentation/Makefile.depend b/lib/clang/libllvminstrumentation/Makefile.depend
new file mode 100644
index 0000000..2574cd5
--- /dev/null
+++ b/lib/clang/libllvminstrumentation/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+AddressSanitizer.o: Intrinsics.inc.h
+AddressSanitizer.po: Intrinsics.inc.h
+ThreadSanitizer.o: Intrinsics.inc.h
+ThreadSanitizer.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvminterpreter/Makefile.depend b/lib/clang/libllvminterpreter/Makefile.depend
new file mode 100644
index 0000000..0c45153
--- /dev/null
+++ b/lib/clang/libllvminterpreter/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+Execution.o: Intrinsics.inc.h
+Execution.po: Intrinsics.inc.h
+Interpreter.o: Intrinsics.inc.h
+Interpreter.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvmipa/Makefile.depend b/lib/clang/libllvmipa/Makefile.depend
new file mode 100644
index 0000000..9b4317f
--- /dev/null
+++ b/lib/clang/libllvmipa/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+CallGraph.o: Intrinsics.inc.h
+CallGraph.po: Intrinsics.inc.h
+CallGraphSCCPass.o: Intrinsics.inc.h
+CallGraphSCCPass.po: Intrinsics.inc.h
+GlobalsModRef.o: Intrinsics.inc.h
+GlobalsModRef.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvmipo/Makefile.depend b/lib/clang/libllvmipo/Makefile.depend
new file mode 100644
index 0000000..6f90d4d
--- /dev/null
+++ b/lib/clang/libllvmipo/Makefile.depend
@@ -0,0 +1,31 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+DeadArgumentElimination.o: Intrinsics.inc.h
+DeadArgumentElimination.po: Intrinsics.inc.h
+FunctionAttrs.o: Intrinsics.inc.h
+FunctionAttrs.po: Intrinsics.inc.h
+GlobalOpt.o: Intrinsics.inc.h
+GlobalOpt.po: Intrinsics.inc.h
+InlineAlways.o: Intrinsics.inc.h
+InlineAlways.po: Intrinsics.inc.h
+InlineSimple.o: Intrinsics.inc.h
+InlineSimple.po: Intrinsics.inc.h
+Inliner.o: Intrinsics.inc.h
+Inliner.po: Intrinsics.inc.h
+PruneEH.o: Intrinsics.inc.h
+PruneEH.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvmjit/Makefile.depend b/lib/clang/libllvmjit/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmjit/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmlinker/Makefile.depend b/lib/clang/libllvmlinker/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmlinker/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmmc/Makefile.depend b/lib/clang/libllvmmc/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmmc/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmmcdisassembler/Makefile.depend b/lib/clang/libllvmmcdisassembler/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmmcdisassembler/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmmcjit/Makefile.depend b/lib/clang/libllvmmcjit/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmmcjit/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmmcparser/Makefile.depend b/lib/clang/libllvmmcparser/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmmcparser/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmmipsasmparser/Makefile.depend b/lib/clang/libllvmmipsasmparser/Makefile.depend
new file mode 100644
index 0000000..a215c2c
--- /dev/null
+++ b/lib/clang/libllvmmipsasmparser/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+MipsAsmParser.o: MipsGenInstrInfo.inc.h
+MipsAsmParser.o: MipsGenRegisterInfo.inc.h
+MipsAsmParser.o: MipsGenSubtargetInfo.inc.h
+MipsAsmParser.po: MipsGenInstrInfo.inc.h
+MipsAsmParser.po: MipsGenRegisterInfo.inc.h
+MipsAsmParser.po: MipsGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmmipscodegen/Makefile.depend b/lib/clang/libllvmmipscodegen/Makefile.depend
new file mode 100644
index 0000000..28ee994
--- /dev/null
+++ b/lib/clang/libllvmmipscodegen/Makefile.depend
@@ -0,0 +1,131 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+MipsAnalyzeImmediate.o: MipsGenInstrInfo.inc.h
+MipsAnalyzeImmediate.o: MipsGenRegisterInfo.inc.h
+MipsAnalyzeImmediate.o: MipsGenSubtargetInfo.inc.h
+MipsAnalyzeImmediate.po: MipsGenInstrInfo.inc.h
+MipsAnalyzeImmediate.po: MipsGenRegisterInfo.inc.h
+MipsAnalyzeImmediate.po: MipsGenSubtargetInfo.inc.h
+MipsAsmPrinter.o: MipsGenInstrInfo.inc.h
+MipsAsmPrinter.o: MipsGenRegisterInfo.inc.h
+MipsAsmPrinter.o: MipsGenSubtargetInfo.inc.h
+MipsAsmPrinter.po: MipsGenInstrInfo.inc.h
+MipsAsmPrinter.po: MipsGenRegisterInfo.inc.h
+MipsAsmPrinter.po: MipsGenSubtargetInfo.inc.h
+MipsCodeEmitter.o: MipsGenCodeEmitter.inc.h
+MipsCodeEmitter.o: MipsGenInstrInfo.inc.h
+MipsCodeEmitter.o: MipsGenRegisterInfo.inc.h
+MipsCodeEmitter.o: MipsGenSubtargetInfo.inc.h
+MipsCodeEmitter.po: MipsGenCodeEmitter.inc.h
+MipsCodeEmitter.po: MipsGenInstrInfo.inc.h
+MipsCodeEmitter.po: MipsGenRegisterInfo.inc.h
+MipsCodeEmitter.po: MipsGenSubtargetInfo.inc.h
+MipsDelaySlotFiller.o: MipsGenInstrInfo.inc.h
+MipsDelaySlotFiller.o: MipsGenRegisterInfo.inc.h
+MipsDelaySlotFiller.o: MipsGenSubtargetInfo.inc.h
+MipsDelaySlotFiller.po: MipsGenInstrInfo.inc.h
+MipsDelaySlotFiller.po: MipsGenRegisterInfo.inc.h
+MipsDelaySlotFiller.po: MipsGenSubtargetInfo.inc.h
+MipsEmitGPRestore.o: MipsGenInstrInfo.inc.h
+MipsEmitGPRestore.o: MipsGenRegisterInfo.inc.h
+MipsEmitGPRestore.o: MipsGenSubtargetInfo.inc.h
+MipsEmitGPRestore.po: MipsGenInstrInfo.inc.h
+MipsEmitGPRestore.po: MipsGenRegisterInfo.inc.h
+MipsEmitGPRestore.po: MipsGenSubtargetInfo.inc.h
+MipsExpandPseudo.o: MipsGenInstrInfo.inc.h
+MipsExpandPseudo.o: MipsGenRegisterInfo.inc.h
+MipsExpandPseudo.o: MipsGenSubtargetInfo.inc.h
+MipsExpandPseudo.po: MipsGenInstrInfo.inc.h
+MipsExpandPseudo.po: MipsGenRegisterInfo.inc.h
+MipsExpandPseudo.po: MipsGenSubtargetInfo.inc.h
+MipsFrameLowering.o: MipsGenInstrInfo.inc.h
+MipsFrameLowering.o: MipsGenRegisterInfo.inc.h
+MipsFrameLowering.o: MipsGenSubtargetInfo.inc.h
+MipsFrameLowering.po: MipsGenInstrInfo.inc.h
+MipsFrameLowering.po: MipsGenRegisterInfo.inc.h
+MipsFrameLowering.po: MipsGenSubtargetInfo.inc.h
+MipsISelDAGToDAG.o: Intrinsics.inc.h
+MipsISelDAGToDAG.o: MipsGenDAGISel.inc.h
+MipsISelDAGToDAG.o: MipsGenInstrInfo.inc.h
+MipsISelDAGToDAG.o: MipsGenRegisterInfo.inc.h
+MipsISelDAGToDAG.o: MipsGenSubtargetInfo.inc.h
+MipsISelDAGToDAG.po: Intrinsics.inc.h
+MipsISelDAGToDAG.po: MipsGenDAGISel.inc.h
+MipsISelDAGToDAG.po: MipsGenInstrInfo.inc.h
+MipsISelDAGToDAG.po: MipsGenRegisterInfo.inc.h
+MipsISelDAGToDAG.po: MipsGenSubtargetInfo.inc.h
+MipsISelLowering.o: Intrinsics.inc.h
+MipsISelLowering.o: MipsGenCallingConv.inc.h
+MipsISelLowering.o: MipsGenInstrInfo.inc.h
+MipsISelLowering.o: MipsGenRegisterInfo.inc.h
+MipsISelLowering.o: MipsGenSubtargetInfo.inc.h
+MipsISelLowering.po: Intrinsics.inc.h
+MipsISelLowering.po: MipsGenCallingConv.inc.h
+MipsISelLowering.po: MipsGenInstrInfo.inc.h
+MipsISelLowering.po: MipsGenRegisterInfo.inc.h
+MipsISelLowering.po: MipsGenSubtargetInfo.inc.h
+MipsInstrInfo.o: MipsGenInstrInfo.inc.h
+MipsInstrInfo.o: MipsGenRegisterInfo.inc.h
+MipsInstrInfo.o: MipsGenSubtargetInfo.inc.h
+MipsInstrInfo.po: MipsGenInstrInfo.inc.h
+MipsInstrInfo.po: MipsGenRegisterInfo.inc.h
+MipsInstrInfo.po: MipsGenSubtargetInfo.inc.h
+MipsJITInfo.o: MipsGenInstrInfo.inc.h
+MipsJITInfo.o: MipsGenRegisterInfo.inc.h
+MipsJITInfo.o: MipsGenSubtargetInfo.inc.h
+MipsJITInfo.po: MipsGenInstrInfo.inc.h
+MipsJITInfo.po: MipsGenRegisterInfo.inc.h
+MipsJITInfo.po: MipsGenSubtargetInfo.inc.h
+MipsMCInstLower.o: MipsGenInstrInfo.inc.h
+MipsMCInstLower.o: MipsGenRegisterInfo.inc.h
+MipsMCInstLower.o: MipsGenSubtargetInfo.inc.h
+MipsMCInstLower.po: MipsGenInstrInfo.inc.h
+MipsMCInstLower.po: MipsGenRegisterInfo.inc.h
+MipsMCInstLower.po: MipsGenSubtargetInfo.inc.h
+MipsMachineFunction.o: MipsGenInstrInfo.inc.h
+MipsMachineFunction.o: MipsGenRegisterInfo.inc.h
+MipsMachineFunction.o: MipsGenSubtargetInfo.inc.h
+MipsMachineFunction.po: MipsGenInstrInfo.inc.h
+MipsMachineFunction.po: MipsGenRegisterInfo.inc.h
+MipsMachineFunction.po: MipsGenSubtargetInfo.inc.h
+MipsRegisterInfo.o: MipsGenInstrInfo.inc.h
+MipsRegisterInfo.o: MipsGenRegisterInfo.inc.h
+MipsRegisterInfo.o: MipsGenSubtargetInfo.inc.h
+MipsRegisterInfo.po: MipsGenInstrInfo.inc.h
+MipsRegisterInfo.po: MipsGenRegisterInfo.inc.h
+MipsRegisterInfo.po: MipsGenSubtargetInfo.inc.h
+MipsSelectionDAGInfo.o: MipsGenInstrInfo.inc.h
+MipsSelectionDAGInfo.o: MipsGenRegisterInfo.inc.h
+MipsSelectionDAGInfo.o: MipsGenSubtargetInfo.inc.h
+MipsSelectionDAGInfo.po: MipsGenInstrInfo.inc.h
+MipsSelectionDAGInfo.po: MipsGenRegisterInfo.inc.h
+MipsSelectionDAGInfo.po: MipsGenSubtargetInfo.inc.h
+MipsSubtarget.o: MipsGenInstrInfo.inc.h
+MipsSubtarget.o: MipsGenRegisterInfo.inc.h
+MipsSubtarget.o: MipsGenSubtargetInfo.inc.h
+MipsSubtarget.po: MipsGenInstrInfo.inc.h
+MipsSubtarget.po: MipsGenRegisterInfo.inc.h
+MipsSubtarget.po: MipsGenSubtargetInfo.inc.h
+MipsTargetMachine.o: MipsGenInstrInfo.inc.h
+MipsTargetMachine.o: MipsGenRegisterInfo.inc.h
+MipsTargetMachine.o: MipsGenSubtargetInfo.inc.h
+MipsTargetMachine.po: MipsGenInstrInfo.inc.h
+MipsTargetMachine.po: MipsGenRegisterInfo.inc.h
+MipsTargetMachine.po: MipsGenSubtargetInfo.inc.h
+MipsTargetObjectFile.o: MipsGenSubtargetInfo.inc.h
+MipsTargetObjectFile.po: MipsGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmmipsdesc/Makefile.depend b/lib/clang/libllvmmipsdesc/Makefile.depend
new file mode 100644
index 0000000..1aceb5f
--- /dev/null
+++ b/lib/clang/libllvmmipsdesc/Makefile.depend
@@ -0,0 +1,43 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+MipsAsmBackend.o: MipsGenInstrInfo.inc.h
+MipsAsmBackend.o: MipsGenRegisterInfo.inc.h
+MipsAsmBackend.o: MipsGenSubtargetInfo.inc.h
+MipsAsmBackend.po: MipsGenInstrInfo.inc.h
+MipsAsmBackend.po: MipsGenRegisterInfo.inc.h
+MipsAsmBackend.po: MipsGenSubtargetInfo.inc.h
+MipsELFObjectWriter.o: MipsGenInstrInfo.inc.h
+MipsELFObjectWriter.o: MipsGenRegisterInfo.inc.h
+MipsELFObjectWriter.o: MipsGenSubtargetInfo.inc.h
+MipsELFObjectWriter.po: MipsGenInstrInfo.inc.h
+MipsELFObjectWriter.po: MipsGenRegisterInfo.inc.h
+MipsELFObjectWriter.po: MipsGenSubtargetInfo.inc.h
+MipsMCCodeEmitter.o: MipsGenInstrInfo.inc.h
+MipsMCCodeEmitter.o: MipsGenMCCodeEmitter.inc.h
+MipsMCCodeEmitter.o: MipsGenRegisterInfo.inc.h
+MipsMCCodeEmitter.o: MipsGenSubtargetInfo.inc.h
+MipsMCCodeEmitter.po: MipsGenInstrInfo.inc.h
+MipsMCCodeEmitter.po: MipsGenMCCodeEmitter.inc.h
+MipsMCCodeEmitter.po: MipsGenRegisterInfo.inc.h
+MipsMCCodeEmitter.po: MipsGenSubtargetInfo.inc.h
+MipsMCTargetDesc.o: MipsGenInstrInfo.inc.h
+MipsMCTargetDesc.o: MipsGenRegisterInfo.inc.h
+MipsMCTargetDesc.o: MipsGenSubtargetInfo.inc.h
+MipsMCTargetDesc.po: MipsGenInstrInfo.inc.h
+MipsMCTargetDesc.po: MipsGenRegisterInfo.inc.h
+MipsMCTargetDesc.po: MipsGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmmipsinfo/Makefile.depend b/lib/clang/libllvmmipsinfo/Makefile.depend
new file mode 100644
index 0000000..54441b5
--- /dev/null
+++ b/lib/clang/libllvmmipsinfo/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+MipsTargetInfo.o: MipsGenInstrInfo.inc.h
+MipsTargetInfo.o: MipsGenRegisterInfo.inc.h
+MipsTargetInfo.o: MipsGenSubtargetInfo.inc.h
+MipsTargetInfo.po: MipsGenInstrInfo.inc.h
+MipsTargetInfo.po: MipsGenRegisterInfo.inc.h
+MipsTargetInfo.po: MipsGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmmipsinstprinter/Makefile.depend b/lib/clang/libllvmmipsinstprinter/Makefile.depend
new file mode 100644
index 0000000..5ecd0b5
--- /dev/null
+++ b/lib/clang/libllvmmipsinstprinter/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+MipsInstPrinter.o: MipsGenAsmWriter.inc.h
+MipsInstPrinter.po: MipsGenAsmWriter.inc.h
+.endif
diff --git a/lib/clang/libllvmobject/Makefile.depend b/lib/clang/libllvmobject/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmobject/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmpowerpccodegen/Makefile.depend b/lib/clang/libllvmpowerpccodegen/Makefile.depend
new file mode 100644
index 0000000..988435f
--- /dev/null
+++ b/lib/clang/libllvmpowerpccodegen/Makefile.depend
@@ -0,0 +1,111 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+PPCAsmPrinter.o: PPCGenInstrInfo.inc.h
+PPCAsmPrinter.o: PPCGenRegisterInfo.inc.h
+PPCAsmPrinter.o: PPCGenSubtargetInfo.inc.h
+PPCAsmPrinter.po: PPCGenInstrInfo.inc.h
+PPCAsmPrinter.po: PPCGenRegisterInfo.inc.h
+PPCAsmPrinter.po: PPCGenSubtargetInfo.inc.h
+PPCBranchSelector.o: PPCGenInstrInfo.inc.h
+PPCBranchSelector.o: PPCGenRegisterInfo.inc.h
+PPCBranchSelector.o: PPCGenSubtargetInfo.inc.h
+PPCBranchSelector.po: PPCGenInstrInfo.inc.h
+PPCBranchSelector.po: PPCGenRegisterInfo.inc.h
+PPCBranchSelector.po: PPCGenSubtargetInfo.inc.h
+PPCCodeEmitter.o: PPCGenCodeEmitter.inc.h
+PPCCodeEmitter.o: PPCGenInstrInfo.inc.h
+PPCCodeEmitter.o: PPCGenRegisterInfo.inc.h
+PPCCodeEmitter.o: PPCGenSubtargetInfo.inc.h
+PPCCodeEmitter.po: PPCGenCodeEmitter.inc.h
+PPCCodeEmitter.po: PPCGenInstrInfo.inc.h
+PPCCodeEmitter.po: PPCGenRegisterInfo.inc.h
+PPCCodeEmitter.po: PPCGenSubtargetInfo.inc.h
+PPCFrameLowering.o: PPCGenInstrInfo.inc.h
+PPCFrameLowering.o: PPCGenRegisterInfo.inc.h
+PPCFrameLowering.o: PPCGenSubtargetInfo.inc.h
+PPCFrameLowering.po: PPCGenInstrInfo.inc.h
+PPCFrameLowering.po: PPCGenRegisterInfo.inc.h
+PPCFrameLowering.po: PPCGenSubtargetInfo.inc.h
+PPCHazardRecognizers.o: PPCGenInstrInfo.inc.h
+PPCHazardRecognizers.o: PPCGenRegisterInfo.inc.h
+PPCHazardRecognizers.o: PPCGenSubtargetInfo.inc.h
+PPCHazardRecognizers.po: PPCGenInstrInfo.inc.h
+PPCHazardRecognizers.po: PPCGenRegisterInfo.inc.h
+PPCHazardRecognizers.po: PPCGenSubtargetInfo.inc.h
+PPCISelDAGToDAG.o: Intrinsics.inc.h
+PPCISelDAGToDAG.o: PPCGenDAGISel.inc.h
+PPCISelDAGToDAG.o: PPCGenInstrInfo.inc.h
+PPCISelDAGToDAG.o: PPCGenRegisterInfo.inc.h
+PPCISelDAGToDAG.o: PPCGenSubtargetInfo.inc.h
+PPCISelDAGToDAG.po: Intrinsics.inc.h
+PPCISelDAGToDAG.po: PPCGenDAGISel.inc.h
+PPCISelDAGToDAG.po: PPCGenInstrInfo.inc.h
+PPCISelDAGToDAG.po: PPCGenRegisterInfo.inc.h
+PPCISelDAGToDAG.po: PPCGenSubtargetInfo.inc.h
+PPCISelLowering.o: Intrinsics.inc.h
+PPCISelLowering.o: PPCGenCallingConv.inc.h
+PPCISelLowering.o: PPCGenInstrInfo.inc.h
+PPCISelLowering.o: PPCGenRegisterInfo.inc.h
+PPCISelLowering.o: PPCGenSubtargetInfo.inc.h
+PPCISelLowering.po: Intrinsics.inc.h
+PPCISelLowering.po: PPCGenCallingConv.inc.h
+PPCISelLowering.po: PPCGenInstrInfo.inc.h
+PPCISelLowering.po: PPCGenRegisterInfo.inc.h
+PPCISelLowering.po: PPCGenSubtargetInfo.inc.h
+PPCInstrInfo.o: PPCGenInstrInfo.inc.h
+PPCInstrInfo.o: PPCGenRegisterInfo.inc.h
+PPCInstrInfo.o: PPCGenSubtargetInfo.inc.h
+PPCInstrInfo.po: PPCGenInstrInfo.inc.h
+PPCInstrInfo.po: PPCGenRegisterInfo.inc.h
+PPCInstrInfo.po: PPCGenSubtargetInfo.inc.h
+PPCJITInfo.o: PPCGenInstrInfo.inc.h
+PPCJITInfo.o: PPCGenRegisterInfo.inc.h
+PPCJITInfo.o: PPCGenSubtargetInfo.inc.h
+PPCJITInfo.po: PPCGenInstrInfo.inc.h
+PPCJITInfo.po: PPCGenRegisterInfo.inc.h
+PPCJITInfo.po: PPCGenSubtargetInfo.inc.h
+PPCMCInstLower.o: PPCGenInstrInfo.inc.h
+PPCMCInstLower.o: PPCGenRegisterInfo.inc.h
+PPCMCInstLower.o: PPCGenSubtargetInfo.inc.h
+PPCMCInstLower.po: PPCGenInstrInfo.inc.h
+PPCMCInstLower.po: PPCGenRegisterInfo.inc.h
+PPCMCInstLower.po: PPCGenSubtargetInfo.inc.h
+PPCRegisterInfo.o: PPCGenInstrInfo.inc.h
+PPCRegisterInfo.o: PPCGenRegisterInfo.inc.h
+PPCRegisterInfo.o: PPCGenSubtargetInfo.inc.h
+PPCRegisterInfo.po: PPCGenInstrInfo.inc.h
+PPCRegisterInfo.po: PPCGenRegisterInfo.inc.h
+PPCRegisterInfo.po: PPCGenSubtargetInfo.inc.h
+PPCSelectionDAGInfo.o: PPCGenInstrInfo.inc.h
+PPCSelectionDAGInfo.o: PPCGenRegisterInfo.inc.h
+PPCSelectionDAGInfo.o: PPCGenSubtargetInfo.inc.h
+PPCSelectionDAGInfo.po: PPCGenInstrInfo.inc.h
+PPCSelectionDAGInfo.po: PPCGenRegisterInfo.inc.h
+PPCSelectionDAGInfo.po: PPCGenSubtargetInfo.inc.h
+PPCSubtarget.o: PPCGenInstrInfo.inc.h
+PPCSubtarget.o: PPCGenRegisterInfo.inc.h
+PPCSubtarget.o: PPCGenSubtargetInfo.inc.h
+PPCSubtarget.po: PPCGenInstrInfo.inc.h
+PPCSubtarget.po: PPCGenRegisterInfo.inc.h
+PPCSubtarget.po: PPCGenSubtargetInfo.inc.h
+PPCTargetMachine.o: PPCGenInstrInfo.inc.h
+PPCTargetMachine.o: PPCGenRegisterInfo.inc.h
+PPCTargetMachine.o: PPCGenSubtargetInfo.inc.h
+PPCTargetMachine.po: PPCGenInstrInfo.inc.h
+PPCTargetMachine.po: PPCGenRegisterInfo.inc.h
+PPCTargetMachine.po: PPCGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmpowerpcdesc/Makefile.depend b/lib/clang/libllvmpowerpcdesc/Makefile.depend
new file mode 100644
index 0000000..b67f8a9
--- /dev/null
+++ b/lib/clang/libllvmpowerpcdesc/Makefile.depend
@@ -0,0 +1,43 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+PPCAsmBackend.o: PPCGenInstrInfo.inc.h
+PPCAsmBackend.o: PPCGenRegisterInfo.inc.h
+PPCAsmBackend.o: PPCGenSubtargetInfo.inc.h
+PPCAsmBackend.po: PPCGenInstrInfo.inc.h
+PPCAsmBackend.po: PPCGenRegisterInfo.inc.h
+PPCAsmBackend.po: PPCGenSubtargetInfo.inc.h
+PPCELFObjectWriter.o: PPCGenInstrInfo.inc.h
+PPCELFObjectWriter.o: PPCGenRegisterInfo.inc.h
+PPCELFObjectWriter.o: PPCGenSubtargetInfo.inc.h
+PPCELFObjectWriter.po: PPCGenInstrInfo.inc.h
+PPCELFObjectWriter.po: PPCGenRegisterInfo.inc.h
+PPCELFObjectWriter.po: PPCGenSubtargetInfo.inc.h
+PPCMCCodeEmitter.o: PPCGenInstrInfo.inc.h
+PPCMCCodeEmitter.o: PPCGenMCCodeEmitter.inc.h
+PPCMCCodeEmitter.o: PPCGenRegisterInfo.inc.h
+PPCMCCodeEmitter.o: PPCGenSubtargetInfo.inc.h
+PPCMCCodeEmitter.po: PPCGenInstrInfo.inc.h
+PPCMCCodeEmitter.po: PPCGenMCCodeEmitter.inc.h
+PPCMCCodeEmitter.po: PPCGenRegisterInfo.inc.h
+PPCMCCodeEmitter.po: PPCGenSubtargetInfo.inc.h
+PPCMCTargetDesc.o: PPCGenInstrInfo.inc.h
+PPCMCTargetDesc.o: PPCGenRegisterInfo.inc.h
+PPCMCTargetDesc.o: PPCGenSubtargetInfo.inc.h
+PPCMCTargetDesc.po: PPCGenInstrInfo.inc.h
+PPCMCTargetDesc.po: PPCGenRegisterInfo.inc.h
+PPCMCTargetDesc.po: PPCGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmpowerpcinfo/Makefile.depend b/lib/clang/libllvmpowerpcinfo/Makefile.depend
new file mode 100644
index 0000000..22102dc
--- /dev/null
+++ b/lib/clang/libllvmpowerpcinfo/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+PowerPCTargetInfo.o: PPCGenInstrInfo.inc.h
+PowerPCTargetInfo.o: PPCGenRegisterInfo.inc.h
+PowerPCTargetInfo.o: PPCGenSubtargetInfo.inc.h
+PowerPCTargetInfo.po: PPCGenInstrInfo.inc.h
+PowerPCTargetInfo.po: PPCGenRegisterInfo.inc.h
+PowerPCTargetInfo.po: PPCGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmpowerpcinstprinter/Makefile.depend b/lib/clang/libllvmpowerpcinstprinter/Makefile.depend
new file mode 100644
index 0000000..da1fa0f
--- /dev/null
+++ b/lib/clang/libllvmpowerpcinstprinter/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+PPCInstPrinter.o: PPCGenAsmWriter.inc.h
+PPCInstPrinter.o: PPCGenInstrInfo.inc.h
+PPCInstPrinter.o: PPCGenRegisterInfo.inc.h
+PPCInstPrinter.o: PPCGenSubtargetInfo.inc.h
+PPCInstPrinter.po: PPCGenAsmWriter.inc.h
+PPCInstPrinter.po: PPCGenInstrInfo.inc.h
+PPCInstPrinter.po: PPCGenRegisterInfo.inc.h
+PPCInstPrinter.po: PPCGenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmruntimedyld/Makefile.depend b/lib/clang/libllvmruntimedyld/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmruntimedyld/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmscalaropts/Makefile.depend b/lib/clang/libllvmscalaropts/Makefile.depend
new file mode 100644
index 0000000..5b49aa4
--- /dev/null
+++ b/lib/clang/libllvmscalaropts/Makefile.depend
@@ -0,0 +1,59 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ADCE.o: Intrinsics.inc.h
+ADCE.po: Intrinsics.inc.h
+CodeGenPrepare.o: Intrinsics.inc.h
+CodeGenPrepare.po: Intrinsics.inc.h
+DeadStoreElimination.o: Intrinsics.inc.h
+DeadStoreElimination.po: Intrinsics.inc.h
+GVN.o: Intrinsics.inc.h
+GVN.po: Intrinsics.inc.h
+GlobalMerge.o: Intrinsics.inc.h
+GlobalMerge.po: Intrinsics.inc.h
+IndVarSimplify.o: Intrinsics.inc.h
+IndVarSimplify.po: Intrinsics.inc.h
+JumpThreading.o: Intrinsics.inc.h
+JumpThreading.po: Intrinsics.inc.h
+LICM.o: Intrinsics.inc.h
+LICM.po: Intrinsics.inc.h
+LoopIdiomRecognize.o: Intrinsics.inc.h
+LoopIdiomRecognize.po: Intrinsics.inc.h
+LoopRotation.o: Intrinsics.inc.h
+LoopRotation.po: Intrinsics.inc.h
+LoopStrengthReduce.o: Intrinsics.inc.h
+LoopStrengthReduce.po: Intrinsics.inc.h
+LoopUnrollPass.o: Intrinsics.inc.h
+LoopUnrollPass.po: Intrinsics.inc.h
+LowerAtomic.o: Intrinsics.inc.h
+LowerAtomic.po: Intrinsics.inc.h
+MemCpyOptimizer.o: Intrinsics.inc.h
+MemCpyOptimizer.po: Intrinsics.inc.h
+ObjCARC.o: Intrinsics.inc.h
+ObjCARC.po: Intrinsics.inc.h
+Reassociate.o: Intrinsics.inc.h
+Reassociate.po: Intrinsics.inc.h
+ScalarReplAggregates.o: Intrinsics.inc.h
+ScalarReplAggregates.po: Intrinsics.inc.h
+SimplifyCFGPass.o: Intrinsics.inc.h
+SimplifyCFGPass.po: Intrinsics.inc.h
+SimplifyLibCalls.o: Intrinsics.inc.h
+SimplifyLibCalls.po: Intrinsics.inc.h
+Sink.o: Intrinsics.inc.h
+Sink.po: Intrinsics.inc.h
+TailRecursionElimination.o: Intrinsics.inc.h
+TailRecursionElimination.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvmselectiondag/Makefile.depend b/lib/clang/libllvmselectiondag/Makefile.depend
new file mode 100644
index 0000000..cae65c8
--- /dev/null
+++ b/lib/clang/libllvmselectiondag/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+FastISel.o: Intrinsics.inc.h
+FastISel.po: Intrinsics.inc.h
+FunctionLoweringInfo.o: Intrinsics.inc.h
+FunctionLoweringInfo.po: Intrinsics.inc.h
+SelectionDAG.o: Intrinsics.inc.h
+SelectionDAG.po: Intrinsics.inc.h
+SelectionDAGBuilder.o: Intrinsics.inc.h
+SelectionDAGBuilder.po: Intrinsics.inc.h
+SelectionDAGDumper.o: Intrinsics.inc.h
+SelectionDAGDumper.po: Intrinsics.inc.h
+SelectionDAGISel.o: Intrinsics.inc.h
+SelectionDAGISel.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvmsupport/Makefile.depend b/lib/clang/libllvmsupport/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmsupport/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmtablegen/Makefile.depend b/lib/clang/libllvmtablegen/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmtablegen/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmtarget/Makefile.depend b/lib/clang/libllvmtarget/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmtarget/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/clang/libllvmtransformutils/Makefile.depend b/lib/clang/libllvmtransformutils/Makefile.depend
new file mode 100644
index 0000000..16320ac
--- /dev/null
+++ b/lib/clang/libllvmtransformutils/Makefile.depend
@@ -0,0 +1,41 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+BasicBlockUtils.o: Intrinsics.inc.h
+BasicBlockUtils.po: Intrinsics.inc.h
+BuildLibCalls.o: Intrinsics.inc.h
+BuildLibCalls.po: Intrinsics.inc.h
+CloneFunction.o: Intrinsics.inc.h
+CloneFunction.po: Intrinsics.inc.h
+CodeExtractor.o: Intrinsics.inc.h
+CodeExtractor.po: Intrinsics.inc.h
+InlineFunction.o: Intrinsics.inc.h
+InlineFunction.po: Intrinsics.inc.h
+Local.o: Intrinsics.inc.h
+Local.po: Intrinsics.inc.h
+LoopSimplify.o: Intrinsics.inc.h
+LoopSimplify.po: Intrinsics.inc.h
+LowerExpectIntrinsic.o: Intrinsics.inc.h
+LowerExpectIntrinsic.po: Intrinsics.inc.h
+LowerInvoke.o: Intrinsics.inc.h
+LowerInvoke.po: Intrinsics.inc.h
+PromoteMemoryToRegister.o: Intrinsics.inc.h
+PromoteMemoryToRegister.po: Intrinsics.inc.h
+SSAUpdater.o: Intrinsics.inc.h
+SSAUpdater.po: Intrinsics.inc.h
+SimplifyCFG.o: Intrinsics.inc.h
+SimplifyCFG.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvmvectorize/Makefile.depend b/lib/clang/libllvmvectorize/Makefile.depend
new file mode 100644
index 0000000..4bf1943
--- /dev/null
+++ b/lib/clang/libllvmvectorize/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+BBVectorize.o: Intrinsics.inc.h
+BBVectorize.po: Intrinsics.inc.h
+.endif
diff --git a/lib/clang/libllvmx86asmparser/Makefile.depend b/lib/clang/libllvmx86asmparser/Makefile.depend
new file mode 100644
index 0000000..22486a9
--- /dev/null
+++ b/lib/clang/libllvmx86asmparser/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+X86AsmLexer.o: X86GenAsmMatcher.inc.h
+X86AsmLexer.o: X86GenInstrInfo.inc.h
+X86AsmLexer.o: X86GenRegisterInfo.inc.h
+X86AsmLexer.o: X86GenSubtargetInfo.inc.h
+X86AsmLexer.po: X86GenAsmMatcher.inc.h
+X86AsmLexer.po: X86GenInstrInfo.inc.h
+X86AsmLexer.po: X86GenRegisterInfo.inc.h
+X86AsmLexer.po: X86GenSubtargetInfo.inc.h
+X86AsmParser.o: X86GenAsmMatcher.inc.h
+X86AsmParser.o: X86GenInstrInfo.inc.h
+X86AsmParser.o: X86GenRegisterInfo.inc.h
+X86AsmParser.o: X86GenSubtargetInfo.inc.h
+X86AsmParser.po: X86GenAsmMatcher.inc.h
+X86AsmParser.po: X86GenInstrInfo.inc.h
+X86AsmParser.po: X86GenRegisterInfo.inc.h
+X86AsmParser.po: X86GenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmx86codegen/Makefile.depend b/lib/clang/libllvmx86codegen/Makefile.depend
new file mode 100644
index 0000000..f1da7d6
--- /dev/null
+++ b/lib/clang/libllvmx86codegen/Makefile.depend
@@ -0,0 +1,127 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+X86AsmPrinter.o: X86GenInstrInfo.inc.h
+X86AsmPrinter.o: X86GenRegisterInfo.inc.h
+X86AsmPrinter.o: X86GenSubtargetInfo.inc.h
+X86AsmPrinter.po: X86GenInstrInfo.inc.h
+X86AsmPrinter.po: X86GenRegisterInfo.inc.h
+X86AsmPrinter.po: X86GenSubtargetInfo.inc.h
+X86CodeEmitter.o: X86GenInstrInfo.inc.h
+X86CodeEmitter.o: X86GenRegisterInfo.inc.h
+X86CodeEmitter.o: X86GenSubtargetInfo.inc.h
+X86CodeEmitter.po: X86GenInstrInfo.inc.h
+X86CodeEmitter.po: X86GenRegisterInfo.inc.h
+X86CodeEmitter.po: X86GenSubtargetInfo.inc.h
+X86FastISel.o: Intrinsics.inc.h
+X86FastISel.o: X86GenCallingConv.inc.h
+X86FastISel.o: X86GenFastISel.inc.h
+X86FastISel.o: X86GenInstrInfo.inc.h
+X86FastISel.o: X86GenRegisterInfo.inc.h
+X86FastISel.o: X86GenSubtargetInfo.inc.h
+X86FastISel.po: Intrinsics.inc.h
+X86FastISel.po: X86GenCallingConv.inc.h
+X86FastISel.po: X86GenFastISel.inc.h
+X86FastISel.po: X86GenInstrInfo.inc.h
+X86FastISel.po: X86GenRegisterInfo.inc.h
+X86FastISel.po: X86GenSubtargetInfo.inc.h
+X86FloatingPoint.o: X86GenInstrInfo.inc.h
+X86FloatingPoint.o: X86GenRegisterInfo.inc.h
+X86FloatingPoint.o: X86GenSubtargetInfo.inc.h
+X86FloatingPoint.po: X86GenInstrInfo.inc.h
+X86FloatingPoint.po: X86GenRegisterInfo.inc.h
+X86FloatingPoint.po: X86GenSubtargetInfo.inc.h
+X86FrameLowering.o: X86GenInstrInfo.inc.h
+X86FrameLowering.o: X86GenRegisterInfo.inc.h
+X86FrameLowering.o: X86GenSubtargetInfo.inc.h
+X86FrameLowering.po: X86GenInstrInfo.inc.h
+X86FrameLowering.po: X86GenRegisterInfo.inc.h
+X86FrameLowering.po: X86GenSubtargetInfo.inc.h
+X86ISelDAGToDAG.o: Intrinsics.inc.h
+X86ISelDAGToDAG.o: X86GenDAGISel.inc.h
+X86ISelDAGToDAG.o: X86GenInstrInfo.inc.h
+X86ISelDAGToDAG.o: X86GenRegisterInfo.inc.h
+X86ISelDAGToDAG.o: X86GenSubtargetInfo.inc.h
+X86ISelDAGToDAG.po: Intrinsics.inc.h
+X86ISelDAGToDAG.po: X86GenDAGISel.inc.h
+X86ISelDAGToDAG.po: X86GenInstrInfo.inc.h
+X86ISelDAGToDAG.po: X86GenRegisterInfo.inc.h
+X86ISelDAGToDAG.po: X86GenSubtargetInfo.inc.h
+X86ISelLowering.o: Intrinsics.inc.h
+X86ISelLowering.o: X86GenCallingConv.inc.h
+X86ISelLowering.o: X86GenInstrInfo.inc.h
+X86ISelLowering.o: X86GenRegisterInfo.inc.h
+X86ISelLowering.o: X86GenSubtargetInfo.inc.h
+X86ISelLowering.po: Intrinsics.inc.h
+X86ISelLowering.po: X86GenCallingConv.inc.h
+X86ISelLowering.po: X86GenInstrInfo.inc.h
+X86ISelLowering.po: X86GenRegisterInfo.inc.h
+X86ISelLowering.po: X86GenSubtargetInfo.inc.h
+X86InstrInfo.o: X86GenInstrInfo.inc.h
+X86InstrInfo.o: X86GenRegisterInfo.inc.h
+X86InstrInfo.o: X86GenSubtargetInfo.inc.h
+X86InstrInfo.po: X86GenInstrInfo.inc.h
+X86InstrInfo.po: X86GenRegisterInfo.inc.h
+X86InstrInfo.po: X86GenSubtargetInfo.inc.h
+X86JITInfo.o: X86GenInstrInfo.inc.h
+X86JITInfo.o: X86GenRegisterInfo.inc.h
+X86JITInfo.o: X86GenSubtargetInfo.inc.h
+X86JITInfo.po: X86GenInstrInfo.inc.h
+X86JITInfo.po: X86GenRegisterInfo.inc.h
+X86JITInfo.po: X86GenSubtargetInfo.inc.h
+X86MCInstLower.o: X86GenInstrInfo.inc.h
+X86MCInstLower.o: X86GenRegisterInfo.inc.h
+X86MCInstLower.o: X86GenSubtargetInfo.inc.h
+X86MCInstLower.po: X86GenInstrInfo.inc.h
+X86MCInstLower.po: X86GenRegisterInfo.inc.h
+X86MCInstLower.po: X86GenSubtargetInfo.inc.h
+X86RegisterInfo.o: X86GenInstrInfo.inc.h
+X86RegisterInfo.o: X86GenRegisterInfo.inc.h
+X86RegisterInfo.o: X86GenSubtargetInfo.inc.h
+X86RegisterInfo.po: X86GenInstrInfo.inc.h
+X86RegisterInfo.po: X86GenRegisterInfo.inc.h
+X86RegisterInfo.po: X86GenSubtargetInfo.inc.h
+X86SelectionDAGInfo.o: X86GenInstrInfo.inc.h
+X86SelectionDAGInfo.o: X86GenRegisterInfo.inc.h
+X86SelectionDAGInfo.o: X86GenSubtargetInfo.inc.h
+X86SelectionDAGInfo.po: X86GenInstrInfo.inc.h
+X86SelectionDAGInfo.po: X86GenRegisterInfo.inc.h
+X86SelectionDAGInfo.po: X86GenSubtargetInfo.inc.h
+X86Subtarget.o: X86GenInstrInfo.inc.h
+X86Subtarget.o: X86GenRegisterInfo.inc.h
+X86Subtarget.o: X86GenSubtargetInfo.inc.h
+X86Subtarget.po: X86GenInstrInfo.inc.h
+X86Subtarget.po: X86GenRegisterInfo.inc.h
+X86Subtarget.po: X86GenSubtargetInfo.inc.h
+X86TargetMachine.o: X86GenInstrInfo.inc.h
+X86TargetMachine.o: X86GenRegisterInfo.inc.h
+X86TargetMachine.o: X86GenSubtargetInfo.inc.h
+X86TargetMachine.po: X86GenInstrInfo.inc.h
+X86TargetMachine.po: X86GenRegisterInfo.inc.h
+X86TargetMachine.po: X86GenSubtargetInfo.inc.h
+X86TargetObjectFile.o: X86GenInstrInfo.inc.h
+X86TargetObjectFile.o: X86GenRegisterInfo.inc.h
+X86TargetObjectFile.o: X86GenSubtargetInfo.inc.h
+X86TargetObjectFile.po: X86GenInstrInfo.inc.h
+X86TargetObjectFile.po: X86GenRegisterInfo.inc.h
+X86TargetObjectFile.po: X86GenSubtargetInfo.inc.h
+X86VZeroUpper.o: X86GenInstrInfo.inc.h
+X86VZeroUpper.o: X86GenRegisterInfo.inc.h
+X86VZeroUpper.o: X86GenSubtargetInfo.inc.h
+X86VZeroUpper.po: X86GenInstrInfo.inc.h
+X86VZeroUpper.po: X86GenRegisterInfo.inc.h
+X86VZeroUpper.po: X86GenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmx86desc/Makefile.depend b/lib/clang/libllvmx86desc/Makefile.depend
new file mode 100644
index 0000000..2c335d7
--- /dev/null
+++ b/lib/clang/libllvmx86desc/Makefile.depend
@@ -0,0 +1,53 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+X86AsmBackend.o: X86GenInstrInfo.inc.h
+X86AsmBackend.o: X86GenRegisterInfo.inc.h
+X86AsmBackend.o: X86GenSubtargetInfo.inc.h
+X86AsmBackend.po: X86GenInstrInfo.inc.h
+X86AsmBackend.po: X86GenRegisterInfo.inc.h
+X86AsmBackend.po: X86GenSubtargetInfo.inc.h
+X86ELFObjectWriter.o: X86GenInstrInfo.inc.h
+X86ELFObjectWriter.o: X86GenRegisterInfo.inc.h
+X86ELFObjectWriter.o: X86GenSubtargetInfo.inc.h
+X86ELFObjectWriter.po: X86GenInstrInfo.inc.h
+X86ELFObjectWriter.po: X86GenRegisterInfo.inc.h
+X86ELFObjectWriter.po: X86GenSubtargetInfo.inc.h
+X86MCCodeEmitter.o: X86GenInstrInfo.inc.h
+X86MCCodeEmitter.o: X86GenRegisterInfo.inc.h
+X86MCCodeEmitter.o: X86GenSubtargetInfo.inc.h
+X86MCCodeEmitter.po: X86GenInstrInfo.inc.h
+X86MCCodeEmitter.po: X86GenRegisterInfo.inc.h
+X86MCCodeEmitter.po: X86GenSubtargetInfo.inc.h
+X86MCTargetDesc.o: X86GenInstrInfo.inc.h
+X86MCTargetDesc.o: X86GenRegisterInfo.inc.h
+X86MCTargetDesc.o: X86GenSubtargetInfo.inc.h
+X86MCTargetDesc.po: X86GenInstrInfo.inc.h
+X86MCTargetDesc.po: X86GenRegisterInfo.inc.h
+X86MCTargetDesc.po: X86GenSubtargetInfo.inc.h
+X86MachObjectWriter.o: X86GenInstrInfo.inc.h
+X86MachObjectWriter.o: X86GenRegisterInfo.inc.h
+X86MachObjectWriter.o: X86GenSubtargetInfo.inc.h
+X86MachObjectWriter.po: X86GenInstrInfo.inc.h
+X86MachObjectWriter.po: X86GenRegisterInfo.inc.h
+X86MachObjectWriter.po: X86GenSubtargetInfo.inc.h
+X86WinCOFFObjectWriter.o: X86GenInstrInfo.inc.h
+X86WinCOFFObjectWriter.o: X86GenRegisterInfo.inc.h
+X86WinCOFFObjectWriter.o: X86GenSubtargetInfo.inc.h
+X86WinCOFFObjectWriter.po: X86GenInstrInfo.inc.h
+X86WinCOFFObjectWriter.po: X86GenRegisterInfo.inc.h
+X86WinCOFFObjectWriter.po: X86GenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmx86disassembler/Makefile.depend b/lib/clang/libllvmx86disassembler/Makefile.depend
new file mode 100644
index 0000000..4c1fae9
--- /dev/null
+++ b/lib/clang/libllvmx86disassembler/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+X86Disassembler.o: X86GenEDInfo.inc.h
+X86Disassembler.o: X86GenInstrInfo.inc.h
+X86Disassembler.o: X86GenRegisterInfo.inc.h
+X86Disassembler.po: X86GenEDInfo.inc.h
+X86Disassembler.po: X86GenInstrInfo.inc.h
+X86Disassembler.po: X86GenRegisterInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmx86info/Makefile.depend b/lib/clang/libllvmx86info/Makefile.depend
new file mode 100644
index 0000000..2da8b53
--- /dev/null
+++ b/lib/clang/libllvmx86info/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+X86TargetInfo.o: X86GenInstrInfo.inc.h
+X86TargetInfo.o: X86GenRegisterInfo.inc.h
+X86TargetInfo.o: X86GenSubtargetInfo.inc.h
+X86TargetInfo.po: X86GenInstrInfo.inc.h
+X86TargetInfo.po: X86GenRegisterInfo.inc.h
+X86TargetInfo.po: X86GenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmx86instprinter/Makefile.depend b/lib/clang/libllvmx86instprinter/Makefile.depend
new file mode 100644
index 0000000..9eafb91
--- /dev/null
+++ b/lib/clang/libllvmx86instprinter/Makefile.depend
@@ -0,0 +1,39 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+X86ATTInstPrinter.o: X86GenAsmWriter.inc.h
+X86ATTInstPrinter.o: X86GenInstrInfo.inc.h
+X86ATTInstPrinter.o: X86GenRegisterInfo.inc.h
+X86ATTInstPrinter.o: X86GenSubtargetInfo.inc.h
+X86ATTInstPrinter.po: X86GenAsmWriter.inc.h
+X86ATTInstPrinter.po: X86GenInstrInfo.inc.h
+X86ATTInstPrinter.po: X86GenRegisterInfo.inc.h
+X86ATTInstPrinter.po: X86GenSubtargetInfo.inc.h
+X86InstComments.o: X86GenInstrInfo.inc.h
+X86InstComments.o: X86GenRegisterInfo.inc.h
+X86InstComments.o: X86GenSubtargetInfo.inc.h
+X86InstComments.po: X86GenInstrInfo.inc.h
+X86InstComments.po: X86GenRegisterInfo.inc.h
+X86InstComments.po: X86GenSubtargetInfo.inc.h
+X86IntelInstPrinter.o: X86GenAsmWriter1.inc.h
+X86IntelInstPrinter.o: X86GenInstrInfo.inc.h
+X86IntelInstPrinter.o: X86GenRegisterInfo.inc.h
+X86IntelInstPrinter.o: X86GenSubtargetInfo.inc.h
+X86IntelInstPrinter.po: X86GenAsmWriter1.inc.h
+X86IntelInstPrinter.po: X86GenInstrInfo.inc.h
+X86IntelInstPrinter.po: X86GenRegisterInfo.inc.h
+X86IntelInstPrinter.po: X86GenSubtargetInfo.inc.h
+.endif
diff --git a/lib/clang/libllvmx86utils/Makefile.depend b/lib/clang/libllvmx86utils/Makefile.depend
new file mode 100644
index 0000000..6a3fc33
--- /dev/null
+++ b/lib/clang/libllvmx86utils/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/csu/amd64/Makefile b/lib/csu/amd64/Makefile
index 80d14a7..5ddbab6 100644
--- a/lib/csu/amd64/Makefile
+++ b/lib/csu/amd64/Makefile
@@ -9,6 +9,12 @@ CFLAGS+= -I${.CURDIR}/../common \
-I${.CURDIR}/../../libc/include
CFLAGS+= -fno-omit-frame-pointer
+FILES= ${OBJS}
+FILESOWN= ${LIBOWN}
+FILESGRP= ${LIBGRP}
+FILESMODE= ${LIBMODE}
+FILESDIR= ${LIBDIR}
+
all: ${OBJS}
CLEANFILES= ${OBJS}
@@ -38,8 +44,5 @@ Scrt1.s: crt1.c
Scrt1.o: Scrt1.s
${CC} ${ACFLAGS} -c -o ${.TARGET} Scrt1.s
-realinstall:
- ${INSTALL} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
- ${OBJS} ${DESTDIR}${LIBDIR}
-.include <bsd.lib.mk>
+.include <bsd.prog.mk>
diff --git a/lib/csu/amd64/Makefile.depend b/lib/csu/amd64/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/csu/amd64/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/csu/arm/Makefile.depend b/lib/csu/arm/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/csu/arm/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/csu/i386-elf/Makefile b/lib/csu/i386-elf/Makefile
index 286c15c..52e1955 100644
--- a/lib/csu/i386-elf/Makefile
+++ b/lib/csu/i386-elf/Makefile
@@ -24,7 +24,7 @@ gcrt1_c.o: gcrt1_c.s
${CC} ${ACFLAGS} -c -o ${.TARGET} gcrt1_c.s
gcrt1.o: gcrt1_c.o crt1_s.o
- ${LD} ${LDFLAGS} -o gcrt1.o -r crt1_s.o gcrt1_c.o
+ ${LD} ${LDFLAGS:N-[BL]/*} -o gcrt1.o -r crt1_s.o gcrt1_c.o
crt1_c.s: crt1_c.c
${CC} ${CFLAGS} -S -o ${.TARGET} ${.CURDIR}/crt1_c.c
@@ -34,7 +34,7 @@ crt1_c.o: crt1_c.s
${CC} ${ACFLAGS} -c -o ${.TARGET} crt1_c.s
crt1.o: crt1_c.o crt1_s.o
- ${LD} ${LDFLAGS} -o crt1.o -r crt1_s.o crt1_c.o
+ ${LD} ${LDFLAGS:N-[BL]/*} -o crt1.o -r crt1_s.o crt1_c.o
objcopy --localize-symbol _start1 crt1.o
Scrt1_c.s: crt1_c.c
@@ -45,7 +45,7 @@ Scrt1_c.o: Scrt1_c.s
${CC} ${ACFLAGS} -c -o ${.TARGET} Scrt1_c.s
Scrt1.o: Scrt1_c.o crt1_s.o
- ${LD} ${LDFLAGS} -o Scrt1.o -r crt1_s.o Scrt1_c.o
+ ${LD} ${LDFLAGS:N-[BL]/*} -o Scrt1.o -r crt1_s.o Scrt1_c.o
objcopy --localize-symbol _start1 Scrt1.o
.include <bsd.prog.mk>
diff --git a/lib/csu/i386-elf/Makefile.depend b/lib/csu/i386-elf/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/csu/i386-elf/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/csu/mips/Makefile.depend b/lib/csu/mips/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/csu/mips/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/csu/powerpc/Makefile.depend b/lib/csu/powerpc/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/csu/powerpc/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/csu/powerpc64/Makefile.depend b/lib/csu/powerpc64/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/csu/powerpc64/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/csu/sparc64/Makefile.depend b/lib/csu/sparc64/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/csu/sparc64/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libalias/libalias/Makefile.depend b/lib/libalias/libalias/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/libalias/libalias/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libalias/modules/cuseeme/Makefile.depend b/lib/libalias/modules/cuseeme/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libalias/modules/cuseeme/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libalias/modules/dummy/Makefile.depend b/lib/libalias/modules/dummy/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libalias/modules/dummy/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libalias/modules/ftp/Makefile.depend b/lib/libalias/modules/ftp/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libalias/modules/ftp/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libalias/modules/irc/Makefile.depend b/lib/libalias/modules/irc/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libalias/modules/irc/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libalias/modules/nbt/Makefile.depend b/lib/libalias/modules/nbt/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libalias/modules/nbt/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libalias/modules/pptp/Makefile.depend b/lib/libalias/modules/pptp/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libalias/modules/pptp/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libalias/modules/skinny/Makefile.depend b/lib/libalias/modules/skinny/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libalias/modules/skinny/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libalias/modules/smedia/Makefile.depend b/lib/libalias/modules/smedia/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libalias/modules/smedia/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libarchive/Makefile.depend b/lib/libarchive/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libarchive/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libauditd/Makefile.depend b/lib/libauditd/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libauditd/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libbegemot/Makefile.depend b/lib/libbegemot/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libbegemot/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libblocksruntime/Makefile.depend b/lib/libblocksruntime/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libblocksruntime/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libbluetooth/Makefile.depend b/lib/libbluetooth/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libbluetooth/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libbsm/Makefile.depend b/lib/libbsm/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/libbsm/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libbsnmp/libbsnmp/Makefile.depend b/lib/libbsnmp/libbsnmp/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libbsnmp/libbsnmp/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libbz2/Makefile.depend b/lib/libbz2/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libbz2/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
index ed37053..ad98d41 100644
--- a/lib/libc/Makefile
+++ b/lib/libc/Makefile
@@ -149,6 +149,16 @@ libkern.${LIBC_ARCH}:: ${KMSRCS}
.include <bsd.lib.mk>
+.if !defined(_SKIP_BUILD)
+# We need libutil.h, get it directly to avoid
+# recording a build dependency
+CFLAGS+= -I${.CURDIR:H}/libutil
+# Same issue with libm
+MSUN_ARCH_SUBDIR != ${MAKE} -B -C ${.CURDIR:H}/msun -V ARCH_SUBDIR
+# unfortunately msun/src contains both private and public headers
+CFLAGS+= -I${.CURDIR:H}/msun/${MSUN_ARCH_SUBDIR} -I${.CURDIR:H}/msun/src
+.endif
+
# Disable warnings in contributed sources.
CWARNFLAGS:= ${.IMPSRC:Ngdtoa_*.c:C/^.+$/${CWARNFLAGS}/:C/^$/-w/}
# XXX For now, we don't allow libc to be compiled with
diff --git a/lib/libc/Makefile.depend b/lib/libc/Makefile.depend
new file mode 100644
index 0000000..080d7af
--- /dev/null
+++ b/lib/libc/Makefile.depend
@@ -0,0 +1,167 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/rpc \
+ include/rpcsvc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+cancelpoints_sem.So: cancelpoints_sem.c
+cancelpoints_sem.o: cancelpoints_sem.c
+cancelpoints_sem.po: cancelpoints_sem.c
+cancelpoints_sem_new.So: cancelpoints_sem_new.c
+cancelpoints_sem_new.o: cancelpoints_sem_new.c
+cancelpoints_sem_new.po: cancelpoints_sem_new.c
+crypt_clnt.So: crypt.h
+crypt_clnt.So: crypt_clnt.c
+crypt_clnt.o: crypt.h
+crypt_clnt.o: crypt_clnt.c
+crypt_clnt.po: crypt.h
+crypt_clnt.po: crypt_clnt.c
+crypt_xdr.So: crypt.h
+crypt_xdr.So: crypt_xdr.c
+crypt_xdr.o: crypt.h
+crypt_xdr.o: crypt_xdr.c
+crypt_xdr.po: crypt.h
+crypt_xdr.po: crypt_xdr.c
+gdtoa_dmisc.So: gdtoa_dmisc.c
+gdtoa_dmisc.o: gdtoa_dmisc.c
+gdtoa_dmisc.po: gdtoa_dmisc.c
+gdtoa_dtoa.So: gdtoa_dtoa.c
+gdtoa_dtoa.o: gdtoa_dtoa.c
+gdtoa_dtoa.po: gdtoa_dtoa.c
+gdtoa_gdtoa.So: gdtoa_gdtoa.c
+gdtoa_gdtoa.o: gdtoa_gdtoa.c
+gdtoa_gdtoa.po: gdtoa_gdtoa.c
+gdtoa_gethex.So: gdtoa_gethex.c
+gdtoa_gethex.o: gdtoa_gethex.c
+gdtoa_gethex.po: gdtoa_gethex.c
+gdtoa_gmisc.So: gdtoa_gmisc.c
+gdtoa_gmisc.o: gdtoa_gmisc.c
+gdtoa_gmisc.po: gdtoa_gmisc.c
+gdtoa_hd_init.So: gdtoa_hd_init.c
+gdtoa_hd_init.o: gdtoa_hd_init.c
+gdtoa_hd_init.po: gdtoa_hd_init.c
+gdtoa_hexnan.So: gdtoa_hexnan.c
+gdtoa_hexnan.o: gdtoa_hexnan.c
+gdtoa_hexnan.po: gdtoa_hexnan.c
+gdtoa_misc.So: gdtoa_misc.c
+gdtoa_misc.o: gdtoa_misc.c
+gdtoa_misc.po: gdtoa_misc.c
+gdtoa_smisc.So: gdtoa_smisc.c
+gdtoa_smisc.o: gdtoa_smisc.c
+gdtoa_smisc.po: gdtoa_smisc.c
+gdtoa_strtod.So: gdtoa_strtod.c
+gdtoa_strtod.o: gdtoa_strtod.c
+gdtoa_strtod.po: gdtoa_strtod.c
+gdtoa_strtodg.So: gdtoa_strtodg.c
+gdtoa_strtodg.o: gdtoa_strtodg.c
+gdtoa_strtodg.po: gdtoa_strtodg.c
+gdtoa_strtof.So: gdtoa_strtof.c
+gdtoa_strtof.o: gdtoa_strtof.c
+gdtoa_strtof.po: gdtoa_strtof.c
+gdtoa_strtord.So: gdtoa_strtord.c
+gdtoa_strtord.o: gdtoa_strtord.c
+gdtoa_strtord.po: gdtoa_strtord.c
+gdtoa_strtorx.So: gdtoa_strtorx.c
+gdtoa_strtorx.o: gdtoa_strtorx.c
+gdtoa_strtorx.po: gdtoa_strtorx.c
+gdtoa_sum.So: gdtoa_sum.c
+gdtoa_sum.o: gdtoa_sum.c
+gdtoa_sum.po: gdtoa_sum.c
+gdtoa_ulp.So: gdtoa_ulp.c
+gdtoa_ulp.o: gdtoa_ulp.c
+gdtoa_ulp.po: gdtoa_ulp.c
+jemalloc_arena.So: jemalloc_arena.c
+jemalloc_arena.o: jemalloc_arena.c
+jemalloc_arena.po: jemalloc_arena.c
+jemalloc_atomic.So: jemalloc_atomic.c
+jemalloc_atomic.o: jemalloc_atomic.c
+jemalloc_atomic.po: jemalloc_atomic.c
+jemalloc_base.So: jemalloc_base.c
+jemalloc_base.o: jemalloc_base.c
+jemalloc_base.po: jemalloc_base.c
+jemalloc_bitmap.So: jemalloc_bitmap.c
+jemalloc_bitmap.o: jemalloc_bitmap.c
+jemalloc_bitmap.po: jemalloc_bitmap.c
+jemalloc_chunk.So: jemalloc_chunk.c
+jemalloc_chunk.o: jemalloc_chunk.c
+jemalloc_chunk.po: jemalloc_chunk.c
+jemalloc_chunk_dss.So: jemalloc_chunk_dss.c
+jemalloc_chunk_dss.o: jemalloc_chunk_dss.c
+jemalloc_chunk_dss.po: jemalloc_chunk_dss.c
+jemalloc_chunk_mmap.So: jemalloc_chunk_mmap.c
+jemalloc_chunk_mmap.o: jemalloc_chunk_mmap.c
+jemalloc_chunk_mmap.po: jemalloc_chunk_mmap.c
+jemalloc_ckh.So: jemalloc_ckh.c
+jemalloc_ckh.o: jemalloc_ckh.c
+jemalloc_ckh.po: jemalloc_ckh.c
+jemalloc_ctl.So: jemalloc_ctl.c
+jemalloc_ctl.o: jemalloc_ctl.c
+jemalloc_ctl.po: jemalloc_ctl.c
+jemalloc_extent.So: jemalloc_extent.c
+jemalloc_extent.o: jemalloc_extent.c
+jemalloc_extent.po: jemalloc_extent.c
+jemalloc_hash.So: jemalloc_hash.c
+jemalloc_hash.o: jemalloc_hash.c
+jemalloc_hash.po: jemalloc_hash.c
+jemalloc_huge.So: jemalloc_huge.c
+jemalloc_huge.o: jemalloc_huge.c
+jemalloc_huge.po: jemalloc_huge.c
+jemalloc_jemalloc.So: jemalloc_jemalloc.c
+jemalloc_jemalloc.o: jemalloc_jemalloc.c
+jemalloc_jemalloc.po: jemalloc_jemalloc.c
+jemalloc_mb.So: jemalloc_mb.c
+jemalloc_mb.o: jemalloc_mb.c
+jemalloc_mb.po: jemalloc_mb.c
+jemalloc_mutex.So: jemalloc_mutex.c
+jemalloc_mutex.o: jemalloc_mutex.c
+jemalloc_mutex.po: jemalloc_mutex.c
+jemalloc_prof.So: jemalloc_prof.c
+jemalloc_prof.o: jemalloc_prof.c
+jemalloc_prof.po: jemalloc_prof.c
+jemalloc_quarantine.So: jemalloc_quarantine.c
+jemalloc_quarantine.o: jemalloc_quarantine.c
+jemalloc_quarantine.po: jemalloc_quarantine.c
+jemalloc_rtree.So: jemalloc_rtree.c
+jemalloc_rtree.o: jemalloc_rtree.c
+jemalloc_rtree.po: jemalloc_rtree.c
+jemalloc_stats.So: jemalloc_stats.c
+jemalloc_stats.o: jemalloc_stats.c
+jemalloc_stats.po: jemalloc_stats.c
+jemalloc_tcache.So: jemalloc_tcache.c
+jemalloc_tcache.o: jemalloc_tcache.c
+jemalloc_tcache.po: jemalloc_tcache.c
+jemalloc_tsd.So: jemalloc_tsd.c
+jemalloc_tsd.o: jemalloc_tsd.c
+jemalloc_tsd.po: jemalloc_tsd.c
+jemalloc_util.So: jemalloc_util.c
+jemalloc_util.o: jemalloc_util.c
+jemalloc_util.po: jemalloc_util.c
+nslexer.So: nslexer.c
+nslexer.So: nsparser.h
+nslexer.o: nslexer.c
+nslexer.o: nsparser.h
+nslexer.po: nslexer.c
+nslexer.po: nsparser.h
+nsparser.So: nsparser.c
+nsparser.o: nsparser.c
+nsparser.po: nsparser.c
+subr_acl_nfs4.So: subr_acl_nfs4.c
+subr_acl_nfs4.o: subr_acl_nfs4.c
+subr_acl_nfs4.po: subr_acl_nfs4.c
+yp_xdr.So: yp.h
+yp_xdr.So: yp_xdr.c
+yp_xdr.o: yp.h
+yp_xdr.o: yp_xdr.c
+yp_xdr.po: yp.h
+yp_xdr.po: yp_xdr.c
+.endif
diff --git a/lib/libcalendar/Makefile.depend b/lib/libcalendar/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/libcalendar/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libcam/Makefile.depend b/lib/libcam/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libcam/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libcom_err/Makefile.depend b/lib/libcom_err/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libcom_err/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libcompat/Makefile.depend b/lib/libcompat/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libcompat/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libcompiler_rt/Makefile.depend b/lib/libcompiler_rt/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/libcompiler_rt/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libcrypt/Makefile.depend b/lib/libcrypt/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/lib/libcrypt/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libdevinfo/Makefile.depend b/lib/libdevinfo/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libdevinfo/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libdevstat/Makefile.depend b/lib/libdevstat/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libdevstat/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libdisk/Makefile.depend b/lib/libdisk/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libdisk/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libdwarf/Makefile.depend b/lib/libdwarf/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libdwarf/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libedit/Makefile.depend b/lib/libedit/Makefile.depend
new file mode 100644
index 0000000..c578f2d
--- /dev/null
+++ b/lib/libedit/Makefile.depend
@@ -0,0 +1,55 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+editline.So: common.h
+editline.So: editline.c
+editline.So: emacs.h
+editline.So: fcns.c
+editline.So: fcns.h
+editline.So: help.c
+editline.So: help.h
+editline.So: vi.h
+editline.o: common.h
+editline.o: editline.c
+editline.o: emacs.h
+editline.o: fcns.c
+editline.o: fcns.h
+editline.o: help.c
+editline.o: help.h
+editline.o: vi.h
+editline.po: common.h
+editline.po: editline.c
+editline.po: emacs.h
+editline.po: fcns.c
+editline.po: fcns.h
+editline.po: help.c
+editline.po: help.h
+editline.po: vi.h
+readline.So: common.h
+readline.So: emacs.h
+readline.So: fcns.h
+readline.So: help.h
+readline.So: vi.h
+readline.o: common.h
+readline.o: emacs.h
+readline.o: fcns.h
+readline.o: help.h
+readline.o: vi.h
+readline.po: common.h
+readline.po: emacs.h
+readline.po: fcns.h
+readline.po: help.h
+readline.po: vi.h
+.endif
diff --git a/lib/libedit/edit/readline/Makefile.depend b/lib/libedit/edit/readline/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/lib/libedit/edit/readline/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libelf/Makefile.depend b/lib/libelf/Makefile.depend
new file mode 100644
index 0000000..a2d3144
--- /dev/null
+++ b/lib/libelf/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+libelf_convert.So: libelf_convert.c
+libelf_convert.o: libelf_convert.c
+libelf_convert.po: libelf_convert.c
+libelf_fsize.So: libelf_fsize.c
+libelf_fsize.o: libelf_fsize.c
+libelf_fsize.po: libelf_fsize.c
+libelf_msize.So: libelf_msize.c
+libelf_msize.o: libelf_msize.c
+libelf_msize.po: libelf_msize.c
+.endif
diff --git a/lib/libexpat/Makefile.depend b/lib/libexpat/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libexpat/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libfetch/Makefile.depend b/lib/libfetch/Makefile.depend
new file mode 100644
index 0000000..145c133
--- /dev/null
+++ b/lib/libfetch/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ftp.So: ftperr.h
+ftp.o: ftperr.h
+ftp.po: ftperr.h
+http.So: httperr.h
+http.o: httperr.h
+http.po: httperr.h
+.endif
diff --git a/lib/libgeom/Makefile.depend b/lib/libgeom/Makefile.depend
new file mode 100644
index 0000000..5c54095
--- /dev/null
+++ b/lib/libgeom/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libexpat \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libgpib/Makefile.depend b/lib/libgpib/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/libgpib/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libgssapi/Makefile.depend b/lib/libgssapi/Makefile.depend
new file mode 100644
index 0000000..11612ba
--- /dev/null
+++ b/lib/libgssapi/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/gssapi \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libipsec/Makefile.depend b/lib/libipsec/Makefile.depend
new file mode 100644
index 0000000..bced0ef
--- /dev/null
+++ b/lib/libipsec/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+policy_parse.So: policy_parse.c
+policy_parse.o: policy_parse.c
+policy_parse.po: policy_parse.c
+policy_token.So: policy_token.c
+policy_token.So: y.tab.h
+policy_token.o: policy_token.c
+policy_token.o: y.tab.h
+policy_token.po: policy_token.c
+policy_token.po: y.tab.h
+.endif
diff --git a/lib/libipx/Makefile.depend b/lib/libipx/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/libipx/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libjail/Makefile.depend b/lib/libjail/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/libjail/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libkiconv/Makefile.depend b/lib/libkiconv/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libkiconv/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libkvm/Makefile.depend b/lib/libkvm/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/lib/libkvm/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/liblzma/Makefile.depend b/lib/liblzma/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/liblzma/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libmagic/Makefile.depend b/lib/libmagic/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libmagic/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libmd/Makefile.depend b/lib/libmd/Makefile.depend
new file mode 100644
index 0000000..d342b5c
--- /dev/null
+++ b/lib/libmd/Makefile.depend
@@ -0,0 +1,37 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+md4hl.So: md4hl.c
+md4hl.o: md4hl.c
+md4hl.po: md4hl.c
+md5hl.So: md5hl.c
+md5hl.o: md5hl.c
+md5hl.po: md5hl.c
+rmd160hl.So: rmd160hl.c
+rmd160hl.o: rmd160hl.c
+rmd160hl.po: rmd160hl.c
+sha0hl.So: sha0hl.c
+sha0hl.o: sha0hl.c
+sha0hl.po: sha0hl.c
+sha1hl.So: sha1hl.c
+sha1hl.o: sha1hl.c
+sha1hl.po: sha1hl.c
+sha256hl.So: sha256hl.c
+sha256hl.o: sha256hl.c
+sha256hl.po: sha256hl.c
+sha512hl.So: sha512hl.c
+sha512hl.o: sha512hl.c
+sha512hl.po: sha512hl.c
+.endif
diff --git a/lib/libmemstat/Makefile.depend b/lib/libmemstat/Makefile.depend
new file mode 100644
index 0000000..4db4c88
--- /dev/null
+++ b/lib/libmemstat/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libmilter/Makefile.depend b/lib/libmilter/Makefile.depend
new file mode 100644
index 0000000..be77ccf
--- /dev/null
+++ b/lib/libmilter/Makefile.depend
@@ -0,0 +1,54 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+comm.So: sm_os.h
+comm.o: sm_os.h
+comm.po: sm_os.h
+engine.So: sm_os.h
+engine.o: sm_os.h
+engine.po: sm_os.h
+errstring.So: sm_os.h
+errstring.o: sm_os.h
+errstring.po: sm_os.h
+handler.So: sm_os.h
+handler.o: sm_os.h
+handler.po: sm_os.h
+listener.So: sm_os.h
+listener.o: sm_os.h
+listener.po: sm_os.h
+main.So: sm_os.h
+main.o: sm_os.h
+main.po: sm_os.h
+monitor.So: sm_os.h
+monitor.o: sm_os.h
+monitor.po: sm_os.h
+signal.So: sm_os.h
+signal.o: sm_os.h
+signal.po: sm_os.h
+sm_gethost.So: sm_os.h
+sm_gethost.o: sm_os.h
+sm_gethost.po: sm_os.h
+smfi.So: sm_os.h
+smfi.o: sm_os.h
+smfi.po: sm_os.h
+strl.So: sm_os.h
+strl.o: sm_os.h
+strl.po: sm_os.h
+worker.So: sm_os.h
+worker.o: sm_os.h
+worker.po: sm_os.h
+.endif
diff --git a/lib/libmp/Makefile.depend b/lib/libmp/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libmp/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libncp/Makefile.depend b/lib/libncp/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/lib/libncp/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libnetgraph/Makefile.depend b/lib/libnetgraph/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libnetgraph/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libngatm/Makefile.depend b/lib/libngatm/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/libngatm/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libopie/Makefile.depend b/lib/libopie/Makefile.depend
new file mode 100644
index 0000000..22f59e0
--- /dev/null
+++ b/lib/libopie/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libmd \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/libpam/Makefile.depend b/lib/libpam/libpam/Makefile.depend
new file mode 100644
index 0000000..5d23c5e
--- /dev/null
+++ b/lib/libpam/libpam/Makefile.depend
@@ -0,0 +1,40 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libpam/modules/pam_chroot \
+ lib/libpam/modules/pam_deny \
+ lib/libpam/modules/pam_echo \
+ lib/libpam/modules/pam_exec \
+ lib/libpam/modules/pam_ftpusers \
+ lib/libpam/modules/pam_group \
+ lib/libpam/modules/pam_guest \
+ lib/libpam/modules/pam_krb5 \
+ lib/libpam/modules/pam_ksu \
+ lib/libpam/modules/pam_lastlog \
+ lib/libpam/modules/pam_login_access \
+ lib/libpam/modules/pam_nologin \
+ lib/libpam/modules/pam_opie \
+ lib/libpam/modules/pam_opieaccess \
+ lib/libpam/modules/pam_passwdqc \
+ lib/libpam/modules/pam_permit \
+ lib/libpam/modules/pam_radius \
+ lib/libpam/modules/pam_rhosts \
+ lib/libpam/modules/pam_rootok \
+ lib/libpam/modules/pam_securetty \
+ lib/libpam/modules/pam_self \
+ lib/libpam/modules/pam_ssh \
+ lib/libpam/modules/pam_tacplus \
+ lib/libpam/modules/pam_unix \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_chroot/Makefile.depend b/lib/libpam/modules/pam_chroot/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_chroot/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_deny/Makefile.depend b/lib/libpam/modules/pam_deny/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/libpam/modules/pam_deny/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_echo/Makefile.depend b/lib/libpam/modules/pam_echo/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_echo/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_exec/Makefile.depend b/lib/libpam/modules/pam_exec/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_exec/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_ftpusers/Makefile.depend b/lib/libpam/modules/pam_ftpusers/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_ftpusers/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_group/Makefile.depend b/lib/libpam/modules/pam_group/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_group/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_guest/Makefile.depend b/lib/libpam/modules/pam_guest/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_guest/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_krb5/Makefile.depend b/lib/libpam/modules/pam_krb5/Makefile.depend
new file mode 100644
index 0000000..eb4d075
--- /dev/null
+++ b/lib/libpam/modules/pam_krb5/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libkrb5 \
+ lib/libcom_err \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_ksu/Makefile.depend b/lib/libpam/modules/pam_ksu/Makefile.depend
new file mode 100644
index 0000000..a35745a
--- /dev/null
+++ b/lib/libpam/modules/pam_ksu/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libkrb5 \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_lastlog/Makefile.depend b/lib/libpam/modules/pam_lastlog/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_lastlog/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_login_access/Makefile.depend b/lib/libpam/modules/pam_login_access/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_login_access/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_nologin/Makefile.depend b/lib/libpam/modules/pam_nologin/Makefile.depend
new file mode 100644
index 0000000..4046f0e
--- /dev/null
+++ b/lib/libpam/modules/pam_nologin/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_opie/Makefile.depend b/lib/libpam/modules/pam_opie/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_opie/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_opieaccess/Makefile.depend b/lib/libpam/modules/pam_opieaccess/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/libpam/modules/pam_opieaccess/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_passwdqc/Makefile.depend b/lib/libpam/modules/pam_passwdqc/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_passwdqc/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_permit/Makefile.depend b/lib/libpam/modules/pam_permit/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/libpam/modules/pam_permit/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_radius/Makefile.depend b/lib/libpam/modules/pam_radius/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_radius/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_rhosts/Makefile.depend b/lib/libpam/modules/pam_rhosts/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_rhosts/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_rootok/Makefile.depend b/lib/libpam/modules/pam_rootok/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/libpam/modules/pam_rootok/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_securetty/Makefile.depend b/lib/libpam/modules/pam_securetty/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_securetty/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_self/Makefile.depend b/lib/libpam/modules/pam_self/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/libpam/modules/pam_self/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_ssh/Makefile.depend b/lib/libpam/modules/pam_ssh/Makefile.depend
new file mode 100644
index 0000000..cc2d1b6
--- /dev/null
+++ b/lib/libpam/modules/pam_ssh/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_tacplus/Makefile.depend b/lib/libpam/modules/pam_tacplus/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpam/modules/pam_tacplus/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpam/modules/pam_unix/Makefile.depend b/lib/libpam/modules/pam_unix/Makefile.depend
new file mode 100644
index 0000000..cc2d1b6
--- /dev/null
+++ b/lib/libpam/modules/pam_unix/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libpcap/Makefile.depend b/lib/libpcap/Makefile.depend
new file mode 100644
index 0000000..5d469eb
--- /dev/null
+++ b/lib/libpcap/Makefile.depend
@@ -0,0 +1,32 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+grammar.So: grammar.c
+grammar.o: grammar.c
+grammar.po: grammar.c
+pcap.So: version.h
+pcap.o: version.h
+pcap.po: version.h
+scanner.So: scanner.c
+scanner.So: tokdefs.h
+scanner.o: scanner.c
+scanner.o: tokdefs.h
+scanner.po: scanner.c
+scanner.po: tokdefs.h
+version.So: version.c
+version.o: version.c
+version.po: version.c
+.endif
diff --git a/lib/libpmc/Makefile.depend b/lib/libpmc/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libpmc/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libproc/Makefile.depend b/lib/libproc/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/lib/libproc/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libprocstat/Makefile.depend b/lib/libprocstat/Makefile.depend
new file mode 100644
index 0000000..4a51c12
--- /dev/null
+++ b/lib/libprocstat/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libkvm \
+ lib/libprocstat/zfs \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libprocstat/zfs/Makefile.depend b/lib/libprocstat/zfs/Makefile.depend
new file mode 100644
index 0000000..cbc3887
--- /dev/null
+++ b/lib/libprocstat/zfs/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libkvm \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libradius/Makefile.depend b/lib/libradius/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/libradius/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/librpcsec_gss/Makefile.depend b/lib/librpcsec_gss/Makefile.depend
new file mode 100644
index 0000000..5324dbc
--- /dev/null
+++ b/lib/librpcsec_gss/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/rpc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/librpcsvc/Makefile.depend b/lib/librpcsvc/Makefile.depend
new file mode 100644
index 0000000..c753690
--- /dev/null
+++ b/lib/librpcsvc/Makefile.depend
@@ -0,0 +1,60 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+klm_prot_xdr.So: klm_prot_xdr.c
+klm_prot_xdr.o: klm_prot_xdr.c
+klm_prot_xdr.po: klm_prot_xdr.c
+mount_xdr.So: mount_xdr.c
+mount_xdr.o: mount_xdr.c
+mount_xdr.po: mount_xdr.c
+nfs_prot_xdr.So: nfs_prot_xdr.c
+nfs_prot_xdr.o: nfs_prot_xdr.c
+nfs_prot_xdr.po: nfs_prot_xdr.c
+nlm_prot_xdr.So: nlm_prot_xdr.c
+nlm_prot_xdr.o: nlm_prot_xdr.c
+nlm_prot_xdr.po: nlm_prot_xdr.c
+rex_xdr.So: rex_xdr.c
+rex_xdr.o: rex_xdr.c
+rex_xdr.po: rex_xdr.c
+rnusers_xdr.So: rnusers_xdr.c
+rnusers_xdr.o: rnusers_xdr.c
+rnusers_xdr.po: rnusers_xdr.c
+rquota_xdr.So: rquota_xdr.c
+rquota_xdr.o: rquota_xdr.c
+rquota_xdr.po: rquota_xdr.c
+rstat_xdr.So: rstat_xdr.c
+rstat_xdr.o: rstat_xdr.c
+rstat_xdr.po: rstat_xdr.c
+rwall_xdr.So: rwall_xdr.c
+rwall_xdr.o: rwall_xdr.c
+rwall_xdr.po: rwall_xdr.c
+sm_inter_xdr.So: sm_inter_xdr.c
+sm_inter_xdr.o: sm_inter_xdr.c
+sm_inter_xdr.po: sm_inter_xdr.c
+spray_xdr.So: spray_xdr.c
+spray_xdr.o: spray_xdr.c
+spray_xdr.po: spray_xdr.c
+yppasswd_xdr.So: yppasswd_xdr.c
+yppasswd_xdr.o: yppasswd_xdr.c
+yppasswd_xdr.po: yppasswd_xdr.c
+ypupdate_prot_xdr.So: ypupdate_prot_xdr.c
+ypupdate_prot_xdr.o: ypupdate_prot_xdr.c
+ypupdate_prot_xdr.po: ypupdate_prot_xdr.c
+ypxfrd_xdr.So: ypxfrd_xdr.c
+ypxfrd_xdr.o: ypxfrd_xdr.c
+ypxfrd_xdr.po: ypxfrd_xdr.c
+.endif
diff --git a/lib/librt/Makefile.depend b/lib/librt/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/librt/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/librtld_db/Makefile.depend b/lib/librtld_db/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/lib/librtld_db/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libsbuf/Makefile.depend b/lib/libsbuf/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libsbuf/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libsdp/Makefile.depend b/lib/libsdp/Makefile.depend
new file mode 100644
index 0000000..47939e0
--- /dev/null
+++ b/lib/libsdp/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libbluetooth \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libsm/Makefile.depend b/lib/libsm/Makefile.depend
new file mode 100644
index 0000000..6a23591
--- /dev/null
+++ b/lib/libsm/Makefile.depend
@@ -0,0 +1,155 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+assert.o: sm_os.h
+assert.po: sm_os.h
+cf.o: sm_os.h
+cf.po: sm_os.h
+clock.o: sm_os.h
+clock.po: sm_os.h
+clrerr.o: sm_os.h
+clrerr.po: sm_os.h
+config.o: sm_os.h
+config.po: sm_os.h
+debug.o: sm_os.h
+debug.po: sm_os.h
+errstring.o: sm_os.h
+errstring.po: sm_os.h
+exc.o: sm_os.h
+exc.po: sm_os.h
+fclose.o: sm_os.h
+fclose.po: sm_os.h
+feof.o: sm_os.h
+feof.po: sm_os.h
+ferror.o: sm_os.h
+ferror.po: sm_os.h
+fflush.o: sm_os.h
+fflush.po: sm_os.h
+fget.o: sm_os.h
+fget.po: sm_os.h
+findfp.o: sm_os.h
+findfp.po: sm_os.h
+flags.o: sm_os.h
+flags.po: sm_os.h
+fopen.o: sm_os.h
+fopen.po: sm_os.h
+fpos.o: sm_os.h
+fpos.po: sm_os.h
+fprintf.o: sm_os.h
+fprintf.po: sm_os.h
+fpurge.o: sm_os.h
+fpurge.po: sm_os.h
+fput.o: sm_os.h
+fput.po: sm_os.h
+fread.o: sm_os.h
+fread.po: sm_os.h
+fscanf.o: sm_os.h
+fscanf.po: sm_os.h
+fseek.o: sm_os.h
+fseek.po: sm_os.h
+fvwrite.o: sm_os.h
+fvwrite.po: sm_os.h
+fwalk.o: sm_os.h
+fwalk.po: sm_os.h
+fwrite.o: sm_os.h
+fwrite.po: sm_os.h
+get.o: sm_os.h
+get.po: sm_os.h
+heap.o: sm_os.h
+heap.po: sm_os.h
+ldap.o: sm_os.h
+ldap.po: sm_os.h
+makebuf.o: sm_os.h
+makebuf.po: sm_os.h
+match.o: sm_os.h
+match.po: sm_os.h
+mbdb.o: sm_os.h
+mbdb.po: sm_os.h
+memstat.o: sm_os.h
+memstat.po: sm_os.h
+mpeix.o: sm_os.h
+mpeix.po: sm_os.h
+niprop.o: sm_os.h
+niprop.po: sm_os.h
+path.o: sm_os.h
+path.po: sm_os.h
+put.o: sm_os.h
+put.po: sm_os.h
+refill.o: sm_os.h
+refill.po: sm_os.h
+rewind.o: sm_os.h
+rewind.po: sm_os.h
+rpool.o: sm_os.h
+rpool.po: sm_os.h
+sem.o: sm_os.h
+sem.po: sm_os.h
+setvbuf.o: sm_os.h
+setvbuf.po: sm_os.h
+shm.o: sm_os.h
+shm.po: sm_os.h
+signal.o: sm_os.h
+signal.po: sm_os.h
+smstdio.o: sm_os.h
+smstdio.po: sm_os.h
+snprintf.o: sm_os.h
+snprintf.po: sm_os.h
+sscanf.o: sm_os.h
+sscanf.po: sm_os.h
+stdio.o: sm_os.h
+stdio.po: sm_os.h
+strcasecmp.o: sm_os.h
+strcasecmp.po: sm_os.h
+strdup.o: sm_os.h
+strdup.po: sm_os.h
+strerror.o: sm_os.h
+strerror.po: sm_os.h
+strexit.o: sm_os.h
+strexit.po: sm_os.h
+string.o: sm_os.h
+string.po: sm_os.h
+stringf.o: sm_os.h
+stringf.po: sm_os.h
+strio.o: sm_os.h
+strio.po: sm_os.h
+strl.o: sm_os.h
+strl.po: sm_os.h
+strrevcmp.o: sm_os.h
+strrevcmp.po: sm_os.h
+strto.o: sm_os.h
+strto.po: sm_os.h
+test.o: sm_os.h
+test.po: sm_os.h
+ungetc.o: sm_os.h
+ungetc.po: sm_os.h
+util.o: sm_os.h
+util.po: sm_os.h
+vasprintf.o: sm_os.h
+vasprintf.po: sm_os.h
+vfprintf.o: sm_os.h
+vfprintf.po: sm_os.h
+vfscanf.o: sm_os.h
+vfscanf.po: sm_os.h
+vprintf.o: sm_os.h
+vprintf.po: sm_os.h
+vsnprintf.o: sm_os.h
+vsnprintf.po: sm_os.h
+wbuf.o: sm_os.h
+wbuf.po: sm_os.h
+wsetup.o: sm_os.h
+wsetup.po: sm_os.h
+xtrap.o: sm_os.h
+xtrap.po: sm_os.h
+.endif
diff --git a/lib/libsmb/Makefile.depend b/lib/libsmb/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/lib/libsmb/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libsmdb/Makefile.depend b/lib/libsmdb/Makefile.depend
new file mode 100644
index 0000000..b8a2618
--- /dev/null
+++ b/lib/libsmdb/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+smdb.o: sm_os.h
+smdb.po: sm_os.h
+smdb1.o: sm_os.h
+smdb1.po: sm_os.h
+smdb2.o: sm_os.h
+smdb2.po: sm_os.h
+smndbm.o: sm_os.h
+smndbm.po: sm_os.h
+.endif
diff --git a/lib/libsmutil/Makefile.depend b/lib/libsmutil/Makefile.depend
new file mode 100644
index 0000000..dac33d9
--- /dev/null
+++ b/lib/libsmutil/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+cf.o: sm_os.h
+cf.po: sm_os.h
+debug.o: sm_os.h
+debug.po: sm_os.h
+err.o: sm_os.h
+err.po: sm_os.h
+lockfile.o: sm_os.h
+lockfile.po: sm_os.h
+safefile.o: sm_os.h
+safefile.po: sm_os.h
+snprintf.o: sm_os.h
+snprintf.po: sm_os.h
+.endif
diff --git a/lib/libstand/Makefile.depend b/lib/libstand/Makefile.depend
new file mode 100644
index 0000000..cac12de
--- /dev/null
+++ b/lib/libstand/Makefile.depend
@@ -0,0 +1,58 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libbz2 \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+_bzlib.o: _bzlib.c
+_bzlib.o: libstand_bzlib_private.h
+_bzlib.po: _bzlib.c
+_bzlib.po: libstand_bzlib_private.h
+_crctable.o: _crctable.c
+_crctable.o: libstand_bzlib_private.h
+_crctable.po: _crctable.c
+_crctable.po: libstand_bzlib_private.h
+_decompress.o: _decompress.c
+_decompress.o: libstand_bzlib_private.h
+_decompress.po: _decompress.c
+_decompress.po: libstand_bzlib_private.h
+_huffman.o: _huffman.c
+_huffman.o: libstand_bzlib_private.h
+_huffman.po: _huffman.c
+_huffman.po: libstand_bzlib_private.h
+_infback.o: _infback.c
+_infback.o: libstand_zutil.h
+_infback.po: _infback.c
+_infback.po: libstand_zutil.h
+_inffast.o: _inffast.c
+_inffast.o: libstand_zutil.h
+_inffast.po: _inffast.c
+_inffast.po: libstand_zutil.h
+_inflate.o: _inflate.c
+_inflate.o: libstand_zutil.h
+_inflate.po: _inflate.c
+_inflate.po: libstand_zutil.h
+_inftrees.o: _inftrees.c
+_inftrees.o: libstand_zutil.h
+_inftrees.po: _inftrees.c
+_inftrees.po: libstand_zutil.h
+_randtable.o: _randtable.c
+_randtable.o: libstand_bzlib_private.h
+_randtable.po: _randtable.c
+_randtable.po: libstand_bzlib_private.h
+_zutil.o: _zutil.c
+_zutil.o: libstand_zutil.h
+_zutil.po: _zutil.c
+_zutil.po: libstand_zutil.h
+.endif
diff --git a/lib/libstdbuf/Makefile.depend b/lib/libstdbuf/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libstdbuf/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libstdthreads/Makefile.depend b/lib/libstdthreads/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libstdthreads/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libtacplus/Makefile.depend b/lib/libtacplus/Makefile.depend
new file mode 100644
index 0000000..22f59e0
--- /dev/null
+++ b/lib/libtacplus/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libmd \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libtelnet/Makefile.depend b/lib/libtelnet/Makefile.depend
new file mode 100644
index 0000000..9dc7971
--- /dev/null
+++ b/lib/libtelnet/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libkrb5 \
+ lib/libmp \
+ lib/libpam/libpam \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libthr/Makefile.depend b/lib/libthr/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/libthr/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libthread_db/Makefile.depend b/lib/libthread_db/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libthread_db/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libufs/Makefile.depend b/lib/libufs/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libufs/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libugidfw/Makefile.depend b/lib/libugidfw/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libugidfw/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libulog/Makefile.depend b/lib/libulog/Makefile.depend
new file mode 100644
index 0000000..46a6d00
--- /dev/null
+++ b/lib/libulog/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libmd \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libusb/Makefile.depend b/lib/libusb/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libusb/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libusbhid/Makefile.depend b/lib/libusbhid/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libusbhid/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libutil/Makefile.depend b/lib/libutil/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/libutil/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libvgl/Makefile.depend b/lib/libvgl/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/lib/libvgl/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libwrap/Makefile.depend b/lib/libwrap/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/lib/libwrap/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/liby/Makefile.depend b/lib/liby/Makefile.depend
new file mode 100644
index 0000000..ff699f7
--- /dev/null
+++ b/lib/liby/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/libypclnt/Makefile.depend b/lib/libypclnt/Makefile.depend
new file mode 100644
index 0000000..0f7986f
--- /dev/null
+++ b/lib/libypclnt/Makefile.depend
@@ -0,0 +1,51 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+yp_clnt.So: yp.h
+yp_clnt.So: yp_clnt.c
+yp_clnt.o: yp.h
+yp_clnt.o: yp_clnt.c
+yp_clnt.po: yp.h
+yp_clnt.po: yp_clnt.c
+ypclnt_passwd.So: yppasswd_private.h
+ypclnt_passwd.o: yppasswd_private.h
+ypclnt_passwd.po: yppasswd_private.h
+yppasswd_clnt.So: yppasswd.h
+yppasswd_clnt.So: yppasswd_clnt.c
+yppasswd_clnt.o: yppasswd.h
+yppasswd_clnt.o: yppasswd_clnt.c
+yppasswd_clnt.po: yppasswd.h
+yppasswd_clnt.po: yppasswd_clnt.c
+yppasswd_private_clnt.So: yppasswd_private.h
+yppasswd_private_clnt.So: yppasswd_private_clnt.c
+yppasswd_private_clnt.o: yppasswd_private.h
+yppasswd_private_clnt.o: yppasswd_private_clnt.c
+yppasswd_private_clnt.po: yppasswd_private.h
+yppasswd_private_clnt.po: yppasswd_private_clnt.c
+yppasswd_private_xdr.So: yppasswd_private.h
+yppasswd_private_xdr.So: yppasswd_private_xdr.c
+yppasswd_private_xdr.o: yppasswd_private.h
+yppasswd_private_xdr.o: yppasswd_private_xdr.c
+yppasswd_private_xdr.po: yppasswd_private.h
+yppasswd_private_xdr.po: yppasswd_private_xdr.c
+yppasswd_xdr.So: yppasswd.h
+yppasswd_xdr.So: yppasswd_xdr.c
+yppasswd_xdr.o: yppasswd.h
+yppasswd_xdr.o: yppasswd_xdr.c
+yppasswd_xdr.po: yppasswd.h
+yppasswd_xdr.po: yppasswd_xdr.c
+.endif
diff --git a/lib/libz/Makefile.depend b/lib/libz/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/lib/libz/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/msun/Makefile b/lib/msun/Makefile
index a1ec6c9..a50dded 100644
--- a/lib/msun/Makefile
+++ b/lib/msun/Makefile
@@ -31,6 +31,8 @@ CFLAGS+= -I${.CURDIR}/ld80
CFLAGS+= -I${.CURDIR}/ld128
.endif
+CFLAGS+= -I${.CURDIR}/${ARCH_SUBDIR}
+
.PATH: ${.CURDIR}/bsdsrc
.PATH: ${.CURDIR}/src
.PATH: ${.CURDIR}/man
diff --git a/lib/msun/Makefile.depend b/lib/msun/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/lib/msun/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/lib/ncurses/form/Makefile.depend b/lib/ncurses/form/Makefile.depend
new file mode 100644
index 0000000..2ca7d7a
--- /dev/null
+++ b/lib/ncurses/form/Makefile.depend
@@ -0,0 +1,134 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+fld_arg.So: ncurses_def.h
+fld_arg.o: ncurses_def.h
+fld_arg.po: ncurses_def.h
+fld_attr.So: ncurses_def.h
+fld_attr.o: ncurses_def.h
+fld_attr.po: ncurses_def.h
+fld_current.So: ncurses_def.h
+fld_current.o: ncurses_def.h
+fld_current.po: ncurses_def.h
+fld_def.So: ncurses_def.h
+fld_def.o: ncurses_def.h
+fld_def.po: ncurses_def.h
+fld_dup.So: ncurses_def.h
+fld_dup.o: ncurses_def.h
+fld_dup.po: ncurses_def.h
+fld_ftchoice.So: ncurses_def.h
+fld_ftchoice.o: ncurses_def.h
+fld_ftchoice.po: ncurses_def.h
+fld_ftlink.So: ncurses_def.h
+fld_ftlink.o: ncurses_def.h
+fld_ftlink.po: ncurses_def.h
+fld_info.So: ncurses_def.h
+fld_info.o: ncurses_def.h
+fld_info.po: ncurses_def.h
+fld_just.So: ncurses_def.h
+fld_just.o: ncurses_def.h
+fld_just.po: ncurses_def.h
+fld_link.So: ncurses_def.h
+fld_link.o: ncurses_def.h
+fld_link.po: ncurses_def.h
+fld_max.So: ncurses_def.h
+fld_max.o: ncurses_def.h
+fld_max.po: ncurses_def.h
+fld_move.So: ncurses_def.h
+fld_move.o: ncurses_def.h
+fld_move.po: ncurses_def.h
+fld_newftyp.So: ncurses_def.h
+fld_newftyp.o: ncurses_def.h
+fld_newftyp.po: ncurses_def.h
+fld_opts.So: ncurses_def.h
+fld_opts.o: ncurses_def.h
+fld_opts.po: ncurses_def.h
+fld_pad.So: ncurses_def.h
+fld_pad.o: ncurses_def.h
+fld_pad.po: ncurses_def.h
+fld_page.So: ncurses_def.h
+fld_page.o: ncurses_def.h
+fld_page.po: ncurses_def.h
+fld_stat.So: ncurses_def.h
+fld_stat.o: ncurses_def.h
+fld_stat.po: ncurses_def.h
+fld_type.So: ncurses_def.h
+fld_type.o: ncurses_def.h
+fld_type.po: ncurses_def.h
+fld_user.So: ncurses_def.h
+fld_user.o: ncurses_def.h
+fld_user.po: ncurses_def.h
+frm_cursor.So: ncurses_def.h
+frm_cursor.o: ncurses_def.h
+frm_cursor.po: ncurses_def.h
+frm_data.So: ncurses_def.h
+frm_data.o: ncurses_def.h
+frm_data.po: ncurses_def.h
+frm_def.So: ncurses_def.h
+frm_def.o: ncurses_def.h
+frm_def.po: ncurses_def.h
+frm_driver.So: ncurses_def.h
+frm_driver.o: ncurses_def.h
+frm_driver.po: ncurses_def.h
+frm_hook.So: ncurses_def.h
+frm_hook.o: ncurses_def.h
+frm_hook.po: ncurses_def.h
+frm_opts.So: ncurses_def.h
+frm_opts.o: ncurses_def.h
+frm_opts.po: ncurses_def.h
+frm_page.So: ncurses_def.h
+frm_page.o: ncurses_def.h
+frm_page.po: ncurses_def.h
+frm_post.So: ncurses_def.h
+frm_post.o: ncurses_def.h
+frm_post.po: ncurses_def.h
+frm_req_name.So: ncurses_def.h
+frm_req_name.o: ncurses_def.h
+frm_req_name.po: ncurses_def.h
+frm_scale.So: ncurses_def.h
+frm_scale.o: ncurses_def.h
+frm_scale.po: ncurses_def.h
+frm_sub.So: ncurses_def.h
+frm_sub.o: ncurses_def.h
+frm_sub.po: ncurses_def.h
+frm_user.So: ncurses_def.h
+frm_user.o: ncurses_def.h
+frm_user.po: ncurses_def.h
+frm_win.So: ncurses_def.h
+frm_win.o: ncurses_def.h
+frm_win.po: ncurses_def.h
+fty_alnum.So: ncurses_def.h
+fty_alnum.o: ncurses_def.h
+fty_alnum.po: ncurses_def.h
+fty_alpha.So: ncurses_def.h
+fty_alpha.o: ncurses_def.h
+fty_alpha.po: ncurses_def.h
+fty_enum.So: ncurses_def.h
+fty_enum.o: ncurses_def.h
+fty_enum.po: ncurses_def.h
+fty_int.So: ncurses_def.h
+fty_int.o: ncurses_def.h
+fty_int.po: ncurses_def.h
+fty_ipv4.So: ncurses_def.h
+fty_ipv4.o: ncurses_def.h
+fty_ipv4.po: ncurses_def.h
+fty_num.So: ncurses_def.h
+fty_num.o: ncurses_def.h
+fty_num.po: ncurses_def.h
+fty_regex.So: ncurses_def.h
+fty_regex.o: ncurses_def.h
+fty_regex.po: ncurses_def.h
+.endif
diff --git a/lib/ncurses/formw/Makefile.depend b/lib/ncurses/formw/Makefile.depend
new file mode 100644
index 0000000..f21c8a2
--- /dev/null
+++ b/lib/ncurses/formw/Makefile.depend
@@ -0,0 +1,134 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+fld_arg.So: ncurses_def.h
+fld_arg.o: ncurses_def.h
+fld_arg.po: ncurses_def.h
+fld_attr.So: ncurses_def.h
+fld_attr.o: ncurses_def.h
+fld_attr.po: ncurses_def.h
+fld_current.So: ncurses_def.h
+fld_current.o: ncurses_def.h
+fld_current.po: ncurses_def.h
+fld_def.So: ncurses_def.h
+fld_def.o: ncurses_def.h
+fld_def.po: ncurses_def.h
+fld_dup.So: ncurses_def.h
+fld_dup.o: ncurses_def.h
+fld_dup.po: ncurses_def.h
+fld_ftchoice.So: ncurses_def.h
+fld_ftchoice.o: ncurses_def.h
+fld_ftchoice.po: ncurses_def.h
+fld_ftlink.So: ncurses_def.h
+fld_ftlink.o: ncurses_def.h
+fld_ftlink.po: ncurses_def.h
+fld_info.So: ncurses_def.h
+fld_info.o: ncurses_def.h
+fld_info.po: ncurses_def.h
+fld_just.So: ncurses_def.h
+fld_just.o: ncurses_def.h
+fld_just.po: ncurses_def.h
+fld_link.So: ncurses_def.h
+fld_link.o: ncurses_def.h
+fld_link.po: ncurses_def.h
+fld_max.So: ncurses_def.h
+fld_max.o: ncurses_def.h
+fld_max.po: ncurses_def.h
+fld_move.So: ncurses_def.h
+fld_move.o: ncurses_def.h
+fld_move.po: ncurses_def.h
+fld_newftyp.So: ncurses_def.h
+fld_newftyp.o: ncurses_def.h
+fld_newftyp.po: ncurses_def.h
+fld_opts.So: ncurses_def.h
+fld_opts.o: ncurses_def.h
+fld_opts.po: ncurses_def.h
+fld_pad.So: ncurses_def.h
+fld_pad.o: ncurses_def.h
+fld_pad.po: ncurses_def.h
+fld_page.So: ncurses_def.h
+fld_page.o: ncurses_def.h
+fld_page.po: ncurses_def.h
+fld_stat.So: ncurses_def.h
+fld_stat.o: ncurses_def.h
+fld_stat.po: ncurses_def.h
+fld_type.So: ncurses_def.h
+fld_type.o: ncurses_def.h
+fld_type.po: ncurses_def.h
+fld_user.So: ncurses_def.h
+fld_user.o: ncurses_def.h
+fld_user.po: ncurses_def.h
+frm_cursor.So: ncurses_def.h
+frm_cursor.o: ncurses_def.h
+frm_cursor.po: ncurses_def.h
+frm_data.So: ncurses_def.h
+frm_data.o: ncurses_def.h
+frm_data.po: ncurses_def.h
+frm_def.So: ncurses_def.h
+frm_def.o: ncurses_def.h
+frm_def.po: ncurses_def.h
+frm_driver.So: ncurses_def.h
+frm_driver.o: ncurses_def.h
+frm_driver.po: ncurses_def.h
+frm_hook.So: ncurses_def.h
+frm_hook.o: ncurses_def.h
+frm_hook.po: ncurses_def.h
+frm_opts.So: ncurses_def.h
+frm_opts.o: ncurses_def.h
+frm_opts.po: ncurses_def.h
+frm_page.So: ncurses_def.h
+frm_page.o: ncurses_def.h
+frm_page.po: ncurses_def.h
+frm_post.So: ncurses_def.h
+frm_post.o: ncurses_def.h
+frm_post.po: ncurses_def.h
+frm_req_name.So: ncurses_def.h
+frm_req_name.o: ncurses_def.h
+frm_req_name.po: ncurses_def.h
+frm_scale.So: ncurses_def.h
+frm_scale.o: ncurses_def.h
+frm_scale.po: ncurses_def.h
+frm_sub.So: ncurses_def.h
+frm_sub.o: ncurses_def.h
+frm_sub.po: ncurses_def.h
+frm_user.So: ncurses_def.h
+frm_user.o: ncurses_def.h
+frm_user.po: ncurses_def.h
+frm_win.So: ncurses_def.h
+frm_win.o: ncurses_def.h
+frm_win.po: ncurses_def.h
+fty_alnum.So: ncurses_def.h
+fty_alnum.o: ncurses_def.h
+fty_alnum.po: ncurses_def.h
+fty_alpha.So: ncurses_def.h
+fty_alpha.o: ncurses_def.h
+fty_alpha.po: ncurses_def.h
+fty_enum.So: ncurses_def.h
+fty_enum.o: ncurses_def.h
+fty_enum.po: ncurses_def.h
+fty_int.So: ncurses_def.h
+fty_int.o: ncurses_def.h
+fty_int.po: ncurses_def.h
+fty_ipv4.So: ncurses_def.h
+fty_ipv4.o: ncurses_def.h
+fty_ipv4.po: ncurses_def.h
+fty_num.So: ncurses_def.h
+fty_num.o: ncurses_def.h
+fty_num.po: ncurses_def.h
+fty_regex.So: ncurses_def.h
+fty_regex.o: ncurses_def.h
+fty_regex.po: ncurses_def.h
+.endif
diff --git a/lib/ncurses/menu/Makefile.depend b/lib/ncurses/menu/Makefile.depend
new file mode 100644
index 0000000..b4dee6d
--- /dev/null
+++ b/lib/ncurses/menu/Makefile.depend
@@ -0,0 +1,95 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+m_attribs.So: ncurses_def.h
+m_attribs.o: ncurses_def.h
+m_attribs.po: ncurses_def.h
+m_cursor.So: ncurses_def.h
+m_cursor.o: ncurses_def.h
+m_cursor.po: ncurses_def.h
+m_driver.So: ncurses_def.h
+m_driver.o: ncurses_def.h
+m_driver.po: ncurses_def.h
+m_format.So: ncurses_def.h
+m_format.o: ncurses_def.h
+m_format.po: ncurses_def.h
+m_global.So: ncurses_def.h
+m_global.o: ncurses_def.h
+m_global.po: ncurses_def.h
+m_hook.So: ncurses_def.h
+m_hook.o: ncurses_def.h
+m_hook.po: ncurses_def.h
+m_item_cur.So: ncurses_def.h
+m_item_cur.o: ncurses_def.h
+m_item_cur.po: ncurses_def.h
+m_item_nam.So: ncurses_def.h
+m_item_nam.o: ncurses_def.h
+m_item_nam.po: ncurses_def.h
+m_item_new.So: ncurses_def.h
+m_item_new.o: ncurses_def.h
+m_item_new.po: ncurses_def.h
+m_item_opt.So: ncurses_def.h
+m_item_opt.o: ncurses_def.h
+m_item_opt.po: ncurses_def.h
+m_item_top.So: ncurses_def.h
+m_item_top.o: ncurses_def.h
+m_item_top.po: ncurses_def.h
+m_item_use.So: ncurses_def.h
+m_item_use.o: ncurses_def.h
+m_item_use.po: ncurses_def.h
+m_item_val.So: ncurses_def.h
+m_item_val.o: ncurses_def.h
+m_item_val.po: ncurses_def.h
+m_item_vis.So: ncurses_def.h
+m_item_vis.o: ncurses_def.h
+m_item_vis.po: ncurses_def.h
+m_items.So: ncurses_def.h
+m_items.o: ncurses_def.h
+m_items.po: ncurses_def.h
+m_new.So: ncurses_def.h
+m_new.o: ncurses_def.h
+m_new.po: ncurses_def.h
+m_opts.So: ncurses_def.h
+m_opts.o: ncurses_def.h
+m_opts.po: ncurses_def.h
+m_pad.So: ncurses_def.h
+m_pad.o: ncurses_def.h
+m_pad.po: ncurses_def.h
+m_pattern.So: ncurses_def.h
+m_pattern.o: ncurses_def.h
+m_pattern.po: ncurses_def.h
+m_post.So: ncurses_def.h
+m_post.o: ncurses_def.h
+m_post.po: ncurses_def.h
+m_req_name.So: ncurses_def.h
+m_req_name.o: ncurses_def.h
+m_req_name.po: ncurses_def.h
+m_scale.So: ncurses_def.h
+m_scale.o: ncurses_def.h
+m_scale.po: ncurses_def.h
+m_spacing.So: ncurses_def.h
+m_spacing.o: ncurses_def.h
+m_spacing.po: ncurses_def.h
+m_sub.So: ncurses_def.h
+m_sub.o: ncurses_def.h
+m_sub.po: ncurses_def.h
+m_userptr.So: ncurses_def.h
+m_userptr.o: ncurses_def.h
+m_userptr.po: ncurses_def.h
+m_win.So: ncurses_def.h
+m_win.o: ncurses_def.h
+m_win.po: ncurses_def.h
+.endif
diff --git a/lib/ncurses/menuw/Makefile.depend b/lib/ncurses/menuw/Makefile.depend
new file mode 100644
index 0000000..023241d
--- /dev/null
+++ b/lib/ncurses/menuw/Makefile.depend
@@ -0,0 +1,95 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+m_attribs.So: ncurses_def.h
+m_attribs.o: ncurses_def.h
+m_attribs.po: ncurses_def.h
+m_cursor.So: ncurses_def.h
+m_cursor.o: ncurses_def.h
+m_cursor.po: ncurses_def.h
+m_driver.So: ncurses_def.h
+m_driver.o: ncurses_def.h
+m_driver.po: ncurses_def.h
+m_format.So: ncurses_def.h
+m_format.o: ncurses_def.h
+m_format.po: ncurses_def.h
+m_global.So: ncurses_def.h
+m_global.o: ncurses_def.h
+m_global.po: ncurses_def.h
+m_hook.So: ncurses_def.h
+m_hook.o: ncurses_def.h
+m_hook.po: ncurses_def.h
+m_item_cur.So: ncurses_def.h
+m_item_cur.o: ncurses_def.h
+m_item_cur.po: ncurses_def.h
+m_item_nam.So: ncurses_def.h
+m_item_nam.o: ncurses_def.h
+m_item_nam.po: ncurses_def.h
+m_item_new.So: ncurses_def.h
+m_item_new.o: ncurses_def.h
+m_item_new.po: ncurses_def.h
+m_item_opt.So: ncurses_def.h
+m_item_opt.o: ncurses_def.h
+m_item_opt.po: ncurses_def.h
+m_item_top.So: ncurses_def.h
+m_item_top.o: ncurses_def.h
+m_item_top.po: ncurses_def.h
+m_item_use.So: ncurses_def.h
+m_item_use.o: ncurses_def.h
+m_item_use.po: ncurses_def.h
+m_item_val.So: ncurses_def.h
+m_item_val.o: ncurses_def.h
+m_item_val.po: ncurses_def.h
+m_item_vis.So: ncurses_def.h
+m_item_vis.o: ncurses_def.h
+m_item_vis.po: ncurses_def.h
+m_items.So: ncurses_def.h
+m_items.o: ncurses_def.h
+m_items.po: ncurses_def.h
+m_new.So: ncurses_def.h
+m_new.o: ncurses_def.h
+m_new.po: ncurses_def.h
+m_opts.So: ncurses_def.h
+m_opts.o: ncurses_def.h
+m_opts.po: ncurses_def.h
+m_pad.So: ncurses_def.h
+m_pad.o: ncurses_def.h
+m_pad.po: ncurses_def.h
+m_pattern.So: ncurses_def.h
+m_pattern.o: ncurses_def.h
+m_pattern.po: ncurses_def.h
+m_post.So: ncurses_def.h
+m_post.o: ncurses_def.h
+m_post.po: ncurses_def.h
+m_req_name.So: ncurses_def.h
+m_req_name.o: ncurses_def.h
+m_req_name.po: ncurses_def.h
+m_scale.So: ncurses_def.h
+m_scale.o: ncurses_def.h
+m_scale.po: ncurses_def.h
+m_spacing.So: ncurses_def.h
+m_spacing.o: ncurses_def.h
+m_spacing.po: ncurses_def.h
+m_sub.So: ncurses_def.h
+m_sub.o: ncurses_def.h
+m_sub.po: ncurses_def.h
+m_userptr.So: ncurses_def.h
+m_userptr.o: ncurses_def.h
+m_userptr.po: ncurses_def.h
+m_win.So: ncurses_def.h
+m_win.o: ncurses_def.h
+m_win.po: ncurses_def.h
+.endif
diff --git a/lib/ncurses/ncurses/Makefile.depend b/lib/ncurses/ncurses/Makefile.depend
new file mode 100644
index 0000000..6cc2521
--- /dev/null
+++ b/lib/ncurses/ncurses/Makefile.depend
@@ -0,0 +1,1807 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+access.So: curses.h
+access.So: ncurses_def.h
+access.So: term.h
+access.So: unctrl.h
+access.o: curses.h
+access.o: ncurses_def.h
+access.o: term.h
+access.o: unctrl.h
+access.po: curses.h
+access.po: ncurses_def.h
+access.po: term.h
+access.po: unctrl.h
+add_tries.So: curses.h
+add_tries.So: ncurses_def.h
+add_tries.So: term.h
+add_tries.So: unctrl.h
+add_tries.o: curses.h
+add_tries.o: ncurses_def.h
+add_tries.o: term.h
+add_tries.o: unctrl.h
+add_tries.po: curses.h
+add_tries.po: ncurses_def.h
+add_tries.po: term.h
+add_tries.po: unctrl.h
+alloc_entry.So: curses.h
+alloc_entry.So: ncurses_def.h
+alloc_entry.So: term.h
+alloc_entry.So: unctrl.h
+alloc_entry.o: curses.h
+alloc_entry.o: ncurses_def.h
+alloc_entry.o: term.h
+alloc_entry.o: unctrl.h
+alloc_entry.po: curses.h
+alloc_entry.po: ncurses_def.h
+alloc_entry.po: term.h
+alloc_entry.po: unctrl.h
+alloc_ttype.So: curses.h
+alloc_ttype.So: ncurses_def.h
+alloc_ttype.So: term.h
+alloc_ttype.So: unctrl.h
+alloc_ttype.o: curses.h
+alloc_ttype.o: ncurses_def.h
+alloc_ttype.o: term.h
+alloc_ttype.o: unctrl.h
+alloc_ttype.po: curses.h
+alloc_ttype.po: ncurses_def.h
+alloc_ttype.po: term.h
+alloc_ttype.po: unctrl.h
+captoinfo.So: curses.h
+captoinfo.So: ncurses_def.h
+captoinfo.So: term.h
+captoinfo.So: unctrl.h
+captoinfo.o: curses.h
+captoinfo.o: ncurses_def.h
+captoinfo.o: term.h
+captoinfo.o: unctrl.h
+captoinfo.po: curses.h
+captoinfo.po: ncurses_def.h
+captoinfo.po: term.h
+captoinfo.po: unctrl.h
+codes.So: codes.c
+codes.So: curses.h
+codes.So: ncurses_def.h
+codes.So: term.h
+codes.So: unctrl.h
+codes.o: codes.c
+codes.o: curses.h
+codes.o: ncurses_def.h
+codes.o: term.h
+codes.o: unctrl.h
+codes.po: codes.c
+codes.po: curses.h
+codes.po: ncurses_def.h
+codes.po: term.h
+codes.po: unctrl.h
+comp_captab.So: comp_captab.c
+comp_captab.So: curses.h
+comp_captab.So: hashsize.h
+comp_captab.So: ncurses_def.h
+comp_captab.So: term.h
+comp_captab.So: unctrl.h
+comp_captab.o: comp_captab.c
+comp_captab.o: curses.h
+comp_captab.o: hashsize.h
+comp_captab.o: ncurses_def.h
+comp_captab.o: term.h
+comp_captab.o: unctrl.h
+comp_captab.po: comp_captab.c
+comp_captab.po: curses.h
+comp_captab.po: hashsize.h
+comp_captab.po: ncurses_def.h
+comp_captab.po: term.h
+comp_captab.po: unctrl.h
+comp_error.So: curses.h
+comp_error.So: ncurses_def.h
+comp_error.So: term.h
+comp_error.So: unctrl.h
+comp_error.o: curses.h
+comp_error.o: ncurses_def.h
+comp_error.o: term.h
+comp_error.o: unctrl.h
+comp_error.po: curses.h
+comp_error.po: ncurses_def.h
+comp_error.po: term.h
+comp_error.po: unctrl.h
+comp_expand.So: curses.h
+comp_expand.So: ncurses_def.h
+comp_expand.So: term.h
+comp_expand.So: unctrl.h
+comp_expand.o: curses.h
+comp_expand.o: ncurses_def.h
+comp_expand.o: term.h
+comp_expand.o: unctrl.h
+comp_expand.po: curses.h
+comp_expand.po: ncurses_def.h
+comp_expand.po: term.h
+comp_expand.po: unctrl.h
+comp_hash.So: curses.h
+comp_hash.So: hashsize.h
+comp_hash.So: ncurses_def.h
+comp_hash.So: term.h
+comp_hash.So: unctrl.h
+comp_hash.o: curses.h
+comp_hash.o: hashsize.h
+comp_hash.o: ncurses_def.h
+comp_hash.o: term.h
+comp_hash.o: unctrl.h
+comp_hash.po: curses.h
+comp_hash.po: hashsize.h
+comp_hash.po: ncurses_def.h
+comp_hash.po: term.h
+comp_hash.po: unctrl.h
+comp_parse.So: curses.h
+comp_parse.So: ncurses_def.h
+comp_parse.So: term.h
+comp_parse.So: unctrl.h
+comp_parse.o: curses.h
+comp_parse.o: ncurses_def.h
+comp_parse.o: term.h
+comp_parse.o: unctrl.h
+comp_parse.po: curses.h
+comp_parse.po: ncurses_def.h
+comp_parse.po: term.h
+comp_parse.po: unctrl.h
+comp_scan.So: curses.h
+comp_scan.So: ncurses_def.h
+comp_scan.So: term.h
+comp_scan.So: unctrl.h
+comp_scan.o: curses.h
+comp_scan.o: ncurses_def.h
+comp_scan.o: term.h
+comp_scan.o: unctrl.h
+comp_scan.po: curses.h
+comp_scan.po: ncurses_def.h
+comp_scan.po: term.h
+comp_scan.po: unctrl.h
+db_iterator.So: curses.h
+db_iterator.So: ncurses_def.h
+db_iterator.So: term.h
+db_iterator.So: unctrl.h
+db_iterator.o: curses.h
+db_iterator.o: ncurses_def.h
+db_iterator.o: term.h
+db_iterator.o: unctrl.h
+db_iterator.po: curses.h
+db_iterator.po: ncurses_def.h
+db_iterator.po: term.h
+db_iterator.po: unctrl.h
+define_key.So: curses.h
+define_key.So: ncurses_def.h
+define_key.So: term.h
+define_key.So: unctrl.h
+define_key.o: curses.h
+define_key.o: ncurses_def.h
+define_key.o: term.h
+define_key.o: unctrl.h
+define_key.po: curses.h
+define_key.po: ncurses_def.h
+define_key.po: term.h
+define_key.po: unctrl.h
+doalloc.So: curses.h
+doalloc.So: ncurses_def.h
+doalloc.So: term.h
+doalloc.So: unctrl.h
+doalloc.o: curses.h
+doalloc.o: ncurses_def.h
+doalloc.o: term.h
+doalloc.o: unctrl.h
+doalloc.po: curses.h
+doalloc.po: ncurses_def.h
+doalloc.po: term.h
+doalloc.po: unctrl.h
+entries.So: curses.h
+entries.So: ncurses_def.h
+entries.So: term.h
+entries.So: unctrl.h
+entries.o: curses.h
+entries.o: ncurses_def.h
+entries.o: term.h
+entries.o: unctrl.h
+entries.po: curses.h
+entries.po: ncurses_def.h
+entries.po: term.h
+entries.po: unctrl.h
+expanded.So: curses.h
+expanded.So: expanded.c
+expanded.So: ncurses_def.h
+expanded.So: term.h
+expanded.So: unctrl.h
+expanded.o: curses.h
+expanded.o: expanded.c
+expanded.o: ncurses_def.h
+expanded.o: term.h
+expanded.o: unctrl.h
+expanded.po: curses.h
+expanded.po: expanded.c
+expanded.po: ncurses_def.h
+expanded.po: term.h
+expanded.po: unctrl.h
+fallback.So: curses.h
+fallback.So: fallback.c
+fallback.So: ncurses_def.h
+fallback.So: term.h
+fallback.So: unctrl.h
+fallback.o: curses.h
+fallback.o: fallback.c
+fallback.o: ncurses_def.h
+fallback.o: term.h
+fallback.o: unctrl.h
+fallback.po: curses.h
+fallback.po: fallback.c
+fallback.po: ncurses_def.h
+fallback.po: term.h
+fallback.po: unctrl.h
+free_ttype.So: curses.h
+free_ttype.So: ncurses_def.h
+free_ttype.So: term.h
+free_ttype.So: unctrl.h
+free_ttype.o: curses.h
+free_ttype.o: ncurses_def.h
+free_ttype.o: term.h
+free_ttype.o: unctrl.h
+free_ttype.po: curses.h
+free_ttype.po: ncurses_def.h
+free_ttype.po: term.h
+free_ttype.po: unctrl.h
+getenv_num.So: curses.h
+getenv_num.So: ncurses_def.h
+getenv_num.So: term.h
+getenv_num.So: unctrl.h
+getenv_num.o: curses.h
+getenv_num.o: ncurses_def.h
+getenv_num.o: term.h
+getenv_num.o: unctrl.h
+getenv_num.po: curses.h
+getenv_num.po: ncurses_def.h
+getenv_num.po: term.h
+getenv_num.po: unctrl.h
+hardscroll.So: curses.h
+hardscroll.So: ncurses_def.h
+hardscroll.So: term.h
+hardscroll.So: unctrl.h
+hardscroll.o: curses.h
+hardscroll.o: ncurses_def.h
+hardscroll.o: term.h
+hardscroll.o: unctrl.h
+hardscroll.po: curses.h
+hardscroll.po: ncurses_def.h
+hardscroll.po: term.h
+hardscroll.po: unctrl.h
+hashed_db.So: curses.h
+hashed_db.So: ncurses_def.h
+hashed_db.So: term.h
+hashed_db.So: unctrl.h
+hashed_db.o: curses.h
+hashed_db.o: ncurses_def.h
+hashed_db.o: term.h
+hashed_db.o: unctrl.h
+hashed_db.po: curses.h
+hashed_db.po: ncurses_def.h
+hashed_db.po: term.h
+hashed_db.po: unctrl.h
+hashmap.So: curses.h
+hashmap.So: ncurses_def.h
+hashmap.So: term.h
+hashmap.So: unctrl.h
+hashmap.o: curses.h
+hashmap.o: ncurses_def.h
+hashmap.o: term.h
+hashmap.o: unctrl.h
+hashmap.po: curses.h
+hashmap.po: ncurses_def.h
+hashmap.po: term.h
+hashmap.po: unctrl.h
+home_terminfo.So: curses.h
+home_terminfo.So: ncurses_def.h
+home_terminfo.So: term.h
+home_terminfo.So: unctrl.h
+home_terminfo.o: curses.h
+home_terminfo.o: ncurses_def.h
+home_terminfo.o: term.h
+home_terminfo.o: unctrl.h
+home_terminfo.po: curses.h
+home_terminfo.po: ncurses_def.h
+home_terminfo.po: term.h
+home_terminfo.po: unctrl.h
+init_keytry.So: curses.h
+init_keytry.So: init_keytry.h
+init_keytry.So: ncurses_def.h
+init_keytry.So: term.h
+init_keytry.So: unctrl.h
+init_keytry.o: curses.h
+init_keytry.o: init_keytry.h
+init_keytry.o: ncurses_def.h
+init_keytry.o: term.h
+init_keytry.o: unctrl.h
+init_keytry.po: curses.h
+init_keytry.po: init_keytry.h
+init_keytry.po: ncurses_def.h
+init_keytry.po: term.h
+init_keytry.po: unctrl.h
+key_defined.So: curses.h
+key_defined.So: ncurses_def.h
+key_defined.So: term.h
+key_defined.So: unctrl.h
+key_defined.o: curses.h
+key_defined.o: ncurses_def.h
+key_defined.o: term.h
+key_defined.o: unctrl.h
+key_defined.po: curses.h
+key_defined.po: ncurses_def.h
+key_defined.po: term.h
+key_defined.po: unctrl.h
+keybound.So: curses.h
+keybound.So: ncurses_def.h
+keybound.So: term.h
+keybound.So: unctrl.h
+keybound.o: curses.h
+keybound.o: ncurses_def.h
+keybound.o: term.h
+keybound.o: unctrl.h
+keybound.po: curses.h
+keybound.po: ncurses_def.h
+keybound.po: term.h
+keybound.po: unctrl.h
+keyok.So: curses.h
+keyok.So: ncurses_def.h
+keyok.So: term.h
+keyok.So: unctrl.h
+keyok.o: curses.h
+keyok.o: ncurses_def.h
+keyok.o: term.h
+keyok.o: unctrl.h
+keyok.po: curses.h
+keyok.po: ncurses_def.h
+keyok.po: term.h
+keyok.po: unctrl.h
+legacy_coding.So: curses.h
+legacy_coding.So: ncurses_def.h
+legacy_coding.So: term.h
+legacy_coding.So: unctrl.h
+legacy_coding.o: curses.h
+legacy_coding.o: ncurses_def.h
+legacy_coding.o: term.h
+legacy_coding.o: unctrl.h
+legacy_coding.po: curses.h
+legacy_coding.po: ncurses_def.h
+legacy_coding.po: term.h
+legacy_coding.po: unctrl.h
+lib_acs.So: curses.h
+lib_acs.So: ncurses_def.h
+lib_acs.So: term.h
+lib_acs.So: unctrl.h
+lib_acs.o: curses.h
+lib_acs.o: ncurses_def.h
+lib_acs.o: term.h
+lib_acs.o: unctrl.h
+lib_acs.po: curses.h
+lib_acs.po: ncurses_def.h
+lib_acs.po: term.h
+lib_acs.po: unctrl.h
+lib_addch.So: curses.h
+lib_addch.So: ncurses_def.h
+lib_addch.So: term.h
+lib_addch.So: unctrl.h
+lib_addch.o: curses.h
+lib_addch.o: ncurses_def.h
+lib_addch.o: term.h
+lib_addch.o: unctrl.h
+lib_addch.po: curses.h
+lib_addch.po: ncurses_def.h
+lib_addch.po: term.h
+lib_addch.po: unctrl.h
+lib_addstr.So: curses.h
+lib_addstr.So: ncurses_def.h
+lib_addstr.So: term.h
+lib_addstr.So: unctrl.h
+lib_addstr.o: curses.h
+lib_addstr.o: ncurses_def.h
+lib_addstr.o: term.h
+lib_addstr.o: unctrl.h
+lib_addstr.po: curses.h
+lib_addstr.po: ncurses_def.h
+lib_addstr.po: term.h
+lib_addstr.po: unctrl.h
+lib_baudrate.So: curses.h
+lib_baudrate.So: ncurses_def.h
+lib_baudrate.So: term.h
+lib_baudrate.So: termcap.h
+lib_baudrate.So: unctrl.h
+lib_baudrate.o: curses.h
+lib_baudrate.o: ncurses_def.h
+lib_baudrate.o: term.h
+lib_baudrate.o: termcap.h
+lib_baudrate.o: unctrl.h
+lib_baudrate.po: curses.h
+lib_baudrate.po: ncurses_def.h
+lib_baudrate.po: term.h
+lib_baudrate.po: termcap.h
+lib_baudrate.po: unctrl.h
+lib_beep.So: curses.h
+lib_beep.So: ncurses_def.h
+lib_beep.So: term.h
+lib_beep.So: unctrl.h
+lib_beep.o: curses.h
+lib_beep.o: ncurses_def.h
+lib_beep.o: term.h
+lib_beep.o: unctrl.h
+lib_beep.po: curses.h
+lib_beep.po: ncurses_def.h
+lib_beep.po: term.h
+lib_beep.po: unctrl.h
+lib_bkgd.So: curses.h
+lib_bkgd.So: ncurses_def.h
+lib_bkgd.So: term.h
+lib_bkgd.So: unctrl.h
+lib_bkgd.o: curses.h
+lib_bkgd.o: ncurses_def.h
+lib_bkgd.o: term.h
+lib_bkgd.o: unctrl.h
+lib_bkgd.po: curses.h
+lib_bkgd.po: ncurses_def.h
+lib_bkgd.po: term.h
+lib_bkgd.po: unctrl.h
+lib_box.So: curses.h
+lib_box.So: ncurses_def.h
+lib_box.So: term.h
+lib_box.So: unctrl.h
+lib_box.o: curses.h
+lib_box.o: ncurses_def.h
+lib_box.o: term.h
+lib_box.o: unctrl.h
+lib_box.po: curses.h
+lib_box.po: ncurses_def.h
+lib_box.po: term.h
+lib_box.po: unctrl.h
+lib_chgat.So: curses.h
+lib_chgat.So: ncurses_def.h
+lib_chgat.So: term.h
+lib_chgat.So: unctrl.h
+lib_chgat.o: curses.h
+lib_chgat.o: ncurses_def.h
+lib_chgat.o: term.h
+lib_chgat.o: unctrl.h
+lib_chgat.po: curses.h
+lib_chgat.po: ncurses_def.h
+lib_chgat.po: term.h
+lib_chgat.po: unctrl.h
+lib_clear.So: curses.h
+lib_clear.So: ncurses_def.h
+lib_clear.So: term.h
+lib_clear.So: unctrl.h
+lib_clear.o: curses.h
+lib_clear.o: ncurses_def.h
+lib_clear.o: term.h
+lib_clear.o: unctrl.h
+lib_clear.po: curses.h
+lib_clear.po: ncurses_def.h
+lib_clear.po: term.h
+lib_clear.po: unctrl.h
+lib_clearok.So: curses.h
+lib_clearok.So: ncurses_def.h
+lib_clearok.So: term.h
+lib_clearok.So: unctrl.h
+lib_clearok.o: curses.h
+lib_clearok.o: ncurses_def.h
+lib_clearok.o: term.h
+lib_clearok.o: unctrl.h
+lib_clearok.po: curses.h
+lib_clearok.po: ncurses_def.h
+lib_clearok.po: term.h
+lib_clearok.po: unctrl.h
+lib_clrbot.So: curses.h
+lib_clrbot.So: ncurses_def.h
+lib_clrbot.So: term.h
+lib_clrbot.So: unctrl.h
+lib_clrbot.o: curses.h
+lib_clrbot.o: ncurses_def.h
+lib_clrbot.o: term.h
+lib_clrbot.o: unctrl.h
+lib_clrbot.po: curses.h
+lib_clrbot.po: ncurses_def.h
+lib_clrbot.po: term.h
+lib_clrbot.po: unctrl.h
+lib_clreol.So: curses.h
+lib_clreol.So: ncurses_def.h
+lib_clreol.So: term.h
+lib_clreol.So: unctrl.h
+lib_clreol.o: curses.h
+lib_clreol.o: ncurses_def.h
+lib_clreol.o: term.h
+lib_clreol.o: unctrl.h
+lib_clreol.po: curses.h
+lib_clreol.po: ncurses_def.h
+lib_clreol.po: term.h
+lib_clreol.po: unctrl.h
+lib_color.So: curses.h
+lib_color.So: ncurses_def.h
+lib_color.So: term.h
+lib_color.So: unctrl.h
+lib_color.o: curses.h
+lib_color.o: ncurses_def.h
+lib_color.o: term.h
+lib_color.o: unctrl.h
+lib_color.po: curses.h
+lib_color.po: ncurses_def.h
+lib_color.po: term.h
+lib_color.po: unctrl.h
+lib_colorset.So: curses.h
+lib_colorset.So: ncurses_def.h
+lib_colorset.So: term.h
+lib_colorset.So: unctrl.h
+lib_colorset.o: curses.h
+lib_colorset.o: ncurses_def.h
+lib_colorset.o: term.h
+lib_colorset.o: unctrl.h
+lib_colorset.po: curses.h
+lib_colorset.po: ncurses_def.h
+lib_colorset.po: term.h
+lib_colorset.po: unctrl.h
+lib_cur_term.So: curses.h
+lib_cur_term.So: ncurses_def.h
+lib_cur_term.So: term.h
+lib_cur_term.So: termcap.h
+lib_cur_term.So: unctrl.h
+lib_cur_term.o: curses.h
+lib_cur_term.o: ncurses_def.h
+lib_cur_term.o: term.h
+lib_cur_term.o: termcap.h
+lib_cur_term.o: unctrl.h
+lib_cur_term.po: curses.h
+lib_cur_term.po: ncurses_def.h
+lib_cur_term.po: term.h
+lib_cur_term.po: termcap.h
+lib_cur_term.po: unctrl.h
+lib_data.So: curses.h
+lib_data.So: ncurses_def.h
+lib_data.So: term.h
+lib_data.So: unctrl.h
+lib_data.o: curses.h
+lib_data.o: ncurses_def.h
+lib_data.o: term.h
+lib_data.o: unctrl.h
+lib_data.po: curses.h
+lib_data.po: ncurses_def.h
+lib_data.po: term.h
+lib_data.po: unctrl.h
+lib_delch.So: curses.h
+lib_delch.So: ncurses_def.h
+lib_delch.So: term.h
+lib_delch.So: unctrl.h
+lib_delch.o: curses.h
+lib_delch.o: ncurses_def.h
+lib_delch.o: term.h
+lib_delch.o: unctrl.h
+lib_delch.po: curses.h
+lib_delch.po: ncurses_def.h
+lib_delch.po: term.h
+lib_delch.po: unctrl.h
+lib_delwin.So: curses.h
+lib_delwin.So: ncurses_def.h
+lib_delwin.So: term.h
+lib_delwin.So: unctrl.h
+lib_delwin.o: curses.h
+lib_delwin.o: ncurses_def.h
+lib_delwin.o: term.h
+lib_delwin.o: unctrl.h
+lib_delwin.po: curses.h
+lib_delwin.po: ncurses_def.h
+lib_delwin.po: term.h
+lib_delwin.po: unctrl.h
+lib_dft_fgbg.So: curses.h
+lib_dft_fgbg.So: ncurses_def.h
+lib_dft_fgbg.So: term.h
+lib_dft_fgbg.So: unctrl.h
+lib_dft_fgbg.o: curses.h
+lib_dft_fgbg.o: ncurses_def.h
+lib_dft_fgbg.o: term.h
+lib_dft_fgbg.o: unctrl.h
+lib_dft_fgbg.po: curses.h
+lib_dft_fgbg.po: ncurses_def.h
+lib_dft_fgbg.po: term.h
+lib_dft_fgbg.po: unctrl.h
+lib_echo.So: curses.h
+lib_echo.So: ncurses_def.h
+lib_echo.So: term.h
+lib_echo.So: unctrl.h
+lib_echo.o: curses.h
+lib_echo.o: ncurses_def.h
+lib_echo.o: term.h
+lib_echo.o: unctrl.h
+lib_echo.po: curses.h
+lib_echo.po: ncurses_def.h
+lib_echo.po: term.h
+lib_echo.po: unctrl.h
+lib_endwin.So: curses.h
+lib_endwin.So: ncurses_def.h
+lib_endwin.So: term.h
+lib_endwin.So: unctrl.h
+lib_endwin.o: curses.h
+lib_endwin.o: ncurses_def.h
+lib_endwin.o: term.h
+lib_endwin.o: unctrl.h
+lib_endwin.po: curses.h
+lib_endwin.po: ncurses_def.h
+lib_endwin.po: term.h
+lib_endwin.po: unctrl.h
+lib_erase.So: curses.h
+lib_erase.So: ncurses_def.h
+lib_erase.So: term.h
+lib_erase.So: unctrl.h
+lib_erase.o: curses.h
+lib_erase.o: ncurses_def.h
+lib_erase.o: term.h
+lib_erase.o: unctrl.h
+lib_erase.po: curses.h
+lib_erase.po: ncurses_def.h
+lib_erase.po: term.h
+lib_erase.po: unctrl.h
+lib_flash.So: curses.h
+lib_flash.So: ncurses_def.h
+lib_flash.So: term.h
+lib_flash.So: unctrl.h
+lib_flash.o: curses.h
+lib_flash.o: ncurses_def.h
+lib_flash.o: term.h
+lib_flash.o: unctrl.h
+lib_flash.po: curses.h
+lib_flash.po: ncurses_def.h
+lib_flash.po: term.h
+lib_flash.po: unctrl.h
+lib_freeall.So: curses.h
+lib_freeall.So: ncurses_def.h
+lib_freeall.So: term.h
+lib_freeall.So: unctrl.h
+lib_freeall.o: curses.h
+lib_freeall.o: ncurses_def.h
+lib_freeall.o: term.h
+lib_freeall.o: unctrl.h
+lib_freeall.po: curses.h
+lib_freeall.po: ncurses_def.h
+lib_freeall.po: term.h
+lib_freeall.po: unctrl.h
+lib_gen.So: curses.h
+lib_gen.So: lib_gen.c
+lib_gen.So: ncurses_def.h
+lib_gen.So: term.h
+lib_gen.So: unctrl.h
+lib_gen.o: curses.h
+lib_gen.o: lib_gen.c
+lib_gen.o: ncurses_def.h
+lib_gen.o: term.h
+lib_gen.o: unctrl.h
+lib_gen.po: curses.h
+lib_gen.po: lib_gen.c
+lib_gen.po: ncurses_def.h
+lib_gen.po: term.h
+lib_gen.po: unctrl.h
+lib_getch.So: curses.h
+lib_getch.So: ncurses_def.h
+lib_getch.So: term.h
+lib_getch.So: unctrl.h
+lib_getch.o: curses.h
+lib_getch.o: ncurses_def.h
+lib_getch.o: term.h
+lib_getch.o: unctrl.h
+lib_getch.po: curses.h
+lib_getch.po: ncurses_def.h
+lib_getch.po: term.h
+lib_getch.po: unctrl.h
+lib_getstr.So: curses.h
+lib_getstr.So: ncurses_def.h
+lib_getstr.So: term.h
+lib_getstr.So: unctrl.h
+lib_getstr.o: curses.h
+lib_getstr.o: ncurses_def.h
+lib_getstr.o: term.h
+lib_getstr.o: unctrl.h
+lib_getstr.po: curses.h
+lib_getstr.po: ncurses_def.h
+lib_getstr.po: term.h
+lib_getstr.po: unctrl.h
+lib_has_cap.So: curses.h
+lib_has_cap.So: ncurses_def.h
+lib_has_cap.So: term.h
+lib_has_cap.So: unctrl.h
+lib_has_cap.o: curses.h
+lib_has_cap.o: ncurses_def.h
+lib_has_cap.o: term.h
+lib_has_cap.o: unctrl.h
+lib_has_cap.po: curses.h
+lib_has_cap.po: ncurses_def.h
+lib_has_cap.po: term.h
+lib_has_cap.po: unctrl.h
+lib_hline.So: curses.h
+lib_hline.So: ncurses_def.h
+lib_hline.So: term.h
+lib_hline.So: unctrl.h
+lib_hline.o: curses.h
+lib_hline.o: ncurses_def.h
+lib_hline.o: term.h
+lib_hline.o: unctrl.h
+lib_hline.po: curses.h
+lib_hline.po: ncurses_def.h
+lib_hline.po: term.h
+lib_hline.po: unctrl.h
+lib_immedok.So: curses.h
+lib_immedok.So: ncurses_def.h
+lib_immedok.So: term.h
+lib_immedok.So: unctrl.h
+lib_immedok.o: curses.h
+lib_immedok.o: ncurses_def.h
+lib_immedok.o: term.h
+lib_immedok.o: unctrl.h
+lib_immedok.po: curses.h
+lib_immedok.po: ncurses_def.h
+lib_immedok.po: term.h
+lib_immedok.po: unctrl.h
+lib_inchstr.So: curses.h
+lib_inchstr.So: ncurses_def.h
+lib_inchstr.So: term.h
+lib_inchstr.So: unctrl.h
+lib_inchstr.o: curses.h
+lib_inchstr.o: ncurses_def.h
+lib_inchstr.o: term.h
+lib_inchstr.o: unctrl.h
+lib_inchstr.po: curses.h
+lib_inchstr.po: ncurses_def.h
+lib_inchstr.po: term.h
+lib_inchstr.po: unctrl.h
+lib_initscr.So: curses.h
+lib_initscr.So: ncurses_def.h
+lib_initscr.So: term.h
+lib_initscr.So: unctrl.h
+lib_initscr.o: curses.h
+lib_initscr.o: ncurses_def.h
+lib_initscr.o: term.h
+lib_initscr.o: unctrl.h
+lib_initscr.po: curses.h
+lib_initscr.po: ncurses_def.h
+lib_initscr.po: term.h
+lib_initscr.po: unctrl.h
+lib_insch.So: curses.h
+lib_insch.So: ncurses_def.h
+lib_insch.So: term.h
+lib_insch.So: unctrl.h
+lib_insch.o: curses.h
+lib_insch.o: ncurses_def.h
+lib_insch.o: term.h
+lib_insch.o: unctrl.h
+lib_insch.po: curses.h
+lib_insch.po: ncurses_def.h
+lib_insch.po: term.h
+lib_insch.po: unctrl.h
+lib_insdel.So: curses.h
+lib_insdel.So: ncurses_def.h
+lib_insdel.So: term.h
+lib_insdel.So: unctrl.h
+lib_insdel.o: curses.h
+lib_insdel.o: ncurses_def.h
+lib_insdel.o: term.h
+lib_insdel.o: unctrl.h
+lib_insdel.po: curses.h
+lib_insdel.po: ncurses_def.h
+lib_insdel.po: term.h
+lib_insdel.po: unctrl.h
+lib_insnstr.So: curses.h
+lib_insnstr.So: ncurses_def.h
+lib_insnstr.So: term.h
+lib_insnstr.So: unctrl.h
+lib_insnstr.o: curses.h
+lib_insnstr.o: ncurses_def.h
+lib_insnstr.o: term.h
+lib_insnstr.o: unctrl.h
+lib_insnstr.po: curses.h
+lib_insnstr.po: ncurses_def.h
+lib_insnstr.po: term.h
+lib_insnstr.po: unctrl.h
+lib_instr.So: curses.h
+lib_instr.So: ncurses_def.h
+lib_instr.So: term.h
+lib_instr.So: unctrl.h
+lib_instr.o: curses.h
+lib_instr.o: ncurses_def.h
+lib_instr.o: term.h
+lib_instr.o: unctrl.h
+lib_instr.po: curses.h
+lib_instr.po: ncurses_def.h
+lib_instr.po: term.h
+lib_instr.po: unctrl.h
+lib_isendwin.So: curses.h
+lib_isendwin.So: ncurses_def.h
+lib_isendwin.So: term.h
+lib_isendwin.So: unctrl.h
+lib_isendwin.o: curses.h
+lib_isendwin.o: ncurses_def.h
+lib_isendwin.o: term.h
+lib_isendwin.o: unctrl.h
+lib_isendwin.po: curses.h
+lib_isendwin.po: ncurses_def.h
+lib_isendwin.po: term.h
+lib_isendwin.po: unctrl.h
+lib_kernel.So: curses.h
+lib_kernel.So: ncurses_def.h
+lib_kernel.So: term.h
+lib_kernel.So: unctrl.h
+lib_kernel.o: curses.h
+lib_kernel.o: ncurses_def.h
+lib_kernel.o: term.h
+lib_kernel.o: unctrl.h
+lib_kernel.po: curses.h
+lib_kernel.po: ncurses_def.h
+lib_kernel.po: term.h
+lib_kernel.po: unctrl.h
+lib_keyname.So: curses.h
+lib_keyname.So: lib_keyname.c
+lib_keyname.So: ncurses_def.h
+lib_keyname.So: term.h
+lib_keyname.So: unctrl.h
+lib_keyname.o: curses.h
+lib_keyname.o: lib_keyname.c
+lib_keyname.o: ncurses_def.h
+lib_keyname.o: term.h
+lib_keyname.o: unctrl.h
+lib_keyname.po: curses.h
+lib_keyname.po: lib_keyname.c
+lib_keyname.po: ncurses_def.h
+lib_keyname.po: term.h
+lib_keyname.po: unctrl.h
+lib_leaveok.So: curses.h
+lib_leaveok.So: ncurses_def.h
+lib_leaveok.So: term.h
+lib_leaveok.So: unctrl.h
+lib_leaveok.o: curses.h
+lib_leaveok.o: ncurses_def.h
+lib_leaveok.o: term.h
+lib_leaveok.o: unctrl.h
+lib_leaveok.po: curses.h
+lib_leaveok.po: ncurses_def.h
+lib_leaveok.po: term.h
+lib_leaveok.po: unctrl.h
+lib_longname.So: curses.h
+lib_longname.So: ncurses_def.h
+lib_longname.So: term.h
+lib_longname.So: unctrl.h
+lib_longname.o: curses.h
+lib_longname.o: ncurses_def.h
+lib_longname.o: term.h
+lib_longname.o: unctrl.h
+lib_longname.po: curses.h
+lib_longname.po: ncurses_def.h
+lib_longname.po: term.h
+lib_longname.po: unctrl.h
+lib_mouse.So: curses.h
+lib_mouse.So: ncurses_def.h
+lib_mouse.So: term.h
+lib_mouse.So: unctrl.h
+lib_mouse.o: curses.h
+lib_mouse.o: ncurses_def.h
+lib_mouse.o: term.h
+lib_mouse.o: unctrl.h
+lib_mouse.po: curses.h
+lib_mouse.po: ncurses_def.h
+lib_mouse.po: term.h
+lib_mouse.po: unctrl.h
+lib_move.So: curses.h
+lib_move.So: ncurses_def.h
+lib_move.So: term.h
+lib_move.So: unctrl.h
+lib_move.o: curses.h
+lib_move.o: ncurses_def.h
+lib_move.o: term.h
+lib_move.o: unctrl.h
+lib_move.po: curses.h
+lib_move.po: ncurses_def.h
+lib_move.po: term.h
+lib_move.po: unctrl.h
+lib_mvcur.So: curses.h
+lib_mvcur.So: ncurses_def.h
+lib_mvcur.So: term.h
+lib_mvcur.So: unctrl.h
+lib_mvcur.o: curses.h
+lib_mvcur.o: ncurses_def.h
+lib_mvcur.o: term.h
+lib_mvcur.o: unctrl.h
+lib_mvcur.po: curses.h
+lib_mvcur.po: ncurses_def.h
+lib_mvcur.po: term.h
+lib_mvcur.po: unctrl.h
+lib_mvwin.So: curses.h
+lib_mvwin.So: ncurses_def.h
+lib_mvwin.So: term.h
+lib_mvwin.So: unctrl.h
+lib_mvwin.o: curses.h
+lib_mvwin.o: ncurses_def.h
+lib_mvwin.o: term.h
+lib_mvwin.o: unctrl.h
+lib_mvwin.po: curses.h
+lib_mvwin.po: ncurses_def.h
+lib_mvwin.po: term.h
+lib_mvwin.po: unctrl.h
+lib_napms.So: curses.h
+lib_napms.So: ncurses_def.h
+lib_napms.So: term.h
+lib_napms.So: unctrl.h
+lib_napms.o: curses.h
+lib_napms.o: ncurses_def.h
+lib_napms.o: term.h
+lib_napms.o: unctrl.h
+lib_napms.po: curses.h
+lib_napms.po: ncurses_def.h
+lib_napms.po: term.h
+lib_napms.po: unctrl.h
+lib_newterm.So: curses.h
+lib_newterm.So: ncurses_def.h
+lib_newterm.So: term.h
+lib_newterm.So: unctrl.h
+lib_newterm.o: curses.h
+lib_newterm.o: ncurses_def.h
+lib_newterm.o: term.h
+lib_newterm.o: unctrl.h
+lib_newterm.po: curses.h
+lib_newterm.po: ncurses_def.h
+lib_newterm.po: term.h
+lib_newterm.po: unctrl.h
+lib_newwin.So: curses.h
+lib_newwin.So: ncurses_def.h
+lib_newwin.So: term.h
+lib_newwin.So: unctrl.h
+lib_newwin.o: curses.h
+lib_newwin.o: ncurses_def.h
+lib_newwin.o: term.h
+lib_newwin.o: unctrl.h
+lib_newwin.po: curses.h
+lib_newwin.po: ncurses_def.h
+lib_newwin.po: term.h
+lib_newwin.po: unctrl.h
+lib_nl.So: curses.h
+lib_nl.So: ncurses_def.h
+lib_nl.So: term.h
+lib_nl.So: unctrl.h
+lib_nl.o: curses.h
+lib_nl.o: ncurses_def.h
+lib_nl.o: term.h
+lib_nl.o: unctrl.h
+lib_nl.po: curses.h
+lib_nl.po: ncurses_def.h
+lib_nl.po: term.h
+lib_nl.po: unctrl.h
+lib_options.So: curses.h
+lib_options.So: ncurses_def.h
+lib_options.So: term.h
+lib_options.So: unctrl.h
+lib_options.o: curses.h
+lib_options.o: ncurses_def.h
+lib_options.o: term.h
+lib_options.o: unctrl.h
+lib_options.po: curses.h
+lib_options.po: ncurses_def.h
+lib_options.po: term.h
+lib_options.po: unctrl.h
+lib_overlay.So: curses.h
+lib_overlay.So: ncurses_def.h
+lib_overlay.So: term.h
+lib_overlay.So: unctrl.h
+lib_overlay.o: curses.h
+lib_overlay.o: ncurses_def.h
+lib_overlay.o: term.h
+lib_overlay.o: unctrl.h
+lib_overlay.po: curses.h
+lib_overlay.po: ncurses_def.h
+lib_overlay.po: term.h
+lib_overlay.po: unctrl.h
+lib_pad.So: curses.h
+lib_pad.So: ncurses_def.h
+lib_pad.So: term.h
+lib_pad.So: unctrl.h
+lib_pad.o: curses.h
+lib_pad.o: ncurses_def.h
+lib_pad.o: term.h
+lib_pad.o: unctrl.h
+lib_pad.po: curses.h
+lib_pad.po: ncurses_def.h
+lib_pad.po: term.h
+lib_pad.po: unctrl.h
+lib_print.So: curses.h
+lib_print.So: ncurses_def.h
+lib_print.So: term.h
+lib_print.So: unctrl.h
+lib_print.o: curses.h
+lib_print.o: ncurses_def.h
+lib_print.o: term.h
+lib_print.o: unctrl.h
+lib_print.po: curses.h
+lib_print.po: ncurses_def.h
+lib_print.po: term.h
+lib_print.po: unctrl.h
+lib_printw.So: curses.h
+lib_printw.So: ncurses_def.h
+lib_printw.So: term.h
+lib_printw.So: unctrl.h
+lib_printw.o: curses.h
+lib_printw.o: ncurses_def.h
+lib_printw.o: term.h
+lib_printw.o: unctrl.h
+lib_printw.po: curses.h
+lib_printw.po: ncurses_def.h
+lib_printw.po: term.h
+lib_printw.po: unctrl.h
+lib_raw.So: curses.h
+lib_raw.So: ncurses_def.h
+lib_raw.So: term.h
+lib_raw.So: unctrl.h
+lib_raw.o: curses.h
+lib_raw.o: ncurses_def.h
+lib_raw.o: term.h
+lib_raw.o: unctrl.h
+lib_raw.po: curses.h
+lib_raw.po: ncurses_def.h
+lib_raw.po: term.h
+lib_raw.po: unctrl.h
+lib_redrawln.So: curses.h
+lib_redrawln.So: ncurses_def.h
+lib_redrawln.So: term.h
+lib_redrawln.So: unctrl.h
+lib_redrawln.o: curses.h
+lib_redrawln.o: ncurses_def.h
+lib_redrawln.o: term.h
+lib_redrawln.o: unctrl.h
+lib_redrawln.po: curses.h
+lib_redrawln.po: ncurses_def.h
+lib_redrawln.po: term.h
+lib_redrawln.po: unctrl.h
+lib_refresh.So: curses.h
+lib_refresh.So: ncurses_def.h
+lib_refresh.So: term.h
+lib_refresh.So: unctrl.h
+lib_refresh.o: curses.h
+lib_refresh.o: ncurses_def.h
+lib_refresh.o: term.h
+lib_refresh.o: unctrl.h
+lib_refresh.po: curses.h
+lib_refresh.po: ncurses_def.h
+lib_refresh.po: term.h
+lib_refresh.po: unctrl.h
+lib_restart.So: curses.h
+lib_restart.So: ncurses_def.h
+lib_restart.So: term.h
+lib_restart.So: unctrl.h
+lib_restart.o: curses.h
+lib_restart.o: ncurses_def.h
+lib_restart.o: term.h
+lib_restart.o: unctrl.h
+lib_restart.po: curses.h
+lib_restart.po: ncurses_def.h
+lib_restart.po: term.h
+lib_restart.po: unctrl.h
+lib_scanw.So: curses.h
+lib_scanw.So: ncurses_def.h
+lib_scanw.So: term.h
+lib_scanw.So: unctrl.h
+lib_scanw.o: curses.h
+lib_scanw.o: ncurses_def.h
+lib_scanw.o: term.h
+lib_scanw.o: unctrl.h
+lib_scanw.po: curses.h
+lib_scanw.po: ncurses_def.h
+lib_scanw.po: term.h
+lib_scanw.po: unctrl.h
+lib_screen.So: curses.h
+lib_screen.So: ncurses_def.h
+lib_screen.So: term.h
+lib_screen.So: unctrl.h
+lib_screen.o: curses.h
+lib_screen.o: ncurses_def.h
+lib_screen.o: term.h
+lib_screen.o: unctrl.h
+lib_screen.po: curses.h
+lib_screen.po: ncurses_def.h
+lib_screen.po: term.h
+lib_screen.po: unctrl.h
+lib_scroll.So: curses.h
+lib_scroll.So: ncurses_def.h
+lib_scroll.So: term.h
+lib_scroll.So: unctrl.h
+lib_scroll.o: curses.h
+lib_scroll.o: ncurses_def.h
+lib_scroll.o: term.h
+lib_scroll.o: unctrl.h
+lib_scroll.po: curses.h
+lib_scroll.po: ncurses_def.h
+lib_scroll.po: term.h
+lib_scroll.po: unctrl.h
+lib_scrollok.So: curses.h
+lib_scrollok.So: ncurses_def.h
+lib_scrollok.So: term.h
+lib_scrollok.So: unctrl.h
+lib_scrollok.o: curses.h
+lib_scrollok.o: ncurses_def.h
+lib_scrollok.o: term.h
+lib_scrollok.o: unctrl.h
+lib_scrollok.po: curses.h
+lib_scrollok.po: ncurses_def.h
+lib_scrollok.po: term.h
+lib_scrollok.po: unctrl.h
+lib_scrreg.So: curses.h
+lib_scrreg.So: ncurses_def.h
+lib_scrreg.So: term.h
+lib_scrreg.So: unctrl.h
+lib_scrreg.o: curses.h
+lib_scrreg.o: ncurses_def.h
+lib_scrreg.o: term.h
+lib_scrreg.o: unctrl.h
+lib_scrreg.po: curses.h
+lib_scrreg.po: ncurses_def.h
+lib_scrreg.po: term.h
+lib_scrreg.po: unctrl.h
+lib_set_term.So: curses.h
+lib_set_term.So: ncurses_def.h
+lib_set_term.So: term.h
+lib_set_term.So: unctrl.h
+lib_set_term.o: curses.h
+lib_set_term.o: ncurses_def.h
+lib_set_term.o: term.h
+lib_set_term.o: unctrl.h
+lib_set_term.po: curses.h
+lib_set_term.po: ncurses_def.h
+lib_set_term.po: term.h
+lib_set_term.po: unctrl.h
+lib_setup.So: curses.h
+lib_setup.So: ncurses_def.h
+lib_setup.So: term.h
+lib_setup.So: unctrl.h
+lib_setup.o: curses.h
+lib_setup.o: ncurses_def.h
+lib_setup.o: term.h
+lib_setup.o: unctrl.h
+lib_setup.po: curses.h
+lib_setup.po: ncurses_def.h
+lib_setup.po: term.h
+lib_setup.po: unctrl.h
+lib_slk.So: curses.h
+lib_slk.So: ncurses_def.h
+lib_slk.So: term.h
+lib_slk.So: unctrl.h
+lib_slk.o: curses.h
+lib_slk.o: ncurses_def.h
+lib_slk.o: term.h
+lib_slk.o: unctrl.h
+lib_slk.po: curses.h
+lib_slk.po: ncurses_def.h
+lib_slk.po: term.h
+lib_slk.po: unctrl.h
+lib_slkatr_set.So: curses.h
+lib_slkatr_set.So: ncurses_def.h
+lib_slkatr_set.So: term.h
+lib_slkatr_set.So: unctrl.h
+lib_slkatr_set.o: curses.h
+lib_slkatr_set.o: ncurses_def.h
+lib_slkatr_set.o: term.h
+lib_slkatr_set.o: unctrl.h
+lib_slkatr_set.po: curses.h
+lib_slkatr_set.po: ncurses_def.h
+lib_slkatr_set.po: term.h
+lib_slkatr_set.po: unctrl.h
+lib_slkatrof.So: curses.h
+lib_slkatrof.So: ncurses_def.h
+lib_slkatrof.So: term.h
+lib_slkatrof.So: unctrl.h
+lib_slkatrof.o: curses.h
+lib_slkatrof.o: ncurses_def.h
+lib_slkatrof.o: term.h
+lib_slkatrof.o: unctrl.h
+lib_slkatrof.po: curses.h
+lib_slkatrof.po: ncurses_def.h
+lib_slkatrof.po: term.h
+lib_slkatrof.po: unctrl.h
+lib_slkatron.So: curses.h
+lib_slkatron.So: ncurses_def.h
+lib_slkatron.So: term.h
+lib_slkatron.So: unctrl.h
+lib_slkatron.o: curses.h
+lib_slkatron.o: ncurses_def.h
+lib_slkatron.o: term.h
+lib_slkatron.o: unctrl.h
+lib_slkatron.po: curses.h
+lib_slkatron.po: ncurses_def.h
+lib_slkatron.po: term.h
+lib_slkatron.po: unctrl.h
+lib_slkatrset.So: curses.h
+lib_slkatrset.So: ncurses_def.h
+lib_slkatrset.So: term.h
+lib_slkatrset.So: unctrl.h
+lib_slkatrset.o: curses.h
+lib_slkatrset.o: ncurses_def.h
+lib_slkatrset.o: term.h
+lib_slkatrset.o: unctrl.h
+lib_slkatrset.po: curses.h
+lib_slkatrset.po: ncurses_def.h
+lib_slkatrset.po: term.h
+lib_slkatrset.po: unctrl.h
+lib_slkattr.So: curses.h
+lib_slkattr.So: ncurses_def.h
+lib_slkattr.So: term.h
+lib_slkattr.So: unctrl.h
+lib_slkattr.o: curses.h
+lib_slkattr.o: ncurses_def.h
+lib_slkattr.o: term.h
+lib_slkattr.o: unctrl.h
+lib_slkattr.po: curses.h
+lib_slkattr.po: ncurses_def.h
+lib_slkattr.po: term.h
+lib_slkattr.po: unctrl.h
+lib_slkclear.So: curses.h
+lib_slkclear.So: ncurses_def.h
+lib_slkclear.So: term.h
+lib_slkclear.So: unctrl.h
+lib_slkclear.o: curses.h
+lib_slkclear.o: ncurses_def.h
+lib_slkclear.o: term.h
+lib_slkclear.o: unctrl.h
+lib_slkclear.po: curses.h
+lib_slkclear.po: ncurses_def.h
+lib_slkclear.po: term.h
+lib_slkclear.po: unctrl.h
+lib_slkcolor.So: curses.h
+lib_slkcolor.So: ncurses_def.h
+lib_slkcolor.So: term.h
+lib_slkcolor.So: unctrl.h
+lib_slkcolor.o: curses.h
+lib_slkcolor.o: ncurses_def.h
+lib_slkcolor.o: term.h
+lib_slkcolor.o: unctrl.h
+lib_slkcolor.po: curses.h
+lib_slkcolor.po: ncurses_def.h
+lib_slkcolor.po: term.h
+lib_slkcolor.po: unctrl.h
+lib_slkinit.So: curses.h
+lib_slkinit.So: ncurses_def.h
+lib_slkinit.So: term.h
+lib_slkinit.So: unctrl.h
+lib_slkinit.o: curses.h
+lib_slkinit.o: ncurses_def.h
+lib_slkinit.o: term.h
+lib_slkinit.o: unctrl.h
+lib_slkinit.po: curses.h
+lib_slkinit.po: ncurses_def.h
+lib_slkinit.po: term.h
+lib_slkinit.po: unctrl.h
+lib_slklab.So: curses.h
+lib_slklab.So: ncurses_def.h
+lib_slklab.So: term.h
+lib_slklab.So: unctrl.h
+lib_slklab.o: curses.h
+lib_slklab.o: ncurses_def.h
+lib_slklab.o: term.h
+lib_slklab.o: unctrl.h
+lib_slklab.po: curses.h
+lib_slklab.po: ncurses_def.h
+lib_slklab.po: term.h
+lib_slklab.po: unctrl.h
+lib_slkrefr.So: curses.h
+lib_slkrefr.So: ncurses_def.h
+lib_slkrefr.So: term.h
+lib_slkrefr.So: unctrl.h
+lib_slkrefr.o: curses.h
+lib_slkrefr.o: ncurses_def.h
+lib_slkrefr.o: term.h
+lib_slkrefr.o: unctrl.h
+lib_slkrefr.po: curses.h
+lib_slkrefr.po: ncurses_def.h
+lib_slkrefr.po: term.h
+lib_slkrefr.po: unctrl.h
+lib_slkset.So: curses.h
+lib_slkset.So: ncurses_def.h
+lib_slkset.So: term.h
+lib_slkset.So: unctrl.h
+lib_slkset.o: curses.h
+lib_slkset.o: ncurses_def.h
+lib_slkset.o: term.h
+lib_slkset.o: unctrl.h
+lib_slkset.po: curses.h
+lib_slkset.po: ncurses_def.h
+lib_slkset.po: term.h
+lib_slkset.po: unctrl.h
+lib_slktouch.So: curses.h
+lib_slktouch.So: ncurses_def.h
+lib_slktouch.So: term.h
+lib_slktouch.So: unctrl.h
+lib_slktouch.o: curses.h
+lib_slktouch.o: ncurses_def.h
+lib_slktouch.o: term.h
+lib_slktouch.o: unctrl.h
+lib_slktouch.po: curses.h
+lib_slktouch.po: ncurses_def.h
+lib_slktouch.po: term.h
+lib_slktouch.po: unctrl.h
+lib_termcap.So: curses.h
+lib_termcap.So: ncurses_def.h
+lib_termcap.So: term.h
+lib_termcap.So: termcap.h
+lib_termcap.So: unctrl.h
+lib_termcap.o: curses.h
+lib_termcap.o: ncurses_def.h
+lib_termcap.o: term.h
+lib_termcap.o: termcap.h
+lib_termcap.o: unctrl.h
+lib_termcap.po: curses.h
+lib_termcap.po: ncurses_def.h
+lib_termcap.po: term.h
+lib_termcap.po: termcap.h
+lib_termcap.po: unctrl.h
+lib_termname.So: curses.h
+lib_termname.So: ncurses_def.h
+lib_termname.So: term.h
+lib_termname.So: unctrl.h
+lib_termname.o: curses.h
+lib_termname.o: ncurses_def.h
+lib_termname.o: term.h
+lib_termname.o: unctrl.h
+lib_termname.po: curses.h
+lib_termname.po: ncurses_def.h
+lib_termname.po: term.h
+lib_termname.po: unctrl.h
+lib_tgoto.So: curses.h
+lib_tgoto.So: ncurses_def.h
+lib_tgoto.So: term.h
+lib_tgoto.So: termcap.h
+lib_tgoto.So: unctrl.h
+lib_tgoto.o: curses.h
+lib_tgoto.o: ncurses_def.h
+lib_tgoto.o: term.h
+lib_tgoto.o: termcap.h
+lib_tgoto.o: unctrl.h
+lib_tgoto.po: curses.h
+lib_tgoto.po: ncurses_def.h
+lib_tgoto.po: term.h
+lib_tgoto.po: termcap.h
+lib_tgoto.po: unctrl.h
+lib_ti.So: curses.h
+lib_ti.So: ncurses_def.h
+lib_ti.So: term.h
+lib_ti.So: unctrl.h
+lib_ti.o: curses.h
+lib_ti.o: ncurses_def.h
+lib_ti.o: term.h
+lib_ti.o: unctrl.h
+lib_ti.po: curses.h
+lib_ti.po: ncurses_def.h
+lib_ti.po: term.h
+lib_ti.po: unctrl.h
+lib_touch.So: curses.h
+lib_touch.So: ncurses_def.h
+lib_touch.So: term.h
+lib_touch.So: unctrl.h
+lib_touch.o: curses.h
+lib_touch.o: ncurses_def.h
+lib_touch.o: term.h
+lib_touch.o: unctrl.h
+lib_touch.po: curses.h
+lib_touch.po: ncurses_def.h
+lib_touch.po: term.h
+lib_touch.po: unctrl.h
+lib_tparm.So: curses.h
+lib_tparm.So: ncurses_def.h
+lib_tparm.So: term.h
+lib_tparm.So: unctrl.h
+lib_tparm.o: curses.h
+lib_tparm.o: ncurses_def.h
+lib_tparm.o: term.h
+lib_tparm.o: unctrl.h
+lib_tparm.po: curses.h
+lib_tparm.po: ncurses_def.h
+lib_tparm.po: term.h
+lib_tparm.po: unctrl.h
+lib_tputs.So: curses.h
+lib_tputs.So: ncurses_def.h
+lib_tputs.So: term.h
+lib_tputs.So: termcap.h
+lib_tputs.So: unctrl.h
+lib_tputs.o: curses.h
+lib_tputs.o: ncurses_def.h
+lib_tputs.o: term.h
+lib_tputs.o: termcap.h
+lib_tputs.o: unctrl.h
+lib_tputs.po: curses.h
+lib_tputs.po: ncurses_def.h
+lib_tputs.po: term.h
+lib_tputs.po: termcap.h
+lib_tputs.po: unctrl.h
+lib_trace.So: curses.h
+lib_trace.So: ncurses_def.h
+lib_trace.So: term.h
+lib_trace.So: unctrl.h
+lib_trace.o: curses.h
+lib_trace.o: ncurses_def.h
+lib_trace.o: term.h
+lib_trace.o: unctrl.h
+lib_trace.po: curses.h
+lib_trace.po: ncurses_def.h
+lib_trace.po: term.h
+lib_trace.po: unctrl.h
+lib_tstp.So: curses.h
+lib_tstp.So: ncurses_def.h
+lib_tstp.So: term.h
+lib_tstp.So: unctrl.h
+lib_tstp.o: curses.h
+lib_tstp.o: ncurses_def.h
+lib_tstp.o: term.h
+lib_tstp.o: unctrl.h
+lib_tstp.po: curses.h
+lib_tstp.po: ncurses_def.h
+lib_tstp.po: term.h
+lib_tstp.po: unctrl.h
+lib_ttyflags.So: curses.h
+lib_ttyflags.So: ncurses_def.h
+lib_ttyflags.So: term.h
+lib_ttyflags.So: unctrl.h
+lib_ttyflags.o: curses.h
+lib_ttyflags.o: ncurses_def.h
+lib_ttyflags.o: term.h
+lib_ttyflags.o: unctrl.h
+lib_ttyflags.po: curses.h
+lib_ttyflags.po: ncurses_def.h
+lib_ttyflags.po: term.h
+lib_ttyflags.po: unctrl.h
+lib_twait.So: curses.h
+lib_twait.So: ncurses_def.h
+lib_twait.So: term.h
+lib_twait.So: unctrl.h
+lib_twait.o: curses.h
+lib_twait.o: ncurses_def.h
+lib_twait.o: term.h
+lib_twait.o: unctrl.h
+lib_twait.po: curses.h
+lib_twait.po: ncurses_def.h
+lib_twait.po: term.h
+lib_twait.po: unctrl.h
+lib_ungetch.So: curses.h
+lib_ungetch.So: ncurses_def.h
+lib_ungetch.So: term.h
+lib_ungetch.So: unctrl.h
+lib_ungetch.o: curses.h
+lib_ungetch.o: ncurses_def.h
+lib_ungetch.o: term.h
+lib_ungetch.o: unctrl.h
+lib_ungetch.po: curses.h
+lib_ungetch.po: ncurses_def.h
+lib_ungetch.po: term.h
+lib_ungetch.po: unctrl.h
+lib_vidattr.So: curses.h
+lib_vidattr.So: ncurses_def.h
+lib_vidattr.So: term.h
+lib_vidattr.So: unctrl.h
+lib_vidattr.o: curses.h
+lib_vidattr.o: ncurses_def.h
+lib_vidattr.o: term.h
+lib_vidattr.o: unctrl.h
+lib_vidattr.po: curses.h
+lib_vidattr.po: ncurses_def.h
+lib_vidattr.po: term.h
+lib_vidattr.po: unctrl.h
+lib_vline.So: curses.h
+lib_vline.So: ncurses_def.h
+lib_vline.So: term.h
+lib_vline.So: unctrl.h
+lib_vline.o: curses.h
+lib_vline.o: ncurses_def.h
+lib_vline.o: term.h
+lib_vline.o: unctrl.h
+lib_vline.po: curses.h
+lib_vline.po: ncurses_def.h
+lib_vline.po: term.h
+lib_vline.po: unctrl.h
+lib_wattroff.So: curses.h
+lib_wattroff.So: ncurses_def.h
+lib_wattroff.So: term.h
+lib_wattroff.So: unctrl.h
+lib_wattroff.o: curses.h
+lib_wattroff.o: ncurses_def.h
+lib_wattroff.o: term.h
+lib_wattroff.o: unctrl.h
+lib_wattroff.po: curses.h
+lib_wattroff.po: ncurses_def.h
+lib_wattroff.po: term.h
+lib_wattroff.po: unctrl.h
+lib_wattron.So: curses.h
+lib_wattron.So: ncurses_def.h
+lib_wattron.So: term.h
+lib_wattron.So: unctrl.h
+lib_wattron.o: curses.h
+lib_wattron.o: ncurses_def.h
+lib_wattron.o: term.h
+lib_wattron.o: unctrl.h
+lib_wattron.po: curses.h
+lib_wattron.po: ncurses_def.h
+lib_wattron.po: term.h
+lib_wattron.po: unctrl.h
+lib_winch.So: curses.h
+lib_winch.So: ncurses_def.h
+lib_winch.So: term.h
+lib_winch.So: unctrl.h
+lib_winch.o: curses.h
+lib_winch.o: ncurses_def.h
+lib_winch.o: term.h
+lib_winch.o: unctrl.h
+lib_winch.po: curses.h
+lib_winch.po: ncurses_def.h
+lib_winch.po: term.h
+lib_winch.po: unctrl.h
+lib_window.So: curses.h
+lib_window.So: ncurses_def.h
+lib_window.So: term.h
+lib_window.So: unctrl.h
+lib_window.o: curses.h
+lib_window.o: ncurses_def.h
+lib_window.o: term.h
+lib_window.o: unctrl.h
+lib_window.po: curses.h
+lib_window.po: ncurses_def.h
+lib_window.po: term.h
+lib_window.po: unctrl.h
+memmove.So: curses.h
+memmove.So: ncurses_def.h
+memmove.So: term.h
+memmove.So: unctrl.h
+memmove.o: curses.h
+memmove.o: ncurses_def.h
+memmove.o: term.h
+memmove.o: unctrl.h
+memmove.po: curses.h
+memmove.po: ncurses_def.h
+memmove.po: term.h
+memmove.po: unctrl.h
+name_match.So: curses.h
+name_match.So: ncurses_def.h
+name_match.So: term.h
+name_match.So: unctrl.h
+name_match.o: curses.h
+name_match.o: ncurses_def.h
+name_match.o: term.h
+name_match.o: unctrl.h
+name_match.po: curses.h
+name_match.po: ncurses_def.h
+name_match.po: term.h
+name_match.po: unctrl.h
+names.So: curses.h
+names.So: names.c
+names.So: ncurses_def.h
+names.So: term.h
+names.So: unctrl.h
+names.o: curses.h
+names.o: names.c
+names.o: ncurses_def.h
+names.o: term.h
+names.o: unctrl.h
+names.po: curses.h
+names.po: names.c
+names.po: ncurses_def.h
+names.po: term.h
+names.po: unctrl.h
+nc_panel.So: curses.h
+nc_panel.So: ncurses_def.h
+nc_panel.So: term.h
+nc_panel.So: unctrl.h
+nc_panel.o: curses.h
+nc_panel.o: ncurses_def.h
+nc_panel.o: term.h
+nc_panel.o: unctrl.h
+nc_panel.po: curses.h
+nc_panel.po: ncurses_def.h
+nc_panel.po: term.h
+nc_panel.po: unctrl.h
+parse_entry.So: curses.h
+parse_entry.So: ncurses_def.h
+parse_entry.So: parametrized.h
+parse_entry.So: term.h
+parse_entry.So: unctrl.h
+parse_entry.o: curses.h
+parse_entry.o: ncurses_def.h
+parse_entry.o: parametrized.h
+parse_entry.o: term.h
+parse_entry.o: unctrl.h
+parse_entry.po: curses.h
+parse_entry.po: ncurses_def.h
+parse_entry.po: parametrized.h
+parse_entry.po: term.h
+parse_entry.po: unctrl.h
+read_entry.So: curses.h
+read_entry.So: ncurses_def.h
+read_entry.So: term.h
+read_entry.So: unctrl.h
+read_entry.o: curses.h
+read_entry.o: ncurses_def.h
+read_entry.o: term.h
+read_entry.o: unctrl.h
+read_entry.po: curses.h
+read_entry.po: ncurses_def.h
+read_entry.po: term.h
+read_entry.po: unctrl.h
+resizeterm.So: curses.h
+resizeterm.So: ncurses_def.h
+resizeterm.So: term.h
+resizeterm.So: unctrl.h
+resizeterm.o: curses.h
+resizeterm.o: ncurses_def.h
+resizeterm.o: term.h
+resizeterm.o: unctrl.h
+resizeterm.po: curses.h
+resizeterm.po: ncurses_def.h
+resizeterm.po: term.h
+resizeterm.po: unctrl.h
+safe_sprintf.So: curses.h
+safe_sprintf.So: ncurses_def.h
+safe_sprintf.So: term.h
+safe_sprintf.So: unctrl.h
+safe_sprintf.o: curses.h
+safe_sprintf.o: ncurses_def.h
+safe_sprintf.o: term.h
+safe_sprintf.o: unctrl.h
+safe_sprintf.po: curses.h
+safe_sprintf.po: ncurses_def.h
+safe_sprintf.po: term.h
+safe_sprintf.po: unctrl.h
+setbuf.So: curses.h
+setbuf.So: ncurses_def.h
+setbuf.So: term.h
+setbuf.So: unctrl.h
+setbuf.o: curses.h
+setbuf.o: ncurses_def.h
+setbuf.o: term.h
+setbuf.o: unctrl.h
+setbuf.po: curses.h
+setbuf.po: ncurses_def.h
+setbuf.po: term.h
+setbuf.po: unctrl.h
+strings.So: curses.h
+strings.So: ncurses_def.h
+strings.So: term.h
+strings.So: unctrl.h
+strings.o: curses.h
+strings.o: ncurses_def.h
+strings.o: term.h
+strings.o: unctrl.h
+strings.po: curses.h
+strings.po: ncurses_def.h
+strings.po: term.h
+strings.po: unctrl.h
+termcap.So: curses.h
+termcap.So: ncurses_def.h
+termcap.So: term.h
+termcap.So: unctrl.h
+termcap.o: curses.h
+termcap.o: ncurses_def.h
+termcap.o: term.h
+termcap.o: unctrl.h
+termcap.po: curses.h
+termcap.po: ncurses_def.h
+termcap.po: term.h
+termcap.po: unctrl.h
+tries.So: curses.h
+tries.So: ncurses_def.h
+tries.So: term.h
+tries.So: unctrl.h
+tries.o: curses.h
+tries.o: ncurses_def.h
+tries.o: term.h
+tries.o: unctrl.h
+tries.po: curses.h
+tries.po: ncurses_def.h
+tries.po: term.h
+tries.po: unctrl.h
+trim_sgr0.So: curses.h
+trim_sgr0.So: ncurses_def.h
+trim_sgr0.So: term.h
+trim_sgr0.So: unctrl.h
+trim_sgr0.o: curses.h
+trim_sgr0.o: ncurses_def.h
+trim_sgr0.o: term.h
+trim_sgr0.o: unctrl.h
+trim_sgr0.po: curses.h
+trim_sgr0.po: ncurses_def.h
+trim_sgr0.po: term.h
+trim_sgr0.po: unctrl.h
+tty_update.So: curses.h
+tty_update.So: ncurses_def.h
+tty_update.So: term.h
+tty_update.So: unctrl.h
+tty_update.o: curses.h
+tty_update.o: ncurses_def.h
+tty_update.o: term.h
+tty_update.o: unctrl.h
+tty_update.po: curses.h
+tty_update.po: ncurses_def.h
+tty_update.po: term.h
+tty_update.po: unctrl.h
+unctrl.So: curses.h
+unctrl.So: ncurses_def.h
+unctrl.So: term.h
+unctrl.So: unctrl.c
+unctrl.So: unctrl.h
+unctrl.o: curses.h
+unctrl.o: ncurses_def.h
+unctrl.o: term.h
+unctrl.o: unctrl.c
+unctrl.o: unctrl.h
+unctrl.po: curses.h
+unctrl.po: ncurses_def.h
+unctrl.po: term.h
+unctrl.po: unctrl.c
+unctrl.po: unctrl.h
+version.So: curses.h
+version.So: ncurses_def.h
+version.So: term.h
+version.So: unctrl.h
+version.o: curses.h
+version.o: ncurses_def.h
+version.o: term.h
+version.o: unctrl.h
+version.po: curses.h
+version.po: ncurses_def.h
+version.po: term.h
+version.po: unctrl.h
+visbuf.So: curses.h
+visbuf.So: ncurses_def.h
+visbuf.So: term.h
+visbuf.So: unctrl.h
+visbuf.o: curses.h
+visbuf.o: ncurses_def.h
+visbuf.o: term.h
+visbuf.o: unctrl.h
+visbuf.po: curses.h
+visbuf.po: ncurses_def.h
+visbuf.po: term.h
+visbuf.po: unctrl.h
+vsscanf.So: curses.h
+vsscanf.So: ncurses_def.h
+vsscanf.So: term.h
+vsscanf.So: unctrl.h
+vsscanf.o: curses.h
+vsscanf.o: ncurses_def.h
+vsscanf.o: term.h
+vsscanf.o: unctrl.h
+vsscanf.po: curses.h
+vsscanf.po: ncurses_def.h
+vsscanf.po: term.h
+vsscanf.po: unctrl.h
+wresize.So: curses.h
+wresize.So: ncurses_def.h
+wresize.So: term.h
+wresize.So: unctrl.h
+wresize.o: curses.h
+wresize.o: ncurses_def.h
+wresize.o: term.h
+wresize.o: unctrl.h
+wresize.po: curses.h
+wresize.po: ncurses_def.h
+wresize.po: term.h
+wresize.po: unctrl.h
+write_entry.So: curses.h
+write_entry.So: ncurses_def.h
+write_entry.So: term.h
+write_entry.So: unctrl.h
+write_entry.o: curses.h
+write_entry.o: ncurses_def.h
+write_entry.o: term.h
+write_entry.o: unctrl.h
+write_entry.po: curses.h
+write_entry.po: ncurses_def.h
+write_entry.po: term.h
+write_entry.po: unctrl.h
+.endif
diff --git a/lib/ncurses/ncursesw/Makefile.depend b/lib/ncurses/ncursesw/Makefile.depend
new file mode 100644
index 0000000..55371bd
--- /dev/null
+++ b/lib/ncurses/ncursesw/Makefile.depend
@@ -0,0 +1,2047 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+access.So: curses.h
+access.So: ncurses_def.h
+access.So: term.h
+access.So: unctrl.h
+access.o: curses.h
+access.o: ncurses_def.h
+access.o: term.h
+access.o: unctrl.h
+access.po: curses.h
+access.po: ncurses_def.h
+access.po: term.h
+access.po: unctrl.h
+add_tries.So: curses.h
+add_tries.So: ncurses_def.h
+add_tries.So: term.h
+add_tries.So: unctrl.h
+add_tries.o: curses.h
+add_tries.o: ncurses_def.h
+add_tries.o: term.h
+add_tries.o: unctrl.h
+add_tries.po: curses.h
+add_tries.po: ncurses_def.h
+add_tries.po: term.h
+add_tries.po: unctrl.h
+alloc_entry.So: curses.h
+alloc_entry.So: ncurses_def.h
+alloc_entry.So: term.h
+alloc_entry.So: unctrl.h
+alloc_entry.o: curses.h
+alloc_entry.o: ncurses_def.h
+alloc_entry.o: term.h
+alloc_entry.o: unctrl.h
+alloc_entry.po: curses.h
+alloc_entry.po: ncurses_def.h
+alloc_entry.po: term.h
+alloc_entry.po: unctrl.h
+alloc_ttype.So: curses.h
+alloc_ttype.So: ncurses_def.h
+alloc_ttype.So: term.h
+alloc_ttype.So: unctrl.h
+alloc_ttype.o: curses.h
+alloc_ttype.o: ncurses_def.h
+alloc_ttype.o: term.h
+alloc_ttype.o: unctrl.h
+alloc_ttype.po: curses.h
+alloc_ttype.po: ncurses_def.h
+alloc_ttype.po: term.h
+alloc_ttype.po: unctrl.h
+captoinfo.So: curses.h
+captoinfo.So: ncurses_def.h
+captoinfo.So: term.h
+captoinfo.So: unctrl.h
+captoinfo.o: curses.h
+captoinfo.o: ncurses_def.h
+captoinfo.o: term.h
+captoinfo.o: unctrl.h
+captoinfo.po: curses.h
+captoinfo.po: ncurses_def.h
+captoinfo.po: term.h
+captoinfo.po: unctrl.h
+charable.So: curses.h
+charable.So: ncurses_def.h
+charable.So: term.h
+charable.So: unctrl.h
+charable.o: curses.h
+charable.o: ncurses_def.h
+charable.o: term.h
+charable.o: unctrl.h
+charable.po: curses.h
+charable.po: ncurses_def.h
+charable.po: term.h
+charable.po: unctrl.h
+codes.So: codes.c
+codes.So: curses.h
+codes.So: ncurses_def.h
+codes.So: term.h
+codes.So: unctrl.h
+codes.o: codes.c
+codes.o: curses.h
+codes.o: ncurses_def.h
+codes.o: term.h
+codes.o: unctrl.h
+codes.po: codes.c
+codes.po: curses.h
+codes.po: ncurses_def.h
+codes.po: term.h
+codes.po: unctrl.h
+comp_captab.So: comp_captab.c
+comp_captab.So: curses.h
+comp_captab.So: hashsize.h
+comp_captab.So: ncurses_def.h
+comp_captab.So: term.h
+comp_captab.So: unctrl.h
+comp_captab.o: comp_captab.c
+comp_captab.o: curses.h
+comp_captab.o: hashsize.h
+comp_captab.o: ncurses_def.h
+comp_captab.o: term.h
+comp_captab.o: unctrl.h
+comp_captab.po: comp_captab.c
+comp_captab.po: curses.h
+comp_captab.po: hashsize.h
+comp_captab.po: ncurses_def.h
+comp_captab.po: term.h
+comp_captab.po: unctrl.h
+comp_error.So: curses.h
+comp_error.So: ncurses_def.h
+comp_error.So: term.h
+comp_error.So: unctrl.h
+comp_error.o: curses.h
+comp_error.o: ncurses_def.h
+comp_error.o: term.h
+comp_error.o: unctrl.h
+comp_error.po: curses.h
+comp_error.po: ncurses_def.h
+comp_error.po: term.h
+comp_error.po: unctrl.h
+comp_expand.So: curses.h
+comp_expand.So: ncurses_def.h
+comp_expand.So: term.h
+comp_expand.So: unctrl.h
+comp_expand.o: curses.h
+comp_expand.o: ncurses_def.h
+comp_expand.o: term.h
+comp_expand.o: unctrl.h
+comp_expand.po: curses.h
+comp_expand.po: ncurses_def.h
+comp_expand.po: term.h
+comp_expand.po: unctrl.h
+comp_hash.So: curses.h
+comp_hash.So: hashsize.h
+comp_hash.So: ncurses_def.h
+comp_hash.So: term.h
+comp_hash.So: unctrl.h
+comp_hash.o: curses.h
+comp_hash.o: hashsize.h
+comp_hash.o: ncurses_def.h
+comp_hash.o: term.h
+comp_hash.o: unctrl.h
+comp_hash.po: curses.h
+comp_hash.po: hashsize.h
+comp_hash.po: ncurses_def.h
+comp_hash.po: term.h
+comp_hash.po: unctrl.h
+comp_parse.So: curses.h
+comp_parse.So: ncurses_def.h
+comp_parse.So: term.h
+comp_parse.So: unctrl.h
+comp_parse.o: curses.h
+comp_parse.o: ncurses_def.h
+comp_parse.o: term.h
+comp_parse.o: unctrl.h
+comp_parse.po: curses.h
+comp_parse.po: ncurses_def.h
+comp_parse.po: term.h
+comp_parse.po: unctrl.h
+comp_scan.So: curses.h
+comp_scan.So: ncurses_def.h
+comp_scan.So: term.h
+comp_scan.So: unctrl.h
+comp_scan.o: curses.h
+comp_scan.o: ncurses_def.h
+comp_scan.o: term.h
+comp_scan.o: unctrl.h
+comp_scan.po: curses.h
+comp_scan.po: ncurses_def.h
+comp_scan.po: term.h
+comp_scan.po: unctrl.h
+db_iterator.So: curses.h
+db_iterator.So: ncurses_def.h
+db_iterator.So: term.h
+db_iterator.So: unctrl.h
+db_iterator.o: curses.h
+db_iterator.o: ncurses_def.h
+db_iterator.o: term.h
+db_iterator.o: unctrl.h
+db_iterator.po: curses.h
+db_iterator.po: ncurses_def.h
+db_iterator.po: term.h
+db_iterator.po: unctrl.h
+define_key.So: curses.h
+define_key.So: ncurses_def.h
+define_key.So: term.h
+define_key.So: unctrl.h
+define_key.o: curses.h
+define_key.o: ncurses_def.h
+define_key.o: term.h
+define_key.o: unctrl.h
+define_key.po: curses.h
+define_key.po: ncurses_def.h
+define_key.po: term.h
+define_key.po: unctrl.h
+doalloc.So: curses.h
+doalloc.So: ncurses_def.h
+doalloc.So: term.h
+doalloc.So: unctrl.h
+doalloc.o: curses.h
+doalloc.o: ncurses_def.h
+doalloc.o: term.h
+doalloc.o: unctrl.h
+doalloc.po: curses.h
+doalloc.po: ncurses_def.h
+doalloc.po: term.h
+doalloc.po: unctrl.h
+entries.So: curses.h
+entries.So: ncurses_def.h
+entries.So: term.h
+entries.So: unctrl.h
+entries.o: curses.h
+entries.o: ncurses_def.h
+entries.o: term.h
+entries.o: unctrl.h
+entries.po: curses.h
+entries.po: ncurses_def.h
+entries.po: term.h
+entries.po: unctrl.h
+expanded.So: curses.h
+expanded.So: expanded.c
+expanded.So: ncurses_def.h
+expanded.So: term.h
+expanded.So: unctrl.h
+expanded.o: curses.h
+expanded.o: expanded.c
+expanded.o: ncurses_def.h
+expanded.o: term.h
+expanded.o: unctrl.h
+expanded.po: curses.h
+expanded.po: expanded.c
+expanded.po: ncurses_def.h
+expanded.po: term.h
+expanded.po: unctrl.h
+fallback.So: curses.h
+fallback.So: fallback.c
+fallback.So: ncurses_def.h
+fallback.So: term.h
+fallback.So: unctrl.h
+fallback.o: curses.h
+fallback.o: fallback.c
+fallback.o: ncurses_def.h
+fallback.o: term.h
+fallback.o: unctrl.h
+fallback.po: curses.h
+fallback.po: fallback.c
+fallback.po: ncurses_def.h
+fallback.po: term.h
+fallback.po: unctrl.h
+free_ttype.So: curses.h
+free_ttype.So: ncurses_def.h
+free_ttype.So: term.h
+free_ttype.So: unctrl.h
+free_ttype.o: curses.h
+free_ttype.o: ncurses_def.h
+free_ttype.o: term.h
+free_ttype.o: unctrl.h
+free_ttype.po: curses.h
+free_ttype.po: ncurses_def.h
+free_ttype.po: term.h
+free_ttype.po: unctrl.h
+getenv_num.So: curses.h
+getenv_num.So: ncurses_def.h
+getenv_num.So: term.h
+getenv_num.So: unctrl.h
+getenv_num.o: curses.h
+getenv_num.o: ncurses_def.h
+getenv_num.o: term.h
+getenv_num.o: unctrl.h
+getenv_num.po: curses.h
+getenv_num.po: ncurses_def.h
+getenv_num.po: term.h
+getenv_num.po: unctrl.h
+hardscroll.So: curses.h
+hardscroll.So: ncurses_def.h
+hardscroll.So: term.h
+hardscroll.So: unctrl.h
+hardscroll.o: curses.h
+hardscroll.o: ncurses_def.h
+hardscroll.o: term.h
+hardscroll.o: unctrl.h
+hardscroll.po: curses.h
+hardscroll.po: ncurses_def.h
+hardscroll.po: term.h
+hardscroll.po: unctrl.h
+hashed_db.So: curses.h
+hashed_db.So: ncurses_def.h
+hashed_db.So: term.h
+hashed_db.So: unctrl.h
+hashed_db.o: curses.h
+hashed_db.o: ncurses_def.h
+hashed_db.o: term.h
+hashed_db.o: unctrl.h
+hashed_db.po: curses.h
+hashed_db.po: ncurses_def.h
+hashed_db.po: term.h
+hashed_db.po: unctrl.h
+hashmap.So: curses.h
+hashmap.So: ncurses_def.h
+hashmap.So: term.h
+hashmap.So: unctrl.h
+hashmap.o: curses.h
+hashmap.o: ncurses_def.h
+hashmap.o: term.h
+hashmap.o: unctrl.h
+hashmap.po: curses.h
+hashmap.po: ncurses_def.h
+hashmap.po: term.h
+hashmap.po: unctrl.h
+home_terminfo.So: curses.h
+home_terminfo.So: ncurses_def.h
+home_terminfo.So: term.h
+home_terminfo.So: unctrl.h
+home_terminfo.o: curses.h
+home_terminfo.o: ncurses_def.h
+home_terminfo.o: term.h
+home_terminfo.o: unctrl.h
+home_terminfo.po: curses.h
+home_terminfo.po: ncurses_def.h
+home_terminfo.po: term.h
+home_terminfo.po: unctrl.h
+init_keytry.So: curses.h
+init_keytry.So: init_keytry.h
+init_keytry.So: ncurses_def.h
+init_keytry.So: term.h
+init_keytry.So: unctrl.h
+init_keytry.o: curses.h
+init_keytry.o: init_keytry.h
+init_keytry.o: ncurses_def.h
+init_keytry.o: term.h
+init_keytry.o: unctrl.h
+init_keytry.po: curses.h
+init_keytry.po: init_keytry.h
+init_keytry.po: ncurses_def.h
+init_keytry.po: term.h
+init_keytry.po: unctrl.h
+key_defined.So: curses.h
+key_defined.So: ncurses_def.h
+key_defined.So: term.h
+key_defined.So: unctrl.h
+key_defined.o: curses.h
+key_defined.o: ncurses_def.h
+key_defined.o: term.h
+key_defined.o: unctrl.h
+key_defined.po: curses.h
+key_defined.po: ncurses_def.h
+key_defined.po: term.h
+key_defined.po: unctrl.h
+keybound.So: curses.h
+keybound.So: ncurses_def.h
+keybound.So: term.h
+keybound.So: unctrl.h
+keybound.o: curses.h
+keybound.o: ncurses_def.h
+keybound.o: term.h
+keybound.o: unctrl.h
+keybound.po: curses.h
+keybound.po: ncurses_def.h
+keybound.po: term.h
+keybound.po: unctrl.h
+keyok.So: curses.h
+keyok.So: ncurses_def.h
+keyok.So: term.h
+keyok.So: unctrl.h
+keyok.o: curses.h
+keyok.o: ncurses_def.h
+keyok.o: term.h
+keyok.o: unctrl.h
+keyok.po: curses.h
+keyok.po: ncurses_def.h
+keyok.po: term.h
+keyok.po: unctrl.h
+legacy_coding.So: curses.h
+legacy_coding.So: ncurses_def.h
+legacy_coding.So: term.h
+legacy_coding.So: unctrl.h
+legacy_coding.o: curses.h
+legacy_coding.o: ncurses_def.h
+legacy_coding.o: term.h
+legacy_coding.o: unctrl.h
+legacy_coding.po: curses.h
+legacy_coding.po: ncurses_def.h
+legacy_coding.po: term.h
+legacy_coding.po: unctrl.h
+lib_acs.So: curses.h
+lib_acs.So: ncurses_def.h
+lib_acs.So: term.h
+lib_acs.So: unctrl.h
+lib_acs.o: curses.h
+lib_acs.o: ncurses_def.h
+lib_acs.o: term.h
+lib_acs.o: unctrl.h
+lib_acs.po: curses.h
+lib_acs.po: ncurses_def.h
+lib_acs.po: term.h
+lib_acs.po: unctrl.h
+lib_add_wch.So: curses.h
+lib_add_wch.So: ncurses_def.h
+lib_add_wch.So: term.h
+lib_add_wch.So: unctrl.h
+lib_add_wch.o: curses.h
+lib_add_wch.o: ncurses_def.h
+lib_add_wch.o: term.h
+lib_add_wch.o: unctrl.h
+lib_add_wch.po: curses.h
+lib_add_wch.po: ncurses_def.h
+lib_add_wch.po: term.h
+lib_add_wch.po: unctrl.h
+lib_addch.So: curses.h
+lib_addch.So: ncurses_def.h
+lib_addch.So: term.h
+lib_addch.So: unctrl.h
+lib_addch.o: curses.h
+lib_addch.o: ncurses_def.h
+lib_addch.o: term.h
+lib_addch.o: unctrl.h
+lib_addch.po: curses.h
+lib_addch.po: ncurses_def.h
+lib_addch.po: term.h
+lib_addch.po: unctrl.h
+lib_addstr.So: curses.h
+lib_addstr.So: ncurses_def.h
+lib_addstr.So: term.h
+lib_addstr.So: unctrl.h
+lib_addstr.o: curses.h
+lib_addstr.o: ncurses_def.h
+lib_addstr.o: term.h
+lib_addstr.o: unctrl.h
+lib_addstr.po: curses.h
+lib_addstr.po: ncurses_def.h
+lib_addstr.po: term.h
+lib_addstr.po: unctrl.h
+lib_baudrate.So: curses.h
+lib_baudrate.So: ncurses_def.h
+lib_baudrate.So: term.h
+lib_baudrate.So: termcap.h
+lib_baudrate.So: unctrl.h
+lib_baudrate.o: curses.h
+lib_baudrate.o: ncurses_def.h
+lib_baudrate.o: term.h
+lib_baudrate.o: termcap.h
+lib_baudrate.o: unctrl.h
+lib_baudrate.po: curses.h
+lib_baudrate.po: ncurses_def.h
+lib_baudrate.po: term.h
+lib_baudrate.po: termcap.h
+lib_baudrate.po: unctrl.h
+lib_beep.So: curses.h
+lib_beep.So: ncurses_def.h
+lib_beep.So: term.h
+lib_beep.So: unctrl.h
+lib_beep.o: curses.h
+lib_beep.o: ncurses_def.h
+lib_beep.o: term.h
+lib_beep.o: unctrl.h
+lib_beep.po: curses.h
+lib_beep.po: ncurses_def.h
+lib_beep.po: term.h
+lib_beep.po: unctrl.h
+lib_bkgd.So: curses.h
+lib_bkgd.So: ncurses_def.h
+lib_bkgd.So: term.h
+lib_bkgd.So: unctrl.h
+lib_bkgd.o: curses.h
+lib_bkgd.o: ncurses_def.h
+lib_bkgd.o: term.h
+lib_bkgd.o: unctrl.h
+lib_bkgd.po: curses.h
+lib_bkgd.po: ncurses_def.h
+lib_bkgd.po: term.h
+lib_bkgd.po: unctrl.h
+lib_box.So: curses.h
+lib_box.So: ncurses_def.h
+lib_box.So: term.h
+lib_box.So: unctrl.h
+lib_box.o: curses.h
+lib_box.o: ncurses_def.h
+lib_box.o: term.h
+lib_box.o: unctrl.h
+lib_box.po: curses.h
+lib_box.po: ncurses_def.h
+lib_box.po: term.h
+lib_box.po: unctrl.h
+lib_box_set.So: curses.h
+lib_box_set.So: ncurses_def.h
+lib_box_set.So: term.h
+lib_box_set.So: unctrl.h
+lib_box_set.o: curses.h
+lib_box_set.o: ncurses_def.h
+lib_box_set.o: term.h
+lib_box_set.o: unctrl.h
+lib_box_set.po: curses.h
+lib_box_set.po: ncurses_def.h
+lib_box_set.po: term.h
+lib_box_set.po: unctrl.h
+lib_cchar.So: curses.h
+lib_cchar.So: ncurses_def.h
+lib_cchar.So: term.h
+lib_cchar.So: unctrl.h
+lib_cchar.o: curses.h
+lib_cchar.o: ncurses_def.h
+lib_cchar.o: term.h
+lib_cchar.o: unctrl.h
+lib_cchar.po: curses.h
+lib_cchar.po: ncurses_def.h
+lib_cchar.po: term.h
+lib_cchar.po: unctrl.h
+lib_chgat.So: curses.h
+lib_chgat.So: ncurses_def.h
+lib_chgat.So: term.h
+lib_chgat.So: unctrl.h
+lib_chgat.o: curses.h
+lib_chgat.o: ncurses_def.h
+lib_chgat.o: term.h
+lib_chgat.o: unctrl.h
+lib_chgat.po: curses.h
+lib_chgat.po: ncurses_def.h
+lib_chgat.po: term.h
+lib_chgat.po: unctrl.h
+lib_clear.So: curses.h
+lib_clear.So: ncurses_def.h
+lib_clear.So: term.h
+lib_clear.So: unctrl.h
+lib_clear.o: curses.h
+lib_clear.o: ncurses_def.h
+lib_clear.o: term.h
+lib_clear.o: unctrl.h
+lib_clear.po: curses.h
+lib_clear.po: ncurses_def.h
+lib_clear.po: term.h
+lib_clear.po: unctrl.h
+lib_clearok.So: curses.h
+lib_clearok.So: ncurses_def.h
+lib_clearok.So: term.h
+lib_clearok.So: unctrl.h
+lib_clearok.o: curses.h
+lib_clearok.o: ncurses_def.h
+lib_clearok.o: term.h
+lib_clearok.o: unctrl.h
+lib_clearok.po: curses.h
+lib_clearok.po: ncurses_def.h
+lib_clearok.po: term.h
+lib_clearok.po: unctrl.h
+lib_clrbot.So: curses.h
+lib_clrbot.So: ncurses_def.h
+lib_clrbot.So: term.h
+lib_clrbot.So: unctrl.h
+lib_clrbot.o: curses.h
+lib_clrbot.o: ncurses_def.h
+lib_clrbot.o: term.h
+lib_clrbot.o: unctrl.h
+lib_clrbot.po: curses.h
+lib_clrbot.po: ncurses_def.h
+lib_clrbot.po: term.h
+lib_clrbot.po: unctrl.h
+lib_clreol.So: curses.h
+lib_clreol.So: ncurses_def.h
+lib_clreol.So: term.h
+lib_clreol.So: unctrl.h
+lib_clreol.o: curses.h
+lib_clreol.o: ncurses_def.h
+lib_clreol.o: term.h
+lib_clreol.o: unctrl.h
+lib_clreol.po: curses.h
+lib_clreol.po: ncurses_def.h
+lib_clreol.po: term.h
+lib_clreol.po: unctrl.h
+lib_color.So: curses.h
+lib_color.So: ncurses_def.h
+lib_color.So: term.h
+lib_color.So: unctrl.h
+lib_color.o: curses.h
+lib_color.o: ncurses_def.h
+lib_color.o: term.h
+lib_color.o: unctrl.h
+lib_color.po: curses.h
+lib_color.po: ncurses_def.h
+lib_color.po: term.h
+lib_color.po: unctrl.h
+lib_colorset.So: curses.h
+lib_colorset.So: ncurses_def.h
+lib_colorset.So: term.h
+lib_colorset.So: unctrl.h
+lib_colorset.o: curses.h
+lib_colorset.o: ncurses_def.h
+lib_colorset.o: term.h
+lib_colorset.o: unctrl.h
+lib_colorset.po: curses.h
+lib_colorset.po: ncurses_def.h
+lib_colorset.po: term.h
+lib_colorset.po: unctrl.h
+lib_cur_term.So: curses.h
+lib_cur_term.So: ncurses_def.h
+lib_cur_term.So: term.h
+lib_cur_term.So: termcap.h
+lib_cur_term.So: unctrl.h
+lib_cur_term.o: curses.h
+lib_cur_term.o: ncurses_def.h
+lib_cur_term.o: term.h
+lib_cur_term.o: termcap.h
+lib_cur_term.o: unctrl.h
+lib_cur_term.po: curses.h
+lib_cur_term.po: ncurses_def.h
+lib_cur_term.po: term.h
+lib_cur_term.po: termcap.h
+lib_cur_term.po: unctrl.h
+lib_data.So: curses.h
+lib_data.So: ncurses_def.h
+lib_data.So: term.h
+lib_data.So: unctrl.h
+lib_data.o: curses.h
+lib_data.o: ncurses_def.h
+lib_data.o: term.h
+lib_data.o: unctrl.h
+lib_data.po: curses.h
+lib_data.po: ncurses_def.h
+lib_data.po: term.h
+lib_data.po: unctrl.h
+lib_delch.So: curses.h
+lib_delch.So: ncurses_def.h
+lib_delch.So: term.h
+lib_delch.So: unctrl.h
+lib_delch.o: curses.h
+lib_delch.o: ncurses_def.h
+lib_delch.o: term.h
+lib_delch.o: unctrl.h
+lib_delch.po: curses.h
+lib_delch.po: ncurses_def.h
+lib_delch.po: term.h
+lib_delch.po: unctrl.h
+lib_delwin.So: curses.h
+lib_delwin.So: ncurses_def.h
+lib_delwin.So: term.h
+lib_delwin.So: unctrl.h
+lib_delwin.o: curses.h
+lib_delwin.o: ncurses_def.h
+lib_delwin.o: term.h
+lib_delwin.o: unctrl.h
+lib_delwin.po: curses.h
+lib_delwin.po: ncurses_def.h
+lib_delwin.po: term.h
+lib_delwin.po: unctrl.h
+lib_dft_fgbg.So: curses.h
+lib_dft_fgbg.So: ncurses_def.h
+lib_dft_fgbg.So: term.h
+lib_dft_fgbg.So: unctrl.h
+lib_dft_fgbg.o: curses.h
+lib_dft_fgbg.o: ncurses_def.h
+lib_dft_fgbg.o: term.h
+lib_dft_fgbg.o: unctrl.h
+lib_dft_fgbg.po: curses.h
+lib_dft_fgbg.po: ncurses_def.h
+lib_dft_fgbg.po: term.h
+lib_dft_fgbg.po: unctrl.h
+lib_echo.So: curses.h
+lib_echo.So: ncurses_def.h
+lib_echo.So: term.h
+lib_echo.So: unctrl.h
+lib_echo.o: curses.h
+lib_echo.o: ncurses_def.h
+lib_echo.o: term.h
+lib_echo.o: unctrl.h
+lib_echo.po: curses.h
+lib_echo.po: ncurses_def.h
+lib_echo.po: term.h
+lib_echo.po: unctrl.h
+lib_endwin.So: curses.h
+lib_endwin.So: ncurses_def.h
+lib_endwin.So: term.h
+lib_endwin.So: unctrl.h
+lib_endwin.o: curses.h
+lib_endwin.o: ncurses_def.h
+lib_endwin.o: term.h
+lib_endwin.o: unctrl.h
+lib_endwin.po: curses.h
+lib_endwin.po: ncurses_def.h
+lib_endwin.po: term.h
+lib_endwin.po: unctrl.h
+lib_erase.So: curses.h
+lib_erase.So: ncurses_def.h
+lib_erase.So: term.h
+lib_erase.So: unctrl.h
+lib_erase.o: curses.h
+lib_erase.o: ncurses_def.h
+lib_erase.o: term.h
+lib_erase.o: unctrl.h
+lib_erase.po: curses.h
+lib_erase.po: ncurses_def.h
+lib_erase.po: term.h
+lib_erase.po: unctrl.h
+lib_erasewchar.So: curses.h
+lib_erasewchar.So: ncurses_def.h
+lib_erasewchar.So: term.h
+lib_erasewchar.So: unctrl.h
+lib_erasewchar.o: curses.h
+lib_erasewchar.o: ncurses_def.h
+lib_erasewchar.o: term.h
+lib_erasewchar.o: unctrl.h
+lib_erasewchar.po: curses.h
+lib_erasewchar.po: ncurses_def.h
+lib_erasewchar.po: term.h
+lib_erasewchar.po: unctrl.h
+lib_flash.So: curses.h
+lib_flash.So: ncurses_def.h
+lib_flash.So: term.h
+lib_flash.So: unctrl.h
+lib_flash.o: curses.h
+lib_flash.o: ncurses_def.h
+lib_flash.o: term.h
+lib_flash.o: unctrl.h
+lib_flash.po: curses.h
+lib_flash.po: ncurses_def.h
+lib_flash.po: term.h
+lib_flash.po: unctrl.h
+lib_freeall.So: curses.h
+lib_freeall.So: ncurses_def.h
+lib_freeall.So: term.h
+lib_freeall.So: unctrl.h
+lib_freeall.o: curses.h
+lib_freeall.o: ncurses_def.h
+lib_freeall.o: term.h
+lib_freeall.o: unctrl.h
+lib_freeall.po: curses.h
+lib_freeall.po: ncurses_def.h
+lib_freeall.po: term.h
+lib_freeall.po: unctrl.h
+lib_gen.So: curses.h
+lib_gen.So: lib_gen.c
+lib_gen.So: ncurses_def.h
+lib_gen.So: term.h
+lib_gen.So: unctrl.h
+lib_gen.o: curses.h
+lib_gen.o: lib_gen.c
+lib_gen.o: ncurses_def.h
+lib_gen.o: term.h
+lib_gen.o: unctrl.h
+lib_gen.po: curses.h
+lib_gen.po: lib_gen.c
+lib_gen.po: ncurses_def.h
+lib_gen.po: term.h
+lib_gen.po: unctrl.h
+lib_get_wch.So: curses.h
+lib_get_wch.So: ncurses_def.h
+lib_get_wch.So: term.h
+lib_get_wch.So: unctrl.h
+lib_get_wch.o: curses.h
+lib_get_wch.o: ncurses_def.h
+lib_get_wch.o: term.h
+lib_get_wch.o: unctrl.h
+lib_get_wch.po: curses.h
+lib_get_wch.po: ncurses_def.h
+lib_get_wch.po: term.h
+lib_get_wch.po: unctrl.h
+lib_get_wstr.So: curses.h
+lib_get_wstr.So: ncurses_def.h
+lib_get_wstr.So: term.h
+lib_get_wstr.So: unctrl.h
+lib_get_wstr.o: curses.h
+lib_get_wstr.o: ncurses_def.h
+lib_get_wstr.o: term.h
+lib_get_wstr.o: unctrl.h
+lib_get_wstr.po: curses.h
+lib_get_wstr.po: ncurses_def.h
+lib_get_wstr.po: term.h
+lib_get_wstr.po: unctrl.h
+lib_getch.So: curses.h
+lib_getch.So: ncurses_def.h
+lib_getch.So: term.h
+lib_getch.So: unctrl.h
+lib_getch.o: curses.h
+lib_getch.o: ncurses_def.h
+lib_getch.o: term.h
+lib_getch.o: unctrl.h
+lib_getch.po: curses.h
+lib_getch.po: ncurses_def.h
+lib_getch.po: term.h
+lib_getch.po: unctrl.h
+lib_getstr.So: curses.h
+lib_getstr.So: ncurses_def.h
+lib_getstr.So: term.h
+lib_getstr.So: unctrl.h
+lib_getstr.o: curses.h
+lib_getstr.o: ncurses_def.h
+lib_getstr.o: term.h
+lib_getstr.o: unctrl.h
+lib_getstr.po: curses.h
+lib_getstr.po: ncurses_def.h
+lib_getstr.po: term.h
+lib_getstr.po: unctrl.h
+lib_has_cap.So: curses.h
+lib_has_cap.So: ncurses_def.h
+lib_has_cap.So: term.h
+lib_has_cap.So: unctrl.h
+lib_has_cap.o: curses.h
+lib_has_cap.o: ncurses_def.h
+lib_has_cap.o: term.h
+lib_has_cap.o: unctrl.h
+lib_has_cap.po: curses.h
+lib_has_cap.po: ncurses_def.h
+lib_has_cap.po: term.h
+lib_has_cap.po: unctrl.h
+lib_hline.So: curses.h
+lib_hline.So: ncurses_def.h
+lib_hline.So: term.h
+lib_hline.So: unctrl.h
+lib_hline.o: curses.h
+lib_hline.o: ncurses_def.h
+lib_hline.o: term.h
+lib_hline.o: unctrl.h
+lib_hline.po: curses.h
+lib_hline.po: ncurses_def.h
+lib_hline.po: term.h
+lib_hline.po: unctrl.h
+lib_hline_set.So: curses.h
+lib_hline_set.So: ncurses_def.h
+lib_hline_set.So: term.h
+lib_hline_set.So: unctrl.h
+lib_hline_set.o: curses.h
+lib_hline_set.o: ncurses_def.h
+lib_hline_set.o: term.h
+lib_hline_set.o: unctrl.h
+lib_hline_set.po: curses.h
+lib_hline_set.po: ncurses_def.h
+lib_hline_set.po: term.h
+lib_hline_set.po: unctrl.h
+lib_immedok.So: curses.h
+lib_immedok.So: ncurses_def.h
+lib_immedok.So: term.h
+lib_immedok.So: unctrl.h
+lib_immedok.o: curses.h
+lib_immedok.o: ncurses_def.h
+lib_immedok.o: term.h
+lib_immedok.o: unctrl.h
+lib_immedok.po: curses.h
+lib_immedok.po: ncurses_def.h
+lib_immedok.po: term.h
+lib_immedok.po: unctrl.h
+lib_in_wch.So: curses.h
+lib_in_wch.So: ncurses_def.h
+lib_in_wch.So: term.h
+lib_in_wch.So: unctrl.h
+lib_in_wch.o: curses.h
+lib_in_wch.o: ncurses_def.h
+lib_in_wch.o: term.h
+lib_in_wch.o: unctrl.h
+lib_in_wch.po: curses.h
+lib_in_wch.po: ncurses_def.h
+lib_in_wch.po: term.h
+lib_in_wch.po: unctrl.h
+lib_in_wchnstr.So: curses.h
+lib_in_wchnstr.So: ncurses_def.h
+lib_in_wchnstr.So: term.h
+lib_in_wchnstr.So: unctrl.h
+lib_in_wchnstr.o: curses.h
+lib_in_wchnstr.o: ncurses_def.h
+lib_in_wchnstr.o: term.h
+lib_in_wchnstr.o: unctrl.h
+lib_in_wchnstr.po: curses.h
+lib_in_wchnstr.po: ncurses_def.h
+lib_in_wchnstr.po: term.h
+lib_in_wchnstr.po: unctrl.h
+lib_inchstr.So: curses.h
+lib_inchstr.So: ncurses_def.h
+lib_inchstr.So: term.h
+lib_inchstr.So: unctrl.h
+lib_inchstr.o: curses.h
+lib_inchstr.o: ncurses_def.h
+lib_inchstr.o: term.h
+lib_inchstr.o: unctrl.h
+lib_inchstr.po: curses.h
+lib_inchstr.po: ncurses_def.h
+lib_inchstr.po: term.h
+lib_inchstr.po: unctrl.h
+lib_initscr.So: curses.h
+lib_initscr.So: ncurses_def.h
+lib_initscr.So: term.h
+lib_initscr.So: unctrl.h
+lib_initscr.o: curses.h
+lib_initscr.o: ncurses_def.h
+lib_initscr.o: term.h
+lib_initscr.o: unctrl.h
+lib_initscr.po: curses.h
+lib_initscr.po: ncurses_def.h
+lib_initscr.po: term.h
+lib_initscr.po: unctrl.h
+lib_ins_wch.So: curses.h
+lib_ins_wch.So: ncurses_def.h
+lib_ins_wch.So: term.h
+lib_ins_wch.So: unctrl.h
+lib_ins_wch.o: curses.h
+lib_ins_wch.o: ncurses_def.h
+lib_ins_wch.o: term.h
+lib_ins_wch.o: unctrl.h
+lib_ins_wch.po: curses.h
+lib_ins_wch.po: ncurses_def.h
+lib_ins_wch.po: term.h
+lib_ins_wch.po: unctrl.h
+lib_insch.So: curses.h
+lib_insch.So: ncurses_def.h
+lib_insch.So: term.h
+lib_insch.So: unctrl.h
+lib_insch.o: curses.h
+lib_insch.o: ncurses_def.h
+lib_insch.o: term.h
+lib_insch.o: unctrl.h
+lib_insch.po: curses.h
+lib_insch.po: ncurses_def.h
+lib_insch.po: term.h
+lib_insch.po: unctrl.h
+lib_insdel.So: curses.h
+lib_insdel.So: ncurses_def.h
+lib_insdel.So: term.h
+lib_insdel.So: unctrl.h
+lib_insdel.o: curses.h
+lib_insdel.o: ncurses_def.h
+lib_insdel.o: term.h
+lib_insdel.o: unctrl.h
+lib_insdel.po: curses.h
+lib_insdel.po: ncurses_def.h
+lib_insdel.po: term.h
+lib_insdel.po: unctrl.h
+lib_insnstr.So: curses.h
+lib_insnstr.So: ncurses_def.h
+lib_insnstr.So: term.h
+lib_insnstr.So: unctrl.h
+lib_insnstr.o: curses.h
+lib_insnstr.o: ncurses_def.h
+lib_insnstr.o: term.h
+lib_insnstr.o: unctrl.h
+lib_insnstr.po: curses.h
+lib_insnstr.po: ncurses_def.h
+lib_insnstr.po: term.h
+lib_insnstr.po: unctrl.h
+lib_instr.So: curses.h
+lib_instr.So: ncurses_def.h
+lib_instr.So: term.h
+lib_instr.So: unctrl.h
+lib_instr.o: curses.h
+lib_instr.o: ncurses_def.h
+lib_instr.o: term.h
+lib_instr.o: unctrl.h
+lib_instr.po: curses.h
+lib_instr.po: ncurses_def.h
+lib_instr.po: term.h
+lib_instr.po: unctrl.h
+lib_inwstr.So: curses.h
+lib_inwstr.So: ncurses_def.h
+lib_inwstr.So: term.h
+lib_inwstr.So: unctrl.h
+lib_inwstr.o: curses.h
+lib_inwstr.o: ncurses_def.h
+lib_inwstr.o: term.h
+lib_inwstr.o: unctrl.h
+lib_inwstr.po: curses.h
+lib_inwstr.po: ncurses_def.h
+lib_inwstr.po: term.h
+lib_inwstr.po: unctrl.h
+lib_isendwin.So: curses.h
+lib_isendwin.So: ncurses_def.h
+lib_isendwin.So: term.h
+lib_isendwin.So: unctrl.h
+lib_isendwin.o: curses.h
+lib_isendwin.o: ncurses_def.h
+lib_isendwin.o: term.h
+lib_isendwin.o: unctrl.h
+lib_isendwin.po: curses.h
+lib_isendwin.po: ncurses_def.h
+lib_isendwin.po: term.h
+lib_isendwin.po: unctrl.h
+lib_kernel.So: curses.h
+lib_kernel.So: ncurses_def.h
+lib_kernel.So: term.h
+lib_kernel.So: unctrl.h
+lib_kernel.o: curses.h
+lib_kernel.o: ncurses_def.h
+lib_kernel.o: term.h
+lib_kernel.o: unctrl.h
+lib_kernel.po: curses.h
+lib_kernel.po: ncurses_def.h
+lib_kernel.po: term.h
+lib_kernel.po: unctrl.h
+lib_key_name.So: curses.h
+lib_key_name.So: ncurses_def.h
+lib_key_name.So: term.h
+lib_key_name.So: unctrl.h
+lib_key_name.o: curses.h
+lib_key_name.o: ncurses_def.h
+lib_key_name.o: term.h
+lib_key_name.o: unctrl.h
+lib_key_name.po: curses.h
+lib_key_name.po: ncurses_def.h
+lib_key_name.po: term.h
+lib_key_name.po: unctrl.h
+lib_keyname.So: curses.h
+lib_keyname.So: lib_keyname.c
+lib_keyname.So: ncurses_def.h
+lib_keyname.So: term.h
+lib_keyname.So: unctrl.h
+lib_keyname.o: curses.h
+lib_keyname.o: lib_keyname.c
+lib_keyname.o: ncurses_def.h
+lib_keyname.o: term.h
+lib_keyname.o: unctrl.h
+lib_keyname.po: curses.h
+lib_keyname.po: lib_keyname.c
+lib_keyname.po: ncurses_def.h
+lib_keyname.po: term.h
+lib_keyname.po: unctrl.h
+lib_leaveok.So: curses.h
+lib_leaveok.So: ncurses_def.h
+lib_leaveok.So: term.h
+lib_leaveok.So: unctrl.h
+lib_leaveok.o: curses.h
+lib_leaveok.o: ncurses_def.h
+lib_leaveok.o: term.h
+lib_leaveok.o: unctrl.h
+lib_leaveok.po: curses.h
+lib_leaveok.po: ncurses_def.h
+lib_leaveok.po: term.h
+lib_leaveok.po: unctrl.h
+lib_longname.So: curses.h
+lib_longname.So: ncurses_def.h
+lib_longname.So: term.h
+lib_longname.So: unctrl.h
+lib_longname.o: curses.h
+lib_longname.o: ncurses_def.h
+lib_longname.o: term.h
+lib_longname.o: unctrl.h
+lib_longname.po: curses.h
+lib_longname.po: ncurses_def.h
+lib_longname.po: term.h
+lib_longname.po: unctrl.h
+lib_mouse.So: curses.h
+lib_mouse.So: ncurses_def.h
+lib_mouse.So: term.h
+lib_mouse.So: unctrl.h
+lib_mouse.o: curses.h
+lib_mouse.o: ncurses_def.h
+lib_mouse.o: term.h
+lib_mouse.o: unctrl.h
+lib_mouse.po: curses.h
+lib_mouse.po: ncurses_def.h
+lib_mouse.po: term.h
+lib_mouse.po: unctrl.h
+lib_move.So: curses.h
+lib_move.So: ncurses_def.h
+lib_move.So: term.h
+lib_move.So: unctrl.h
+lib_move.o: curses.h
+lib_move.o: ncurses_def.h
+lib_move.o: term.h
+lib_move.o: unctrl.h
+lib_move.po: curses.h
+lib_move.po: ncurses_def.h
+lib_move.po: term.h
+lib_move.po: unctrl.h
+lib_mvcur.So: curses.h
+lib_mvcur.So: ncurses_def.h
+lib_mvcur.So: term.h
+lib_mvcur.So: unctrl.h
+lib_mvcur.o: curses.h
+lib_mvcur.o: ncurses_def.h
+lib_mvcur.o: term.h
+lib_mvcur.o: unctrl.h
+lib_mvcur.po: curses.h
+lib_mvcur.po: ncurses_def.h
+lib_mvcur.po: term.h
+lib_mvcur.po: unctrl.h
+lib_mvwin.So: curses.h
+lib_mvwin.So: ncurses_def.h
+lib_mvwin.So: term.h
+lib_mvwin.So: unctrl.h
+lib_mvwin.o: curses.h
+lib_mvwin.o: ncurses_def.h
+lib_mvwin.o: term.h
+lib_mvwin.o: unctrl.h
+lib_mvwin.po: curses.h
+lib_mvwin.po: ncurses_def.h
+lib_mvwin.po: term.h
+lib_mvwin.po: unctrl.h
+lib_napms.So: curses.h
+lib_napms.So: ncurses_def.h
+lib_napms.So: term.h
+lib_napms.So: unctrl.h
+lib_napms.o: curses.h
+lib_napms.o: ncurses_def.h
+lib_napms.o: term.h
+lib_napms.o: unctrl.h
+lib_napms.po: curses.h
+lib_napms.po: ncurses_def.h
+lib_napms.po: term.h
+lib_napms.po: unctrl.h
+lib_newterm.So: curses.h
+lib_newterm.So: ncurses_def.h
+lib_newterm.So: term.h
+lib_newterm.So: unctrl.h
+lib_newterm.o: curses.h
+lib_newterm.o: ncurses_def.h
+lib_newterm.o: term.h
+lib_newterm.o: unctrl.h
+lib_newterm.po: curses.h
+lib_newterm.po: ncurses_def.h
+lib_newterm.po: term.h
+lib_newterm.po: unctrl.h
+lib_newwin.So: curses.h
+lib_newwin.So: ncurses_def.h
+lib_newwin.So: term.h
+lib_newwin.So: unctrl.h
+lib_newwin.o: curses.h
+lib_newwin.o: ncurses_def.h
+lib_newwin.o: term.h
+lib_newwin.o: unctrl.h
+lib_newwin.po: curses.h
+lib_newwin.po: ncurses_def.h
+lib_newwin.po: term.h
+lib_newwin.po: unctrl.h
+lib_nl.So: curses.h
+lib_nl.So: ncurses_def.h
+lib_nl.So: term.h
+lib_nl.So: unctrl.h
+lib_nl.o: curses.h
+lib_nl.o: ncurses_def.h
+lib_nl.o: term.h
+lib_nl.o: unctrl.h
+lib_nl.po: curses.h
+lib_nl.po: ncurses_def.h
+lib_nl.po: term.h
+lib_nl.po: unctrl.h
+lib_options.So: curses.h
+lib_options.So: ncurses_def.h
+lib_options.So: term.h
+lib_options.So: unctrl.h
+lib_options.o: curses.h
+lib_options.o: ncurses_def.h
+lib_options.o: term.h
+lib_options.o: unctrl.h
+lib_options.po: curses.h
+lib_options.po: ncurses_def.h
+lib_options.po: term.h
+lib_options.po: unctrl.h
+lib_overlay.So: curses.h
+lib_overlay.So: ncurses_def.h
+lib_overlay.So: term.h
+lib_overlay.So: unctrl.h
+lib_overlay.o: curses.h
+lib_overlay.o: ncurses_def.h
+lib_overlay.o: term.h
+lib_overlay.o: unctrl.h
+lib_overlay.po: curses.h
+lib_overlay.po: ncurses_def.h
+lib_overlay.po: term.h
+lib_overlay.po: unctrl.h
+lib_pad.So: curses.h
+lib_pad.So: ncurses_def.h
+lib_pad.So: term.h
+lib_pad.So: unctrl.h
+lib_pad.o: curses.h
+lib_pad.o: ncurses_def.h
+lib_pad.o: term.h
+lib_pad.o: unctrl.h
+lib_pad.po: curses.h
+lib_pad.po: ncurses_def.h
+lib_pad.po: term.h
+lib_pad.po: unctrl.h
+lib_pecho_wchar.So: curses.h
+lib_pecho_wchar.So: ncurses_def.h
+lib_pecho_wchar.So: term.h
+lib_pecho_wchar.So: unctrl.h
+lib_pecho_wchar.o: curses.h
+lib_pecho_wchar.o: ncurses_def.h
+lib_pecho_wchar.o: term.h
+lib_pecho_wchar.o: unctrl.h
+lib_pecho_wchar.po: curses.h
+lib_pecho_wchar.po: ncurses_def.h
+lib_pecho_wchar.po: term.h
+lib_pecho_wchar.po: unctrl.h
+lib_print.So: curses.h
+lib_print.So: ncurses_def.h
+lib_print.So: term.h
+lib_print.So: unctrl.h
+lib_print.o: curses.h
+lib_print.o: ncurses_def.h
+lib_print.o: term.h
+lib_print.o: unctrl.h
+lib_print.po: curses.h
+lib_print.po: ncurses_def.h
+lib_print.po: term.h
+lib_print.po: unctrl.h
+lib_printw.So: curses.h
+lib_printw.So: ncurses_def.h
+lib_printw.So: term.h
+lib_printw.So: unctrl.h
+lib_printw.o: curses.h
+lib_printw.o: ncurses_def.h
+lib_printw.o: term.h
+lib_printw.o: unctrl.h
+lib_printw.po: curses.h
+lib_printw.po: ncurses_def.h
+lib_printw.po: term.h
+lib_printw.po: unctrl.h
+lib_raw.So: curses.h
+lib_raw.So: ncurses_def.h
+lib_raw.So: term.h
+lib_raw.So: unctrl.h
+lib_raw.o: curses.h
+lib_raw.o: ncurses_def.h
+lib_raw.o: term.h
+lib_raw.o: unctrl.h
+lib_raw.po: curses.h
+lib_raw.po: ncurses_def.h
+lib_raw.po: term.h
+lib_raw.po: unctrl.h
+lib_redrawln.So: curses.h
+lib_redrawln.So: ncurses_def.h
+lib_redrawln.So: term.h
+lib_redrawln.So: unctrl.h
+lib_redrawln.o: curses.h
+lib_redrawln.o: ncurses_def.h
+lib_redrawln.o: term.h
+lib_redrawln.o: unctrl.h
+lib_redrawln.po: curses.h
+lib_redrawln.po: ncurses_def.h
+lib_redrawln.po: term.h
+lib_redrawln.po: unctrl.h
+lib_refresh.So: curses.h
+lib_refresh.So: ncurses_def.h
+lib_refresh.So: term.h
+lib_refresh.So: unctrl.h
+lib_refresh.o: curses.h
+lib_refresh.o: ncurses_def.h
+lib_refresh.o: term.h
+lib_refresh.o: unctrl.h
+lib_refresh.po: curses.h
+lib_refresh.po: ncurses_def.h
+lib_refresh.po: term.h
+lib_refresh.po: unctrl.h
+lib_restart.So: curses.h
+lib_restart.So: ncurses_def.h
+lib_restart.So: term.h
+lib_restart.So: unctrl.h
+lib_restart.o: curses.h
+lib_restart.o: ncurses_def.h
+lib_restart.o: term.h
+lib_restart.o: unctrl.h
+lib_restart.po: curses.h
+lib_restart.po: ncurses_def.h
+lib_restart.po: term.h
+lib_restart.po: unctrl.h
+lib_scanw.So: curses.h
+lib_scanw.So: ncurses_def.h
+lib_scanw.So: term.h
+lib_scanw.So: unctrl.h
+lib_scanw.o: curses.h
+lib_scanw.o: ncurses_def.h
+lib_scanw.o: term.h
+lib_scanw.o: unctrl.h
+lib_scanw.po: curses.h
+lib_scanw.po: ncurses_def.h
+lib_scanw.po: term.h
+lib_scanw.po: unctrl.h
+lib_screen.So: curses.h
+lib_screen.So: ncurses_def.h
+lib_screen.So: term.h
+lib_screen.So: unctrl.h
+lib_screen.o: curses.h
+lib_screen.o: ncurses_def.h
+lib_screen.o: term.h
+lib_screen.o: unctrl.h
+lib_screen.po: curses.h
+lib_screen.po: ncurses_def.h
+lib_screen.po: term.h
+lib_screen.po: unctrl.h
+lib_scroll.So: curses.h
+lib_scroll.So: ncurses_def.h
+lib_scroll.So: term.h
+lib_scroll.So: unctrl.h
+lib_scroll.o: curses.h
+lib_scroll.o: ncurses_def.h
+lib_scroll.o: term.h
+lib_scroll.o: unctrl.h
+lib_scroll.po: curses.h
+lib_scroll.po: ncurses_def.h
+lib_scroll.po: term.h
+lib_scroll.po: unctrl.h
+lib_scrollok.So: curses.h
+lib_scrollok.So: ncurses_def.h
+lib_scrollok.So: term.h
+lib_scrollok.So: unctrl.h
+lib_scrollok.o: curses.h
+lib_scrollok.o: ncurses_def.h
+lib_scrollok.o: term.h
+lib_scrollok.o: unctrl.h
+lib_scrollok.po: curses.h
+lib_scrollok.po: ncurses_def.h
+lib_scrollok.po: term.h
+lib_scrollok.po: unctrl.h
+lib_scrreg.So: curses.h
+lib_scrreg.So: ncurses_def.h
+lib_scrreg.So: term.h
+lib_scrreg.So: unctrl.h
+lib_scrreg.o: curses.h
+lib_scrreg.o: ncurses_def.h
+lib_scrreg.o: term.h
+lib_scrreg.o: unctrl.h
+lib_scrreg.po: curses.h
+lib_scrreg.po: ncurses_def.h
+lib_scrreg.po: term.h
+lib_scrreg.po: unctrl.h
+lib_set_term.So: curses.h
+lib_set_term.So: ncurses_def.h
+lib_set_term.So: term.h
+lib_set_term.So: unctrl.h
+lib_set_term.o: curses.h
+lib_set_term.o: ncurses_def.h
+lib_set_term.o: term.h
+lib_set_term.o: unctrl.h
+lib_set_term.po: curses.h
+lib_set_term.po: ncurses_def.h
+lib_set_term.po: term.h
+lib_set_term.po: unctrl.h
+lib_setup.So: curses.h
+lib_setup.So: ncurses_def.h
+lib_setup.So: term.h
+lib_setup.So: unctrl.h
+lib_setup.o: curses.h
+lib_setup.o: ncurses_def.h
+lib_setup.o: term.h
+lib_setup.o: unctrl.h
+lib_setup.po: curses.h
+lib_setup.po: ncurses_def.h
+lib_setup.po: term.h
+lib_setup.po: unctrl.h
+lib_slk.So: curses.h
+lib_slk.So: ncurses_def.h
+lib_slk.So: term.h
+lib_slk.So: unctrl.h
+lib_slk.o: curses.h
+lib_slk.o: ncurses_def.h
+lib_slk.o: term.h
+lib_slk.o: unctrl.h
+lib_slk.po: curses.h
+lib_slk.po: ncurses_def.h
+lib_slk.po: term.h
+lib_slk.po: unctrl.h
+lib_slk_wset.So: curses.h
+lib_slk_wset.So: ncurses_def.h
+lib_slk_wset.So: term.h
+lib_slk_wset.So: unctrl.h
+lib_slk_wset.o: curses.h
+lib_slk_wset.o: ncurses_def.h
+lib_slk_wset.o: term.h
+lib_slk_wset.o: unctrl.h
+lib_slk_wset.po: curses.h
+lib_slk_wset.po: ncurses_def.h
+lib_slk_wset.po: term.h
+lib_slk_wset.po: unctrl.h
+lib_slkatr_set.So: curses.h
+lib_slkatr_set.So: ncurses_def.h
+lib_slkatr_set.So: term.h
+lib_slkatr_set.So: unctrl.h
+lib_slkatr_set.o: curses.h
+lib_slkatr_set.o: ncurses_def.h
+lib_slkatr_set.o: term.h
+lib_slkatr_set.o: unctrl.h
+lib_slkatr_set.po: curses.h
+lib_slkatr_set.po: ncurses_def.h
+lib_slkatr_set.po: term.h
+lib_slkatr_set.po: unctrl.h
+lib_slkatrof.So: curses.h
+lib_slkatrof.So: ncurses_def.h
+lib_slkatrof.So: term.h
+lib_slkatrof.So: unctrl.h
+lib_slkatrof.o: curses.h
+lib_slkatrof.o: ncurses_def.h
+lib_slkatrof.o: term.h
+lib_slkatrof.o: unctrl.h
+lib_slkatrof.po: curses.h
+lib_slkatrof.po: ncurses_def.h
+lib_slkatrof.po: term.h
+lib_slkatrof.po: unctrl.h
+lib_slkatron.So: curses.h
+lib_slkatron.So: ncurses_def.h
+lib_slkatron.So: term.h
+lib_slkatron.So: unctrl.h
+lib_slkatron.o: curses.h
+lib_slkatron.o: ncurses_def.h
+lib_slkatron.o: term.h
+lib_slkatron.o: unctrl.h
+lib_slkatron.po: curses.h
+lib_slkatron.po: ncurses_def.h
+lib_slkatron.po: term.h
+lib_slkatron.po: unctrl.h
+lib_slkatrset.So: curses.h
+lib_slkatrset.So: ncurses_def.h
+lib_slkatrset.So: term.h
+lib_slkatrset.So: unctrl.h
+lib_slkatrset.o: curses.h
+lib_slkatrset.o: ncurses_def.h
+lib_slkatrset.o: term.h
+lib_slkatrset.o: unctrl.h
+lib_slkatrset.po: curses.h
+lib_slkatrset.po: ncurses_def.h
+lib_slkatrset.po: term.h
+lib_slkatrset.po: unctrl.h
+lib_slkattr.So: curses.h
+lib_slkattr.So: ncurses_def.h
+lib_slkattr.So: term.h
+lib_slkattr.So: unctrl.h
+lib_slkattr.o: curses.h
+lib_slkattr.o: ncurses_def.h
+lib_slkattr.o: term.h
+lib_slkattr.o: unctrl.h
+lib_slkattr.po: curses.h
+lib_slkattr.po: ncurses_def.h
+lib_slkattr.po: term.h
+lib_slkattr.po: unctrl.h
+lib_slkclear.So: curses.h
+lib_slkclear.So: ncurses_def.h
+lib_slkclear.So: term.h
+lib_slkclear.So: unctrl.h
+lib_slkclear.o: curses.h
+lib_slkclear.o: ncurses_def.h
+lib_slkclear.o: term.h
+lib_slkclear.o: unctrl.h
+lib_slkclear.po: curses.h
+lib_slkclear.po: ncurses_def.h
+lib_slkclear.po: term.h
+lib_slkclear.po: unctrl.h
+lib_slkcolor.So: curses.h
+lib_slkcolor.So: ncurses_def.h
+lib_slkcolor.So: term.h
+lib_slkcolor.So: unctrl.h
+lib_slkcolor.o: curses.h
+lib_slkcolor.o: ncurses_def.h
+lib_slkcolor.o: term.h
+lib_slkcolor.o: unctrl.h
+lib_slkcolor.po: curses.h
+lib_slkcolor.po: ncurses_def.h
+lib_slkcolor.po: term.h
+lib_slkcolor.po: unctrl.h
+lib_slkinit.So: curses.h
+lib_slkinit.So: ncurses_def.h
+lib_slkinit.So: term.h
+lib_slkinit.So: unctrl.h
+lib_slkinit.o: curses.h
+lib_slkinit.o: ncurses_def.h
+lib_slkinit.o: term.h
+lib_slkinit.o: unctrl.h
+lib_slkinit.po: curses.h
+lib_slkinit.po: ncurses_def.h
+lib_slkinit.po: term.h
+lib_slkinit.po: unctrl.h
+lib_slklab.So: curses.h
+lib_slklab.So: ncurses_def.h
+lib_slklab.So: term.h
+lib_slklab.So: unctrl.h
+lib_slklab.o: curses.h
+lib_slklab.o: ncurses_def.h
+lib_slklab.o: term.h
+lib_slklab.o: unctrl.h
+lib_slklab.po: curses.h
+lib_slklab.po: ncurses_def.h
+lib_slklab.po: term.h
+lib_slklab.po: unctrl.h
+lib_slkrefr.So: curses.h
+lib_slkrefr.So: ncurses_def.h
+lib_slkrefr.So: term.h
+lib_slkrefr.So: unctrl.h
+lib_slkrefr.o: curses.h
+lib_slkrefr.o: ncurses_def.h
+lib_slkrefr.o: term.h
+lib_slkrefr.o: unctrl.h
+lib_slkrefr.po: curses.h
+lib_slkrefr.po: ncurses_def.h
+lib_slkrefr.po: term.h
+lib_slkrefr.po: unctrl.h
+lib_slkset.So: curses.h
+lib_slkset.So: ncurses_def.h
+lib_slkset.So: term.h
+lib_slkset.So: unctrl.h
+lib_slkset.o: curses.h
+lib_slkset.o: ncurses_def.h
+lib_slkset.o: term.h
+lib_slkset.o: unctrl.h
+lib_slkset.po: curses.h
+lib_slkset.po: ncurses_def.h
+lib_slkset.po: term.h
+lib_slkset.po: unctrl.h
+lib_slktouch.So: curses.h
+lib_slktouch.So: ncurses_def.h
+lib_slktouch.So: term.h
+lib_slktouch.So: unctrl.h
+lib_slktouch.o: curses.h
+lib_slktouch.o: ncurses_def.h
+lib_slktouch.o: term.h
+lib_slktouch.o: unctrl.h
+lib_slktouch.po: curses.h
+lib_slktouch.po: ncurses_def.h
+lib_slktouch.po: term.h
+lib_slktouch.po: unctrl.h
+lib_termcap.So: curses.h
+lib_termcap.So: ncurses_def.h
+lib_termcap.So: term.h
+lib_termcap.So: termcap.h
+lib_termcap.So: unctrl.h
+lib_termcap.o: curses.h
+lib_termcap.o: ncurses_def.h
+lib_termcap.o: term.h
+lib_termcap.o: termcap.h
+lib_termcap.o: unctrl.h
+lib_termcap.po: curses.h
+lib_termcap.po: ncurses_def.h
+lib_termcap.po: term.h
+lib_termcap.po: termcap.h
+lib_termcap.po: unctrl.h
+lib_termname.So: curses.h
+lib_termname.So: ncurses_def.h
+lib_termname.So: term.h
+lib_termname.So: unctrl.h
+lib_termname.o: curses.h
+lib_termname.o: ncurses_def.h
+lib_termname.o: term.h
+lib_termname.o: unctrl.h
+lib_termname.po: curses.h
+lib_termname.po: ncurses_def.h
+lib_termname.po: term.h
+lib_termname.po: unctrl.h
+lib_tgoto.So: curses.h
+lib_tgoto.So: ncurses_def.h
+lib_tgoto.So: term.h
+lib_tgoto.So: termcap.h
+lib_tgoto.So: unctrl.h
+lib_tgoto.o: curses.h
+lib_tgoto.o: ncurses_def.h
+lib_tgoto.o: term.h
+lib_tgoto.o: termcap.h
+lib_tgoto.o: unctrl.h
+lib_tgoto.po: curses.h
+lib_tgoto.po: ncurses_def.h
+lib_tgoto.po: term.h
+lib_tgoto.po: termcap.h
+lib_tgoto.po: unctrl.h
+lib_ti.So: curses.h
+lib_ti.So: ncurses_def.h
+lib_ti.So: term.h
+lib_ti.So: unctrl.h
+lib_ti.o: curses.h
+lib_ti.o: ncurses_def.h
+lib_ti.o: term.h
+lib_ti.o: unctrl.h
+lib_ti.po: curses.h
+lib_ti.po: ncurses_def.h
+lib_ti.po: term.h
+lib_ti.po: unctrl.h
+lib_touch.So: curses.h
+lib_touch.So: ncurses_def.h
+lib_touch.So: term.h
+lib_touch.So: unctrl.h
+lib_touch.o: curses.h
+lib_touch.o: ncurses_def.h
+lib_touch.o: term.h
+lib_touch.o: unctrl.h
+lib_touch.po: curses.h
+lib_touch.po: ncurses_def.h
+lib_touch.po: term.h
+lib_touch.po: unctrl.h
+lib_tparm.So: curses.h
+lib_tparm.So: ncurses_def.h
+lib_tparm.So: term.h
+lib_tparm.So: unctrl.h
+lib_tparm.o: curses.h
+lib_tparm.o: ncurses_def.h
+lib_tparm.o: term.h
+lib_tparm.o: unctrl.h
+lib_tparm.po: curses.h
+lib_tparm.po: ncurses_def.h
+lib_tparm.po: term.h
+lib_tparm.po: unctrl.h
+lib_tputs.So: curses.h
+lib_tputs.So: ncurses_def.h
+lib_tputs.So: term.h
+lib_tputs.So: termcap.h
+lib_tputs.So: unctrl.h
+lib_tputs.o: curses.h
+lib_tputs.o: ncurses_def.h
+lib_tputs.o: term.h
+lib_tputs.o: termcap.h
+lib_tputs.o: unctrl.h
+lib_tputs.po: curses.h
+lib_tputs.po: ncurses_def.h
+lib_tputs.po: term.h
+lib_tputs.po: termcap.h
+lib_tputs.po: unctrl.h
+lib_trace.So: curses.h
+lib_trace.So: ncurses_def.h
+lib_trace.So: term.h
+lib_trace.So: unctrl.h
+lib_trace.o: curses.h
+lib_trace.o: ncurses_def.h
+lib_trace.o: term.h
+lib_trace.o: unctrl.h
+lib_trace.po: curses.h
+lib_trace.po: ncurses_def.h
+lib_trace.po: term.h
+lib_trace.po: unctrl.h
+lib_tstp.So: curses.h
+lib_tstp.So: ncurses_def.h
+lib_tstp.So: term.h
+lib_tstp.So: unctrl.h
+lib_tstp.o: curses.h
+lib_tstp.o: ncurses_def.h
+lib_tstp.o: term.h
+lib_tstp.o: unctrl.h
+lib_tstp.po: curses.h
+lib_tstp.po: ncurses_def.h
+lib_tstp.po: term.h
+lib_tstp.po: unctrl.h
+lib_ttyflags.So: curses.h
+lib_ttyflags.So: ncurses_def.h
+lib_ttyflags.So: term.h
+lib_ttyflags.So: unctrl.h
+lib_ttyflags.o: curses.h
+lib_ttyflags.o: ncurses_def.h
+lib_ttyflags.o: term.h
+lib_ttyflags.o: unctrl.h
+lib_ttyflags.po: curses.h
+lib_ttyflags.po: ncurses_def.h
+lib_ttyflags.po: term.h
+lib_ttyflags.po: unctrl.h
+lib_twait.So: curses.h
+lib_twait.So: ncurses_def.h
+lib_twait.So: term.h
+lib_twait.So: unctrl.h
+lib_twait.o: curses.h
+lib_twait.o: ncurses_def.h
+lib_twait.o: term.h
+lib_twait.o: unctrl.h
+lib_twait.po: curses.h
+lib_twait.po: ncurses_def.h
+lib_twait.po: term.h
+lib_twait.po: unctrl.h
+lib_unget_wch.So: curses.h
+lib_unget_wch.So: ncurses_def.h
+lib_unget_wch.So: term.h
+lib_unget_wch.So: unctrl.h
+lib_unget_wch.o: curses.h
+lib_unget_wch.o: ncurses_def.h
+lib_unget_wch.o: term.h
+lib_unget_wch.o: unctrl.h
+lib_unget_wch.po: curses.h
+lib_unget_wch.po: ncurses_def.h
+lib_unget_wch.po: term.h
+lib_unget_wch.po: unctrl.h
+lib_ungetch.So: curses.h
+lib_ungetch.So: ncurses_def.h
+lib_ungetch.So: term.h
+lib_ungetch.So: unctrl.h
+lib_ungetch.o: curses.h
+lib_ungetch.o: ncurses_def.h
+lib_ungetch.o: term.h
+lib_ungetch.o: unctrl.h
+lib_ungetch.po: curses.h
+lib_ungetch.po: ncurses_def.h
+lib_ungetch.po: term.h
+lib_ungetch.po: unctrl.h
+lib_vid_attr.So: curses.h
+lib_vid_attr.So: ncurses_def.h
+lib_vid_attr.So: term.h
+lib_vid_attr.So: unctrl.h
+lib_vid_attr.o: curses.h
+lib_vid_attr.o: ncurses_def.h
+lib_vid_attr.o: term.h
+lib_vid_attr.o: unctrl.h
+lib_vid_attr.po: curses.h
+lib_vid_attr.po: ncurses_def.h
+lib_vid_attr.po: term.h
+lib_vid_attr.po: unctrl.h
+lib_vidattr.So: curses.h
+lib_vidattr.So: ncurses_def.h
+lib_vidattr.So: term.h
+lib_vidattr.So: unctrl.h
+lib_vidattr.o: curses.h
+lib_vidattr.o: ncurses_def.h
+lib_vidattr.o: term.h
+lib_vidattr.o: unctrl.h
+lib_vidattr.po: curses.h
+lib_vidattr.po: ncurses_def.h
+lib_vidattr.po: term.h
+lib_vidattr.po: unctrl.h
+lib_vline.So: curses.h
+lib_vline.So: ncurses_def.h
+lib_vline.So: term.h
+lib_vline.So: unctrl.h
+lib_vline.o: curses.h
+lib_vline.o: ncurses_def.h
+lib_vline.o: term.h
+lib_vline.o: unctrl.h
+lib_vline.po: curses.h
+lib_vline.po: ncurses_def.h
+lib_vline.po: term.h
+lib_vline.po: unctrl.h
+lib_vline_set.So: curses.h
+lib_vline_set.So: ncurses_def.h
+lib_vline_set.So: term.h
+lib_vline_set.So: unctrl.h
+lib_vline_set.o: curses.h
+lib_vline_set.o: ncurses_def.h
+lib_vline_set.o: term.h
+lib_vline_set.o: unctrl.h
+lib_vline_set.po: curses.h
+lib_vline_set.po: ncurses_def.h
+lib_vline_set.po: term.h
+lib_vline_set.po: unctrl.h
+lib_wacs.So: curses.h
+lib_wacs.So: ncurses_def.h
+lib_wacs.So: term.h
+lib_wacs.So: unctrl.h
+lib_wacs.o: curses.h
+lib_wacs.o: ncurses_def.h
+lib_wacs.o: term.h
+lib_wacs.o: unctrl.h
+lib_wacs.po: curses.h
+lib_wacs.po: ncurses_def.h
+lib_wacs.po: term.h
+lib_wacs.po: unctrl.h
+lib_wattroff.So: curses.h
+lib_wattroff.So: ncurses_def.h
+lib_wattroff.So: term.h
+lib_wattroff.So: unctrl.h
+lib_wattroff.o: curses.h
+lib_wattroff.o: ncurses_def.h
+lib_wattroff.o: term.h
+lib_wattroff.o: unctrl.h
+lib_wattroff.po: curses.h
+lib_wattroff.po: ncurses_def.h
+lib_wattroff.po: term.h
+lib_wattroff.po: unctrl.h
+lib_wattron.So: curses.h
+lib_wattron.So: ncurses_def.h
+lib_wattron.So: term.h
+lib_wattron.So: unctrl.h
+lib_wattron.o: curses.h
+lib_wattron.o: ncurses_def.h
+lib_wattron.o: term.h
+lib_wattron.o: unctrl.h
+lib_wattron.po: curses.h
+lib_wattron.po: ncurses_def.h
+lib_wattron.po: term.h
+lib_wattron.po: unctrl.h
+lib_winch.So: curses.h
+lib_winch.So: ncurses_def.h
+lib_winch.So: term.h
+lib_winch.So: unctrl.h
+lib_winch.o: curses.h
+lib_winch.o: ncurses_def.h
+lib_winch.o: term.h
+lib_winch.o: unctrl.h
+lib_winch.po: curses.h
+lib_winch.po: ncurses_def.h
+lib_winch.po: term.h
+lib_winch.po: unctrl.h
+lib_window.So: curses.h
+lib_window.So: ncurses_def.h
+lib_window.So: term.h
+lib_window.So: unctrl.h
+lib_window.o: curses.h
+lib_window.o: ncurses_def.h
+lib_window.o: term.h
+lib_window.o: unctrl.h
+lib_window.po: curses.h
+lib_window.po: ncurses_def.h
+lib_window.po: term.h
+lib_window.po: unctrl.h
+lib_wunctrl.So: curses.h
+lib_wunctrl.So: ncurses_def.h
+lib_wunctrl.So: term.h
+lib_wunctrl.So: unctrl.h
+lib_wunctrl.o: curses.h
+lib_wunctrl.o: ncurses_def.h
+lib_wunctrl.o: term.h
+lib_wunctrl.o: unctrl.h
+lib_wunctrl.po: curses.h
+lib_wunctrl.po: ncurses_def.h
+lib_wunctrl.po: term.h
+lib_wunctrl.po: unctrl.h
+memmove.So: curses.h
+memmove.So: ncurses_def.h
+memmove.So: term.h
+memmove.So: unctrl.h
+memmove.o: curses.h
+memmove.o: ncurses_def.h
+memmove.o: term.h
+memmove.o: unctrl.h
+memmove.po: curses.h
+memmove.po: ncurses_def.h
+memmove.po: term.h
+memmove.po: unctrl.h
+name_match.So: curses.h
+name_match.So: ncurses_def.h
+name_match.So: term.h
+name_match.So: unctrl.h
+name_match.o: curses.h
+name_match.o: ncurses_def.h
+name_match.o: term.h
+name_match.o: unctrl.h
+name_match.po: curses.h
+name_match.po: ncurses_def.h
+name_match.po: term.h
+name_match.po: unctrl.h
+names.So: curses.h
+names.So: names.c
+names.So: ncurses_def.h
+names.So: term.h
+names.So: unctrl.h
+names.o: curses.h
+names.o: names.c
+names.o: ncurses_def.h
+names.o: term.h
+names.o: unctrl.h
+names.po: curses.h
+names.po: names.c
+names.po: ncurses_def.h
+names.po: term.h
+names.po: unctrl.h
+nc_panel.So: curses.h
+nc_panel.So: ncurses_def.h
+nc_panel.So: term.h
+nc_panel.So: unctrl.h
+nc_panel.o: curses.h
+nc_panel.o: ncurses_def.h
+nc_panel.o: term.h
+nc_panel.o: unctrl.h
+nc_panel.po: curses.h
+nc_panel.po: ncurses_def.h
+nc_panel.po: term.h
+nc_panel.po: unctrl.h
+parse_entry.So: curses.h
+parse_entry.So: ncurses_def.h
+parse_entry.So: parametrized.h
+parse_entry.So: term.h
+parse_entry.So: unctrl.h
+parse_entry.o: curses.h
+parse_entry.o: ncurses_def.h
+parse_entry.o: parametrized.h
+parse_entry.o: term.h
+parse_entry.o: unctrl.h
+parse_entry.po: curses.h
+parse_entry.po: ncurses_def.h
+parse_entry.po: parametrized.h
+parse_entry.po: term.h
+parse_entry.po: unctrl.h
+read_entry.So: curses.h
+read_entry.So: ncurses_def.h
+read_entry.So: term.h
+read_entry.So: unctrl.h
+read_entry.o: curses.h
+read_entry.o: ncurses_def.h
+read_entry.o: term.h
+read_entry.o: unctrl.h
+read_entry.po: curses.h
+read_entry.po: ncurses_def.h
+read_entry.po: term.h
+read_entry.po: unctrl.h
+resizeterm.So: curses.h
+resizeterm.So: ncurses_def.h
+resizeterm.So: term.h
+resizeterm.So: unctrl.h
+resizeterm.o: curses.h
+resizeterm.o: ncurses_def.h
+resizeterm.o: term.h
+resizeterm.o: unctrl.h
+resizeterm.po: curses.h
+resizeterm.po: ncurses_def.h
+resizeterm.po: term.h
+resizeterm.po: unctrl.h
+safe_sprintf.So: curses.h
+safe_sprintf.So: ncurses_def.h
+safe_sprintf.So: term.h
+safe_sprintf.So: unctrl.h
+safe_sprintf.o: curses.h
+safe_sprintf.o: ncurses_def.h
+safe_sprintf.o: term.h
+safe_sprintf.o: unctrl.h
+safe_sprintf.po: curses.h
+safe_sprintf.po: ncurses_def.h
+safe_sprintf.po: term.h
+safe_sprintf.po: unctrl.h
+setbuf.So: curses.h
+setbuf.So: ncurses_def.h
+setbuf.So: term.h
+setbuf.So: unctrl.h
+setbuf.o: curses.h
+setbuf.o: ncurses_def.h
+setbuf.o: term.h
+setbuf.o: unctrl.h
+setbuf.po: curses.h
+setbuf.po: ncurses_def.h
+setbuf.po: term.h
+setbuf.po: unctrl.h
+strings.So: curses.h
+strings.So: ncurses_def.h
+strings.So: term.h
+strings.So: unctrl.h
+strings.o: curses.h
+strings.o: ncurses_def.h
+strings.o: term.h
+strings.o: unctrl.h
+strings.po: curses.h
+strings.po: ncurses_def.h
+strings.po: term.h
+strings.po: unctrl.h
+termcap.So: curses.h
+termcap.So: ncurses_def.h
+termcap.So: term.h
+termcap.So: unctrl.h
+termcap.o: curses.h
+termcap.o: ncurses_def.h
+termcap.o: term.h
+termcap.o: unctrl.h
+termcap.po: curses.h
+termcap.po: ncurses_def.h
+termcap.po: term.h
+termcap.po: unctrl.h
+tries.So: curses.h
+tries.So: ncurses_def.h
+tries.So: term.h
+tries.So: unctrl.h
+tries.o: curses.h
+tries.o: ncurses_def.h
+tries.o: term.h
+tries.o: unctrl.h
+tries.po: curses.h
+tries.po: ncurses_def.h
+tries.po: term.h
+tries.po: unctrl.h
+trim_sgr0.So: curses.h
+trim_sgr0.So: ncurses_def.h
+trim_sgr0.So: term.h
+trim_sgr0.So: unctrl.h
+trim_sgr0.o: curses.h
+trim_sgr0.o: ncurses_def.h
+trim_sgr0.o: term.h
+trim_sgr0.o: unctrl.h
+trim_sgr0.po: curses.h
+trim_sgr0.po: ncurses_def.h
+trim_sgr0.po: term.h
+trim_sgr0.po: unctrl.h
+tty_update.So: curses.h
+tty_update.So: ncurses_def.h
+tty_update.So: term.h
+tty_update.So: unctrl.h
+tty_update.o: curses.h
+tty_update.o: ncurses_def.h
+tty_update.o: term.h
+tty_update.o: unctrl.h
+tty_update.po: curses.h
+tty_update.po: ncurses_def.h
+tty_update.po: term.h
+tty_update.po: unctrl.h
+unctrl.So: curses.h
+unctrl.So: ncurses_def.h
+unctrl.So: term.h
+unctrl.So: unctrl.c
+unctrl.So: unctrl.h
+unctrl.o: curses.h
+unctrl.o: ncurses_def.h
+unctrl.o: term.h
+unctrl.o: unctrl.c
+unctrl.o: unctrl.h
+unctrl.po: curses.h
+unctrl.po: ncurses_def.h
+unctrl.po: term.h
+unctrl.po: unctrl.c
+unctrl.po: unctrl.h
+version.So: curses.h
+version.So: ncurses_def.h
+version.So: term.h
+version.So: unctrl.h
+version.o: curses.h
+version.o: ncurses_def.h
+version.o: term.h
+version.o: unctrl.h
+version.po: curses.h
+version.po: ncurses_def.h
+version.po: term.h
+version.po: unctrl.h
+visbuf.So: curses.h
+visbuf.So: ncurses_def.h
+visbuf.So: term.h
+visbuf.So: unctrl.h
+visbuf.o: curses.h
+visbuf.o: ncurses_def.h
+visbuf.o: term.h
+visbuf.o: unctrl.h
+visbuf.po: curses.h
+visbuf.po: ncurses_def.h
+visbuf.po: term.h
+visbuf.po: unctrl.h
+vsscanf.So: curses.h
+vsscanf.So: ncurses_def.h
+vsscanf.So: term.h
+vsscanf.So: unctrl.h
+vsscanf.o: curses.h
+vsscanf.o: ncurses_def.h
+vsscanf.o: term.h
+vsscanf.o: unctrl.h
+vsscanf.po: curses.h
+vsscanf.po: ncurses_def.h
+vsscanf.po: term.h
+vsscanf.po: unctrl.h
+wresize.So: curses.h
+wresize.So: ncurses_def.h
+wresize.So: term.h
+wresize.So: unctrl.h
+wresize.o: curses.h
+wresize.o: ncurses_def.h
+wresize.o: term.h
+wresize.o: unctrl.h
+wresize.po: curses.h
+wresize.po: ncurses_def.h
+wresize.po: term.h
+wresize.po: unctrl.h
+write_entry.So: curses.h
+write_entry.So: ncurses_def.h
+write_entry.So: term.h
+write_entry.So: unctrl.h
+write_entry.o: curses.h
+write_entry.o: ncurses_def.h
+write_entry.o: term.h
+write_entry.o: unctrl.h
+write_entry.po: curses.h
+write_entry.po: ncurses_def.h
+write_entry.po: term.h
+write_entry.po: unctrl.h
+.endif
diff --git a/lib/ncurses/panel/Makefile.depend b/lib/ncurses/panel/Makefile.depend
new file mode 100644
index 0000000..3f1939e
--- /dev/null
+++ b/lib/ncurses/panel/Makefile.depend
@@ -0,0 +1,62 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+p_above.So: ncurses_def.h
+p_above.o: ncurses_def.h
+p_above.po: ncurses_def.h
+p_below.So: ncurses_def.h
+p_below.o: ncurses_def.h
+p_below.po: ncurses_def.h
+p_bottom.So: ncurses_def.h
+p_bottom.o: ncurses_def.h
+p_bottom.po: ncurses_def.h
+p_delete.So: ncurses_def.h
+p_delete.o: ncurses_def.h
+p_delete.po: ncurses_def.h
+p_hidden.So: ncurses_def.h
+p_hidden.o: ncurses_def.h
+p_hidden.po: ncurses_def.h
+p_hide.So: ncurses_def.h
+p_hide.o: ncurses_def.h
+p_hide.po: ncurses_def.h
+p_move.So: ncurses_def.h
+p_move.o: ncurses_def.h
+p_move.po: ncurses_def.h
+p_new.So: ncurses_def.h
+p_new.o: ncurses_def.h
+p_new.po: ncurses_def.h
+p_replace.So: ncurses_def.h
+p_replace.o: ncurses_def.h
+p_replace.po: ncurses_def.h
+p_show.So: ncurses_def.h
+p_show.o: ncurses_def.h
+p_show.po: ncurses_def.h
+p_top.So: ncurses_def.h
+p_top.o: ncurses_def.h
+p_top.po: ncurses_def.h
+p_update.So: ncurses_def.h
+p_update.o: ncurses_def.h
+p_update.po: ncurses_def.h
+p_user.So: ncurses_def.h
+p_user.o: ncurses_def.h
+p_user.po: ncurses_def.h
+p_win.So: ncurses_def.h
+p_win.o: ncurses_def.h
+p_win.po: ncurses_def.h
+panel.So: ncurses_def.h
+panel.o: ncurses_def.h
+panel.po: ncurses_def.h
+.endif
diff --git a/lib/ncurses/panelw/Makefile.depend b/lib/ncurses/panelw/Makefile.depend
new file mode 100644
index 0000000..18cd49b
--- /dev/null
+++ b/lib/ncurses/panelw/Makefile.depend
@@ -0,0 +1,62 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+p_above.So: ncurses_def.h
+p_above.o: ncurses_def.h
+p_above.po: ncurses_def.h
+p_below.So: ncurses_def.h
+p_below.o: ncurses_def.h
+p_below.po: ncurses_def.h
+p_bottom.So: ncurses_def.h
+p_bottom.o: ncurses_def.h
+p_bottom.po: ncurses_def.h
+p_delete.So: ncurses_def.h
+p_delete.o: ncurses_def.h
+p_delete.po: ncurses_def.h
+p_hidden.So: ncurses_def.h
+p_hidden.o: ncurses_def.h
+p_hidden.po: ncurses_def.h
+p_hide.So: ncurses_def.h
+p_hide.o: ncurses_def.h
+p_hide.po: ncurses_def.h
+p_move.So: ncurses_def.h
+p_move.o: ncurses_def.h
+p_move.po: ncurses_def.h
+p_new.So: ncurses_def.h
+p_new.o: ncurses_def.h
+p_new.po: ncurses_def.h
+p_replace.So: ncurses_def.h
+p_replace.o: ncurses_def.h
+p_replace.po: ncurses_def.h
+p_show.So: ncurses_def.h
+p_show.o: ncurses_def.h
+p_show.po: ncurses_def.h
+p_top.So: ncurses_def.h
+p_top.o: ncurses_def.h
+p_top.po: ncurses_def.h
+p_update.So: ncurses_def.h
+p_update.o: ncurses_def.h
+p_update.po: ncurses_def.h
+p_user.So: ncurses_def.h
+p_user.o: ncurses_def.h
+p_user.po: ncurses_def.h
+p_win.So: ncurses_def.h
+p_win.o: ncurses_def.h
+p_win.po: ncurses_def.h
+panel.So: ncurses_def.h
+panel.o: ncurses_def.h
+panel.po: ncurses_def.h
+.endif
diff --git a/libexec/atrun/Makefile.depend b/libexec/atrun/Makefile.depend
new file mode 100644
index 0000000..641b391
--- /dev/null
+++ b/libexec/atrun/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libpam/libpam \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/bootpd/Makefile.depend b/libexec/bootpd/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/libexec/bootpd/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/bootpd/bootpgw/Makefile.depend b/libexec/bootpd/bootpgw/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/libexec/bootpd/bootpgw/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/bootpd/tools/bootpef/Makefile.depend b/libexec/bootpd/tools/bootpef/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/libexec/bootpd/tools/bootpef/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/bootpd/tools/bootptest/Makefile.depend b/libexec/bootpd/tools/bootptest/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/libexec/bootpd/tools/bootptest/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/comsat/Makefile.depend b/libexec/comsat/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/libexec/comsat/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/fingerd/Makefile.depend b/libexec/fingerd/Makefile.depend
new file mode 100644
index 0000000..c262920
--- /dev/null
+++ b/libexec/fingerd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/ftpd/Makefile.depend b/libexec/ftpd/Makefile.depend
new file mode 100644
index 0000000..2a9801d
--- /dev/null
+++ b/libexec/ftpd/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libmd \
+ lib/libopie \
+ lib/libpam/libpam \
+ lib/libtelnet \
+ lib/libutil \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ftpcmd.o: ftpcmd.c
+ftpcmd.po: ftpcmd.c
+.endif
diff --git a/libexec/getty/Makefile.depend b/libexec/getty/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/libexec/getty/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/mail.local/Makefile.depend b/libexec/mail.local/Makefile.depend
new file mode 100644
index 0000000..5486088
--- /dev/null
+++ b/libexec/mail.local/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsm \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+mail.local.o: sm_os.h
+mail.local.po: sm_os.h
+.endif
diff --git a/libexec/mknetid/Makefile.depend b/libexec/mknetid/Makefile.depend
new file mode 100644
index 0000000..6e9b14f
--- /dev/null
+++ b/libexec/mknetid/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/pppoed/Makefile.depend b/libexec/pppoed/Makefile.depend
new file mode 100644
index 0000000..1835644
--- /dev/null
+++ b/libexec/pppoed/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libnetgraph \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/rbootd/Makefile.depend b/libexec/rbootd/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/libexec/rbootd/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/revnetgroup/Makefile.depend b/libexec/revnetgroup/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/libexec/revnetgroup/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/rlogind/Makefile.depend b/libexec/rlogind/Makefile.depend
new file mode 100644
index 0000000..c262920
--- /dev/null
+++ b/libexec/rlogind/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/rpc.rquotad/Makefile.depend b/libexec/rpc.rquotad/Makefile.depend
new file mode 100644
index 0000000..ed142e7
--- /dev/null
+++ b/libexec/rpc.rquotad/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/rpc.rstatd/Makefile.depend b/libexec/rpc.rstatd/Makefile.depend
new file mode 100644
index 0000000..1cf1716
--- /dev/null
+++ b/libexec/rpc.rstatd/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libdevstat \
+ lib/libkvm \
+ lib/librpcsvc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/rpc.rusersd/Makefile.depend b/libexec/rpc.rusersd/Makefile.depend
new file mode 100644
index 0000000..bf35174
--- /dev/null
+++ b/libexec/rpc.rusersd/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/rpc.rwalld/Makefile.depend b/libexec/rpc.rwalld/Makefile.depend
new file mode 100644
index 0000000..7ca71be
--- /dev/null
+++ b/libexec/rpc.rwalld/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/rpc.sprayd/Makefile.depend b/libexec/rpc.sprayd/Makefile.depend
new file mode 100644
index 0000000..60fe900
--- /dev/null
+++ b/libexec/rpc.sprayd/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/rshd/Makefile.depend b/libexec/rshd/Makefile.depend
new file mode 100644
index 0000000..b332af0
--- /dev/null
+++ b/libexec/rshd/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libpam/libpam \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/rtld-elf/Makefile.depend b/libexec/rtld-elf/Makefile.depend
new file mode 100644
index 0000000..32bd00b
--- /dev/null
+++ b/libexec/rtld-elf/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/smrsh/Makefile.depend b/libexec/smrsh/Makefile.depend
new file mode 100644
index 0000000..be1fe94
--- /dev/null
+++ b/libexec/smrsh/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsm \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+smrsh.o: sm_os.h
+smrsh.po: sm_os.h
+.endif
diff --git a/libexec/talkd/Makefile.depend b/libexec/talkd/Makefile.depend
new file mode 100644
index 0000000..083e419
--- /dev/null
+++ b/libexec/talkd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/tcpd/Makefile.depend b/libexec/tcpd/Makefile.depend
new file mode 100644
index 0000000..cd2e9bb
--- /dev/null
+++ b/libexec/tcpd/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/telnetd/Makefile.depend b/libexec/telnetd/Makefile.depend
new file mode 100644
index 0000000..a12d055
--- /dev/null
+++ b/libexec/telnetd/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libmp \
+ lib/libpam/libpam \
+ lib/libtelnet \
+ lib/libutil \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/tftp-proxy/Makefile.depend b/libexec/tftp-proxy/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/libexec/tftp-proxy/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/tftpd/Makefile.depend b/libexec/tftpd/Makefile.depend
new file mode 100644
index 0000000..b30ae55
--- /dev/null
+++ b/libexec/tftpd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/ulog-helper/Makefile.depend b/libexec/ulog-helper/Makefile.depend
new file mode 100644
index 0000000..1a4b120
--- /dev/null
+++ b/libexec/ulog-helper/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libulog \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/libexec/ypxfr/Makefile.depend b/libexec/ypxfr/Makefile.depend
new file mode 100644
index 0000000..eb84d15
--- /dev/null
+++ b/libexec/ypxfr/Makefile.depend
@@ -0,0 +1,31 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+yp_clnt.o: yp.h
+yp_clnt.o: yp_clnt.c
+yp_clnt.po: yp.h
+yp_clnt.po: yp_clnt.c
+ypxfr_clnt.o: yp.h
+ypxfr_clnt.o: ypxfr_clnt.c
+ypxfr_clnt.po: yp.h
+ypxfr_clnt.po: ypxfr_clnt.c
+.endif
diff --git a/sbin/adjkerntz/Makefile.depend b/sbin/adjkerntz/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/adjkerntz/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/atacontrol/Makefile.depend b/sbin/atacontrol/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/atacontrol/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/atm/atmconfig/Makefile.depend b/sbin/atm/atmconfig/Makefile.depend
new file mode 100644
index 0000000..a793200
--- /dev/null
+++ b/sbin/atm/atmconfig/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbsnmp/libbsnmp \
+ lib/libc \
+ lib/libnetgraph \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+atmconfig_device.o: oid.h
+atmconfig_device.po: oid.h
+.endif
diff --git a/sbin/badsect/Makefile.depend b/sbin/badsect/Makefile.depend
new file mode 100644
index 0000000..250cad8
--- /dev/null
+++ b/sbin/badsect/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libufs \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/bsdlabel/Makefile.depend b/sbin/bsdlabel/Makefile.depend
new file mode 100644
index 0000000..378b35f
--- /dev/null
+++ b/sbin/bsdlabel/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libexpat \
+ lib/libgeom \
+ lib/libsbuf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/camcontrol/Makefile.depend b/sbin/camcontrol/Makefile.depend
new file mode 100644
index 0000000..f9f3597
--- /dev/null
+++ b/sbin/camcontrol/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcam \
+ lib/libsbuf \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ccdconfig/Makefile.depend b/sbin/ccdconfig/Makefile.depend
new file mode 100644
index 0000000..25f093b
--- /dev/null
+++ b/sbin/ccdconfig/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/clri/Makefile.depend b/sbin/clri/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/clri/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/comcontrol/Makefile.depend b/sbin/comcontrol/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/comcontrol/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/conscontrol/Makefile.depend b/sbin/conscontrol/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/conscontrol/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ddb/Makefile.depend b/sbin/ddb/Makefile.depend
new file mode 100644
index 0000000..553674c
--- /dev/null
+++ b/sbin/ddb/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/devd/Makefile.depend b/sbin/devd/Makefile.depend
new file mode 100644
index 0000000..7ffa1cc
--- /dev/null
+++ b/sbin/devd/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libstdc++ \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+parse.o: parse.c
+parse.po: parse.c
+token.o: token.c
+token.o: y.tab.h
+token.po: token.c
+token.po: y.tab.h
+.endif
diff --git a/sbin/devfs/Makefile.depend b/sbin/devfs/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/devfs/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/dhclient/Makefile.depend b/sbin/dhclient/Makefile.depend
new file mode 100644
index 0000000..c262920
--- /dev/null
+++ b/sbin/dhclient/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/dmesg/Makefile.depend b/sbin/dmesg/Makefile.depend
new file mode 100644
index 0000000..553674c
--- /dev/null
+++ b/sbin/dmesg/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/dump/Makefile.depend b/sbin/dump/Makefile.depend
new file mode 100644
index 0000000..25ca344
--- /dev/null
+++ b/sbin/dump/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/dumpfs/Makefile.depend b/sbin/dumpfs/Makefile.depend
new file mode 100644
index 0000000..250cad8
--- /dev/null
+++ b/sbin/dumpfs/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libufs \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/dumpon/Makefile.depend b/sbin/dumpon/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/dumpon/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/etherswitchcfg/Makefile.depend b/sbin/etherswitchcfg/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/etherswitchcfg/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/fdisk/Makefile.depend b/sbin/fdisk/Makefile.depend
new file mode 100644
index 0000000..378b35f
--- /dev/null
+++ b/sbin/fdisk/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libexpat \
+ lib/libgeom \
+ lib/libsbuf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/fdisk_pc98/Makefile.depend b/sbin/fdisk_pc98/Makefile.depend
new file mode 100644
index 0000000..25f093b
--- /dev/null
+++ b/sbin/fdisk_pc98/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ffsinfo/Makefile.depend b/sbin/ffsinfo/Makefile.depend
new file mode 100644
index 0000000..250cad8
--- /dev/null
+++ b/sbin/ffsinfo/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libufs \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/fsck/Makefile.depend b/sbin/fsck/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/fsck/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/fsck_ffs/Makefile.depend b/sbin/fsck_ffs/Makefile.depend
new file mode 100644
index 0000000..250cad8
--- /dev/null
+++ b/sbin/fsck_ffs/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libufs \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/fsck_msdosfs/Makefile.depend b/sbin/fsck_msdosfs/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/fsck_msdosfs/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/fsdb/Makefile.depend b/sbin/fsdb/Makefile.depend
new file mode 100644
index 0000000..a1ddabb
--- /dev/null
+++ b/sbin/fsdb/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/libufs \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/fsirand/Makefile.depend b/sbin/fsirand/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/sbin/fsirand/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/gbde/Makefile.depend b/sbin/gbde/Makefile.depend
new file mode 100644
index 0000000..91fe7f3
--- /dev/null
+++ b/sbin/gbde/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgeom \
+ lib/libmd \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+template.o: template.c
+template.po: template.c
+.endif
diff --git a/sbin/geom/class/cache/Makefile.depend b/sbin/geom/class/cache/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/cache/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/concat/Makefile.depend b/sbin/geom/class/concat/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/concat/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/eli/Makefile.depend b/sbin/geom/class/eli/Makefile.depend
new file mode 100644
index 0000000..6efdbbb
--- /dev/null
+++ b/sbin/geom/class/eli/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/journal/Makefile.depend b/sbin/geom/class/journal/Makefile.depend
new file mode 100644
index 0000000..880734b
--- /dev/null
+++ b/sbin/geom/class/journal/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+ lib/libufs \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/label/Makefile.depend b/sbin/geom/class/label/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/label/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/mirror/Makefile.depend b/sbin/geom/class/mirror/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/mirror/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/mountver/Makefile.depend b/sbin/geom/class/mountver/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/mountver/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/multipath/Makefile.depend b/sbin/geom/class/multipath/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/multipath/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/nop/Makefile.depend b/sbin/geom/class/nop/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/nop/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/part/Makefile.depend b/sbin/geom/class/part/Makefile.depend
new file mode 100644
index 0000000..43fbfcd
--- /dev/null
+++ b/sbin/geom/class/part/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/raid/Makefile.depend b/sbin/geom/class/raid/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/raid/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/raid3/Makefile.depend b/sbin/geom/class/raid3/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/raid3/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/sched/Makefile.depend b/sbin/geom/class/sched/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/sched/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/shsec/Makefile.depend b/sbin/geom/class/shsec/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/shsec/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/stripe/Makefile.depend b/sbin/geom/class/stripe/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/stripe/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/class/virstor/Makefile.depend b/sbin/geom/class/virstor/Makefile.depend
new file mode 100644
index 0000000..42e09bed
--- /dev/null
+++ b/sbin/geom/class/virstor/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/geom/core/Makefile.depend b/sbin/geom/core/Makefile.depend
new file mode 100644
index 0000000..8c8ea60
--- /dev/null
+++ b/sbin/geom/core/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libexpat \
+ lib/libgeom \
+ lib/libsbuf \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ggate/ggatec/Makefile.depend b/sbin/ggate/ggatec/Makefile.depend
new file mode 100644
index 0000000..3ca9d65
--- /dev/null
+++ b/sbin/ggate/ggatec/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libexpat \
+ lib/libgeom \
+ lib/libsbuf \
+ lib/libthr \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ggate/ggated/Makefile.depend b/sbin/ggate/ggated/Makefile.depend
new file mode 100644
index 0000000..bcc7a2b
--- /dev/null
+++ b/sbin/ggate/ggated/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgeom \
+ lib/libthr \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ggate/ggatel/Makefile.depend b/sbin/ggate/ggatel/Makefile.depend
new file mode 100644
index 0000000..21370bf
--- /dev/null
+++ b/sbin/ggate/ggatel/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libexpat \
+ lib/libgeom \
+ lib/libsbuf \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/growfs/Makefile.depend b/sbin/growfs/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/sbin/growfs/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/gvinum/Makefile.depend b/sbin/gvinum/Makefile.depend
new file mode 100644
index 0000000..e74fcab
--- /dev/null
+++ b/sbin/gvinum/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libdevstat \
+ lib/libedit \
+ lib/libedit/edit/readline \
+ lib/libgeom \
+ lib/libkvm \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/hastctl/Makefile.depend b/sbin/hastctl/Makefile.depend
new file mode 100644
index 0000000..de07064
--- /dev/null
+++ b/sbin/hastctl/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+parse.o: parse.c
+parse.po: parse.c
+token.o: token.c
+token.o: y.tab.h
+token.po: token.c
+token.po: y.tab.h
+.endif
diff --git a/sbin/hastd/Makefile.depend b/sbin/hastd/Makefile.depend
new file mode 100644
index 0000000..80d7656
--- /dev/null
+++ b/sbin/hastd/Makefile.depend
@@ -0,0 +1,32 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libexpat \
+ lib/libgeom \
+ lib/libsbuf \
+ lib/libthr \
+ lib/libutil \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+parse.o: parse.c
+parse.po: parse.c
+token.o: token.c
+token.o: y.tab.h
+token.po: token.c
+token.po: y.tab.h
+.endif
diff --git a/sbin/ifconfig/Makefile.depend b/sbin/ifconfig/Makefile.depend
new file mode 100644
index 0000000..71684ef
--- /dev/null
+++ b/sbin/ifconfig/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libexpat \
+ lib/libipx \
+ lib/libjail \
+ lib/libsbuf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/init/Makefile.depend b/sbin/init/Makefile.depend
new file mode 100644
index 0000000..4478ec6
--- /dev/null
+++ b/sbin/init/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ipf/ipf/Makefile.depend b/sbin/ipf/ipf/Makefile.depend
new file mode 100644
index 0000000..5a71ca9
--- /dev/null
+++ b/sbin/ipf/ipf/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ lib/libpcap \
+ sbin/ipf/libipf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ipf_l.o: ipf_l.c
+ipf_l.o: ipf_l.h
+ipf_l.o: ipf_y.h
+ipf_l.po: ipf_l.c
+ipf_l.po: ipf_l.h
+ipf_l.po: ipf_y.h
+ipf_y.o: ipf_l.h
+ipf_y.o: ipf_y.c
+ipf_y.po: ipf_l.h
+ipf_y.po: ipf_y.c
+.endif
diff --git a/sbin/ipf/ipfs/Makefile.depend b/sbin/ipf/ipfs/Makefile.depend
new file mode 100644
index 0000000..ccb33b6
--- /dev/null
+++ b/sbin/ipf/ipfs/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ sbin/ipf/libipf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ipf/ipfstat/Makefile.depend b/sbin/ipf/ipfstat/Makefile.depend
new file mode 100644
index 0000000..6ad3373
--- /dev/null
+++ b/sbin/ipf/ipfstat/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+ sbin/ipf/libipf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ipf/ipftest/Makefile.depend b/sbin/ipf/ipftest/Makefile.depend
new file mode 100644
index 0000000..7b891af
--- /dev/null
+++ b/sbin/ipf/ipftest/Makefile.depend
@@ -0,0 +1,52 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ sbin/ipf/libipf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ipf_l.o: ipf_l.c
+ipf_l.o: ipf_l.h
+ipf_l.o: ipf_y.h
+ipf_l.po: ipf_l.c
+ipf_l.po: ipf_l.h
+ipf_l.po: ipf_y.h
+ipf_y.o: ipf_l.h
+ipf_y.o: ipf_y.c
+ipf_y.po: ipf_l.h
+ipf_y.po: ipf_y.c
+ipnat_l.o: ipnat_l.c
+ipnat_l.o: ipnat_l.h
+ipnat_l.o: ipnat_y.h
+ipnat_l.po: ipnat_l.c
+ipnat_l.po: ipnat_l.h
+ipnat_l.po: ipnat_y.h
+ipnat_y.o: ipnat_l.h
+ipnat_y.o: ipnat_y.c
+ipnat_y.po: ipnat_l.h
+ipnat_y.po: ipnat_y.c
+ippool_l.o: ippool_l.c
+ippool_l.o: ippool_l.h
+ippool_l.o: ippool_y.h
+ippool_l.po: ippool_l.c
+ippool_l.po: ippool_l.h
+ippool_l.po: ippool_y.h
+ippool_y.o: ippool_l.h
+ippool_y.o: ippool_y.c
+ippool_y.po: ippool_l.h
+ippool_y.po: ippool_y.c
+.endif
diff --git a/sbin/ipf/ipmon/Makefile.depend b/sbin/ipf/ipmon/Makefile.depend
new file mode 100644
index 0000000..7a9fb87
--- /dev/null
+++ b/sbin/ipf/ipmon/Makefile.depend
@@ -0,0 +1,32 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ sbin/ipf/libipf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ipmon_l.o: ipmon_l.c
+ipmon_l.o: ipmon_l.h
+ipmon_l.o: ipmon_y.h
+ipmon_l.po: ipmon_l.c
+ipmon_l.po: ipmon_l.h
+ipmon_l.po: ipmon_y.h
+ipmon_y.o: ipmon_l.h
+ipmon_y.o: ipmon_y.c
+ipmon_y.po: ipmon_l.h
+ipmon_y.po: ipmon_y.c
+.endif
diff --git a/sbin/ipf/ipnat/Makefile.depend b/sbin/ipf/ipnat/Makefile.depend
new file mode 100644
index 0000000..4031ae5
--- /dev/null
+++ b/sbin/ipf/ipnat/Makefile.depend
@@ -0,0 +1,32 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ sbin/ipf/libipf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ipnat_l.o: ipnat_l.c
+ipnat_l.o: ipnat_l.h
+ipnat_l.o: ipnat_y.h
+ipnat_l.po: ipnat_l.c
+ipnat_l.po: ipnat_l.h
+ipnat_l.po: ipnat_y.h
+ipnat_y.o: ipnat_l.h
+ipnat_y.o: ipnat_y.c
+ipnat_y.po: ipnat_l.h
+ipnat_y.po: ipnat_y.c
+.endif
diff --git a/sbin/ipf/ippool/Makefile.depend b/sbin/ipf/ippool/Makefile.depend
new file mode 100644
index 0000000..b720567
--- /dev/null
+++ b/sbin/ipf/ippool/Makefile.depend
@@ -0,0 +1,32 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ sbin/ipf/libipf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ippool_l.o: ippool_l.c
+ippool_l.o: ippool_l.h
+ippool_l.o: ippool_y.h
+ippool_l.po: ippool_l.c
+ippool_l.po: ippool_l.h
+ippool_l.po: ippool_y.h
+ippool_y.o: ippool_l.h
+ippool_y.o: ippool_y.c
+ippool_y.po: ippool_l.h
+ippool_y.po: ippool_y.c
+.endif
diff --git a/sbin/ipf/ipresend/Makefile.depend b/sbin/ipf/ipresend/Makefile.depend
new file mode 100644
index 0000000..a326d52
--- /dev/null
+++ b/sbin/ipf/ipresend/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ lib/msun \
+ sbin/ipf/libipf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ipf/libipf/Makefile.depend b/sbin/ipf/libipf/Makefile.depend
new file mode 100644
index 0000000..3dfd462
--- /dev/null
+++ b/sbin/ipf/libipf/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ipfw/Makefile.depend b/sbin/ipfw/Makefile.depend
new file mode 100644
index 0000000..38cce34
--- /dev/null
+++ b/sbin/ipfw/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libalias/libalias \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/iscontrol/Makefile.depend b/sbin/iscontrol/Makefile.depend
new file mode 100644
index 0000000..1725e28
--- /dev/null
+++ b/sbin/iscontrol/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcam \
+ lib/libmd \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/kldconfig/Makefile.depend b/sbin/kldconfig/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/kldconfig/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/kldload/Makefile.depend b/sbin/kldload/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/kldload/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/kldstat/Makefile.depend b/sbin/kldstat/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/sbin/kldstat/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/kldunload/Makefile.depend b/sbin/kldunload/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/sbin/kldunload/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ldconfig/Makefile.depend b/sbin/ldconfig/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/ldconfig/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mca/Makefile.depend b/sbin/mca/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/mca/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/md5/Makefile.depend b/sbin/md5/Makefile.depend
new file mode 100644
index 0000000..7520d5d
--- /dev/null
+++ b/sbin/md5/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mdconfig/Makefile.depend b/sbin/mdconfig/Makefile.depend
new file mode 100644
index 0000000..11643b1
--- /dev/null
+++ b/sbin/mdconfig/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libdevstat \
+ lib/libexpat \
+ lib/libgeom \
+ lib/libkvm \
+ lib/libsbuf \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mdmfs/Makefile.depend b/sbin/mdmfs/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/mdmfs/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mknod/Makefile.depend b/sbin/mknod/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/mknod/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mksnap_ffs/Makefile.depend b/sbin/mksnap_ffs/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/mksnap_ffs/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mount/Makefile.depend b/sbin/mount/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/sbin/mount/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mount_cd9660/Makefile.depend b/sbin/mount_cd9660/Makefile.depend
new file mode 100644
index 0000000..f09f976
--- /dev/null
+++ b/sbin/mount_cd9660/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkiconv \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mount_ext2fs/Makefile.depend b/sbin/mount_ext2fs/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/mount_ext2fs/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mount_msdosfs/Makefile.depend b/sbin/mount_msdosfs/Makefile.depend
new file mode 100644
index 0000000..0dbc784
--- /dev/null
+++ b/sbin/mount_msdosfs/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkiconv \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mount_nfs/Makefile.depend b/sbin/mount_nfs/Makefile.depend
new file mode 100644
index 0000000..a3e1b44
--- /dev/null
+++ b/sbin/mount_nfs/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mount_ntfs/Makefile.depend b/sbin/mount_ntfs/Makefile.depend
new file mode 100644
index 0000000..0dbc784
--- /dev/null
+++ b/sbin/mount_ntfs/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkiconv \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mount_nullfs/Makefile.depend b/sbin/mount_nullfs/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/mount_nullfs/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mount_reiserfs/Makefile.depend b/sbin/mount_reiserfs/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/mount_reiserfs/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mount_std/Makefile.depend b/sbin/mount_std/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/mount_std/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mount_udf/Makefile.depend b/sbin/mount_udf/Makefile.depend
new file mode 100644
index 0000000..18a3d5f
--- /dev/null
+++ b/sbin/mount_udf/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkiconv \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/mount_unionfs/Makefile.depend b/sbin/mount_unionfs/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/mount_unionfs/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/natd/Makefile.depend b/sbin/natd/Makefile.depend
new file mode 100644
index 0000000..34c524c
--- /dev/null
+++ b/sbin/natd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libalias/libalias \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/newfs/Makefile.depend b/sbin/newfs/Makefile.depend
new file mode 100644
index 0000000..da2c5d6
--- /dev/null
+++ b/sbin/newfs/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libufs \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/newfs_msdos/Makefile.depend b/sbin/newfs_msdos/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/newfs_msdos/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/nfsiod/Makefile.depend b/sbin/nfsiod/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/sbin/nfsiod/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/nos-tun/Makefile.depend b/sbin/nos-tun/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/sbin/nos-tun/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/pfctl/Makefile.depend b/sbin/pfctl/Makefile.depend
new file mode 100644
index 0000000..14e9867
--- /dev/null
+++ b/sbin/pfctl/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+parse.o: parse.c
+parse.po: parse.c
+.endif
diff --git a/sbin/pflogd/Makefile.depend b/sbin/pflogd/Makefile.depend
new file mode 100644
index 0000000..447f532
--- /dev/null
+++ b/sbin/pflogd/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libpcap \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ping/Makefile.depend b/sbin/ping/Makefile.depend
new file mode 100644
index 0000000..4e0ace6
--- /dev/null
+++ b/sbin/ping/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipsec \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/ping6/Makefile.depend b/sbin/ping6/Makefile.depend
new file mode 100644
index 0000000..e79eabf
--- /dev/null
+++ b/sbin/ping6/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipsec \
+ lib/libmd \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/quotacheck/Makefile.depend b/sbin/quotacheck/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/sbin/quotacheck/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/rcorder/Makefile.depend b/sbin/rcorder/Makefile.depend
new file mode 100644
index 0000000..670ea5b
--- /dev/null
+++ b/sbin/rcorder/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+rcorder.o: util.h
+rcorder.po: util.h
+.endif
diff --git a/sbin/reboot/Makefile.depend b/sbin/reboot/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/reboot/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/recoverdisk/Makefile.depend b/sbin/recoverdisk/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/recoverdisk/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/resolvconf/Makefile.depend b/sbin/resolvconf/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/sbin/resolvconf/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/restore/Makefile.depend b/sbin/restore/Makefile.depend
new file mode 100644
index 0000000..25ca344
--- /dev/null
+++ b/sbin/restore/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/route/Makefile.depend b/sbin/route/Makefile.depend
new file mode 100644
index 0000000..ff427b8
--- /dev/null
+++ b/sbin/route/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+route.o: keywords.h
+route.po: keywords.h
+.endif
diff --git a/sbin/routed/Makefile.depend b/sbin/routed/Makefile.depend
new file mode 100644
index 0000000..2ceda9e
--- /dev/null
+++ b/sbin/routed/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/routed/rtquery/Makefile.depend b/sbin/routed/rtquery/Makefile.depend
new file mode 100644
index 0000000..2ceda9e
--- /dev/null
+++ b/sbin/routed/rtquery/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/rtsol/Makefile.depend b/sbin/rtsol/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/sbin/rtsol/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/savecore/Makefile.depend b/sbin/savecore/Makefile.depend
new file mode 100644
index 0000000..1e192bd
--- /dev/null
+++ b/sbin/savecore/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/sconfig/Makefile.depend b/sbin/sconfig/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/sconfig/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/setkey/Makefile.depend b/sbin/setkey/Makefile.depend
new file mode 100644
index 0000000..03129d2
--- /dev/null
+++ b/sbin/setkey/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipsec \
+ lib/liby \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+parse.o: parse.c
+parse.po: parse.c
+token.o: token.c
+token.o: y.tab.h
+token.po: token.c
+token.po: y.tab.h
+.endif
diff --git a/sbin/shutdown/Makefile.depend b/sbin/shutdown/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/shutdown/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/spppcontrol/Makefile.depend b/sbin/spppcontrol/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/spppcontrol/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/sunlabel/Makefile.depend b/sbin/sunlabel/Makefile.depend
new file mode 100644
index 0000000..25f093b
--- /dev/null
+++ b/sbin/sunlabel/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/swapon/Makefile.depend b/sbin/swapon/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/sbin/swapon/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/sysctl/Makefile.depend b/sbin/sysctl/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/sbin/sysctl/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/tunefs/Makefile.depend b/sbin/tunefs/Makefile.depend
new file mode 100644
index 0000000..250cad8
--- /dev/null
+++ b/sbin/tunefs/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libufs \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sbin/umount/Makefile.depend b/sbin/umount/Makefile.depend
new file mode 100644
index 0000000..6e9b14f
--- /dev/null
+++ b/sbin/umount/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/lib/libcrypto/Makefile.depend b/secure/lib/libcrypto/Makefile.depend
new file mode 100644
index 0000000..e8b704c
--- /dev/null
+++ b/secure/lib/libcrypto/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/msun \
+ secure/lib/libssl \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+cversion.So: buildinf.h
+cversion.o: buildinf.h
+cversion.po: buildinf.h
+.endif
diff --git a/secure/lib/libcrypto/engines/lib4758cca/Makefile.depend b/secure/lib/libcrypto/engines/lib4758cca/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/secure/lib/libcrypto/engines/lib4758cca/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/lib/libcrypto/engines/libaep/Makefile.depend b/secure/lib/libcrypto/engines/libaep/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/secure/lib/libcrypto/engines/libaep/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/lib/libcrypto/engines/libatalla/Makefile.depend b/secure/lib/libcrypto/engines/libatalla/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/secure/lib/libcrypto/engines/libatalla/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/lib/libcrypto/engines/libchil/Makefile.depend b/secure/lib/libcrypto/engines/libchil/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/secure/lib/libcrypto/engines/libchil/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/lib/libcrypto/engines/libcswift/Makefile.depend b/secure/lib/libcrypto/engines/libcswift/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/secure/lib/libcrypto/engines/libcswift/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/lib/libcrypto/engines/libnuron/Makefile.depend b/secure/lib/libcrypto/engines/libnuron/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/secure/lib/libcrypto/engines/libnuron/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/lib/libcrypto/engines/libsureware/Makefile.depend b/secure/lib/libcrypto/engines/libsureware/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/secure/lib/libcrypto/engines/libsureware/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/lib/libcrypto/engines/libubsec/Makefile.depend b/secure/lib/libcrypto/engines/libubsec/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/secure/lib/libcrypto/engines/libubsec/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/lib/libssh/Makefile.depend b/secure/lib/libssh/Makefile.depend
new file mode 100644
index 0000000..2470419
--- /dev/null
+++ b/secure/lib/libssh/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libkrb5 \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/lib/libssl/Makefile.depend b/secure/lib/libssl/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/secure/lib/libssl/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/libexec/sftp-server/Makefile.depend b/secure/libexec/sftp-server/Makefile.depend
new file mode 100644
index 0000000..d4a2b7e
--- /dev/null
+++ b/secure/libexec/sftp-server/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libz \
+ secure/lib/libcrypto \
+ secure/lib/libssh \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/libexec/ssh-keysign/Makefile.depend b/secure/libexec/ssh-keysign/Makefile.depend
new file mode 100644
index 0000000..d4a2b7e
--- /dev/null
+++ b/secure/libexec/ssh-keysign/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libz \
+ secure/lib/libcrypto \
+ secure/lib/libssh \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/libexec/ssh-pkcs11-helper/Makefile.depend b/secure/libexec/ssh-pkcs11-helper/Makefile.depend
new file mode 100644
index 0000000..d4a2b7e
--- /dev/null
+++ b/secure/libexec/ssh-pkcs11-helper/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libz \
+ secure/lib/libcrypto \
+ secure/lib/libssh \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/usr.bin/bdes/Makefile.depend b/secure/usr.bin/bdes/Makefile.depend
new file mode 100644
index 0000000..1ae71d9
--- /dev/null
+++ b/secure/usr.bin/bdes/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/usr.bin/openssl/Makefile.depend b/secure/usr.bin/openssl/Makefile.depend
new file mode 100644
index 0000000..6435f70
--- /dev/null
+++ b/secure/usr.bin/openssl/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+ secure/lib/libcrypto \
+ secure/lib/libssl \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/usr.bin/scp/Makefile.depend b/secure/usr.bin/scp/Makefile.depend
new file mode 100644
index 0000000..d4a2b7e
--- /dev/null
+++ b/secure/usr.bin/scp/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libz \
+ secure/lib/libcrypto \
+ secure/lib/libssh \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/usr.bin/sftp/Makefile.depend b/secure/usr.bin/sftp/Makefile.depend
new file mode 100644
index 0000000..6452c55
--- /dev/null
+++ b/secure/usr.bin/sftp/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libedit \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libz \
+ lib/ncurses/ncurses \
+ secure/lib/libcrypto \
+ secure/lib/libssh \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/usr.bin/ssh-add/Makefile.depend b/secure/usr.bin/ssh-add/Makefile.depend
new file mode 100644
index 0000000..d4a2b7e
--- /dev/null
+++ b/secure/usr.bin/ssh-add/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libz \
+ secure/lib/libcrypto \
+ secure/lib/libssh \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/usr.bin/ssh-agent/Makefile.depend b/secure/usr.bin/ssh-agent/Makefile.depend
new file mode 100644
index 0000000..d4a2b7e
--- /dev/null
+++ b/secure/usr.bin/ssh-agent/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libz \
+ secure/lib/libcrypto \
+ secure/lib/libssh \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/usr.bin/ssh-keygen/Makefile.depend b/secure/usr.bin/ssh-keygen/Makefile.depend
new file mode 100644
index 0000000..d4a2b7e
--- /dev/null
+++ b/secure/usr.bin/ssh-keygen/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libz \
+ secure/lib/libcrypto \
+ secure/lib/libssh \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/usr.bin/ssh-keyscan/Makefile.depend b/secure/usr.bin/ssh-keyscan/Makefile.depend
new file mode 100644
index 0000000..d4a2b7e
--- /dev/null
+++ b/secure/usr.bin/ssh-keyscan/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libz \
+ secure/lib/libcrypto \
+ secure/lib/libssh \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/usr.bin/ssh/Makefile.depend b/secure/usr.bin/ssh/Makefile.depend
new file mode 100644
index 0000000..37b112f
--- /dev/null
+++ b/secure/usr.bin/ssh/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/gssapi \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libkrb5 \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libgssapi \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libz \
+ secure/lib/libcrypto \
+ secure/lib/libssh \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/secure/usr.sbin/sshd/Makefile.depend b/secure/usr.sbin/sshd/Makefile.depend
new file mode 100644
index 0000000..255e652
--- /dev/null
+++ b/secure/usr.sbin/sshd/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/gssapi \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libgssapi_krb5 \
+ kerberos5/lib/libkrb5 \
+ lib/${CSU_DIR} \
+ lib/libbsm \
+ lib/libc \
+ lib/libcrypt \
+ lib/libgssapi \
+ lib/libpam/libpam \
+ lib/libutil \
+ lib/libwrap \
+ lib/libz \
+ secure/lib/libcrypto \
+ secure/lib/libssh \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/colldef/Makefile.depend b/share/colldef/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/colldef/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/dict/Makefile.depend b/share/dict/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/dict/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/doc/IPv6/Makefile.depend b/share/doc/IPv6/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/doc/IPv6/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/doc/bind9/Makefile.depend b/share/doc/bind9/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/doc/bind9/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/doc/legal/intel_ipw/Makefile.depend b/share/doc/legal/intel_ipw/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/doc/legal/intel_ipw/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/doc/legal/intel_iwi/Makefile.depend b/share/doc/legal/intel_iwi/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/doc/legal/intel_iwi/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/doc/legal/intel_iwn/Makefile.depend b/share/doc/legal/intel_iwn/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/doc/legal/intel_iwn/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/doc/legal/intel_wpi/Makefile.depend b/share/doc/legal/intel_wpi/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/doc/legal/intel_wpi/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/doc/llvm/Makefile.depend b/share/doc/llvm/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/doc/llvm/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/doc/llvm/clang/Makefile.depend b/share/doc/llvm/clang/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/doc/llvm/clang/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/examples/libvgl/Makefile.depend b/share/examples/libvgl/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/share/examples/libvgl/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/APPLE/Makefile.depend b/share/i18n/csmapper/APPLE/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/APPLE/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/AST/Makefile.depend b/share/i18n/csmapper/AST/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/AST/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/BIG5/Makefile.depend b/share/i18n/csmapper/BIG5/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/BIG5/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/CNS/Makefile.depend b/share/i18n/csmapper/CNS/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/CNS/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/CP/Makefile.depend b/share/i18n/csmapper/CP/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/CP/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/EBCDIC/Makefile.depend b/share/i18n/csmapper/EBCDIC/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/EBCDIC/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/GB/Makefile.depend b/share/i18n/csmapper/GB/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/GB/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/GEORGIAN/Makefile.depend b/share/i18n/csmapper/GEORGIAN/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/GEORGIAN/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/ISO-8859/Makefile.depend b/share/i18n/csmapper/ISO-8859/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/ISO-8859/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/ISO646/Makefile.depend b/share/i18n/csmapper/ISO646/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/i18n/csmapper/ISO646/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/JIS/Makefile.depend b/share/i18n/csmapper/JIS/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/JIS/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/KAZAKH/Makefile.depend b/share/i18n/csmapper/KAZAKH/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/KAZAKH/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/KOI/Makefile.depend b/share/i18n/csmapper/KOI/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/KOI/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/KS/Makefile.depend b/share/i18n/csmapper/KS/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/KS/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/MISC/Makefile.depend b/share/i18n/csmapper/MISC/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/MISC/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/i18n/csmapper/TCVN/Makefile.depend b/share/i18n/csmapper/TCVN/Makefile.depend
new file mode 100644
index 0000000..8b6d5ba
--- /dev/null
+++ b/share/i18n/csmapper/TCVN/Makefile.depend
@@ -0,0 +1,15 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ usr.bin/mkcsmapper_static \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man1/Makefile.depend b/share/man/man1/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man1/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man3/Makefile.depend b/share/man/man3/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man3/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man4/Makefile.depend b/share/man/man4/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man4/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man4/man4.arm/Makefile.depend b/share/man/man4/man4.arm/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man4/man4.arm/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man4/man4.i386/Makefile.depend b/share/man/man4/man4.i386/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man4/man4.i386/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man4/man4.powerpc/Makefile.depend b/share/man/man4/man4.powerpc/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man4/man4.powerpc/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man4/man4.sparc64/Makefile.depend b/share/man/man4/man4.sparc64/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man4/man4.sparc64/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man5/Makefile.depend b/share/man/man5/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man5/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man6/Makefile.depend b/share/man/man6/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man6/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man7/Makefile.depend b/share/man/man7/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man7/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man8/Makefile.depend b/share/man/man8/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man8/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/man/man9/Makefile.depend b/share/man/man9/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/man/man9/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/me/Makefile.depend b/share/me/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/me/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/misc/Makefile.depend b/share/misc/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/misc/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/mk/Makefile.depend b/share/mk/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/mk/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/mk/auto.obj.mk b/share/mk/auto.obj.mk
new file mode 100644
index 0000000..cd4b2b0
--- /dev/null
+++ b/share/mk/auto.obj.mk
@@ -0,0 +1,57 @@
+# $Id: auto.obj.mk,v 1.8 2011/08/08 17:35:20 sjg Exp $
+#
+# @(#) Copyright (c) 2004, Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+#
+
+ECHO_TRACE ?= echo
+
+.ifndef Mkdirs
+# A race condition in some versions of mkdir, means that it can bail
+# if another process made a dir that mkdir expected to.
+# We repeat the mkdir -p a number of times to try and work around this.
+# We stop looping as soon as the dir exists.
+# If we get to the end of the loop, a plain mkdir will issue an error.
+Mkdirs= Mkdirs() { \
+ for d in $$*; do \
+ for i in 1 2 3 4 5 6; do \
+ mkdir -p $$d; \
+ test -d $$d && return 0; \
+ done > /dev/null 2>&1; \
+ mkdir $$d || exit $$?; \
+ done; }
+.endif
+
+# if MKOBJDIRS is set to auto (and NOOBJ isn't defined) do some magic...
+# This will automatically create objdirs as needed.
+# Skip it if we are just doing 'clean'.
+.if !defined(NOOBJ) && !defined(NO_OBJ) && ${MKOBJDIRS:Uno} == auto
+# Use __objdir here so it is easier to tweak without impacting
+# the logic.
+__objdir?= ${MAKEOBJDIR}
+__objdir:= ${__objdir:tA}
+.if ${.OBJDIR} != ${__objdir}
+# We need to chdir, make the directory if needed
+.if !exists(${__objdir}/) && \
+ (${.TARGETS} == "" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} != "")
+# This will actually make it...
+__objdir_made != echo ${__objdir}/; umask ${OBJDIR_UMASK:U002}; \
+ ${ECHO_TRACE} "[Creating objdir ${__objdir}...]" >&2; \
+ ${Mkdirs}; Mkdirs ${__objdir}
+.endif
+# This causes make to use the specified directory as .OBJDIR
+.OBJDIR: ${__objdir}
+.if ${.OBJDIR} != ${__objdir} && ${__objdir_made:Uno:M${__objdir}/*} != ""
+.error could not use ${__objdir}
+.endif
+.endif
+.endif
diff --git a/share/mk/bsd.dep.mk b/share/mk/bsd.dep.mk
index deac736..64e0d3c 100644
--- a/share/mk/bsd.dep.mk
+++ b/share/mk/bsd.dep.mk
@@ -119,6 +119,17 @@ ${_YC:R}.o: ${_YC}
.endfor
.endif
+.if defined(.PARSEDIR)
+.if ${MK_META_MODE} == "yes"
+.include <meta.autodep.mk>
+# this depend: bypasses that below
+# the dependency helps when bootstrapping
+depend: beforedepend ${DPSRCS} ${SRCS} afterdepend
+beforedepend:
+afterdepend: beforedepend
+.endif
+.endif
+
.if !target(depend)
.if defined(SRCS)
depend: beforedepend ${DEPENDFILE} afterdepend
diff --git a/share/mk/bsd.files.mk b/share/mk/bsd.files.mk
index 240f958..9ddb315 100644
--- a/share/mk/bsd.files.mk
+++ b/share/mk/bsd.files.mk
@@ -22,6 +22,10 @@ ${group}OWN?= ${SHAREOWN}
${group}GRP?= ${SHAREGRP}
${group}MODE?= ${SHAREMODE}
${group}DIR?= ${BINDIR}
+.if !make(buildincludes)
+STAGE_SETS+= ${group}
+.endif
+STAGE_DIR.${group}= ${STAGE_OBJTOP}${${group}DIR}
_${group}FILES=
.for file in ${${group}}
@@ -37,6 +41,12 @@ ${group}NAME_${file:T}?= ${${group}NAME}
.else
${group}NAME_${file:T}?= ${file:T}
.endif
+.if !make(buildincludes)
+STAGE_AS_SETS+= ${group}
+.endif
+STAGE_AS_${file:T}= ${${group}NAME_${file:T}}
+stage_as.${group}: ${file}
+
installfiles: _${group}INS_${file:T}
_${group}INS_${file:T}: ${file}
${INSTALL} -o ${${group}OWN_${.ALLSRC:T}} \
@@ -48,6 +58,8 @@ _${group}FILES+= ${file}
.endif
.endfor
.if !empty(_${group}FILES)
+stage_files.${group}: ${_${group}FILES}
+
installfiles: _${group}INS
_${group}INS: ${_${group}FILES}
.if defined(${group}NAME)
@@ -67,3 +79,12 @@ _${group}INS: ${_${group}FILES}
realinstall: installfiles
.ORDER: beforeinstall installfiles
+
+.if ${MK_STAGING} != "no"
+.if !empty(STAGE_SETS)
+buildfiles: stage_files
+.if !empty(STAGE_AS_SETS)
+buildfiles: stage_as
+.endif
+.endif
+.endif
diff --git a/share/mk/bsd.incs.mk b/share/mk/bsd.incs.mk
index d51fb17..8182b30 100644
--- a/share/mk/bsd.incs.mk
+++ b/share/mk/bsd.incs.mk
@@ -24,6 +24,8 @@ ${group}OWN?= ${BINOWN}
${group}GRP?= ${BINGRP}
${group}MODE?= ${NOBINMODE}
${group}DIR?= ${INCLUDEDIR}
+STAGE_SETS+= ${group}
+STAGE_DIR.${group}= ${STAGE_OBJTOP}${${group}DIR}
_${group}INCS=
.for header in ${${group}}
@@ -39,6 +41,10 @@ ${group}NAME_${header:T}?= ${${group}NAME}
.else
${group}NAME_${header:T}?= ${header:T}
.endif
+STAGE_AS_SETS+= ${group}
+STAGE_AS_${header:T}= ${${group}NAME_${header:T}}
+stage_as.${group}: ${header}
+
installincludes: _${group}INS_${header:T}
_${group}INS_${header:T}: ${header}
${INSTALL} -C -o ${${group}OWN_${.ALLSRC:T}} \
@@ -50,6 +56,8 @@ _${group}INCS+= ${header}
.endif
.endfor
.if !empty(_${group}INCS)
+stage_files.${group}: ${_${group}INCS}
+
installincludes: _${group}INS
_${group}INS: ${_${group}INCS}
.if defined(${group}NAME)
@@ -81,4 +89,15 @@ installincludes:
realinstall: installincludes
.ORDER: beforeinstall installincludes
+.if ${MK_STAGING} != "no"
+.if !target(stage_includes)
+.if !empty(STAGE_SETS)
+buildincludes: stage_files
+.if !empty(STAGE_AS_SETS)
+buildincludes: stage_as
+.endif
+.endif
+.endif
+.endif
+
.endif # !defined(NO_INCS) && ${MK_TOOLCHAIN} != "no"
diff --git a/share/mk/bsd.init.mk b/share/mk/bsd.init.mk
index 72a6de0..f5c31a5 100644
--- a/share/mk/bsd.init.mk
+++ b/share/mk/bsd.init.mk
@@ -6,10 +6,19 @@
.if !target(__<bsd.init.mk>__)
__<bsd.init.mk>__:
+.sinclude "local.init.mk"
.if exists(${.CURDIR}/../Makefile.inc)
.include "${.CURDIR}/../Makefile.inc"
.endif
.include <bsd.compat.mk>
.include <bsd.own.mk>
.MAIN: all
+
+.if defined(.PARSEDIR)
+.if ${.MAKE.LEVEL:U1} == 0 && ${BUILD_AT_LEVEL0:Uyes:tl} == "no"
+# this tells lib.mk and prog.mk to not actually build anything
+_SKIP_BUILD = not building at level 0
+.endif
+.endif
+
.endif # !target(__<bsd.init.mk>__)
diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk
index efaf9dc..236e12d 100644
--- a/share/mk/bsd.lib.mk
+++ b/share/mk/bsd.lib.mk
@@ -113,7 +113,9 @@ PO_FLAG=-pg
${CC} ${PICFLAG} -DPIC ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
${CTFCONVERT_CMD}
+.if !defined(_SKIP_BUILD)
all: objwarn
+.endif
.include <bsd.symver.mk>
@@ -219,11 +221,15 @@ ${LINTLIB}: ${LINTOBJS}
.endif # !defined(INTERNALLIB)
+.if defined(_SKIP_BUILD)
+all:
+.else
all: ${_LIBS}
.if ${MK_MAN} != "no"
all: _manpages
.endif
+.endif
_EXTRADEPEND:
@TMP=_depend$$$$; \
@@ -397,3 +403,15 @@ clean:
.include <bsd.obj.mk>
.include <bsd.sys.mk>
+
+.if ${MK_STAGING} != "no"
+.if defined(_SKIP_BUILD)
+stage_libs stage_files stage_as:
+.else
+.if !empty(_LIBS)
+stage_libs: ${_LIBS}
+all: stage_libs
+.endif
+.include <meta.stage.mk>
+.endif
+.endif
diff --git a/share/mk/bsd.obj.mk b/share/mk/bsd.obj.mk
index 634261e..38afcde 100644
--- a/share/mk/bsd.obj.mk
+++ b/share/mk/bsd.obj.mk
@@ -50,6 +50,15 @@ CANONICALOBJDIR:=${MAKEOBJDIR}
CANONICALOBJDIR:=/usr/obj${.CURDIR}
.endif
+.if defined(.PARSEDIR) && !defined(NO_OBJ) && !defined(NO_AUTO_OBJ)
+.if ${MK_AUTO_OBJ} == "yes"
+__objdir?= ${CANONICALOBJDIR}
+# this is what auto.obj.mk wants to see
+MKOBJDIRS=auto
+.include "auto.obj.mk"
+.endif
+.endif
+
#
# Warn of unorthodox object directory.
#
diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk
index 3a2658c..52aac91 100644
--- a/share/mk/bsd.own.mk
+++ b/share/mk/bsd.own.mk
@@ -417,6 +417,7 @@ __DEFAULT_YES_OPTIONS = \
ZONEINFO
__DEFAULT_NO_OPTIONS = \
+ AUTO_OBJ \
BMAKE \
BSD_GREP \
BIND_IDN \
@@ -432,9 +433,12 @@ __DEFAULT_NO_OPTIONS = \
ICONV \
IDEA \
INSTALL_AS_USER \
+ META_MODE \
NAND \
OFED \
- SHARED_TOOLCHAIN
+ SHARED_TOOLCHAIN \
+ STAGING \
+ STAGING_PROG
#
# Default behaviour of some options depends on the architecture. Unfortunately
@@ -584,6 +588,16 @@ MK_GDB:= no
MK_CLANG_IS_CC:= no
.endif
+.if !defined(.PARSEDIR)
+MK_AUTO_OBJ:= no
+MK_META_MODE:= no
+.endif
+
+.if ${MK_META_MODE} == "no"
+MK_STAGING:= no
+MK_STAGING_PROG:= no
+.endif
+
#
# Set defaults for the MK_*_SUPPORT variables.
#
diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk
index 3c306eb..82a3b07 100644
--- a/share/mk/bsd.prog.mk
+++ b/share/mk/bsd.prog.mk
@@ -102,10 +102,14 @@ MAN1= ${MAN}
.endif
.endif
+.if defined(_SKIP_BUILD)
+all:
+.else
all: objwarn ${PROG} ${SCRIPTS}
.if ${MK_MAN} != "no"
all: _manpages
.endif
+.endif
.if defined(PROG)
CLEANFILES+= ${PROG}
@@ -230,3 +234,25 @@ ${OBJS}: ${SRCS:M*.h}
.if defined(PORTNAME)
.include <bsd.pkg.mk>
.endif
+
+.if ${MK_STAGING} != "no"
+.if defined(_SKIP_BUILD)
+stage_files stage_as:
+.else
+# normally only libs and includes are staged
+.if ${MK_STAGING_PROG:Uno} != "no"
+STAGE_SETS+= prog
+STAGE_DIR.prog= ${STAGE_OBJTOP}${BINDIR}
+.if !empty(PROG)
+all: stage_files
+stage_files.prog: ${PROG}
+.endif
+.if !empty(SYMLINKS)
+all: stage_symlinks
+STAGE_SYMLINKS.prog= ${SYMLINKS}
+.endif
+
+.endif
+.include <meta.stage.mk>
+.endif
+.endif
diff --git a/share/mk/bsd.subdir.mk b/share/mk/bsd.subdir.mk
index a66ab9b..f9962df 100644
--- a/share/mk/bsd.subdir.mk
+++ b/share/mk/bsd.subdir.mk
@@ -31,6 +31,15 @@
.include <bsd.init.mk>
+.if defined(.PARSEDIR) && !defined(NEED_SUBDIR)
+.if ${.MAKE.LEVEL} == 0 && ${.MAKE.MODE:Mmeta*} != "" && !empty(SUBDIR) && !(make(clean*) || make(destroy*))
+.include <meta.subdir.mk>
+# ignore this
+_SUBDIR:
+.endif
+.endif
+.if !target(_SUBDIR)
+
DISTRIBUTION?= base
.if !target(distribute)
distribute:
@@ -82,6 +91,8 @@ ${__target}:
${_+_}set -e; cd ${.CURDIR}; ${MAKE} build${__target}; ${MAKE} install${__target}
.endfor
+.endif
+
.if !target(install)
.if !target(beforeinstall)
beforeinstall:
diff --git a/share/mk/dirdeps.mk b/share/mk/dirdeps.mk
new file mode 100644
index 0000000..e8c02b7
--- /dev/null
+++ b/share/mk/dirdeps.mk
@@ -0,0 +1,368 @@
+# $Id: dirdeps.mk,v 1.22 2012/04/25 15:12:29 sjg Exp $
+
+# Copyright (c) 2010-2012, Juniper Networks, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Much of the complexity here is for supporting cross-building.
+# If a tree does not support that, simply using plain Makefile.depend
+# should provide sufficient clue.
+# Otherwise the recommendation is to use Makefile.depend.${MACHINE}
+# as expected below.
+
+# Note: this file gets multiply included.
+# This is what we do with DIRDEPS
+
+# DIRDEPS:
+# This is a list of directories - relative to SRCTOP, it is only
+# of interest to .MAKE.LEVEL 0.
+# In some cases the entry may be qualified with a .<machine>
+# suffix, for example to force building something for the pseudo
+# machines "host" or "common" regardless of current ${MACHINE}.
+# All unqualified entries end up being qualified with .${MACHINE}
+# and _DIRDEPS_USE below, uses the suffix to set MACHINE
+# correctly when visiting each entry.
+#
+# Each entry is also converted into a set of paths to look for
+# Makefile.depend.<machine> to learn the dependencies of each.
+# Each Makefile.depend.<machine> sets DEP_RELDIR to be the
+# the RELDIR (path relative to SRCTOP) for its directory, and
+# DEP_MACHINE to its suffix (<machine>), further since
+# each Makefile.depend.<machine> includes dirdeps.mk, this
+# processing is recursive and results in .MAKE.LEVEL 0 learning the
+# dependencies of the tree wrt the initial directory (_DEP_RELDIR).
+#
+# BUILD_AT_LEVEL0
+# Indicates whether .MAKE.LEVEL 0 builds anything:
+# if "no" sub-makes are used to build everything,
+# if "yes" sub-makes are only used to build for other machines.
+
+.if ${.MAKE.LEVEL} == 0
+# only the first instance is interested in all this
+
+# First off, we want to know what ${MACHINE} to build for.
+# This can be complicated if we are using a mixture of ${MACHINE} specific
+# and non-specific Makefile.depend*
+
+.if !target(_DIRDEP_USE)
+# do some setup we only need once
+_CURDIR ?= ${.CURDIR}
+
+.if !defined(.MAKE.DEPENDFILE_PREFERENCE)
+# this makes the logic below neater?
+.MAKE.DEPENDFILE_PREFERENCE = ${_CURDIR}/${.MAKE.DEPENDFILE:T}
+.if ${.MAKE.DEPENDFILE:E} == "${MACHINE}"
+.MAKE.DEPENDFILE_PREFERENCE += ${_CURDIR}/${.MAKE.DEPENDFILE:T:R}
+.endif
+.endif
+
+_default_dependfile := ${.MAKE.DEPENDFILE_PREFERENCE:[1]:T}
+_machine_dependfiles := ${.MAKE.DEPENDFILE_PREFERENCE:M*.${MACHINE}}
+
+# for machine specific dependfiles we require ${MACHINE} to be at the end
+# also for the sake of sanity we require a common prefix
+.if !defined(.MAKE.DEPENDFILE_PREFIX)
+.if !empty(_machine_dependfiles)
+.MAKE.DEPENDFILE_PREFIX := ${_machine_dependfiles:[1]:T:R}
+.else
+.MAKE.DEPENDFILE_PREFIX := ${_default_dependfile:T}
+.endif
+.endif
+
+
+# this is how we identify non-machine specific dependfiles
+N_notmachine := ${.MAKE.DEPENDFILE_PREFERENCE:E:N${MACHINE}:${M_ListToSkip}}
+
+.endif # !target(_DIRDEP_USE)
+
+_last_dependfile := ${.MAKE.MAKEFILES:M*/${.MAKE.DEPENDFILE_PREFIX}*:[-1]}
+
+# Note: if a makefile is read many times, the above
+# will not work, so we also test for DEP_MACHINE==depend below.
+.if empty(_last_dependfile)
+# we haven't included one yet
+DEP_MACHINE ?= ${TARGET_MACHINE:U${MACHINE}}
+# else it should be correctly set by ${.MAKE.DEPENDFILE}
+.elif ${_last_dependfile:E:${N_notmachine}} == "" || ${DEP_MACHINE:Uno:${N_notmachine}} == ""
+# don't rely on manually maintained files to be correct
+DEP_MACHINE := ${_DEP_MACHINE:U${MACHINE}}
+.else
+# just in case
+DEP_MACHINE ?= ${_last_dependfile:E}
+.endif
+
+# pickup customizations
+# as below you can use !target(_DIRDEP_USE) to protect things
+# which should only be done once.
+.-include "local.dirdeps.mk"
+
+# the first time we are included the _DIRDEP_USE target will not be defined
+# we can use this as a clue to do initialization and other one time things.
+.if !target(_DIRDEP_USE)
+# make sure this target exists
+dirdeps:
+
+# We normally expect to be included by Makefile.depend.*
+# which sets the DEP_* macros below.
+DEP_RELDIR ?= ${RELDIR}
+
+# this can cause lots of output!
+# set to a set of glob expressions that might match RELDIR
+DEBUG_DIRDEPS ?= no
+
+# remember the initial value of DEP_RELDIR - we test for it below.
+_DEP_RELDIR := ${DEP_RELDIR}
+
+# things we skip for host tools
+SKIP_HOSTDIR ?=
+
+NSkipHostDir = ${SKIP_HOSTDIR:N*.host:S,$,.host,:N.host:${M_ListToSkip}}
+NSkipHostDep = ${SKIP_HOSTDIR:R:@d@*/$d*.host@:${M_ListToSkip}}
+
+# things we always skip
+# SKIP_DIRDEPS allows for adding entries on command line.
+SKIP_DIR += .host *.WAIT ${SKIP_DIRDEPS}
+
+.ifdef HOSTPROG
+SKIP_DIR += ${SKIP_HOSTDIR}
+.endif
+
+NSkipDir = ${SKIP_DIR:${M_ListToSkip}}
+
+.if defined(NO_DIRDEPS) || defined(NODIRDEPS)
+# confine ourselves to the original dir
+DIRDEPS_FILTER += M${_DEP_RELDIR}*
+.endif
+
+# we supress SUBDIR when visiting the leaves
+# we assume sys.mk will set MACHINE_ARCH
+_DIRDEP_USE: .USE .MAKE
+ @for m in ${.MAKE.MAKEFILE_PREFERENCE}; do \
+ test -s ${.TARGET:R}/$$m || continue; \
+ echo "${TRACER}Checking ${.TARGET:R} for ${.TARGET:E} ..."; \
+ MACHINE=${.TARGET:E} MACHINE_ARCH= NO_SUBDIR=1 \
+ ${.MAKE} -C ${.TARGET:R} || exit 1; \
+ break; \
+ done
+
+.ifdef ALL_MACHINES
+# this is how you limit it to only the machines we have been built for
+# previously.
+.if empty(ONLY_MACHINE_LIST)
+.if !empty(ALL_MACHINE_LIST)
+# ALL_MACHINE_LIST is the list of all legal machines - ignore anything else
+_machine_list != cd ${_CURDIR} && 'ls' -1 ${ALL_MACHINE_LIST:O:u:@m@${.MAKE.DEPENDFILE:T:R}.$m@} 2> /dev/null; echo
+.else
+_machine_list != 'ls' -1 ${_CURDIR}/${.MAKE.DEPENDFILE_PREFIX}.* 2> /dev/null; echo
+.endif
+_only_machines := ${_machine_list:${NIgnoreFiles:UN*.bak}:E:O:u}
+.else
+_only_machines := ${ONLY_MACHINE_LIST}
+.endif
+
+.if empty(_only_machines)
+# we must be boot-strapping
+_only_machines := ${TARGET_MACHINE:U${ALL_MACHINE_LIST:U${DEP_MACHINE}}}
+.endif
+
+.else # ! ALL_MACHINES
+# if ONLY_MACHINE_LIST is set, we are limited to that
+# if TARGET_MACHINE is set - it is really the same as ONLY_MACHINE_LIST
+# otherwise DEP_MACHINE is it - so DEP_MACHINE will match.
+_only_machines := ${ONLY_MACHINE_LIST:U${TARGET_MACHINE:U${DEP_MACHINE}}:M${DEP_MACHINE}}
+.endif
+
+.if !empty(NOT_MACHINE_LIST)
+_only_machines := ${_only_machines:${NOT_MACHINE_LIST:${M_ListToSkip}}}
+.endif
+
+# make sure we have a starting place?
+DIRDEPS ?= ${RELDIR}
+.endif # target
+
+_debug_reldir := ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.${DEP_MACHINE}:L:M$x}@}
+_debug_search := ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.depend:L:M$x}@}
+
+# the rest is done repeatedly for every Makefile.depend we read.
+# if we are anything but the original dir we care only about the
+# machine type we were included for..
+
+.if ${DEP_RELDIR} == "."
+_this_dir := ${SRCTOP}
+.else
+_this_dir := ${SRCTOP}/${DEP_RELDIR}
+.endif
+
+# on rare occasions, there can be a need for extra help
+_dep_hack := ${_this_dir}/${.MAKE.DEPENDFILE_PREFIX}.inc
+.-include "${_dep_hack}"
+
+.if ${DEP_RELDIR} != ${_DEP_RELDIR} || ${DEP_MACHINE} != ${MACHINE}
+# this should be all
+_machines := ${DEP_MACHINE}
+.else
+# this is the machine list we actually use below
+_machines := ${_only_machines}
+
+.if defined(HOSTPROG) || ${DEP_MACHINE} == "host"
+# we need to build this guy's dependencies for host as well.
+_machines += host
+.endif
+
+_machines := ${_machines:O:u}
+.endif
+
+_build_dirs =
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# pickup other machines for this dir if necessary
+.if ${BUILD_AT_LEVEL0:Uyes} == "no"
+_build_dirs += ${_machines:@m@${_CURDIR}.$m@}
+.else
+_build_dirs += ${_machines:N${DEP_MACHINE}:@m@${_CURDIR}.$m@}
+.if ${DEP_MACHINE} == ${MACHINE}
+# pickup local dependencies now
+.-include <.depend>
+.endif
+.endif
+.endif
+
+.if !empty(_debug_reldir)
+.info ${DEP_RELDIR}.${DEP_MACHINE}: _last_dependfile='${_last_dependfile}'
+.info ${DEP_RELDIR}.${DEP_MACHINE}: DIRDEPS='${DIRDEPS}'
+.info ${DEP_RELDIR}.${DEP_MACHINE}: _machines='${_machines}'
+.endif
+
+.if !empty(DIRDEPS)
+
+# this is what we start with
+__depdirs := ${DIRDEPS:${NSkipDir}:${DIRDEPS_FILTER:ts:}:O:u:@d@${SRCTOP}/$d@}
+
+# some entries may be qualified with .<machine>
+# the :M*/*/*.* just tries to limit the dirs we check to likely ones.
+# the ${d:E:M*/*} ensures we don't consider junos/usr.sbin/mgd
+__qual_depdirs := ${__depdirs:M*/*/*.*:@d@${exists($d):?:${"${d:E:M*/*}":?:${exists(${d:R}):?$d:}}}@}
+__unqual_depdirs := ${__depdirs:${__qual_depdirs:Uno:${M_ListToSkip}}}
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# if it was called out - we likely need it.
+__hostdpadd := ${DPADD:U.:M${HOST_OBJTOP}/*:S,${HOST_OBJTOP}/,,:H:${NSkipDir}:${DIRDEPS_FILTER:ts:}:S,$,.host,:N.*:@d@${SRCTOP}/$d@}
+__qual_depdirs += ${__hostdpadd}
+.endif
+
+.if !empty(_debug_reldir)
+.info depdirs=${__depdirs}
+.info qualified=${__qual_depdirs}
+.info unqualified=${__unqual_depdirs}
+.endif
+
+# _build_dirs is what we will feed to _DIRDEP_USE
+_build_dirs += \
+ ${__qual_depdirs:M*.host:${NSkipHostDir}:N.host} \
+ ${__qual_depdirs:N*.host} \
+ ${_machines:@m@${__unqual_depdirs:@d@$d.$m@}@}
+
+_build_dirs := ${_build_dirs:O:u}
+
+# this is where we will pick up more dependencies from
+# the inner inline loops look complex, but save a significant
+# amount of memory compared to a .for loop.
+_depdir_files =
+.for d in ${_build_dirs}
+.if exists($d)
+# easy, we're building for ${MACHINE}
+_depdir_files += ${.MAKE.DEPENDFILE_PREFERENCE:T:@m@${exists($d/$m):?$d/$m:}@:[1]}
+.elif exists(${d:R}) && ${d:R:T} == ${d:T:R}
+# a little more complex - building for another machine
+# we will ensure the file is qualified with a machine
+# so that if necessary _DEP_MACHINE can be set below
+_depdir_files += ${.MAKE.DEPENDFILE_PREFERENCE:T:S,.${MACHINE}$,.${d:E},:@m@${exists(${d:R}/$m):?${d:R}/$m:}@:[1]:@m@${"${m:M*.${d:E}}":?$m:$m.${d:E}}@}
+.endif
+.endfor
+
+# clean up
+_depdir_files := ${_depdir_files:O:u}
+
+.endif # empty DIRDEPS
+
+# Normally if doing make -V something,
+# we do not want to waste time chasing DIRDEPS
+# but if we want to count the number of Makefile.depend* read, we do.
+.if ${.MAKEFLAGS:M-V${_V_READ_DIRDEPS}} == ""
+.if !empty(_build_dirs)
+# this makes it all happen
+dirdeps: ${_build_dirs}
+${_build_dirs}: _DIRDEP_USE
+
+.if !empty(_debug_reldir)
+.info ${DEP_RELDIR}.${DEP_MACHINE}: ${_build_dirs}
+.endif
+
+.for m in ${_machines}
+# it would be nice to do :N${.TARGET}
+.if !empty(__qual_depdirs)
+.for q in ${__qual_depdirs:E:O:u:N$m}
+.if !empty(_debug_reldir) || ${DEBUG_DIRDEPS:@x@${${DEP_RELDIR}.$m:L:M$x}${${DEP_RELDIR}.$q:L:M$x}@} != ""
+.info ${DEP_RELDIR}.$m: ${_build_dirs:M*.$q}
+.endif
+${_this_dir}.$m: ${_build_dirs:M*.$q}
+.endfor
+.endif
+.if !empty(_debug_reldir)
+.info ${DEP_RELDIR}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m}
+.endif
+${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m}
+.endfor
+
+.endif
+
+.for d in ${_depdir_files}
+.if ${.MAKE.MAKEFILES:M${d}} == ""
+.if !empty(_debug_search)
+.info Looking for $d
+.endif
+.if exists($d)
+.include <$d>
+.elif exists(${d:R})
+# an unqualified file exists, we qualified it above so we can set _DEP_MACHINE
+# it might be manually maintained and shared by all machine types
+# tell it the machine we are interested in.
+_DEP_MACHINE := ${d:E}
+.if !empty(_debug_reldir)
+.info loading ${d:R} for ${_DEP_MACHINE}
+.endif
+# pretend we read $d, so we don't come by here again.
+.MAKE.MAKEFILES += $d
+.include <${d:R}>
+.endif
+.endif
+.endfor
+.endif # -V
+
+.elif ${.MAKE.LEVEL} > 42
+.error You should have stopped recursing by now.
+.else
+_DEP_RELDIR := ${DEP_RELDIR}
+# pickup local dependencies
+.-include <.depend>
+.endif
+
diff --git a/share/mk/gendirdeps.mk b/share/mk/gendirdeps.mk
new file mode 100644
index 0000000..890f495
--- /dev/null
+++ b/share/mk/gendirdeps.mk
@@ -0,0 +1,301 @@
+# $Id: gendirdeps.mk,v 1.10 2012/06/30 00:37:50 sjg Exp $
+
+# Copyright (c) 2010, Juniper Networks, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#
+# This makefile [re]generates ${.MAKE.DEPENDFILE}
+#
+
+.include <install-new.mk>
+
+# Assumptions:
+# RELDIR is the relative path from ${SRCTOP} to ${_CURDIR}
+# (SRCTOP is ${SB}/src)
+# _CURDIR is the absolute version of ${.CURDIR}
+# _OBJDIR is the absolute version of ${.OBJDIR}
+# _objroot is realpath of ${_OBJTOP} without ${MACHINE}
+# this may be different from _OBJROOT if $SB/obj is a
+# symlink to another filesystem.
+# _objroot must be a prefix match for _objtop
+
+.MAIN: all
+
+# keep this simple
+.MAKE.MODE = compat
+
+all:
+
+_CURDIR ?= ${.CURDIR}
+_OBJDIR ?= ${.OBJDIR}
+_OBJTOP ?= ${OBJTOP}
+_OBJROOT ?= ${OBJROOT:U${_OBJTOP}}
+_objroot ?= ${_OBJROOT:tA}
+
+_this = ${.PARSEDIR}/${.PARSEFILE}
+
+# remember what to make
+_DEPENDFILE := ${_CURDIR}/${.MAKE.DEPENDFILE:T}
+
+# We do _not_ want to read our own output!
+.MAKE.DEPENDFILE = /dev/null
+
+# caller should have set this
+META_FILES ?= ${.MAKE.META.FILES}
+
+.if !empty(META_FILES)
+
+.if ${.MAKE.LEVEL} > 0 && !empty(GENDIRDEPS_FILTER)
+# so we can compare below
+.-include <${_DEPENDFILE}>
+# yes, I mean :U with no value
+_DIRDEPS := ${DIRDEPS:U:O:u}
+.endif
+
+META_FILES := ${META_FILES:T:O:u}
+.export META_FILES
+
+# pickup customizations
+.-include "local.gendirdeps.mk"
+
+# these are actually prefixes that we'll skip
+# they should all be absolute paths
+SKIP_GENDIRDEPS ?=
+.if !empty(SKIP_GENDIRDEPS)
+_skip_gendirdeps = egrep -v '^(${SKIP_GENDIRDEPS:O:u:ts|})' |
+.else
+_skip_gendirdeps =
+.endif
+
+# this (*should* be set in meta.sys.mk)
+# is the script that extracts what we want.
+META2DEPS ?= ${.PARSEDIR}/meta2deps.sh
+META2DEPS := ${META2DEPS}
+
+.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != "" && ${DEBUG_GENDIRDEPS:Uno:Mmeta2d*} != ""
+_time = time
+_sh_x = sh -x
+_py_d = -ddd
+.else
+_time =
+_sh_x =
+_py_d =
+.endif
+
+.if ${META2DEPS:E} == "py"
+# we can afford to do this all the time.
+DPDEPS ?= no
+META2DEPS_CMD = ${_time} ${PYTHON} ${META2DEPS} ${_py_d} \
+ -R ${RELDIR} -H ${HOST_TARGET} -O ${M2D_OBJROOT}
+.if ${DPDEPS:tl} != "no"
+META2DEPS_CMD += -D ${DPDEPS}
+.endif
+.if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} == ""
+# meta2deps.py only groks objroot
+# so we need to give it what it expects
+M2D_OBJROOT = ${OBJTOP}/
+# and tell it not to add machine qualifiers
+META2DEPS_ARGS += MACHINE=none
+.else
+.if defined(SB_OBJROOT)
+M2D_OBJROOT ?= ${SB_OBJROOT}
+.else
+M2D_OBJROOT = ${OBJTOP}/
+.endif
+.endif
+.if defined(SB_BACKING_SB)
+META2DEPS_CMD += -S ${SB_BACKING_SB}/src -O ${SB_BACKING_SB}/${SB_OBJPREFIX}
+.endif
+META2DEPS_FILTER = sed 's,^src:,${SRCTOP}/,;s,^\([^/]\),${OBJTOP}/\1,' |
+.elif ${META2DEPS:E} == "sh"
+META2DEPS_CMD = ${_time} ${_sh_x} ${META2DEPS} \
+ OBJTOP=${_objtop} SB_OBJROOT=${_objroot}
+.else
+META2DEPS_CMD ?= ${META2DEPS}
+.endif
+
+# we are only interested in the dirs
+# sepecifically those we read something from.
+# we canonicalize them to keep things simple
+# if we are using a split-fs sandbox, it gets a little messier.
+_objtop := ${_OBJTOP:tA}
+dir_list != cd ${_OBJDIR} && \
+ ${META2DEPS_CMD} MACHINE=${MACHINE} \
+ SRCTOP=${SRCTOP} RELDIR=${RELDIR} CURDIR=${_CURDIR} \
+ ${META2DEPS_ARGS} \
+ ${META_FILES:O:u} | ${META2DEPS_FILTER} ${_skip_gendirdeps} \
+ sed 's,//*$$,,;s,\.${HOST_TARGET}$$,.host,'
+
+.if ${dir_list:M*ERROR\:*} != ""
+.warning ${dir_list:tW:C,.*(ERROR),\1,}
+.warning Skipping ${_DEPENDFILE:S,${SRCTOP}/,,}
+# we are not going to update anything
+.else
+
+.if !empty(DPADD)
+_nonlibs := ${DPADD:T:Nlib*:N*include}
+.if !empty(_nonlibs)
+dir_list += ${_nonlibs:@x@${DPADD:M*/$x}@:H:tA}
+.endif
+.endif
+
+# DIRDEPS represent things that had to have been built first
+# so they should all be undir OBJTOP.
+# Note that ${_OBJTOP}/bsd/include/machine will get reported
+# to us as $SRCTOP/bsd/sys/$MACHINE_ARCH/include meaning we
+# will want to visit bsd/include
+# so we add
+# ${"${dir_list:M*bsd/sys/${MACHINE_ARCH}/include}":?bsd/include:}
+# to GENDIRDEPS_DIR_LIST_XTRAS
+dirdep_list = \
+ ${dir_list:M${_objtop}*/*:C,${_objtop}[^/]*/,,} \
+ ${GENDIRDEPS_DIR_LIST_XTRAS}
+
+# anything we use from an object dir other than ours
+# needs to be qualified with its .<machine> suffix
+# (we used the pseudo machine "host" for the HOST_TARGET).
+qualdir_list = \
+ ${dir_list:M${_objroot}*/*/*:N${SRCTOP}*:N${_objtop}*:C,${_objroot}([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,}
+
+.if ${_OBJROOT} != ${_objroot}
+dirdep_list += \
+ ${dir_list:M${_OBJTOP}*/*:C,${_OBJTOP}[^/]*/,,}
+
+qualdir_list += \
+ ${dir_list:M${_OBJROOT}*/*/*:N${SRCTOP}*:N${_OBJTOP}*:C,${_OBJROOT}([^/]+)/(.*),\2.\1,:S,.${HOST_TARGET},.host,}
+.endif
+
+dirdep_list := ${dirdep_list:O:u}
+qualdir_list := ${qualdir_list:O:u}
+
+DIRDEPS = \
+ ${dirdep_list:N${RELDIR}:N${RELDIR}/*} \
+ ${qualdir_list:N${RELDIR}.*:N${RELDIR}/*}
+
+# We only consider things below $RELDIR/ if they have a makefile.
+# This is the same test that _DIRDEPS_USE applies.
+# We have do a double test with dirdep_list as it _may_ contain
+# qualified dirs - if we got anything from a stage dir.
+# qualdir_list we know are all qualified.
+# It would be nice do peform this check for all of DIRDEPS,
+# but we cannot assume that all of the tree is present,
+# in fact we can only assume that RELDIR is.
+DIRDEPS += \
+ ${dirdep_list:M${RELDIR}/*:@d@${.MAKE.MAKEFILE_PREFERENCE:@m@${exists(${SRCTOP}/$d/$m):?$d:${exists(${SRCTOP}/${d:R}/$m):?$d:}}@}@} \
+ ${qualdir_list:M${RELDIR}/*:@d@${.MAKE.MAKEFILE_PREFERENCE:@m@${exists(${SRCTOP}/${d:R}/$m):?$d:}@}@}
+
+DIRDEPS := ${DIRDEPS:${GENDIRDEPS_FILTER:UNno:ts:}:O:u}
+
+.if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != ""
+.info ${RELDIR}: dir_list='${dir_list}'
+.info ${RELDIR}: dirdep_list='${dirdep_list}'
+.info ${RELDIR}: qualdir_list='${qualdir_list}'
+.info ${RELDIR}: SKIP_GENDIRDEPS='${SKIP_GENDIRDEPS}'
+.info ${RELDIR}: GENDIRDEPS_FILTER='${GENDIRDEPS_FILTER}'
+.info ${RELDIR}: FORCE_DPADD='${DPADD}'
+.info ${RELDIR}: DIRDEPS='${DIRDEPS}'
+.endif
+
+# SRC_DIRDEPS is for checkout logic
+src_dirdep_list = \
+ ${dir_list:M${SRCTOP}/*:S,${SRCTOP}/,,}
+
+SRC_DIRDEPS = \
+ ${src_dirdep_list:N${RELDIR}:N${RELDIR}/*:C,(/h)/.*,,}
+
+SRC_DIRDEPS := ${SRC_DIRDEPS:${GENDIRDEPS_SRC_FILTER:UN/*:ts:}:O:u}
+
+# if you want to capture SRC_DIRDEPS in .MAKE.DEPENDFILE put
+# SRC_DIRDEPS_FILE = ${_DEPENDFILE}
+# in local.gendirdeps.mk
+.if ${SRC_DIRDEPS_FILE:Uno:tl} != "no"
+ECHO_SRC_DIRDEPS = echo 'SRC_DIRDEPS = \'; echo '${SRC_DIRDEPS:@d@ $d \\${.newline}@}'; echo;
+
+.if ${SRC_DIRDEPS_FILE:T} == ${_DEPENDFILE:T}
+_include_src_dirdeps = ${ECHO_SRC_DIRDEPS}
+.else
+all: ${SRC_DIRDEPS_FILE}
+.if !target(${SRC_DIRDEPS_FILE})
+${SRC_DIRDEPS_FILE}: ${META_FILES} ${_this} ${META2DEPS}
+ @(${ECHO_SRC_DIRDEPS}) > $@
+.endif
+.endif
+.endif
+_include_src_dirdeps ?=
+
+all: ${_DEPENDFILE}
+
+# if this is going to exist it would be there by now
+.if !exists(.depend)
+CAT_DEPEND = /dev/null
+.endif
+CAT_DEPEND ?= .depend
+
+.if !empty(_DIRDEPS) && ${DIRDEPS} != ${_DIRDEPS}
+# we may have changed a filter
+.PHONY: ${_DEPENDFILE}
+.endif
+
+# 'cat .depend' should suffice, but if we are mixing build modes
+# .depend may contain things we don't want.
+# The sed command at the end of the stream, allows for the filters
+# to output _{VAR} tokens which we will turn into proper ${VAR} references.
+${_DEPENDFILE}: ${CAT_DEPEND:M.depend} ${META_FILES:O:u:@m@${exists($m):?$m:}@} ${_this} ${META2DEPS}
+ @(echo '# Autogenerated - do NOT edit!'; echo; \
+ echo 'DEP_RELDIR := $${_PARSEDIR:S,$${SRCTOP}/,,}'; echo; \
+ echo 'DEP_MACHINE := $${.PARSEFILE:E}'; echo; \
+ echo 'DIRDEPS = \'; \
+ echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \
+ ${_include_src_dirdeps} \
+ echo '.include <dirdeps.mk>'; \
+ echo; \
+ echo '.if $${DEP_RELDIR} == $${_DEP_RELDIR}'; \
+ echo '# local dependencies - needed for -jN in clean tree'; \
+ [ -s ${CAT_DEPEND} ] && { grep : ${CAT_DEPEND} | grep -v '[/\\]'; }; \
+ echo '.endif' ) | sed 's,_\([{(]\),$$\1,g' > $@.new${.MAKE.PID}
+ @${InstallNew}; InstallNew -s $@.new${.MAKE.PID}
+
+.endif # meta2deps failed
+.elif !empty(SUBDIR)
+
+DIRDEPS := ${SUBDIR:S,^,${RELDIR}/,:O:u}
+
+all: ${_DEPENDFILE}
+
+${_DEPENDFILE}: ${MAKEFILE} ${_this}
+ @(echo '# Autogenerated - do NOT edit!'; echo; \
+ echo 'DEP_RELDIR := $${_PARSEDIR:S,$${SRCTOP}/,,}'; echo; \
+ echo 'DEP_MACHINE := $${.PARSEFILE:E}'; echo; \
+ echo 'DIRDEPS = \'; \
+ echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \
+ echo '.include <dirdeps.mk>'; \
+ echo ) | sed 's,_\([{(]\),$$\1,g' > $@.new
+ @${InstallNew}; InstallNew $@.new
+
+.else
+
+# nothing to do
+all ${_DEPENDFILE}:
+
+.endif
+${_DEPENDFILE}: .PRECIOUS
diff --git a/share/mk/host-target.mk b/share/mk/host-target.mk
new file mode 100644
index 0000000..c6d4562
--- /dev/null
+++ b/share/mk/host-target.mk
@@ -0,0 +1,31 @@
+# RCSid:
+# $Id: host-target.mk,v 1.6 2011/03/02 05:05:21 sjg Exp $
+
+# Host platform information; may be overridden
+.if !defined(_HOST_OSNAME)
+_HOST_OSNAME != uname -s
+.export _HOST_OSNAME
+.endif
+.if !defined(_HOST_OSREL)
+_HOST_OSREL != uname -r
+.export _HOST_OSREL
+.endif
+.if !defined(_HOST_ARCH)
+_HOST_ARCH != uname -p 2>/dev/null || uname -m
+# uname -p may produce garbage on linux
+.if ${_HOST_ARCH:[\#]} > 1
+_HOST_ARCH != uname -m
+.endif
+.export _HOST_ARCH
+.endif
+
+HOST_OSMAJOR := ${_HOST_OSREL:C/[^0-9].*//}
+HOST_OSTYPE := ${_HOST_OSNAME}-${_HOST_OSREL:C/\([^\)]*\)//}-${_HOST_ARCH}
+HOST_OS := ${_HOST_OSNAME}
+host_os := ${_HOST_OSNAME:tl}
+HOST_TARGET := ${host_os}${HOST_OSMAJOR}-${_HOST_ARCH}
+
+# tr is insanely non-portable, accommodate the lowest common denominator
+TR ?= tr
+toLower = ${TR} 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
+toUpper = ${TR} 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
diff --git a/share/mk/install-new.mk b/share/mk/install-new.mk
new file mode 100644
index 0000000..ddfff20
--- /dev/null
+++ b/share/mk/install-new.mk
@@ -0,0 +1,53 @@
+# $Id: install-new.mk,v 1.3 2012/03/24 18:25:49 sjg Exp $
+#
+# @(#) Copyright (c) 2009, Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+#
+
+.if !defined(InstallNew)
+
+# copy if src and target are different making a backup if desired
+CmpCp= CmpCp() { \
+ src=$$1 target=$$2 _bak=$$3; \
+ if ! test -s $$target || ! cmp -s $$target $$src; then \
+ trap "" 1 2 3 15; \
+ if test -s $$target; then \
+ if test "x$$_bak" != x; then \
+ rm -f $$target$$_bak; \
+ mv $$target $$target$$_bak; \
+ else \
+ rm -f $$target; \
+ fi; \
+ fi; \
+ cp $$src $$target; \
+ fi; }
+
+# If the .new file is different, we want it.
+# Note: this function will work as is for *.new$RANDOM"
+InstallNew= ${CmpCp}; InstallNew() { \
+ _t=-e; _bak=; \
+ while :; do \
+ case "$$1" in \
+ -?) _t=$$1; shift;; \
+ --bak) _bak=$$2; shift 2;; \
+ *) break;; \
+ esac; \
+ done; \
+ for new in "$$@"; do \
+ if test $$_t $$new; then \
+ target=`expr $$new : '\(.*\).new'`; \
+ CmpCp $$new $$target $$_bak; \
+ fi; \
+ rm -f $$new; \
+ done; :; }
+
+.endif
diff --git a/share/mk/local.autodep.mk b/share/mk/local.autodep.mk
new file mode 100644
index 0000000..8327540
--- /dev/null
+++ b/share/mk/local.autodep.mk
@@ -0,0 +1,21 @@
+
+.if ${.MAKE.DEPENDFILE:M*.${MACHINE}} == ""
+# by default only MACHINE0 does updates
+UPDATE_DEPENDFILE_MACHINE?= ${MACHINE0}
+.if ${MACHINE} != ${UPDATE_DEPENDFILE_MACHINE}
+UPDATE_DEPENDFILE= no
+.endif
+.endif
+
+CFLAGS+= ${CFLAGS_LAST}
+CLEANFILES+= .depend
+
+# handy for debugging
+.SUFFIXES: .S .c .cc .cpp .cpp-out
+
+
+.S.cpp-out .c.cpp-out: .NOMETA
+ @${CC} -E ${CFLAGS} ${.IMPSRC} | grep -v '^[[:space:]]*$$'
+
+.cc.cpp-out: .NOMETA
+ @${CXX} -E ${CXXFLAGS} ${.IMPSRC} | grep -v '^[[:space:]]*$$'
diff --git a/share/mk/local.dirdeps.mk b/share/mk/local.dirdeps.mk
new file mode 100644
index 0000000..dedf9e2
--- /dev/null
+++ b/share/mk/local.dirdeps.mk
@@ -0,0 +1,15 @@
+.if !target(_DIRDEP_USE)
+# first time read
+.if ${MACHINE} == "host"
+DIRDEPS_FILTER+= \
+ Ninclude* \
+ Nlib/* \
+ Ngnu/lib/* \
+
+.endif
+.endif
+
+# this is how we can handle optional dependencies
+.if ${MK_SSP:Uno} != "no" && defined(PROG)
+DIRDEPS += gnu/lib/libssp/libssp_nonshared
+.endif
diff --git a/share/mk/local.gendirdeps.mk b/share/mk/local.gendirdeps.mk
new file mode 100644
index 0000000..88c11e9
--- /dev/null
+++ b/share/mk/local.gendirdeps.mk
@@ -0,0 +1,10 @@
+# supress optional dependecies
+# local.dirdeps.mk will put them in if necessary
+GENDIRDEPS_FILTER+= Ngnu/lib/libssp/libssp_nonshared
+
+# gendirdeps.mk will turn _{VAR} into ${VAR} which keeps this simple
+GENDIRDEPS_FILTER+= ${CSU_DIR:L:@v@S,/${$v},/_{${v}},@}
+
+# this could easily get confused
+GENDIRDEPS_FILTER+= ${MACHINE_CPUARCH MACHINE_CPU MACHINE_ARCH MACHINE:L:@v@S,/${$v}/,/_{${v}}/,@:NS,//,*:u}
+
diff --git a/share/mk/local.init.mk b/share/mk/local.init.mk
new file mode 100644
index 0000000..eb15b1e
--- /dev/null
+++ b/share/mk/local.init.mk
@@ -0,0 +1,18 @@
+
+.if defined(.PARSEDIR)
+.if ${.MAKE.MODE:Mmeta*} != ""
+.if !empty(SUBDIR) && !defined(LIB) && !defined(PROG) && ${.MAKE.MAKEFILES:M*bsd.prog.mk} == ""
+.if ${.MAKE.MODE:Mleaf*} != ""
+# we only want leaf dirs to build in meta mode... and we are not one
+.MAKE.MODE = normal
+.endif
+.endif
+.endif
+.endif
+
+.if ${MACHINE} == "host"
+HOST_CC?= /usr/bin/cc
+HOST_CFLAGS+= -DHOSTPROG
+CC= ${HOST_CC}
+CFLAGS+= ${HOST_CFLAGS}
+.endif
diff --git a/share/mk/local.sys.mk b/share/mk/local.sys.mk
new file mode 100644
index 0000000..8b8f085
--- /dev/null
+++ b/share/mk/local.sys.mk
@@ -0,0 +1,197 @@
+WITH_INSTALL_AS_USER= yes
+
+.if defined(.PARSEDIR) # bmake
+
+# some handy macros
+_this = ${.PARSEDIR:tA}/${.PARSEFILE}
+# some useful modifiers
+
+# A useful trick for testing multiple :M's against something
+# :L says to use the variable's name as its value - ie. literal
+# got = ${clean* destroy:${M_ListToMatch:S,V,.TARGETS,}}
+M_ListToMatch = L:@m@$${V:M$$m}@
+# match against our initial targets (see above)
+M_L_TARGETS = ${M_ListToMatch:S,V,_TARGETS,}
+
+# turn a list into a set of :N modifiers
+# NskipFoo = ${Foo:${M_ListToSkip}}
+M_ListToSkip= O:u:ts::S,:,:N,g:S,^,N,
+
+# type should be a builtin in any sh since about 1980,
+# AUTOCONF := ${autoconf:L:${M_whence}}
+M_type = @x@(type $$x 2> /dev/null); echo;@:sh:[0]:N* found*:[@]:C,[()],,g
+M_whence = ${M_type}:M/*
+
+# convert a path to a valid shell variable
+M_P2V = tu:C,[./-],_,g
+
+# convert path to absolute
+.if ${MAKE_VERSION:U0} > 20100408
+M_tA = tA
+.else
+M_tA = C,.*,('cd' & \&\& 'pwd') 2> /dev/null || echo &,:sh
+.endif
+
+# this is handy for forcing a space into something.
+AnEmptyVar=
+
+# absoulte path to what we are reading.
+_PARSEDIR = ${.PARSEDIR:${M_tA}}
+
+.if !empty(SB)
+SB_SRC ?= ${SB}/src
+SB_OBJROOT ?= ${SB}/obj
+# this is what we use below
+SRCTOP ?= ${SB_SRC}
+OBJROOT ?= ${SB_OBJROOT}
+.endif
+
+.if empty(SRCTOP)
+SRCTOP := ${_PARSEDIR:H:H}
+.export SRCTOP
+OBJROOT ?= ${SRCTOP:H}/obj/
+.endif
+
+# we need HOST_TARGET etc below.
+.include <host-target.mk>
+
+OBJTOP ?= ${OBJROOT}${MACHINE}
+
+.if !defined(_TARGETS)
+# some things we do only once
+_TARGETS := ${.TARGETS}
+.-include <sys.env.mk>
+.if !empty(OBJROOT)
+.if ${OBJROOT:M*/} != ""
+OBJROOT:= ${OBJROOT:tA}/
+.else
+OBJROOT:= ${OBJROOT:H:tA}/${OBJROOT:T}
+.endif
+.export OBJROOT
+.endif
+.endif
+
+.if !empty(SRCTOP)
+.if ${.CURDIR} == ${SRCTOP}
+RELDIR = .
+.elif ${.CURDIR:M${SRCTOP}/*}
+RELDIR := ${.CURDIR:S,${SRCTOP}/,,}
+.endif
+.endif
+
+HOST_OBJTOP ?= ${OBJROOT}${HOST_TARGET}
+
+.if ${OBJTOP} == ${HOST_OBJTOP} || ${REQUESTED_MACHINE:U${MACHINE}} == "host"
+MACHINE= host
+.endif
+.if ${MACHINE} == "host"
+OBJTOP := ${HOST_OBJTOP}
+.endif
+
+# if you want objdirs make them automatic
+.if ${MKOBJDIRS:Uno} == "auto"
+WITH_AUTO_OBJ= yes
+.include <auto.obj.mk>
+.endif
+
+.ifndef WITHOUT_META_MODE
+WITH_META_MODE= yes
+
+.ifndef WITHOUT_STAGING
+WITH_STAGING= yes
+.endif
+
+PYTHON ?= /usr/local/bin/python
+
+.if ${.MAKE.LEVEL} == 0
+# this works best if share/mk is ready for it.
+BUILD_AT_LEVEL0= no
+# By default only MACHINE0 updates dependencies
+# see local.autodep.mk
+MACHINE0 := ${MACHINE}
+.export MACHINE0
+.export PYTHON
+.endif
+
+# we want to end up with a singe stage tree for all machines
+.ifndef WITHOUT_STAGING
+.if empty(STAGE_ROOT)
+STAGE_ROOT?= ${OBJROOT}stage
+.export STAGE_ROOT
+.endif
+.endif
+
+.if !empty(STAGE_ROOT)
+.if ${MACHINE} == "host"
+STAGE_MACHINE= ${HOST_TARGET}
+.else
+STAGE_MACHINE= ${MACHINE}
+.endif
+STAGE_OBJTOP= ${STAGE_ROOT}/${STAGE_MACHINE}
+STAGE_COMMON_OBJTOP= ${STAGE_ROOT}/common
+STAGE_HOST_OBJTOP= ${STAGE_ROOT}/${HOST_TARGET}
+
+STAGE_LIBDIR= ${STAGE_OBJTOP}${LIBDIR:U/lib}
+# this is not the same as INCLUDEDIR
+STAGE_INCSDIR= ${STAGE_OBJTOP}${INCSDIR:U/include}
+
+.ifndef WITH_SYSROOT
+.if ${MACHINE} != "host"
+CFLAGS_LAST+= -nostdinc
+.endif
+CFLAGS_LAST+= -isystem ${STAGE_OBJTOP}/usr/include -isystem ${STAGE_OBJTOP}/include
+LDFLAGS+= -B${STAGE_LIBDIR} -L${STAGE_LIBDIR}
+.else
+# if ld suppored sysroot, this would suffice
+CFLAGS_LAST+= --sysroot=${STAGE_OBJTOP} -isystem ${STAGE_OBJTOP}/include
+.endif
+.endif
+
+.include "meta.sys.mk"
+
+# most dirs can be satisfied with one Makefile.depend ?
+.undef .MAKE.DEPENDFILE
+.MAKE.DEPENDFILE_PREFERENCE = \
+ ${.MAKE.DEPENDFILE_PREFIX} \
+ ${.MAKE.DEPENDFILE_PREFIX}.${MACHINE}
+
+.include "sys.dependfile.mk"
+
+.if ${MACHINE} == "host"
+# need a machine specific file
+.MAKE.DEPENDFILE= ${.MAKE.DEPENDFILE_PREFIX}.${MACHINE}
+.endif
+
+.MAKE.META.BAILIWICK = ${SB} ${OBJROOT} ${STAGE_ROOT}
+
+.endif # meta mode
+
+# ensure we have a value
+.MAKE.MODE ?= normal
+
+# don't rely on MACHINE_ARCH being set or valid
+
+MACHINE_ARCH.host = ${_HOST_ARCH}
+MACHINE_ARCH.${MACHINE} ?= ${MACHINE}
+MACHINE_ARCH := ${MACHINE_ARCH.${MACHINE}}
+
+CSU_DIR.i386 = csu/i386-elf
+CSU_DIR.${MACHINE_ARCH} ?= csu/${MACHINE_ARCH}
+CSU_DIR := ${CSU_DIR.${MACHINE_ARCH}}
+
+MAKE_PRINT_VAR_ON_ERROR+= \
+ .CURDIR \
+ .MAKE \
+ .OBJDIR \
+ .TARGETS \
+ DESTDIR \
+ LD_LIBRARY_PATH \
+ MACHINE \
+ MACHINE_ARCH \
+ MAKEOBJDIRPREFIX \
+ MAKESYSPATH \
+ MAKE_VERSION\
+ OBJTOP \
+ ${MAKE_PRINT_VAR_ON_ERROR_XTRAS}
+
+.endif # bmake
diff --git a/share/mk/meta.autodep.mk b/share/mk/meta.autodep.mk
new file mode 100644
index 0000000..f063837
--- /dev/null
+++ b/share/mk/meta.autodep.mk
@@ -0,0 +1,261 @@
+# $Id: meta.autodep.mk,v 1.28 2012/07/13 15:38:16 sjg Exp $
+
+#
+# @(#) Copyright (c) 2010, Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+#
+
+_this ?= ${.PARSEFILE}
+.if !target(__${_this}__)
+__${_this}__: .NOTMAIN
+
+.-include "local.autodep.mk"
+
+.if defined(SRCS)
+# it would be nice to be able to query .SUFFIXES
+OBJ_EXTENSIONS+= .o .po .lo .So
+
+# explicit dependencies help short-circuit .SUFFIX searches
+SRCS_DEP_FILTER+= N*.[hly]
+.for s in ${SRCS:${SRCS_DEP_FILTER:O:u:ts:}}
+.for e in ${OBJ_EXTENSIONS:O:u}
+.if !target(${s:T:R}$e)
+${s:T:R}$e: $s
+.endif
+.endfor
+.endfor
+.endif
+
+.if make(gendirdeps)
+# you are supposed to know what you are doing!
+UPDATE_DEPENDFILE = yes
+.elif !empty(.TARGETS) && !make(all)
+# do not update the *depend* files
+# unless we are building the entire directory or the default target.
+# NO means don't update .depend - or Makefile.depend*
+# no means update .depend but not Makefile.depend*
+UPDATE_DEPENDFILE = NO
+.elif ${.MAKEFLAGS:M-k} != ""
+# it is a bad idea to update anything
+UPDATE_DEPENDFILE = NO
+.endif
+
+_CURDIR ?= ${.CURDIR}
+_DEPENDFILE := ${_CURDIR}/${.MAKE.DEPENDFILE:T}
+
+.if ${.MAKE.LEVEL} == 0
+.if ${BUILD_AT_LEVEL0:Uyes:tl} == "no"
+UPDATE_DEPENDFILE = NO
+.endif
+.endif
+.if !exists(${_DEPENDFILE})
+_bootstrap_dirdeps = yes
+.endif
+_bootstrap_dirdeps ?= no
+UPDATE_DEPENDFILE ?= yes
+
+.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
+.info ${_DEPENDFILE:S,${SRCTOP}/,,} update=${UPDATE_DEPENDFILE}
+.endif
+
+.if !empty(XMAKE_META_FILE)
+.if exists(${.OBJDIR}/${XMAKE_META_FILE})
+# we cannot get accurate dependencies from an update build
+UPDATE_DEPENDFILE = NO
+.else
+META_XTRAS += ${XMAKE_META_FILE}
+.endif
+.endif
+
+.if ${_bootstrap_dirdeps} == "yes" || exists(${_DEPENDFILE})
+# if it isn't supposed to be touched by us the Makefile should have
+# UPDATE_DEPENDFILE = no
+WANT_UPDATE_DEPENDFILE ?= yes
+.endif
+
+.if ${WANT_UPDATE_DEPENDFILE:Uno:tl} != "no"
+.if ${.MAKE.MODE:Mmeta*} == "" || ${.MAKE.MODE:M*read*} != ""
+UPDATE_DEPENDFILE = no
+.endif
+
+.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
+.info ${_DEPENDFILE:S,${SRCTOP}/,,} update=${UPDATE_DEPENDFILE}
+.endif
+
+.if ${UPDATE_DEPENDFILE:tl} == "yes"
+# sometimes we want .meta files generated to aid debugging/error detection
+# but do not want to consider them for dependencies
+# for example the result of running configure
+# just make sure this is not empty
+META_FILE_FILTER ?= N.meta
+
+.if !empty(DPADD)
+# if we have any non-libs in DPADD,
+# they probably need to be paid attention to
+.if !empty(DPLIBS)
+FORCE_DPADD = ${DPADD:${DPLIBS:${M_ListToSkip}}:${DPADD_LAST:${M_ListToSkip}}}
+.else
+_nonlibs := ${DPADD:T:Nlib*:N*include}
+.if !empty(_nonlibs)
+FORCE_DPADD += ${_nonlibs:@x@${DPADD:M*/$x}@}
+.endif
+.endif
+.endif
+
+.if !make(gendirdeps)
+.END: gendirdeps
+.endif
+
+# if we don't have OBJS, then .depend isn't useful
+.if !target(.depend) && (!empty(OBJS) || ${.ALLTARGETS:M*.o} != "")
+# some makefiles and/or targets contain
+# circular dependencies if you dig too deep
+# (as meta mode is apt to do)
+# so we provide a means of supressing them.
+# the input to the loop below is target: dependency
+# with just one dependency per line.
+# Also some targets are not really local, or use random names.
+# Use local.autodep.mk to provide local additions!
+SUPPRESS_DEPEND += \
+ ${SB:S,/,_,g}* \
+ *:y.tab.c \
+ *.c:*.c \
+ *.h:*.h
+
+.NOPATH: .depend
+# we use ${.MAKE.META.CREATED} to trigger an update but
+# we process using ${.MAKE.META.FILES}
+# the double $$ defers initial evaluation
+# if necessary, we fake .po dependencies, just so the result
+# in Makefile.depend* is stable
+# The current objdir may be refered to in various ways
+OBJDIR_REFS += ${.OBJDIR} ${.OBJDIR:tA} ${_OBJDIR} ${RELOBJTOP}/${RELDIR}
+_depend = .depend
+# it would be nice to be able to get .SUFFIXES as ${.SUFFIXES}
+# we actually only care about the .SUFFIXES of files that might be
+# generated by tools like yacc.
+DEPEND_SUFFIXES += .c .h .cpp .hpp .cxx .hxx .cc .hh
+.depend: .NOMETA $${.MAKE.META.CREATED} ${_this}
+ @echo "Updating $@: ${.OODATE:T:[1..8]}"
+ @egrep -i '^R .*\.(${DEPEND_SUFFIXES:tl:O:u:S,^.,,:ts|})$$' /dev/null ${.MAKE.META.FILES:T:O:u:${META_FILE_FILTER:ts:}:M*o.meta} | \
+ sed -e 's, \./, ,${OBJDIR_REFS:O:u:@d@;s, $d/, ,@};/\//d' \
+ -e 's,^\([^/][^/]*\).meta...[0-9]* ,\1: ,' | \
+ sort -u | \
+ while read t d; do \
+ case "$$d:" in $$t) continue;; esac; \
+ case "$$t$$d" in ${SUPPRESS_DEPEND:U.:O:u:ts|}) continue;; esac; \
+ echo $$t $$d; \
+ done > $@.${.MAKE.PID}
+ @case "${.MAKE.META.FILES:T:M*.po.*}" in \
+ *.po.*) mv $@.${.MAKE.PID} $@;; \
+ *) { cat $@.${.MAKE.PID}; \
+ sed 's,\.So:,.o:,;s,\.o:,.po:,' $@.${.MAKE.PID}; } | sort -u > $@; \
+ rm -f $@.${.MAKE.PID};; \
+ esac
+.else
+# make sure this exists
+.depend:
+# do _not_ assume that .depend is in any fit state for us to use
+CAT_DEPEND = /dev/null
+.if ${.MAKE.LEVEL} > 0
+.export CAT_DEPEND
+.endif
+_depend =
+.endif
+
+.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
+.info ${_DEPENDFILE:S,${SRCTOP}/,,} _depend=${_depend}
+.endif
+
+gendirdeps: ${_DEPENDFILE}
+
+.if !target(${_DEPENDFILE})
+.if ${_bootstrap_dirdeps} == "yes"
+# We are boot-strapping a new directory
+# Use DPADD to seed DIRDEPS
+.if !empty(DPADD)
+# anything which matches ${_OBJROOT}* but not ${_OBJTOP}*
+# needs to be qualified in DIRDEPS
+# The pseudo machine "host" is used for HOST_TARGET
+DIRDEPS = \
+ ${DPADD:M${_OBJTOP}*:H:C,${_OBJTOP}[^/]*/,,:N.:O:u} \
+ ${DPADD:M${_OBJROOT}*:N${_OBJTOP}*:H:S,${_OBJROOT},,:C,^([^/]+)/(.*),\2.\1,:S,${HOST_TARGET}$,host,:N.*:O:u}
+
+.endif
+.endif
+
+_gendirdeps_mutex =
+.if defined(NEED_GENDIRDEPS_MUTEX)
+# If a src dir gets built with multiple object dirs,
+# we need a mutex. Obviously, this is best avoided.
+# Note if .MAKE.DEPENDFILE is common for all ${MACHINE}
+# you either need to mutex, or ensure only one machine builds at a time!
+# lockf is an example of a suitable tool
+LOCKF ?= /usr/bin/lockf
+.if exists(${LOCKF})
+GENDIRDEPS_MUTEXER ?= ${LOCKF} -k
+.endif
+.if empty(GENDIRDEPS_MUTEXER)
+.error NEED_GENDIRDEPS_MUTEX defined, but GENDIRDEPS_MUTEXER not set
+.else
+_gendirdeps_mutex = ${GENDIRDEPS_MUTEXER} ${GENDIRDEPS_MUTEX:U${_CURDIR}/Makefile}
+.endif
+.endif
+
+# If we have META_XTRAS we most likely did not create them
+# but we need to behave as if we did.
+# Avoid adding glob patterns to .MAKE.META.CREATED though.
+.MAKE.META.CREATED += ${META_XTRAS:N*\**:O:u}
+
+.if make(gendirdeps)
+META_FILES = *.meta
+.elif ${OPTIMIZE_OBJECT_META_FILES:Uno:tl} == "no"
+META_FILES = ${.MAKE.META.FILES:T:N.depend*:O:u}
+.else
+# if we have 1000's of .o.meta, .So.meta etc we need only look at one set
+# it is left as an exercise for the reader to work out what this does
+META_FILES = ${.MAKE.META.FILES:T:N.depend*:N*o.meta:O:u} \
+ ${.MAKE.META.FILES:T:M*.${.MAKE.META.FILES:M*o.meta:R:E:O:u:[1]}.meta:O:u}
+.endif
+
+.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
+.info ${_DEPENDFILE:S,${SRCTOP}/,,}: ${_depend} ${.PARSEDIR}/gendirdeps.mk ${META2DEPS} xtras=${META_XTRAS}
+.endif
+
+.if ${.MAKE.LEVEL} > 0 && !empty(GENDIRDEPS_FILTER)
+.export GENDIRDEPS_FILTER
+.endif
+
+_makesyspath:= ${_PARSEDIR}
+${_DEPENDFILE}: ${_depend} ${.PARSEDIR}/gendirdeps.mk ${META2DEPS} $${.MAKE.META.CREATED}
+ @echo Checking $@: ${.OODATE:T:[1..8]}
+ @(cd . && \
+ SKIP_GENDIRDEPS='${SKIP_GENDIRDEPS:O:u}' \
+ DPADD='${FORCE_DPADD:O:u}' ${_gendirdeps_mutex} \
+ MAKESYSPATH=${_makesyspath} \
+ ${.MAKE} -f gendirdeps.mk RELDIR=${RELDIR} _DEPENDFILE=${_DEPENDFILE} \
+ META_FILES='${META_XTRAS:T:O:u} ${META_FILES:T:O:u:${META_FILE_FILTER:ts:}}')
+ @test -s $@ && touch $@; :
+.endif
+
+.endif
+.endif
+
+.if ${_bootstrap_dirdeps} == "yes"
+# make sure this is included at least once
+.include <dirdeps.mk>
+.else
+${_DEPENDFILE}: .PRECIOUS
+.endif
+
+CLEANFILES += *.meta filemon.* *.db
+.endif
diff --git a/share/mk/meta.stage.mk b/share/mk/meta.stage.mk
new file mode 100644
index 0000000..f43fd01
--- /dev/null
+++ b/share/mk/meta.stage.mk
@@ -0,0 +1,166 @@
+# $Id: meta.stage.mk,v 1.11 2011/05/05 15:01:05 sjg Exp $
+#
+# @(#) Copyright (c) 2011, Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+#
+
+.if !target(__${.PARSEFILE}__)
+__${.PARSEFILE}__:
+
+.if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} != ""
+# this is generally safer anyway
+_dirdep = ${RELDIR}.${MACHINE}
+.else
+_dirdep = ${RELDIR}
+.endif
+
+# this allows us to trace dependencies back to their src dir
+.dirdep:
+ @echo '${_dirdep}' > $@
+
+.if defined(NO_POSIX_SHELL) || ${type printf:L:sh:Mbuiltin} == ""
+_stage_file_basename = `basename $$f`
+_stage_target_dirname = `dirname $$t`
+.else
+_stage_file_basename = $${f\#\#*/}
+_stage_target_dirname = $${t%/*}
+.endif
+
+# common logic for staging files
+# this all relies on RELDIR being set to a subdir of SRCTOP
+# we use ln(1) if we can, else cp(1)
+STAGE_FILE_SCRIPT = StageFiles() { \
+ dest=$$1; shift; \
+ mkdir -p $$dest; \
+ [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \
+ for f in "$$@"; do \
+ case "$$f" in */*) t=$$dest/${_stage_file_basename};; *) t=$$dest/$$f;; esac; \
+ rm -f $$t $$t.dirdep; \
+ { ln $$f $$t 2> /dev/null || \
+ cp -p $$f $$t; } && \
+ { ln .dirdep $$t.dirdep 2> /dev/null || \
+ cp .dirdep $$t.dirdep; }; \
+ done; }
+
+STAGE_LINKS_SCRIPT = StageLinks() { \
+ case "$$1" in --) shift;; -*) lnf=$$1; shift;; esac; \
+ dest=$$1; shift; \
+ mkdir -p $$dest; \
+ [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \
+ while test $$\# -ge 2; do \
+ l=$$1; shift; \
+ t=$$dest/$$1; \
+ case "$$1" in */*) mkdir -p ${_stage_target_dirname};; esac; \
+ shift; \
+ rm -f $$t $$t.dirdep 2>/dev/null; \
+ ln $$lnf $$l $$t; \
+ { ln .dirdep $$t.dirdep 2> /dev/null || \
+ cp .dirdep $$t.dirdep; }; \
+ done; :; }
+
+STAGE_AS_SCRIPT = StageAs() { \
+ dest=$$1; shift; \
+ mkdir -p $$dest; \
+ [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \
+ while test $$\# -ge 2; do \
+ s=$$1; shift; \
+ t=$$dest/$$1; \
+ case "$$1" in */*) mkdir -p ${_stage_target_dirname};; esac; \
+ shift; \
+ rm -f $$t $$t.dirdep; \
+ { ln $$s $$t 2> /dev/null || \
+ cp -p $$s $$t; } && \
+ { ln .dirdep $$t.dirdep 2> /dev/null || \
+ cp .dirdep $$t.dirdep; }; \
+ done; }
+
+# this is simple, a list of the "staged" files depends on this,
+_STAGE_BASENAME_USE: .USE ${.TARGET:T}
+ @${STAGE_FILE_SCRIPT}; StageFiles ${.TARGET:H} ${.TARGET:T}
+
+.if !empty(STAGE_INCSDIR)
+STAGE_INCS ?= ${.ALLSRC:N.dirdep}
+
+stage_incs: .dirdep
+ @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_INCSDIR} ${STAGE_INCS}
+ @touch $@
+.endif
+
+.if !empty(STAGE_LIBDIR)
+STAGE_LIBS ?= ${.ALLSRC:N.dirdep}
+
+stage_libs: .dirdep
+ @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_LIBDIR} ${STAGE_LIBS}
+.if !empty(SHLIB_LINKS)
+ @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR} \
+ ${SHLIB_LINKS:@t@${STAGE_LIBS:T:M$t.*} $t@}
+.elif !empty(SHLIB_LINK) && !empty(SHLIB_NAME)
+ @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR} ${SHLIB_NAME} ${SHLIB_LINK} ${SYMLINKS:T}
+.endif
+ @touch $@
+.endif
+
+.if !empty(STAGE_DIR)
+STAGE_SETS += _default
+STAGE_DIR._default = ${STAGE_DIR}
+STAGE_SYMLINKS_DIR._default = ${STAGE_SYMLINKS_DIR:U${STAGE_DIR}}
+STAGE_FILES._default = ${STAGE_FILES}
+STAGE_SYMLINKS._default = ${STAGE_SYMLINKS}
+STAGE_FILES ?= ${.ALLSRC:N.dirdep:Nstage_*}
+STAGE_SYMLINKS ?= ${.ALLSRC:T:N.dirdep:Nstage_*}
+.endif
+
+.if !empty(STAGE_SETS)
+
+# some makefiles need to populate multiple directories
+.for s in ${STAGE_SETS:O:u}
+STAGE_FILES.$s ?= ${.ALLSRC:N.dirdep}
+STAGE_SYMLINKS.$s ?= ${.ALLSRC:N.dirdep}
+
+.if $s != "_default"
+stage_files: stage_files.$s
+stage_files.$s: .dirdep
+.else
+stage_files: .dirdep
+.endif
+ @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}} ${STAGE_FILES.$s}
+ @touch $@
+
+.if $s != "_default"
+stage_symlinks: stage_symlinks.$s
+stage_symlinks.$s: .dirdep
+.else
+stage_symlinks: .dirdep
+.endif
+ @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_SYMLINKS_DIR.$s:U${STAGE_DIR.$s}} ${STAGE_SYMLINKS.$s}
+ @touch $@
+
+.endfor
+.endif
+
+.if !empty(STAGE_AS_SETS)
+
+# sometimes things need to be renamed as they are staged
+# each ${file} will be staged as ${STAGE_AS_${file:T}}
+# one could achieve the same with SYMLINKS
+.for s in ${STAGE_AS_SETS:O:u}
+STAGE_AS.$s ?= ${.ALLSRC:N.dirdep}
+
+stage_as: stage_as.$s
+stage_as.$s: .dirdep
+ @${STAGE_AS_SCRIPT}; StageAs ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}} ${STAGE_AS.$s:@f@$f ${STAGE_AS_${f:T}:U${f:T}}@}
+ @touch $@
+
+.endfor
+.endif
+
+.endif
diff --git a/share/mk/meta.subdir.mk b/share/mk/meta.subdir.mk
new file mode 100644
index 0000000..1a77b44
--- /dev/null
+++ b/share/mk/meta.subdir.mk
@@ -0,0 +1,79 @@
+# $Id: meta.subdir.mk,v 1.8 2011/11/09 22:27:25 sjg Exp $
+
+#
+# @(#) Copyright (c) 2010, Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+#
+
+.if !defined(NO_SUBDIR) && !empty(SUBDIR)
+.if make(destroy*) || make(clean*)
+.MAKE.MODE = compat
+.if !commands(destroy)
+.-include <bsd.obj.mk>
+.endif
+.elif ${.MAKE.LEVEL} == 0
+
+.MAIN: all
+
+.if !exists(${.CURDIR}/${.MAKE.DEPENDFILE:T}) || make(gendirdeps)
+# start with this
+DIRDEPS = ${SUBDIR:N.WAIT:O:u:@d@${RELDIR}/$d@}
+
+.if make(gendirdeps)
+.include <meta.autodep.mk>
+.else
+# this is the cunning bit
+# actually it is probably a bit risky
+# since we may pickup subdirs which are not relevant
+# the alternative is a walk through the tree though
+# which is difficult without a sub-make.
+
+.if defined(BOOTSTRAP_DEPENDFILES)
+_find_name = ${.MAKE.MAKEFILE_PREFERENCE:@m@-o -name $m@:S,^-o,,1}
+DIRDEPS = ${_subdeps:H:O:u:@d@${RELDIR}/$d@}
+.elif ${.MAKE.DEPENDFILE:E} == ${MACHINE} && defined(ALL_MACHINES)
+# we want to find Makefile.depend.* ie for all machines
+# and turn the dirs into dir.<machine>
+_find_name = -name '${.MAKE.DEPENDFILE:T:R}*'
+DIRDEPS = ${_subdeps:O:u:${NIgnoreFiles}:@d@${RELDIR}/${d:H}.${d:E}@:S,.${MACHINE}$,,:S,.depend$,,}
+.else
+# much simpler
+_find_name = -name ${.MAKE.DEPENDFILE:T}
+.if ${.MAKE.DEPENDFILE:E} == ${MACHINE}
+_find_name += -o -name ${.MAKE.DEPENDFILE:T:R}
+.endif
+DIRDEPS = ${_subdeps:H:O:u:@d@${RELDIR}/$d@}
+.endif
+
+_subdeps != cd ${.CURDIR} && \
+ find ${SUBDIR:N.WAIT} -type f \( ${_find_name} \) -print -o \
+ -name .svn -prune 2> /dev/null; echo
+
+.if empty(_subdeps)
+DIRDEPS =
+.else
+# clean up if needed
+DIRDEPS := ${DIRDEPS:S,^./,,:S,/./,/,g:${SUBDIREPS_FILTER:Uu}}
+.endif
+# we just dealt with it, if we leave it defined,
+# dirdeps.mk will compute some interesting combinations.
+.undef ALL_MACHINES
+
+DEP_RELDIR = ${RELDIR}
+.include <dirdeps.mk>
+.endif
+.endif
+.else
+all: .PHONY
+.endif
+
+.endif
diff --git a/share/mk/meta.sys.mk b/share/mk/meta.sys.mk
new file mode 100644
index 0000000..379e338
--- /dev/null
+++ b/share/mk/meta.sys.mk
@@ -0,0 +1,139 @@
+# $Id: meta.sys.mk,v 1.14 2011/10/02 00:40:56 sjg Exp $
+
+#
+# @(#) Copyright (c) 2010, Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+#
+
+# include this if you want to enable meta mode
+# for maximum benefit, requires filemon(4) driver.
+
+.if ${MAKE_VERSION:U0} > 20100901
+.if !target(.ERROR)
+
+
+META_MODE += meta verbose
+.MAKE.MODE ?= ${META_MODE}
+
+.if ${.MAKE.LEVEL} == 0
+_make_mode := ${.MAKE.MODE} ${META_MODE}
+.if ${_make_mode:M*read*} != "" || ${_make_mode:M*nofilemon*} != ""
+# tell everyone we are not updating Makefile.depend*
+UPDATE_DEPENDFILE = NO
+.export UPDATE_DEPENDFILE
+.endif
+.if ${UPDATE_DEPENDFILE:Uyes:tl} == "no" && !exists(/dev/filemon)
+# we should not get upset
+META_MODE += nofilemon
+.export META_MODE
+.endif
+.endif
+
+.if !defined(NO_SILENT)
+.if ${MAKE_VERSION} > 20110818
+# only be silent when we have a .meta file
+META_MODE += silent=yes
+.else
+.SILENT:
+.endif
+.endif
+
+# make defaults .MAKE.DEPENDFILE to .depend
+# that won't work for us.
+.if ${.MAKE.DEPENDFILE} == ".depend"
+.undef .MAKE.DEPENDFILE
+.endif
+
+# if you don't cross build for multiple MACHINEs concurrently, then
+# .MAKE.DEPENDFILE = Makefile.depend
+# probably makes sense - you can set that in local.sys.mk
+.MAKE.DEPENDFILE ?= Makefile.depend.${MACHINE}
+
+# we use the pseudo machine "host" for the build host.
+# this should be taken care of before we get here
+.if ${OBJTOP:Ua} == ${HOST_OBJTOP:Ub}
+MACHINE = host
+.endif
+
+.if ${.MAKE.LEVEL} == 0
+# it can be handy to know which MACHINE kicked off the build
+# for example, if using Makefild.depend for multiple machines,
+# allowing only MACHINE0 to update can keep things simple.
+MACHINE0 := ${MACHINE}
+
+.if defined(PYTHON) && exists(${PYTHON})
+# we prefer the python version of this - it is much faster
+META2DEPS ?= ${.PARSEDIR}/meta2deps.py
+.else
+META2DEPS ?= ${.PARSEDIR}/meta2deps.sh
+.endif
+META2DEPS := ${META2DEPS}
+.export META2DEPS
+.endif
+
+MAKE_PRINT_VAR_ON_ERROR += \
+ .ERROR_TARGET \
+ .ERROR_META_FILE \
+ .MAKE.LEVEL \
+ MAKEFILE \
+ .MAKE.MODE
+
+.if !defined(SB) && defined(SRCTOP)
+SB = ${SRCTOP:H}
+.endif
+ERROR_LOGDIR ?= ${SB}/error
+meta_error_log = ${ERROR_LOGDIR}/meta-${.MAKE.PID}.log
+
+# we are not interested in make telling us a failure happened elsewhere
+.ERROR: _metaError
+_metaError: .NOMETA .NOTMAIN
+ -@[ "${.ERROR_META_FILE}" ] && { \
+ grep -q 'failure has been detected in another branch' ${.ERROR_META_FILE} && exit 0; \
+ mkdir -p ${meta_error_log:H}; \
+ cp ${.ERROR_META_FILE} ${meta_error_log}; \
+ echo "ERROR: log ${meta_error_log}" >&2; }; :
+
+.endif
+
+# Are we, after all, in meta mode?
+.if ${.MAKE.MODE:Mmeta*} != ""
+MKDEP = meta.autodep
+
+.if ${.MAKE.LEVEL} == 0
+# make sure dirdeps target exists and do it first
+all: dirdeps .WAIT
+dirdeps:
+.NOPATH: dirdeps
+
+.if defined(ALL_MACHINES)
+# the first .MAIN: is what counts
+# by default dirdeps is all we want at level0
+.MAIN: dirdeps
+# tell dirdeps.mk what we want
+BUILD_AT_LEVEL0 = no
+.endif
+
+.if ${.MAKE.DEPENDFILE:E} == ${MACHINE}
+# it works best if we do everything via sub-makes
+BUILD_AT_LEVEL0 ?= no
+.endif
+BUILD_AT_LEVEL0 ?= yes
+.endif
+
+# if we think we are updating dependencies,
+# then filemon had better be present
+.if ${UPDATE_DEPENDFILE:Uyes:tl} != "no" && !exists(/dev/filemon)
+.error ${.newline}ERROR: The filemon module (/dev/filemon) is not loaded.
+.endif
+
+.endif
+.endif
diff --git a/share/mk/meta2deps.py b/share/mk/meta2deps.py
new file mode 100755
index 0000000..8e33e2c
--- /dev/null
+++ b/share/mk/meta2deps.py
@@ -0,0 +1,606 @@
+#!/usr/bin/env python
+
+"""
+This script parses each "meta" file and extracts the
+information needed to deduce build and src dependencies.
+
+It works much the same as the original shell script, but is
+*much* more efficient.
+
+The parsing work is handled by the class MetaFile.
+We only pay attention to a subset of the information in the
+"meta" files. Specifically:
+
+'CWD' to initialize our notion.
+
+'C' to track chdir(2) on a per process basis
+
+'R' files read are what we really care about.
+ directories read, provide a clue to resolving
+ subsequent relative paths. That is if we cannot find
+ them relative to 'cwd', we check relative to the last
+ dir read.
+
+'W' files opened for write or read-write,
+ for filemon V3 and earlier.
+
+'E' files executed.
+
+'L' files linked
+
+'V' the filemon version, this record is used as a clue
+ that we have reached the interesting bit.
+
+"""
+
+"""
+RCSid:
+ $Id: meta2deps.py,v 1.5 2011/11/14 00:18:42 sjg Exp $
+
+ Copyright (c) 2011, Juniper Networks, Inc.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""
+
+import os, re, sys
+
+def getv(dict, key, d=None):
+ """Lookup key in dict and return value or the supplied default."""
+ if key in dict:
+ return dict[key]
+ return d
+
+def resolve(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr):
+ """
+ Return an absolute path, resolving via cwd or last_dir if needed.
+ """
+ if path.endswith('/.'):
+ path = path[0:-2]
+ if path[0] == '/':
+ return path
+ if path == '.':
+ return cwd
+ if path.startswith('./'):
+ return cwd + path[1:]
+ if last_dir == cwd:
+ last_dir = None
+ for d in [last_dir, cwd]:
+ if not d:
+ continue
+ p = '/'.join([d,path])
+ if debug > 2:
+ print >> debug_out, "looking for:", p,
+ if not os.path.exists(p):
+ if debug > 2:
+ print >> debug_out, "nope"
+ p = None
+ continue
+ if debug > 2:
+ print >> debug_out, "found:", p
+ return p
+ return None
+
+def abspath(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr):
+ """
+ Return an absolute path, resolving via cwd or last_dir if needed.
+ this gets called a lot, so we try to avoid calling realpath
+ until we know we have something.
+ """
+ path = resolve(path, cwd, last_dir, debug, debug_out)
+ if path and (path.find('./') > 0 or
+ path.endswith('/..') or
+ os.path.islink(path)):
+ return os.path.realpath(path)
+ return path
+
+def sort_unique(list, cmp=None, key=None, reverse=False):
+ list.sort(cmp, key, reverse)
+ nl = []
+ le = None
+ for e in list:
+ if e == le:
+ continue
+ nl.append(e)
+ return nl
+
+class MetaFile:
+ """class to parse meta files generated by bmake."""
+
+ conf = None
+ dirdep_re = None
+ host_target = None
+ srctops = []
+ objroots = []
+
+ seen = {}
+ obj_deps = []
+ src_deps = []
+ file_deps = []
+
+ def __init__(self, name, conf={}):
+ """if name is set we will parse it now.
+ conf can have the follwing keys:
+
+ SRCTOPS list of tops of the src tree(s).
+
+ CURDIR the src directory 'bmake' was run from.
+
+ RELDIR the relative path from SRCTOP to CURDIR
+
+ MACHINE the machine we built for.
+ set to 'none' if we are not cross-building.
+
+ HOST_TARGET
+ when we build for the psuedo machine 'host'
+ the object tree uses HOST_TARGET rather than MACHINE.
+
+ OBJROOTS a list of the common prefix for all obj dirs it might
+ end in '/' or '-'.
+
+ DPDEPS names an optional file to which per file dependencies
+ will be appended.
+ For example if 'some/path/foo.h' is read from SRCTOP
+ then 'DPDEPS_some/path/foo.h +=' "RELDIR" is output.
+ This can allow 'bmake' to learn all the dirs within
+ the tree that depend on 'foo.h'
+
+ debug desired debug level
+
+ debug_out open file to send debug output to (sys.stderr)
+
+ """
+
+ self.name = name
+ self.debug = getv(conf, 'debug', 0)
+ self.debug_out = getv(conf, 'debug_out', sys.stderr)
+
+ if not self.conf:
+ # some of the steps below we want to do only once
+ self.conf = conf
+ self.host_target = getv(conf, 'HOST_TARGET')
+ for srctop in getv(conf, 'SRCTOPS', []):
+ if srctop[-1] != '/':
+ srctop += '/'
+ if not srctop in self.srctops:
+ self.srctops.append(srctop)
+
+ for objroot in getv(conf, 'OBJROOTS', []):
+ if not objroot in self.objroots:
+ self.objroots.append(objroot)
+ _objroot = os.path.realpath(objroot)
+ if objroot[-1] == '/':
+ _objroot += '/'
+ if not _objroot in self.objroots:
+ self.objroots.append(_objroot)
+
+ if self.debug:
+ print >> self.debug_out, "host_target=", self.host_target
+ print >> self.debug_out, "srctops=", self.srctops
+ print >> self.debug_out, "objroots=", self.objroots
+
+ self.dirdep_re = re.compile(r'([^/]+)/(.+)')
+
+ self.curdir = getv(conf, 'CURDIR')
+ self.machine = getv(conf, 'MACHINE', '')
+ self.reldir = getv(conf, 'RELDIR')
+ self.dpdeps = getv(conf, 'DPDEPS')
+ if self.dpdeps and not self.reldir:
+ if self.debug:
+ print >> self.debug_out, "need reldir:",
+ if self.curdir:
+ srctop = self.find_top(self.curdir, self.srctops)
+ if srctop:
+ self.reldir = self.curdir.replace(srctop,'')
+ if self.debug:
+ print >> self.debug_out, self.reldir
+ if not self.reldir:
+ self.dpdeps = None # we cannot do it?
+
+ if name:
+ self.parse()
+
+ def reset(self):
+ """reset state if we are being passed meta files from multiple directories."""
+ self.seen = {}
+ self.obj_deps = []
+ self.src_deps = []
+ self.file_deps = []
+
+ def dirdeps(self, sep='\n'):
+ """return DIRDEPS"""
+ return sep.strip() + sep.join(self.obj_deps)
+
+ def src_dirdeps(self, sep='\n'):
+ """return SRC_DIRDEPS"""
+ return sep.strip() + sep.join(self.src_deps)
+
+ def file_depends(self, out=None):
+ """Append DPDEPS_${file} += ${RELDIR}
+ for each file we saw, to the output file."""
+ if not self.reldir:
+ return None
+ for f in sort_unique(self.file_deps):
+ print >> out, 'DPDEPS_%s += %s' % (f, self.reldir)
+
+ def seenit(self, dir):
+ """rememer that we have seen dir."""
+ self.seen[dir] = 1
+
+ def add(self, list, data, clue=''):
+ """add data to list if it isn't already there."""
+ if data not in list:
+ list.append(data)
+ if self.debug:
+ print >> self.debug_out, "%s: %sAdd: %s" % (self.name, clue, data)
+
+ def find_top(self, path, list):
+ """the logical tree may be split accross multiple trees"""
+ for top in list:
+ if path.startswith(top):
+ if self.debug > 2:
+ print >> self.debug_out, "found in", top
+ return top
+ return None
+
+ def find_obj(self, objroot, dir, path, input):
+ """return path within objroot, taking care of .dirdep files"""
+ ddep = None
+ for ddepf in [path + '.dirdep', dir + '/.dirdep']:
+ if not ddep and os.path.exists(ddepf):
+ ddep = open(ddepf, 'rb').readline().strip('# \n')
+ if self.debug > 1:
+ print >> self.debug_out, "found %s: %s\n" % (ddepf, ddep)
+ if ddep.endswith(self.machine):
+ ddep = ddep[0:-(1+len(self.machine))]
+
+ if not ddep:
+ # no .dirdeps, so remember that we've seen the raw input
+ self.seenit(input)
+ self.seenit(dir)
+ if self.machine == 'none':
+ if dir.startswith(objroot):
+ return dir.replace(objroot,'')
+ return None
+ m = self.dirdep_re.match(dir.replace(objroot,''))
+ if m:
+ ddep = m.group(2)
+ dmachine = m.group(1)
+ if dmachine != self.machine:
+ if not (self.machine == 'host' and
+ dmachine == self.host_target):
+ if self.debug > 2:
+ print >> self.debug_out, "adding .%s to %s" % (dmachine, ddep)
+ ddep += '.' + dmachine
+
+ return ddep
+
+ def parse(self, name=None, file=None):
+ """A meta file looks like:
+
+ # Meta data file "path"
+ CMD "command-line"
+ CWD "cwd"
+ TARGET "target"
+ -- command output --
+ -- filemon acquired metadata --
+ # buildmon version 3
+ V 3
+ C "pid" "cwd"
+ E "pid" "path"
+ F "pid" "child"
+ R "pid" "path"
+ W "pid" "path"
+ X "pid" "status"
+ D "pid" "path"
+ L "pid" "src" "target"
+ M "pid" "old" "new"
+ S "pid" "path"
+ # Bye bye
+
+ We go to some effort to avoid processing a dependency more than once.
+ Of the above record types only C,E,F,L,R,V and W are of interest.
+ """
+
+ version = 0 # unknown
+ if name:
+ self.name = name;
+ if file:
+ f = file
+ cwd = last_dir = self.cwd
+ else:
+ f = open(self.name, 'rb')
+ skip = True
+ pid_cwd = {}
+ pid_last_dir = {}
+ last_pid = 0
+
+ if self.curdir:
+ self.seenit(self.curdir) # we ignore this
+
+ interesting = 'CEFLRV'
+ for line in f:
+ # ignore anything we don't care about
+ if not line[0] in interesting:
+ continue
+ if self.debug > 2:
+ print >> self.debug_out, "input:", line,
+ w = line.split()
+
+ if skip:
+ if w[0] == 'V':
+ skip = False
+ version = int(w[1])
+ """
+ if version < 4:
+ # we cannot ignore 'W' records
+ # as they may be 'rw'
+ interesting += 'W'
+ """
+ elif w[0] == 'CWD':
+ self.cwd = cwd = last_dir = w[1]
+ self.seenit(cwd) # ignore this
+ if self.debug:
+ print >> self.debug_out, "%s: CWD=%s" % (self.name, cwd)
+ continue
+
+ pid = int(w[1])
+ if pid != last_pid:
+ if last_pid:
+ pid_cwd[last_pid] = cwd
+ pid_last_dir[last_pid] = last_dir
+ cwd = getv(pid_cwd, pid, self.cwd)
+ last_dir = getv(pid_last_dir, pid, self.cwd)
+ last_pid = pid
+
+ # process operations
+ if w[0] == 'F':
+ npid = int(w[2])
+ pid_cwd[npid] = cwd
+ pid_last_dir[npid] = cwd
+ last_pid = npid
+ continue
+ elif w[0] == 'C':
+ cwd = abspath(w[2], cwd, None, self.debug, self.debug_out)
+ if cwd.endswith('/.'):
+ cwd = cwd[0:-2]
+ last_dir = cwd
+ if self.debug > 1:
+ print >> self.debug_out, "cwd=", cwd
+ continue
+
+ if w[2] in self.seen:
+ if self.debug > 2:
+ print >> self.debug_out, "seen:", w[2]
+ continue
+ # file operations
+ if w[0] in 'ML':
+ path = w[2].strip("'")
+ else:
+ path = w[2]
+ # we don't want to resolve the last component if it is
+ # a symlink
+ path = resolve(path, cwd, last_dir, self.debug, self.debug_out)
+ if not path:
+ continue
+ dir,base = os.path.split(path)
+ if dir in self.seen:
+ if self.debug > 2:
+ print >> self.debug_out, "seen:", dir
+ continue
+ # we can have a path in an objdir which is a link
+ # to the src dir, we may need to add dependencies for each
+ rdir = dir
+ dir = abspath(dir, cwd, last_dir, self.debug, self.debug_out)
+ if rdir == dir or rdir.find('./') > 0:
+ rdir = None
+ # now put path back together
+ path = '/'.join([dir,base])
+ if self.debug > 1:
+ print >> self.debug_out, "raw=%s rdir=%s dir=%s path=%s" % (w[2], rdir, dir, path)
+ if w[0] in 'SRWL':
+ if w[0] == 'W' and path.endswith('.dirdep'):
+ continue
+ if path in [last_dir, cwd, self.cwd, self.curdir]:
+ if self.debug > 1:
+ print >> self.debug_out, "skipping:", path
+ continue
+ if os.path.isdir(path):
+ if w[0] in 'RW':
+ last_dir = path;
+ if self.debug > 1:
+ print >> self.debug_out, "ldir=", last_dir
+ continue
+
+ if w[0] in 'REWML':
+ # finally, we get down to it
+ if dir == self.cwd or dir == self.curdir:
+ continue
+ srctop = self.find_top(path, self.srctops)
+ if srctop:
+ if self.dpdeps:
+ self.add(self.file_deps, path.replace(srctop,''), 'file')
+ self.add(self.src_deps, dir.replace(srctop,''), 'src')
+ self.seenit(w[2])
+ self.seenit(dir)
+ if rdir and not rdir.startswith(srctop):
+ dir = rdir # for below
+ rdir = None
+ else:
+ continue
+
+ objroot = None
+ for dir in [dir,rdir]:
+ if not dir:
+ continue
+ objroot = self.find_top(dir, self.objroots)
+ if objroot:
+ break
+ if objroot:
+ ddep = self.find_obj(objroot, dir, path, w[2])
+ if ddep:
+ self.add(self.obj_deps, ddep, 'obj')
+ else:
+ # don't waste time looking again
+ self.seenit(w[2])
+ self.seenit(dir)
+ if not file:
+ f.close()
+
+
+def main(argv, klass=MetaFile, xopts='', xoptf=None):
+ """Simple driver for class MetaFile.
+
+ Usage:
+ script [options] [key=value ...] "meta" ...
+
+ Options and key=value pairs contribute to the
+ dictionary passed to MetaFile.
+
+ -S "SRCTOP"
+ add "SRCTOP" to the "SRCTOPS" list.
+
+ -C "CURDIR"
+
+ -O "OBJROOT"
+ add "OBJROOT" to the "OBJROOTS" list.
+
+ -m "MACHINE"
+
+ -H "HOST_TARGET"
+
+ -D "DPDEPS"
+
+ -d bumps debug level
+
+ """
+ import getopt
+
+ # import Psyco if we can
+ # it can speed things up quite a bit
+ have_psyco = 0
+ try:
+ import psyco
+ psyco.full()
+ have_psyco = 1
+ except:
+ pass
+
+ conf = {
+ 'SRCTOPS': [],
+ 'OBJROOTS': [],
+ }
+
+ try:
+ machine = os.environ['MACHINE']
+ if machine:
+ conf['MACHINE'] = machine
+ srctop = os.environ['SB_SRC']
+ if srctop:
+ conf['SRCTOPS'].append(srctop)
+ objroot = os.environ['SB_OBJROOT']
+ if objroot:
+ conf['OBJROOTS'].append(objroot)
+ except:
+ pass
+
+ debug = 0
+ output = True
+
+ opts, args = getopt.getopt(argv[1:], 'dS:C:O:R:m:D:H:q' + xopts)
+ for o, a in opts:
+ if o == '-d':
+ debug += 1
+ elif o == '-q':
+ output = False
+ elif o == '-H':
+ conf['HOST_TARGET'] = a
+ elif o == '-S':
+ if a not in conf['SRCTOPS']:
+ conf['SRCTOPS'].append(a)
+ elif o == '-C':
+ conf['CURDIR'] = a
+ elif o == '-O':
+ if a not in conf['OBJROOTS']:
+ conf['OBJROOTS'].append(a)
+ elif o == '-R':
+ conf['RELDIR'] = a
+ elif o == '-D':
+ conf['DPDEPS'] = a
+ elif o == '-m':
+ conf['MACHINE'] = a
+ elif xoptf:
+ xoptf(o, a, conf)
+
+ conf['debug'] = debug
+
+ # get any var=val assignments
+ eaten = []
+ for a in args:
+ if a.find('=') > 0:
+ k,v = a.split('=')
+ if k in ['SRCTOP','OBJROOT','SRCTOPS','OBJROOTS']:
+ if k == 'SRCTOP':
+ k = 'SRCTOPS'
+ elif k == 'OBJROOT':
+ k = 'OBJROOTS'
+ if v not in conf[k]:
+ conf[k].append(v)
+ else:
+ conf[k] = v
+ eaten.append(a)
+ continue
+ break
+
+ for a in eaten:
+ args.remove(a)
+
+ debug_out = getv(conf, 'debug_out', sys.stderr)
+
+ if debug:
+ print >> debug_out, "config:"
+ print >> debug_out, "psyco=", have_psyco
+ for k,v in conf.items():
+ print >> debug_out, "%s=%s" % (k,v)
+
+ for a in args:
+ m = klass(a, conf)
+
+ if output:
+ print m.dirdeps()
+
+ print m.src_dirdeps('\nsrc:')
+
+ dpdeps = getv(conf, 'DPDEPS')
+ if dpdeps:
+ m.file_depends(open(dpdeps, 'wb'))
+
+ return m
+
+if __name__ == '__main__':
+ try:
+ main(sys.argv)
+ except:
+ # yes, this goes to stdout
+ print "ERROR: ", sys.exc_info()[1]
+ raise
+
diff --git a/share/mk/meta2deps.sh b/share/mk/meta2deps.sh
new file mode 100755
index 0000000..2fec368
--- /dev/null
+++ b/share/mk/meta2deps.sh
@@ -0,0 +1,306 @@
+#!/bin/sh
+
+# NAME:
+# meta2deps.sh - extract useful info from .meta files
+#
+# SYNOPSIS:
+# meta2deps.sh SB="SB" "meta" ...
+#
+# DESCRIPTION:
+# This script looks each "meta" file and extracts the
+# information needed to deduce build and src dependencies.
+#
+# To do this, we extract the 'CWD' record as well as all the
+# syscall traces which describe 'R'ead, 'C'hdir and 'E'xec
+# syscalls.
+#
+# The typical meta file looks like::
+#.nf
+#
+# # Meta data file "path"
+# CMD "command-line"
+# CWD "cwd"
+# TARGET "target"
+# -- command output --
+# -- filemon acquired metadata --
+# # buildmon version 2
+# V 2
+# E "pid" "path"
+# R "pid" "path"
+# C "pid" "cwd"
+# R "pid" "path"
+# X "pid" "status"
+#.fi
+#
+# The fact that all the syscall entry lines start with a single
+# character make these files quite easy to process using sed(1).
+#
+# To simplify the logic the 'CWD' line is made to look like a
+# normal 'C'hdir entry, and "cwd" is remembered so that it can
+# be prefixed to any "path" which is not absolute.
+#
+# If the "path" being read ends in '.srcrel' it is the content
+# of (actually the first line of) that file that we are
+# interested in.
+#
+# Any "path" which lies outside of the sandbox "SB" is generally
+# not of interest and is ignored.
+#
+# The output, is a set of absolute paths with "SB" like:
+#.nf
+#
+# $SB/obj-i386/bsd/gnu/lib/csu
+# $SB/obj-i386/bsd/gnu/lib/libgcc
+# $SB/obj-i386/bsd/include
+# $SB/obj-i386/bsd/lib/csu/i386-elf
+# $SB/obj-i386/bsd/lib/libc
+# $SB/src/bsd/include
+# $SB/src/bsd/sys/i386/include
+# $SB/src/bsd/sys/sys
+# $SB/src/pan-release/rtsock
+# $SB/src/pfe-shared/include/jnx
+#.fi
+#
+# Which can then be further processed by 'gendirdeps.mk'
+#
+# If we are passed 'DPDEPS='"dpdeps", then for each src file
+# outside of "CURDIR" we read, we output a line like:
+#.nf
+#
+# DPDEPS_$path += $RELDIR
+#.fi
+#
+# with "$path" geting turned into reldir's, so that we can end
+# up with a list of all the directories which depend on each src
+# file in another directory. This can allow for efficient yet
+# complete testing of changes.
+
+
+# RCSid:
+# $Id: meta2deps.sh,v 1.2 2011/10/02 00:34:47 sjg Exp $
+
+# Copyright (c) 2010, Juniper Networks, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+meta2src() {
+ cat /dev/null "$@" |
+ sed -n '/^R .*\.[chyl]$/s,^..[0-9]* ,,p' |
+ sort -u
+}
+
+meta2dirs() {
+ cat /dev/null "$@" |
+ sed -n '/^R .*\/.*\.[a-z0-9][^\/]*$/s,^..[0-9]* \(.*\)/[^/]*$,\1,p' |
+ sort -u
+}
+
+meta2deps() {
+ DPDEPS=
+ while :
+ do
+ case "$1" in
+ *=*) eval export "$1"; shift;;
+ *) break;;
+ esac
+ done
+
+ [ -z "$RELDIR" ] && unset DPDEPS
+ tf=/tmp/m2d$$-$USER
+ rm -f $tf.*
+ trap 'rm -f $tf.*; trap 0' 0
+
+ > $tf.dirdep
+ > $tf.qual
+ > $tf.srcdep
+ > $tf.srcrel
+ > $tf.dpdeps
+
+ seenit=
+ seensrc=
+ lpid=
+ cat /dev/null "$@" |
+ sed -e 's,^CWD,C C,;/^[CREFL] /!d' -e "s,',,g" |
+ while read op pid path junk
+ do
+ : op=$op pid=$pid path=$path
+ # we track cwd and ldir (of interest) per pid
+ # CWD is bmake's cwd
+ case "$lpid,$pid" in
+ ,C) CWD=$path cwd=$path ldir=$path
+ if [ -z "$SB" ]; then
+ SB=`echo $CWD | sed 's,/obj.*,,'`
+ fi
+ SRCTOP=${SRCTOP:-$SB/src}
+ continue
+ ;;
+ $pid,$pid) ;;
+ *)
+ case "$lpid" in
+ "") ;;
+ *) eval ldir_$lpid=$ldir cwd_$lpid=$cwd;;
+ esac
+ eval ldir=\${ldir_$pid:-$CWD} cwd=\${cwd_$pid:-$CWD}
+ lpid=$pid
+ ;;
+ esac
+
+ case "$op,$path" in
+ W,*srcrel) continue;;
+ C,*)
+ case "$path" in
+ /*) cwd=$path;;
+ *) cwd=`cd $cwd/$path 2> /dev/null && /bin/pwd`;;
+ esac
+ # watch out for temp dirs that no longer exist
+ test -d ${cwd:-/dev/null/no/such} || cwd=$CWD
+ continue
+ ;;
+ F,*) eval cwd_$path=$cwd ldir_$path=$ldir
+ continue
+ ;;
+ *) dir=${path%/*}
+ case "$path" in
+ $SB/*|${SB_BACKING_SB:-$SB}/*) ;;
+ $SB_OBJROOT*) ;;
+ /*/stage/*) ;;
+ /*) continue;;
+ *) for path in $ldir/$path $cwd/$path
+ do
+ test -e $path && break
+ done
+ dir=${path%/*}
+ ;;
+ esac
+ ;;
+ esac
+ # avoid repeating ourselves...
+ case "$DPDEPS,$seensrc," in
+ ,*)
+ case ",$seenit," in
+ *,$dir,*) continue;;
+ esac
+ ;;
+ *,$path,*) continue;;
+ esac
+ # canonicalize if needed
+ case "/$dir/" in
+ */../*|*/./*)
+ rdir=$dir
+ dir=`cd $dir 2> /dev/null && /bin/pwd`
+ seen="$rdir,$dir"
+ ;;
+ *) seen=$dir;;
+ esac
+ case "$dir" in
+ ${CURDIR:-.}|${CURDIR:-.}/*|"") continue;;
+ $SRCTOP/*|${SB_BACKING_SB:-$SB}/src/*)
+ # avoid repeating ourselves...
+ case "$DPDEPS,$seensrc," in
+ ,*)
+ case ",$seenit," in
+ *,$dir,*) continue;;
+ esac
+ ;;
+ esac
+ ;;
+ *)
+ case ",$seenit," in
+ *,$dir,*) continue;;
+ esac
+ ;;
+ esac
+ if [ -d $path ]; then
+ case "$path" in
+ */..) ldir=${dir%/*};;
+ *) ldir=$path;;
+ esac
+ continue
+ fi
+ [ -f $path ] || continue
+ case "$dir" in
+ $CWD) continue;; # ignore
+ $SRCTOP/*|${SB_BACKING_SB:-$SB}/src/*)
+ seenit="$seenit,$seen"
+ echo $dir >> $tf.srcdep
+ case "$DPDEPS,$reldir,$seensrc," in
+ ,*) ;;
+ *) seensrc="$seensrc,$path"
+ echo "DPDEPS_$dir/${path##*/} += $RELDIR" >> $tf.dpdeps
+ ;;
+ esac
+ continue
+ ;;
+ esac
+ # if there is a .dirdep we cannot skip
+ # just because we've seen the dir before.
+ if [ -s $path.dirdep ]; then
+ # this file contains:
+ # '# ${RELDIR}.<machine>'
+ echo $path.dirdep >> $tf.qual
+ continue
+ elif [ -s $dir.dirdep ]; then
+ echo $dir.dirdep >> $tf.qual
+ seenit="$seenit,$seen"
+ continue
+ fi
+ seenit="$seenit,$seen"
+ case "$dir" in
+ $SB/*|${SB_OBJROOT:-$SB/}*|${SB_BACKING_SB:-$SB}/*)
+ echo $dir;;
+ esac
+ done > $tf.dirdep
+ _nl=echo
+ for f in $tf.dirdep $tf.qual $tf.srcdep
+ do
+ [ -s $f ] || continue
+ case $f in
+ *qual) # a list of .dirdep files
+ # we can prefix everthing with $OBJTOP to
+ # tell gendirdeps.mk that these are
+ # DIRDEP entries, since they are already
+ # qualified with .<machine> as needed.
+ # We strip .$MACHINE though
+ xargs cat < $f | sort -u |
+ sed "s,^# ,,;s,^,$OBJTOP/,;s,\.$MACHINE\$,,"
+ ;;
+ *) sort -u $f;;
+ esac
+ _nl=:
+ done
+ if [ -s $tf.dpdeps ]; then
+ case "$DPDEPS" in
+ */*) ;;
+ *) echo > $DPDEPS;; # the echo is needed!
+ esac
+ sort -u $tf.dpdeps |
+ sed "s,${SRCTOP}/,,;s,${SB_BACKING_SB:-$SB}/src/,," >> $DPDEPS
+ fi
+ # ensure we produce _something_ else egrep -v gets upset
+ $_nl
+}
+
+case /$0 in
+*/meta2dep*) meta2deps "$@";;
+*/meta2dirs*) meta2dirs "$@";;
+*/meta2src*) meta2src "$@";;
+esac
diff --git a/share/mk/sys.dependfile.mk b/share/mk/sys.dependfile.mk
new file mode 100644
index 0000000..2b99f84
--- /dev/null
+++ b/share/mk/sys.dependfile.mk
@@ -0,0 +1,38 @@
+# $Id: sys.dependfile.mk,v 1.3 2012/04/25 15:45:04 sjg Exp $
+#
+# @(#) Copyright (c) 2012, Simon J. Gerraty
+#
+# This file is provided in the hope that it will
+# be of use. There is absolutely NO WARRANTY.
+# Permission to copy, redistribute or otherwise
+# use this file is hereby granted provided that
+# the above copyright notice and this notice are
+# left intact.
+#
+# Please send copies of changes and bug-fixes to:
+# sjg@crufty.net
+#
+
+# This only makes sense in meta mode.
+# This allows a mixture of auto generated as well as manually edited
+# dependency files, which can be differentiated by their names.
+# As per dirdeps.mk we only require:
+# 1. a common prefix
+# 2. that machine specific files end in .${MACHINE}
+#
+# The .MAKE.DEPENDFILE_PREFERENCE below is an example.
+
+# All depend file names should start with this
+.MAKE.DEPENDFILE_PREFIX ?= Makefile.depend
+
+# The order of preference: we will use the first one of these we find
+# otherwise the 1st entry will be used by default.
+.MAKE.DEPENDFILE_PREFERENCE ?= \
+ ${.CURDIR}/${.MAKE.DEPENDFILE_PREFIX}.${MACHINE} \
+ ${.CURDIR}/${.MAKE.DEPENDFILE_PREFIX}
+
+_e := ${.MAKE.DEPENDFILE_PREFERENCE:@m@${exists($m):?$m:}@}
+.if !empty(_e)
+.MAKE.DEPENDFILE := ${_e:[1]}
+.endif
+.MAKE.DEPENDFILE ?= ${.MAKE.DEPENDFILE_PREFERENCE:[1]}
diff --git a/share/mklocale/Makefile.depend b/share/mklocale/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/mklocale/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/monetdef/Makefile.depend b/share/monetdef/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/monetdef/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/msgdef/Makefile.depend b/share/msgdef/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/msgdef/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/numericdef/Makefile.depend b/share/numericdef/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/numericdef/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/security/Makefile.depend b/share/security/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/security/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/skel/Makefile.depend b/share/skel/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/skel/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/snmp/mibs/Makefile.depend b/share/snmp/mibs/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/snmp/mibs/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/syscons/fonts/Makefile.depend b/share/syscons/fonts/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/syscons/fonts/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/syscons/keymaps/Makefile.depend b/share/syscons/keymaps/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/syscons/keymaps/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/syscons/scrnmaps/Makefile.depend b/share/syscons/scrnmaps/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/share/syscons/scrnmaps/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/tabset/Makefile.depend b/share/tabset/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/tabset/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/termcap/Makefile.depend b/share/termcap/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/termcap/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/timedef/Makefile.depend b/share/timedef/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/timedef/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/share/zoneinfo/Makefile.depend b/share/zoneinfo/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/share/zoneinfo/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sys/boot/ficl/Makefile.depend b/sys/boot/ficl/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/sys/boot/ficl/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sys/boot/i386/boot2/Makefile.depend b/sys/boot/i386/boot2/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/sys/boot/i386/boot2/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sys/boot/i386/loader/Makefile.depend b/sys/boot/i386/loader/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/sys/boot/i386/loader/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sys/boot/i386/zfsloader/Makefile.depend b/sys/boot/i386/zfsloader/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/sys/boot/i386/zfsloader/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk
index f0d3d4d..26dc506 100644
--- a/sys/conf/kmod.mk
+++ b/sys/conf/kmod.mk
@@ -252,6 +252,8 @@ SYSDIR= ${_dir}
.error "can't find kernel source tree"
.endif
+.NOPATH: ${_ILINKS}
+
${_ILINKS}:
@case ${.TARGET} in \
machine) \
diff --git a/sys/contrib/pf/net/if_pflog.c b/sys/contrib/pf/net/if_pflog.c
new file mode 100644
index 0000000..349930b
--- /dev/null
+++ b/sys/contrib/pf/net/if_pflog.c
@@ -0,0 +1,435 @@
+/* $OpenBSD: if_pflog.c,v 1.26 2007/10/18 21:58:18 mpf Exp $ */
+/*
+ * The authors of this code are John Ioannidis (ji@tla.org),
+ * Angelos D. Keromytis (kermit@csd.uch.gr) and
+ * Niels Provos (provos@physnet.uni-hamburg.de).
+ *
+ * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
+ * in November 1995.
+ *
+ * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
+ * by Angelos D. Keromytis.
+ *
+ * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
+ * and Niels Provos.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis
+ * and Niels Provos.
+ * Copyright (c) 2001, Angelos D. Keromytis, Niels Provos.
+ *
+ * Permission to use, copy, and modify this software with or without fee
+ * is hereby granted, provided that this entire notice is included in
+ * all copies of any software which is or includes a copy or
+ * modification of this software.
+ * You may use this code under the GNU public license if you so wish. Please
+ * contribute changes back to the authors under this freer than GPL license
+ * so that we may further the use of strong encryption without limitations to
+ * all.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
+ * PURPOSE.
+ */
+
+#ifdef __FreeBSD__
+#include "opt_inet.h"
+#include "opt_inet6.h"
+#include "opt_bpf.h"
+#include "opt_pf.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifdef DEV_BPF
+#define NBPFILTER DEV_BPF
+#else
+#define NBPFILTER 0
+#endif
+
+#ifdef DEV_PFLOG
+#define NPFLOG DEV_PFLOG
+#else
+#define NPFLOG 0
+#endif
+
+#else /* ! __FreeBSD__ */
+#include "bpfilter.h"
+#include "pflog.h"
+#endif /* __FreeBSD__ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/proc.h>
+#include <sys/socket.h>
+#ifdef __FreeBSD__
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/sockio.h>
+#else
+#include <sys/ioctl.h>
+#endif
+
+#include <net/if.h>
+#ifdef __FreeBSD__
+#include <net/if_clone.h>
+#endif
+#include <net/if_types.h>
+#include <net/route.h>
+#include <net/bpf.h>
+
+#if defined(INET) || defined(INET6)
+#include <netinet/in.h>
+#endif
+#ifdef INET
+#include <netinet/in_var.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#endif
+
+#ifdef INET6
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>
+#endif /* INET6 */
+
+#include <net/pfvar.h>
+#include <net/if_pflog.h>
+
+#ifdef __FreeBSD__
+#ifdef INET
+#include <machine/in_cksum.h>
+#endif /* INET */
+#endif /* __FreeBSD__ */
+
+#define PFLOGMTU (32768 + MHLEN + MLEN)
+
+#ifdef PFLOGDEBUG
+#define DPRINTF(x) do { if (pflogdebug) printf x ; } while (0)
+#else
+#define DPRINTF(x)
+#endif
+
+void pflogattach(int);
+int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
+#ifdef __FreeBSD__
+ struct route *);
+#else
+ struct rtentry *);
+#endif
+int pflogioctl(struct ifnet *, u_long, caddr_t);
+void pflogstart(struct ifnet *);
+#ifdef __FreeBSD__
+static int pflog_clone_create(struct if_clone *, int, caddr_t);
+static void pflog_clone_destroy(struct ifnet *);
+#else
+int pflog_clone_create(struct if_clone *, int);
+int pflog_clone_destroy(struct ifnet *);
+#endif
+
+LIST_HEAD(, pflog_softc) pflogif_list;
+#ifdef __FreeBSD__
+IFC_SIMPLE_DECLARE(pflog, 1);
+#else
+struct if_clone pflog_cloner =
+ IF_CLONE_INITIALIZER("pflog", pflog_clone_create, pflog_clone_destroy);
+#endif
+
+struct ifnet *pflogifs[PFLOGIFS_MAX]; /* for fast access */
+
+void
+pflogattach(int npflog)
+{
+ int i;
+ LIST_INIT(&pflogif_list);
+ for (i = 0; i < PFLOGIFS_MAX; i++)
+ pflogifs[i] = NULL;
+ if_clone_attach(&pflog_cloner);
+}
+
+#ifdef __FreeBSD__
+static int
+pflog_clone_create(struct if_clone *ifc, int unit, caddr_t param)
+#else
+int
+pflog_clone_create(struct if_clone *ifc, int unit)
+#endif
+{
+ struct ifnet *ifp;
+ struct pflog_softc *pflogif;
+ int s;
+
+ if (unit >= PFLOGIFS_MAX)
+ return (EINVAL);
+
+ if ((pflogif = malloc(sizeof(*pflogif),
+ M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
+ return (ENOMEM);
+
+ pflogif->sc_unit = unit;
+#ifdef __FreeBSD__
+ ifp = pflogif->sc_ifp = if_alloc(IFT_PFLOG);
+ if (ifp == NULL) {
+ free(pflogif, M_DEVBUF);
+ return (ENOSPC);
+ }
+ if_initname(ifp, ifc->ifc_name, unit);
+#else
+ ifp = &pflogif->sc_if;
+ snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflog%d", unit);
+#endif
+ ifp->if_softc = pflogif;
+ ifp->if_mtu = PFLOGMTU;
+ ifp->if_ioctl = pflogioctl;
+ ifp->if_output = pflogoutput;
+ ifp->if_start = pflogstart;
+#ifndef __FreeBSD__
+ ifp->if_type = IFT_PFLOG;
+#endif
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ ifp->if_hdrlen = PFLOG_HDRLEN;
+ if_attach(ifp);
+#ifndef __FreeBSD__
+ if_alloc_sadl(ifp);
+#endif
+
+#if NBPFILTER > 0
+#ifdef __FreeBSD__
+ bpfattach(ifp, DLT_PFLOG, PFLOG_HDRLEN);
+#else
+ bpfattach(&pflogif->sc_if.if_bpf, ifp, DLT_PFLOG, PFLOG_HDRLEN);
+#endif
+#endif
+
+ s = splnet();
+#ifdef __FreeBSD__
+ /* XXX: Why pf(4) lock?! Better add a pflog lock?! */
+ PF_LOCK();
+#endif
+ LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list);
+ pflogifs[unit] = ifp;
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+
+ return (0);
+}
+
+#ifdef __FreeBSD__
+static void
+pflog_clone_destroy(struct ifnet *ifp)
+#else
+int
+pflog_clone_destroy(struct ifnet *ifp)
+#endif
+{
+ struct pflog_softc *pflogif = ifp->if_softc;
+ int s;
+
+ s = splnet();
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ pflogifs[pflogif->sc_unit] = NULL;
+ LIST_REMOVE(pflogif, sc_list);
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+
+#if NBPFILTER > 0
+ bpfdetach(ifp);
+#endif
+ if_detach(ifp);
+#ifdef __FreeBSD__
+ if_free(ifp);
+#endif
+ free(pflogif, M_DEVBUF);
+#ifndef __FreeBSD__
+ return (0);
+#endif
+}
+
+/*
+ * Start output on the pflog interface.
+ */
+void
+pflogstart(struct ifnet *ifp)
+{
+ struct mbuf *m;
+#ifndef __FreeBSD__
+ int s;
+#endif
+
+ for (;;) {
+#ifdef __FreeBSD__
+ IF_LOCK(&ifp->if_snd);
+ _IF_DROP(&ifp->if_snd);
+ _IF_DEQUEUE(&ifp->if_snd, m);
+ IF_UNLOCK(&ifp->if_snd);
+#else
+ s = splnet();
+ IF_DROP(&ifp->if_snd);
+ IF_DEQUEUE(&ifp->if_snd, m);
+ splx(s);
+#endif
+
+ if (m == NULL)
+ return;
+ else
+ m_freem(m);
+ }
+}
+
+int
+pflogoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
+#ifdef __FreeBSD__
+ struct route *rt)
+#else
+ struct rtentry *rt)
+#endif
+{
+ m_freem(m);
+ return (0);
+}
+
+/* ARGSUSED */
+int
+pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+ switch (cmd) {
+ case SIOCSIFFLAGS:
+#ifdef __FreeBSD__
+ if (ifp->if_flags & IFF_UP)
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ else
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+#else
+ if (ifp->if_flags & IFF_UP)
+ ifp->if_flags |= IFF_RUNNING;
+ else
+ ifp->if_flags &= ~IFF_RUNNING;
+#endif
+ break;
+ default:
+ return (ENOTTY);
+ }
+
+ return (0);
+}
+
+int
+pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
+ u_int8_t reason, struct pf_rule *rm, struct pf_rule *am,
+ struct pf_ruleset *ruleset, struct pf_pdesc *pd)
+{
+#if NBPFILTER > 0
+ struct ifnet *ifn;
+ struct pfloghdr hdr;
+
+ if (kif == NULL || m == NULL || rm == NULL || pd == NULL)
+ return ( 1);
+
+ if ((ifn = pflogifs[rm->logif]) == NULL || !ifn->if_bpf)
+ return (0);
+
+ bzero(&hdr, sizeof(hdr));
+ hdr.length = PFLOG_REAL_HDRLEN;
+ hdr.af = af;
+ hdr.action = rm->action;
+ hdr.reason = reason;
+ memcpy(hdr.ifname, kif->pfik_name, sizeof(hdr.ifname));
+
+ if (am == NULL) {
+ hdr.rulenr = htonl(rm->nr);
+ hdr.subrulenr = 1;
+ } else {
+ hdr.rulenr = htonl(am->nr);
+ hdr.subrulenr = htonl(rm->nr);
+ if (ruleset != NULL && ruleset->anchor != NULL)
+ strlcpy(hdr.ruleset, ruleset->anchor->name,
+ sizeof(hdr.ruleset));
+ }
+ if (rm->log & PF_LOG_SOCKET_LOOKUP && !pd->lookup.done)
+#ifdef __FreeBSD__
+ /*
+ * XXX: This should not happen as we force an early lookup
+ * via debug.pfugidhack
+ */
+ ; /* empty */
+#else
+ pd->lookup.done = pf_socket_lookup(dir, pd);
+#endif
+ if (pd->lookup.done > 0) {
+ hdr.uid = pd->lookup.uid;
+ hdr.pid = pd->lookup.pid;
+ } else {
+ hdr.uid = UID_MAX;
+ hdr.pid = NO_PID;
+ }
+ hdr.rule_uid = rm->cuid;
+ hdr.rule_pid = rm->cpid;
+ hdr.dir = dir;
+
+#ifdef INET
+ if (af == AF_INET && dir == PF_OUT) {
+ struct ip *ip;
+
+ ip = mtod(m, struct ip *);
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
+ }
+#endif /* INET */
+
+ ifn->if_opackets++;
+ ifn->if_obytes += m->m_pkthdr.len;
+#ifdef __FreeBSD__
+ BPF_MTAP2(ifn, &hdr, PFLOG_HDRLEN, m);
+#else
+ bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, PFLOG_HDRLEN, m,
+ BPF_DIRECTION_OUT);
+#endif
+#endif
+
+ return (0);
+}
+
+#ifdef __FreeBSD__
+static int
+pflog_modevent(module_t mod, int type, void *data)
+{
+ int error = 0;
+
+ switch (type) {
+ case MOD_LOAD:
+ pflogattach(1);
+ PF_LOCK();
+ pflog_packet_ptr = pflog_packet;
+ PF_UNLOCK();
+ break;
+ case MOD_UNLOAD:
+ PF_LOCK();
+ pflog_packet_ptr = NULL;
+ PF_UNLOCK();
+ if_clone_detach(&pflog_cloner);
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+
+ return error;
+}
+
+static moduledata_t pflog_mod = { "pflog", pflog_modevent, 0 };
+
+#define PFLOG_MODVER 1
+
+DECLARE_MODULE(pflog, pflog_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+MODULE_VERSION(pflog, PFLOG_MODVER);
+MODULE_DEPEND(pflog, pf, PF_MODVER, PF_MODVER, PF_MODVER);
+#endif /* __FreeBSD__ */
diff --git a/sys/contrib/pf/net/if_pflog.h b/sys/contrib/pf/net/if_pflog.h
new file mode 100644
index 0000000..5f48f6c
--- /dev/null
+++ b/sys/contrib/pf/net/if_pflog.h
@@ -0,0 +1,101 @@
+/* $OpenBSD: if_pflog.h,v 1.13 2006/10/23 12:46:09 henning Exp $ */
+/*
+ * Copyright 2001 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NET_IF_PFLOG_H_
+#define _NET_IF_PFLOG_H_
+
+#define PFLOGIFS_MAX 16
+
+struct pflog_softc {
+#ifdef __FreeBSD__
+ struct ifnet *sc_ifp; /* the interface pointer */
+#else
+ struct ifnet sc_if; /* the interface */
+#endif
+ int sc_unit;
+ LIST_ENTRY(pflog_softc) sc_list;
+};
+
+#define PFLOG_RULESET_NAME_SIZE 16
+
+struct pfloghdr {
+ u_int8_t length;
+ sa_family_t af;
+ u_int8_t action;
+ u_int8_t reason;
+ char ifname[IFNAMSIZ];
+ char ruleset[PFLOG_RULESET_NAME_SIZE];
+ u_int32_t rulenr;
+ u_int32_t subrulenr;
+ uid_t uid;
+ pid_t pid;
+ uid_t rule_uid;
+ pid_t rule_pid;
+ u_int8_t dir;
+ u_int8_t pad[3];
+};
+
+#define PFLOG_HDRLEN sizeof(struct pfloghdr)
+/* minus pad, also used as a signature */
+#define PFLOG_REAL_HDRLEN offsetof(struct pfloghdr, pad)
+
+/* XXX remove later when old format logs are no longer needed */
+struct old_pfloghdr {
+ u_int32_t af;
+ char ifname[IFNAMSIZ];
+ short rnr;
+ u_short reason;
+ u_short action;
+ u_short dir;
+};
+#define OLD_PFLOG_HDRLEN sizeof(struct old_pfloghdr)
+
+#ifdef _KERNEL
+#ifdef __FreeBSD__
+struct pf_rule;
+struct pf_ruleset;
+struct pfi_kif;
+struct pf_pdesc;
+
+#if 0
+typedef int pflog_packet_t(struct pfi_kif *, struct mbuf *, sa_family_t,
+ u_int8_t, u_int8_t, struct pf_rule *, struct pf_rule *,
+ struct pf_ruleset *, struct pf_pdesc *);
+extern pflog_packet_t *pflog_packet_ptr;
+#endif
+#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) do { \
+ if (pflog_packet_ptr != NULL) \
+ pflog_packet_ptr(i,a,b,c,d,e,f,g,h); \
+} while (0)
+#else /* ! __FreeBSD__ */
+#if NPFLOG > 0
+#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) pflog_packet(i,a,b,c,d,e,f,g,h)
+#else
+#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) ((void)0)
+#endif /* NPFLOG > 0 */
+#endif
+#endif /* _KERNEL */
+#endif /* _NET_IF_PFLOG_H_ */
diff --git a/sys/contrib/pf/net/if_pflow.h b/sys/contrib/pf/net/if_pflow.h
new file mode 100644
index 0000000..35ccbeb
--- /dev/null
+++ b/sys/contrib/pf/net/if_pflow.h
@@ -0,0 +1,126 @@
+/* $OpenBSD: if_pflow.h,v 1.5 2009/02/27 11:09:36 gollo Exp $ */
+
+/*
+ * Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _NET_IF_PFLOW_H_
+#define _NET_IF_PFLOW_H_
+
+#define PFLOW_ID_LEN sizeof(u_int64_t)
+
+#define PFLOW_MAXFLOWS 30
+#define PFLOW_VERSION 5
+#define PFLOW_ENGINE_TYPE 42
+#define PFLOW_ENGINE_ID 42
+#define PFLOW_MAXBYTES 0xffffffff
+#define PFLOW_TIMEOUT 30
+
+struct pflow_flow {
+ u_int32_t src_ip;
+ u_int32_t dest_ip;
+ u_int32_t nexthop_ip;
+ u_int16_t if_index_in;
+ u_int16_t if_index_out;
+ u_int32_t flow_packets;
+ u_int32_t flow_octets;
+ u_int32_t flow_start;
+ u_int32_t flow_finish;
+ u_int16_t src_port;
+ u_int16_t dest_port;
+ u_int8_t pad1;
+ u_int8_t tcp_flags;
+ u_int8_t protocol;
+ u_int8_t tos;
+ u_int16_t src_as;
+ u_int16_t dest_as;
+ u_int8_t src_mask;
+ u_int8_t dest_mask;
+ u_int16_t pad2;
+} __packed;
+
+#ifdef _KERNEL
+
+extern int pflow_ok;
+
+struct pflow_softc {
+ struct ifnet sc_if;
+ struct ifnet *sc_pflow_ifp;
+
+ unsigned int sc_count;
+ unsigned int sc_maxcount;
+ u_int64_t sc_gcounter;
+ struct ip_moptions sc_imo;
+#ifdef __FreeBSD__
+ struct callout sc_tmo;
+#else
+ struct timeout sc_tmo;
+#endif
+ struct in_addr sc_sender_ip;
+ u_int16_t sc_sender_port;
+ struct in_addr sc_receiver_ip;
+ u_int16_t sc_receiver_port;
+ struct mbuf *sc_mbuf; /* current cumulative mbuf */
+ SLIST_ENTRY(pflow_softc) sc_next;
+};
+
+extern struct pflow_softc *pflowif;
+
+#endif /* _KERNEL */
+
+struct pflow_header {
+ u_int16_t version;
+ u_int16_t count;
+ u_int32_t uptime_ms;
+ u_int32_t time_sec;
+ u_int32_t time_nanosec;
+ u_int32_t flow_sequence;
+ u_int8_t engine_type;
+ u_int8_t engine_id;
+ u_int8_t reserved1;
+ u_int8_t reserved2;
+} __packed;
+
+#define PFLOW_HDRLEN sizeof(struct pflow_header)
+
+struct pflowstats {
+ u_int64_t pflow_flows;
+ u_int64_t pflow_packets;
+ u_int64_t pflow_onomem;
+ u_int64_t pflow_oerrors;
+};
+
+/*
+ * Configuration structure for SIOCSETPFLOW SIOCGETPFLOW
+ */
+struct pflowreq {
+ struct in_addr sender_ip;
+ struct in_addr receiver_ip;
+ u_int16_t receiver_port;
+ u_int16_t addrmask;
+#define PFLOW_MASK_SRCIP 0x01
+#define PFLOW_MASK_DSTIP 0x02
+#define PFLOW_MASK_DSTPRT 0x04
+};
+
+#ifdef _KERNEL
+int export_pflow(struct pf_state *);
+int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+#endif /* _KERNEL */
+
+#endif /* _NET_IF_PFLOW_H_ */
diff --git a/sys/contrib/pf/net/if_pfsync.c b/sys/contrib/pf/net/if_pfsync.c
new file mode 100644
index 0000000..7da6c2e
--- /dev/null
+++ b/sys/contrib/pf/net/if_pfsync.c
@@ -0,0 +1,3474 @@
+/* $OpenBSD: if_pfsync.c,v 1.110 2009/02/24 05:39:19 dlg Exp $ */
+
+/*
+ * Copyright (c) 2002 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2009 David Gwynne <dlg@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Revisions picked from OpenBSD after revision 1.110 import:
+ * 1.118, 1.124, 1.148, 1.149, 1.151, 1.171 - fixes to bulk updates
+ * 1.120, 1.175 - use monotonic time_uptime
+ * 1.122 - reduce number of updates for non-TCP sessions
+ * 1.128 - cleanups
+ * 1.146 - bzero() mbuf before sparsely filling it with data
+ * 1.170 - SIOCSIFMTU checks
+ * 1.126, 1.142 - deferred packets processing
+ * 1.173 - correct expire time processing
+ */
+
+#ifdef __FreeBSD__
+#include "opt_inet.h"
+#include "opt_inet6.h"
+#include "opt_pf.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define NBPFILTER 1
+#endif /* __FreeBSD__ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#ifdef __FreeBSD__
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/priv.h>
+#endif
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#ifdef __FreeBSD__
+#include <sys/endian.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/sockio.h>
+#include <sys/taskqueue.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/protosw.h>
+#else
+#include <sys/ioctl.h>
+#include <sys/timeout.h>
+#endif
+#include <sys/sysctl.h>
+#ifndef __FreeBSD__
+#include <sys/pool.h>
+#endif
+
+#include <net/if.h>
+#ifdef __FreeBSD__
+#include <net/if_clone.h>
+#endif
+#include <net/if_types.h>
+#include <net/route.h>
+#include <net/bpf.h>
+#include <net/netisr.h>
+#ifdef __FreeBSD__
+#include <net/vnet.h>
+#endif
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_seq.h>
+
+#ifdef INET
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#endif
+
+#ifdef INET6
+#include <netinet6/nd6.h>
+#endif /* INET6 */
+
+#ifdef __FreeBSD__
+#include <netinet/ip_carp.h>
+#else
+#include "carp.h"
+#if NCARP > 0
+#include <netinet/ip_carp.h>
+#endif
+#endif
+
+#include <net/pfvar.h>
+#include <net/if_pfsync.h>
+
+#ifndef __FreeBSD__
+#include "bpfilter.h"
+#include "pfsync.h"
+#endif
+
+#define PFSYNC_MINPKT ( \
+ sizeof(struct ip) + \
+ sizeof(struct pfsync_header) + \
+ sizeof(struct pfsync_subheader) + \
+ sizeof(struct pfsync_eof))
+
+struct pfsync_pkt {
+ struct ip *ip;
+ struct in_addr src;
+ u_int8_t flags;
+};
+
+int pfsync_input_hmac(struct mbuf *, int);
+
+int pfsync_upd_tcp(struct pf_state *, struct pfsync_state_peer *,
+ struct pfsync_state_peer *);
+
+int pfsync_in_clr(struct pfsync_pkt *, struct mbuf *, int, int);
+int pfsync_in_ins(struct pfsync_pkt *, struct mbuf *, int, int);
+int pfsync_in_iack(struct pfsync_pkt *, struct mbuf *, int, int);
+int pfsync_in_upd(struct pfsync_pkt *, struct mbuf *, int, int);
+int pfsync_in_upd_c(struct pfsync_pkt *, struct mbuf *, int, int);
+int pfsync_in_ureq(struct pfsync_pkt *, struct mbuf *, int, int);
+int pfsync_in_del(struct pfsync_pkt *, struct mbuf *, int, int);
+int pfsync_in_del_c(struct pfsync_pkt *, struct mbuf *, int, int);
+int pfsync_in_bus(struct pfsync_pkt *, struct mbuf *, int, int);
+int pfsync_in_tdb(struct pfsync_pkt *, struct mbuf *, int, int);
+int pfsync_in_eof(struct pfsync_pkt *, struct mbuf *, int, int);
+
+int pfsync_in_error(struct pfsync_pkt *, struct mbuf *, int, int);
+
+int (*pfsync_acts[])(struct pfsync_pkt *, struct mbuf *, int, int) = {
+ pfsync_in_clr, /* PFSYNC_ACT_CLR */
+ pfsync_in_ins, /* PFSYNC_ACT_INS */
+ pfsync_in_iack, /* PFSYNC_ACT_INS_ACK */
+ pfsync_in_upd, /* PFSYNC_ACT_UPD */
+ pfsync_in_upd_c, /* PFSYNC_ACT_UPD_C */
+ pfsync_in_ureq, /* PFSYNC_ACT_UPD_REQ */
+ pfsync_in_del, /* PFSYNC_ACT_DEL */
+ pfsync_in_del_c, /* PFSYNC_ACT_DEL_C */
+ pfsync_in_error, /* PFSYNC_ACT_INS_F */
+ pfsync_in_error, /* PFSYNC_ACT_DEL_F */
+ pfsync_in_bus, /* PFSYNC_ACT_BUS */
+ pfsync_in_tdb, /* PFSYNC_ACT_TDB */
+ pfsync_in_eof /* PFSYNC_ACT_EOF */
+};
+
+struct pfsync_q {
+ int (*write)(struct pf_state *, struct mbuf *, int);
+ size_t len;
+ u_int8_t action;
+};
+
+/* we have one of these for every PFSYNC_S_ */
+int pfsync_out_state(struct pf_state *, struct mbuf *, int);
+int pfsync_out_iack(struct pf_state *, struct mbuf *, int);
+int pfsync_out_upd_c(struct pf_state *, struct mbuf *, int);
+int pfsync_out_del(struct pf_state *, struct mbuf *, int);
+
+struct pfsync_q pfsync_qs[] = {
+ { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_INS },
+ { pfsync_out_iack, sizeof(struct pfsync_ins_ack), PFSYNC_ACT_INS_ACK },
+ { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_UPD },
+ { pfsync_out_upd_c, sizeof(struct pfsync_upd_c), PFSYNC_ACT_UPD_C },
+ { pfsync_out_del, sizeof(struct pfsync_del_c), PFSYNC_ACT_DEL_C }
+};
+
+void pfsync_q_ins(struct pf_state *, int);
+void pfsync_q_del(struct pf_state *);
+
+struct pfsync_upd_req_item {
+ TAILQ_ENTRY(pfsync_upd_req_item) ur_entry;
+ struct pfsync_upd_req ur_msg;
+};
+TAILQ_HEAD(pfsync_upd_reqs, pfsync_upd_req_item);
+
+struct pfsync_deferral {
+ TAILQ_ENTRY(pfsync_deferral) pd_entry;
+ struct pf_state *pd_st;
+ struct mbuf *pd_m;
+#ifdef __FreeBSD__
+ struct callout pd_tmo;
+#else
+ struct timeout pd_tmo;
+#endif
+};
+TAILQ_HEAD(pfsync_deferrals, pfsync_deferral);
+
+#define PFSYNC_PLSIZE MAX(sizeof(struct pfsync_upd_req_item), \
+ sizeof(struct pfsync_deferral))
+
+#ifdef notyet
+int pfsync_out_tdb(struct tdb *, struct mbuf *, int);
+#endif
+
+struct pfsync_softc {
+#ifdef __FreeBSD__
+ struct ifnet *sc_ifp;
+#else
+ struct ifnet sc_if;
+#endif
+ struct ifnet *sc_sync_if;
+
+#ifdef __FreeBSD__
+ uma_zone_t sc_pool;
+#else
+ struct pool sc_pool;
+#endif
+
+ struct ip_moptions sc_imo;
+
+ struct in_addr sc_sync_peer;
+ u_int8_t sc_maxupdates;
+#ifdef __FreeBSD__
+ int pfsync_sync_ok;
+#endif
+
+ struct ip sc_template;
+
+ struct pf_state_queue sc_qs[PFSYNC_S_COUNT];
+ size_t sc_len;
+
+ struct pfsync_upd_reqs sc_upd_req_list;
+
+ int sc_defer;
+ struct pfsync_deferrals sc_deferrals;
+ u_int sc_deferred;
+
+ void *sc_plus;
+ size_t sc_pluslen;
+
+ u_int32_t sc_ureq_sent;
+ int sc_bulk_tries;
+#ifdef __FreeBSD__
+ struct callout sc_bulkfail_tmo;
+#else
+ struct timeout sc_bulkfail_tmo;
+#endif
+
+ u_int32_t sc_ureq_received;
+ struct pf_state *sc_bulk_next;
+ struct pf_state *sc_bulk_last;
+#ifdef __FreeBSD__
+ struct callout sc_bulk_tmo;
+#else
+ struct timeout sc_bulk_tmo;
+#endif
+
+ TAILQ_HEAD(, tdb) sc_tdb_q;
+
+#ifdef __FreeBSD__
+ struct callout sc_tmo;
+#else
+ struct timeout sc_tmo;
+#endif
+};
+
+#ifdef __FreeBSD__
+static MALLOC_DEFINE(M_PFSYNC, "pfsync", "pfsync data");
+static VNET_DEFINE(struct pfsync_softc *, pfsyncif) = NULL;
+#define V_pfsyncif VNET(pfsyncif)
+static VNET_DEFINE(void *, pfsync_swi_cookie) = NULL;
+#define V_pfsync_swi_cookie VNET(pfsync_swi_cookie)
+static VNET_DEFINE(struct pfsyncstats, pfsyncstats);
+#define V_pfsyncstats VNET(pfsyncstats)
+static VNET_DEFINE(int, pfsync_carp_adj) = CARP_MAXSKEW;
+#define V_pfsync_carp_adj VNET(pfsync_carp_adj)
+
+static void pfsyncintr(void *);
+static int pfsync_multicast_setup(struct pfsync_softc *);
+static void pfsync_multicast_cleanup(struct pfsync_softc *);
+static int pfsync_init(void);
+static void pfsync_uninit(void);
+static void pfsync_sendout1(int);
+
+#define schednetisr(NETISR_PFSYNC) swi_sched(V_pfsync_swi_cookie, 0)
+
+SYSCTL_NODE(_net, OID_AUTO, pfsync, CTLFLAG_RW, 0, "PFSYNC");
+SYSCTL_VNET_STRUCT(_net_pfsync, OID_AUTO, stats, CTLFLAG_RW,
+ &VNET_NAME(pfsyncstats), pfsyncstats,
+ "PFSYNC statistics (struct pfsyncstats, net/if_pfsync.h)");
+SYSCTL_INT(_net_pfsync, OID_AUTO, carp_demotion_factor, CTLFLAG_RW,
+ &VNET_NAME(pfsync_carp_adj), 0, "pfsync's CARP demotion factor adjustment");
+#else
+struct pfsync_softc *pfsyncif = NULL;
+struct pfsyncstats pfsyncstats;
+#define V_pfsyncstats pfsyncstats
+#endif
+
+void pfsyncattach(int);
+#ifdef __FreeBSD__
+int pfsync_clone_create(struct if_clone *, int, caddr_t);
+void pfsync_clone_destroy(struct ifnet *);
+#else
+int pfsync_clone_create(struct if_clone *, int);
+int pfsync_clone_destroy(struct ifnet *);
+#endif
+int pfsync_alloc_scrub_memory(struct pfsync_state_peer *,
+ struct pf_state_peer *);
+void pfsync_update_net_tdb(struct pfsync_tdb *);
+int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
+#ifdef __FreeBSD__
+ struct route *);
+#else
+ struct rtentry *);
+#endif
+int pfsyncioctl(struct ifnet *, u_long, caddr_t);
+void pfsyncstart(struct ifnet *);
+
+struct mbuf *pfsync_if_dequeue(struct ifnet *);
+
+void pfsync_deferred(struct pf_state *, int);
+void pfsync_undefer(struct pfsync_deferral *, int);
+void pfsync_defer_tmo(void *);
+
+void pfsync_request_update(u_int32_t, u_int64_t);
+void pfsync_update_state_req(struct pf_state *);
+
+void pfsync_drop(struct pfsync_softc *);
+void pfsync_sendout(void);
+void pfsync_send_plus(void *, size_t);
+void pfsync_timeout(void *);
+void pfsync_tdb_timeout(void *);
+
+void pfsync_bulk_start(void);
+void pfsync_bulk_status(u_int8_t);
+void pfsync_bulk_update(void *);
+void pfsync_bulk_fail(void *);
+
+#ifdef __FreeBSD__
+/* XXX: ugly */
+#define betoh64 (unsigned long long)be64toh
+#define timeout_del callout_stop
+#endif
+
+#define PFSYNC_MAX_BULKTRIES 12
+#ifndef __FreeBSD__
+int pfsync_sync_ok;
+#endif
+
+#ifdef __FreeBSD__
+VNET_DEFINE(struct ifc_simple_data, pfsync_cloner_data);
+VNET_DEFINE(struct if_clone, pfsync_cloner);
+#define V_pfsync_cloner_data VNET(pfsync_cloner_data)
+#define V_pfsync_cloner VNET(pfsync_cloner)
+IFC_SIMPLE_DECLARE(pfsync, 1);
+#else
+struct if_clone pfsync_cloner =
+ IF_CLONE_INITIALIZER("pfsync", pfsync_clone_create, pfsync_clone_destroy);
+#endif
+
+void
+pfsyncattach(int npfsync)
+{
+ if_clone_attach(&pfsync_cloner);
+}
+int
+#ifdef __FreeBSD__
+pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
+#else
+pfsync_clone_create(struct if_clone *ifc, int unit)
+#endif
+{
+ struct pfsync_softc *sc;
+ struct ifnet *ifp;
+ int q;
+
+ if (unit != 0)
+ return (EINVAL);
+
+#ifdef __FreeBSD__
+ sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
+ sc->pfsync_sync_ok = 1;
+#else
+ pfsync_sync_ok = 1;
+ sc = malloc(sizeof(*pfsyncif), M_DEVBUF, M_NOWAIT | M_ZERO);
+#endif
+
+ for (q = 0; q < PFSYNC_S_COUNT; q++)
+ TAILQ_INIT(&sc->sc_qs[q]);
+
+#ifdef __FreeBSD__
+ sc->sc_pool = uma_zcreate("pfsync", PFSYNC_PLSIZE, NULL, NULL, NULL,
+ NULL, UMA_ALIGN_PTR, 0);
+#else
+ pool_init(&sc->sc_pool, PFSYNC_PLSIZE, 0, 0, 0, "pfsync", NULL);
+#endif
+ TAILQ_INIT(&sc->sc_upd_req_list);
+ TAILQ_INIT(&sc->sc_deferrals);
+ sc->sc_deferred = 0;
+
+ TAILQ_INIT(&sc->sc_tdb_q);
+
+ sc->sc_len = PFSYNC_MINPKT;
+ sc->sc_maxupdates = 128;
+
+#ifndef __FreeBSD__
+ sc->sc_imo.imo_membership = (struct in_multi **)malloc(
+ (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_IPMOPTS,
+ M_WAITOK | M_ZERO);
+ sc->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS;
+#endif
+
+#ifdef __FreeBSD__
+ ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC);
+ if (ifp == NULL) {
+ uma_zdestroy(sc->sc_pool);
+ free(sc, M_PFSYNC);
+ return (ENOSPC);
+ }
+ if_initname(ifp, ifc->ifc_name, unit);
+#else
+ ifp = &sc->sc_if;
+ snprintf(ifp->if_xname, sizeof ifp->if_xname, "pfsync%d", unit);
+#endif
+ ifp->if_softc = sc;
+ ifp->if_ioctl = pfsyncioctl;
+ ifp->if_output = pfsyncoutput;
+ ifp->if_start = pfsyncstart;
+ ifp->if_type = IFT_PFSYNC;
+ ifp->if_snd.ifq_maxlen = ifqmaxlen;
+ ifp->if_hdrlen = sizeof(struct pfsync_header);
+ ifp->if_mtu = ETHERMTU;
+#ifdef __FreeBSD__
+ callout_init(&sc->sc_tmo, CALLOUT_MPSAFE);
+ callout_init_mtx(&sc->sc_bulk_tmo, &pf_task_mtx, 0);
+ callout_init(&sc->sc_bulkfail_tmo, CALLOUT_MPSAFE);
+#else
+ timeout_set(&sc->sc_tmo, pfsync_timeout, sc);
+ timeout_set(&sc->sc_bulk_tmo, pfsync_bulk_update, sc);
+ timeout_set(&sc->sc_bulkfail_tmo, pfsync_bulk_fail, sc);
+#endif
+
+ if_attach(ifp);
+#ifndef __FreeBSD__
+ if_alloc_sadl(ifp);
+
+#if NCARP > 0
+ if_addgroup(ifp, "carp");
+#endif
+#endif
+
+#if NBPFILTER > 0
+#ifdef __FreeBSD__
+ bpfattach(ifp, DLT_PFSYNC, PFSYNC_HDRLEN);
+#else
+ bpfattach(&sc->sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN);
+#endif
+#endif
+
+#ifdef __FreeBSD__
+ V_pfsyncif = sc;
+#else
+ pfsyncif = sc;
+#endif
+
+ return (0);
+}
+
+#ifdef __FreeBSD__
+void
+#else
+int
+#endif
+pfsync_clone_destroy(struct ifnet *ifp)
+{
+ struct pfsync_softc *sc = ifp->if_softc;
+
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ timeout_del(&sc->sc_bulkfail_tmo);
+ timeout_del(&sc->sc_bulk_tmo);
+ timeout_del(&sc->sc_tmo);
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+ if (!sc->pfsync_sync_ok && carp_demote_adj_p)
+ (*carp_demote_adj_p)(-V_pfsync_carp_adj, "pfsync destroy");
+#else
+#if NCARP > 0
+ if (!pfsync_sync_ok)
+ carp_group_demote_adj(&sc->sc_if, -1);
+#endif
+#endif
+#if NBPFILTER > 0
+ bpfdetach(ifp);
+#endif
+ if_detach(ifp);
+
+ pfsync_drop(sc);
+
+ while (sc->sc_deferred > 0)
+ pfsync_undefer(TAILQ_FIRST(&sc->sc_deferrals), 0);
+
+#ifdef __FreeBSD__
+ UMA_DESTROY(sc->sc_pool);
+#else
+ pool_destroy(&sc->sc_pool);
+#endif
+#ifdef __FreeBSD__
+ if_free(ifp);
+ if (sc->sc_imo.imo_membership)
+ pfsync_multicast_cleanup(sc);
+ free(sc, M_PFSYNC);
+#else
+ free(sc->sc_imo.imo_membership, M_IPMOPTS);
+ free(sc, M_DEVBUF);
+#endif
+
+#ifdef __FreeBSD__
+ V_pfsyncif = NULL;
+#else
+ pfsyncif = NULL;
+#endif
+
+#ifndef __FreeBSD__
+ return (0);
+#endif
+}
+
+struct mbuf *
+pfsync_if_dequeue(struct ifnet *ifp)
+{
+ struct mbuf *m;
+#ifndef __FreeBSD__
+ int s;
+#endif
+
+#ifdef __FreeBSD__
+ IF_LOCK(&ifp->if_snd);
+ _IF_DROP(&ifp->if_snd);
+ _IF_DEQUEUE(&ifp->if_snd, m);
+ IF_UNLOCK(&ifp->if_snd);
+#else
+ s = splnet();
+ IF_DEQUEUE(&ifp->if_snd, m);
+ splx(s);
+#endif
+
+ return (m);
+}
+
+/*
+ * Start output on the pfsync interface.
+ */
+void
+pfsyncstart(struct ifnet *ifp)
+{
+ struct mbuf *m;
+
+ while ((m = pfsync_if_dequeue(ifp)) != NULL) {
+#ifndef __FreeBSD__
+ IF_DROP(&ifp->if_snd);
+#endif
+ m_freem(m);
+ }
+}
+
+int
+pfsync_alloc_scrub_memory(struct pfsync_state_peer *s,
+ struct pf_state_peer *d)
+{
+ if (s->scrub.scrub_flag && d->scrub == NULL) {
+#ifdef __FreeBSD__
+ d->scrub = pool_get(&V_pf_state_scrub_pl, PR_NOWAIT | PR_ZERO);
+#else
+ d->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT | PR_ZERO);
+#endif
+ if (d->scrub == NULL)
+ return (ENOMEM);
+ }
+
+ return (0);
+}
+
+#ifndef __FreeBSD__
+void
+pfsync_state_export(struct pfsync_state *sp, struct pf_state *st)
+{
+ bzero(sp, sizeof(struct pfsync_state));
+
+ /* copy from state key */
+ sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
+ sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
+ sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
+ sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
+ sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
+ sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
+ sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
+ sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
+ sp->proto = st->key[PF_SK_WIRE]->proto;
+ sp->af = st->key[PF_SK_WIRE]->af;
+
+ /* copy from state */
+ strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
+ bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
+ sp->creation = htonl(time_uptime - st->creation);
+ sp->expire = pf_state_expires(st);
+ if (sp->expire <= time_second)
+ sp->expire = htonl(0);
+ else
+ sp->expire = htonl(sp->expire - time_second);
+
+ sp->direction = st->direction;
+ sp->log = st->log;
+ sp->timeout = st->timeout;
+ sp->state_flags = st->state_flags;
+ if (st->src_node)
+ sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
+ if (st->nat_src_node)
+ sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
+
+ bcopy(&st->id, &sp->id, sizeof(sp->id));
+ sp->creatorid = st->creatorid;
+ pf_state_peer_hton(&st->src, &sp->src);
+ pf_state_peer_hton(&st->dst, &sp->dst);
+
+ if (st->rule.ptr == NULL)
+ sp->rule = htonl(-1);
+ else
+ sp->rule = htonl(st->rule.ptr->nr);
+ if (st->anchor.ptr == NULL)
+ sp->anchor = htonl(-1);
+ else
+ sp->anchor = htonl(st->anchor.ptr->nr);
+ if (st->nat_rule.ptr == NULL)
+ sp->nat_rule = htonl(-1);
+ else
+ sp->nat_rule = htonl(st->nat_rule.ptr->nr);
+
+ pf_state_counter_hton(st->packets[0], sp->packets[0]);
+ pf_state_counter_hton(st->packets[1], sp->packets[1]);
+ pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
+ pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
+
+}
+#endif
+
+int
+pfsync_state_import(struct pfsync_state *sp, u_int8_t flags)
+{
+ struct pf_state *st = NULL;
+ struct pf_state_key *skw = NULL, *sks = NULL;
+ struct pf_rule *r = NULL;
+ struct pfi_kif *kif;
+ int pool_flags;
+ int error;
+
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+
+ if (sp->creatorid == 0 && V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (sp->creatorid == 0 && pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pfsync_state_import: invalid creator id:"
+ " %08x\n", ntohl(sp->creatorid));
+ return (EINVAL);
+ }
+
+ if ((kif = pfi_kif_get(sp->ifname)) == NULL) {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC)
+#endif
+ printf("pfsync_state_import: "
+ "unknown interface: %s\n", sp->ifname);
+ if (flags & PFSYNC_SI_IOCTL)
+ return (EINVAL);
+ return (0); /* skip this state */
+ }
+
+ /*
+ * If the ruleset checksums match or the state is coming from the ioctl,
+ * it's safe to associate the state with the rule of that number.
+ */
+ if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) &&
+ (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->rule) <
+ pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount)
+ r = pf_main_ruleset.rules[
+ PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)];
+ else
+#ifdef __FreeBSD__
+ r = &V_pf_default_rule;
+#else
+ r = &pf_default_rule;
+#endif
+
+ if ((r->max_states && r->states_cur >= r->max_states))
+ goto cleanup;
+
+#ifdef __FreeBSD__
+ if (flags & PFSYNC_SI_IOCTL)
+ pool_flags = PR_WAITOK | PR_ZERO;
+ else
+ pool_flags = PR_NOWAIT | PR_ZERO;
+
+ if ((st = pool_get(&V_pf_state_pl, pool_flags)) == NULL)
+ goto cleanup;
+#else
+ if (flags & PFSYNC_SI_IOCTL)
+ pool_flags = PR_WAITOK | PR_LIMITFAIL | PR_ZERO;
+ else
+ pool_flags = PR_LIMITFAIL | PR_ZERO;
+
+ if ((st = pool_get(&pf_state_pl, pool_flags)) == NULL)
+ goto cleanup;
+#endif
+
+ if ((skw = pf_alloc_state_key(pool_flags)) == NULL)
+ goto cleanup;
+
+ if (PF_ANEQ(&sp->key[PF_SK_WIRE].addr[0],
+ &sp->key[PF_SK_STACK].addr[0], sp->af) ||
+ PF_ANEQ(&sp->key[PF_SK_WIRE].addr[1],
+ &sp->key[PF_SK_STACK].addr[1], sp->af) ||
+ sp->key[PF_SK_WIRE].port[0] != sp->key[PF_SK_STACK].port[0] ||
+ sp->key[PF_SK_WIRE].port[1] != sp->key[PF_SK_STACK].port[1]) {
+ if ((sks = pf_alloc_state_key(pool_flags)) == NULL)
+ goto cleanup;
+ } else
+ sks = skw;
+
+ /* allocate memory for scrub info */
+ if (pfsync_alloc_scrub_memory(&sp->src, &st->src) ||
+ pfsync_alloc_scrub_memory(&sp->dst, &st->dst))
+ goto cleanup;
+
+ /* copy to state key(s) */
+ skw->addr[0] = sp->key[PF_SK_WIRE].addr[0];
+ skw->addr[1] = sp->key[PF_SK_WIRE].addr[1];
+ skw->port[0] = sp->key[PF_SK_WIRE].port[0];
+ skw->port[1] = sp->key[PF_SK_WIRE].port[1];
+ skw->proto = sp->proto;
+ skw->af = sp->af;
+ if (sks != skw) {
+ sks->addr[0] = sp->key[PF_SK_STACK].addr[0];
+ sks->addr[1] = sp->key[PF_SK_STACK].addr[1];
+ sks->port[0] = sp->key[PF_SK_STACK].port[0];
+ sks->port[1] = sp->key[PF_SK_STACK].port[1];
+ sks->proto = sp->proto;
+ sks->af = sp->af;
+ }
+
+ /* copy to state */
+ bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr));
+ st->creation = time_uptime - ntohl(sp->creation);
+ st->expire = time_second;
+ if (sp->expire) {
+ uint32_t timeout;
+
+ timeout = r->timeout[sp->timeout];
+ if (!timeout)
+#ifdef __FreeBSD__
+ timeout = V_pf_default_rule.timeout[sp->timeout];
+#else
+ timeout = pf_default_rule.timeout[sp->timeout];
+#endif
+
+ /* sp->expire may have been adaptively scaled by export. */
+ st->expire -= timeout - ntohl(sp->expire);
+ }
+
+ st->direction = sp->direction;
+ st->log = sp->log;
+ st->timeout = sp->timeout;
+ st->state_flags = sp->state_flags;
+
+ bcopy(sp->id, &st->id, sizeof(st->id));
+ st->creatorid = sp->creatorid;
+ pf_state_peer_ntoh(&sp->src, &st->src);
+ pf_state_peer_ntoh(&sp->dst, &st->dst);
+
+ st->rule.ptr = r;
+ st->nat_rule.ptr = NULL;
+ st->anchor.ptr = NULL;
+ st->rt_kif = NULL;
+
+ st->pfsync_time = time_uptime;
+ st->sync_state = PFSYNC_S_NONE;
+
+ /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */
+ r->states_cur++;
+ r->states_tot++;
+
+ if (!ISSET(flags, PFSYNC_SI_IOCTL))
+ SET(st->state_flags, PFSTATE_NOSYNC);
+
+ if ((error = pf_state_insert(kif, skw, sks, st)) != 0) {
+ /* XXX when we have nat_rule/anchors, use STATE_DEC_COUNTERS */
+ r->states_cur--;
+ goto cleanup_state;
+ }
+
+ if (!ISSET(flags, PFSYNC_SI_IOCTL)) {
+ CLR(st->state_flags, PFSTATE_NOSYNC);
+ if (ISSET(st->state_flags, PFSTATE_ACK)) {
+ pfsync_q_ins(st, PFSYNC_S_IACK);
+ schednetisr(NETISR_PFSYNC);
+ }
+ }
+ CLR(st->state_flags, PFSTATE_ACK);
+
+ return (0);
+
+cleanup:
+ error = ENOMEM;
+ if (skw == sks)
+ sks = NULL;
+#ifdef __FreeBSD__
+ if (skw != NULL)
+ pool_put(&V_pf_state_key_pl, skw);
+ if (sks != NULL)
+ pool_put(&V_pf_state_key_pl, sks);
+#else
+ if (skw != NULL)
+ pool_put(&pf_state_key_pl, skw);
+ if (sks != NULL)
+ pool_put(&pf_state_key_pl, sks);
+#endif
+
+cleanup_state: /* pf_state_insert frees the state keys */
+ if (st) {
+#ifdef __FreeBSD__
+ if (st->dst.scrub)
+ pool_put(&V_pf_state_scrub_pl, st->dst.scrub);
+ if (st->src.scrub)
+ pool_put(&V_pf_state_scrub_pl, st->src.scrub);
+ pool_put(&V_pf_state_pl, st);
+#else
+ if (st->dst.scrub)
+ pool_put(&pf_state_scrub_pl, st->dst.scrub);
+ if (st->src.scrub)
+ pool_put(&pf_state_scrub_pl, st->src.scrub);
+ pool_put(&pf_state_pl, st);
+#endif
+ }
+ return (error);
+}
+
+void
+#ifdef __FreeBSD__
+pfsync_input(struct mbuf *m, __unused int off)
+#else
+pfsync_input(struct mbuf *m, ...)
+#endif
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+ struct pfsync_pkt pkt;
+ struct ip *ip = mtod(m, struct ip *);
+ struct pfsync_header *ph;
+ struct pfsync_subheader subh;
+
+ int offset;
+ int rv;
+
+ V_pfsyncstats.pfsyncs_ipackets++;
+
+ /* verify that we have a sync interface configured */
+#ifdef __FreeBSD__
+ if (!sc || !sc->sc_sync_if || !V_pf_status.running)
+#else
+ if (!sc || !sc->sc_sync_if || !pf_status.running)
+#endif
+ goto done;
+
+ /* verify that the packet came in on the right interface */
+ if (sc->sc_sync_if != m->m_pkthdr.rcvif) {
+ V_pfsyncstats.pfsyncs_badif++;
+ goto done;
+ }
+
+#ifdef __FreeBSD__
+ sc->sc_ifp->if_ipackets++;
+ sc->sc_ifp->if_ibytes += m->m_pkthdr.len;
+#else
+ sc->sc_if.if_ipackets++;
+ sc->sc_if.if_ibytes += m->m_pkthdr.len;
+#endif
+ /* verify that the IP TTL is 255. */
+ if (ip->ip_ttl != PFSYNC_DFLTTL) {
+ V_pfsyncstats.pfsyncs_badttl++;
+ goto done;
+ }
+
+ offset = ip->ip_hl << 2;
+ if (m->m_pkthdr.len < offset + sizeof(*ph)) {
+ V_pfsyncstats.pfsyncs_hdrops++;
+ goto done;
+ }
+
+ if (offset + sizeof(*ph) > m->m_len) {
+ if (m_pullup(m, offset + sizeof(*ph)) == NULL) {
+ V_pfsyncstats.pfsyncs_hdrops++;
+ return;
+ }
+ ip = mtod(m, struct ip *);
+ }
+ ph = (struct pfsync_header *)((char *)ip + offset);
+
+ /* verify the version */
+ if (ph->version != PFSYNC_VERSION) {
+ V_pfsyncstats.pfsyncs_badver++;
+ goto done;
+ }
+
+#if 0
+ if (pfsync_input_hmac(m, offset) != 0) {
+ /* XXX stats */
+ goto done;
+ }
+#endif
+
+ /* Cheaper to grab this now than having to mess with mbufs later */
+ pkt.ip = ip;
+ pkt.src = ip->ip_src;
+ pkt.flags = 0;
+
+#ifdef __FreeBSD__
+ if (!bcmp(&ph->pfcksum, &V_pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH))
+#else
+ if (!bcmp(&ph->pfcksum, &pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH))
+#endif
+ pkt.flags |= PFSYNC_SI_CKSUM;
+
+ offset += sizeof(*ph);
+ for (;;) {
+ m_copydata(m, offset, sizeof(subh), (caddr_t)&subh);
+ offset += sizeof(subh);
+
+ if (subh.action >= PFSYNC_ACT_MAX) {
+ V_pfsyncstats.pfsyncs_badact++;
+ goto done;
+ }
+
+ rv = (*pfsync_acts[subh.action])(&pkt, m, offset,
+ ntohs(subh.count));
+ if (rv == -1)
+ return;
+
+ offset += rv;
+ }
+
+done:
+ m_freem(m);
+}
+
+int
+pfsync_in_clr(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+ struct pfsync_clr *clr;
+ struct mbuf *mp;
+ int len = sizeof(*clr) * count;
+ int i, offp;
+
+ struct pf_state *st, *nexts;
+ struct pf_state_key *sk, *nextsk;
+ struct pf_state_item *si;
+ u_int32_t creatorid;
+ int s;
+
+ mp = m_pulldown(m, offset, len, &offp);
+ if (mp == NULL) {
+ V_pfsyncstats.pfsyncs_badlen++;
+ return (-1);
+ }
+ clr = (struct pfsync_clr *)(mp->m_data + offp);
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ for (i = 0; i < count; i++) {
+ creatorid = clr[i].creatorid;
+
+ if (clr[i].ifname[0] == '\0') {
+#ifdef __FreeBSD__
+ for (st = RB_MIN(pf_state_tree_id, &V_tree_id);
+ st; st = nexts) {
+ nexts = RB_NEXT(pf_state_tree_id, &V_tree_id, st);
+#else
+ for (st = RB_MIN(pf_state_tree_id, &tree_id);
+ st; st = nexts) {
+ nexts = RB_NEXT(pf_state_tree_id, &tree_id, st);
+#endif
+ if (st->creatorid == creatorid) {
+ SET(st->state_flags, PFSTATE_NOSYNC);
+ pf_unlink_state(st);
+ }
+ }
+ } else {
+ if (pfi_kif_get(clr[i].ifname) == NULL)
+ continue;
+
+ /* XXX correct? */
+#ifdef __FreeBSD__
+ for (sk = RB_MIN(pf_state_tree, &V_pf_statetbl);
+#else
+ for (sk = RB_MIN(pf_state_tree, &pf_statetbl);
+#endif
+ sk; sk = nextsk) {
+ nextsk = RB_NEXT(pf_state_tree,
+#ifdef __FreeBSD__
+ &V_pf_statetbl, sk);
+#else
+ &pf_statetbl, sk);
+#endif
+ TAILQ_FOREACH(si, &sk->states, entry) {
+ if (si->s->creatorid == creatorid) {
+ SET(si->s->state_flags,
+ PFSTATE_NOSYNC);
+ pf_unlink_state(si->s);
+ }
+ }
+ }
+ }
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+
+ return (len);
+}
+
+int
+pfsync_in_ins(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+ struct mbuf *mp;
+ struct pfsync_state *sa, *sp;
+ int len = sizeof(*sp) * count;
+ int i, offp;
+
+ int s;
+
+ mp = m_pulldown(m, offset, len, &offp);
+ if (mp == NULL) {
+ V_pfsyncstats.pfsyncs_badlen++;
+ return (-1);
+ }
+ sa = (struct pfsync_state *)(mp->m_data + offp);
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ for (i = 0; i < count; i++) {
+ sp = &sa[i];
+
+ /* check for invalid values */
+ if (sp->timeout >= PFTM_MAX ||
+ sp->src.state > PF_TCPS_PROXY_DST ||
+ sp->dst.state > PF_TCPS_PROXY_DST ||
+ sp->direction > PF_OUT ||
+ (sp->af != AF_INET && sp->af != AF_INET6)) {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pfsync_input: PFSYNC5_ACT_INS: "
+ "invalid value\n");
+ }
+ V_pfsyncstats.pfsyncs_badval++;
+ continue;
+ }
+
+ if (pfsync_state_import(sp, pkt->flags) == ENOMEM) {
+ /* drop out, but process the rest of the actions */
+ break;
+ }
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+
+ return (len);
+}
+
+int
+pfsync_in_iack(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+ struct pfsync_ins_ack *ia, *iaa;
+ struct pf_state_cmp id_key;
+ struct pf_state *st;
+
+ struct mbuf *mp;
+ int len = count * sizeof(*ia);
+ int offp, i;
+ int s;
+
+ mp = m_pulldown(m, offset, len, &offp);
+ if (mp == NULL) {
+ V_pfsyncstats.pfsyncs_badlen++;
+ return (-1);
+ }
+ iaa = (struct pfsync_ins_ack *)(mp->m_data + offp);
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ for (i = 0; i < count; i++) {
+ ia = &iaa[i];
+
+ bcopy(&ia->id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = ia->creatorid;
+
+ st = pf_find_state_byid(&id_key);
+ if (st == NULL)
+ continue;
+
+ if (ISSET(st->state_flags, PFSTATE_ACK))
+ pfsync_deferred(st, 0);
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+ /*
+ * XXX this is not yet implemented, but we know the size of the
+ * message so we can skip it.
+ */
+
+ return (count * sizeof(struct pfsync_ins_ack));
+}
+
+int
+pfsync_upd_tcp(struct pf_state *st, struct pfsync_state_peer *src,
+ struct pfsync_state_peer *dst)
+{
+ int sfail = 0;
+
+ /*
+ * The state should never go backwards except
+ * for syn-proxy states. Neither should the
+ * sequence window slide backwards.
+ */
+ if (st->src.state > src->state &&
+ (st->src.state < PF_TCPS_PROXY_SRC ||
+ src->state >= PF_TCPS_PROXY_SRC))
+ sfail = 1;
+ else if (SEQ_GT(st->src.seqlo, ntohl(src->seqlo)))
+ sfail = 3;
+ else if (st->dst.state > dst->state) {
+ /* There might still be useful
+ * information about the src state here,
+ * so import that part of the update,
+ * then "fail" so we send the updated
+ * state back to the peer who is missing
+ * our what we know. */
+ pf_state_peer_ntoh(src, &st->src);
+ /* XXX do anything with timeouts? */
+ sfail = 7;
+ } else if (st->dst.state >= TCPS_SYN_SENT &&
+ SEQ_GT(st->dst.seqlo, ntohl(dst->seqlo)))
+ sfail = 4;
+
+ return (sfail);
+}
+
+int
+pfsync_in_upd(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+ struct pfsync_state *sa, *sp;
+ struct pf_state_cmp id_key;
+ struct pf_state_key *sk;
+ struct pf_state *st;
+ int sfail;
+
+ struct mbuf *mp;
+ int len = count * sizeof(*sp);
+ int offp, i;
+ int s;
+
+ mp = m_pulldown(m, offset, len, &offp);
+ if (mp == NULL) {
+ V_pfsyncstats.pfsyncs_badlen++;
+ return (-1);
+ }
+ sa = (struct pfsync_state *)(mp->m_data + offp);
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ for (i = 0; i < count; i++) {
+ sp = &sa[i];
+
+ /* check for invalid values */
+ if (sp->timeout >= PFTM_MAX ||
+ sp->src.state > PF_TCPS_PROXY_DST ||
+ sp->dst.state > PF_TCPS_PROXY_DST) {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pfsync_input: PFSYNC_ACT_UPD: "
+ "invalid value\n");
+ }
+ V_pfsyncstats.pfsyncs_badval++;
+ continue;
+ }
+
+ bcopy(sp->id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = sp->creatorid;
+
+ st = pf_find_state_byid(&id_key);
+ if (st == NULL) {
+ /* insert the update */
+ if (pfsync_state_import(sp, 0))
+ V_pfsyncstats.pfsyncs_badstate++;
+ continue;
+ }
+
+ if (ISSET(st->state_flags, PFSTATE_ACK))
+ pfsync_deferred(st, 1);
+
+ sk = st->key[PF_SK_WIRE]; /* XXX right one? */
+ sfail = 0;
+ if (sk->proto == IPPROTO_TCP)
+ sfail = pfsync_upd_tcp(st, &sp->src, &sp->dst);
+ else {
+ /*
+ * Non-TCP protocol state machine always go
+ * forwards
+ */
+ if (st->src.state > sp->src.state)
+ sfail = 5;
+ else if (st->dst.state > sp->dst.state)
+ sfail = 6;
+ }
+
+ if (sfail) {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pfsync: %s stale update (%d)"
+ " id: %016llx creatorid: %08x\n",
+ (sfail < 7 ? "ignoring" : "partial"),
+ sfail, betoh64(st->id),
+ ntohl(st->creatorid));
+ }
+ V_pfsyncstats.pfsyncs_stale++;
+
+ pfsync_update_state(st);
+ schednetisr(NETISR_PFSYNC);
+ continue;
+ }
+ pfsync_alloc_scrub_memory(&sp->dst, &st->dst);
+ pf_state_peer_ntoh(&sp->src, &st->src);
+ pf_state_peer_ntoh(&sp->dst, &st->dst);
+ st->expire = time_second;
+ st->timeout = sp->timeout;
+ st->pfsync_time = time_uptime;
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+
+ return (len);
+}
+
+int
+pfsync_in_upd_c(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+ struct pfsync_upd_c *ua, *up;
+ struct pf_state_key *sk;
+ struct pf_state_cmp id_key;
+ struct pf_state *st;
+
+ int len = count * sizeof(*up);
+ int sfail;
+
+ struct mbuf *mp;
+ int offp, i;
+ int s;
+
+ mp = m_pulldown(m, offset, len, &offp);
+ if (mp == NULL) {
+ V_pfsyncstats.pfsyncs_badlen++;
+ return (-1);
+ }
+ ua = (struct pfsync_upd_c *)(mp->m_data + offp);
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ for (i = 0; i < count; i++) {
+ up = &ua[i];
+
+ /* check for invalid values */
+ if (up->timeout >= PFTM_MAX ||
+ up->src.state > PF_TCPS_PROXY_DST ||
+ up->dst.state > PF_TCPS_PROXY_DST) {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pfsync_input: "
+ "PFSYNC_ACT_UPD_C: "
+ "invalid value\n");
+ }
+ V_pfsyncstats.pfsyncs_badval++;
+ continue;
+ }
+
+ bcopy(&up->id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = up->creatorid;
+
+ st = pf_find_state_byid(&id_key);
+ if (st == NULL) {
+ /* We don't have this state. Ask for it. */
+ pfsync_request_update(id_key.creatorid, id_key.id);
+ continue;
+ }
+
+ if (ISSET(st->state_flags, PFSTATE_ACK))
+ pfsync_deferred(st, 1);
+
+ sk = st->key[PF_SK_WIRE]; /* XXX right one? */
+ sfail = 0;
+ if (sk->proto == IPPROTO_TCP)
+ sfail = pfsync_upd_tcp(st, &up->src, &up->dst);
+ else {
+ /*
+ * Non-TCP protocol state machine always go forwards
+ */
+ if (st->src.state > up->src.state)
+ sfail = 5;
+ else if (st->dst.state > up->dst.state)
+ sfail = 6;
+ }
+
+ if (sfail) {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pfsync: ignoring stale update "
+ "(%d) id: %016llx "
+ "creatorid: %08x\n", sfail,
+ betoh64(st->id),
+ ntohl(st->creatorid));
+ }
+ V_pfsyncstats.pfsyncs_stale++;
+
+ pfsync_update_state(st);
+ schednetisr(NETISR_PFSYNC);
+ continue;
+ }
+ pfsync_alloc_scrub_memory(&up->dst, &st->dst);
+ pf_state_peer_ntoh(&up->src, &st->src);
+ pf_state_peer_ntoh(&up->dst, &st->dst);
+ st->expire = time_second;
+ st->timeout = up->timeout;
+ st->pfsync_time = time_uptime;
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+
+ return (len);
+}
+
+int
+pfsync_in_ureq(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+ struct pfsync_upd_req *ur, *ura;
+ struct mbuf *mp;
+ int len = count * sizeof(*ur);
+ int i, offp;
+
+ struct pf_state_cmp id_key;
+ struct pf_state *st;
+
+ mp = m_pulldown(m, offset, len, &offp);
+ if (mp == NULL) {
+ V_pfsyncstats.pfsyncs_badlen++;
+ return (-1);
+ }
+ ura = (struct pfsync_upd_req *)(mp->m_data + offp);
+
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ for (i = 0; i < count; i++) {
+ ur = &ura[i];
+
+ bcopy(&ur->id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = ur->creatorid;
+
+ if (id_key.id == 0 && id_key.creatorid == 0)
+ pfsync_bulk_start();
+ else {
+ st = pf_find_state_byid(&id_key);
+ if (st == NULL) {
+ V_pfsyncstats.pfsyncs_badstate++;
+ continue;
+ }
+ if (ISSET(st->state_flags, PFSTATE_NOSYNC))
+ continue;
+
+ pfsync_update_state_req(st);
+ }
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+
+ return (len);
+}
+
+int
+pfsync_in_del(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+ struct mbuf *mp;
+ struct pfsync_state *sa, *sp;
+ struct pf_state_cmp id_key;
+ struct pf_state *st;
+ int len = count * sizeof(*sp);
+ int offp, i;
+ int s;
+
+ mp = m_pulldown(m, offset, len, &offp);
+ if (mp == NULL) {
+ V_pfsyncstats.pfsyncs_badlen++;
+ return (-1);
+ }
+ sa = (struct pfsync_state *)(mp->m_data + offp);
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ for (i = 0; i < count; i++) {
+ sp = &sa[i];
+
+ bcopy(sp->id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = sp->creatorid;
+
+ st = pf_find_state_byid(&id_key);
+ if (st == NULL) {
+ V_pfsyncstats.pfsyncs_badstate++;
+ continue;
+ }
+ SET(st->state_flags, PFSTATE_NOSYNC);
+ pf_unlink_state(st);
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+
+ return (len);
+}
+
+int
+pfsync_in_del_c(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+ struct mbuf *mp;
+ struct pfsync_del_c *sa, *sp;
+ struct pf_state_cmp id_key;
+ struct pf_state *st;
+ int len = count * sizeof(*sp);
+ int offp, i;
+ int s;
+
+ mp = m_pulldown(m, offset, len, &offp);
+ if (mp == NULL) {
+ V_pfsyncstats.pfsyncs_badlen++;
+ return (-1);
+ }
+ sa = (struct pfsync_del_c *)(mp->m_data + offp);
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ for (i = 0; i < count; i++) {
+ sp = &sa[i];
+
+ bcopy(&sp->id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = sp->creatorid;
+
+ st = pf_find_state_byid(&id_key);
+ if (st == NULL) {
+ V_pfsyncstats.pfsyncs_badstate++;
+ continue;
+ }
+
+ SET(st->state_flags, PFSTATE_NOSYNC);
+ pf_unlink_state(st);
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+
+ return (len);
+}
+
+int
+pfsync_in_bus(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+ struct pfsync_bus *bus;
+ struct mbuf *mp;
+ int len = count * sizeof(*bus);
+ int offp;
+
+ /* If we're not waiting for a bulk update, who cares. */
+ if (sc->sc_ureq_sent == 0)
+ return (len);
+
+ mp = m_pulldown(m, offset, len, &offp);
+ if (mp == NULL) {
+ V_pfsyncstats.pfsyncs_badlen++;
+ return (-1);
+ }
+ bus = (struct pfsync_bus *)(mp->m_data + offp);
+
+ switch (bus->status) {
+ case PFSYNC_BUS_START:
+#ifdef __FreeBSD__
+ callout_reset(&sc->sc_bulkfail_tmo, 4 * hz +
+ V_pf_pool_limits[PF_LIMIT_STATES].limit /
+ ((sc->sc_ifp->if_mtu - PFSYNC_MINPKT) /
+ sizeof(struct pfsync_state)),
+ pfsync_bulk_fail, V_pfsyncif);
+#else
+ timeout_add(&sc->sc_bulkfail_tmo, 4 * hz +
+ pf_pool_limits[PF_LIMIT_STATES].limit /
+ ((sc->sc_if.if_mtu - PFSYNC_MINPKT) /
+ sizeof(struct pfsync_state)));
+#endif
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC)
+#endif
+ printf("pfsync: received bulk update start\n");
+ break;
+
+ case PFSYNC_BUS_END:
+ if (time_uptime - ntohl(bus->endtime) >=
+ sc->sc_ureq_sent) {
+ /* that's it, we're happy */
+ sc->sc_ureq_sent = 0;
+ sc->sc_bulk_tries = 0;
+ timeout_del(&sc->sc_bulkfail_tmo);
+#ifdef __FreeBSD__
+ if (!sc->pfsync_sync_ok && carp_demote_adj_p)
+ (*carp_demote_adj_p)(-V_pfsync_carp_adj,
+ "pfsync bulk done");
+ sc->pfsync_sync_ok = 1;
+#else
+#if NCARP > 0
+ if (!pfsync_sync_ok)
+ carp_group_demote_adj(&sc->sc_if, -1);
+#endif
+ pfsync_sync_ok = 1;
+#endif
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC)
+#endif
+ printf("pfsync: received valid "
+ "bulk update end\n");
+ } else {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC)
+#endif
+ printf("pfsync: received invalid "
+ "bulk update end: bad timestamp\n");
+ }
+ break;
+ }
+
+ return (len);
+}
+
+int
+pfsync_in_tdb(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+ int len = count * sizeof(struct pfsync_tdb);
+
+#if defined(IPSEC)
+ struct pfsync_tdb *tp;
+ struct mbuf *mp;
+ int offp;
+ int i;
+ int s;
+
+ mp = m_pulldown(m, offset, len, &offp);
+ if (mp == NULL) {
+ V_pfsyncstats.pfsyncs_badlen++;
+ return (-1);
+ }
+ tp = (struct pfsync_tdb *)(mp->m_data + offp);
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ for (i = 0; i < count; i++)
+ pfsync_update_net_tdb(&tp[i]);
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+#endif
+
+ return (len);
+}
+
+#if defined(IPSEC)
+/* Update an in-kernel tdb. Silently fail if no tdb is found. */
+void
+pfsync_update_net_tdb(struct pfsync_tdb *pt)
+{
+ struct tdb *tdb;
+ int s;
+
+ /* check for invalid values */
+ if (ntohl(pt->spi) <= SPI_RESERVED_MAX ||
+ (pt->dst.sa.sa_family != AF_INET &&
+ pt->dst.sa.sa_family != AF_INET6))
+ goto bad;
+
+ s = spltdb();
+ tdb = gettdb(pt->spi, &pt->dst, pt->sproto);
+ if (tdb) {
+ pt->rpl = ntohl(pt->rpl);
+ pt->cur_bytes = betoh64(pt->cur_bytes);
+
+ /* Neither replay nor byte counter should ever decrease. */
+ if (pt->rpl < tdb->tdb_rpl ||
+ pt->cur_bytes < tdb->tdb_cur_bytes) {
+ splx(s);
+ goto bad;
+ }
+
+ tdb->tdb_rpl = pt->rpl;
+ tdb->tdb_cur_bytes = pt->cur_bytes;
+ }
+ splx(s);
+ return;
+
+bad:
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC)
+#endif
+ printf("pfsync_insert: PFSYNC_ACT_TDB_UPD: "
+ "invalid value\n");
+ V_pfsyncstats.pfsyncs_badstate++;
+ return;
+}
+#endif
+
+
+int
+pfsync_in_eof(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+ /* check if we are at the right place in the packet */
+ if (offset != m->m_pkthdr.len - sizeof(struct pfsync_eof))
+ V_pfsyncstats.pfsyncs_badact++;
+
+ /* we're done. free and let the caller return */
+ m_freem(m);
+ return (-1);
+}
+
+int
+pfsync_in_error(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
+{
+ V_pfsyncstats.pfsyncs_badact++;
+
+ m_freem(m);
+ return (-1);
+}
+
+int
+pfsyncoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
+#ifdef __FreeBSD__
+ struct route *rt)
+#else
+ struct rtentry *rt)
+#endif
+{
+ m_freem(m);
+ return (0);
+}
+
+/* ARGSUSED */
+int
+pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+#ifndef __FreeBSD__
+ struct proc *p = curproc;
+#endif
+ struct pfsync_softc *sc = ifp->if_softc;
+ struct ifreq *ifr = (struct ifreq *)data;
+ struct ip_moptions *imo = &sc->sc_imo;
+ struct pfsyncreq pfsyncr;
+ struct ifnet *sifp;
+ struct ip *ip;
+ int s, error;
+
+ switch (cmd) {
+#if 0
+ case SIOCSIFADDR:
+ case SIOCAIFADDR:
+ case SIOCSIFDSTADDR:
+#endif
+ case SIOCSIFFLAGS:
+#ifdef __FreeBSD__
+ if (ifp->if_flags & IFF_UP)
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ else
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+#else
+ if (ifp->if_flags & IFF_UP)
+ ifp->if_flags |= IFF_RUNNING;
+ else
+ ifp->if_flags &= ~IFF_RUNNING;
+#endif
+ break;
+ case SIOCSIFMTU:
+ if (!sc->sc_sync_if ||
+ ifr->ifr_mtu <= PFSYNC_MINPKT ||
+ ifr->ifr_mtu > sc->sc_sync_if->if_mtu)
+ return (EINVAL);
+ if (ifr->ifr_mtu < ifp->if_mtu) {
+ s = splnet();
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ pfsync_sendout();
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+ }
+ ifp->if_mtu = ifr->ifr_mtu;
+ break;
+ case SIOCGETPFSYNC:
+ bzero(&pfsyncr, sizeof(pfsyncr));
+ if (sc->sc_sync_if) {
+ strlcpy(pfsyncr.pfsyncr_syncdev,
+ sc->sc_sync_if->if_xname, IFNAMSIZ);
+ }
+ pfsyncr.pfsyncr_syncpeer = sc->sc_sync_peer;
+ pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates;
+ pfsyncr.pfsyncr_defer = sc->sc_defer;
+ return (copyout(&pfsyncr, ifr->ifr_data, sizeof(pfsyncr)));
+
+ case SIOCSETPFSYNC:
+#ifdef __FreeBSD__
+ if ((error = priv_check(curthread, PRIV_NETINET_PF)) != 0)
+#else
+ if ((error = suser(p, p->p_acflag)) != 0)
+#endif
+ return (error);
+ if ((error = copyin(ifr->ifr_data, &pfsyncr, sizeof(pfsyncr))))
+ return (error);
+
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ if (pfsyncr.pfsyncr_syncpeer.s_addr == 0)
+#ifdef __FreeBSD__
+ sc->sc_sync_peer.s_addr = htonl(INADDR_PFSYNC_GROUP);
+#else
+ sc->sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
+#endif
+ else
+ sc->sc_sync_peer.s_addr =
+ pfsyncr.pfsyncr_syncpeer.s_addr;
+
+ if (pfsyncr.pfsyncr_maxupdates > 255)
+#ifdef __FreeBSD__
+ {
+ PF_UNLOCK();
+#endif
+ return (EINVAL);
+#ifdef __FreeBSD__
+ }
+#endif
+ sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
+ sc->sc_defer = pfsyncr.pfsyncr_defer;
+
+ if (pfsyncr.pfsyncr_syncdev[0] == 0) {
+ sc->sc_sync_if = NULL;
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+ if (imo->imo_membership)
+ pfsync_multicast_cleanup(sc);
+#else
+ if (imo->imo_num_memberships > 0) {
+ in_delmulti(imo->imo_membership[
+ --imo->imo_num_memberships]);
+ imo->imo_multicast_ifp = NULL;
+ }
+#endif
+ break;
+ }
+
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ if ((sifp = ifunit(pfsyncr.pfsyncr_syncdev)) == NULL)
+ return (EINVAL);
+
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ s = splnet();
+#ifdef __FreeBSD__
+ if (sifp->if_mtu < sc->sc_ifp->if_mtu ||
+#else
+ if (sifp->if_mtu < sc->sc_if.if_mtu ||
+#endif
+ (sc->sc_sync_if != NULL &&
+ sifp->if_mtu < sc->sc_sync_if->if_mtu) ||
+ sifp->if_mtu < MCLBYTES - sizeof(struct ip))
+ pfsync_sendout();
+ sc->sc_sync_if = sifp;
+
+#ifdef __FreeBSD__
+ if (imo->imo_membership) {
+ PF_UNLOCK();
+ pfsync_multicast_cleanup(sc);
+ PF_LOCK();
+ }
+#else
+ if (imo->imo_num_memberships > 0) {
+ in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
+ imo->imo_multicast_ifp = NULL;
+ }
+#endif
+
+#ifdef __FreeBSD__
+ if (sc->sc_sync_if &&
+ sc->sc_sync_peer.s_addr == htonl(INADDR_PFSYNC_GROUP)) {
+ PF_UNLOCK();
+ error = pfsync_multicast_setup(sc);
+ if (error)
+ return (error);
+ PF_LOCK();
+ }
+#else
+ if (sc->sc_sync_if &&
+ sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
+ struct in_addr addr;
+
+ if (!(sc->sc_sync_if->if_flags & IFF_MULTICAST)) {
+ sc->sc_sync_if = NULL;
+ splx(s);
+ return (EADDRNOTAVAIL);
+ }
+
+ addr.s_addr = INADDR_PFSYNC_GROUP;
+
+ if ((imo->imo_membership[0] =
+ in_addmulti(&addr, sc->sc_sync_if)) == NULL) {
+ sc->sc_sync_if = NULL;
+ splx(s);
+ return (ENOBUFS);
+ }
+ imo->imo_num_memberships++;
+ imo->imo_multicast_ifp = sc->sc_sync_if;
+ imo->imo_multicast_ttl = PFSYNC_DFLTTL;
+ imo->imo_multicast_loop = 0;
+ }
+#endif /* !__FreeBSD__ */
+
+ ip = &sc->sc_template;
+ bzero(ip, sizeof(*ip));
+ ip->ip_v = IPVERSION;
+ ip->ip_hl = sizeof(sc->sc_template) >> 2;
+ ip->ip_tos = IPTOS_LOWDELAY;
+ /* len and id are set later */
+#ifdef __FreeBSD__
+ ip->ip_off = IP_DF;
+#else
+ ip->ip_off = htons(IP_DF);
+#endif
+ ip->ip_ttl = PFSYNC_DFLTTL;
+ ip->ip_p = IPPROTO_PFSYNC;
+ ip->ip_src.s_addr = INADDR_ANY;
+ ip->ip_dst.s_addr = sc->sc_sync_peer.s_addr;
+
+ if (sc->sc_sync_if) {
+ /* Request a full state table update. */
+ sc->sc_ureq_sent = time_uptime;
+#ifdef __FreeBSD__
+ if (sc->pfsync_sync_ok && carp_demote_adj_p)
+ (*carp_demote_adj_p)(V_pfsync_carp_adj,
+ "pfsync bulk start");
+ sc->pfsync_sync_ok = 0;
+#else
+#if NCARP > 0
+ if (pfsync_sync_ok)
+ carp_group_demote_adj(&sc->sc_if, 1);
+#endif
+ pfsync_sync_ok = 0;
+#endif
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC)
+#endif
+ printf("pfsync: requesting bulk update\n");
+#ifdef __FreeBSD__
+ callout_reset(&sc->sc_bulkfail_tmo, 5 * hz,
+ pfsync_bulk_fail, V_pfsyncif);
+#else
+ timeout_add_sec(&sc->sc_bulkfail_tmo, 5);
+#endif
+ pfsync_request_update(0, 0);
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+
+ break;
+
+ default:
+ return (ENOTTY);
+ }
+
+ return (0);
+}
+
+int
+pfsync_out_state(struct pf_state *st, struct mbuf *m, int offset)
+{
+ struct pfsync_state *sp = (struct pfsync_state *)(m->m_data + offset);
+
+ pfsync_state_export(sp, st);
+
+ return (sizeof(*sp));
+}
+
+int
+pfsync_out_iack(struct pf_state *st, struct mbuf *m, int offset)
+{
+ struct pfsync_ins_ack *iack =
+ (struct pfsync_ins_ack *)(m->m_data + offset);
+
+ iack->id = st->id;
+ iack->creatorid = st->creatorid;
+
+ return (sizeof(*iack));
+}
+
+int
+pfsync_out_upd_c(struct pf_state *st, struct mbuf *m, int offset)
+{
+ struct pfsync_upd_c *up = (struct pfsync_upd_c *)(m->m_data + offset);
+
+ bzero(up, sizeof(*up));
+ up->id = st->id;
+ pf_state_peer_hton(&st->src, &up->src);
+ pf_state_peer_hton(&st->dst, &up->dst);
+ up->creatorid = st->creatorid;
+ up->timeout = st->timeout;
+
+ return (sizeof(*up));
+}
+
+int
+pfsync_out_del(struct pf_state *st, struct mbuf *m, int offset)
+{
+ struct pfsync_del_c *dp = (struct pfsync_del_c *)(m->m_data + offset);
+
+ dp->id = st->id;
+ dp->creatorid = st->creatorid;
+
+ SET(st->state_flags, PFSTATE_NOSYNC);
+
+ return (sizeof(*dp));
+}
+
+void
+pfsync_drop(struct pfsync_softc *sc)
+{
+ struct pf_state *st;
+ struct pfsync_upd_req_item *ur;
+#ifdef notyet
+ struct tdb *t;
+#endif
+ int q;
+
+ for (q = 0; q < PFSYNC_S_COUNT; q++) {
+ if (TAILQ_EMPTY(&sc->sc_qs[q]))
+ continue;
+
+ TAILQ_FOREACH(st, &sc->sc_qs[q], sync_list) {
+#ifdef PFSYNC_DEBUG
+#ifdef __FreeBSD__
+ KASSERT(st->sync_state == q,
+ ("%s: st->sync_state == q",
+ __FUNCTION__));
+#else
+ KASSERT(st->sync_state == q);
+#endif
+#endif
+ st->sync_state = PFSYNC_S_NONE;
+ }
+ TAILQ_INIT(&sc->sc_qs[q]);
+ }
+
+ while ((ur = TAILQ_FIRST(&sc->sc_upd_req_list)) != NULL) {
+ TAILQ_REMOVE(&sc->sc_upd_req_list, ur, ur_entry);
+ pool_put(&sc->sc_pool, ur);
+ }
+
+ sc->sc_plus = NULL;
+
+#ifdef notyet
+ if (!TAILQ_EMPTY(&sc->sc_tdb_q)) {
+ TAILQ_FOREACH(t, &sc->sc_tdb_q, tdb_sync_entry)
+ CLR(t->tdb_flags, TDBF_PFSYNC);
+
+ TAILQ_INIT(&sc->sc_tdb_q);
+ }
+#endif
+
+ sc->sc_len = PFSYNC_MINPKT;
+}
+
+#ifdef __FreeBSD__
+void pfsync_sendout()
+{
+ pfsync_sendout1(1);
+}
+
+static void
+pfsync_sendout1(int schedswi)
+{
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+void
+pfsync_sendout(void)
+{
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+#if NBPFILTER > 0
+#ifdef __FreeBSD__
+ struct ifnet *ifp = sc->sc_ifp;
+#else
+ struct ifnet *ifp = &sc->sc_if;
+#endif
+#endif
+ struct mbuf *m;
+ struct ip *ip;
+ struct pfsync_header *ph;
+ struct pfsync_subheader *subh;
+ struct pf_state *st;
+ struct pfsync_upd_req_item *ur;
+#ifdef notyet
+ struct tdb *t;
+#endif
+ int offset;
+ int q, count = 0;
+
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+#else
+ splassert(IPL_NET);
+#endif
+
+ if (sc == NULL || sc->sc_len == PFSYNC_MINPKT)
+ return;
+
+#if NBPFILTER > 0
+ if (ifp->if_bpf == NULL && sc->sc_sync_if == NULL) {
+#else
+ if (sc->sc_sync_if == NULL) {
+#endif
+ pfsync_drop(sc);
+ return;
+ }
+
+#ifdef __FreeBSD__
+ m = m_get2(M_NOWAIT, MT_DATA, M_PKTHDR, max_linkhdr + sc->sc_len);
+ if (m == NULL) {
+ sc->sc_ifp->if_oerrors++;
+ V_pfsyncstats.pfsyncs_onomem++;
+ return;
+ }
+#else
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL) {
+ sc->sc_if.if_oerrors++;
+ pfsyncstats.pfsyncs_onomem++;
+ pfsync_drop(sc);
+ return;
+ }
+
+ if (max_linkhdr + sc->sc_len > MHLEN) {
+ MCLGETI(m, M_DONTWAIT, NULL, max_linkhdr + sc->sc_len);
+ if (!ISSET(m->m_flags, M_EXT)) {
+ m_free(m);
+ sc->sc_if.if_oerrors++;
+ pfsyncstats.pfsyncs_onomem++;
+ pfsync_drop(sc);
+ return;
+ }
+ }
+#endif
+ m->m_data += max_linkhdr;
+ m->m_len = m->m_pkthdr.len = sc->sc_len;
+
+ /* build the ip header */
+ ip = (struct ip *)m->m_data;
+ bcopy(&sc->sc_template, ip, sizeof(*ip));
+ offset = sizeof(*ip);
+
+#ifdef __FreeBSD__
+ ip->ip_len = m->m_pkthdr.len;
+#else
+ ip->ip_len = htons(m->m_pkthdr.len);
+#endif
+ ip->ip_id = htons(ip_randomid());
+
+ /* build the pfsync header */
+ ph = (struct pfsync_header *)(m->m_data + offset);
+ bzero(ph, sizeof(*ph));
+ offset += sizeof(*ph);
+
+ ph->version = PFSYNC_VERSION;
+ ph->len = htons(sc->sc_len - sizeof(*ip));
+#ifdef __FreeBSD__
+ bcopy(V_pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH);
+#else
+ bcopy(pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH);
+#endif
+
+ /* walk the queues */
+ for (q = 0; q < PFSYNC_S_COUNT; q++) {
+ if (TAILQ_EMPTY(&sc->sc_qs[q]))
+ continue;
+
+ subh = (struct pfsync_subheader *)(m->m_data + offset);
+ offset += sizeof(*subh);
+
+ count = 0;
+ TAILQ_FOREACH(st, &sc->sc_qs[q], sync_list) {
+#ifdef PFSYNC_DEBUG
+#ifdef __FreeBSD__
+ KASSERT(st->sync_state == q,
+ ("%s: st->sync_state == q",
+ __FUNCTION__));
+#else
+ KASSERT(st->sync_state == q);
+#endif
+#endif
+
+ offset += pfsync_qs[q].write(st, m, offset);
+ st->sync_state = PFSYNC_S_NONE;
+ count++;
+ }
+ TAILQ_INIT(&sc->sc_qs[q]);
+
+ bzero(subh, sizeof(*subh));
+ subh->action = pfsync_qs[q].action;
+ subh->count = htons(count);
+ }
+
+ if (!TAILQ_EMPTY(&sc->sc_upd_req_list)) {
+ subh = (struct pfsync_subheader *)(m->m_data + offset);
+ offset += sizeof(*subh);
+
+ count = 0;
+ while ((ur = TAILQ_FIRST(&sc->sc_upd_req_list)) != NULL) {
+ TAILQ_REMOVE(&sc->sc_upd_req_list, ur, ur_entry);
+
+ bcopy(&ur->ur_msg, m->m_data + offset,
+ sizeof(ur->ur_msg));
+ offset += sizeof(ur->ur_msg);
+
+ pool_put(&sc->sc_pool, ur);
+
+ count++;
+ }
+
+ bzero(subh, sizeof(*subh));
+ subh->action = PFSYNC_ACT_UPD_REQ;
+ subh->count = htons(count);
+ }
+
+ /* has someone built a custom region for us to add? */
+ if (sc->sc_plus != NULL) {
+ bcopy(sc->sc_plus, m->m_data + offset, sc->sc_pluslen);
+ offset += sc->sc_pluslen;
+
+ sc->sc_plus = NULL;
+ }
+
+#ifdef notyet
+ if (!TAILQ_EMPTY(&sc->sc_tdb_q)) {
+ subh = (struct pfsync_subheader *)(m->m_data + offset);
+ offset += sizeof(*subh);
+
+ count = 0;
+ TAILQ_FOREACH(t, &sc->sc_tdb_q, tdb_sync_entry) {
+ offset += pfsync_out_tdb(t, m, offset);
+ CLR(t->tdb_flags, TDBF_PFSYNC);
+
+ count++;
+ }
+ TAILQ_INIT(&sc->sc_tdb_q);
+
+ bzero(subh, sizeof(*subh));
+ subh->action = PFSYNC_ACT_TDB;
+ subh->count = htons(count);
+ }
+#endif
+
+ subh = (struct pfsync_subheader *)(m->m_data + offset);
+ offset += sizeof(*subh);
+
+ bzero(subh, sizeof(*subh));
+ subh->action = PFSYNC_ACT_EOF;
+ subh->count = htons(1);
+
+ /* XXX write checksum in EOF here */
+
+ /* we're done, let's put it on the wire */
+#if NBPFILTER > 0
+ if (ifp->if_bpf) {
+ m->m_data += sizeof(*ip);
+ m->m_len = m->m_pkthdr.len = sc->sc_len - sizeof(*ip);
+#ifdef __FreeBSD__
+ BPF_MTAP(ifp, m);
+#else
+ bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
+#endif
+ m->m_data -= sizeof(*ip);
+ m->m_len = m->m_pkthdr.len = sc->sc_len;
+ }
+
+ if (sc->sc_sync_if == NULL) {
+ sc->sc_len = PFSYNC_MINPKT;
+ m_freem(m);
+ return;
+ }
+#endif
+
+#ifdef __FreeBSD__
+ sc->sc_ifp->if_opackets++;
+ sc->sc_ifp->if_obytes += m->m_pkthdr.len;
+ sc->sc_len = PFSYNC_MINPKT;
+
+ if (!_IF_QFULL(&sc->sc_ifp->if_snd))
+ _IF_ENQUEUE(&sc->sc_ifp->if_snd, m);
+ else {
+ m_freem(m);
+ sc->sc_ifp->if_snd.ifq_drops++;
+ }
+ if (schedswi)
+ swi_sched(V_pfsync_swi_cookie, 0);
+#else
+ sc->sc_if.if_opackets++;
+ sc->sc_if.if_obytes += m->m_pkthdr.len;
+
+ if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL) == 0)
+ pfsyncstats.pfsyncs_opackets++;
+ else
+ pfsyncstats.pfsyncs_oerrors++;
+
+ /* start again */
+ sc->sc_len = PFSYNC_MINPKT;
+#endif
+}
+
+void
+pfsync_insert_state(struct pf_state *st)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+#else
+ splassert(IPL_SOFTNET);
+#endif
+
+ if (ISSET(st->rule.ptr->rule_flag, PFRULE_NOSYNC) ||
+ st->key[PF_SK_WIRE]->proto == IPPROTO_PFSYNC) {
+ SET(st->state_flags, PFSTATE_NOSYNC);
+ return;
+ }
+
+ if (sc == NULL || ISSET(st->state_flags, PFSTATE_NOSYNC))
+ return;
+
+#ifdef PFSYNC_DEBUG
+#ifdef __FreeBSD__
+ KASSERT(st->sync_state == PFSYNC_S_NONE,
+ ("%s: st->sync_state == PFSYNC_S_NONE", __FUNCTION__));
+#else
+ KASSERT(st->sync_state == PFSYNC_S_NONE);
+#endif
+#endif
+
+ if (sc->sc_len == PFSYNC_MINPKT)
+#ifdef __FreeBSD__
+ callout_reset(&sc->sc_tmo, 1 * hz, pfsync_timeout,
+ V_pfsyncif);
+#else
+ timeout_add_sec(&sc->sc_tmo, 1);
+#endif
+
+ pfsync_q_ins(st, PFSYNC_S_INS);
+
+ st->sync_updates = 0;
+}
+
+int defer = 10;
+
+int
+pfsync_defer(struct pf_state *st, struct mbuf *m)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+ struct pfsync_deferral *pd;
+
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+#else
+ splassert(IPL_SOFTNET);
+#endif
+
+ if (!sc->sc_defer || m->m_flags & (M_BCAST|M_MCAST))
+ return (0);
+
+ if (sc->sc_deferred >= 128)
+ pfsync_undefer(TAILQ_FIRST(&sc->sc_deferrals), 0);
+
+ pd = pool_get(&sc->sc_pool, M_NOWAIT);
+ if (pd == NULL)
+ return (0);
+ sc->sc_deferred++;
+
+#ifdef __FreeBSD__
+ m->m_flags |= M_SKIP_FIREWALL;
+#else
+ m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
+#endif
+ SET(st->state_flags, PFSTATE_ACK);
+
+ pd->pd_st = st;
+ pd->pd_m = m;
+
+ TAILQ_INSERT_TAIL(&sc->sc_deferrals, pd, pd_entry);
+#ifdef __FreeBSD__
+ callout_init(&pd->pd_tmo, CALLOUT_MPSAFE);
+ callout_reset(&pd->pd_tmo, defer, pfsync_defer_tmo,
+ pd);
+#else
+ timeout_set(&pd->pd_tmo, pfsync_defer_tmo, pd);
+ timeout_add(&pd->pd_tmo, defer);
+#endif
+
+ swi_sched(V_pfsync_swi_cookie, 0);
+
+ return (1);
+}
+
+void
+pfsync_undefer(struct pfsync_deferral *pd, int drop)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+ int s;
+
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+#else
+ splassert(IPL_SOFTNET);
+#endif
+
+ TAILQ_REMOVE(&sc->sc_deferrals, pd, pd_entry);
+ sc->sc_deferred--;
+
+ CLR(pd->pd_st->state_flags, PFSTATE_ACK);
+ timeout_del(&pd->pd_tmo); /* bah */
+ if (drop)
+ m_freem(pd->pd_m);
+ else {
+ s = splnet();
+#ifdef __FreeBSD__
+ /* XXX: use pf_defered?! */
+ PF_UNLOCK();
+#endif
+ ip_output(pd->pd_m, (void *)NULL, (void *)NULL, 0,
+ (void *)NULL, (void *)NULL);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ splx(s);
+ }
+
+ pool_put(&sc->sc_pool, pd);
+}
+
+void
+pfsync_defer_tmo(void *arg)
+{
+#if defined(__FreeBSD__) && defined(VIMAGE)
+ struct pfsync_deferral *pd = arg;
+#endif
+ int s;
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ CURVNET_SET(pd->pd_m->m_pkthdr.rcvif->if_vnet); /* XXX */
+ PF_LOCK();
+#endif
+ pfsync_undefer(arg, 0);
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+ CURVNET_RESTORE();
+#endif
+ splx(s);
+}
+
+void
+pfsync_deferred(struct pf_state *st, int drop)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+ struct pfsync_deferral *pd;
+
+ TAILQ_FOREACH(pd, &sc->sc_deferrals, pd_entry) {
+ if (pd->pd_st == st) {
+ pfsync_undefer(pd, drop);
+ return;
+ }
+ }
+
+ panic("pfsync_send_deferred: unable to find deferred state");
+}
+
+u_int pfsync_upds = 0;
+
+void
+pfsync_update_state(struct pf_state *st)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+ int sync = 0;
+
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+#else
+ splassert(IPL_SOFTNET);
+#endif
+
+ if (sc == NULL)
+ return;
+
+ if (ISSET(st->state_flags, PFSTATE_ACK))
+ pfsync_deferred(st, 0);
+ if (ISSET(st->state_flags, PFSTATE_NOSYNC)) {
+ if (st->sync_state != PFSYNC_S_NONE)
+ pfsync_q_del(st);
+ return;
+ }
+
+ if (sc->sc_len == PFSYNC_MINPKT)
+#ifdef __FreeBSD__
+ callout_reset(&sc->sc_tmo, 1 * hz, pfsync_timeout,
+ V_pfsyncif);
+#else
+ timeout_add_sec(&sc->sc_tmo, 1);
+#endif
+
+ switch (st->sync_state) {
+ case PFSYNC_S_UPD_C:
+ case PFSYNC_S_UPD:
+ case PFSYNC_S_INS:
+ /* we're already handling it */
+
+ if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) {
+ st->sync_updates++;
+ if (st->sync_updates >= sc->sc_maxupdates)
+ sync = 1;
+ }
+ break;
+
+ case PFSYNC_S_IACK:
+ pfsync_q_del(st);
+ case PFSYNC_S_NONE:
+ pfsync_q_ins(st, PFSYNC_S_UPD_C);
+ st->sync_updates = 0;
+ break;
+
+ default:
+ panic("pfsync_update_state: unexpected sync state %d",
+ st->sync_state);
+ }
+
+ if (sync || (time_uptime - st->pfsync_time) < 2) {
+ pfsync_upds++;
+ schednetisr(NETISR_PFSYNC);
+ }
+}
+
+void
+pfsync_request_update(u_int32_t creatorid, u_int64_t id)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+ struct pfsync_upd_req_item *item;
+ size_t nlen = sizeof(struct pfsync_upd_req);
+ int s;
+
+ PF_LOCK_ASSERT();
+
+ /*
+ * this code does nothing to prevent multiple update requests for the
+ * same state being generated.
+ */
+
+ item = pool_get(&sc->sc_pool, PR_NOWAIT);
+ if (item == NULL) {
+ /* XXX stats */
+ return;
+ }
+
+ item->ur_msg.id = id;
+ item->ur_msg.creatorid = creatorid;
+
+ if (TAILQ_EMPTY(&sc->sc_upd_req_list))
+ nlen += sizeof(struct pfsync_subheader);
+
+#ifdef __FreeBSD__
+ if (sc->sc_len + nlen > sc->sc_ifp->if_mtu) {
+#else
+ if (sc->sc_len + nlen > sc->sc_if.if_mtu) {
+#endif
+ s = splnet();
+ pfsync_sendout();
+ splx(s);
+
+ nlen = sizeof(struct pfsync_subheader) +
+ sizeof(struct pfsync_upd_req);
+ }
+
+ TAILQ_INSERT_TAIL(&sc->sc_upd_req_list, item, ur_entry);
+ sc->sc_len += nlen;
+
+ schednetisr(NETISR_PFSYNC);
+}
+
+void
+pfsync_update_state_req(struct pf_state *st)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+
+ PF_LOCK_ASSERT();
+
+ if (sc == NULL)
+ panic("pfsync_update_state_req: nonexistant instance");
+
+ if (ISSET(st->state_flags, PFSTATE_NOSYNC)) {
+ if (st->sync_state != PFSYNC_S_NONE)
+ pfsync_q_del(st);
+ return;
+ }
+
+ switch (st->sync_state) {
+ case PFSYNC_S_UPD_C:
+ case PFSYNC_S_IACK:
+ pfsync_q_del(st);
+ case PFSYNC_S_NONE:
+ pfsync_q_ins(st, PFSYNC_S_UPD);
+ schednetisr(NETISR_PFSYNC);
+ return;
+
+ case PFSYNC_S_INS:
+ case PFSYNC_S_UPD:
+ case PFSYNC_S_DEL:
+ /* we're already handling it */
+ return;
+
+ default:
+ panic("pfsync_update_state_req: unexpected sync state %d",
+ st->sync_state);
+ }
+}
+
+void
+pfsync_delete_state(struct pf_state *st)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+#else
+ splassert(IPL_SOFTNET);
+#endif
+
+ if (sc == NULL)
+ return;
+
+ if (ISSET(st->state_flags, PFSTATE_ACK))
+ pfsync_deferred(st, 1);
+ if (ISSET(st->state_flags, PFSTATE_NOSYNC)) {
+ if (st->sync_state != PFSYNC_S_NONE)
+ pfsync_q_del(st);
+ return;
+ }
+
+ if (sc->sc_len == PFSYNC_MINPKT)
+#ifdef __FreeBSD__
+ callout_reset(&sc->sc_tmo, 1 * hz, pfsync_timeout,
+ V_pfsyncif);
+#else
+ timeout_add_sec(&sc->sc_tmo, 1);
+#endif
+
+ switch (st->sync_state) {
+ case PFSYNC_S_INS:
+ /* we never got to tell the world so just forget about it */
+ pfsync_q_del(st);
+ return;
+
+ case PFSYNC_S_UPD_C:
+ case PFSYNC_S_UPD:
+ case PFSYNC_S_IACK:
+ pfsync_q_del(st);
+ /* FALLTHROUGH to putting it on the del list */
+
+ case PFSYNC_S_NONE:
+ pfsync_q_ins(st, PFSYNC_S_DEL);
+ return;
+
+ default:
+ panic("pfsync_delete_state: unexpected sync state %d",
+ st->sync_state);
+ }
+}
+
+void
+pfsync_clear_states(u_int32_t creatorid, const char *ifname)
+{
+ struct {
+ struct pfsync_subheader subh;
+ struct pfsync_clr clr;
+ } __packed r;
+
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+#else
+ splassert(IPL_SOFTNET);
+#endif
+
+ if (sc == NULL)
+ return;
+
+ bzero(&r, sizeof(r));
+
+ r.subh.action = PFSYNC_ACT_CLR;
+ r.subh.count = htons(1);
+
+ strlcpy(r.clr.ifname, ifname, sizeof(r.clr.ifname));
+ r.clr.creatorid = creatorid;
+
+ pfsync_send_plus(&r, sizeof(r));
+}
+
+void
+pfsync_q_ins(struct pf_state *st, int q)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+ size_t nlen = pfsync_qs[q].len;
+ int s;
+
+ PF_LOCK_ASSERT();
+
+#ifdef __FreeBSD__
+ KASSERT(st->sync_state == PFSYNC_S_NONE,
+ ("%s: st->sync_state == PFSYNC_S_NONE", __FUNCTION__));
+#else
+ KASSERT(st->sync_state == PFSYNC_S_NONE);
+#endif
+
+#if 1 || defined(PFSYNC_DEBUG)
+ if (sc->sc_len < PFSYNC_MINPKT)
+#ifdef __FreeBSD__
+ panic("pfsync pkt len is too low %zu", sc->sc_len);
+#else
+ panic("pfsync pkt len is too low %d", sc->sc_len);
+#endif
+#endif
+ if (TAILQ_EMPTY(&sc->sc_qs[q]))
+ nlen += sizeof(struct pfsync_subheader);
+
+#ifdef __FreeBSD__
+ if (sc->sc_len + nlen > sc->sc_ifp->if_mtu) {
+#else
+ if (sc->sc_len + nlen > sc->sc_if.if_mtu) {
+#endif
+ s = splnet();
+ pfsync_sendout();
+ splx(s);
+
+ nlen = sizeof(struct pfsync_subheader) + pfsync_qs[q].len;
+ }
+
+ sc->sc_len += nlen;
+ TAILQ_INSERT_TAIL(&sc->sc_qs[q], st, sync_list);
+ st->sync_state = q;
+}
+
+void
+pfsync_q_del(struct pf_state *st)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+ int q = st->sync_state;
+
+#ifdef __FreeBSD__
+ KASSERT(st->sync_state != PFSYNC_S_NONE,
+ ("%s: st->sync_state != PFSYNC_S_NONE", __FUNCTION__));
+#else
+ KASSERT(st->sync_state != PFSYNC_S_NONE);
+#endif
+
+ sc->sc_len -= pfsync_qs[q].len;
+ TAILQ_REMOVE(&sc->sc_qs[q], st, sync_list);
+ st->sync_state = PFSYNC_S_NONE;
+
+ if (TAILQ_EMPTY(&sc->sc_qs[q]))
+ sc->sc_len -= sizeof(struct pfsync_subheader);
+}
+
+#ifdef notyet
+void
+pfsync_update_tdb(struct tdb *t, int output)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+ size_t nlen = sizeof(struct pfsync_tdb);
+ int s;
+
+ if (sc == NULL)
+ return;
+
+ if (!ISSET(t->tdb_flags, TDBF_PFSYNC)) {
+ if (TAILQ_EMPTY(&sc->sc_tdb_q))
+ nlen += sizeof(struct pfsync_subheader);
+
+ if (sc->sc_len + nlen > sc->sc_if.if_mtu) {
+ s = splnet();
+ PF_LOCK();
+ pfsync_sendout();
+ PF_UNLOCK();
+ splx(s);
+
+ nlen = sizeof(struct pfsync_subheader) +
+ sizeof(struct pfsync_tdb);
+ }
+
+ sc->sc_len += nlen;
+ TAILQ_INSERT_TAIL(&sc->sc_tdb_q, t, tdb_sync_entry);
+ SET(t->tdb_flags, TDBF_PFSYNC);
+ t->tdb_updates = 0;
+ } else {
+ if (++t->tdb_updates >= sc->sc_maxupdates)
+ schednetisr(NETISR_PFSYNC);
+ }
+
+ if (output)
+ SET(t->tdb_flags, TDBF_PFSYNC_RPL);
+ else
+ CLR(t->tdb_flags, TDBF_PFSYNC_RPL);
+}
+
+void
+pfsync_delete_tdb(struct tdb *t)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+
+ if (sc == NULL || !ISSET(t->tdb_flags, TDBF_PFSYNC))
+ return;
+
+ sc->sc_len -= sizeof(struct pfsync_tdb);
+ TAILQ_REMOVE(&sc->sc_tdb_q, t, tdb_sync_entry);
+ CLR(t->tdb_flags, TDBF_PFSYNC);
+
+ if (TAILQ_EMPTY(&sc->sc_tdb_q))
+ sc->sc_len -= sizeof(struct pfsync_subheader);
+}
+
+int
+pfsync_out_tdb(struct tdb *t, struct mbuf *m, int offset)
+{
+ struct pfsync_tdb *ut = (struct pfsync_tdb *)(m->m_data + offset);
+
+ bzero(ut, sizeof(*ut));
+ ut->spi = t->tdb_spi;
+ bcopy(&t->tdb_dst, &ut->dst, sizeof(ut->dst));
+ /*
+ * When a failover happens, the master's rpl is probably above
+ * what we see here (we may be up to a second late), so
+ * increase it a bit for outbound tdbs to manage most such
+ * situations.
+ *
+ * For now, just add an offset that is likely to be larger
+ * than the number of packets we can see in one second. The RFC
+ * just says the next packet must have a higher seq value.
+ *
+ * XXX What is a good algorithm for this? We could use
+ * a rate-determined increase, but to know it, we would have
+ * to extend struct tdb.
+ * XXX pt->rpl can wrap over MAXINT, but if so the real tdb
+ * will soon be replaced anyway. For now, just don't handle
+ * this edge case.
+ */
+#define RPL_INCR 16384
+ ut->rpl = htonl(t->tdb_rpl + (ISSET(t->tdb_flags, TDBF_PFSYNC_RPL) ?
+ RPL_INCR : 0));
+ ut->cur_bytes = htobe64(t->tdb_cur_bytes);
+ ut->sproto = t->tdb_sproto;
+
+ return (sizeof(*ut));
+}
+#endif
+
+void
+pfsync_bulk_start(void)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC)
+#endif
+ printf("pfsync: received bulk update request\n");
+
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+ if (TAILQ_EMPTY(&V_state_list))
+#else
+ if (TAILQ_EMPTY(&state_list))
+#endif
+ pfsync_bulk_status(PFSYNC_BUS_END);
+ else {
+ sc->sc_ureq_received = time_uptime;
+ if (sc->sc_bulk_next == NULL)
+#ifdef __FreeBSD__
+ sc->sc_bulk_next = TAILQ_FIRST(&V_state_list);
+#else
+ sc->sc_bulk_next = TAILQ_FIRST(&state_list);
+#endif
+ sc->sc_bulk_last = sc->sc_bulk_next;
+
+ pfsync_bulk_status(PFSYNC_BUS_START);
+ callout_reset(&sc->sc_bulk_tmo, 1, pfsync_bulk_update, sc);
+ }
+}
+
+void
+pfsync_bulk_update(void *arg)
+{
+ struct pfsync_softc *sc = arg;
+ struct pf_state *st = sc->sc_bulk_next;
+ int i = 0;
+ int s;
+
+ PF_LOCK_ASSERT();
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ CURVNET_SET(sc->sc_ifp->if_vnet);
+#endif
+ for (;;) {
+ if (st->sync_state == PFSYNC_S_NONE &&
+ st->timeout < PFTM_MAX &&
+ st->pfsync_time <= sc->sc_ureq_received) {
+ pfsync_update_state_req(st);
+ i++;
+ }
+
+ st = TAILQ_NEXT(st, entry_list);
+ if (st == NULL)
+#ifdef __FreeBSD__
+ st = TAILQ_FIRST(&V_state_list);
+#else
+ st = TAILQ_FIRST(&state_list);
+#endif
+
+ if (st == sc->sc_bulk_last) {
+ /* we're done */
+ sc->sc_bulk_next = NULL;
+ sc->sc_bulk_last = NULL;
+ pfsync_bulk_status(PFSYNC_BUS_END);
+ break;
+ }
+
+#ifdef __FreeBSD__
+ if (i > 1 && (sc->sc_ifp->if_mtu - sc->sc_len) <
+#else
+ if (i > 1 && (sc->sc_if.if_mtu - sc->sc_len) <
+#endif
+ sizeof(struct pfsync_state)) {
+ /* we've filled a packet */
+ sc->sc_bulk_next = st;
+#ifdef __FreeBSD__
+ callout_reset(&sc->sc_bulk_tmo, 1,
+ pfsync_bulk_update, sc);
+#else
+ timeout_add(&sc->sc_bulk_tmo, 1);
+#endif
+ break;
+ }
+ }
+
+#ifdef __FreeBSD__
+ CURVNET_RESTORE();
+#endif
+ splx(s);
+}
+
+void
+pfsync_bulk_status(u_int8_t status)
+{
+ struct {
+ struct pfsync_subheader subh;
+ struct pfsync_bus bus;
+ } __packed r;
+
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+
+ PF_LOCK_ASSERT();
+
+ bzero(&r, sizeof(r));
+
+ r.subh.action = PFSYNC_ACT_BUS;
+ r.subh.count = htons(1);
+
+#ifdef __FreeBSD__
+ r.bus.creatorid = V_pf_status.hostid;
+#else
+ r.bus.creatorid = pf_status.hostid;
+#endif
+ r.bus.endtime = htonl(time_uptime - sc->sc_ureq_received);
+ r.bus.status = status;
+
+ pfsync_send_plus(&r, sizeof(r));
+}
+
+void
+pfsync_bulk_fail(void *arg)
+{
+ struct pfsync_softc *sc = arg;
+
+#ifdef __FreeBSD__
+ CURVNET_SET(sc->sc_ifp->if_vnet);
+#endif
+
+ if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) {
+ /* Try again */
+#ifdef __FreeBSD__
+ callout_reset(&sc->sc_bulkfail_tmo, 5 * hz,
+ pfsync_bulk_fail, V_pfsyncif);
+#else
+ timeout_add_sec(&sc->sc_bulkfail_tmo, 5);
+#endif
+ PF_LOCK();
+ pfsync_request_update(0, 0);
+ PF_UNLOCK();
+ } else {
+ /* Pretend like the transfer was ok */
+ sc->sc_ureq_sent = 0;
+ sc->sc_bulk_tries = 0;
+#ifdef __FreeBSD__
+ if (!sc->pfsync_sync_ok && carp_demote_adj_p)
+ (*carp_demote_adj_p)(-V_pfsync_carp_adj,
+ "pfsync bulk fail");
+ sc->pfsync_sync_ok = 1;
+#else
+#if NCARP > 0
+ if (!pfsync_sync_ok)
+ carp_group_demote_adj(&sc->sc_if, -1);
+#endif
+ pfsync_sync_ok = 1;
+#endif
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC)
+#endif
+ printf("pfsync: failed to receive bulk update\n");
+ }
+
+#ifdef __FreeBSD__
+ CURVNET_RESTORE();
+#endif
+}
+
+void
+pfsync_send_plus(void *plus, size_t pluslen)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+ int s;
+
+ PF_LOCK_ASSERT();
+
+#ifdef __FreeBSD__
+ if (sc->sc_len + pluslen > sc->sc_ifp->if_mtu) {
+#else
+ if (sc->sc_len + pluslen > sc->sc_if.if_mtu) {
+#endif
+ s = splnet();
+ pfsync_sendout();
+ splx(s);
+ }
+
+ sc->sc_plus = plus;
+ sc->sc_len += (sc->sc_pluslen = pluslen);
+
+ s = splnet();
+ pfsync_sendout();
+ splx(s);
+}
+
+int
+pfsync_up(void)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+
+#ifdef __FreeBSD__
+ if (sc == NULL || !ISSET(sc->sc_ifp->if_flags, IFF_DRV_RUNNING))
+#else
+ if (sc == NULL || !ISSET(sc->sc_if.if_flags, IFF_RUNNING))
+#endif
+ return (0);
+
+ return (1);
+}
+
+int
+pfsync_state_in_use(struct pf_state *st)
+{
+#ifdef __FreeBSD__
+ struct pfsync_softc *sc = V_pfsyncif;
+#else
+ struct pfsync_softc *sc = pfsyncif;
+#endif
+
+ if (sc == NULL)
+ return (0);
+
+ if (st->sync_state != PFSYNC_S_NONE ||
+ st == sc->sc_bulk_next ||
+ st == sc->sc_bulk_last)
+ return (1);
+
+ return (0);
+}
+
+u_int pfsync_ints;
+u_int pfsync_tmos;
+
+void
+pfsync_timeout(void *arg)
+{
+#if defined(__FreeBSD__) && defined(VIMAGE)
+ struct pfsync_softc *sc = arg;
+#endif
+ int s;
+
+#ifdef __FreeBSD__
+ CURVNET_SET(sc->sc_ifp->if_vnet);
+#endif
+
+ pfsync_tmos++;
+
+ s = splnet();
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ pfsync_sendout();
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ splx(s);
+
+#ifdef __FreeBSD__
+ CURVNET_RESTORE();
+#endif
+}
+
+/* this is a softnet/netisr handler */
+void
+#ifdef __FreeBSD__
+pfsyncintr(void *arg)
+{
+ struct pfsync_softc *sc = arg;
+ struct mbuf *m, *n;
+
+ CURVNET_SET(sc->sc_ifp->if_vnet);
+ pfsync_ints++;
+
+ PF_LOCK();
+ if (sc->sc_len > PFSYNC_MINPKT)
+ pfsync_sendout1(0);
+ _IF_DEQUEUE_ALL(&sc->sc_ifp->if_snd, m);
+ PF_UNLOCK();
+
+ for (; m != NULL; m = n) {
+
+ n = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL)
+ == 0)
+ V_pfsyncstats.pfsyncs_opackets++;
+ else
+ V_pfsyncstats.pfsyncs_oerrors++;
+ }
+ CURVNET_RESTORE();
+}
+#else
+pfsyncintr(void)
+{
+ int s;
+
+ pfsync_ints++;
+
+ s = splnet();
+ pfsync_sendout();
+ splx(s);
+}
+#endif
+
+int
+pfsync_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
+ size_t newlen)
+{
+
+#ifdef notyet
+ /* All sysctl names at this level are terminal. */
+ if (namelen != 1)
+ return (ENOTDIR);
+
+ switch (name[0]) {
+ case PFSYNCCTL_STATS:
+ if (newp != NULL)
+ return (EPERM);
+ return (sysctl_struct(oldp, oldlenp, newp, newlen,
+ &V_pfsyncstats, sizeof(V_pfsyncstats)));
+ }
+#endif
+ return (ENOPROTOOPT);
+}
+
+#ifdef __FreeBSD__
+static int
+pfsync_multicast_setup(struct pfsync_softc *sc)
+{
+ struct ip_moptions *imo = &sc->sc_imo;
+ int error;
+
+ if (!(sc->sc_sync_if->if_flags & IFF_MULTICAST)) {
+ sc->sc_sync_if = NULL;
+ return (EADDRNOTAVAIL);
+ }
+
+ imo->imo_membership = (struct in_multi **)malloc(
+ (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_PFSYNC,
+ M_WAITOK | M_ZERO);
+ imo->imo_max_memberships = IP_MIN_MEMBERSHIPS;
+ imo->imo_multicast_vif = -1;
+
+ if ((error = in_joingroup(sc->sc_sync_if, &sc->sc_sync_peer, NULL,
+ &imo->imo_membership[0])) != 0) {
+ free(imo->imo_membership, M_PFSYNC);
+ return (error);
+ }
+ imo->imo_num_memberships++;
+ imo->imo_multicast_ifp = sc->sc_sync_if;
+ imo->imo_multicast_ttl = PFSYNC_DFLTTL;
+ imo->imo_multicast_loop = 0;
+
+ return (0);
+}
+
+static void
+pfsync_multicast_cleanup(struct pfsync_softc *sc)
+{
+ struct ip_moptions *imo = &sc->sc_imo;
+
+ in_leavegroup(imo->imo_membership[0], NULL);
+ free(imo->imo_membership, M_PFSYNC);
+ imo->imo_membership = NULL;
+ imo->imo_multicast_ifp = NULL;
+}
+
+#ifdef INET
+extern struct domain inetdomain;
+static struct protosw in_pfsync_protosw = {
+ .pr_type = SOCK_RAW,
+ .pr_domain = &inetdomain,
+ .pr_protocol = IPPROTO_PFSYNC,
+ .pr_flags = PR_ATOMIC|PR_ADDR,
+ .pr_input = pfsync_input,
+ .pr_output = (pr_output_t *)rip_output,
+ .pr_ctloutput = rip_ctloutput,
+ .pr_usrreqs = &rip_usrreqs
+};
+#endif
+
+static int
+pfsync_init()
+{
+ VNET_ITERATOR_DECL(vnet_iter);
+ int error = 0;
+
+ VNET_LIST_RLOCK();
+ VNET_FOREACH(vnet_iter) {
+ CURVNET_SET(vnet_iter);
+ V_pfsync_cloner = pfsync_cloner;
+ V_pfsync_cloner_data = pfsync_cloner_data;
+ V_pfsync_cloner.ifc_data = &V_pfsync_cloner_data;
+ if_clone_attach(&V_pfsync_cloner);
+ error = swi_add(NULL, "pfsync", pfsyncintr, V_pfsyncif,
+ SWI_NET, INTR_MPSAFE, &V_pfsync_swi_cookie);
+ CURVNET_RESTORE();
+ if (error)
+ goto fail_locked;
+ }
+ VNET_LIST_RUNLOCK();
+#ifdef INET
+ error = pf_proto_register(PF_INET, &in_pfsync_protosw);
+ if (error)
+ goto fail;
+ error = ipproto_register(IPPROTO_PFSYNC);
+ if (error) {
+ pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW);
+ goto fail;
+ }
+#endif
+ PF_LOCK();
+ pfsync_state_import_ptr = pfsync_state_import;
+ pfsync_up_ptr = pfsync_up;
+ pfsync_insert_state_ptr = pfsync_insert_state;
+ pfsync_update_state_ptr = pfsync_update_state;
+ pfsync_delete_state_ptr = pfsync_delete_state;
+ pfsync_clear_states_ptr = pfsync_clear_states;
+ pfsync_state_in_use_ptr = pfsync_state_in_use;
+ pfsync_defer_ptr = pfsync_defer;
+ PF_UNLOCK();
+
+ return (0);
+
+fail:
+ VNET_LIST_RLOCK();
+fail_locked:
+ VNET_FOREACH(vnet_iter) {
+ CURVNET_SET(vnet_iter);
+ if (V_pfsync_swi_cookie) {
+ swi_remove(V_pfsync_swi_cookie);
+ if_clone_detach(&V_pfsync_cloner);
+ }
+ CURVNET_RESTORE();
+ }
+ VNET_LIST_RUNLOCK();
+
+ return (error);
+}
+
+static void
+pfsync_uninit()
+{
+ VNET_ITERATOR_DECL(vnet_iter);
+
+ PF_LOCK();
+ pfsync_state_import_ptr = NULL;
+ pfsync_up_ptr = NULL;
+ pfsync_insert_state_ptr = NULL;
+ pfsync_update_state_ptr = NULL;
+ pfsync_delete_state_ptr = NULL;
+ pfsync_clear_states_ptr = NULL;
+ pfsync_state_in_use_ptr = NULL;
+ pfsync_defer_ptr = NULL;
+ PF_UNLOCK();
+
+ ipproto_unregister(IPPROTO_PFSYNC);
+ pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW);
+ VNET_LIST_RLOCK();
+ VNET_FOREACH(vnet_iter) {
+ CURVNET_SET(vnet_iter);
+ swi_remove(V_pfsync_swi_cookie);
+ if_clone_detach(&V_pfsync_cloner);
+ CURVNET_RESTORE();
+ }
+ VNET_LIST_RUNLOCK();
+}
+
+static int
+pfsync_modevent(module_t mod, int type, void *data)
+{
+ int error = 0;
+
+ switch (type) {
+ case MOD_LOAD:
+ error = pfsync_init();
+ break;
+ case MOD_QUIESCE:
+ /*
+ * Module should not be unloaded due to race conditions.
+ */
+ error = EPERM;
+ break;
+ case MOD_UNLOAD:
+ pfsync_uninit();
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+
+ return (error);
+}
+
+static moduledata_t pfsync_mod = {
+ "pfsync",
+ pfsync_modevent,
+ 0
+};
+
+#define PFSYNC_MODVER 1
+
+DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
+MODULE_VERSION(pfsync, PFSYNC_MODVER);
+MODULE_DEPEND(pfsync, pf, PF_MODVER, PF_MODVER, PF_MODVER);
+#endif /* __FreeBSD__ */
diff --git a/sys/contrib/pf/net/if_pfsync.h b/sys/contrib/pf/net/if_pfsync.h
new file mode 100644
index 0000000..3f34038
--- /dev/null
+++ b/sys/contrib/pf/net/if_pfsync.h
@@ -0,0 +1,324 @@
+/* $OpenBSD: if_pfsync.h,v 1.35 2008/06/29 08:42:15 mcbride Exp $ */
+
+/*
+ * Copyright (c) 2001 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2008 David Gwynne <dlg@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _NET_IF_PFSYNC_H_
+#define _NET_IF_PFSYNC_H_
+
+#define PFSYNC_VERSION 5
+#define PFSYNC_DFLTTL 255
+
+#define PFSYNC_ACT_CLR 0 /* clear all states */
+#define PFSYNC_ACT_INS 1 /* insert state */
+#define PFSYNC_ACT_INS_ACK 2 /* ack of insterted state */
+#define PFSYNC_ACT_UPD 3 /* update state */
+#define PFSYNC_ACT_UPD_C 4 /* "compressed" update state */
+#define PFSYNC_ACT_UPD_REQ 5 /* request "uncompressed" state */
+#define PFSYNC_ACT_DEL 6 /* delete state */
+#define PFSYNC_ACT_DEL_C 7 /* "compressed" delete state */
+#define PFSYNC_ACT_INS_F 8 /* insert fragment */
+#define PFSYNC_ACT_DEL_F 9 /* delete fragments */
+#define PFSYNC_ACT_BUS 10 /* bulk update status */
+#define PFSYNC_ACT_TDB 11 /* TDB replay counter update */
+#define PFSYNC_ACT_EOF 12 /* end of frame */
+#define PFSYNC_ACT_MAX 13
+
+#define PFSYNC_ACTIONS "CLR ST", \
+ "INS ST", \
+ "INS ST ACK", \
+ "UPD ST", \
+ "UPD ST COMP", \
+ "UPD ST REQ", \
+ "DEL ST", \
+ "DEL ST COMP", \
+ "INS FR", \
+ "DEL FR", \
+ "BULK UPD STAT", \
+ "TDB UPD", \
+ "EOF"
+
+#define PFSYNC_HMAC_LEN 20
+
+/*
+ * A pfsync frame is built from a header followed by several sections which
+ * are all prefixed with their own subheaders. Frames must be terminated with
+ * an EOF subheader.
+ *
+ * | ... |
+ * | IP header |
+ * +============================+
+ * | pfsync_header |
+ * +----------------------------+
+ * | pfsync_subheader |
+ * +----------------------------+
+ * | first action fields |
+ * | ... |
+ * +----------------------------+
+ * | pfsync_subheader |
+ * +----------------------------+
+ * | second action fields |
+ * | ... |
+ * +----------------------------+
+ * | EOF pfsync_subheader |
+ * +----------------------------+
+ * | HMAC |
+ * +============================+
+ */
+
+/*
+ * Frame header
+ */
+
+struct pfsync_header {
+ u_int8_t version;
+ u_int8_t _pad;
+ u_int16_t len;
+ u_int8_t pfcksum[PF_MD5_DIGEST_LENGTH];
+} __packed;
+
+/*
+ * Frame region subheader
+ */
+
+struct pfsync_subheader {
+ u_int8_t action;
+ u_int8_t _pad;
+ u_int16_t count;
+} __packed;
+
+/*
+ * CLR
+ */
+
+struct pfsync_clr {
+ char ifname[IFNAMSIZ];
+ u_int32_t creatorid;
+} __packed;
+
+/*
+ * INS, UPD, DEL
+ */
+
+/* these use struct pfsync_state in pfvar.h */
+
+/*
+ * INS_ACK
+ */
+
+struct pfsync_ins_ack {
+ u_int64_t id;
+ u_int32_t creatorid;
+} __packed;
+
+/*
+ * UPD_C
+ */
+
+struct pfsync_upd_c {
+ u_int64_t id;
+ struct pfsync_state_peer src;
+ struct pfsync_state_peer dst;
+ u_int32_t creatorid;
+ u_int32_t expire;
+ u_int8_t timeout;
+ u_int8_t _pad[3];
+} __packed;
+
+/*
+ * UPD_REQ
+ */
+
+struct pfsync_upd_req {
+ u_int64_t id;
+ u_int32_t creatorid;
+} __packed;
+
+/*
+ * DEL_C
+ */
+
+struct pfsync_del_c {
+ u_int64_t id;
+ u_int32_t creatorid;
+} __packed;
+
+/*
+ * INS_F, DEL_F
+ */
+
+/* not implemented (yet) */
+
+/*
+ * BUS
+ */
+
+struct pfsync_bus {
+ u_int32_t creatorid;
+ u_int32_t endtime;
+ u_int8_t status;
+#define PFSYNC_BUS_START 1
+#define PFSYNC_BUS_END 2
+ u_int8_t _pad[3];
+} __packed;
+
+/*
+ * TDB
+ */
+
+struct pfsync_tdb {
+ u_int32_t spi;
+ union sockaddr_union dst;
+ u_int32_t rpl;
+ u_int64_t cur_bytes;
+ u_int8_t sproto;
+ u_int8_t updates;
+ u_int8_t _pad[2];
+} __packed;
+
+/*
+ * EOF
+ */
+
+struct pfsync_eof {
+ u_int8_t hmac[PFSYNC_HMAC_LEN];
+} __packed;
+
+#define PFSYNC_HDRLEN sizeof(struct pfsync_header)
+
+
+
+/*
+ * Names for PFSYNC sysctl objects
+ */
+#define PFSYNCCTL_STATS 1 /* PFSYNC stats */
+#define PFSYNCCTL_MAXID 2
+
+#define PFSYNCCTL_NAMES { \
+ { 0, 0 }, \
+ { "stats", CTLTYPE_STRUCT }, \
+}
+
+struct pfsyncstats {
+ u_int64_t pfsyncs_ipackets; /* total input packets, IPv4 */
+ u_int64_t pfsyncs_ipackets6; /* total input packets, IPv6 */
+ u_int64_t pfsyncs_badif; /* not the right interface */
+ u_int64_t pfsyncs_badttl; /* TTL is not PFSYNC_DFLTTL */
+ u_int64_t pfsyncs_hdrops; /* packets shorter than hdr */
+ u_int64_t pfsyncs_badver; /* bad (incl unsupp) version */
+ u_int64_t pfsyncs_badact; /* bad action */
+ u_int64_t pfsyncs_badlen; /* data length does not match */
+ u_int64_t pfsyncs_badauth; /* bad authentication */
+ u_int64_t pfsyncs_stale; /* stale state */
+ u_int64_t pfsyncs_badval; /* bad values */
+ u_int64_t pfsyncs_badstate; /* insert/lookup failed */
+
+ u_int64_t pfsyncs_opackets; /* total output packets, IPv4 */
+ u_int64_t pfsyncs_opackets6; /* total output packets, IPv6 */
+ u_int64_t pfsyncs_onomem; /* no memory for an mbuf */
+ u_int64_t pfsyncs_oerrors; /* ip output error */
+};
+
+/*
+ * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
+ */
+struct pfsyncreq {
+ char pfsyncr_syncdev[IFNAMSIZ];
+ struct in_addr pfsyncr_syncpeer;
+ int pfsyncr_maxupdates;
+ int pfsyncr_defer;
+};
+
+#ifdef __FreeBSD__
+#define SIOCSETPFSYNC _IOW('i', 247, struct ifreq)
+#define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq)
+#endif
+
+#ifdef _KERNEL
+
+/*
+ * this shows where a pf state is with respect to the syncing.
+ */
+#define PFSYNC_S_INS 0x00
+#define PFSYNC_S_IACK 0x01
+#define PFSYNC_S_UPD 0x02
+#define PFSYNC_S_UPD_C 0x03
+#define PFSYNC_S_DEL 0x04
+#define PFSYNC_S_COUNT 0x05
+
+#define PFSYNC_S_DEFER 0xfe
+#define PFSYNC_S_NONE 0xff
+
+#ifdef __FreeBSD__
+void pfsync_input(struct mbuf *, __unused int);
+#else
+void pfsync_input(struct mbuf *, ...);
+#endif
+int pfsync_sysctl(int *, u_int, void *, size_t *,
+ void *, size_t);
+
+#define PFSYNC_SI_IOCTL 0x01
+#define PFSYNC_SI_CKSUM 0x02
+#define PFSYNC_SI_ACK 0x04
+int pfsync_state_import(struct pfsync_state *, u_int8_t);
+#ifndef __FreeBSD__
+void pfsync_state_export(struct pfsync_state *,
+ struct pf_state *);
+#endif
+
+void pfsync_insert_state(struct pf_state *);
+void pfsync_update_state(struct pf_state *);
+void pfsync_delete_state(struct pf_state *);
+void pfsync_clear_states(u_int32_t, const char *);
+
+#ifdef notyet
+void pfsync_update_tdb(struct tdb *, int);
+void pfsync_delete_tdb(struct tdb *);
+#endif
+
+int pfsync_defer(struct pf_state *, struct mbuf *);
+
+int pfsync_up(void);
+int pfsync_state_in_use(struct pf_state *);
+#endif
+
+#endif /* _NET_IF_PFSYNC_H_ */
diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c
new file mode 100644
index 0000000..ac51282
--- /dev/null
+++ b/sys/contrib/pf/net/pf.c
@@ -0,0 +1,7620 @@
+/* $OpenBSD: pf.c,v 1.634 2009/02/27 12:37:45 henning Exp $ */
+
+/*
+ * Copyright (c) 2001 Daniel Hartmeier
+ * Copyright (c) 2002 - 2008 Henning Brauer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Effort sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
+ *
+ */
+
+#ifdef __FreeBSD__
+#include "opt_inet.h"
+#include "opt_inet6.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#endif
+
+#ifdef __FreeBSD__
+#include "opt_bpf.h"
+#include "opt_pf.h"
+
+#define NPFSYNC 1
+
+#ifdef DEV_PFLOW
+#define NPFLOW DEV_PFLOW
+#else
+#define NPFLOW 0
+#endif
+
+#else
+#include "bpfilter.h"
+#include "pflog.h"
+#include "pfsync.h"
+#include "pflow.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/filio.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/time.h>
+#ifdef __FreeBSD__
+#include <sys/random.h>
+#include <sys/sysctl.h>
+#include <sys/endian.h>
+#define betoh64 be64toh
+#else
+#include <sys/pool.h>
+#endif
+#include <sys/proc.h>
+#ifdef __FreeBSD__
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/sx.h>
+#else
+#include <sys/rwlock.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <sys/md5.h>
+#else
+#include <crypto/md5.h>
+#endif
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/bpf.h>
+#include <net/route.h>
+#ifdef __FreeBSD__
+#ifdef RADIX_MPATH
+#include <net/radix_mpath.h>
+#endif
+#else
+#include <net/radix_mpath.h>
+#endif
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/in_pcb.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+#include <netinet/icmp_var.h>
+#include <netinet/if_ether.h>
+#ifdef __FreeBSD__
+#include <netinet/ip_fw.h>
+#include <netinet/ipfw/ip_fw_private.h> /* XXX: only for DIR_IN/DIR_OUT */
+#endif
+
+#ifndef __FreeBSD__
+#include <dev/rndvar.h>
+#endif
+#include <net/pfvar.h>
+#include <net/if_pflog.h>
+#include <net/if_pflow.h>
+#include <net/if_pfsync.h>
+
+#ifdef INET6
+#include <netinet/ip6.h>
+#include <netinet/in_pcb.h>
+#include <netinet/icmp6.h>
+#include <netinet6/nd6.h>
+#ifdef __FreeBSD__
+#include <netinet6/ip6_var.h>
+#include <netinet6/in6_pcb.h>
+#endif
+#endif /* INET6 */
+
+#ifdef __FreeBSD__
+#include <machine/in_cksum.h>
+#include <sys/limits.h>
+#include <sys/ucred.h>
+#include <security/mac/mac_framework.h>
+
+extern int ip_optcopy(struct ip *, struct ip *);
+#endif
+
+#ifdef __FreeBSD__
+#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
+#else
+#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
+#endif
+
+/*
+ * Global variables
+ */
+
+/* state tables */
+#ifdef __FreeBSD__
+VNET_DEFINE(struct pf_state_tree, pf_statetbl);
+
+VNET_DEFINE(struct pf_altqqueue, pf_altqs[2]);
+VNET_DEFINE(struct pf_palist, pf_pabuf);
+VNET_DEFINE(struct pf_altqqueue *, pf_altqs_active);
+VNET_DEFINE(struct pf_altqqueue *, pf_altqs_inactive);
+VNET_DEFINE(struct pf_status, pf_status);
+
+VNET_DEFINE(u_int32_t, ticket_altqs_active);
+VNET_DEFINE(u_int32_t, ticket_altqs_inactive);
+VNET_DEFINE(int, altqs_inactive_open);
+VNET_DEFINE(u_int32_t, ticket_pabuf);
+
+VNET_DEFINE(MD5_CTX, pf_tcp_secret_ctx);
+#define V_pf_tcp_secret_ctx VNET(pf_tcp_secret_ctx)
+VNET_DEFINE(u_char, pf_tcp_secret[16]);
+#define V_pf_tcp_secret VNET(pf_tcp_secret)
+VNET_DEFINE(int, pf_tcp_secret_init);
+#define V_pf_tcp_secret_init VNET(pf_tcp_secret_init)
+VNET_DEFINE(int, pf_tcp_iss_off);
+#define V_pf_tcp_iss_off VNET(pf_tcp_iss_off)
+
+struct pf_anchor_stackframe {
+ struct pf_ruleset *rs;
+ struct pf_rule *r;
+ struct pf_anchor_node *parent;
+ struct pf_anchor *child;
+};
+VNET_DEFINE(struct pf_anchor_stackframe, pf_anchor_stack[64]);
+#define V_pf_anchor_stack VNET(pf_anchor_stack)
+
+VNET_DEFINE(uma_zone_t, pf_src_tree_pl);
+VNET_DEFINE(uma_zone_t, pf_rule_pl);
+VNET_DEFINE(uma_zone_t, pf_pooladdr_pl);
+VNET_DEFINE(uma_zone_t, pf_state_pl);
+VNET_DEFINE(uma_zone_t, pf_state_key_pl);
+VNET_DEFINE(uma_zone_t, pf_state_item_pl);
+VNET_DEFINE(uma_zone_t, pf_altq_pl);
+#else
+struct pf_state_tree pf_statetbl;
+
+struct pf_altqqueue pf_altqs[2];
+struct pf_palist pf_pabuf;
+struct pf_altqqueue *pf_altqs_active;
+struct pf_altqqueue *pf_altqs_inactive;
+struct pf_status pf_status;
+
+u_int32_t ticket_altqs_active;
+u_int32_t ticket_altqs_inactive;
+int altqs_inactive_open;
+u_int32_t ticket_pabuf;
+
+MD5_CTX pf_tcp_secret_ctx;
+u_char pf_tcp_secret[16];
+int pf_tcp_secret_init;
+int pf_tcp_iss_off;
+
+struct pf_anchor_stackframe {
+ struct pf_ruleset *rs;
+ struct pf_rule *r;
+ struct pf_anchor_node *parent;
+ struct pf_anchor *child;
+} pf_anchor_stack[64];
+
+struct pool pf_src_tree_pl, pf_rule_pl, pf_pooladdr_pl;
+struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl;
+struct pool pf_altq_pl;
+#endif
+
+void pf_init_threshold(struct pf_threshold *, u_int32_t,
+ u_int32_t);
+void pf_add_threshold(struct pf_threshold *);
+int pf_check_threshold(struct pf_threshold *);
+
+void pf_change_ap(struct pf_addr *, u_int16_t *,
+ u_int16_t *, u_int16_t *, struct pf_addr *,
+ u_int16_t, u_int8_t, sa_family_t);
+int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *,
+ struct tcphdr *, struct pf_state_peer *);
+#ifdef INET6
+void pf_change_a6(struct pf_addr *, u_int16_t *,
+ struct pf_addr *, u_int8_t);
+#endif /* INET6 */
+void pf_change_icmp(struct pf_addr *, u_int16_t *,
+ struct pf_addr *, struct pf_addr *, u_int16_t,
+ u_int16_t *, u_int16_t *, u_int16_t *,
+ u_int16_t *, u_int8_t, sa_family_t);
+#ifdef __FreeBSD__
+void pf_send_tcp(struct mbuf *,
+ const struct pf_rule *, sa_family_t,
+#else
+void pf_send_tcp(const struct pf_rule *, sa_family_t,
+#endif
+ const struct pf_addr *, const struct pf_addr *,
+ u_int16_t, u_int16_t, u_int32_t, u_int32_t,
+ u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
+ u_int16_t, struct ether_header *, struct ifnet *);
+static void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
+ sa_family_t, struct pf_rule *);
+void pf_detach_state(struct pf_state *);
+void pf_state_key_detach(struct pf_state *, int);
+u_int32_t pf_tcp_iss(struct pf_pdesc *);
+int pf_test_rule(struct pf_rule **, struct pf_state **,
+ int, struct pfi_kif *, struct mbuf *, int,
+ void *, struct pf_pdesc *, struct pf_rule **,
+#ifdef __FreeBSD__
+ struct pf_ruleset **, struct ifqueue *,
+ struct inpcb *);
+#else
+ struct pf_ruleset **, struct ifqueue *);
+#endif
+static __inline int pf_create_state(struct pf_rule *, struct pf_rule *,
+ struct pf_rule *, struct pf_pdesc *,
+ struct pf_src_node *, struct pf_state_key *,
+ struct pf_state_key *, struct pf_state_key *,
+ struct pf_state_key *, struct mbuf *, int,
+ u_int16_t, u_int16_t, int *, struct pfi_kif *,
+ struct pf_state **, int, u_int16_t, u_int16_t,
+ int);
+int pf_test_fragment(struct pf_rule **, int,
+ struct pfi_kif *, struct mbuf *, void *,
+ struct pf_pdesc *, struct pf_rule **,
+ struct pf_ruleset **);
+int pf_tcp_track_full(struct pf_state_peer *,
+ struct pf_state_peer *, struct pf_state **,
+ struct pfi_kif *, struct mbuf *, int,
+ struct pf_pdesc *, u_short *, int *);
+int pf_tcp_track_sloppy(struct pf_state_peer *,
+ struct pf_state_peer *, struct pf_state **,
+ struct pf_pdesc *, u_short *);
+int pf_test_state_tcp(struct pf_state **, int,
+ struct pfi_kif *, struct mbuf *, int,
+ void *, struct pf_pdesc *, u_short *);
+int pf_test_state_udp(struct pf_state **, int,
+ struct pfi_kif *, struct mbuf *, int,
+ void *, struct pf_pdesc *);
+int pf_test_state_icmp(struct pf_state **, int,
+ struct pfi_kif *, struct mbuf *, int,
+ void *, struct pf_pdesc *, u_short *);
+int pf_test_state_other(struct pf_state **, int,
+ struct pfi_kif *, struct mbuf *, struct pf_pdesc *);
+void pf_route(struct mbuf **, struct pf_rule *, int,
+ struct ifnet *, struct pf_state *,
+ struct pf_pdesc *);
+void pf_route6(struct mbuf **, struct pf_rule *, int,
+ struct ifnet *, struct pf_state *,
+ struct pf_pdesc *);
+#ifndef __FreeBSD__
+int pf_socket_lookup(int, struct pf_pdesc *);
+#endif
+u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t,
+ sa_family_t);
+u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
+ sa_family_t);
+u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t,
+ int, u_int16_t);
+void pf_set_rt_ifp(struct pf_state *,
+ struct pf_addr *);
+int pf_check_proto_cksum(struct mbuf *, int, int,
+ u_int8_t, sa_family_t);
+#ifndef __FreeBSD__
+struct pf_divert *pf_get_divert(struct mbuf *);
+#endif
+void pf_print_state_parts(struct pf_state *,
+ struct pf_state_key *, struct pf_state_key *);
+int pf_addr_wrap_neq(struct pf_addr_wrap *,
+ struct pf_addr_wrap *);
+int pf_compare_state_keys(struct pf_state_key *,
+ struct pf_state_key *, struct pfi_kif *, u_int);
+#ifdef __FreeBSD__
+struct pf_state *pf_find_state(struct pfi_kif *,
+ struct pf_state_key_cmp *, u_int, struct mbuf *,
+ struct pf_mtag *);
+#else
+struct pf_state *pf_find_state(struct pfi_kif *,
+ struct pf_state_key_cmp *, u_int, struct mbuf *);
+#endif
+int pf_src_connlimit(struct pf_state **);
+int pf_check_congestion(struct ifqueue *);
+
+#ifdef __FreeBSD__
+int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len);
+
+VNET_DECLARE(int, pf_end_threads);
+
+VNET_DEFINE(struct pf_pool_limit, pf_pool_limits[PF_LIMIT_MAX]);
+#else
+extern struct pool pfr_ktable_pl;
+extern struct pool pfr_kentry_pl;
+
+struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
+ { &pf_state_pl, PFSTATE_HIWAT },
+ { &pf_src_tree_pl, PFSNODE_HIWAT },
+ { &pf_frent_pl, PFFRAG_FRENT_HIWAT },
+ { &pfr_ktable_pl, PFR_KTABLE_HIWAT },
+ { &pfr_kentry_pl, PFR_KENTRY_HIWAT }
+};
+#endif
+
+#ifdef __FreeBSD__
+#define PPACKET_LOOPED() \
+ (pd->pf_mtag->flags & PF_PACKET_LOOPED)
+
+#define PACKET_LOOPED() \
+ (pd.pf_mtag->flags & PF_PACKET_LOOPED)
+
+#define STATE_LOOKUP(i, k, d, s, m, pt) \
+ do { \
+ s = pf_find_state(i, k, d, m, pt); \
+ if (s == NULL || (s)->timeout == PFTM_PURGE) \
+ return (PF_DROP); \
+ if (PPACKET_LOOPED()) \
+ return (PF_PASS); \
+ if (d == PF_OUT && \
+ (((s)->rule.ptr->rt == PF_ROUTETO && \
+ (s)->rule.ptr->direction == PF_OUT) || \
+ ((s)->rule.ptr->rt == PF_REPLYTO && \
+ (s)->rule.ptr->direction == PF_IN)) && \
+ (s)->rt_kif != NULL && \
+ (s)->rt_kif != i) \
+ return (PF_PASS); \
+ } while (0)
+#else
+#define STATE_LOOKUP(i, k, d, s, m) \
+ do { \
+ s = pf_find_state(i, k, d, m); \
+ if (s == NULL || (s)->timeout == PFTM_PURGE) \
+ return (PF_DROP); \
+ if (d == PF_OUT && \
+ (((s)->rule.ptr->rt == PF_ROUTETO && \
+ (s)->rule.ptr->direction == PF_OUT) || \
+ ((s)->rule.ptr->rt == PF_REPLYTO && \
+ (s)->rule.ptr->direction == PF_IN)) && \
+ (s)->rt_kif != NULL && \
+ (s)->rt_kif != i) \
+ return (PF_PASS); \
+ } while (0)
+#endif
+
+#ifdef __FreeBSD__
+#define BOUND_IFACE(r, k) \
+ ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : V_pfi_all
+#else
+#define BOUND_IFACE(r, k) \
+ ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
+#endif
+
+#define STATE_INC_COUNTERS(s) \
+ do { \
+ s->rule.ptr->states_cur++; \
+ s->rule.ptr->states_tot++; \
+ if (s->anchor.ptr != NULL) { \
+ s->anchor.ptr->states_cur++; \
+ s->anchor.ptr->states_tot++; \
+ } \
+ if (s->nat_rule.ptr != NULL) { \
+ s->nat_rule.ptr->states_cur++; \
+ s->nat_rule.ptr->states_tot++; \
+ } \
+ } while (0)
+
+#define STATE_DEC_COUNTERS(s) \
+ do { \
+ if (s->nat_rule.ptr != NULL) \
+ s->nat_rule.ptr->states_cur--; \
+ if (s->anchor.ptr != NULL) \
+ s->anchor.ptr->states_cur--; \
+ s->rule.ptr->states_cur--; \
+ } while (0)
+
+static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
+static __inline int pf_state_compare_key(struct pf_state_key *,
+ struct pf_state_key *);
+static __inline int pf_state_compare_id(struct pf_state *,
+ struct pf_state *);
+
+#ifdef __FreeBSD__
+VNET_DEFINE(struct pf_src_tree, tree_src_tracking);
+
+VNET_DEFINE(struct pf_state_tree_id, tree_id);
+VNET_DEFINE(struct pf_state_queue, state_list);
+#else
+struct pf_src_tree tree_src_tracking;
+
+struct pf_state_tree_id tree_id;
+struct pf_state_queue state_list;
+#endif
+
+RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
+RB_GENERATE(pf_state_tree, pf_state_key, entry, pf_state_compare_key);
+RB_GENERATE(pf_state_tree_id, pf_state,
+ entry_id, pf_state_compare_id);
+
+static __inline int
+pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
+{
+ int diff;
+
+ if (a->rule.ptr > b->rule.ptr)
+ return (1);
+ if (a->rule.ptr < b->rule.ptr)
+ return (-1);
+ if ((diff = a->af - b->af) != 0)
+ return (diff);
+ switch (a->af) {
+#ifdef INET
+ case AF_INET:
+ if (a->addr.addr32[0] > b->addr.addr32[0])
+ return (1);
+ if (a->addr.addr32[0] < b->addr.addr32[0])
+ return (-1);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (a->addr.addr32[3] > b->addr.addr32[3])
+ return (1);
+ if (a->addr.addr32[3] < b->addr.addr32[3])
+ return (-1);
+ if (a->addr.addr32[2] > b->addr.addr32[2])
+ return (1);
+ if (a->addr.addr32[2] < b->addr.addr32[2])
+ return (-1);
+ if (a->addr.addr32[1] > b->addr.addr32[1])
+ return (1);
+ if (a->addr.addr32[1] < b->addr.addr32[1])
+ return (-1);
+ if (a->addr.addr32[0] > b->addr.addr32[0])
+ return (1);
+ if (a->addr.addr32[0] < b->addr.addr32[0])
+ return (-1);
+ break;
+#endif /* INET6 */
+ }
+ return (0);
+}
+
+#ifdef INET6
+void
+pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
+{
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ dst->addr32[0] = src->addr32[0];
+ break;
+#endif /* INET */
+ case AF_INET6:
+ dst->addr32[0] = src->addr32[0];
+ dst->addr32[1] = src->addr32[1];
+ dst->addr32[2] = src->addr32[2];
+ dst->addr32[3] = src->addr32[3];
+ break;
+ }
+}
+#endif /* INET6 */
+
+void
+pf_init_threshold(struct pf_threshold *threshold,
+ u_int32_t limit, u_int32_t seconds)
+{
+ threshold->limit = limit * PF_THRESHOLD_MULT;
+ threshold->seconds = seconds;
+ threshold->count = 0;
+ threshold->last = time_second;
+}
+
+void
+pf_add_threshold(struct pf_threshold *threshold)
+{
+ u_int32_t t = time_second, diff = t - threshold->last;
+
+ if (diff >= threshold->seconds)
+ threshold->count = 0;
+ else
+ threshold->count -= threshold->count * diff /
+ threshold->seconds;
+ threshold->count += PF_THRESHOLD_MULT;
+ threshold->last = t;
+}
+
+int
+pf_check_threshold(struct pf_threshold *threshold)
+{
+ return (threshold->count > threshold->limit);
+}
+
+int
+pf_src_connlimit(struct pf_state **state)
+{
+ int bad = 0;
+
+ (*state)->src_node->conn++;
+ (*state)->src.tcp_est = 1;
+ pf_add_threshold(&(*state)->src_node->conn_rate);
+
+ if ((*state)->rule.ptr->max_src_conn &&
+ (*state)->rule.ptr->max_src_conn <
+ (*state)->src_node->conn) {
+#ifdef __FreeBSD__
+ V_pf_status.lcounters[LCNT_SRCCONN]++;
+#else
+ pf_status.lcounters[LCNT_SRCCONN]++;
+#endif
+ bad++;
+ }
+
+ if ((*state)->rule.ptr->max_src_conn_rate.limit &&
+ pf_check_threshold(&(*state)->src_node->conn_rate)) {
+#ifdef __FreeBSD__
+ V_pf_status.lcounters[LCNT_SRCCONNRATE]++;
+#else
+ pf_status.lcounters[LCNT_SRCCONNRATE]++;
+#endif
+ bad++;
+ }
+
+ if (!bad)
+ return (0);
+
+ if ((*state)->rule.ptr->overload_tbl) {
+ struct pfr_addr p;
+ u_int32_t killed = 0;
+
+#ifdef __FreeBSD__
+ V_pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pf_src_connlimit: blocking address ");
+ pf_print_host(&(*state)->src_node->addr, 0,
+ (*state)->key[PF_SK_WIRE]->af);
+ }
+
+ bzero(&p, sizeof(p));
+ p.pfra_af = (*state)->key[PF_SK_WIRE]->af;
+ switch ((*state)->key[PF_SK_WIRE]->af) {
+#ifdef INET
+ case AF_INET:
+ p.pfra_net = 32;
+ p.pfra_ip4addr = (*state)->src_node->addr.v4;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ p.pfra_net = 128;
+ p.pfra_ip6addr = (*state)->src_node->addr.v6;
+ break;
+#endif /* INET6 */
+ }
+
+ pfr_insert_kentry((*state)->rule.ptr->overload_tbl,
+ &p, time_second);
+
+ /* kill existing states if that's required. */
+ if ((*state)->rule.ptr->flush) {
+ struct pf_state_key *sk;
+ struct pf_state *st;
+
+#ifdef __FreeBSD__
+ V_pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
+ RB_FOREACH(st, pf_state_tree_id, &V_tree_id) {
+#else
+ pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
+ RB_FOREACH(st, pf_state_tree_id, &tree_id) {
+#endif
+ sk = st->key[PF_SK_WIRE];
+ /*
+ * Kill states from this source. (Only those
+ * from the same rule if PF_FLUSH_GLOBAL is not
+ * set)
+ */
+ if (sk->af ==
+ (*state)->key[PF_SK_WIRE]->af &&
+ (((*state)->direction == PF_OUT &&
+ PF_AEQ(&(*state)->src_node->addr,
+ &sk->addr[1], sk->af)) ||
+ ((*state)->direction == PF_IN &&
+ PF_AEQ(&(*state)->src_node->addr,
+ &sk->addr[0], sk->af))) &&
+ ((*state)->rule.ptr->flush &
+ PF_FLUSH_GLOBAL ||
+ (*state)->rule.ptr == st->rule.ptr)) {
+ st->timeout = PFTM_PURGE;
+ st->src.state = st->dst.state =
+ TCPS_CLOSED;
+ killed++;
+ }
+ }
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC)
+#endif
+ printf(", %u states killed", killed);
+ }
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC)
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC)
+#endif
+ printf("\n");
+ }
+
+ /* kill this state */
+ (*state)->timeout = PFTM_PURGE;
+ (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
+ return (1);
+}
+
+int
+pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
+ struct pf_addr *src, sa_family_t af)
+{
+ struct pf_src_node k;
+
+ if (*sn == NULL) {
+ k.af = af;
+ PF_ACPY(&k.addr, src, af);
+ if (rule->rule_flag & PFRULE_RULESRCTRACK ||
+ rule->rpool.opts & PF_POOL_STICKYADDR)
+ k.rule.ptr = rule;
+ else
+ k.rule.ptr = NULL;
+#ifdef __FreeBSD__
+ V_pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
+ *sn = RB_FIND(pf_src_tree, &V_tree_src_tracking, &k);
+#else
+ pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
+ *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
+#endif
+ }
+ if (*sn == NULL) {
+ if (!rule->max_src_nodes ||
+ rule->src_nodes < rule->max_src_nodes)
+#ifdef __FreeBSD__
+ (*sn) = pool_get(&V_pf_src_tree_pl, PR_NOWAIT | PR_ZERO);
+#else
+ (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT | PR_ZERO);
+#endif
+ else
+#ifdef __FreeBSD__
+ V_pf_status.lcounters[LCNT_SRCNODES]++;
+#else
+ pf_status.lcounters[LCNT_SRCNODES]++;
+#endif
+ if ((*sn) == NULL)
+ return (-1);
+
+ pf_init_threshold(&(*sn)->conn_rate,
+ rule->max_src_conn_rate.limit,
+ rule->max_src_conn_rate.seconds);
+
+ (*sn)->af = af;
+ if (rule->rule_flag & PFRULE_RULESRCTRACK ||
+ rule->rpool.opts & PF_POOL_STICKYADDR)
+ (*sn)->rule.ptr = rule;
+ else
+ (*sn)->rule.ptr = NULL;
+ PF_ACPY(&(*sn)->addr, src, af);
+ if (RB_INSERT(pf_src_tree,
+#ifdef __FreeBSD__
+ &V_tree_src_tracking, *sn) != NULL) {
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ &tree_src_tracking, *sn) != NULL) {
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pf: src_tree insert failed: ");
+ pf_print_host(&(*sn)->addr, 0, af);
+ printf("\n");
+ }
+#ifdef __FreeBSD__
+ pool_put(&V_pf_src_tree_pl, *sn);
+#else
+ pool_put(&pf_src_tree_pl, *sn);
+#endif
+ return (-1);
+ }
+ (*sn)->creation = time_second;
+ (*sn)->ruletype = rule->action;
+ if ((*sn)->rule.ptr != NULL)
+ (*sn)->rule.ptr->src_nodes++;
+#ifdef __FreeBSD__
+ V_pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
+ V_pf_status.src_nodes++;
+#else
+ pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
+ pf_status.src_nodes++;
+#endif
+ } else {
+ if (rule->max_src_states &&
+ (*sn)->states >= rule->max_src_states) {
+#ifdef __FreeBSD__
+ V_pf_status.lcounters[LCNT_SRCSTATES]++;
+#else
+ pf_status.lcounters[LCNT_SRCSTATES]++;
+#endif
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+/* state table stuff */
+
+static __inline int
+pf_state_compare_key(struct pf_state_key *a, struct pf_state_key *b)
+{
+ int diff;
+
+ if ((diff = a->proto - b->proto) != 0)
+ return (diff);
+ if ((diff = a->af - b->af) != 0)
+ return (diff);
+ switch (a->af) {
+#ifdef INET
+ case AF_INET:
+ if (a->addr[0].addr32[0] > b->addr[0].addr32[0])
+ return (1);
+ if (a->addr[0].addr32[0] < b->addr[0].addr32[0])
+ return (-1);
+ if (a->addr[1].addr32[0] > b->addr[1].addr32[0])
+ return (1);
+ if (a->addr[1].addr32[0] < b->addr[1].addr32[0])
+ return (-1);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (a->addr[0].addr32[3] > b->addr[0].addr32[3])
+ return (1);
+ if (a->addr[0].addr32[3] < b->addr[0].addr32[3])
+ return (-1);
+ if (a->addr[1].addr32[3] > b->addr[1].addr32[3])
+ return (1);
+ if (a->addr[1].addr32[3] < b->addr[1].addr32[3])
+ return (-1);
+ if (a->addr[0].addr32[2] > b->addr[0].addr32[2])
+ return (1);
+ if (a->addr[0].addr32[2] < b->addr[0].addr32[2])
+ return (-1);
+ if (a->addr[1].addr32[2] > b->addr[1].addr32[2])
+ return (1);
+ if (a->addr[1].addr32[2] < b->addr[1].addr32[2])
+ return (-1);
+ if (a->addr[0].addr32[1] > b->addr[0].addr32[1])
+ return (1);
+ if (a->addr[0].addr32[1] < b->addr[0].addr32[1])
+ return (-1);
+ if (a->addr[1].addr32[1] > b->addr[1].addr32[1])
+ return (1);
+ if (a->addr[1].addr32[1] < b->addr[1].addr32[1])
+ return (-1);
+ if (a->addr[0].addr32[0] > b->addr[0].addr32[0])
+ return (1);
+ if (a->addr[0].addr32[0] < b->addr[0].addr32[0])
+ return (-1);
+ if (a->addr[1].addr32[0] > b->addr[1].addr32[0])
+ return (1);
+ if (a->addr[1].addr32[0] < b->addr[1].addr32[0])
+ return (-1);
+ break;
+#endif /* INET6 */
+ }
+
+ if ((diff = a->port[0] - b->port[0]) != 0)
+ return (diff);
+ if ((diff = a->port[1] - b->port[1]) != 0)
+ return (diff);
+
+ return (0);
+}
+
+static __inline int
+pf_state_compare_id(struct pf_state *a, struct pf_state *b)
+{
+ if (a->id > b->id)
+ return (1);
+ if (a->id < b->id)
+ return (-1);
+ if (a->creatorid > b->creatorid)
+ return (1);
+ if (a->creatorid < b->creatorid)
+ return (-1);
+
+ return (0);
+}
+
+int
+pf_state_key_attach(struct pf_state_key *sk, struct pf_state *s, int idx)
+{
+ struct pf_state_item *si;
+ struct pf_state_key *cur;
+ struct pf_state *olds = NULL;
+
+#ifdef __FreeBSD__
+ KASSERT(s->key[idx] == NULL, ("%s: key is null!", __FUNCTION__));
+#else
+ KASSERT(s->key[idx] == NULL); /* XXX handle this? */
+#endif
+
+#ifdef __FreeBSD__
+ if ((cur = RB_INSERT(pf_state_tree, &V_pf_statetbl, sk)) != NULL) {
+#else
+ if ((cur = RB_INSERT(pf_state_tree, &pf_statetbl, sk)) != NULL) {
+#endif
+ /* key exists. check for same kif, if none, add to key */
+ TAILQ_FOREACH(si, &cur->states, entry)
+ if (si->s->kif == s->kif &&
+ si->s->direction == s->direction) {
+ if (sk->proto == IPPROTO_TCP &&
+ si->s->src.state >= TCPS_FIN_WAIT_2 &&
+ si->s->dst.state >= TCPS_FIN_WAIT_2) {
+ si->s->src.state = si->s->dst.state =
+ TCPS_CLOSED;
+ /* unlink late or sks can go away */
+ olds = si->s;
+ } else {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pf: %s key attach "
+ "failed on %s: ",
+ (idx == PF_SK_WIRE) ?
+ "wire" : "stack",
+ s->kif->pfik_name);
+ pf_print_state_parts(s,
+ (idx == PF_SK_WIRE) ?
+ sk : NULL,
+ (idx == PF_SK_STACK) ?
+ sk : NULL);
+ printf(", existing: ");
+ pf_print_state_parts(si->s,
+ (idx == PF_SK_WIRE) ?
+ sk : NULL,
+ (idx == PF_SK_STACK) ?
+ sk : NULL);
+ printf("\n");
+ }
+#ifdef __FreeBSD__
+ pool_put(&V_pf_state_key_pl, sk);
+#else
+ pool_put(&pf_state_key_pl, sk);
+#endif
+ return (-1); /* collision! */
+ }
+ }
+#ifdef __FreeBSD__
+ pool_put(&V_pf_state_key_pl, sk);
+#else
+ pool_put(&pf_state_key_pl, sk);
+#endif
+ s->key[idx] = cur;
+ } else
+ s->key[idx] = sk;
+
+#ifdef __FreeBSD__
+ if ((si = pool_get(&V_pf_state_item_pl, PR_NOWAIT)) == NULL) {
+#else
+ if ((si = pool_get(&pf_state_item_pl, PR_NOWAIT)) == NULL) {
+#endif
+ pf_state_key_detach(s, idx);
+ return (-1);
+ }
+ si->s = s;
+
+ /* list is sorted, if-bound states before floating */
+#ifdef __FreeBSD__
+ if (s->kif == V_pfi_all)
+#else
+ if (s->kif == pfi_all)
+#endif
+ TAILQ_INSERT_TAIL(&s->key[idx]->states, si, entry);
+ else
+ TAILQ_INSERT_HEAD(&s->key[idx]->states, si, entry);
+
+ if (olds)
+ pf_unlink_state(olds);
+
+ return (0);
+}
+
+void
+pf_detach_state(struct pf_state *s)
+{
+ if (s->key[PF_SK_WIRE] == s->key[PF_SK_STACK])
+ s->key[PF_SK_WIRE] = NULL;
+
+ if (s->key[PF_SK_STACK] != NULL)
+ pf_state_key_detach(s, PF_SK_STACK);
+
+ if (s->key[PF_SK_WIRE] != NULL)
+ pf_state_key_detach(s, PF_SK_WIRE);
+}
+
+void
+pf_state_key_detach(struct pf_state *s, int idx)
+{
+ struct pf_state_item *si;
+
+ si = TAILQ_FIRST(&s->key[idx]->states);
+ while (si && si->s != s)
+ si = TAILQ_NEXT(si, entry);
+
+ if (si) {
+ TAILQ_REMOVE(&s->key[idx]->states, si, entry);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_state_item_pl, si);
+#else
+ pool_put(&pf_state_item_pl, si);
+#endif
+ }
+
+ if (TAILQ_EMPTY(&s->key[idx]->states)) {
+#ifdef __FreeBSD__
+ RB_REMOVE(pf_state_tree, &V_pf_statetbl, s->key[idx]);
+#else
+ RB_REMOVE(pf_state_tree, &pf_statetbl, s->key[idx]);
+#endif
+ if (s->key[idx]->reverse)
+ s->key[idx]->reverse->reverse = NULL;
+#ifdef __FreeBSD__
+ /* XXX: implement this */
+#else
+ if (s->key[idx]->inp)
+ s->key[idx]->inp->inp_pf_sk = NULL;
+#endif
+#ifdef __FreeBSD__
+ pool_put(&V_pf_state_key_pl, s->key[idx]);
+#else
+ pool_put(&pf_state_key_pl, s->key[idx]);
+#endif
+ }
+ s->key[idx] = NULL;
+}
+
+struct pf_state_key *
+pf_alloc_state_key(int pool_flags)
+{
+ struct pf_state_key *sk;
+
+#ifdef __FreeBSD__
+ if ((sk = pool_get(&V_pf_state_key_pl, pool_flags)) == NULL)
+#else
+ if ((sk = pool_get(&pf_state_key_pl, pool_flags)) == NULL)
+#endif
+ return (NULL);
+ TAILQ_INIT(&sk->states);
+
+ return (sk);
+}
+
+int
+pf_state_key_setup(struct pf_pdesc *pd, struct pf_rule *nr,
+ struct pf_state_key **skw, struct pf_state_key **sks,
+ struct pf_state_key **skp, struct pf_state_key **nkp,
+ struct pf_addr *saddr, struct pf_addr *daddr,
+ u_int16_t sport, u_int16_t dport)
+{
+#ifdef __FreeBSD__
+ KASSERT((*skp == NULL && *nkp == NULL),
+ ("%s: skp == NULL && nkp == NULL", __FUNCTION__));
+#else
+ KASSERT((*skp == NULL && *nkp == NULL));
+#endif
+
+ if ((*skp = pf_alloc_state_key(PR_NOWAIT | PR_ZERO)) == NULL)
+ return (ENOMEM);
+
+ PF_ACPY(&(*skp)->addr[pd->sidx], saddr, pd->af);
+ PF_ACPY(&(*skp)->addr[pd->didx], daddr, pd->af);
+ (*skp)->port[pd->sidx] = sport;
+ (*skp)->port[pd->didx] = dport;
+ (*skp)->proto = pd->proto;
+ (*skp)->af = pd->af;
+
+ if (nr != NULL) {
+ if ((*nkp = pf_alloc_state_key(PR_NOWAIT | PR_ZERO)) == NULL)
+ return (ENOMEM); /* caller must handle cleanup */
+
+ /* XXX maybe just bcopy and TAILQ_INIT(&(*nkp)->states) */
+ PF_ACPY(&(*nkp)->addr[0], &(*skp)->addr[0], pd->af);
+ PF_ACPY(&(*nkp)->addr[1], &(*skp)->addr[1], pd->af);
+ (*nkp)->port[0] = (*skp)->port[0];
+ (*nkp)->port[1] = (*skp)->port[1];
+ (*nkp)->proto = pd->proto;
+ (*nkp)->af = pd->af;
+ } else
+ *nkp = *skp;
+
+ if (pd->dir == PF_IN) {
+ *skw = *skp;
+ *sks = *nkp;
+ } else {
+ *sks = *skp;
+ *skw = *nkp;
+ }
+ return (0);
+}
+
+
+int
+pf_state_insert(struct pfi_kif *kif, struct pf_state_key *skw,
+ struct pf_state_key *sks, struct pf_state *s)
+{
+#ifndef __FreeBSD__
+ splassert(IPL_SOFTNET);
+#endif
+
+ s->kif = kif;
+
+ if (skw == sks) {
+ if (pf_state_key_attach(skw, s, PF_SK_WIRE))
+ return (-1);
+ s->key[PF_SK_STACK] = s->key[PF_SK_WIRE];
+ } else {
+ if (pf_state_key_attach(skw, s, PF_SK_WIRE)) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_state_key_pl, sks);
+#else
+ pool_put(&pf_state_key_pl, sks);
+#endif
+ return (-1);
+ }
+ if (pf_state_key_attach(sks, s, PF_SK_STACK)) {
+ pf_state_key_detach(s, PF_SK_WIRE);
+ return (-1);
+ }
+ }
+
+ if (s->id == 0 && s->creatorid == 0) {
+#ifdef __FreeBSD__
+ s->id = htobe64(V_pf_status.stateid++);
+ s->creatorid = V_pf_status.hostid;
+#else
+ s->id = htobe64(pf_status.stateid++);
+ s->creatorid = pf_status.hostid;
+#endif
+ }
+#ifdef __FreeBSD__
+ if (RB_INSERT(pf_state_tree_id, &V_tree_id, s) != NULL) {
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (RB_INSERT(pf_state_tree_id, &tree_id, s) != NULL) {
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pf: state insert failed: "
+ "id: %016llx creatorid: %08x",
+#ifdef __FreeBSD__
+ (unsigned long long)betoh64(s->id), ntohl(s->creatorid));
+#else
+ betoh64(s->id), ntohl(s->creatorid));
+#endif
+ printf("\n");
+ }
+ pf_detach_state(s);
+ return (-1);
+ }
+#ifdef __FreeBSD__
+ TAILQ_INSERT_TAIL(&V_state_list, s, entry_list);
+ V_pf_status.fcounters[FCNT_STATE_INSERT]++;
+ V_pf_status.states++;
+#else
+ TAILQ_INSERT_TAIL(&state_list, s, entry_list);
+ pf_status.fcounters[FCNT_STATE_INSERT]++;
+ pf_status.states++;
+#endif
+ pfi_kif_ref(kif, PFI_KIF_REF_STATE);
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_insert_state_ptr != NULL)
+ pfsync_insert_state_ptr(s);
+#else
+ pfsync_insert_state(s);
+#endif
+#endif
+ return (0);
+}
+
+struct pf_state *
+pf_find_state_byid(struct pf_state_cmp *key)
+{
+#ifdef __FreeBSD__
+ V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
+
+ return (RB_FIND(pf_state_tree_id, &V_tree_id, (struct pf_state *)key));
+#else
+ pf_status.fcounters[FCNT_STATE_SEARCH]++;
+
+ return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key));
+#endif
+}
+
+/* XXX debug function, intended to be removed one day */
+int
+pf_compare_state_keys(struct pf_state_key *a, struct pf_state_key *b,
+ struct pfi_kif *kif, u_int dir)
+{
+ /* a (from hdr) and b (new) must be exact opposites of each other */
+ if (a->af == b->af && a->proto == b->proto &&
+ PF_AEQ(&a->addr[0], &b->addr[1], a->af) &&
+ PF_AEQ(&a->addr[1], &b->addr[0], a->af) &&
+ a->port[0] == b->port[1] &&
+ a->port[1] == b->port[0])
+ return (0);
+ else {
+ /* mismatch. must not happen. */
+ printf("pf: state key linking mismatch! dir=%s, "
+ "if=%s, stored af=%u, a0: ",
+ dir == PF_OUT ? "OUT" : "IN", kif->pfik_name, a->af);
+ pf_print_host(&a->addr[0], a->port[0], a->af);
+ printf(", a1: ");
+ pf_print_host(&a->addr[1], a->port[1], a->af);
+ printf(", proto=%u", a->proto);
+ printf(", found af=%u, a0: ", b->af);
+ pf_print_host(&b->addr[0], b->port[0], b->af);
+ printf(", a1: ");
+ pf_print_host(&b->addr[1], b->port[1], b->af);
+ printf(", proto=%u", b->proto);
+ printf(".\n");
+ return (-1);
+ }
+}
+
+struct pf_state *
+#ifdef __FreeBSD__
+pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir,
+ struct mbuf *m, struct pf_mtag *pftag)
+#else
+pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir,
+ struct mbuf *m)
+#endif
+{
+ struct pf_state_key *sk;
+ struct pf_state_item *si;
+
+#ifdef __FreeBSD__
+ V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
+#else
+ pf_status.fcounters[FCNT_STATE_SEARCH]++;
+#endif
+
+#ifdef __FreeBSD__
+ if (dir == PF_OUT && pftag->statekey &&
+ ((struct pf_state_key *)pftag->statekey)->reverse)
+ sk = ((struct pf_state_key *)pftag->statekey)->reverse;
+ else {
+#ifdef __FreeBSD__
+ if ((sk = RB_FIND(pf_state_tree, &V_pf_statetbl,
+#else
+ if ((sk = RB_FIND(pf_state_tree, &pf_statetbl,
+#endif
+ (struct pf_state_key *)key)) == NULL)
+ return (NULL);
+ if (dir == PF_OUT && pftag->statekey &&
+ pf_compare_state_keys(pftag->statekey, sk,
+ kif, dir) == 0) {
+ ((struct pf_state_key *)
+ pftag->statekey)->reverse = sk;
+ sk->reverse = pftag->statekey;
+ }
+ }
+#else
+ if (dir == PF_OUT && m->m_pkthdr.pf.statekey &&
+ ((struct pf_state_key *)m->m_pkthdr.pf.statekey)->reverse)
+ sk = ((struct pf_state_key *)m->m_pkthdr.pf.statekey)->reverse;
+ else {
+#ifdef __FreeBSD__
+ if ((sk = RB_FIND(pf_state_tree, &V_pf_statetbl,
+#else
+ if ((sk = RB_FIND(pf_state_tree, &pf_statetbl,
+#endif
+ (struct pf_state_key *)key)) == NULL)
+ return (NULL);
+ if (dir == PF_OUT && m->m_pkthdr.pf.statekey &&
+ pf_compare_state_keys(m->m_pkthdr.pf.statekey, sk,
+ kif, dir) == 0) {
+ ((struct pf_state_key *)
+ m->m_pkthdr.pf.statekey)->reverse = sk;
+ sk->reverse = m->m_pkthdr.pf.statekey;
+ }
+ }
+#endif
+
+ if (dir == PF_OUT)
+#ifdef __FreeBSD__
+ pftag->statekey = NULL;
+#else
+ m->m_pkthdr.pf.statekey = NULL;
+#endif
+
+ /* list is sorted, if-bound states before floating ones */
+ TAILQ_FOREACH(si, &sk->states, entry)
+#ifdef __FreeBSD__
+ if ((si->s->kif == V_pfi_all || si->s->kif == kif) &&
+#else
+ if ((si->s->kif == pfi_all || si->s->kif == kif) &&
+#endif
+ sk == (dir == PF_IN ? si->s->key[PF_SK_WIRE] :
+ si->s->key[PF_SK_STACK]))
+ return (si->s);
+
+ return (NULL);
+}
+
+struct pf_state *
+pf_find_state_all(struct pf_state_key_cmp *key, u_int dir, int *more)
+{
+ struct pf_state_key *sk;
+ struct pf_state_item *si, *ret = NULL;
+
+#ifdef __FreeBSD__
+ V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
+#else
+ pf_status.fcounters[FCNT_STATE_SEARCH]++;
+#endif
+
+#ifdef __FreeBSD__
+ sk = RB_FIND(pf_state_tree, &V_pf_statetbl, (struct pf_state_key *)key);
+#else
+ sk = RB_FIND(pf_state_tree, &pf_statetbl, (struct pf_state_key *)key);
+#endif
+ if (sk != NULL) {
+ TAILQ_FOREACH(si, &sk->states, entry)
+ if (dir == PF_INOUT ||
+ (sk == (dir == PF_IN ? si->s->key[PF_SK_WIRE] :
+ si->s->key[PF_SK_STACK]))) {
+ if (more == NULL)
+ return (si->s);
+
+ if (ret)
+ (*more)++;
+ else
+ ret = si;
+ }
+ }
+ return (ret ? ret->s : NULL);
+}
+
+/* END state table stuff */
+
+
+void
+pf_purge_thread(void *v)
+{
+ int nloops = 0, s;
+#ifdef __FreeBSD__
+ int locked;
+#endif
+
+ CURVNET_SET((struct vnet *)v);
+
+ for (;;) {
+ tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz);
+
+#ifdef __FreeBSD__
+ sx_slock(&V_pf_consistency_lock);
+ PF_LOCK();
+ locked = 0;
+
+ if (V_pf_end_threads) {
+ PF_UNLOCK();
+ sx_sunlock(&V_pf_consistency_lock);
+ sx_xlock(&V_pf_consistency_lock);
+ PF_LOCK();
+
+ pf_purge_expired_states(V_pf_status.states, 1);
+ pf_purge_expired_fragments();
+ pf_purge_expired_src_nodes(1);
+ V_pf_end_threads++;
+
+ sx_xunlock(&V_pf_consistency_lock);
+ PF_UNLOCK();
+ wakeup(pf_purge_thread);
+ kproc_exit(0);
+ }
+#endif
+ s = splsoftnet();
+
+ /* process a fraction of the state table every second */
+#ifdef __FreeBSD__
+ if (!pf_purge_expired_states(1 + (V_pf_status.states /
+ V_pf_default_rule.timeout[PFTM_INTERVAL]), 0)) {
+ PF_UNLOCK();
+ sx_sunlock(&V_pf_consistency_lock);
+ sx_xlock(&V_pf_consistency_lock);
+ PF_LOCK();
+ locked = 1;
+
+ pf_purge_expired_states(1 + (V_pf_status.states /
+ V_pf_default_rule.timeout[PFTM_INTERVAL]), 1);
+ }
+#else
+ pf_purge_expired_states(1 + (pf_status.states
+ / pf_default_rule.timeout[PFTM_INTERVAL]));
+#endif
+
+ /* purge other expired types every PFTM_INTERVAL seconds */
+#ifdef __FreeBSD__
+ if (++nloops >= V_pf_default_rule.timeout[PFTM_INTERVAL]) {
+#else
+ if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) {
+#endif
+ pf_purge_expired_fragments();
+ pf_purge_expired_src_nodes(0);
+ nloops = 0;
+ }
+
+ splx(s);
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+ if (locked)
+ sx_xunlock(&V_pf_consistency_lock);
+ else
+ sx_sunlock(&V_pf_consistency_lock);
+#endif
+ }
+ CURVNET_RESTORE();
+}
+
+u_int32_t
+pf_state_expires(const struct pf_state *state)
+{
+ u_int32_t timeout;
+ u_int32_t start;
+ u_int32_t end;
+ u_int32_t states;
+
+ /* handle all PFTM_* > PFTM_MAX here */
+ if (state->timeout == PFTM_PURGE)
+ return (time_second);
+ if (state->timeout == PFTM_UNTIL_PACKET)
+ return (0);
+#ifdef __FreeBSD__
+ KASSERT(state->timeout != PFTM_UNLINKED,
+ ("pf_state_expires: timeout == PFTM_UNLINKED"));
+ KASSERT((state->timeout < PFTM_MAX),
+ ("pf_state_expires: timeout > PFTM_MAX"));
+#else
+ KASSERT(state->timeout != PFTM_UNLINKED);
+ KASSERT(state->timeout < PFTM_MAX);
+#endif
+ timeout = state->rule.ptr->timeout[state->timeout];
+ if (!timeout)
+#ifdef __FreeBSD__
+ timeout = V_pf_default_rule.timeout[state->timeout];
+#else
+ timeout = pf_default_rule.timeout[state->timeout];
+#endif
+ start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
+ if (start) {
+ end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
+ states = state->rule.ptr->states_cur;
+ } else {
+#ifdef __FreeBSD__
+ start = V_pf_default_rule.timeout[PFTM_ADAPTIVE_START];
+ end = V_pf_default_rule.timeout[PFTM_ADAPTIVE_END];
+ states = V_pf_status.states;
+#else
+ start = pf_default_rule.timeout[PFTM_ADAPTIVE_START];
+ end = pf_default_rule.timeout[PFTM_ADAPTIVE_END];
+ states = pf_status.states;
+#endif
+ }
+ if (end && states > start && start < end) {
+ if (states < end)
+ return (state->expire + timeout * (end - states) /
+ (end - start));
+ else
+ return (time_second);
+ }
+ return (state->expire + timeout);
+}
+
+#ifdef __FreeBSD__
+int
+pf_purge_expired_src_nodes(int waslocked)
+#else
+void
+pf_purge_expired_src_nodes(int waslocked)
+#endif
+{
+ struct pf_src_node *cur, *next;
+ int locked = waslocked;
+
+#ifdef __FreeBSD__
+ for (cur = RB_MIN(pf_src_tree, &V_tree_src_tracking); cur; cur = next) {
+ next = RB_NEXT(pf_src_tree, &V_tree_src_tracking, cur);
+#else
+ for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
+ next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
+#endif
+
+ if (cur->states <= 0 && cur->expire <= time_second) {
+ if (! locked) {
+#ifdef __FreeBSD__
+ if (!sx_try_upgrade(&V_pf_consistency_lock))
+ return (0);
+#else
+ rw_enter_write(&pf_consistency_lock);
+#endif
+ next = RB_NEXT(pf_src_tree,
+#ifdef __FreeBSD__
+ &V_tree_src_tracking, cur);
+#else
+ &tree_src_tracking, cur);
+#endif
+ locked = 1;
+ }
+ if (cur->rule.ptr != NULL) {
+ cur->rule.ptr->src_nodes--;
+ if (cur->rule.ptr->states_cur <= 0 &&
+ cur->rule.ptr->max_src_nodes <= 0)
+ pf_rm_rule(NULL, cur->rule.ptr);
+ }
+#ifdef __FreeBSD__
+ RB_REMOVE(pf_src_tree, &V_tree_src_tracking, cur);
+ V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
+ V_pf_status.src_nodes--;
+ pool_put(&V_pf_src_tree_pl, cur);
+#else
+ RB_REMOVE(pf_src_tree, &tree_src_tracking, cur);
+ pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
+ pf_status.src_nodes--;
+ pool_put(&pf_src_tree_pl, cur);
+#endif
+ }
+ }
+
+ if (locked && !waslocked)
+#ifdef __FreeBSD__
+ {
+ sx_downgrade(&V_pf_consistency_lock);
+ }
+ return (1);
+#else
+ rw_exit_write(&pf_consistency_lock);
+#endif
+}
+
+void
+pf_src_tree_remove_state(struct pf_state *s)
+{
+ u_int32_t timeout;
+
+ if (s->src_node != NULL) {
+ if (s->src.tcp_est)
+ --s->src_node->conn;
+ if (--s->src_node->states <= 0) {
+ timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
+ if (!timeout)
+ timeout =
+#ifdef __FreeBSD__
+ V_pf_default_rule.timeout[PFTM_SRC_NODE];
+#else
+ pf_default_rule.timeout[PFTM_SRC_NODE];
+#endif
+ s->src_node->expire = time_second + timeout;
+ }
+ }
+ if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
+ if (--s->nat_src_node->states <= 0) {
+ timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
+ if (!timeout)
+ timeout =
+#ifdef __FreeBSD__
+ V_pf_default_rule.timeout[PFTM_SRC_NODE];
+#else
+ pf_default_rule.timeout[PFTM_SRC_NODE];
+#endif
+ s->nat_src_node->expire = time_second + timeout;
+ }
+ }
+ s->src_node = s->nat_src_node = NULL;
+}
+
+/* callers should be at splsoftnet */
+void
+pf_unlink_state(struct pf_state *cur)
+{
+#ifdef __FreeBSD__
+ if (cur->local_flags & PFSTATE_EXPIRING)
+ return;
+ cur->local_flags |= PFSTATE_EXPIRING;
+#else
+ splassert(IPL_SOFTNET);
+#endif
+
+ if (cur->src.state == PF_TCPS_PROXY_DST) {
+ /* XXX wire key the right one? */
+#ifdef __FreeBSD__
+ pf_send_tcp(NULL, cur->rule.ptr, cur->key[PF_SK_WIRE]->af,
+#else
+ pf_send_tcp(cur->rule.ptr, cur->key[PF_SK_WIRE]->af,
+#endif
+ &cur->key[PF_SK_WIRE]->addr[1],
+ &cur->key[PF_SK_WIRE]->addr[0],
+ cur->key[PF_SK_WIRE]->port[1],
+ cur->key[PF_SK_WIRE]->port[0],
+ cur->src.seqhi, cur->src.seqlo + 1,
+ TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
+ }
+#ifdef __FreeBSD__
+ RB_REMOVE(pf_state_tree_id, &V_tree_id, cur);
+#else
+ RB_REMOVE(pf_state_tree_id, &tree_id, cur);
+#endif
+#if NPFLOW > 0
+ if (cur->state_flags & PFSTATE_PFLOW)
+#ifdef __FreeBSD__
+ if (export_pflow_ptr != NULL)
+ export_pflow_ptr(cur);
+#else
+ export_pflow(cur);
+#endif
+#endif
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_delete_state_ptr != NULL)
+ pfsync_delete_state_ptr(cur);
+#else
+ pfsync_delete_state(cur);
+#endif
+#endif
+ cur->timeout = PFTM_UNLINKED;
+ pf_src_tree_remove_state(cur);
+ pf_detach_state(cur);
+}
+
+/* callers should be at splsoftnet and hold the
+ * write_lock on pf_consistency_lock */
+void
+pf_free_state(struct pf_state *cur)
+{
+#ifndef __FreeBSD__
+ splassert(IPL_SOFTNET);
+#endif
+
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_state_in_use_ptr != NULL &&
+ pfsync_state_in_use_ptr(cur))
+#else
+ if (pfsync_state_in_use(cur))
+#endif
+ return;
+#endif
+#ifdef __FreeBSD__
+ KASSERT(cur->timeout == PFTM_UNLINKED,
+ ("pf_free_state: cur->timeout != PFTM_UNLINKED"));
+#else
+ KASSERT(cur->timeout == PFTM_UNLINKED);
+#endif
+ if (--cur->rule.ptr->states_cur <= 0 &&
+ cur->rule.ptr->src_nodes <= 0)
+ pf_rm_rule(NULL, cur->rule.ptr);
+ if (cur->nat_rule.ptr != NULL)
+ if (--cur->nat_rule.ptr->states_cur <= 0 &&
+ cur->nat_rule.ptr->src_nodes <= 0)
+ pf_rm_rule(NULL, cur->nat_rule.ptr);
+ if (cur->anchor.ptr != NULL)
+ if (--cur->anchor.ptr->states_cur <= 0)
+ pf_rm_rule(NULL, cur->anchor.ptr);
+ pf_normalize_tcp_cleanup(cur);
+ pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE);
+#ifdef __FreeBSD__
+ TAILQ_REMOVE(&V_state_list, cur, entry_list);
+#else
+ TAILQ_REMOVE(&state_list, cur, entry_list);
+#endif
+ if (cur->tag)
+ pf_tag_unref(cur->tag);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_state_pl, cur);
+ V_pf_status.fcounters[FCNT_STATE_REMOVALS]++;
+ V_pf_status.states--;
+#else
+ pool_put(&pf_state_pl, cur);
+ pf_status.fcounters[FCNT_STATE_REMOVALS]++;
+ pf_status.states--;
+#endif
+}
+
+#ifdef __FreeBSD__
+int
+pf_purge_expired_states(u_int32_t maxcheck, int waslocked)
+#else
+void
+pf_purge_expired_states(u_int32_t maxcheck)
+#endif
+{
+ static struct pf_state *cur = NULL;
+ struct pf_state *next;
+#ifdef __FreeBSD__
+ int locked = waslocked;
+#else
+ int locked = 0;
+#endif
+
+ while (maxcheck--) {
+ /* wrap to start of list when we hit the end */
+ if (cur == NULL) {
+#ifdef __FreeBSD__
+ cur = TAILQ_FIRST(&V_state_list);
+#else
+ cur = TAILQ_FIRST(&state_list);
+#endif
+ if (cur == NULL)
+ break; /* list empty */
+ }
+
+ /* get next state, as cur may get deleted */
+ next = TAILQ_NEXT(cur, entry_list);
+
+ if (cur->timeout == PFTM_UNLINKED) {
+ /* free unlinked state */
+ if (! locked) {
+#ifdef __FreeBSD__
+ if (!sx_try_upgrade(&V_pf_consistency_lock))
+ return (0);
+#else
+ rw_enter_write(&pf_consistency_lock);
+#endif
+ locked = 1;
+ }
+ pf_free_state(cur);
+ } else if (pf_state_expires(cur) <= time_second) {
+ /* unlink and free expired state */
+ pf_unlink_state(cur);
+ if (! locked) {
+#ifdef __FreeBSD__
+ if (!sx_try_upgrade(&V_pf_consistency_lock))
+ return (0);
+#else
+ rw_enter_write(&pf_consistency_lock);
+#endif
+ locked = 1;
+ }
+ pf_free_state(cur);
+ }
+ cur = next;
+ }
+
+#ifdef __FreeBSD__
+ if (!waslocked && locked)
+ sx_downgrade(&V_pf_consistency_lock);
+
+ return (1);
+#else
+ if (locked)
+ rw_exit_write(&pf_consistency_lock);
+#endif
+}
+
+int
+pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
+{
+ if (aw->type != PF_ADDR_TABLE)
+ return (0);
+ if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname, 1)) == NULL)
+ return (1);
+ return (0);
+}
+
+void
+pf_tbladdr_remove(struct pf_addr_wrap *aw)
+{
+ if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
+ return;
+ pfr_detach_table(aw->p.tbl);
+ aw->p.tbl = NULL;
+}
+
+void
+pf_tbladdr_copyout(struct pf_addr_wrap *aw)
+{
+ struct pfr_ktable *kt = aw->p.tbl;
+
+ if (aw->type != PF_ADDR_TABLE || kt == NULL)
+ return;
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
+ kt = kt->pfrkt_root;
+ aw->p.tbl = NULL;
+ aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
+ kt->pfrkt_cnt : -1;
+}
+
+void
+pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
+{
+ switch (af) {
+#ifdef INET
+ case AF_INET: {
+ u_int32_t a = ntohl(addr->addr32[0]);
+ printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
+ (a>>8)&255, a&255);
+ if (p) {
+ p = ntohs(p);
+ printf(":%u", p);
+ }
+ break;
+ }
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6: {
+ u_int16_t b;
+ u_int8_t i, curstart, curend, maxstart, maxend;
+ curstart = curend = maxstart = maxend = 255;
+ for (i = 0; i < 8; i++) {
+ if (!addr->addr16[i]) {
+ if (curstart == 255)
+ curstart = i;
+ curend = i;
+ } else {
+ if ((curend - curstart) >
+ (maxend - maxstart)) {
+ maxstart = curstart;
+ maxend = curend;
+ }
+ curstart = curend = 255;
+ }
+ }
+ if ((curend - curstart) >
+ (maxend - maxstart)) {
+ maxstart = curstart;
+ maxend = curend;
+ }
+ for (i = 0; i < 8; i++) {
+ if (i >= maxstart && i <= maxend) {
+ if (i == 0)
+ printf(":");
+ if (i == maxend)
+ printf(":");
+ } else {
+ b = ntohs(addr->addr16[i]);
+ printf("%x", b);
+ if (i < 7)
+ printf(":");
+ }
+ }
+ if (p) {
+ p = ntohs(p);
+ printf("[%u]", p);
+ }
+ break;
+ }
+#endif /* INET6 */
+ }
+}
+
+void
+pf_print_state(struct pf_state *s)
+{
+ pf_print_state_parts(s, NULL, NULL);
+}
+
+void
+pf_print_state_parts(struct pf_state *s,
+ struct pf_state_key *skwp, struct pf_state_key *sksp)
+{
+ struct pf_state_key *skw, *sks;
+ u_int8_t proto, dir;
+
+ /* Do our best to fill these, but they're skipped if NULL */
+ skw = skwp ? skwp : (s ? s->key[PF_SK_WIRE] : NULL);
+ sks = sksp ? sksp : (s ? s->key[PF_SK_STACK] : NULL);
+ proto = skw ? skw->proto : (sks ? sks->proto : 0);
+ dir = s ? s->direction : 0;
+
+ switch (proto) {
+ case IPPROTO_IPV4:
+ printf("IPv4");
+ break;
+ case IPPROTO_IPV6:
+ printf("IPv6");
+ break;
+ case IPPROTO_TCP:
+ printf("TCP");
+ break;
+ case IPPROTO_UDP:
+ printf("UDP");
+ break;
+ case IPPROTO_ICMP:
+ printf("ICMP");
+ break;
+ case IPPROTO_ICMPV6:
+ printf("ICMPv6");
+ break;
+ default:
+ printf("%u", skw->proto);
+ break;
+ }
+ switch (dir) {
+ case PF_IN:
+ printf(" in");
+ break;
+ case PF_OUT:
+ printf(" out");
+ break;
+ }
+ if (skw) {
+ printf(" wire: ");
+ pf_print_host(&skw->addr[0], skw->port[0], skw->af);
+ printf(" ");
+ pf_print_host(&skw->addr[1], skw->port[1], skw->af);
+ }
+ if (sks) {
+ printf(" stack: ");
+ if (sks != skw) {
+ pf_print_host(&sks->addr[0], sks->port[0], sks->af);
+ printf(" ");
+ pf_print_host(&sks->addr[1], sks->port[1], sks->af);
+ } else
+ printf("-");
+ }
+ if (s) {
+ if (proto == IPPROTO_TCP) {
+ printf(" [lo=%u high=%u win=%u modulator=%u",
+ s->src.seqlo, s->src.seqhi,
+ s->src.max_win, s->src.seqdiff);
+ if (s->src.wscale && s->dst.wscale)
+ printf(" wscale=%u",
+ s->src.wscale & PF_WSCALE_MASK);
+ printf("]");
+ printf(" [lo=%u high=%u win=%u modulator=%u",
+ s->dst.seqlo, s->dst.seqhi,
+ s->dst.max_win, s->dst.seqdiff);
+ if (s->src.wscale && s->dst.wscale)
+ printf(" wscale=%u",
+ s->dst.wscale & PF_WSCALE_MASK);
+ printf("]");
+ }
+ printf(" %u:%u", s->src.state, s->dst.state);
+ }
+}
+
+void
+pf_print_flags(u_int8_t f)
+{
+ if (f)
+ printf(" ");
+ if (f & TH_FIN)
+ printf("F");
+ if (f & TH_SYN)
+ printf("S");
+ if (f & TH_RST)
+ printf("R");
+ if (f & TH_PUSH)
+ printf("P");
+ if (f & TH_ACK)
+ printf("A");
+ if (f & TH_URG)
+ printf("U");
+ if (f & TH_ECE)
+ printf("E");
+ if (f & TH_CWR)
+ printf("W");
+}
+
+#define PF_SET_SKIP_STEPS(i) \
+ do { \
+ while (head[i] != cur) { \
+ head[i]->skip[i].ptr = cur; \
+ head[i] = TAILQ_NEXT(head[i], entries); \
+ } \
+ } while (0)
+
+void
+pf_calc_skip_steps(struct pf_rulequeue *rules)
+{
+ struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT];
+ int i;
+
+ cur = TAILQ_FIRST(rules);
+ prev = cur;
+ for (i = 0; i < PF_SKIP_COUNT; ++i)
+ head[i] = cur;
+ while (cur != NULL) {
+
+ if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
+ PF_SET_SKIP_STEPS(PF_SKIP_IFP);
+ if (cur->direction != prev->direction)
+ PF_SET_SKIP_STEPS(PF_SKIP_DIR);
+ if (cur->af != prev->af)
+ PF_SET_SKIP_STEPS(PF_SKIP_AF);
+ if (cur->proto != prev->proto)
+ PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
+ if (cur->src.neg != prev->src.neg ||
+ pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
+ PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
+ if (cur->src.port[0] != prev->src.port[0] ||
+ cur->src.port[1] != prev->src.port[1] ||
+ cur->src.port_op != prev->src.port_op)
+ PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
+ if (cur->dst.neg != prev->dst.neg ||
+ pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
+ PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
+ if (cur->dst.port[0] != prev->dst.port[0] ||
+ cur->dst.port[1] != prev->dst.port[1] ||
+ cur->dst.port_op != prev->dst.port_op)
+ PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
+
+ prev = cur;
+ cur = TAILQ_NEXT(cur, entries);
+ }
+ for (i = 0; i < PF_SKIP_COUNT; ++i)
+ PF_SET_SKIP_STEPS(i);
+}
+
+int
+pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
+{
+ if (aw1->type != aw2->type)
+ return (1);
+ switch (aw1->type) {
+ case PF_ADDR_ADDRMASK:
+ case PF_ADDR_RANGE:
+ if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
+ return (1);
+ if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
+ return (1);
+ return (0);
+ case PF_ADDR_DYNIFTL:
+ return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
+ case PF_ADDR_NOROUTE:
+ case PF_ADDR_URPFFAILED:
+ return (0);
+ case PF_ADDR_TABLE:
+ return (aw1->p.tbl != aw2->p.tbl);
+ case PF_ADDR_RTLABEL:
+ return (aw1->v.rtlabel != aw2->v.rtlabel);
+ default:
+ printf("invalid address type: %d\n", aw1->type);
+ return (1);
+ }
+}
+
+u_int16_t
+pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)
+{
+ u_int32_t l;
+
+ if (udp && !cksum)
+ return (0x0000);
+ l = cksum + old - new;
+ l = (l >> 16) + (l & 65535);
+ l = l & 65535;
+ if (udp && !l)
+ return (0xFFFF);
+ return (l);
+}
+
+void
+pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc,
+ struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af)
+{
+ struct pf_addr ao;
+ u_int16_t po = *p;
+
+ PF_ACPY(&ao, a, af);
+ PF_ACPY(a, an, af);
+
+ *p = pn;
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
+ ao.addr16[0], an->addr16[0], 0),
+ ao.addr16[1], an->addr16[1], 0);
+ *p = pn;
+ *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
+ ao.addr16[0], an->addr16[0], u),
+ ao.addr16[1], an->addr16[1], u),
+ po, pn, u);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
+ pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
+ pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
+ ao.addr16[0], an->addr16[0], u),
+ ao.addr16[1], an->addr16[1], u),
+ ao.addr16[2], an->addr16[2], u),
+ ao.addr16[3], an->addr16[3], u),
+ ao.addr16[4], an->addr16[4], u),
+ ao.addr16[5], an->addr16[5], u),
+ ao.addr16[6], an->addr16[6], u),
+ ao.addr16[7], an->addr16[7], u),
+ po, pn, u);
+ break;
+#endif /* INET6 */
+ }
+}
+
+
+/* Changes a u_int32_t. Uses a void * so there are no align restrictions */
+void
+pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u)
+{
+ u_int32_t ao;
+
+ memcpy(&ao, a, sizeof(ao));
+ memcpy(a, &an, sizeof(u_int32_t));
+ *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u),
+ ao % 65536, an % 65536, u);
+}
+
+#ifdef INET6
+void
+pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u)
+{
+ struct pf_addr ao;
+
+ PF_ACPY(&ao, a, AF_INET6);
+ PF_ACPY(a, an, AF_INET6);
+
+ *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
+ pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
+ pf_cksum_fixup(pf_cksum_fixup(*c,
+ ao.addr16[0], an->addr16[0], u),
+ ao.addr16[1], an->addr16[1], u),
+ ao.addr16[2], an->addr16[2], u),
+ ao.addr16[3], an->addr16[3], u),
+ ao.addr16[4], an->addr16[4], u),
+ ao.addr16[5], an->addr16[5], u),
+ ao.addr16[6], an->addr16[6], u),
+ ao.addr16[7], an->addr16[7], u);
+}
+#endif /* INET6 */
+
+void
+pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa,
+ struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c,
+ u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af)
+{
+ struct pf_addr oia, ooa;
+
+ PF_ACPY(&oia, ia, af);
+ if (oa)
+ PF_ACPY(&ooa, oa, af);
+
+ /* Change inner protocol port, fix inner protocol checksum. */
+ if (ip != NULL) {
+ u_int16_t oip = *ip;
+ u_int32_t opc;
+
+ if (pc != NULL)
+ opc = *pc;
+ *ip = np;
+ if (pc != NULL)
+ *pc = pf_cksum_fixup(*pc, oip, *ip, u);
+ *ic = pf_cksum_fixup(*ic, oip, *ip, 0);
+ if (pc != NULL)
+ *ic = pf_cksum_fixup(*ic, opc, *pc, 0);
+ }
+ /* Change inner ip address, fix inner ip and icmp checksums. */
+ PF_ACPY(ia, na, af);
+ switch (af) {
+#ifdef INET
+ case AF_INET: {
+ u_int32_t oh2c = *h2c;
+
+ *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c,
+ oia.addr16[0], ia->addr16[0], 0),
+ oia.addr16[1], ia->addr16[1], 0);
+ *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
+ oia.addr16[0], ia->addr16[0], 0),
+ oia.addr16[1], ia->addr16[1], 0);
+ *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0);
+ break;
+ }
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
+ pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
+ pf_cksum_fixup(pf_cksum_fixup(*ic,
+ oia.addr16[0], ia->addr16[0], u),
+ oia.addr16[1], ia->addr16[1], u),
+ oia.addr16[2], ia->addr16[2], u),
+ oia.addr16[3], ia->addr16[3], u),
+ oia.addr16[4], ia->addr16[4], u),
+ oia.addr16[5], ia->addr16[5], u),
+ oia.addr16[6], ia->addr16[6], u),
+ oia.addr16[7], ia->addr16[7], u);
+ break;
+#endif /* INET6 */
+ }
+ /* Outer ip address, fix outer ip or icmpv6 checksum, if necessary. */
+ if (oa) {
+ PF_ACPY(oa, na, af);
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ *hc = pf_cksum_fixup(pf_cksum_fixup(*hc,
+ ooa.addr16[0], oa->addr16[0], 0),
+ ooa.addr16[1], oa->addr16[1], 0);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
+ pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
+ pf_cksum_fixup(pf_cksum_fixup(*ic,
+ ooa.addr16[0], oa->addr16[0], u),
+ ooa.addr16[1], oa->addr16[1], u),
+ ooa.addr16[2], oa->addr16[2], u),
+ ooa.addr16[3], oa->addr16[3], u),
+ ooa.addr16[4], oa->addr16[4], u),
+ ooa.addr16[5], oa->addr16[5], u),
+ ooa.addr16[6], oa->addr16[6], u),
+ ooa.addr16[7], oa->addr16[7], u);
+ break;
+#endif /* INET6 */
+ }
+ }
+}
+
+
+/*
+ * Need to modulate the sequence numbers in the TCP SACK option
+ * (credits to Krzysztof Pfaff for report and patch)
+ */
+int
+pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd,
+ struct tcphdr *th, struct pf_state_peer *dst)
+{
+ int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen;
+#ifdef __FreeBSD__
+ u_int8_t opts[TCP_MAXOLEN], *opt = opts;
+#else
+ u_int8_t opts[MAX_TCPOPTLEN], *opt = opts;
+#endif
+ int copyback = 0, i, olen;
+ struct sackblk sack;
+
+#define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2)
+ if (hlen < TCPOLEN_SACKLEN ||
+ !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af))
+ return 0;
+
+ while (hlen >= TCPOLEN_SACKLEN) {
+ olen = opt[1];
+ switch (*opt) {
+ case TCPOPT_EOL: /* FALLTHROUGH */
+ case TCPOPT_NOP:
+ opt++;
+ hlen--;
+ break;
+ case TCPOPT_SACK:
+ if (olen > hlen)
+ olen = hlen;
+ if (olen >= TCPOLEN_SACKLEN) {
+ for (i = 2; i + TCPOLEN_SACK <= olen;
+ i += TCPOLEN_SACK) {
+ memcpy(&sack, &opt[i], sizeof(sack));
+ pf_change_a(&sack.start, &th->th_sum,
+ htonl(ntohl(sack.start) -
+ dst->seqdiff), 0);
+ pf_change_a(&sack.end, &th->th_sum,
+ htonl(ntohl(sack.end) -
+ dst->seqdiff), 0);
+ memcpy(&opt[i], &sack, sizeof(sack));
+ }
+ copyback = 1;
+ }
+ /* FALLTHROUGH */
+ default:
+ if (olen < 2)
+ olen = 2;
+ hlen -= olen;
+ opt += olen;
+ }
+ }
+
+ if (copyback)
+#ifdef __FreeBSD__
+ m_copyback(m, off + sizeof(*th), thoptlen, (caddr_t)opts);
+#else
+ m_copyback(m, off + sizeof(*th), thoptlen, opts);
+#endif
+ return (copyback);
+}
+
+void
+#ifdef __FreeBSD__
+pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af,
+#else
+pf_send_tcp(const struct pf_rule *r, sa_family_t af,
+#endif
+ const struct pf_addr *saddr, const struct pf_addr *daddr,
+ u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
+ u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
+ u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp)
+{
+ struct mbuf *m;
+ int len, tlen;
+#ifdef INET
+ struct ip *h;
+#endif /* INET */
+#ifdef INET6
+ struct ip6_hdr *h6;
+#endif /* INET6 */
+ struct tcphdr *th;
+ char *opt;
+#ifdef __FreeBSD__
+ struct pf_mtag *pf_mtag;
+
+ KASSERT(
+#ifdef INET
+ af == AF_INET
+#else
+ 0
+#endif
+ ||
+#ifdef INET6
+ af == AF_INET6
+#else
+ 0
+#endif
+ , ("Unsupported AF %d", af));
+ len = 0;
+ th = NULL;
+#ifdef INET
+ h = NULL;
+#endif
+#ifdef INET6
+ h6 = NULL;
+#endif
+#endif /* __FreeBSD__ */
+
+ /* maximum segment size tcp option */
+ tlen = sizeof(struct tcphdr);
+ if (mss)
+ tlen += 4;
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ len = sizeof(struct ip) + tlen;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ len = sizeof(struct ip6_hdr) + tlen;
+ break;
+#endif /* INET6 */
+ }
+
+ /* create outgoing mbuf */
+ m = m_gethdr(M_DONTWAIT, MT_HEADER);
+ if (m == NULL)
+ return;
+#ifdef __FreeBSD__
+#ifdef MAC
+ mac_netinet_firewall_send(m);
+#endif
+ if ((pf_mtag = pf_get_mtag(m)) == NULL) {
+ m_freem(m);
+ return;
+ }
+#endif
+ if (tag)
+#ifdef __FreeBSD__
+ m->m_flags |= M_SKIP_FIREWALL;
+ pf_mtag->tag = rtag;
+#else
+ m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
+ m->m_pkthdr.pf.tag = rtag;
+#endif
+
+ if (r != NULL && r->rtableid >= 0)
+#ifdef __FreeBSD__
+ {
+ M_SETFIB(m, r->rtableid);
+ pf_mtag->rtableid = r->rtableid;
+#else
+ m->m_pkthdr.pf.rtableid = r->rtableid;
+#endif
+#ifdef __FreeBSD__
+ }
+#endif
+
+#ifdef ALTQ
+ if (r != NULL && r->qid) {
+#ifdef __FreeBSD__
+ pf_mtag->qid = r->qid;
+
+ /* add hints for ecn */
+ pf_mtag->hdr = mtod(m, struct ip *);
+#else
+ m->m_pkthdr.pf.qid = r->qid;
+ /* add hints for ecn */
+ m->m_pkthdr.pf.hdr = mtod(m, struct ip *);
+#endif
+ }
+#endif /* ALTQ */
+ m->m_data += max_linkhdr;
+ m->m_pkthdr.len = m->m_len = len;
+ m->m_pkthdr.rcvif = NULL;
+ bzero(m->m_data, len);
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ h = mtod(m, struct ip *);
+
+ /* IP header fields included in the TCP checksum */
+ h->ip_p = IPPROTO_TCP;
+ h->ip_len = htons(tlen);
+ h->ip_src.s_addr = saddr->v4.s_addr;
+ h->ip_dst.s_addr = daddr->v4.s_addr;
+
+ th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip));
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ h6 = mtod(m, struct ip6_hdr *);
+
+ /* IP header fields included in the TCP checksum */
+ h6->ip6_nxt = IPPROTO_TCP;
+ h6->ip6_plen = htons(tlen);
+ memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr));
+ memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr));
+
+ th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr));
+ break;
+#endif /* INET6 */
+ }
+
+ /* TCP header */
+ th->th_sport = sport;
+ th->th_dport = dport;
+ th->th_seq = htonl(seq);
+ th->th_ack = htonl(ack);
+ th->th_off = tlen >> 2;
+ th->th_flags = flags;
+ th->th_win = htons(win);
+
+ if (mss) {
+ opt = (char *)(th + 1);
+ opt[0] = TCPOPT_MAXSEG;
+ opt[1] = 4;
+ HTONS(mss);
+ bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2);
+ }
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ /* TCP checksum */
+ th->th_sum = in_cksum(m, len);
+
+ /* Finish the IP header */
+ h->ip_v = 4;
+ h->ip_hl = sizeof(*h) >> 2;
+ h->ip_tos = IPTOS_LOWDELAY;
+#ifdef __FreeBSD__
+ h->ip_off = V_path_mtu_discovery ? IP_DF : 0;
+ h->ip_len = len;
+ h->ip_ttl = ttl ? ttl : V_ip_defttl;
+#else
+ h->ip_len = htons(len);
+ h->ip_off = htons(ip_mtudisc ? IP_DF : 0);
+ h->ip_ttl = ttl ? ttl : ip_defttl;
+#endif
+ h->ip_sum = 0;
+ if (eh == NULL) {
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+ ip_output(m, (void *)NULL, (void *)NULL, 0,
+ (void *)NULL, (void *)NULL);
+ PF_LOCK();
+#else /* ! __FreeBSD__ */
+ ip_output(m, (void *)NULL, (void *)NULL, 0,
+ (void *)NULL, (void *)NULL);
+#endif
+ } else {
+ struct route ro;
+ struct rtentry rt;
+ struct ether_header *e = (void *)ro.ro_dst.sa_data;
+
+ if (ifp == NULL) {
+ m_freem(m);
+ return;
+ }
+ rt.rt_ifp = ifp;
+ ro.ro_rt = &rt;
+ ro.ro_dst.sa_len = sizeof(ro.ro_dst);
+ ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT;
+ bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN);
+ bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN);
+ e->ether_type = eh->ether_type;
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+ /* XXX_IMPORT: later */
+ ip_output(m, (void *)NULL, &ro, 0,
+ (void *)NULL, (void *)NULL);
+ PF_LOCK();
+#else /* ! __FreeBSD__ */
+ ip_output(m, (void *)NULL, &ro, IP_ROUTETOETHER,
+ (void *)NULL, (void *)NULL);
+#endif
+ }
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ /* TCP checksum */
+ th->th_sum = in6_cksum(m, IPPROTO_TCP,
+ sizeof(struct ip6_hdr), tlen);
+
+ h6->ip6_vfc |= IPV6_VERSION;
+ h6->ip6_hlim = IPV6_DEFHLIM;
+
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+ ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
+ PF_LOCK();
+#else
+ ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
+#endif
+ break;
+#endif /* INET6 */
+ }
+}
+
+static void
+pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
+ struct pf_rule *r)
+{
+ struct mbuf *m0;
+#ifdef __FreeBSD__
+#ifdef INET
+ struct ip *ip;
+#endif
+ struct pf_mtag *pf_mtag;
+#endif
+
+#ifdef __FreeBSD__
+ m0 = m_copypacket(m, M_DONTWAIT);
+ if (m0 == NULL)
+ return;
+#else
+ if ((m0 = m_copy(m, 0, M_COPYALL)) == NULL)
+ return;
+#endif
+
+#ifdef __FreeBSD__
+ if ((pf_mtag = pf_get_mtag(m0)) == NULL)
+ return;
+ /* XXX: revisit */
+ m0->m_flags |= M_SKIP_FIREWALL;
+#else
+ m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
+#endif
+
+ if (r->rtableid >= 0)
+#ifdef __FreeBSD__
+ {
+ M_SETFIB(m0, r->rtableid);
+ pf_mtag->rtableid = r->rtableid;
+#else
+ m0->m_pkthdr.pf.rtableid = r->rtableid;
+#endif
+#ifdef __FreeBSD__
+ }
+#endif
+
+#ifdef ALTQ
+ if (r->qid) {
+#ifdef __FreeBSD__
+ pf_mtag->qid = r->qid;
+ /* add hints for ecn */
+ pf_mtag->hdr = mtod(m0, struct ip *);
+#else
+ m0->m_pkthdr.pf.qid = r->qid;
+ /* add hints for ecn */
+ m0->m_pkthdr.pf.hdr = mtod(m0, struct ip *);
+#endif
+ }
+#endif /* ALTQ */
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+#ifdef __FreeBSD__
+ /* icmp_error() expects host byte ordering */
+ ip = mtod(m0, struct ip *);
+ NTOHS(ip->ip_len);
+ NTOHS(ip->ip_off);
+ PF_UNLOCK();
+ icmp_error(m0, type, code, 0, 0);
+ PF_LOCK();
+#else
+ icmp_error(m0, type, code, 0, 0);
+#endif
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ icmp6_error(m0, type, code, 0);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ break;
+#endif /* INET6 */
+ }
+}
+
+/*
+ * Return 1 if the addresses a and b match (with mask m), otherwise return 0.
+ * If n is 0, they match if they are equal. If n is != 0, they match if they
+ * are different.
+ */
+int
+pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
+ struct pf_addr *b, sa_family_t af)
+{
+ int match = 0;
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ if ((a->addr32[0] & m->addr32[0]) ==
+ (b->addr32[0] & m->addr32[0]))
+ match++;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (((a->addr32[0] & m->addr32[0]) ==
+ (b->addr32[0] & m->addr32[0])) &&
+ ((a->addr32[1] & m->addr32[1]) ==
+ (b->addr32[1] & m->addr32[1])) &&
+ ((a->addr32[2] & m->addr32[2]) ==
+ (b->addr32[2] & m->addr32[2])) &&
+ ((a->addr32[3] & m->addr32[3]) ==
+ (b->addr32[3] & m->addr32[3])))
+ match++;
+ break;
+#endif /* INET6 */
+ }
+ if (match) {
+ if (n)
+ return (0);
+ else
+ return (1);
+ } else {
+ if (n)
+ return (1);
+ else
+ return (0);
+ }
+}
+
+/*
+ * Return 1 if b <= a <= e, otherwise return 0.
+ */
+int
+pf_match_addr_range(struct pf_addr *b, struct pf_addr *e,
+ struct pf_addr *a, sa_family_t af)
+{
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ if ((a->addr32[0] < b->addr32[0]) ||
+ (a->addr32[0] > e->addr32[0]))
+ return (0);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6: {
+ int i;
+
+ /* check a >= b */
+ for (i = 0; i < 4; ++i)
+ if (a->addr32[i] > b->addr32[i])
+ break;
+ else if (a->addr32[i] < b->addr32[i])
+ return (0);
+ /* check a <= e */
+ for (i = 0; i < 4; ++i)
+ if (a->addr32[i] < e->addr32[i])
+ break;
+ else if (a->addr32[i] > e->addr32[i])
+ return (0);
+ break;
+ }
+#endif /* INET6 */
+ }
+ return (1);
+}
+
+int
+pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
+{
+ switch (op) {
+ case PF_OP_IRG:
+ return ((p > a1) && (p < a2));
+ case PF_OP_XRG:
+ return ((p < a1) || (p > a2));
+ case PF_OP_RRG:
+ return ((p >= a1) && (p <= a2));
+ case PF_OP_EQ:
+ return (p == a1);
+ case PF_OP_NE:
+ return (p != a1);
+ case PF_OP_LT:
+ return (p < a1);
+ case PF_OP_LE:
+ return (p <= a1);
+ case PF_OP_GT:
+ return (p > a1);
+ case PF_OP_GE:
+ return (p >= a1);
+ }
+ return (0); /* never reached */
+}
+
+int
+pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
+{
+ NTOHS(a1);
+ NTOHS(a2);
+ NTOHS(p);
+ return (pf_match(op, a1, a2, p));
+}
+
+int
+pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
+{
+ if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
+ return (0);
+ return (pf_match(op, a1, a2, u));
+}
+
+int
+pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
+{
+ if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
+ return (0);
+ return (pf_match(op, a1, a2, g));
+}
+
+int
+#ifdef __FreeBSD__
+pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag,
+ struct pf_mtag *pf_mtag)
+#else
+pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag)
+#endif
+{
+ if (*tag == -1)
+#ifdef __FreeBSD__
+ *tag = pf_mtag->tag;
+#else
+ *tag = m->m_pkthdr.pf.tag;
+#endif
+
+ return ((!r->match_tag_not && r->match_tag == *tag) ||
+ (r->match_tag_not && r->match_tag != *tag));
+}
+
+int
+#ifdef __FreeBSD__
+pf_tag_packet(struct mbuf *m, int tag, int rtableid,
+ struct pf_mtag *pf_mtag)
+#else
+pf_tag_packet(struct mbuf *m, int tag, int rtableid)
+#endif
+{
+ if (tag <= 0 && rtableid < 0)
+ return (0);
+
+ if (tag > 0)
+#ifdef __FreeBSD__
+ pf_mtag->tag = tag;
+#else
+ m->m_pkthdr.pf.tag = tag;
+#endif
+ if (rtableid >= 0)
+#ifdef __FreeBSD__
+ {
+ M_SETFIB(m, rtableid);
+ }
+#else
+ m->m_pkthdr.pf.rtableid = rtableid;
+#endif
+
+ return (0);
+}
+
+void
+pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n,
+ struct pf_rule **r, struct pf_rule **a, int *match)
+{
+ struct pf_anchor_stackframe *f;
+
+ (*r)->anchor->match = 0;
+ if (match)
+ *match = 0;
+#ifdef __FreeBSD__
+ if (*depth >= sizeof(V_pf_anchor_stack) /
+ sizeof(V_pf_anchor_stack[0])) {
+#else
+ if (*depth >= sizeof(pf_anchor_stack) /
+ sizeof(pf_anchor_stack[0])) {
+#endif
+ printf("pf_step_into_anchor: stack overflow\n");
+ *r = TAILQ_NEXT(*r, entries);
+ return;
+ } else if (*depth == 0 && a != NULL)
+ *a = *r;
+#ifdef __FreeBSD__
+ f = V_pf_anchor_stack + (*depth)++;
+#else
+ f = pf_anchor_stack + (*depth)++;
+#endif
+ f->rs = *rs;
+ f->r = *r;
+ if ((*r)->anchor_wildcard) {
+ f->parent = &(*r)->anchor->children;
+ if ((f->child = RB_MIN(pf_anchor_node, f->parent)) ==
+ NULL) {
+ *r = NULL;
+ return;
+ }
+ *rs = &f->child->ruleset;
+ } else {
+ f->parent = NULL;
+ f->child = NULL;
+ *rs = &(*r)->anchor->ruleset;
+ }
+ *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
+}
+
+int
+pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n,
+ struct pf_rule **r, struct pf_rule **a, int *match)
+{
+ struct pf_anchor_stackframe *f;
+ int quick = 0;
+
+ do {
+ if (*depth <= 0)
+ break;
+#ifdef __FreeBSD__
+ f = V_pf_anchor_stack + *depth - 1;
+#else
+ f = pf_anchor_stack + *depth - 1;
+#endif
+ if (f->parent != NULL && f->child != NULL) {
+ if (f->child->match ||
+ (match != NULL && *match)) {
+ f->r->anchor->match = 1;
+ *match = 0;
+ }
+ f->child = RB_NEXT(pf_anchor_node, f->parent, f->child);
+ if (f->child != NULL) {
+ *rs = &f->child->ruleset;
+ *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
+ if (*r == NULL)
+ continue;
+ else
+ break;
+ }
+ }
+ (*depth)--;
+ if (*depth == 0 && a != NULL)
+ *a = NULL;
+ *rs = f->rs;
+ if (f->r->anchor->match || (match != NULL && *match))
+ quick = f->r->quick;
+ *r = TAILQ_NEXT(f->r, entries);
+ } while (*r == NULL);
+
+ return (quick);
+}
+
+#ifdef INET6
+void
+pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
+ struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
+{
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
+ ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
+ break;
+#endif /* INET */
+ case AF_INET6:
+ naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
+ ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
+ naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) |
+ ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]);
+ naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) |
+ ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]);
+ naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) |
+ ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]);
+ break;
+ }
+}
+
+void
+pf_addr_inc(struct pf_addr *addr, sa_family_t af)
+{
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1);
+ break;
+#endif /* INET */
+ case AF_INET6:
+ if (addr->addr32[3] == 0xffffffff) {
+ addr->addr32[3] = 0;
+ if (addr->addr32[2] == 0xffffffff) {
+ addr->addr32[2] = 0;
+ if (addr->addr32[1] == 0xffffffff) {
+ addr->addr32[1] = 0;
+ addr->addr32[0] =
+ htonl(ntohl(addr->addr32[0]) + 1);
+ } else
+ addr->addr32[1] =
+ htonl(ntohl(addr->addr32[1]) + 1);
+ } else
+ addr->addr32[2] =
+ htonl(ntohl(addr->addr32[2]) + 1);
+ } else
+ addr->addr32[3] =
+ htonl(ntohl(addr->addr32[3]) + 1);
+ break;
+ }
+}
+#endif /* INET6 */
+
+int
+#ifdef __FreeBSD__
+pf_socket_lookup(int direction, struct pf_pdesc *pd, struct inpcb *inp_arg)
+#else
+pf_socket_lookup(int direction, struct pf_pdesc *pd)
+#endif
+{
+ struct pf_addr *saddr, *daddr;
+ u_int16_t sport, dport;
+#ifdef __FreeBSD__
+ struct inpcbinfo *pi;
+#else
+ struct inpcbtable *tb;
+#endif
+ struct inpcb *inp;
+
+ if (pd == NULL)
+ return (-1);
+ pd->lookup.uid = UID_MAX;
+ pd->lookup.gid = GID_MAX;
+ pd->lookup.pid = NO_PID;
+
+#ifdef __FreeBSD__
+ if (inp_arg != NULL) {
+ INP_LOCK_ASSERT(inp_arg);
+ pd->lookup.uid = inp_arg->inp_cred->cr_uid;
+ pd->lookup.gid = inp_arg->inp_cred->cr_groups[0];
+ return (1);
+ }
+#endif
+
+ switch (pd->proto) {
+ case IPPROTO_TCP:
+ if (pd->hdr.tcp == NULL)
+ return (-1);
+ sport = pd->hdr.tcp->th_sport;
+ dport = pd->hdr.tcp->th_dport;
+#ifdef __FreeBSD__
+ pi = &V_tcbinfo;
+#else
+ tb = &tcbtable;
+#endif
+ break;
+ case IPPROTO_UDP:
+ if (pd->hdr.udp == NULL)
+ return (-1);
+ sport = pd->hdr.udp->uh_sport;
+ dport = pd->hdr.udp->uh_dport;
+#ifdef __FreeBSD__
+ pi = &V_udbinfo;
+#else
+ tb = &udbtable;
+#endif
+ break;
+ default:
+ return (-1);
+ }
+ if (direction == PF_IN) {
+ saddr = pd->src;
+ daddr = pd->dst;
+ } else {
+ u_int16_t p;
+
+ p = sport;
+ sport = dport;
+ dport = p;
+ saddr = pd->dst;
+ daddr = pd->src;
+ }
+ switch (pd->af) {
+#ifdef INET
+ case AF_INET:
+#ifdef __FreeBSD__
+ /*
+ * XXXRW: would be nice if we had an mbuf here so that we
+ * could use in_pcblookup_mbuf().
+ */
+ inp = in_pcblookup(pi, saddr->v4, sport, daddr->v4,
+ dport, INPLOOKUP_RLOCKPCB, NULL);
+ if (inp == NULL) {
+ inp = in_pcblookup(pi, saddr->v4, sport,
+ daddr->v4, dport, INPLOOKUP_WILDCARD |
+ INPLOOKUP_RLOCKPCB, NULL);
+ if (inp == NULL)
+ return (-1);
+ }
+#else
+ inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport);
+ if (inp == NULL) {
+ inp = in_pcblookup_listen(tb, daddr->v4, dport, 0,
+ NULL);
+ if (inp == NULL)
+ return (-1);
+ }
+#endif
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+#ifdef __FreeBSD__
+ /*
+ * XXXRW: would be nice if we had an mbuf here so that we
+ * could use in6_pcblookup_mbuf().
+ */
+ inp = in6_pcblookup(pi, &saddr->v6, sport,
+ &daddr->v6, dport, INPLOOKUP_RLOCKPCB, NULL);
+ if (inp == NULL) {
+ inp = in6_pcblookup(pi, &saddr->v6, sport,
+ &daddr->v6, dport, INPLOOKUP_WILDCARD |
+ INPLOOKUP_RLOCKPCB, NULL);
+ if (inp == NULL)
+ return (-1);
+ }
+#else
+ inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
+ dport);
+ if (inp == NULL) {
+ inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0,
+ NULL);
+ if (inp == NULL)
+ return (-1);
+ }
+#endif
+ break;
+#endif /* INET6 */
+
+ default:
+ return (-1);
+ }
+#ifdef __FreeBSD__
+ INP_RLOCK_ASSERT(inp);
+ pd->lookup.uid = inp->inp_cred->cr_uid;
+ pd->lookup.gid = inp->inp_cred->cr_groups[0];
+ INP_RUNLOCK(inp);
+#else
+ pd->lookup.uid = inp->inp_socket->so_euid;
+ pd->lookup.gid = inp->inp_socket->so_egid;
+ pd->lookup.pid = inp->inp_socket->so_cpid;
+#endif
+ return (1);
+}
+
+u_int8_t
+pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
+{
+ int hlen;
+ u_int8_t hdr[60];
+ u_int8_t *opt, optlen;
+ u_int8_t wscale = 0;
+
+ hlen = th_off << 2; /* hlen <= sizeof(hdr) */
+ if (hlen <= sizeof(struct tcphdr))
+ return (0);
+ if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
+ return (0);
+ opt = hdr + sizeof(struct tcphdr);
+ hlen -= sizeof(struct tcphdr);
+ while (hlen >= 3) {
+ switch (*opt) {
+ case TCPOPT_EOL:
+ case TCPOPT_NOP:
+ ++opt;
+ --hlen;
+ break;
+ case TCPOPT_WINDOW:
+ wscale = opt[2];
+ if (wscale > TCP_MAX_WINSHIFT)
+ wscale = TCP_MAX_WINSHIFT;
+ wscale |= PF_WSCALE_FLAG;
+ /* FALLTHROUGH */
+ default:
+ optlen = opt[1];
+ if (optlen < 2)
+ optlen = 2;
+ hlen -= optlen;
+ opt += optlen;
+ break;
+ }
+ }
+ return (wscale);
+}
+
+u_int16_t
+pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
+{
+ int hlen;
+ u_int8_t hdr[60];
+ u_int8_t *opt, optlen;
+#ifdef __FreeBSD__
+ u_int16_t mss = V_tcp_mssdflt;
+#else
+ u_int16_t mss = tcp_mssdflt;
+#endif
+
+ hlen = th_off << 2; /* hlen <= sizeof(hdr) */
+ if (hlen <= sizeof(struct tcphdr))
+ return (0);
+ if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
+ return (0);
+ opt = hdr + sizeof(struct tcphdr);
+ hlen -= sizeof(struct tcphdr);
+ while (hlen >= TCPOLEN_MAXSEG) {
+ switch (*opt) {
+ case TCPOPT_EOL:
+ case TCPOPT_NOP:
+ ++opt;
+ --hlen;
+ break;
+ case TCPOPT_MAXSEG:
+ bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2);
+ NTOHS(mss);
+ /* FALLTHROUGH */
+ default:
+ optlen = opt[1];
+ if (optlen < 2)
+ optlen = 2;
+ hlen -= optlen;
+ opt += optlen;
+ break;
+ }
+ }
+ return (mss);
+}
+
+u_int16_t
+pf_calc_mss(struct pf_addr *addr, sa_family_t af, int rtableid, u_int16_t offer)
+{
+#ifdef INET
+ struct sockaddr_in *dst;
+ struct route ro;
+#endif /* INET */
+#ifdef INET6
+ struct sockaddr_in6 *dst6;
+ struct route_in6 ro6;
+#endif /* INET6 */
+ struct rtentry *rt = NULL;
+#ifdef __FreeBSD__
+ int hlen = 0;
+ u_int16_t mss = V_tcp_mssdflt;
+#else
+ int hlen;
+ u_int16_t mss = tcp_mssdflt;
+#endif
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ hlen = sizeof(struct ip);
+ bzero(&ro, sizeof(ro));
+ dst = (struct sockaddr_in *)&ro.ro_dst;
+ dst->sin_family = AF_INET;
+ dst->sin_len = sizeof(*dst);
+ dst->sin_addr = addr->v4;
+#ifdef __FreeBSD__
+ in_rtalloc_ign(&ro, 0, rtableid);
+#else /* ! __FreeBSD__ */
+ rtalloc_noclone(&ro, NO_CLONING);
+#endif
+ rt = ro.ro_rt;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ hlen = sizeof(struct ip6_hdr);
+ bzero(&ro6, sizeof(ro6));
+ dst6 = (struct sockaddr_in6 *)&ro6.ro_dst;
+ dst6->sin6_family = AF_INET6;
+ dst6->sin6_len = sizeof(*dst6);
+ dst6->sin6_addr = addr->v6;
+#ifdef __FreeBSD__
+ in6_rtalloc_ign(&ro6, 0, rtableid);
+#else /* ! __FreeBSD__ */
+ rtalloc_noclone((struct route *)&ro6, NO_CLONING);
+#endif
+ rt = ro6.ro_rt;
+ break;
+#endif /* INET6 */
+ }
+
+ if (rt && rt->rt_ifp) {
+ mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
+#ifdef __FreeBSD__
+ mss = max(V_tcp_mssdflt, mss);
+#else
+ mss = max(tcp_mssdflt, mss);
+#endif
+ RTFREE(rt);
+ }
+ mss = min(mss, offer);
+ mss = max(mss, 64); /* sanity - at least max opt space */
+ return (mss);
+}
+
+void
+pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
+{
+ struct pf_rule *r = s->rule.ptr;
+ struct pf_src_node *sn = NULL;
+
+ s->rt_kif = NULL;
+ if (!r->rt || r->rt == PF_FASTROUTE)
+ return;
+ switch (s->key[PF_SK_WIRE]->af) {
+#ifdef INET
+ case AF_INET:
+ pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, &sn);
+ s->rt_kif = r->rpool.cur->kif;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, &sn);
+ s->rt_kif = r->rpool.cur->kif;
+ break;
+#endif /* INET6 */
+ }
+}
+
+u_int32_t
+pf_tcp_iss(struct pf_pdesc *pd)
+{
+ MD5_CTX ctx;
+ u_int32_t digest[4];
+
+#ifdef __FreeBSD__
+ if (V_pf_tcp_secret_init == 0) {
+ read_random(&V_pf_tcp_secret, sizeof(V_pf_tcp_secret));
+ MD5Init(&V_pf_tcp_secret_ctx);
+ MD5Update(&V_pf_tcp_secret_ctx, V_pf_tcp_secret,
+ sizeof(V_pf_tcp_secret));
+ V_pf_tcp_secret_init = 1;
+ }
+
+ ctx = V_pf_tcp_secret_ctx;
+#else
+ if (pf_tcp_secret_init == 0) {
+ arc4random_buf(pf_tcp_secret, sizeof(pf_tcp_secret));
+ MD5Init(&pf_tcp_secret_ctx);
+ MD5Update(&pf_tcp_secret_ctx, pf_tcp_secret,
+ sizeof(pf_tcp_secret));
+ pf_tcp_secret_init = 1;
+ }
+
+ ctx = pf_tcp_secret_ctx;
+#endif
+
+ MD5Update(&ctx, (char *)&pd->hdr.tcp->th_sport, sizeof(u_short));
+ MD5Update(&ctx, (char *)&pd->hdr.tcp->th_dport, sizeof(u_short));
+ if (pd->af == AF_INET6) {
+ MD5Update(&ctx, (char *)&pd->src->v6, sizeof(struct in6_addr));
+ MD5Update(&ctx, (char *)&pd->dst->v6, sizeof(struct in6_addr));
+ } else {
+ MD5Update(&ctx, (char *)&pd->src->v4, sizeof(struct in_addr));
+ MD5Update(&ctx, (char *)&pd->dst->v4, sizeof(struct in_addr));
+ }
+ MD5Final((u_char *)digest, &ctx);
+#ifdef __FreeBSD__
+ V_pf_tcp_iss_off += 4096;
+#define ISN_RANDOM_INCREMENT (4096 - 1)
+ return (digest[0] + (arc4random() & ISN_RANDOM_INCREMENT) +
+ V_pf_tcp_iss_off);
+#undef ISN_RANDOM_INCREMENT
+#else
+ pf_tcp_iss_off += 4096;
+ return (digest[0] + tcp_iss + pf_tcp_iss_off);
+#endif
+}
+
+int
+pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
+ struct pfi_kif *kif, struct mbuf *m, int off, void *h,
+ struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
+#ifdef __FreeBSD__
+ struct ifqueue *ifq, struct inpcb *inp)
+#else
+ struct ifqueue *ifq)
+#endif
+{
+ struct pf_rule *nr = NULL;
+ struct pf_addr *saddr = pd->src, *daddr = pd->dst;
+ sa_family_t af = pd->af;
+ struct pf_rule *r, *a = NULL;
+ struct pf_ruleset *ruleset = NULL;
+ struct pf_src_node *nsn = NULL;
+ struct tcphdr *th = pd->hdr.tcp;
+ struct pf_state_key *skw = NULL, *sks = NULL;
+ struct pf_state_key *sk = NULL, *nk = NULL;
+ u_short reason;
+ int rewrite = 0, hdrlen = 0;
+ int tag = -1, rtableid = -1;
+ int asd = 0;
+ int match = 0;
+ int state_icmp = 0;
+#ifdef __FreeBSD__
+ u_int16_t sport = 0, dport = 0;
+ u_int16_t bproto_sum = 0, bip_sum = 0;
+#else
+ u_int16_t sport, dport;
+ u_int16_t bproto_sum = 0, bip_sum;
+#endif
+ u_int8_t icmptype = 0, icmpcode = 0;
+
+
+ if (direction == PF_IN && pf_check_congestion(ifq)) {
+ REASON_SET(&reason, PFRES_CONGEST);
+ return (PF_DROP);
+ }
+
+#ifdef __FreeBSD__
+ if (inp != NULL)
+ pd->lookup.done = pf_socket_lookup(direction, pd, inp);
+ else if (V_debug_pfugidhack) {
+ PF_UNLOCK();
+ DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n"));
+ pd->lookup.done = pf_socket_lookup(direction, pd, inp);
+ PF_LOCK();
+ }
+#endif
+
+ switch (pd->proto) {
+ case IPPROTO_TCP:
+ sport = th->th_sport;
+ dport = th->th_dport;
+ hdrlen = sizeof(*th);
+ break;
+ case IPPROTO_UDP:
+ sport = pd->hdr.udp->uh_sport;
+ dport = pd->hdr.udp->uh_dport;
+ hdrlen = sizeof(*pd->hdr.udp);
+ break;
+#ifdef INET
+ case IPPROTO_ICMP:
+ if (pd->af != AF_INET)
+ break;
+ sport = dport = pd->hdr.icmp->icmp_id;
+ hdrlen = sizeof(*pd->hdr.icmp);
+ icmptype = pd->hdr.icmp->icmp_type;
+ icmpcode = pd->hdr.icmp->icmp_code;
+
+ if (icmptype == ICMP_UNREACH ||
+ icmptype == ICMP_SOURCEQUENCH ||
+ icmptype == ICMP_REDIRECT ||
+ icmptype == ICMP_TIMXCEED ||
+ icmptype == ICMP_PARAMPROB)
+ state_icmp++;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case IPPROTO_ICMPV6:
+ if (af != AF_INET6)
+ break;
+ sport = dport = pd->hdr.icmp6->icmp6_id;
+ hdrlen = sizeof(*pd->hdr.icmp6);
+ icmptype = pd->hdr.icmp6->icmp6_type;
+ icmpcode = pd->hdr.icmp6->icmp6_code;
+
+ if (icmptype == ICMP6_DST_UNREACH ||
+ icmptype == ICMP6_PACKET_TOO_BIG ||
+ icmptype == ICMP6_TIME_EXCEEDED ||
+ icmptype == ICMP6_PARAM_PROB)
+ state_icmp++;
+ break;
+#endif /* INET6 */
+ default:
+ sport = dport = hdrlen = 0;
+ break;
+ }
+
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
+
+ /* check packet for BINAT/NAT/RDR */
+ if ((nr = pf_get_translation(pd, m, off, direction, kif, &nsn,
+ &skw, &sks, &sk, &nk, saddr, daddr, sport, dport)) != NULL) {
+ if (nk == NULL || sk == NULL) {
+ REASON_SET(&reason, PFRES_MEMORY);
+ goto cleanup;
+ }
+
+ if (pd->ip_sum)
+ bip_sum = *pd->ip_sum;
+
+ switch (pd->proto) {
+ case IPPROTO_TCP:
+ bproto_sum = th->th_sum;
+ pd->proto_sum = &th->th_sum;
+
+ if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) ||
+ nk->port[pd->sidx] != sport) {
+ pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
+ &th->th_sum, &nk->addr[pd->sidx],
+ nk->port[pd->sidx], 0, af);
+ pd->sport = &th->th_sport;
+ sport = th->th_sport;
+ }
+
+ if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) ||
+ nk->port[pd->didx] != dport) {
+ pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
+ &th->th_sum, &nk->addr[pd->didx],
+ nk->port[pd->didx], 0, af);
+ dport = th->th_dport;
+ pd->dport = &th->th_dport;
+ }
+ rewrite++;
+ break;
+ case IPPROTO_UDP:
+ bproto_sum = pd->hdr.udp->uh_sum;
+ pd->proto_sum = &pd->hdr.udp->uh_sum;
+
+ if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) ||
+ nk->port[pd->sidx] != sport) {
+ pf_change_ap(saddr, &pd->hdr.udp->uh_sport,
+ pd->ip_sum, &pd->hdr.udp->uh_sum,
+ &nk->addr[pd->sidx],
+ nk->port[pd->sidx], 1, af);
+ sport = pd->hdr.udp->uh_sport;
+ pd->sport = &pd->hdr.udp->uh_sport;
+ }
+
+ if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) ||
+ nk->port[pd->didx] != dport) {
+ pf_change_ap(daddr, &pd->hdr.udp->uh_dport,
+ pd->ip_sum, &pd->hdr.udp->uh_sum,
+ &nk->addr[pd->didx],
+ nk->port[pd->didx], 1, af);
+ dport = pd->hdr.udp->uh_dport;
+ pd->dport = &pd->hdr.udp->uh_dport;
+ }
+ rewrite++;
+ break;
+#ifdef INET
+ case IPPROTO_ICMP:
+ nk->port[0] = nk->port[1];
+ if (PF_ANEQ(saddr, &nk->addr[pd->sidx], AF_INET))
+ pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
+ nk->addr[pd->sidx].v4.s_addr, 0);
+
+ if (PF_ANEQ(daddr, &nk->addr[pd->didx], AF_INET))
+ pf_change_a(&daddr->v4.s_addr, pd->ip_sum,
+ nk->addr[pd->didx].v4.s_addr, 0);
+
+ if (nk->port[1] != pd->hdr.icmp->icmp_id) {
+ pd->hdr.icmp->icmp_cksum = pf_cksum_fixup(
+ pd->hdr.icmp->icmp_cksum, sport,
+ nk->port[1], 0);
+ pd->hdr.icmp->icmp_id = nk->port[1];
+ pd->sport = &pd->hdr.icmp->icmp_id;
+ }
+ m_copyback(m, off, ICMP_MINLEN, (caddr_t)pd->hdr.icmp);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case IPPROTO_ICMPV6:
+ nk->port[0] = nk->port[1];
+ if (PF_ANEQ(saddr, &nk->addr[pd->sidx], AF_INET6))
+ pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum,
+ &nk->addr[pd->sidx], 0);
+
+ if (PF_ANEQ(daddr, &nk->addr[pd->didx], AF_INET6))
+ pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum,
+ &nk->addr[pd->didx], 0);
+ rewrite++;
+ break;
+#endif /* INET */
+ default:
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ if (PF_ANEQ(saddr,
+ &nk->addr[pd->sidx], AF_INET))
+ pf_change_a(&saddr->v4.s_addr,
+ pd->ip_sum,
+ nk->addr[pd->sidx].v4.s_addr, 0);
+
+ if (PF_ANEQ(daddr,
+ &nk->addr[pd->didx], AF_INET))
+ pf_change_a(&daddr->v4.s_addr,
+ pd->ip_sum,
+ nk->addr[pd->didx].v4.s_addr, 0);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (PF_ANEQ(saddr,
+ &nk->addr[pd->sidx], AF_INET6))
+ PF_ACPY(saddr, &nk->addr[pd->sidx], af);
+
+ if (PF_ANEQ(daddr,
+ &nk->addr[pd->didx], AF_INET6))
+ PF_ACPY(saddr, &nk->addr[pd->didx], af);
+ break;
+#endif /* INET */
+ }
+ break;
+ }
+ if (nr->natpass)
+ r = NULL;
+ pd->nat_rule = nr;
+ }
+
+ while (r != NULL) {
+ r->evaluations++;
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
+ r = r->skip[PF_SKIP_IFP].ptr;
+ else if (r->direction && r->direction != direction)
+ r = r->skip[PF_SKIP_DIR].ptr;
+ else if (r->af && r->af != af)
+ r = r->skip[PF_SKIP_AF].ptr;
+ else if (r->proto && r->proto != pd->proto)
+ r = r->skip[PF_SKIP_PROTO].ptr;
+ else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
+ r->src.neg, kif, M_GETFIB(m)))
+ r = r->skip[PF_SKIP_SRC_ADDR].ptr;
+ /* tcp/udp only. port_op always 0 in other cases */
+ else if (r->src.port_op && !pf_match_port(r->src.port_op,
+ r->src.port[0], r->src.port[1], sport))
+ r = r->skip[PF_SKIP_SRC_PORT].ptr;
+ else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
+ r->dst.neg, NULL, M_GETFIB(m)))
+ r = r->skip[PF_SKIP_DST_ADDR].ptr;
+ /* tcp/udp only. port_op always 0 in other cases */
+ else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
+ r->dst.port[0], r->dst.port[1], dport))
+ r = r->skip[PF_SKIP_DST_PORT].ptr;
+ /* icmp only. type always 0 in other cases */
+ else if (r->type && r->type != icmptype + 1)
+ r = TAILQ_NEXT(r, entries);
+ /* icmp only. type always 0 in other cases */
+ else if (r->code && r->code != icmpcode + 1)
+ r = TAILQ_NEXT(r, entries);
+ else if (r->tos && !(r->tos == pd->tos))
+ r = TAILQ_NEXT(r, entries);
+ else if (r->rule_flag & PFRULE_FRAGMENT)
+ r = TAILQ_NEXT(r, entries);
+ else if (pd->proto == IPPROTO_TCP &&
+ (r->flagset & th->th_flags) != r->flags)
+ r = TAILQ_NEXT(r, entries);
+ /* tcp/udp only. uid.op always 0 in other cases */
+ else if (r->uid.op && (pd->lookup.done || (pd->lookup.done =
+#ifdef __FreeBSD__
+ pf_socket_lookup(direction, pd, inp), 1)) &&
+#else
+ pf_socket_lookup(direction, pd), 1)) &&
+#endif
+ !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
+ pd->lookup.uid))
+ r = TAILQ_NEXT(r, entries);
+ /* tcp/udp only. gid.op always 0 in other cases */
+ else if (r->gid.op && (pd->lookup.done || (pd->lookup.done =
+#ifdef __FreeBSD__
+ pf_socket_lookup(direction, pd, inp), 1)) &&
+#else
+ pf_socket_lookup(direction, pd), 1)) &&
+#endif
+ !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
+ pd->lookup.gid))
+ r = TAILQ_NEXT(r, entries);
+ else if (r->prob &&
+#ifdef __FreeBSD__
+ r->prob <= arc4random())
+#else
+ r->prob <= arc4random_uniform(UINT_MAX - 1) + 1)
+#endif
+ r = TAILQ_NEXT(r, entries);
+#ifdef __FreeBSD__
+ else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
+#else
+ else if (r->match_tag && !pf_match_tag(m, r, &tag))
+#endif
+ r = TAILQ_NEXT(r, entries);
+ else if (r->os_fingerprint != PF_OSFP_ANY &&
+ (pd->proto != IPPROTO_TCP || !pf_osfp_match(
+ pf_osfp_fingerprint(pd, m, off, th),
+ r->os_fingerprint)))
+ r = TAILQ_NEXT(r, entries);
+ else {
+ if (r->tag)
+ tag = r->tag;
+ if (r->rtableid >= 0)
+ rtableid = r->rtableid;
+ if (r->anchor == NULL) {
+ match = 1;
+ *rm = r;
+ *am = a;
+ *rsm = ruleset;
+ if ((*rm)->quick)
+ break;
+ r = TAILQ_NEXT(r, entries);
+ } else
+ pf_step_into_anchor(&asd, &ruleset,
+ PF_RULESET_FILTER, &r, &a, &match);
+ }
+ if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
+ PF_RULESET_FILTER, &r, &a, &match))
+ break;
+ }
+ r = *rm;
+ a = *am;
+ ruleset = *rsm;
+
+ REASON_SET(&reason, PFRES_MATCH);
+
+ if (r->log || (nr != NULL && nr->log)) {
+ if (rewrite)
+ m_copyback(m, off, hdrlen, pd->hdr.any);
+ PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr,
+ a, ruleset, pd);
+ }
+
+ if ((r->action == PF_DROP) &&
+ ((r->rule_flag & PFRULE_RETURNRST) ||
+ (r->rule_flag & PFRULE_RETURNICMP) ||
+ (r->rule_flag & PFRULE_RETURN))) {
+ /* undo NAT changes, if they have taken place */
+ if (nr != NULL) {
+ PF_ACPY(saddr, &sk->addr[pd->sidx], af);
+ PF_ACPY(daddr, &sk->addr[pd->didx], af);
+ if (pd->sport)
+ *pd->sport = sk->port[pd->sidx];
+ if (pd->dport)
+ *pd->dport = sk->port[pd->didx];
+ if (pd->proto_sum)
+ *pd->proto_sum = bproto_sum;
+ if (pd->ip_sum)
+ *pd->ip_sum = bip_sum;
+ m_copyback(m, off, hdrlen, pd->hdr.any);
+ }
+ if (pd->proto == IPPROTO_TCP &&
+ ((r->rule_flag & PFRULE_RETURNRST) ||
+ (r->rule_flag & PFRULE_RETURN)) &&
+ !(th->th_flags & TH_RST)) {
+ u_int32_t ack = ntohl(th->th_seq) + pd->p_len;
+ int len = 0;
+#ifdef INET
+ struct ip *h4;
+#endif
+#ifdef INET6
+ struct ip6_hdr *h6;
+#endif
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ h4 = mtod(m, struct ip *);
+ len = ntohs(h4->ip_len) - off;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ h6 = mtod(m, struct ip6_hdr *);
+ len = ntohs(h6->ip6_plen) - (off - sizeof(*h6));
+ break;
+#endif
+ }
+
+ if (pf_check_proto_cksum(m, off, len, IPPROTO_TCP, af))
+ REASON_SET(&reason, PFRES_PROTCKSUM);
+ else {
+ if (th->th_flags & TH_SYN)
+ ack++;
+ if (th->th_flags & TH_FIN)
+ ack++;
+#ifdef __FreeBSD__
+ pf_send_tcp(m, r, af, pd->dst,
+#else
+ pf_send_tcp(r, af, pd->dst,
+#endif
+ pd->src, th->th_dport, th->th_sport,
+ ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
+ r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp);
+ }
+ } else if (pd->proto != IPPROTO_ICMP && af == AF_INET &&
+ r->return_icmp)
+ pf_send_icmp(m, r->return_icmp >> 8,
+ r->return_icmp & 255, af, r);
+ else if (pd->proto != IPPROTO_ICMPV6 && af == AF_INET6 &&
+ r->return_icmp6)
+ pf_send_icmp(m, r->return_icmp6 >> 8,
+ r->return_icmp6 & 255, af, r);
+ }
+
+ if (r->action == PF_DROP)
+ goto cleanup;
+
+#ifdef __FreeBSD__
+ if (pf_tag_packet(m, tag, rtableid, pd->pf_mtag)) {
+#else
+ if (pf_tag_packet(m, tag, rtableid)) {
+#endif
+ REASON_SET(&reason, PFRES_MEMORY);
+ goto cleanup;
+ }
+
+ if (!state_icmp && (r->keep_state || nr != NULL ||
+ (pd->flags & PFDESC_TCP_NORM))) {
+ int action;
+ action = pf_create_state(r, nr, a, pd, nsn, skw, sks, nk, sk, m,
+ off, sport, dport, &rewrite, kif, sm, tag, bproto_sum,
+ bip_sum, hdrlen);
+ if (action != PF_PASS)
+ return (action);
+ } else {
+#ifdef __FreeBSD__
+ if (sk != NULL)
+ pool_put(&V_pf_state_key_pl, sk);
+ if (nk != NULL)
+ pool_put(&V_pf_state_key_pl, nk);
+#else
+ if (sk != NULL)
+ pool_put(&pf_state_key_pl, sk);
+ if (nk != NULL)
+ pool_put(&pf_state_key_pl, nk);
+#endif
+ }
+
+ /* copy back packet headers if we performed NAT operations */
+ if (rewrite)
+ m_copyback(m, off, hdrlen, pd->hdr.any);
+
+#if NPFSYNC > 0
+ if (*sm != NULL && !ISSET((*sm)->state_flags, PFSTATE_NOSYNC) &&
+#ifdef __FreeBSD__
+ direction == PF_OUT && pfsync_up_ptr != NULL && pfsync_up_ptr()) {
+#else
+ direction == PF_OUT && pfsync_up()) {
+#endif
+ /*
+ * We want the state created, but we dont
+ * want to send this in case a partner
+ * firewall has to know about it to allow
+ * replies through it.
+ */
+#ifdef __FreeBSD__
+ if (pfsync_defer_ptr != NULL &&
+ pfsync_defer_ptr(*sm, m))
+#else
+ if (pfsync_defer(*sm, m))
+#endif
+ return (PF_DEFER);
+ }
+#endif
+
+ return (PF_PASS);
+
+cleanup:
+#ifdef __FreeBSD__
+ if (sk != NULL)
+ pool_put(&V_pf_state_key_pl, sk);
+ if (nk != NULL)
+ pool_put(&V_pf_state_key_pl, nk);
+#else
+ if (sk != NULL)
+ pool_put(&pf_state_key_pl, sk);
+ if (nk != NULL)
+ pool_put(&pf_state_key_pl, nk);
+#endif
+ return (PF_DROP);
+}
+
+static __inline int
+pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
+ struct pf_pdesc *pd, struct pf_src_node *nsn, struct pf_state_key *skw,
+ struct pf_state_key *sks, struct pf_state_key *nk, struct pf_state_key *sk,
+ struct mbuf *m, int off, u_int16_t sport, u_int16_t dport, int *rewrite,
+ struct pfi_kif *kif, struct pf_state **sm, int tag, u_int16_t bproto_sum,
+ u_int16_t bip_sum, int hdrlen)
+{
+ struct pf_state *s = NULL;
+ struct pf_src_node *sn = NULL;
+ struct tcphdr *th = pd->hdr.tcp;
+#ifdef __FreeBSD__
+ u_int16_t mss = V_tcp_mssdflt;
+#else
+ u_int16_t mss = tcp_mssdflt;
+#endif
+ u_short reason;
+
+ /* check maximums */
+ if (r->max_states && (r->states_cur >= r->max_states)) {
+#ifdef __FreeBSD__
+ V_pf_status.lcounters[LCNT_STATES]++;
+#else
+ pf_status.lcounters[LCNT_STATES]++;
+#endif
+ REASON_SET(&reason, PFRES_MAXSTATES);
+ return (PF_DROP);
+ }
+ /* src node for filter rule */
+ if ((r->rule_flag & PFRULE_SRCTRACK ||
+ r->rpool.opts & PF_POOL_STICKYADDR) &&
+ pf_insert_src_node(&sn, r, pd->src, pd->af) != 0) {
+ REASON_SET(&reason, PFRES_SRCLIMIT);
+ goto csfailed;
+ }
+ /* src node for translation rule */
+ if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
+ pf_insert_src_node(&nsn, nr, &sk->addr[pd->sidx], pd->af)) {
+ REASON_SET(&reason, PFRES_SRCLIMIT);
+ goto csfailed;
+ }
+#ifdef __FreeBSD__
+ s = pool_get(&V_pf_state_pl, PR_NOWAIT | PR_ZERO);
+#else
+ s = pool_get(&pf_state_pl, PR_NOWAIT | PR_ZERO);
+#endif
+ if (s == NULL) {
+ REASON_SET(&reason, PFRES_MEMORY);
+ goto csfailed;
+ }
+ s->rule.ptr = r;
+ s->nat_rule.ptr = nr;
+ s->anchor.ptr = a;
+ STATE_INC_COUNTERS(s);
+ if (r->allow_opts)
+ s->state_flags |= PFSTATE_ALLOWOPTS;
+ if (r->rule_flag & PFRULE_STATESLOPPY)
+ s->state_flags |= PFSTATE_SLOPPY;
+ if (r->rule_flag & PFRULE_PFLOW)
+ s->state_flags |= PFSTATE_PFLOW;
+ s->log = r->log & PF_LOG_ALL;
+ s->sync_state = PFSYNC_S_NONE;
+ if (nr != NULL)
+ s->log |= nr->log & PF_LOG_ALL;
+ switch (pd->proto) {
+ case IPPROTO_TCP:
+ s->src.seqlo = ntohl(th->th_seq);
+ s->src.seqhi = s->src.seqlo + pd->p_len + 1;
+ if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
+ r->keep_state == PF_STATE_MODULATE) {
+ /* Generate sequence number modulator */
+ if ((s->src.seqdiff = pf_tcp_iss(pd) - s->src.seqlo) ==
+ 0)
+ s->src.seqdiff = 1;
+ pf_change_a(&th->th_seq, &th->th_sum,
+ htonl(s->src.seqlo + s->src.seqdiff), 0);
+ *rewrite = 1;
+ } else
+ s->src.seqdiff = 0;
+ if (th->th_flags & TH_SYN) {
+ s->src.seqhi++;
+ s->src.wscale = pf_get_wscale(m, off,
+ th->th_off, pd->af);
+ }
+ s->src.max_win = MAX(ntohs(th->th_win), 1);
+ if (s->src.wscale & PF_WSCALE_MASK) {
+ /* Remove scale factor from initial window */
+ int win = s->src.max_win;
+ win += 1 << (s->src.wscale & PF_WSCALE_MASK);
+ s->src.max_win = (win - 1) >>
+ (s->src.wscale & PF_WSCALE_MASK);
+ }
+ if (th->th_flags & TH_FIN)
+ s->src.seqhi++;
+ s->dst.seqhi = 1;
+ s->dst.max_win = 1;
+ s->src.state = TCPS_SYN_SENT;
+ s->dst.state = TCPS_CLOSED;
+ s->timeout = PFTM_TCP_FIRST_PACKET;
+ break;
+ case IPPROTO_UDP:
+ s->src.state = PFUDPS_SINGLE;
+ s->dst.state = PFUDPS_NO_TRAFFIC;
+ s->timeout = PFTM_UDP_FIRST_PACKET;
+ break;
+ case IPPROTO_ICMP:
+#ifdef INET6
+ case IPPROTO_ICMPV6:
+#endif
+ s->timeout = PFTM_ICMP_FIRST_PACKET;
+ break;
+ default:
+ s->src.state = PFOTHERS_SINGLE;
+ s->dst.state = PFOTHERS_NO_TRAFFIC;
+ s->timeout = PFTM_OTHER_FIRST_PACKET;
+ }
+
+ s->creation = time_second;
+ s->expire = time_second;
+
+ if (sn != NULL) {
+ s->src_node = sn;
+ s->src_node->states++;
+ }
+ if (nsn != NULL) {
+ /* XXX We only modify one side for now. */
+ PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af);
+ s->nat_src_node = nsn;
+ s->nat_src_node->states++;
+ }
+ if (pd->proto == IPPROTO_TCP) {
+ if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m,
+ off, pd, th, &s->src, &s->dst)) {
+ REASON_SET(&reason, PFRES_MEMORY);
+ pf_src_tree_remove_state(s);
+ STATE_DEC_COUNTERS(s);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_state_pl, s);
+#else
+ pool_put(&pf_state_pl, s);
+#endif
+ return (PF_DROP);
+ }
+ if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub &&
+ pf_normalize_tcp_stateful(m, off, pd, &reason, th, s,
+ &s->src, &s->dst, rewrite)) {
+ /* This really shouldn't happen!!! */
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_normalize_tcp_stateful failed on first pkt"));
+ pf_normalize_tcp_cleanup(s);
+ pf_src_tree_remove_state(s);
+ STATE_DEC_COUNTERS(s);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_state_pl, s);
+#else
+ pool_put(&pf_state_pl, s);
+#endif
+ return (PF_DROP);
+ }
+ }
+ s->direction = pd->dir;
+
+ if (sk == NULL && pf_state_key_setup(pd, nr, &skw, &sks, &sk, &nk,
+ pd->src, pd->dst, sport, dport))
+ goto csfailed;
+
+ if (pf_state_insert(BOUND_IFACE(r, kif), skw, sks, s)) {
+ if (pd->proto == IPPROTO_TCP)
+ pf_normalize_tcp_cleanup(s);
+ REASON_SET(&reason, PFRES_STATEINS);
+ pf_src_tree_remove_state(s);
+ STATE_DEC_COUNTERS(s);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_state_pl, s);
+#else
+ pool_put(&pf_state_pl, s);
+#endif
+ return (PF_DROP);
+ } else
+ *sm = s;
+
+ pf_set_rt_ifp(s, pd->src); /* needs s->state_key set */
+ if (tag > 0) {
+ pf_tag_ref(tag);
+ s->tag = tag;
+ }
+ if (pd->proto == IPPROTO_TCP && (th->th_flags & (TH_SYN|TH_ACK)) ==
+ TH_SYN && r->keep_state == PF_STATE_SYNPROXY) {
+ s->src.state = PF_TCPS_PROXY_SRC;
+ /* undo NAT changes, if they have taken place */
+ if (nr != NULL) {
+ struct pf_state_key *skt = s->key[PF_SK_WIRE];
+ if (pd->dir == PF_OUT)
+ skt = s->key[PF_SK_STACK];
+ PF_ACPY(pd->src, &skt->addr[pd->sidx], pd->af);
+ PF_ACPY(pd->dst, &skt->addr[pd->didx], pd->af);
+ if (pd->sport)
+ *pd->sport = skt->port[pd->sidx];
+ if (pd->dport)
+ *pd->dport = skt->port[pd->didx];
+ if (pd->proto_sum)
+ *pd->proto_sum = bproto_sum;
+ if (pd->ip_sum)
+ *pd->ip_sum = bip_sum;
+ m_copyback(m, off, hdrlen, pd->hdr.any);
+ }
+ s->src.seqhi = htonl(arc4random());
+ /* Find mss option */
+ int rtid = M_GETFIB(m);
+ mss = pf_get_mss(m, off, th->th_off, pd->af);
+ mss = pf_calc_mss(pd->src, pd->af, rtid, mss);
+ mss = pf_calc_mss(pd->dst, pd->af, rtid, mss);
+ s->src.mss = mss;
+#ifdef __FreeBSD__
+ pf_send_tcp(NULL, r, pd->af, pd->dst, pd->src, th->th_dport,
+#else
+ pf_send_tcp(r, pd->af, pd->dst, pd->src, th->th_dport,
+#endif
+ th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
+ TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL);
+ REASON_SET(&reason, PFRES_SYNPROXY);
+ return (PF_SYNPROXY_DROP);
+ }
+
+ return (PF_PASS);
+
+csfailed:
+#ifdef __FreeBSD__
+ if (sk != NULL)
+ pool_put(&V_pf_state_key_pl, sk);
+ if (nk != NULL)
+ pool_put(&V_pf_state_key_pl, nk);
+#else
+ if (sk != NULL)
+ pool_put(&pf_state_key_pl, sk);
+ if (nk != NULL)
+ pool_put(&pf_state_key_pl, nk);
+#endif
+
+ if (sn != NULL && sn->states == 0 && sn->expire == 0) {
+#ifdef __FreeBSD__
+ RB_REMOVE(pf_src_tree, &V_tree_src_tracking, sn);
+ V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
+ V_pf_status.src_nodes--;
+ pool_put(&V_pf_src_tree_pl, sn);
+#else
+ RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
+ pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
+ pf_status.src_nodes--;
+ pool_put(&pf_src_tree_pl, sn);
+#endif
+ }
+ if (nsn != sn && nsn != NULL && nsn->states == 0 && nsn->expire == 0) {
+#ifdef __FreeBSD__
+ RB_REMOVE(pf_src_tree, &V_tree_src_tracking, nsn);
+ V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
+ V_pf_status.src_nodes--;
+ pool_put(&V_pf_src_tree_pl, nsn);
+#else
+ RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
+ pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
+ pf_status.src_nodes--;
+ pool_put(&pf_src_tree_pl, nsn);
+#endif
+ }
+ return (PF_DROP);
+}
+
+int
+pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
+ struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am,
+ struct pf_ruleset **rsm)
+{
+ struct pf_rule *r, *a = NULL;
+ struct pf_ruleset *ruleset = NULL;
+ sa_family_t af = pd->af;
+ u_short reason;
+ int tag = -1;
+ int asd = 0;
+ int match = 0;
+
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
+ while (r != NULL) {
+ r->evaluations++;
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
+ r = r->skip[PF_SKIP_IFP].ptr;
+ else if (r->direction && r->direction != direction)
+ r = r->skip[PF_SKIP_DIR].ptr;
+ else if (r->af && r->af != af)
+ r = r->skip[PF_SKIP_AF].ptr;
+ else if (r->proto && r->proto != pd->proto)
+ r = r->skip[PF_SKIP_PROTO].ptr;
+ else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
+ r->src.neg, kif, M_GETFIB(m)))
+ r = r->skip[PF_SKIP_SRC_ADDR].ptr;
+ else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
+ r->dst.neg, NULL, M_GETFIB(m)))
+ r = r->skip[PF_SKIP_DST_ADDR].ptr;
+ else if (r->tos && !(r->tos == pd->tos))
+ r = TAILQ_NEXT(r, entries);
+ else if (r->os_fingerprint != PF_OSFP_ANY)
+ r = TAILQ_NEXT(r, entries);
+ else if (pd->proto == IPPROTO_UDP &&
+ (r->src.port_op || r->dst.port_op))
+ r = TAILQ_NEXT(r, entries);
+ else if (pd->proto == IPPROTO_TCP &&
+ (r->src.port_op || r->dst.port_op || r->flagset))
+ r = TAILQ_NEXT(r, entries);
+ else if ((pd->proto == IPPROTO_ICMP ||
+ pd->proto == IPPROTO_ICMPV6) &&
+ (r->type || r->code))
+ r = TAILQ_NEXT(r, entries);
+ else if (r->prob && r->prob <=
+ (arc4random() % (UINT_MAX - 1) + 1))
+ r = TAILQ_NEXT(r, entries);
+#ifdef __FreeBSD__
+ else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
+#else
+ else if (r->match_tag && !pf_match_tag(m, r, &tag))
+#endif
+ r = TAILQ_NEXT(r, entries);
+ else {
+ if (r->anchor == NULL) {
+ match = 1;
+ *rm = r;
+ *am = a;
+ *rsm = ruleset;
+ if ((*rm)->quick)
+ break;
+ r = TAILQ_NEXT(r, entries);
+ } else
+ pf_step_into_anchor(&asd, &ruleset,
+ PF_RULESET_FILTER, &r, &a, &match);
+ }
+ if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
+ PF_RULESET_FILTER, &r, &a, &match))
+ break;
+ }
+ r = *rm;
+ a = *am;
+ ruleset = *rsm;
+
+ REASON_SET(&reason, PFRES_MATCH);
+
+ if (r->log)
+ PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset,
+ pd);
+
+ if (r->action != PF_PASS)
+ return (PF_DROP);
+
+#ifdef __FreeBSD__
+ if (pf_tag_packet(m, tag, -1, pd->pf_mtag)) {
+#else
+ if (pf_tag_packet(m, tag, -1)) {
+#endif
+ REASON_SET(&reason, PFRES_MEMORY);
+ return (PF_DROP);
+ }
+
+ return (PF_PASS);
+}
+
+int
+pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst,
+ struct pf_state **state, struct pfi_kif *kif, struct mbuf *m, int off,
+ struct pf_pdesc *pd, u_short *reason, int *copyback)
+{
+ struct tcphdr *th = pd->hdr.tcp;
+ u_int16_t win = ntohs(th->th_win);
+ u_int32_t ack, end, seq, orig_seq;
+ u_int8_t sws, dws;
+ int ackskew;
+
+ if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
+ sws = src->wscale & PF_WSCALE_MASK;
+ dws = dst->wscale & PF_WSCALE_MASK;
+ } else
+ sws = dws = 0;
+
+ /*
+ * Sequence tracking algorithm from Guido van Rooij's paper:
+ * http://www.madison-gurkha.com/publications/tcp_filtering/
+ * tcp_filtering.ps
+ */
+
+ orig_seq = seq = ntohl(th->th_seq);
+ if (src->seqlo == 0) {
+ /* First packet from this end. Set its state */
+
+ if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) &&
+ src->scrub == NULL) {
+ if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
+ REASON_SET(reason, PFRES_MEMORY);
+ return (PF_DROP);
+ }
+ }
+
+ /* Deferred generation of sequence number modulator */
+ if (dst->seqdiff && !src->seqdiff) {
+ /* use random iss for the TCP server */
+ while ((src->seqdiff = arc4random() - seq) == 0)
+ ;
+ ack = ntohl(th->th_ack) - dst->seqdiff;
+ pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
+ src->seqdiff), 0);
+ pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
+ *copyback = 1;
+ } else {
+ ack = ntohl(th->th_ack);
+ }
+
+ end = seq + pd->p_len;
+ if (th->th_flags & TH_SYN) {
+ end++;
+ if (dst->wscale & PF_WSCALE_FLAG) {
+ src->wscale = pf_get_wscale(m, off, th->th_off,
+ pd->af);
+ if (src->wscale & PF_WSCALE_FLAG) {
+ /* Remove scale factor from initial
+ * window */
+ sws = src->wscale & PF_WSCALE_MASK;
+ win = ((u_int32_t)win + (1 << sws) - 1)
+ >> sws;
+ dws = dst->wscale & PF_WSCALE_MASK;
+ } else {
+ /* fixup other window */
+ dst->max_win <<= dst->wscale &
+ PF_WSCALE_MASK;
+ /* in case of a retrans SYN|ACK */
+ dst->wscale = 0;
+ }
+ }
+ }
+ if (th->th_flags & TH_FIN)
+ end++;
+
+ src->seqlo = seq;
+ if (src->state < TCPS_SYN_SENT)
+ src->state = TCPS_SYN_SENT;
+
+ /*
+ * May need to slide the window (seqhi may have been set by
+ * the crappy stack check or if we picked up the connection
+ * after establishment)
+ */
+ if (src->seqhi == 1 ||
+ SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi))
+ src->seqhi = end + MAX(1, dst->max_win << dws);
+ if (win > src->max_win)
+ src->max_win = win;
+
+ } else {
+ ack = ntohl(th->th_ack) - dst->seqdiff;
+ if (src->seqdiff) {
+ /* Modulate sequence numbers */
+ pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
+ src->seqdiff), 0);
+ pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
+ *copyback = 1;
+ }
+ end = seq + pd->p_len;
+ if (th->th_flags & TH_SYN)
+ end++;
+ if (th->th_flags & TH_FIN)
+ end++;
+ }
+
+ if ((th->th_flags & TH_ACK) == 0) {
+ /* Let it pass through the ack skew check */
+ ack = dst->seqlo;
+ } else if ((ack == 0 &&
+ (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
+ /* broken tcp stacks do not set ack */
+ (dst->state < TCPS_SYN_SENT)) {
+ /*
+ * Many stacks (ours included) will set the ACK number in an
+ * FIN|ACK if the SYN times out -- no sequence to ACK.
+ */
+ ack = dst->seqlo;
+ }
+
+ if (seq == end) {
+ /* Ease sequencing restrictions on no data packets */
+ seq = src->seqlo;
+ end = seq;
+ }
+
+ ackskew = dst->seqlo - ack;
+
+
+ /*
+ * Need to demodulate the sequence numbers in any TCP SACK options
+ * (Selective ACK). We could optionally validate the SACK values
+ * against the current ACK window, either forwards or backwards, but
+ * I'm not confident that SACK has been implemented properly
+ * everywhere. It wouldn't surprise me if several stacks accidently
+ * SACK too far backwards of previously ACKed data. There really aren't
+ * any security implications of bad SACKing unless the target stack
+ * doesn't validate the option length correctly. Someone trying to
+ * spoof into a TCP connection won't bother blindly sending SACK
+ * options anyway.
+ */
+ if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) {
+ if (pf_modulate_sack(m, off, pd, th, dst))
+ *copyback = 1;
+ }
+
+
+#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */
+ if (SEQ_GEQ(src->seqhi, end) &&
+ /* Last octet inside other's window space */
+ SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
+ /* Retrans: not more than one window back */
+ (ackskew >= -MAXACKWINDOW) &&
+ /* Acking not more than one reassembled fragment backwards */
+ (ackskew <= (MAXACKWINDOW << sws)) &&
+ /* Acking not more than one window forward */
+ ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
+ (orig_seq == src->seqlo + 1) || (orig_seq + 1 == src->seqlo) ||
+ (pd->flags & PFDESC_IP_REAS) == 0)) {
+ /* Require an exact/+1 sequence match on resets when possible */
+
+ if (dst->scrub || src->scrub) {
+ if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
+ *state, src, dst, copyback))
+ return (PF_DROP);
+ }
+
+ /* update max window */
+ if (src->max_win < win)
+ src->max_win = win;
+ /* synchronize sequencing */
+ if (SEQ_GT(end, src->seqlo))
+ src->seqlo = end;
+ /* slide the window of what the other end can send */
+ if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
+ dst->seqhi = ack + MAX((win << sws), 1);
+
+
+ /* update states */
+ if (th->th_flags & TH_SYN)
+ if (src->state < TCPS_SYN_SENT)
+ src->state = TCPS_SYN_SENT;
+ if (th->th_flags & TH_FIN)
+ if (src->state < TCPS_CLOSING)
+ src->state = TCPS_CLOSING;
+ if (th->th_flags & TH_ACK) {
+ if (dst->state == TCPS_SYN_SENT) {
+ dst->state = TCPS_ESTABLISHED;
+ if (src->state == TCPS_ESTABLISHED &&
+ (*state)->src_node != NULL &&
+ pf_src_connlimit(state)) {
+ REASON_SET(reason, PFRES_SRCLIMIT);
+ return (PF_DROP);
+ }
+ } else if (dst->state == TCPS_CLOSING)
+ dst->state = TCPS_FIN_WAIT_2;
+ }
+ if (th->th_flags & TH_RST)
+ src->state = dst->state = TCPS_TIME_WAIT;
+
+ /* update expire time */
+ (*state)->expire = time_second;
+ if (src->state >= TCPS_FIN_WAIT_2 &&
+ dst->state >= TCPS_FIN_WAIT_2)
+ (*state)->timeout = PFTM_TCP_CLOSED;
+ else if (src->state >= TCPS_CLOSING &&
+ dst->state >= TCPS_CLOSING)
+ (*state)->timeout = PFTM_TCP_FIN_WAIT;
+ else if (src->state < TCPS_ESTABLISHED ||
+ dst->state < TCPS_ESTABLISHED)
+ (*state)->timeout = PFTM_TCP_OPENING;
+ else if (src->state >= TCPS_CLOSING ||
+ dst->state >= TCPS_CLOSING)
+ (*state)->timeout = PFTM_TCP_CLOSING;
+ else
+ (*state)->timeout = PFTM_TCP_ESTABLISHED;
+
+ /* Fall through to PASS packet */
+
+ } else if ((dst->state < TCPS_SYN_SENT ||
+ dst->state >= TCPS_FIN_WAIT_2 ||
+ src->state >= TCPS_FIN_WAIT_2) &&
+ SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) &&
+ /* Within a window forward of the originating packet */
+ SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
+ /* Within a window backward of the originating packet */
+
+ /*
+ * This currently handles three situations:
+ * 1) Stupid stacks will shotgun SYNs before their peer
+ * replies.
+ * 2) When PF catches an already established stream (the
+ * firewall rebooted, the state table was flushed, routes
+ * changed...)
+ * 3) Packets get funky immediately after the connection
+ * closes (this should catch Solaris spurious ACK|FINs
+ * that web servers like to spew after a close)
+ *
+ * This must be a little more careful than the above code
+ * since packet floods will also be caught here. We don't
+ * update the TTL here to mitigate the damage of a packet
+ * flood and so the same code can handle awkward establishment
+ * and a loosened connection close.
+ * In the establishment case, a correct peer response will
+ * validate the connection, go through the normal state code
+ * and keep updating the state TTL.
+ */
+
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pf: loose state match: ");
+ pf_print_state(*state);
+ pf_print_flags(th->th_flags);
+ printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
+ "pkts=%llu:%llu dir=%s,%s\n", seq, orig_seq, ack,
+#ifdef __FreeBSD__
+ pd->p_len, ackskew, (unsigned long long)(*state)->packets[0],
+ (unsigned long long)(*state)->packets[1],
+#else
+ pd->p_len, ackskew, (*state)->packets[0],
+ (*state)->packets[1],
+#endif
+ pd->dir == PF_IN ? "in" : "out",
+ pd->dir == (*state)->direction ? "fwd" : "rev");
+ }
+
+ if (dst->scrub || src->scrub) {
+ if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
+ *state, src, dst, copyback))
+ return (PF_DROP);
+ }
+
+ /* update max window */
+ if (src->max_win < win)
+ src->max_win = win;
+ /* synchronize sequencing */
+ if (SEQ_GT(end, src->seqlo))
+ src->seqlo = end;
+ /* slide the window of what the other end can send */
+ if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
+ dst->seqhi = ack + MAX((win << sws), 1);
+
+ /*
+ * Cannot set dst->seqhi here since this could be a shotgunned
+ * SYN and not an already established connection.
+ */
+
+ if (th->th_flags & TH_FIN)
+ if (src->state < TCPS_CLOSING)
+ src->state = TCPS_CLOSING;
+ if (th->th_flags & TH_RST)
+ src->state = dst->state = TCPS_TIME_WAIT;
+
+ /* Fall through to PASS packet */
+
+ } else {
+ if ((*state)->dst.state == TCPS_SYN_SENT &&
+ (*state)->src.state == TCPS_SYN_SENT) {
+ /* Send RST for state mismatches during handshake */
+ if (!(th->th_flags & TH_RST))
+#ifdef __FreeBSD__
+ pf_send_tcp(NULL, (*state)->rule.ptr, pd->af,
+#else
+ pf_send_tcp((*state)->rule.ptr, pd->af,
+#endif
+ pd->dst, pd->src, th->th_dport,
+ th->th_sport, ntohl(th->th_ack), 0,
+ TH_RST, 0, 0,
+ (*state)->rule.ptr->return_ttl, 1, 0,
+ pd->eh, kif->pfik_ifp);
+ src->seqlo = 0;
+ src->seqhi = 1;
+ src->max_win = 1;
+#ifdef __FreeBSD__
+ } else if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ } else if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pf: BAD state: ");
+ pf_print_state(*state);
+ pf_print_flags(th->th_flags);
+ printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
+ "pkts=%llu:%llu dir=%s,%s\n",
+ seq, orig_seq, ack, pd->p_len, ackskew,
+#ifdef __FreeBSD__
+ (unsigned long long)(*state)->packets[0],
+ (unsigned long long)(*state)->packets[1],
+#else
+ (*state)->packets[0], (*state)->packets[1],
+#endif
+ pd->dir == PF_IN ? "in" : "out",
+ pd->dir == (*state)->direction ? "fwd" : "rev");
+ printf("pf: State failure on: %c %c %c %c | %c %c\n",
+ SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
+ SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
+ ' ': '2',
+ (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
+ (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
+ SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5',
+ SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
+ }
+ REASON_SET(reason, PFRES_BADSTATE);
+ return (PF_DROP);
+ }
+
+ return (PF_PASS);
+}
+
+int
+pf_tcp_track_sloppy(struct pf_state_peer *src, struct pf_state_peer *dst,
+ struct pf_state **state, struct pf_pdesc *pd, u_short *reason)
+{
+ struct tcphdr *th = pd->hdr.tcp;
+
+ if (th->th_flags & TH_SYN)
+ if (src->state < TCPS_SYN_SENT)
+ src->state = TCPS_SYN_SENT;
+ if (th->th_flags & TH_FIN)
+ if (src->state < TCPS_CLOSING)
+ src->state = TCPS_CLOSING;
+ if (th->th_flags & TH_ACK) {
+ if (dst->state == TCPS_SYN_SENT) {
+ dst->state = TCPS_ESTABLISHED;
+ if (src->state == TCPS_ESTABLISHED &&
+ (*state)->src_node != NULL &&
+ pf_src_connlimit(state)) {
+ REASON_SET(reason, PFRES_SRCLIMIT);
+ return (PF_DROP);
+ }
+ } else if (dst->state == TCPS_CLOSING) {
+ dst->state = TCPS_FIN_WAIT_2;
+ } else if (src->state == TCPS_SYN_SENT &&
+ dst->state < TCPS_SYN_SENT) {
+ /*
+ * Handle a special sloppy case where we only see one
+ * half of the connection. If there is a ACK after
+ * the initial SYN without ever seeing a packet from
+ * the destination, set the connection to established.
+ */
+ dst->state = src->state = TCPS_ESTABLISHED;
+ if ((*state)->src_node != NULL &&
+ pf_src_connlimit(state)) {
+ REASON_SET(reason, PFRES_SRCLIMIT);
+ return (PF_DROP);
+ }
+ } else if (src->state == TCPS_CLOSING &&
+ dst->state == TCPS_ESTABLISHED &&
+ dst->seqlo == 0) {
+ /*
+ * Handle the closing of half connections where we
+ * don't see the full bidirectional FIN/ACK+ACK
+ * handshake.
+ */
+ dst->state = TCPS_CLOSING;
+ }
+ }
+ if (th->th_flags & TH_RST)
+ src->state = dst->state = TCPS_TIME_WAIT;
+
+ /* update expire time */
+ (*state)->expire = time_second;
+ if (src->state >= TCPS_FIN_WAIT_2 &&
+ dst->state >= TCPS_FIN_WAIT_2)
+ (*state)->timeout = PFTM_TCP_CLOSED;
+ else if (src->state >= TCPS_CLOSING &&
+ dst->state >= TCPS_CLOSING)
+ (*state)->timeout = PFTM_TCP_FIN_WAIT;
+ else if (src->state < TCPS_ESTABLISHED ||
+ dst->state < TCPS_ESTABLISHED)
+ (*state)->timeout = PFTM_TCP_OPENING;
+ else if (src->state >= TCPS_CLOSING ||
+ dst->state >= TCPS_CLOSING)
+ (*state)->timeout = PFTM_TCP_CLOSING;
+ else
+ (*state)->timeout = PFTM_TCP_ESTABLISHED;
+
+ return (PF_PASS);
+}
+
+int
+pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
+ struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
+ u_short *reason)
+{
+ struct pf_state_key_cmp key;
+ struct tcphdr *th = pd->hdr.tcp;
+ int copyback = 0;
+ struct pf_state_peer *src, *dst;
+ struct pf_state_key *sk;
+
+ key.af = pd->af;
+ key.proto = IPPROTO_TCP;
+ if (direction == PF_IN) { /* wire side, straight */
+ PF_ACPY(&key.addr[0], pd->src, key.af);
+ PF_ACPY(&key.addr[1], pd->dst, key.af);
+ key.port[0] = th->th_sport;
+ key.port[1] = th->th_dport;
+ } else { /* stack side, reverse */
+ PF_ACPY(&key.addr[1], pd->src, key.af);
+ PF_ACPY(&key.addr[0], pd->dst, key.af);
+ key.port[1] = th->th_sport;
+ key.port[0] = th->th_dport;
+ }
+
+#ifdef __FreeBSD__
+ STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
+#else
+ STATE_LOOKUP(kif, &key, direction, *state, m);
+#endif
+
+ if (direction == (*state)->direction) {
+ src = &(*state)->src;
+ dst = &(*state)->dst;
+ } else {
+ src = &(*state)->dst;
+ dst = &(*state)->src;
+ }
+
+ sk = (*state)->key[pd->didx];
+
+ if ((*state)->src.state == PF_TCPS_PROXY_SRC) {
+ if (direction != (*state)->direction) {
+ REASON_SET(reason, PFRES_SYNPROXY);
+ return (PF_SYNPROXY_DROP);
+ }
+ if (th->th_flags & TH_SYN) {
+ if (ntohl(th->th_seq) != (*state)->src.seqlo) {
+ REASON_SET(reason, PFRES_SYNPROXY);
+ return (PF_DROP);
+ }
+#ifdef __FreeBSD__
+ pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst,
+#else
+ pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
+#endif
+ pd->src, th->th_dport, th->th_sport,
+ (*state)->src.seqhi, ntohl(th->th_seq) + 1,
+ TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1,
+ 0, NULL, NULL);
+ REASON_SET(reason, PFRES_SYNPROXY);
+ return (PF_SYNPROXY_DROP);
+ } else if (!(th->th_flags & TH_ACK) ||
+ (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
+ (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
+ REASON_SET(reason, PFRES_SYNPROXY);
+ return (PF_DROP);
+ } else if ((*state)->src_node != NULL &&
+ pf_src_connlimit(state)) {
+ REASON_SET(reason, PFRES_SRCLIMIT);
+ return (PF_DROP);
+ } else
+ (*state)->src.state = PF_TCPS_PROXY_DST;
+ }
+ if ((*state)->src.state == PF_TCPS_PROXY_DST) {
+ if (direction == (*state)->direction) {
+ if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) ||
+ (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
+ (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
+ REASON_SET(reason, PFRES_SYNPROXY);
+ return (PF_DROP);
+ }
+ (*state)->src.max_win = MAX(ntohs(th->th_win), 1);
+ if ((*state)->dst.seqhi == 1)
+ (*state)->dst.seqhi = htonl(arc4random());
+#ifdef __FreeBSD__
+ pf_send_tcp(NULL, (*state)->rule.ptr, pd->af,
+#else
+ pf_send_tcp((*state)->rule.ptr, pd->af,
+#endif
+ &sk->addr[pd->sidx], &sk->addr[pd->didx],
+ sk->port[pd->sidx], sk->port[pd->didx],
+ (*state)->dst.seqhi, 0, TH_SYN, 0,
+ (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL);
+ REASON_SET(reason, PFRES_SYNPROXY);
+ return (PF_SYNPROXY_DROP);
+ } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
+ (TH_SYN|TH_ACK)) ||
+ (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) {
+ REASON_SET(reason, PFRES_SYNPROXY);
+ return (PF_DROP);
+ } else {
+ (*state)->dst.max_win = MAX(ntohs(th->th_win), 1);
+ (*state)->dst.seqlo = ntohl(th->th_seq);
+#ifdef __FreeBSD__
+ pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst,
+#else
+ pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
+#endif
+ pd->src, th->th_dport, th->th_sport,
+ ntohl(th->th_ack), ntohl(th->th_seq) + 1,
+ TH_ACK, (*state)->src.max_win, 0, 0, 0,
+ (*state)->tag, NULL, NULL);
+#ifdef __FreeBSD__
+ pf_send_tcp(NULL, (*state)->rule.ptr, pd->af,
+#else
+ pf_send_tcp((*state)->rule.ptr, pd->af,
+#endif
+ &sk->addr[pd->sidx], &sk->addr[pd->didx],
+ sk->port[pd->sidx], sk->port[pd->didx],
+ (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
+ TH_ACK, (*state)->dst.max_win, 0, 0, 1,
+ 0, NULL, NULL);
+ (*state)->src.seqdiff = (*state)->dst.seqhi -
+ (*state)->src.seqlo;
+ (*state)->dst.seqdiff = (*state)->src.seqhi -
+ (*state)->dst.seqlo;
+ (*state)->src.seqhi = (*state)->src.seqlo +
+ (*state)->dst.max_win;
+ (*state)->dst.seqhi = (*state)->dst.seqlo +
+ (*state)->src.max_win;
+ (*state)->src.wscale = (*state)->dst.wscale = 0;
+ (*state)->src.state = (*state)->dst.state =
+ TCPS_ESTABLISHED;
+ REASON_SET(reason, PFRES_SYNPROXY);
+ return (PF_SYNPROXY_DROP);
+ }
+ }
+
+ if (((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) &&
+ dst->state >= TCPS_FIN_WAIT_2 &&
+ src->state >= TCPS_FIN_WAIT_2) {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pf: state reuse ");
+ pf_print_state(*state);
+ pf_print_flags(th->th_flags);
+ printf("\n");
+ }
+ /* XXX make sure it's the same direction ?? */
+ (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
+ pf_unlink_state(*state);
+ *state = NULL;
+ return (PF_DROP);
+ }
+
+ if ((*state)->state_flags & PFSTATE_SLOPPY) {
+ if (pf_tcp_track_sloppy(src, dst, state, pd, reason) == PF_DROP)
+ return (PF_DROP);
+ } else {
+ if (pf_tcp_track_full(src, dst, state, kif, m, off, pd, reason,
+ &copyback) == PF_DROP)
+ return (PF_DROP);
+ }
+
+ /* translate source/destination address, if necessary */
+ if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
+ struct pf_state_key *nk = (*state)->key[pd->didx];
+
+ if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) ||
+ nk->port[pd->sidx] != th->th_sport)
+ pf_change_ap(pd->src, &th->th_sport, pd->ip_sum,
+ &th->th_sum, &nk->addr[pd->sidx],
+ nk->port[pd->sidx], 0, pd->af);
+
+ if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) ||
+ nk->port[pd->didx] != th->th_dport)
+ pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum,
+ &th->th_sum, &nk->addr[pd->didx],
+ nk->port[pd->didx], 0, pd->af);
+ copyback = 1;
+ }
+
+ /* Copyback sequence modulation or stateful scrub changes if needed */
+ if (copyback)
+#ifdef __FreeBSD__
+ m_copyback(m, off, sizeof(*th), (caddr_t)th);
+#else
+ m_copyback(m, off, sizeof(*th), th);
+#endif
+
+ return (PF_PASS);
+}
+
+int
+pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
+ struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
+{
+ struct pf_state_peer *src, *dst;
+ struct pf_state_key_cmp key;
+ struct udphdr *uh = pd->hdr.udp;
+
+ key.af = pd->af;
+ key.proto = IPPROTO_UDP;
+ if (direction == PF_IN) { /* wire side, straight */
+ PF_ACPY(&key.addr[0], pd->src, key.af);
+ PF_ACPY(&key.addr[1], pd->dst, key.af);
+ key.port[0] = uh->uh_sport;
+ key.port[1] = uh->uh_dport;
+ } else { /* stack side, reverse */
+ PF_ACPY(&key.addr[1], pd->src, key.af);
+ PF_ACPY(&key.addr[0], pd->dst, key.af);
+ key.port[1] = uh->uh_sport;
+ key.port[0] = uh->uh_dport;
+ }
+
+#ifdef __FreeBSD__
+ STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
+#else
+ STATE_LOOKUP(kif, &key, direction, *state, m);
+#endif
+
+ if (direction == (*state)->direction) {
+ src = &(*state)->src;
+ dst = &(*state)->dst;
+ } else {
+ src = &(*state)->dst;
+ dst = &(*state)->src;
+ }
+
+ /* update states */
+ if (src->state < PFUDPS_SINGLE)
+ src->state = PFUDPS_SINGLE;
+ if (dst->state == PFUDPS_SINGLE)
+ dst->state = PFUDPS_MULTIPLE;
+
+ /* update expire time */
+ (*state)->expire = time_second;
+ if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE)
+ (*state)->timeout = PFTM_UDP_MULTIPLE;
+ else
+ (*state)->timeout = PFTM_UDP_SINGLE;
+
+ /* translate source/destination address, if necessary */
+ if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
+ struct pf_state_key *nk = (*state)->key[pd->didx];
+
+ if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) ||
+ nk->port[pd->sidx] != uh->uh_sport)
+ pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum,
+ &uh->uh_sum, &nk->addr[pd->sidx],
+ nk->port[pd->sidx], 1, pd->af);
+
+ if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) ||
+ nk->port[pd->didx] != uh->uh_dport)
+ pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum,
+ &uh->uh_sum, &nk->addr[pd->didx],
+ nk->port[pd->didx], 1, pd->af);
+#ifdef __FreeBSD__
+ m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
+#else
+ m_copyback(m, off, sizeof(*uh), uh);
+#endif
+ }
+
+ return (PF_PASS);
+}
+
+int
+pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
+ struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason)
+{
+ struct pf_addr *saddr = pd->src, *daddr = pd->dst;
+#ifdef __FreeBSD__
+ u_int16_t icmpid = 0, *icmpsum;
+#else
+ u_int16_t icmpid, *icmpsum;
+#endif
+ u_int8_t icmptype;
+ int state_icmp = 0;
+ struct pf_state_key_cmp key;
+
+ switch (pd->proto) {
+#ifdef INET
+ case IPPROTO_ICMP:
+ icmptype = pd->hdr.icmp->icmp_type;
+ icmpid = pd->hdr.icmp->icmp_id;
+ icmpsum = &pd->hdr.icmp->icmp_cksum;
+
+ if (icmptype == ICMP_UNREACH ||
+ icmptype == ICMP_SOURCEQUENCH ||
+ icmptype == ICMP_REDIRECT ||
+ icmptype == ICMP_TIMXCEED ||
+ icmptype == ICMP_PARAMPROB)
+ state_icmp++;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case IPPROTO_ICMPV6:
+ icmptype = pd->hdr.icmp6->icmp6_type;
+ icmpid = pd->hdr.icmp6->icmp6_id;
+ icmpsum = &pd->hdr.icmp6->icmp6_cksum;
+
+ if (icmptype == ICMP6_DST_UNREACH ||
+ icmptype == ICMP6_PACKET_TOO_BIG ||
+ icmptype == ICMP6_TIME_EXCEEDED ||
+ icmptype == ICMP6_PARAM_PROB)
+ state_icmp++;
+ break;
+#endif /* INET6 */
+ }
+
+ if (!state_icmp) {
+
+ /*
+ * ICMP query/reply message not related to a TCP/UDP packet.
+ * Search for an ICMP state.
+ */
+ key.af = pd->af;
+ key.proto = pd->proto;
+ key.port[0] = key.port[1] = icmpid;
+ if (direction == PF_IN) { /* wire side, straight */
+ PF_ACPY(&key.addr[0], pd->src, key.af);
+ PF_ACPY(&key.addr[1], pd->dst, key.af);
+ } else { /* stack side, reverse */
+ PF_ACPY(&key.addr[1], pd->src, key.af);
+ PF_ACPY(&key.addr[0], pd->dst, key.af);
+ }
+
+#ifdef __FreeBSD__
+ STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
+#else
+ STATE_LOOKUP(kif, &key, direction, *state, m);
+#endif
+
+ (*state)->expire = time_second;
+ (*state)->timeout = PFTM_ICMP_ERROR_REPLY;
+
+ /* translate source/destination address, if necessary */
+ if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
+ struct pf_state_key *nk = (*state)->key[pd->didx];
+
+ switch (pd->af) {
+#ifdef INET
+ case AF_INET:
+ if (PF_ANEQ(pd->src,
+ &nk->addr[pd->sidx], AF_INET))
+ pf_change_a(&saddr->v4.s_addr,
+ pd->ip_sum,
+ nk->addr[pd->sidx].v4.s_addr, 0);
+
+ if (PF_ANEQ(pd->dst, &nk->addr[pd->didx],
+ AF_INET))
+ pf_change_a(&daddr->v4.s_addr,
+ pd->ip_sum,
+ nk->addr[pd->didx].v4.s_addr, 0);
+
+ if (nk->port[0] !=
+ pd->hdr.icmp->icmp_id) {
+ pd->hdr.icmp->icmp_cksum =
+ pf_cksum_fixup(
+ pd->hdr.icmp->icmp_cksum, icmpid,
+ nk->port[pd->sidx], 0);
+ pd->hdr.icmp->icmp_id =
+ nk->port[pd->sidx];
+ }
+
+ m_copyback(m, off, ICMP_MINLEN,
+#ifdef __FreeBSD__
+ (caddr_t)
+#endif
+ pd->hdr.icmp);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (PF_ANEQ(pd->src,
+ &nk->addr[pd->sidx], AF_INET6))
+ pf_change_a6(saddr,
+ &pd->hdr.icmp6->icmp6_cksum,
+ &nk->addr[pd->sidx], 0);
+
+ if (PF_ANEQ(pd->dst,
+ &nk->addr[pd->didx], AF_INET6))
+ pf_change_a6(daddr,
+ &pd->hdr.icmp6->icmp6_cksum,
+ &nk->addr[pd->didx], 0);
+
+ m_copyback(m, off,
+ sizeof(struct icmp6_hdr),
+#ifdef __FreeBSD__
+ (caddr_t)
+#endif
+ pd->hdr.icmp6);
+ break;
+#endif /* INET6 */
+ }
+ }
+ return (PF_PASS);
+
+ } else {
+ /*
+ * ICMP error message in response to a TCP/UDP packet.
+ * Extract the inner TCP/UDP header and search for that state.
+ */
+
+ struct pf_pdesc pd2;
+#ifdef __FreeBSD__
+ bzero(&pd2, sizeof pd2);
+#endif
+#ifdef INET
+ struct ip h2;
+#endif /* INET */
+#ifdef INET6
+ struct ip6_hdr h2_6;
+ int terminal = 0;
+#endif /* INET6 */
+#ifdef __FreeBSD__
+ int ipoff2 = 0;
+ int off2 = 0;
+#else
+ int ipoff2;
+ int off2;
+#endif
+
+ pd2.af = pd->af;
+ /* Payload packet is from the opposite direction. */
+ pd2.sidx = (direction == PF_IN) ? 1 : 0;
+ pd2.didx = (direction == PF_IN) ? 0 : 1;
+ switch (pd->af) {
+#ifdef INET
+ case AF_INET:
+ /* offset of h2 in mbuf chain */
+ ipoff2 = off + ICMP_MINLEN;
+
+ if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2),
+ NULL, reason, pd2.af)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: ICMP error message too short "
+ "(ip)\n"));
+ return (PF_DROP);
+ }
+ /*
+ * ICMP error messages don't refer to non-first
+ * fragments
+ */
+ if (h2.ip_off & htons(IP_OFFMASK)) {
+ REASON_SET(reason, PFRES_FRAG);
+ return (PF_DROP);
+ }
+
+ /* offset of protocol header that follows h2 */
+ off2 = ipoff2 + (h2.ip_hl << 2);
+
+ pd2.proto = h2.ip_p;
+ pd2.src = (struct pf_addr *)&h2.ip_src;
+ pd2.dst = (struct pf_addr *)&h2.ip_dst;
+ pd2.ip_sum = &h2.ip_sum;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ ipoff2 = off + sizeof(struct icmp6_hdr);
+
+ if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6),
+ NULL, reason, pd2.af)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: ICMP error message too short "
+ "(ip6)\n"));
+ return (PF_DROP);
+ }
+ pd2.proto = h2_6.ip6_nxt;
+ pd2.src = (struct pf_addr *)&h2_6.ip6_src;
+ pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
+ pd2.ip_sum = NULL;
+ off2 = ipoff2 + sizeof(h2_6);
+ do {
+ switch (pd2.proto) {
+ case IPPROTO_FRAGMENT:
+ /*
+ * ICMPv6 error messages for
+ * non-first fragments
+ */
+ REASON_SET(reason, PFRES_FRAG);
+ return (PF_DROP);
+ case IPPROTO_AH:
+ case IPPROTO_HOPOPTS:
+ case IPPROTO_ROUTING:
+ case IPPROTO_DSTOPTS: {
+ /* get next header and header length */
+ struct ip6_ext opt6;
+
+ if (!pf_pull_hdr(m, off2, &opt6,
+ sizeof(opt6), NULL, reason,
+ pd2.af)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: ICMPv6 short opt\n"));
+ return (PF_DROP);
+ }
+ if (pd2.proto == IPPROTO_AH)
+ off2 += (opt6.ip6e_len + 2) * 4;
+ else
+ off2 += (opt6.ip6e_len + 1) * 8;
+ pd2.proto = opt6.ip6e_nxt;
+ /* goto the next header */
+ break;
+ }
+ default:
+ terminal++;
+ break;
+ }
+ } while (!terminal);
+ break;
+#endif /* INET6 */
+ }
+
+ switch (pd2.proto) {
+ case IPPROTO_TCP: {
+ struct tcphdr th;
+ u_int32_t seq;
+ struct pf_state_peer *src, *dst;
+ u_int8_t dws;
+ int copyback = 0;
+
+ /*
+ * Only the first 8 bytes of the TCP header can be
+ * expected. Don't access any TCP header fields after
+ * th_seq, an ackskew test is not possible.
+ */
+ if (!pf_pull_hdr(m, off2, &th, 8, NULL, reason,
+ pd2.af)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: ICMP error message too short "
+ "(tcp)\n"));
+ return (PF_DROP);
+ }
+
+ key.af = pd2.af;
+ key.proto = IPPROTO_TCP;
+ PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
+ PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
+ key.port[pd2.sidx] = th.th_sport;
+ key.port[pd2.didx] = th.th_dport;
+
+#ifdef __FreeBSD__
+ STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
+#else
+ STATE_LOOKUP(kif, &key, direction, *state, m);
+#endif
+
+ if (direction == (*state)->direction) {
+ src = &(*state)->dst;
+ dst = &(*state)->src;
+ } else {
+ src = &(*state)->src;
+ dst = &(*state)->dst;
+ }
+
+ if (src->wscale && dst->wscale)
+ dws = dst->wscale & PF_WSCALE_MASK;
+ else
+ dws = 0;
+
+ /* Demodulate sequence number */
+ seq = ntohl(th.th_seq) - src->seqdiff;
+ if (src->seqdiff) {
+ pf_change_a(&th.th_seq, icmpsum,
+ htonl(seq), 0);
+ copyback = 1;
+ }
+
+ if (!((*state)->state_flags & PFSTATE_SLOPPY) &&
+ (!SEQ_GEQ(src->seqhi, seq) ||
+ !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)))) {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pf: BAD ICMP %d:%d ",
+ icmptype, pd->hdr.icmp->icmp_code);
+ pf_print_host(pd->src, 0, pd->af);
+ printf(" -> ");
+ pf_print_host(pd->dst, 0, pd->af);
+ printf(" state: ");
+ pf_print_state(*state);
+ printf(" seq=%u\n", seq);
+ }
+ REASON_SET(reason, PFRES_BADSTATE);
+ return (PF_DROP);
+ } else {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pf: OK ICMP %d:%d ",
+ icmptype, pd->hdr.icmp->icmp_code);
+ pf_print_host(pd->src, 0, pd->af);
+ printf(" -> ");
+ pf_print_host(pd->dst, 0, pd->af);
+ printf(" state: ");
+ pf_print_state(*state);
+ printf(" seq=%u\n", seq);
+ }
+ }
+
+ /* translate source/destination address, if necessary */
+ if ((*state)->key[PF_SK_WIRE] !=
+ (*state)->key[PF_SK_STACK]) {
+ struct pf_state_key *nk =
+ (*state)->key[pd->didx];
+
+ if (PF_ANEQ(pd2.src,
+ &nk->addr[pd2.sidx], pd2.af) ||
+ nk->port[pd2.sidx] != th.th_sport)
+ pf_change_icmp(pd2.src, &th.th_sport,
+ daddr, &nk->addr[pd2.sidx],
+ nk->port[pd2.sidx], NULL,
+ pd2.ip_sum, icmpsum,
+ pd->ip_sum, 0, pd2.af);
+
+ if (PF_ANEQ(pd2.dst,
+ &nk->addr[pd2.didx], pd2.af) ||
+ nk->port[pd2.didx] != th.th_dport)
+ pf_change_icmp(pd2.dst, &th.th_dport,
+ NULL, /* XXX Inbound NAT? */
+ &nk->addr[pd2.didx],
+ nk->port[pd2.didx], NULL,
+ pd2.ip_sum, icmpsum,
+ pd->ip_sum, 0, pd2.af);
+ copyback = 1;
+ }
+
+ if (copyback) {
+ switch (pd2.af) {
+#ifdef INET
+ case AF_INET:
+ m_copyback(m, off, ICMP_MINLEN,
+#ifdef __FreeBSD__
+ (caddr_t)
+#endif
+ pd->hdr.icmp);
+ m_copyback(m, ipoff2, sizeof(h2),
+#ifdef __FreeBSD__
+ (caddr_t)
+#endif
+ &h2);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ m_copyback(m, off,
+ sizeof(struct icmp6_hdr),
+#ifdef __FreeBSD__
+ (caddr_t)
+#endif
+ pd->hdr.icmp6);
+ m_copyback(m, ipoff2, sizeof(h2_6),
+#ifdef __FreeBSD__
+ (caddr_t)
+#endif
+ &h2_6);
+ break;
+#endif /* INET6 */
+ }
+#ifdef __FreeBSD__
+ m_copyback(m, off2, 8, (caddr_t)&th);
+#else
+ m_copyback(m, off2, 8, &th);
+#endif
+ }
+
+ return (PF_PASS);
+ break;
+ }
+ case IPPROTO_UDP: {
+ struct udphdr uh;
+
+ if (!pf_pull_hdr(m, off2, &uh, sizeof(uh),
+ NULL, reason, pd2.af)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: ICMP error message too short "
+ "(udp)\n"));
+ return (PF_DROP);
+ }
+
+ key.af = pd2.af;
+ key.proto = IPPROTO_UDP;
+ PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
+ PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
+ key.port[pd2.sidx] = uh.uh_sport;
+ key.port[pd2.didx] = uh.uh_dport;
+
+#ifdef __FreeBSD__
+ STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
+#else
+ STATE_LOOKUP(kif, &key, direction, *state, m);
+#endif
+
+ /* translate source/destination address, if necessary */
+ if ((*state)->key[PF_SK_WIRE] !=
+ (*state)->key[PF_SK_STACK]) {
+ struct pf_state_key *nk =
+ (*state)->key[pd->didx];
+
+ if (PF_ANEQ(pd2.src,
+ &nk->addr[pd2.sidx], pd2.af) ||
+ nk->port[pd2.sidx] != uh.uh_sport)
+ pf_change_icmp(pd2.src, &uh.uh_sport,
+ daddr, &nk->addr[pd2.sidx],
+ nk->port[pd2.sidx], &uh.uh_sum,
+ pd2.ip_sum, icmpsum,
+ pd->ip_sum, 1, pd2.af);
+
+ if (PF_ANEQ(pd2.dst,
+ &nk->addr[pd2.didx], pd2.af) ||
+ nk->port[pd2.didx] != uh.uh_dport)
+ pf_change_icmp(pd2.dst, &uh.uh_dport,
+ NULL, /* XXX Inbound NAT? */
+ &nk->addr[pd2.didx],
+ nk->port[pd2.didx], &uh.uh_sum,
+ pd2.ip_sum, icmpsum,
+ pd->ip_sum, 1, pd2.af);
+
+ switch (pd2.af) {
+#ifdef INET
+ case AF_INET:
+ m_copyback(m, off, ICMP_MINLEN,
+#ifdef __FreeBSD__
+ (caddr_t)
+#endif
+ pd->hdr.icmp);
+#ifdef __FreeBSD__
+ m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
+#else
+ m_copyback(m, ipoff2, sizeof(h2), &h2);
+#endif
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ m_copyback(m, off,
+ sizeof(struct icmp6_hdr),
+#ifdef __FreeBSD__
+ (caddr_t)
+#endif
+ pd->hdr.icmp6);
+ m_copyback(m, ipoff2, sizeof(h2_6),
+#ifdef __FreeBSD__
+ (caddr_t)
+#endif
+ &h2_6);
+ break;
+#endif /* INET6 */
+ }
+#ifdef __FreeBSD__
+ m_copyback(m, off2, sizeof(uh), (caddr_t)&uh);
+#else
+ m_copyback(m, off2, sizeof(uh), &uh);
+#endif
+ }
+ return (PF_PASS);
+ break;
+ }
+#ifdef INET
+ case IPPROTO_ICMP: {
+ struct icmp iih;
+
+ if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN,
+ NULL, reason, pd2.af)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: ICMP error message too short i"
+ "(icmp)\n"));
+ return (PF_DROP);
+ }
+
+ key.af = pd2.af;
+ key.proto = IPPROTO_ICMP;
+ PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
+ PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
+ key.port[0] = key.port[1] = iih.icmp_id;
+
+#ifdef __FreeBSD__
+ STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
+#else
+ STATE_LOOKUP(kif, &key, direction, *state, m);
+#endif
+
+ /* translate source/destination address, if necessary */
+ if ((*state)->key[PF_SK_WIRE] !=
+ (*state)->key[PF_SK_STACK]) {
+ struct pf_state_key *nk =
+ (*state)->key[pd->didx];
+
+ if (PF_ANEQ(pd2.src,
+ &nk->addr[pd2.sidx], pd2.af) ||
+ nk->port[pd2.sidx] != iih.icmp_id)
+ pf_change_icmp(pd2.src, &iih.icmp_id,
+ daddr, &nk->addr[pd2.sidx],
+ nk->port[pd2.sidx], NULL,
+ pd2.ip_sum, icmpsum,
+ pd->ip_sum, 0, AF_INET);
+
+ if (PF_ANEQ(pd2.dst,
+ &nk->addr[pd2.didx], pd2.af) ||
+ nk->port[pd2.didx] != iih.icmp_id)
+ pf_change_icmp(pd2.dst, &iih.icmp_id,
+ NULL, /* XXX Inbound NAT? */
+ &nk->addr[pd2.didx],
+ nk->port[pd2.didx], NULL,
+ pd2.ip_sum, icmpsum,
+ pd->ip_sum, 0, AF_INET);
+
+#ifdef __FreeBSD__
+ m_copyback(m, off, ICMP_MINLEN, (caddr_t)pd->hdr.icmp);
+ m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
+ m_copyback(m, off2, ICMP_MINLEN, (caddr_t)&iih);
+#else
+ m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp);
+ m_copyback(m, ipoff2, sizeof(h2), &h2);
+ m_copyback(m, off2, ICMP_MINLEN, &iih);
+#endif
+ }
+ return (PF_PASS);
+ break;
+ }
+#endif /* INET */
+#ifdef INET6
+ case IPPROTO_ICMPV6: {
+ struct icmp6_hdr iih;
+
+ if (!pf_pull_hdr(m, off2, &iih,
+ sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: ICMP error message too short "
+ "(icmp6)\n"));
+ return (PF_DROP);
+ }
+
+ key.af = pd2.af;
+ key.proto = IPPROTO_ICMPV6;
+ PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
+ PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
+ key.port[0] = key.port[1] = iih.icmp6_id;
+
+#ifdef __FreeBSD__
+ STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
+#else
+ STATE_LOOKUP(kif, &key, direction, *state, m);
+#endif
+
+ /* translate source/destination address, if necessary */
+ if ((*state)->key[PF_SK_WIRE] !=
+ (*state)->key[PF_SK_STACK]) {
+ struct pf_state_key *nk =
+ (*state)->key[pd->didx];
+
+ if (PF_ANEQ(pd2.src,
+ &nk->addr[pd2.sidx], pd2.af) ||
+ nk->port[pd2.sidx] != iih.icmp6_id)
+ pf_change_icmp(pd2.src, &iih.icmp6_id,
+ daddr, &nk->addr[pd2.sidx],
+ nk->port[pd2.sidx], NULL,
+ pd2.ip_sum, icmpsum,
+ pd->ip_sum, 0, AF_INET6);
+
+ if (PF_ANEQ(pd2.dst,
+ &nk->addr[pd2.didx], pd2.af) ||
+ nk->port[pd2.didx] != iih.icmp6_id)
+ pf_change_icmp(pd2.dst, &iih.icmp6_id,
+ NULL, /* XXX Inbound NAT? */
+ &nk->addr[pd2.didx],
+ nk->port[pd2.didx], NULL,
+ pd2.ip_sum, icmpsum,
+ pd->ip_sum, 0, AF_INET6);
+
+#ifdef __FreeBSD__
+ m_copyback(m, off, sizeof(struct icmp6_hdr),
+ (caddr_t)pd->hdr.icmp6);
+ m_copyback(m, ipoff2, sizeof(h2_6), (caddr_t)&h2_6);
+ m_copyback(m, off2, sizeof(struct icmp6_hdr),
+ (caddr_t)&iih);
+#else
+ m_copyback(m, off, sizeof(struct icmp6_hdr),
+ pd->hdr.icmp6);
+ m_copyback(m, ipoff2, sizeof(h2_6), &h2_6);
+ m_copyback(m, off2, sizeof(struct icmp6_hdr),
+ &iih);
+#endif
+ }
+ return (PF_PASS);
+ break;
+ }
+#endif /* INET6 */
+ default: {
+ key.af = pd2.af;
+ key.proto = pd2.proto;
+ PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
+ PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
+ key.port[0] = key.port[1] = 0;
+
+#ifdef __FreeBSD__
+ STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
+#else
+ STATE_LOOKUP(kif, &key, direction, *state, m);
+#endif
+
+ /* translate source/destination address, if necessary */
+ if ((*state)->key[PF_SK_WIRE] !=
+ (*state)->key[PF_SK_STACK]) {
+ struct pf_state_key *nk =
+ (*state)->key[pd->didx];
+
+ if (PF_ANEQ(pd2.src,
+ &nk->addr[pd2.sidx], pd2.af))
+ pf_change_icmp(pd2.src, NULL, daddr,
+ &nk->addr[pd2.sidx], 0, NULL,
+ pd2.ip_sum, icmpsum,
+ pd->ip_sum, 0, pd2.af);
+
+ if (PF_ANEQ(pd2.dst,
+ &nk->addr[pd2.didx], pd2.af))
+ pf_change_icmp(pd2.src, NULL,
+ NULL, /* XXX Inbound NAT? */
+ &nk->addr[pd2.didx], 0, NULL,
+ pd2.ip_sum, icmpsum,
+ pd->ip_sum, 0, pd2.af);
+
+ switch (pd2.af) {
+#ifdef INET
+ case AF_INET:
+#ifdef __FreeBSD__
+ m_copyback(m, off, ICMP_MINLEN,
+ (caddr_t)pd->hdr.icmp);
+ m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
+#else
+ m_copyback(m, off, ICMP_MINLEN,
+ pd->hdr.icmp);
+ m_copyback(m, ipoff2, sizeof(h2), &h2);
+#endif
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ m_copyback(m, off,
+ sizeof(struct icmp6_hdr),
+#ifdef __FreeBSD__
+ (caddr_t)
+#endif
+ pd->hdr.icmp6);
+ m_copyback(m, ipoff2, sizeof(h2_6),
+#ifdef __FreeBSD__
+ (caddr_t)
+#endif
+ &h2_6);
+ break;
+#endif /* INET6 */
+ }
+ }
+ return (PF_PASS);
+ break;
+ }
+ }
+ }
+}
+
+int
+pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
+ struct mbuf *m, struct pf_pdesc *pd)
+{
+ struct pf_state_peer *src, *dst;
+ struct pf_state_key_cmp key;
+
+ key.af = pd->af;
+ key.proto = pd->proto;
+ if (direction == PF_IN) {
+ PF_ACPY(&key.addr[0], pd->src, key.af);
+ PF_ACPY(&key.addr[1], pd->dst, key.af);
+ key.port[0] = key.port[1] = 0;
+ } else {
+ PF_ACPY(&key.addr[1], pd->src, key.af);
+ PF_ACPY(&key.addr[0], pd->dst, key.af);
+ key.port[1] = key.port[0] = 0;
+ }
+
+#ifdef __FreeBSD__
+ STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
+#else
+ STATE_LOOKUP(kif, &key, direction, *state, m);
+#endif
+
+ if (direction == (*state)->direction) {
+ src = &(*state)->src;
+ dst = &(*state)->dst;
+ } else {
+ src = &(*state)->dst;
+ dst = &(*state)->src;
+ }
+
+ /* update states */
+ if (src->state < PFOTHERS_SINGLE)
+ src->state = PFOTHERS_SINGLE;
+ if (dst->state == PFOTHERS_SINGLE)
+ dst->state = PFOTHERS_MULTIPLE;
+
+ /* update expire time */
+ (*state)->expire = time_second;
+ if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE)
+ (*state)->timeout = PFTM_OTHER_MULTIPLE;
+ else
+ (*state)->timeout = PFTM_OTHER_SINGLE;
+
+ /* translate source/destination address, if necessary */
+ if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
+ struct pf_state_key *nk = (*state)->key[pd->didx];
+
+#ifdef __FreeBSD__
+ KASSERT(nk, ("%s: nk is null", __FUNCTION__));
+ KASSERT(pd, ("%s: pd is null", __FUNCTION__));
+ KASSERT(pd->src, ("%s: pd->src is null", __FUNCTION__));
+ KASSERT(pd->dst, ("%s: pd->dst is null", __FUNCTION__));
+#else
+ KASSERT(nk);
+ KASSERT(pd);
+ KASSERT(pd->src);
+ KASSERT(pd->dst);
+#endif
+ switch (pd->af) {
+#ifdef INET
+ case AF_INET:
+ if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], AF_INET))
+ pf_change_a(&pd->src->v4.s_addr,
+ pd->ip_sum,
+ nk->addr[pd->sidx].v4.s_addr,
+ 0);
+
+
+ if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], AF_INET))
+ pf_change_a(&pd->dst->v4.s_addr,
+ pd->ip_sum,
+ nk->addr[pd->didx].v4.s_addr,
+ 0);
+
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], AF_INET))
+ PF_ACPY(pd->src, &nk->addr[pd->sidx], pd->af);
+
+ if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], AF_INET))
+ PF_ACPY(pd->dst, &nk->addr[pd->didx], pd->af);
+#endif /* INET6 */
+ }
+ }
+ return (PF_PASS);
+}
+
+/*
+ * ipoff and off are measured from the start of the mbuf chain.
+ * h must be at "ipoff" on the mbuf chain.
+ */
+void *
+pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
+ u_short *actionp, u_short *reasonp, sa_family_t af)
+{
+ switch (af) {
+#ifdef INET
+ case AF_INET: {
+ struct ip *h = mtod(m, struct ip *);
+ u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
+
+ if (fragoff) {
+ if (fragoff >= len)
+ ACTION_SET(actionp, PF_PASS);
+ else {
+ ACTION_SET(actionp, PF_DROP);
+ REASON_SET(reasonp, PFRES_FRAG);
+ }
+ return (NULL);
+ }
+ if (m->m_pkthdr.len < off + len ||
+ ntohs(h->ip_len) < off + len) {
+ ACTION_SET(actionp, PF_DROP);
+ REASON_SET(reasonp, PFRES_SHORT);
+ return (NULL);
+ }
+ break;
+ }
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6: {
+ struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
+
+ if (m->m_pkthdr.len < off + len ||
+ (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) <
+ (unsigned)(off + len)) {
+ ACTION_SET(actionp, PF_DROP);
+ REASON_SET(reasonp, PFRES_SHORT);
+ return (NULL);
+ }
+ break;
+ }
+#endif /* INET6 */
+ }
+ m_copydata(m, off, len, p);
+ return (p);
+}
+
+int
+pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif,
+ int rtableid)
+{
+#ifdef __FreeBSD__
+#ifdef RADIX_MPATH
+ struct radix_node_head *rnh;
+#endif
+#endif
+ struct sockaddr_in *dst;
+ int ret = 1;
+ int check_mpath;
+#ifndef __FreeBSD__
+ extern int ipmultipath;
+#endif
+#ifdef INET6
+#ifndef __FreeBSD__
+ extern int ip6_multipath;
+#endif
+ struct sockaddr_in6 *dst6;
+ struct route_in6 ro;
+#else
+ struct route ro;
+#endif
+ struct radix_node *rn;
+ struct rtentry *rt;
+ struct ifnet *ifp;
+
+ check_mpath = 0;
+#ifdef __FreeBSD__
+#ifdef RADIX_MPATH
+ /* XXX: stick to table 0 for now */
+ rnh = rt_tables_get_rnh(0, af);
+ if (rnh != NULL && rn_mpath_capable(rnh))
+ check_mpath = 1;
+#endif
+#endif
+ bzero(&ro, sizeof(ro));
+ switch (af) {
+ case AF_INET:
+ dst = satosin(&ro.ro_dst);
+ dst->sin_family = AF_INET;
+ dst->sin_len = sizeof(*dst);
+ dst->sin_addr = addr->v4;
+#ifndef __FreeBSD__
+ if (ipmultipath)
+ check_mpath = 1;
+#endif
+ break;
+#ifdef INET6
+ case AF_INET6:
+ /*
+ * Skip check for addresses with embedded interface scope,
+ * as they would always match anyway.
+ */
+ if (IN6_IS_SCOPE_EMBED(&addr->v6))
+ goto out;
+ dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
+ dst6->sin6_family = AF_INET6;
+ dst6->sin6_len = sizeof(*dst6);
+ dst6->sin6_addr = addr->v6;
+#ifndef __FreeBSD__
+ if (ip6_multipath)
+ check_mpath = 1;
+#endif
+ break;
+#endif /* INET6 */
+ default:
+ return (0);
+ }
+
+ /* Skip checks for ipsec interfaces */
+ if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC)
+ goto out;
+
+#ifdef __FreeBSD__
+ switch (af) {
+#ifdef INET6
+ case AF_INET6:
+ in6_rtalloc_ign(&ro, 0, rtableid);
+ break;
+#endif
+#ifdef INET
+ case AF_INET:
+ in_rtalloc_ign((struct route *)&ro, 0, rtableid);
+ break;
+#endif
+ default:
+ rtalloc_ign((struct route *)&ro, 0); /* No/default FIB. */
+ break;
+ }
+#else /* ! __FreeBSD__ */
+ rtalloc_noclone((struct route *)&ro, NO_CLONING);
+#endif
+
+ if (ro.ro_rt != NULL) {
+ /* No interface given, this is a no-route check */
+ if (kif == NULL)
+ goto out;
+
+ if (kif->pfik_ifp == NULL) {
+ ret = 0;
+ goto out;
+ }
+
+ /* Perform uRPF check if passed input interface */
+ ret = 0;
+ rn = (struct radix_node *)ro.ro_rt;
+ do {
+ rt = (struct rtentry *)rn;
+#ifndef __FreeBSD__ /* CARPDEV */
+ if (rt->rt_ifp->if_type == IFT_CARP)
+ ifp = rt->rt_ifp->if_carpdev;
+ else
+#endif
+ ifp = rt->rt_ifp;
+
+ if (kif->pfik_ifp == ifp)
+ ret = 1;
+#ifdef __FreeBSD__
+#ifdef RADIX_MPATH
+ rn = rn_mpath_next(rn);
+#endif
+#else
+ rn = rn_mpath_next(rn, 0);
+#endif
+ } while (check_mpath == 1 && rn != NULL && ret == 0);
+ } else
+ ret = 0;
+out:
+ if (ro.ro_rt != NULL)
+ RTFREE(ro.ro_rt);
+ return (ret);
+}
+
+int
+pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw,
+ int rtableid)
+{
+ struct sockaddr_in *dst;
+#ifdef INET6
+ struct sockaddr_in6 *dst6;
+ struct route_in6 ro;
+#else
+ struct route ro;
+#endif
+ int ret = 0;
+
+ bzero(&ro, sizeof(ro));
+ switch (af) {
+ case AF_INET:
+ dst = satosin(&ro.ro_dst);
+ dst->sin_family = AF_INET;
+ dst->sin_len = sizeof(*dst);
+ dst->sin_addr = addr->v4;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
+ dst6->sin6_family = AF_INET6;
+ dst6->sin6_len = sizeof(*dst6);
+ dst6->sin6_addr = addr->v6;
+ break;
+#endif /* INET6 */
+ default:
+ return (0);
+ }
+
+#ifdef __FreeBSD__
+ switch (af) {
+#ifdef INET6
+ case AF_INET6:
+ in6_rtalloc_ign(&ro, 0, rtableid);
+ break;
+#endif
+#ifdef INET
+ case AF_INET:
+ in_rtalloc_ign((struct route *)&ro, 0, rtableid);
+ break;
+#endif
+ default:
+ rtalloc_ign((struct route *)&ro, 0);
+ break;
+ }
+#else /* ! __FreeBSD__ */
+ rtalloc_noclone((struct route *)&ro, NO_CLONING);
+#endif
+
+ if (ro.ro_rt != NULL) {
+#ifdef __FreeBSD__
+ /* XXX_IMPORT: later */
+#else
+ if (ro.ro_rt->rt_labelid == aw->v.rtlabel)
+ ret = 1;
+#endif
+ RTFREE(ro.ro_rt);
+ }
+
+ return (ret);
+}
+
+#ifdef INET
+void
+pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
+ struct pf_state *s, struct pf_pdesc *pd)
+{
+ struct mbuf *m0, *m1;
+ struct route iproute;
+ struct route *ro = NULL;
+ struct sockaddr_in *dst;
+ struct ip *ip;
+ struct ifnet *ifp = NULL;
+ struct pf_addr naddr;
+ struct pf_src_node *sn = NULL;
+ int error = 0;
+#ifdef __FreeBSD__
+ int sw_csum;
+#endif
+#ifdef IPSEC
+ struct m_tag *mtag;
+#endif /* IPSEC */
+
+ if (m == NULL || *m == NULL || r == NULL ||
+ (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
+ panic("pf_route: invalid parameters");
+
+#ifdef __FreeBSD__
+ if (pd->pf_mtag->routed++ > 3) {
+#else
+ if ((*m)->m_pkthdr.pf.routed++ > 3) {
+#endif
+ m0 = *m;
+ *m = NULL;
+ goto bad;
+ }
+
+ if (r->rt == PF_DUPTO) {
+#ifdef __FreeBSD__
+ if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
+#else
+ if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
+#endif
+ return;
+ } else {
+ if ((r->rt == PF_REPLYTO) == (r->direction == dir))
+ return;
+ m0 = *m;
+ }
+
+ if (m0->m_len < sizeof(struct ip)) {
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_route: m0->m_len < sizeof(struct ip)\n"));
+ goto bad;
+ }
+
+ ip = mtod(m0, struct ip *);
+
+ ro = &iproute;
+ bzero((caddr_t)ro, sizeof(*ro));
+ dst = satosin(&ro->ro_dst);
+ dst->sin_family = AF_INET;
+ dst->sin_len = sizeof(*dst);
+ dst->sin_addr = ip->ip_dst;
+
+ if (r->rt == PF_FASTROUTE) {
+#ifdef __FreeBSD__
+ in_rtalloc_ign(ro, 0, M_GETFIB(m0));
+#else
+ rtalloc(ro);
+#endif
+ if (ro->ro_rt == 0) {
+#ifdef __FreeBSD__
+ KMOD_IPSTAT_INC(ips_noroute);
+#else
+ ipstat.ips_noroute++;
+#endif
+ goto bad;
+ }
+
+ ifp = ro->ro_rt->rt_ifp;
+ ro->ro_rt->rt_use++;
+
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY)
+ dst = satosin(ro->ro_rt->rt_gateway);
+ } else {
+ if (TAILQ_EMPTY(&r->rpool.list)) {
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n"));
+ goto bad;
+ }
+ if (s == NULL) {
+ pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
+ &naddr, NULL, &sn);
+ if (!PF_AZERO(&naddr, AF_INET))
+ dst->sin_addr.s_addr = naddr.v4.s_addr;
+ ifp = r->rpool.cur->kif ?
+ r->rpool.cur->kif->pfik_ifp : NULL;
+ } else {
+ if (!PF_AZERO(&s->rt_addr, AF_INET))
+ dst->sin_addr.s_addr =
+ s->rt_addr.v4.s_addr;
+ ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
+ }
+ }
+ if (ifp == NULL)
+ goto bad;
+
+ if (oifp != ifp) {
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+ if (pf_test(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) {
+ PF_LOCK();
+ goto bad;
+ } else if (m0 == NULL) {
+ PF_LOCK();
+ goto done;
+ }
+ PF_LOCK();
+#else
+ if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS)
+ goto bad;
+ else if (m0 == NULL)
+ goto done;
+#endif
+ if (m0->m_len < sizeof(struct ip)) {
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_route: m0->m_len < sizeof(struct ip)\n"));
+ goto bad;
+ }
+ ip = mtod(m0, struct ip *);
+ }
+
+#ifdef __FreeBSD__
+ /* Copied from FreeBSD 5.1-CURRENT ip_output. */
+ m0->m_pkthdr.csum_flags |= CSUM_IP;
+ sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist;
+ if (sw_csum & CSUM_DELAY_DATA) {
+ /*
+ * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least)
+ */
+ NTOHS(ip->ip_len);
+ NTOHS(ip->ip_off); /* XXX: needed? */
+ in_delayed_cksum(m0);
+ HTONS(ip->ip_len);
+ HTONS(ip->ip_off);
+ sw_csum &= ~CSUM_DELAY_DATA;
+ }
+ m0->m_pkthdr.csum_flags &= ifp->if_hwassist;
+
+ if (ntohs(ip->ip_len) <= ifp->if_mtu ||
+ (ifp->if_hwassist & CSUM_FRAGMENT &&
+ ((ip->ip_off & htons(IP_DF)) == 0))) {
+ /*
+ * ip->ip_len = htons(ip->ip_len);
+ * ip->ip_off = htons(ip->ip_off);
+ */
+ ip->ip_sum = 0;
+ if (sw_csum & CSUM_DELAY_IP) {
+ /* From KAME */
+ if (ip->ip_v == IPVERSION &&
+ (ip->ip_hl << 2) == sizeof(*ip)) {
+ ip->ip_sum = in_cksum_hdr(ip);
+ } else {
+ ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
+ }
+ }
+ PF_UNLOCK();
+ error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro);
+ PF_LOCK();
+ goto done;
+ }
+#else
+ /* Copied from ip_output. */
+#ifdef IPSEC
+ /*
+ * If deferred crypto processing is needed, check that the
+ * interface supports it.
+ */
+ if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL))
+ != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) {
+ /* Notify IPsec to do its own crypto. */
+ ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
+ goto bad;
+ }
+#endif /* IPSEC */
+
+ /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */
+ if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) {
+ if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) ||
+ ifp->if_bridge != NULL) {
+ in_delayed_cksum(m0);
+ m0->m_pkthdr.csum_flags &= ~M_TCPV4_CSUM_OUT; /* Clr */
+ }
+ } else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) {
+ if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) ||
+ ifp->if_bridge != NULL) {
+ in_delayed_cksum(m0);
+ m0->m_pkthdr.csum_flags &= ~M_UDPV4_CSUM_OUT; /* Clr */
+ }
+ }
+
+ if (ntohs(ip->ip_len) <= ifp->if_mtu) {
+ ip->ip_sum = 0;
+ if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
+ ifp->if_bridge == NULL) {
+ m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
+#ifdef __FreeBSD__
+ KMOD_IPSTAT_INC(ips_outhwcsum);
+#else
+ ipstat.ips_outhwcsum++;
+#endif
+ } else
+ ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
+ /* Update relevant hardware checksum stats for TCP/UDP */
+ if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT)
+ KMOD_TCPSTAT_INC(tcps_outhwcsum);
+ else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT)
+ KMOD_UDPSTAT_INC(udps_outhwcsum);
+ error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL);
+ goto done;
+ }
+#endif
+
+ /*
+ * Too large for interface; fragment if possible.
+ * Must be able to put at least 8 bytes per fragment.
+ */
+ if (ip->ip_off & htons(IP_DF)) {
+#ifdef __FreeBSD__
+ KMOD_IPSTAT_INC(ips_cantfrag);
+#else
+ ipstat.ips_cantfrag++;
+#endif
+ if (r->rt != PF_DUPTO) {
+#ifdef __FreeBSD__
+ /* icmp_error() expects host byte ordering */
+ NTOHS(ip->ip_len);
+ NTOHS(ip->ip_off);
+ PF_UNLOCK();
+ icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
+ ifp->if_mtu);
+ PF_LOCK();
+#else
+ icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
+ ifp->if_mtu);
+#endif
+ goto done;
+ } else
+ goto bad;
+ }
+
+ m1 = m0;
+#ifdef __FreeBSD__
+ /*
+ * XXX: is cheaper + less error prone than own function
+ */
+ NTOHS(ip->ip_len);
+ NTOHS(ip->ip_off);
+ error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum);
+#else
+ error = ip_fragment(m0, ifp, ifp->if_mtu);
+#endif
+ if (error) {
+#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */
+ m0 = NULL;
+#endif
+ goto bad;
+ }
+
+ for (m0 = m1; m0; m0 = m1) {
+ m1 = m0->m_nextpkt;
+ m0->m_nextpkt = 0;
+#ifdef __FreeBSD__
+ if (error == 0) {
+ PF_UNLOCK();
+ error = (*ifp->if_output)(ifp, m0, sintosa(dst),
+ NULL);
+ PF_LOCK();
+ } else
+#else
+ if (error == 0)
+ error = (*ifp->if_output)(ifp, m0, sintosa(dst),
+ NULL);
+ else
+#endif
+ m_freem(m0);
+ }
+
+ if (error == 0)
+#ifdef __FreeBSD__
+ KMOD_IPSTAT_INC(ips_fragmented);
+#else
+ ipstat.ips_fragmented++;
+#endif
+
+done:
+ if (r->rt != PF_DUPTO)
+ *m = NULL;
+ if (ro == &iproute && ro->ro_rt)
+ RTFREE(ro->ro_rt);
+ return;
+
+bad:
+ m_freem(m0);
+ goto done;
+}
+#endif /* INET */
+
+#ifdef INET6
+void
+pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
+ struct pf_state *s, struct pf_pdesc *pd)
+{
+ struct mbuf *m0;
+ struct route_in6 ip6route;
+ struct route_in6 *ro;
+ struct sockaddr_in6 *dst;
+ struct ip6_hdr *ip6;
+ struct ifnet *ifp = NULL;
+ struct pf_addr naddr;
+ struct pf_src_node *sn = NULL;
+
+ if (m == NULL || *m == NULL || r == NULL ||
+ (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
+ panic("pf_route6: invalid parameters");
+
+#ifdef __FreeBSD__
+ if (pd->pf_mtag->routed++ > 3) {
+#else
+ if ((*m)->m_pkthdr.pf.routed++ > 3) {
+#endif
+ m0 = *m;
+ *m = NULL;
+ goto bad;
+ }
+
+ if (r->rt == PF_DUPTO) {
+#ifdef __FreeBSD__
+ if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
+#else
+ if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
+#endif
+ return;
+ } else {
+ if ((r->rt == PF_REPLYTO) == (r->direction == dir))
+ return;
+ m0 = *m;
+ }
+
+ if (m0->m_len < sizeof(struct ip6_hdr)) {
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
+ goto bad;
+ }
+ ip6 = mtod(m0, struct ip6_hdr *);
+
+ ro = &ip6route;
+ bzero((caddr_t)ro, sizeof(*ro));
+ dst = (struct sockaddr_in6 *)&ro->ro_dst;
+ dst->sin6_family = AF_INET6;
+ dst->sin6_len = sizeof(*dst);
+ dst->sin6_addr = ip6->ip6_dst;
+
+ /* Cheat. XXX why only in the v6 case??? */
+ if (r->rt == PF_FASTROUTE) {
+#ifdef __FreeBSD__
+ m0->m_flags |= M_SKIP_FIREWALL;
+ PF_UNLOCK();
+ ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
+#else
+ m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
+ ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
+#endif
+ return;
+ }
+
+ if (TAILQ_EMPTY(&r->rpool.list)) {
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n"));
+ goto bad;
+ }
+ if (s == NULL) {
+ pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
+ &naddr, NULL, &sn);
+ if (!PF_AZERO(&naddr, AF_INET6))
+ PF_ACPY((struct pf_addr *)&dst->sin6_addr,
+ &naddr, AF_INET6);
+ ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
+ } else {
+ if (!PF_AZERO(&s->rt_addr, AF_INET6))
+ PF_ACPY((struct pf_addr *)&dst->sin6_addr,
+ &s->rt_addr, AF_INET6);
+ ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
+ }
+ if (ifp == NULL)
+ goto bad;
+
+ if (oifp != ifp) {
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+ if (pf_test6(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) {
+ PF_LOCK();
+ goto bad;
+ } else if (m0 == NULL) {
+ PF_LOCK();
+ goto done;
+ }
+ PF_LOCK();
+#else
+ if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS)
+ goto bad;
+ else if (m0 == NULL)
+ goto done;
+#endif
+ if (m0->m_len < sizeof(struct ip6_hdr)) {
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
+ goto bad;
+ }
+ ip6 = mtod(m0, struct ip6_hdr *);
+ }
+
+ /*
+ * If the packet is too large for the outgoing interface,
+ * send back an icmp6 error.
+ */
+ if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr))
+ dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+ if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ nd6_output(ifp, ifp, m0, dst, NULL);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ } else {
+ in6_ifstat_inc(ifp, ifs6_in_toobig);
+#ifdef __FreeBSD__
+ if (r->rt != PF_DUPTO) {
+ PF_UNLOCK();
+ icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
+ PF_LOCK();
+ } else
+#else
+ if (r->rt != PF_DUPTO)
+ icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
+ else
+#endif
+ goto bad;
+ }
+
+done:
+ if (r->rt != PF_DUPTO)
+ *m = NULL;
+ return;
+
+bad:
+ m_freem(m0);
+ goto done;
+}
+#endif /* INET6 */
+
+#ifdef __FreeBSD__
+/*
+ * FreeBSD supports cksum offloads for the following drivers.
+ * em(4), fxp(4), ixgb(4), lge(4), ndis(4), nge(4), re(4),
+ * ti(4), txp(4), xl(4)
+ *
+ * CSUM_DATA_VALID | CSUM_PSEUDO_HDR :
+ * network driver performed cksum including pseudo header, need to verify
+ * csum_data
+ * CSUM_DATA_VALID :
+ * network driver performed cksum, needs to additional pseudo header
+ * cksum computation with partial csum_data(i.e. lack of H/W support for
+ * pseudo header, for instance hme(4), sk(4) and possibly gem(4))
+ *
+ * After validating the cksum of packet, set both flag CSUM_DATA_VALID and
+ * CSUM_PSEUDO_HDR in order to avoid recomputation of the cksum in upper
+ * TCP/UDP layer.
+ * Also, set csum_data to 0xffff to force cksum validation.
+ */
+int
+pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af)
+{
+ u_int16_t sum = 0;
+ int hw_assist = 0;
+ struct ip *ip;
+
+ if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
+ return (1);
+ if (m->m_pkthdr.len < off + len)
+ return (1);
+
+ switch (p) {
+ case IPPROTO_TCP:
+ if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
+ if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
+ sum = m->m_pkthdr.csum_data;
+ } else {
+ ip = mtod(m, struct ip *);
+ sum = in_pseudo(ip->ip_src.s_addr,
+ ip->ip_dst.s_addr, htonl((u_short)len +
+ m->m_pkthdr.csum_data + IPPROTO_TCP));
+ }
+ sum ^= 0xffff;
+ ++hw_assist;
+ }
+ break;
+ case IPPROTO_UDP:
+ if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
+ if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
+ sum = m->m_pkthdr.csum_data;
+ } else {
+ ip = mtod(m, struct ip *);
+ sum = in_pseudo(ip->ip_src.s_addr,
+ ip->ip_dst.s_addr, htonl((u_short)len +
+ m->m_pkthdr.csum_data + IPPROTO_UDP));
+ }
+ sum ^= 0xffff;
+ ++hw_assist;
+ }
+ break;
+ case IPPROTO_ICMP:
+#ifdef INET6
+ case IPPROTO_ICMPV6:
+#endif /* INET6 */
+ break;
+ default:
+ return (1);
+ }
+
+ if (!hw_assist) {
+ switch (af) {
+ case AF_INET:
+ if (p == IPPROTO_ICMP) {
+ if (m->m_len < off)
+ return (1);
+ m->m_data += off;
+ m->m_len -= off;
+ sum = in_cksum(m, len);
+ m->m_data -= off;
+ m->m_len += off;
+ } else {
+ if (m->m_len < sizeof(struct ip))
+ return (1);
+ sum = in4_cksum(m, p, off, len);
+ }
+ break;
+#ifdef INET6
+ case AF_INET6:
+ if (m->m_len < sizeof(struct ip6_hdr))
+ return (1);
+ sum = in6_cksum(m, p, off, len);
+ break;
+#endif /* INET6 */
+ default:
+ return (1);
+ }
+ }
+ if (sum) {
+ switch (p) {
+ case IPPROTO_TCP:
+ {
+ KMOD_TCPSTAT_INC(tcps_rcvbadsum);
+ break;
+ }
+ case IPPROTO_UDP:
+ {
+ KMOD_UDPSTAT_INC(udps_badsum);
+ break;
+ }
+#ifdef INET
+ case IPPROTO_ICMP:
+ {
+ KMOD_ICMPSTAT_INC(icps_checksum);
+ break;
+ }
+#endif
+#ifdef INET6
+ case IPPROTO_ICMPV6:
+ {
+ KMOD_ICMP6STAT_INC(icp6s_checksum);
+ break;
+ }
+#endif /* INET6 */
+ }
+ return (1);
+ } else {
+ if (p == IPPROTO_TCP || p == IPPROTO_UDP) {
+ m->m_pkthdr.csum_flags |=
+ (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
+ m->m_pkthdr.csum_data = 0xffff;
+ }
+ }
+ return (0);
+}
+#else /* !__FreeBSD__ */
+
+/*
+ * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag
+ * off is the offset where the protocol header starts
+ * len is the total length of protocol header plus payload
+ * returns 0 when the checksum is valid, otherwise returns 1.
+ */
+int
+pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
+ sa_family_t af)
+{
+ u_int16_t flag_ok, flag_bad;
+ u_int16_t sum;
+
+ switch (p) {
+ case IPPROTO_TCP:
+ flag_ok = M_TCP_CSUM_IN_OK;
+ flag_bad = M_TCP_CSUM_IN_BAD;
+ break;
+ case IPPROTO_UDP:
+ flag_ok = M_UDP_CSUM_IN_OK;
+ flag_bad = M_UDP_CSUM_IN_BAD;
+ break;
+ case IPPROTO_ICMP:
+#ifdef INET6
+ case IPPROTO_ICMPV6:
+#endif /* INET6 */
+ flag_ok = flag_bad = 0;
+ break;
+ default:
+ return (1);
+ }
+ if (m->m_pkthdr.csum_flags & flag_ok)
+ return (0);
+ if (m->m_pkthdr.csum_flags & flag_bad)
+ return (1);
+ if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
+ return (1);
+ if (m->m_pkthdr.len < off + len)
+ return (1);
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ if (p == IPPROTO_ICMP) {
+ if (m->m_len < off)
+ return (1);
+ m->m_data += off;
+ m->m_len -= off;
+ sum = in_cksum(m, len);
+ m->m_data -= off;
+ m->m_len += off;
+ } else {
+ if (m->m_len < sizeof(struct ip))
+ return (1);
+ sum = in4_cksum(m, p, off, len);
+ }
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (m->m_len < sizeof(struct ip6_hdr))
+ return (1);
+ sum = in6_cksum(m, p, off, len);
+ break;
+#endif /* INET6 */
+ default:
+ return (1);
+ }
+ if (sum) {
+ m->m_pkthdr.csum_flags |= flag_bad;
+ switch (p) {
+ case IPPROTO_TCP:
+ KMOD_TCPSTAT_INC(tcps_rcvbadsum);
+ break;
+ case IPPROTO_UDP:
+ KMOD_UDPSTAT_INC(udps_badsum);
+ break;
+#ifdef INET
+ case IPPROTO_ICMP:
+ KMOD_ICMPSTAT_INC(icps_checksum);
+ break;
+#endif
+#ifdef INET6
+ case IPPROTO_ICMPV6:
+ KMOD_ICMP6STAT_INC(icp6s_checksum);
+ break;
+#endif /* INET6 */
+ }
+ return (1);
+ }
+ m->m_pkthdr.csum_flags |= flag_ok;
+ return (0);
+}
+#endif
+
+#ifndef __FreeBSD__
+struct pf_divert *
+pf_find_divert(struct mbuf *m)
+{
+ struct m_tag *mtag;
+
+ if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL)
+ return (NULL);
+
+ return ((struct pf_divert *)(mtag + 1));
+}
+
+struct pf_divert *
+pf_get_divert(struct mbuf *m)
+{
+ struct m_tag *mtag;
+
+ if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL) {
+ mtag = m_tag_get(PACKET_TAG_PF_DIVERT, sizeof(struct pf_divert),
+ M_NOWAIT);
+ if (mtag == NULL)
+ return (NULL);
+ bzero(mtag + 1, sizeof(struct pf_divert));
+ m_tag_prepend(m, mtag);
+ }
+
+ return ((struct pf_divert *)(mtag + 1));
+}
+#endif
+
+#ifdef INET
+int
+#ifdef __FreeBSD__
+pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
+ struct ether_header *eh, struct inpcb *inp)
+#else
+pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
+ struct ether_header *eh)
+#endif
+{
+ struct pfi_kif *kif;
+ u_short action, reason = 0, log = 0;
+ struct mbuf *m = *m0;
+#ifdef __FreeBSD__
+ struct ip *h = NULL;
+ struct m_tag *ipfwtag;
+ struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr;
+#else
+ struct ip *h;
+ struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
+#endif
+ struct pf_state *s = NULL;
+ struct pf_ruleset *ruleset = NULL;
+ struct pf_pdesc pd;
+ int off, dirndx, pqid = 0;
+
+#ifdef __FreeBSD__
+ PF_LOCK();
+ if (!V_pf_status.running)
+ {
+ PF_UNLOCK();
+ return (PF_PASS);
+ }
+#else
+ if (!pf_status.running)
+ return (PF_PASS);
+#endif
+
+ memset(&pd, 0, sizeof(pd));
+#ifdef __FreeBSD__
+ if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) {
+ PF_UNLOCK();
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_test: pf_get_mtag returned NULL\n"));
+ return (PF_DROP);
+ }
+#endif
+#ifndef __FreeBSD__
+ if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
+ kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
+ else
+#endif
+ kif = (struct pfi_kif *)ifp->if_pf_kif;
+
+ if (kif == NULL) {
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname));
+ return (PF_DROP);
+ }
+ if (kif->pfik_flags & PFI_IFLAG_SKIP)
+#ifdef __FreeBSD__
+ {
+ PF_UNLOCK();
+#endif
+ return (PF_PASS);
+#ifdef __FreeBSD__
+ }
+#endif
+
+#ifdef __FreeBSD__
+ M_ASSERTPKTHDR(m);
+#else
+#ifdef DIAGNOSTIC
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("non-M_PKTHDR is passed to pf_test");
+#endif /* DIAGNOSTIC */
+#endif
+
+ if (m->m_pkthdr.len < (int)sizeof(*h)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_SHORT);
+ log = 1;
+ goto done;
+ }
+
+#ifdef __FreeBSD__
+ if (m->m_flags & M_SKIP_FIREWALL) {
+ PF_UNLOCK();
+ return (PF_PASS);
+ }
+#else
+ if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED)
+ return (PF_PASS);
+#endif
+
+#ifdef __FreeBSD__
+ if (ip_divert_ptr != NULL &&
+ ((ipfwtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL)) != NULL)) {
+ struct ipfw_rule_ref *rr = (struct ipfw_rule_ref *)(ipfwtag+1);
+ if (rr->info & IPFW_IS_DIVERT && rr->rulenum == 0) {
+ pd.pf_mtag->flags |= PF_PACKET_LOOPED;
+ m_tag_delete(m, ipfwtag);
+ }
+ if (pd.pf_mtag->flags & PF_FASTFWD_OURS_PRESENT) {
+ m->m_flags |= M_FASTFWD_OURS;
+ pd.pf_mtag->flags &= ~PF_FASTFWD_OURS_PRESENT;
+ }
+ } else
+#endif
+ /* We do IP header normalization and packet reassembly here */
+ if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) {
+ action = PF_DROP;
+ goto done;
+ }
+ m = *m0; /* pf_normalize messes with m0 */
+ h = mtod(m, struct ip *);
+
+ off = h->ip_hl << 2;
+ if (off < (int)sizeof(*h)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_SHORT);
+ log = 1;
+ goto done;
+ }
+
+ pd.src = (struct pf_addr *)&h->ip_src;
+ pd.dst = (struct pf_addr *)&h->ip_dst;
+ pd.sport = pd.dport = NULL;
+ pd.ip_sum = &h->ip_sum;
+ pd.proto_sum = NULL;
+ pd.proto = h->ip_p;
+ pd.dir = dir;
+ pd.sidx = (dir == PF_IN) ? 0 : 1;
+ pd.didx = (dir == PF_IN) ? 1 : 0;
+ pd.af = AF_INET;
+ pd.tos = h->ip_tos;
+ pd.tot_len = ntohs(h->ip_len);
+ pd.eh = eh;
+
+ /* handle fragments that didn't get reassembled by normalization */
+ if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
+ action = pf_test_fragment(&r, dir, kif, m, h,
+ &pd, &a, &ruleset);
+ goto done;
+ }
+
+ switch (h->ip_p) {
+
+ case IPPROTO_TCP: {
+ struct tcphdr th;
+
+ pd.hdr.tcp = &th;
+ if (!pf_pull_hdr(m, off, &th, sizeof(th),
+ &action, &reason, AF_INET)) {
+ log = action != PF_PASS;
+ goto done;
+ }
+ pd.p_len = pd.tot_len - off - (th.th_off << 2);
+ if ((th.th_flags & TH_ACK) && pd.p_len == 0)
+ pqid = 1;
+ action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
+ if (action == PF_DROP)
+ goto done;
+ action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
+ &reason);
+ if (action == PF_PASS) {
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_update_state_ptr != NULL)
+ pfsync_update_state_ptr(s);
+#else
+ pfsync_update_state(s);
+#endif
+#endif /* NPFSYNC */
+ r = s->rule.ptr;
+ a = s->anchor.ptr;
+ log = s->log;
+ } else if (s == NULL)
+#ifdef __FreeBSD__
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, NULL, inp);
+#else
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, &ipintrq);
+#endif
+ break;
+ }
+
+ case IPPROTO_UDP: {
+ struct udphdr uh;
+
+ pd.hdr.udp = &uh;
+ if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
+ &action, &reason, AF_INET)) {
+ log = action != PF_PASS;
+ goto done;
+ }
+ if (uh.uh_dport == 0 ||
+ ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
+ ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_SHORT);
+ goto done;
+ }
+ action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
+ if (action == PF_PASS) {
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_update_state_ptr != NULL)
+ pfsync_update_state_ptr(s);
+#else
+ pfsync_update_state(s);
+#endif
+#endif /* NPFSYNC */
+ r = s->rule.ptr;
+ a = s->anchor.ptr;
+ log = s->log;
+ } else if (s == NULL)
+#ifdef __FreeBSD__
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, NULL, inp);
+#else
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, &ipintrq);
+#endif
+ break;
+ }
+
+ case IPPROTO_ICMP: {
+ struct icmp ih;
+
+ pd.hdr.icmp = &ih;
+ if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN,
+ &action, &reason, AF_INET)) {
+ log = action != PF_PASS;
+ goto done;
+ }
+ action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
+ &reason);
+ if (action == PF_PASS) {
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_update_state_ptr != NULL)
+ pfsync_update_state_ptr(s);
+#else
+ pfsync_update_state(s);
+#endif
+#endif /* NPFSYNC */
+ r = s->rule.ptr;
+ a = s->anchor.ptr;
+ log = s->log;
+ } else if (s == NULL)
+#ifdef __FreeBSD__
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, NULL, inp);
+#else
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, &ipintrq);
+#endif
+ break;
+ }
+
+#ifdef INET6
+ case IPPROTO_ICMPV6: {
+ action = PF_DROP;
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: dropping IPv4 packet with ICMPv6 payload\n"));
+ goto done;
+ }
+#endif
+
+ default:
+ action = pf_test_state_other(&s, dir, kif, m, &pd);
+ if (action == PF_PASS) {
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_update_state_ptr != NULL)
+ pfsync_update_state_ptr(s);
+#else
+ pfsync_update_state(s);
+#endif
+#endif /* NPFSYNC */
+ r = s->rule.ptr;
+ a = s->anchor.ptr;
+ log = s->log;
+ } else if (s == NULL)
+#ifdef __FreeBSD__
+ action = pf_test_rule(&r, &s, dir, kif, m, off, h,
+ &pd, &a, &ruleset, NULL, inp);
+#else
+ action = pf_test_rule(&r, &s, dir, kif, m, off, h,
+ &pd, &a, &ruleset, &ipintrq);
+#endif
+ break;
+ }
+
+done:
+ if (action == PF_PASS && h->ip_hl > 5 &&
+ !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_IPOPTIONS);
+ log = 1;
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: dropping packet with ip options\n"));
+ }
+
+ if ((s && s->tag) || r->rtableid >= 0)
+#ifdef __FreeBSD__
+ pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag);
+#else
+ pf_tag_packet(m, s ? s->tag : 0, r->rtableid);
+#endif
+
+ if (dir == PF_IN && s && s->key[PF_SK_STACK])
+#ifdef __FreeBSD__
+ pd.pf_mtag->statekey = s->key[PF_SK_STACK];
+#else
+ m->m_pkthdr.pf.statekey = s->key[PF_SK_STACK];
+#endif
+
+#ifdef ALTQ
+ if (action == PF_PASS && r->qid) {
+#ifdef __FreeBSD__
+ if (pqid || (pd.tos & IPTOS_LOWDELAY))
+ pd.pf_mtag->qid = r->pqid;
+ else
+ pd.pf_mtag->qid = r->qid;
+ /* add hints for ecn */
+ pd.pf_mtag->hdr = h;
+
+#else
+ if (pqid || (pd.tos & IPTOS_LOWDELAY))
+ m->m_pkthdr.pf.qid = r->pqid;
+ else
+ m->m_pkthdr.pf.qid = r->qid;
+ /* add hints for ecn */
+ m->m_pkthdr.pf.hdr = h;
+#endif
+ }
+#endif /* ALTQ */
+
+ /*
+ * connections redirected to loopback should not match sockets
+ * bound specifically to loopback due to security implications,
+ * see tcp_input() and in_pcblookup_listen().
+ */
+ if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
+ pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
+ (s->nat_rule.ptr->action == PF_RDR ||
+ s->nat_rule.ptr->action == PF_BINAT) &&
+ (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
+#ifdef __FreeBSD__
+ m->m_flags |= M_SKIP_FIREWALL;
+#else
+ m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST;
+#endif
+
+#ifdef __FreeBSD__
+ if (action == PF_PASS && r->divert.port &&
+ ip_divert_ptr != NULL && !PACKET_LOOPED()) {
+
+ ipfwtag = m_tag_alloc(MTAG_IPFW_RULE, 0,
+ sizeof(struct ipfw_rule_ref), M_NOWAIT | M_ZERO);
+ if (ipfwtag != NULL) {
+ ((struct ipfw_rule_ref *)(ipfwtag+1))->info =
+ ntohs(r->divert.port);
+ ((struct ipfw_rule_ref *)(ipfwtag+1))->rulenum = dir;
+
+ m_tag_prepend(m, ipfwtag);
+
+ PF_UNLOCK();
+
+ if (m->m_flags & M_FASTFWD_OURS) {
+ pd.pf_mtag->flags |= PF_FASTFWD_OURS_PRESENT;
+ m->m_flags &= ~M_FASTFWD_OURS;
+ }
+
+ ip_divert_ptr(*m0,
+ dir == PF_IN ? DIR_IN : DIR_OUT);
+ *m0 = NULL;
+ return (action);
+ } else {
+ /* XXX: ipfw has the same behaviour! */
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_MEMORY);
+ log = 1;
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: failed to allocate divert tag\n"));
+ }
+ }
+#else
+ if (dir == PF_IN && action == PF_PASS && r->divert.port) {
+ struct pf_divert *divert;
+
+ if ((divert = pf_get_divert(m))) {
+ m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED;
+ divert->port = r->divert.port;
+ divert->addr.ipv4 = r->divert.addr.v4;
+ }
+ }
+#endif
+
+ if (log) {
+ struct pf_rule *lr;
+
+ if (s != NULL && s->nat_rule.ptr != NULL &&
+ s->nat_rule.ptr->log & PF_LOG_ALL)
+ lr = s->nat_rule.ptr;
+ else
+ lr = r;
+ PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset,
+ &pd);
+ }
+
+ kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
+ kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++;
+
+ if (action == PF_PASS || r->action == PF_DROP) {
+ dirndx = (dir == PF_OUT);
+ r->packets[dirndx]++;
+ r->bytes[dirndx] += pd.tot_len;
+ if (a != NULL) {
+ a->packets[dirndx]++;
+ a->bytes[dirndx] += pd.tot_len;
+ }
+ if (s != NULL) {
+ if (s->nat_rule.ptr != NULL) {
+ s->nat_rule.ptr->packets[dirndx]++;
+ s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
+ }
+ if (s->src_node != NULL) {
+ s->src_node->packets[dirndx]++;
+ s->src_node->bytes[dirndx] += pd.tot_len;
+ }
+ if (s->nat_src_node != NULL) {
+ s->nat_src_node->packets[dirndx]++;
+ s->nat_src_node->bytes[dirndx] += pd.tot_len;
+ }
+ dirndx = (dir == s->direction) ? 0 : 1;
+ s->packets[dirndx]++;
+ s->bytes[dirndx] += pd.tot_len;
+ }
+ tr = r;
+ nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
+#ifdef __FreeBSD__
+ if (nr != NULL && r == &V_pf_default_rule)
+#else
+ if (nr != NULL && r == &pf_default_rule)
+#endif
+ tr = nr;
+ if (tr->src.addr.type == PF_ADDR_TABLE)
+ pfr_update_stats(tr->src.addr.p.tbl,
+ (s == NULL) ? pd.src :
+ &s->key[(s->direction == PF_IN)]->
+ addr[(s->direction == PF_OUT)],
+ pd.af, pd.tot_len, dir == PF_OUT,
+ r->action == PF_PASS, tr->src.neg);
+ if (tr->dst.addr.type == PF_ADDR_TABLE)
+ pfr_update_stats(tr->dst.addr.p.tbl,
+ (s == NULL) ? pd.dst :
+ &s->key[(s->direction == PF_IN)]->
+ addr[(s->direction == PF_IN)],
+ pd.af, pd.tot_len, dir == PF_OUT,
+ r->action == PF_PASS, tr->dst.neg);
+ }
+
+ switch (action) {
+ case PF_SYNPROXY_DROP:
+ m_freem(*m0);
+ case PF_DEFER:
+ *m0 = NULL;
+ action = PF_PASS;
+ break;
+ default:
+ /* pf_route can free the mbuf causing *m0 to become NULL */
+ if (r->rt)
+ pf_route(m0, r, dir, kif->pfik_ifp, s, &pd);
+ break;
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ return (action);
+}
+#endif /* INET */
+
+#ifdef INET6
+int
+#ifdef __FreeBSD__
+pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
+ struct ether_header *eh, struct inpcb *inp)
+#else
+pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
+ struct ether_header *eh)
+#endif
+{
+ struct pfi_kif *kif;
+ u_short action, reason = 0, log = 0;
+ struct mbuf *m = *m0, *n = NULL;
+#ifdef __FreeBSD__
+ struct ip6_hdr *h = NULL;
+ struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr;
+#else
+ struct ip6_hdr *h;
+ struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
+#endif
+ struct pf_state *s = NULL;
+ struct pf_ruleset *ruleset = NULL;
+ struct pf_pdesc pd;
+ int off, terminal = 0, dirndx, rh_cnt = 0;
+
+#ifdef __FreeBSD__
+ PF_LOCK();
+ if (!V_pf_status.running) {
+ PF_UNLOCK();
+ return (PF_PASS);
+ }
+#else
+ if (!pf_status.running)
+ return (PF_PASS);
+#endif
+
+ memset(&pd, 0, sizeof(pd));
+#ifdef __FreeBSD__
+ if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) {
+ PF_UNLOCK();
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_test: pf_get_mtag returned NULL\n"));
+ return (PF_DROP);
+ }
+#endif
+#ifndef __FreeBSD__
+ if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
+ kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
+ else
+#endif
+ kif = (struct pfi_kif *)ifp->if_pf_kif;
+
+ if (kif == NULL) {
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ DPFPRINTF(PF_DEBUG_URGENT,
+ ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname));
+ return (PF_DROP);
+ }
+ if (kif->pfik_flags & PFI_IFLAG_SKIP)
+#ifdef __FreeBSD__
+ {
+ PF_UNLOCK();
+#endif
+ return (PF_PASS);
+#ifdef __FreeBSD__
+ }
+#endif
+
+#ifdef __FreeBSD__
+ M_ASSERTPKTHDR(m);
+#else
+#ifdef DIAGNOSTIC
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("non-M_PKTHDR is passed to pf_test6");
+#endif /* DIAGNOSTIC */
+#endif
+
+ if (m->m_pkthdr.len < (int)sizeof(*h)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_SHORT);
+ log = 1;
+ goto done;
+ }
+
+#ifdef __FreeBSD__
+ if (pd.pf_mtag->flags & PF_TAG_GENERATED) {
+ PF_UNLOCK();
+#else
+ if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED)
+#endif
+ return (PF_PASS);
+#ifdef __FreeBSD__
+ }
+#endif
+
+ /* We do IP header normalization and packet reassembly here */
+ if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) {
+ action = PF_DROP;
+ goto done;
+ }
+ m = *m0; /* pf_normalize messes with m0 */
+ h = mtod(m, struct ip6_hdr *);
+
+#if 1
+ /*
+ * we do not support jumbogram yet. if we keep going, zero ip6_plen
+ * will do something bad, so drop the packet for now.
+ */
+ if (htons(h->ip6_plen) == 0) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_NORM); /*XXX*/
+ goto done;
+ }
+#endif
+
+ pd.src = (struct pf_addr *)&h->ip6_src;
+ pd.dst = (struct pf_addr *)&h->ip6_dst;
+ pd.sport = pd.dport = NULL;
+ pd.ip_sum = NULL;
+ pd.proto_sum = NULL;
+ pd.dir = dir;
+ pd.sidx = (dir == PF_IN) ? 0 : 1;
+ pd.didx = (dir == PF_IN) ? 1 : 0;
+ pd.af = AF_INET6;
+ pd.tos = 0;
+ pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
+ pd.eh = eh;
+
+ off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr);
+ pd.proto = h->ip6_nxt;
+ do {
+ switch (pd.proto) {
+ case IPPROTO_FRAGMENT:
+ action = pf_test_fragment(&r, dir, kif, m, h,
+ &pd, &a, &ruleset);
+ if (action == PF_DROP)
+ REASON_SET(&reason, PFRES_FRAG);
+ goto done;
+ case IPPROTO_ROUTING: {
+ struct ip6_rthdr rthdr;
+
+ if (rh_cnt++) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: IPv6 more than one rthdr\n"));
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_IPOPTIONS);
+ log = 1;
+ goto done;
+ }
+ if (!pf_pull_hdr(m, off, &rthdr, sizeof(rthdr), NULL,
+ &reason, pd.af)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: IPv6 short rthdr\n"));
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_SHORT);
+ log = 1;
+ goto done;
+ }
+ if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: IPv6 rthdr0\n"));
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_IPOPTIONS);
+ log = 1;
+ goto done;
+ }
+ /* FALLTHROUGH */
+ }
+ case IPPROTO_AH:
+ case IPPROTO_HOPOPTS:
+ case IPPROTO_DSTOPTS: {
+ /* get next header and header length */
+ struct ip6_ext opt6;
+
+ if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6),
+ NULL, &reason, pd.af)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: IPv6 short opt\n"));
+ action = PF_DROP;
+ log = 1;
+ goto done;
+ }
+ if (pd.proto == IPPROTO_AH)
+ off += (opt6.ip6e_len + 2) * 4;
+ else
+ off += (opt6.ip6e_len + 1) * 8;
+ pd.proto = opt6.ip6e_nxt;
+ /* goto the next header */
+ break;
+ }
+ default:
+ terminal++;
+ break;
+ }
+ } while (!terminal);
+
+ /* if there's no routing header, use unmodified mbuf for checksumming */
+ if (!n)
+ n = m;
+
+ switch (pd.proto) {
+
+ case IPPROTO_TCP: {
+ struct tcphdr th;
+
+ pd.hdr.tcp = &th;
+ if (!pf_pull_hdr(m, off, &th, sizeof(th),
+ &action, &reason, AF_INET6)) {
+ log = action != PF_PASS;
+ goto done;
+ }
+ pd.p_len = pd.tot_len - off - (th.th_off << 2);
+ action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
+ if (action == PF_DROP)
+ goto done;
+ action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
+ &reason);
+ if (action == PF_PASS) {
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_update_state_ptr != NULL)
+ pfsync_update_state_ptr(s);
+#else
+ pfsync_update_state(s);
+#endif
+#endif /* NPFSYNC */
+ r = s->rule.ptr;
+ a = s->anchor.ptr;
+ log = s->log;
+ } else if (s == NULL)
+#ifdef __FreeBSD__
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, NULL, inp);
+#else
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, &ip6intrq);
+#endif
+ break;
+ }
+
+ case IPPROTO_UDP: {
+ struct udphdr uh;
+
+ pd.hdr.udp = &uh;
+ if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
+ &action, &reason, AF_INET6)) {
+ log = action != PF_PASS;
+ goto done;
+ }
+ if (uh.uh_dport == 0 ||
+ ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
+ ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_SHORT);
+ goto done;
+ }
+ action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
+ if (action == PF_PASS) {
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_update_state_ptr != NULL)
+ pfsync_update_state_ptr(s);
+#else
+ pfsync_update_state(s);
+#endif
+#endif /* NPFSYNC */
+ r = s->rule.ptr;
+ a = s->anchor.ptr;
+ log = s->log;
+ } else if (s == NULL)
+#ifdef __FreeBSD__
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, NULL, inp);
+#else
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, &ip6intrq);
+#endif
+ break;
+ }
+
+ case IPPROTO_ICMP: {
+ action = PF_DROP;
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: dropping IPv6 packet with ICMPv4 payload\n"));
+ goto done;
+ }
+
+ case IPPROTO_ICMPV6: {
+ struct icmp6_hdr ih;
+
+ pd.hdr.icmp6 = &ih;
+ if (!pf_pull_hdr(m, off, &ih, sizeof(ih),
+ &action, &reason, AF_INET6)) {
+ log = action != PF_PASS;
+ goto done;
+ }
+ action = pf_test_state_icmp(&s, dir, kif,
+ m, off, h, &pd, &reason);
+ if (action == PF_PASS) {
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_update_state_ptr != NULL)
+ pfsync_update_state_ptr(s);
+#else
+ pfsync_update_state(s);
+#endif
+#endif /* NPFSYNC */
+ r = s->rule.ptr;
+ a = s->anchor.ptr;
+ log = s->log;
+ } else if (s == NULL)
+#ifdef __FreeBSD__
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, NULL, inp);
+#else
+ action = pf_test_rule(&r, &s, dir, kif,
+ m, off, h, &pd, &a, &ruleset, &ip6intrq);
+#endif
+ break;
+ }
+
+ default:
+ action = pf_test_state_other(&s, dir, kif, m, &pd);
+ if (action == PF_PASS) {
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_update_state_ptr != NULL)
+ pfsync_update_state_ptr(s);
+#else
+ pfsync_update_state(s);
+#endif
+#endif /* NPFSYNC */
+ r = s->rule.ptr;
+ a = s->anchor.ptr;
+ log = s->log;
+ } else if (s == NULL)
+#ifdef __FreeBSD__
+ action = pf_test_rule(&r, &s, dir, kif, m, off, h,
+ &pd, &a, &ruleset, NULL, inp);
+#else
+ action = pf_test_rule(&r, &s, dir, kif, m, off, h,
+ &pd, &a, &ruleset, &ip6intrq);
+#endif
+ break;
+ }
+
+done:
+ if (n != m) {
+ m_freem(n);
+ n = NULL;
+ }
+
+ /* handle dangerous IPv6 extension headers. */
+ if (action == PF_PASS && rh_cnt &&
+ !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) {
+ action = PF_DROP;
+ REASON_SET(&reason, PFRES_IPOPTIONS);
+ log = 1;
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: dropping packet with dangerous v6 headers\n"));
+ }
+
+ if ((s && s->tag) || r->rtableid >= 0)
+#ifdef __FreeBSD__
+ pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag);
+#else
+ pf_tag_packet(m, s ? s->tag : 0, r->rtableid);
+#endif
+
+ if (dir == PF_IN && s && s->key[PF_SK_STACK])
+#ifdef __FreeBSD__
+ pd.pf_mtag->statekey = s->key[PF_SK_STACK];
+#else
+ m->m_pkthdr.pf.statekey = s->key[PF_SK_STACK];
+#endif
+
+#ifdef ALTQ
+ if (action == PF_PASS && r->qid) {
+#ifdef __FreeBSD__
+ if (pd.tos & IPTOS_LOWDELAY)
+ pd.pf_mtag->qid = r->pqid;
+ else
+ pd.pf_mtag->qid = r->qid;
+ /* add hints for ecn */
+ pd.pf_mtag->hdr = h;
+#else
+ if (pd.tos & IPTOS_LOWDELAY)
+ m->m_pkthdr.pf.qid = r->pqid;
+ else
+ m->m_pkthdr.pf.qid = r->qid;
+ /* add hints for ecn */
+ m->m_pkthdr.pf.hdr = h;
+#endif
+ }
+#endif /* ALTQ */
+
+ if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
+ pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
+ (s->nat_rule.ptr->action == PF_RDR ||
+ s->nat_rule.ptr->action == PF_BINAT) &&
+ IN6_IS_ADDR_LOOPBACK(&pd.dst->v6))
+#ifdef __FreeBSD__
+ m->m_flags |= M_SKIP_FIREWALL;
+#else
+ m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST;
+#endif
+
+#ifdef __FreeBSD__
+ /* XXX: Anybody working on it?! */
+ if (r->divert.port)
+ printf("pf: divert(9) is not supported for IPv6\n");
+#else
+ if (dir == PF_IN && action == PF_PASS && r->divert.port) {
+ struct pf_divert *divert;
+
+ if ((divert = pf_get_divert(m))) {
+ m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED;
+ divert->port = r->divert.port;
+ divert->addr.ipv6 = r->divert.addr.v6;
+ }
+ }
+#endif
+
+ if (log) {
+ struct pf_rule *lr;
+
+ if (s != NULL && s->nat_rule.ptr != NULL &&
+ s->nat_rule.ptr->log & PF_LOG_ALL)
+ lr = s->nat_rule.ptr;
+ else
+ lr = r;
+ PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset,
+ &pd);
+ }
+
+ kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
+ kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++;
+
+ if (action == PF_PASS || r->action == PF_DROP) {
+ dirndx = (dir == PF_OUT);
+ r->packets[dirndx]++;
+ r->bytes[dirndx] += pd.tot_len;
+ if (a != NULL) {
+ a->packets[dirndx]++;
+ a->bytes[dirndx] += pd.tot_len;
+ }
+ if (s != NULL) {
+ if (s->nat_rule.ptr != NULL) {
+ s->nat_rule.ptr->packets[dirndx]++;
+ s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
+ }
+ if (s->src_node != NULL) {
+ s->src_node->packets[dirndx]++;
+ s->src_node->bytes[dirndx] += pd.tot_len;
+ }
+ if (s->nat_src_node != NULL) {
+ s->nat_src_node->packets[dirndx]++;
+ s->nat_src_node->bytes[dirndx] += pd.tot_len;
+ }
+ dirndx = (dir == s->direction) ? 0 : 1;
+ s->packets[dirndx]++;
+ s->bytes[dirndx] += pd.tot_len;
+ }
+ tr = r;
+ nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
+#ifdef __FreeBSD__
+ if (nr != NULL && r == &V_pf_default_rule)
+#else
+ if (nr != NULL && r == &pf_default_rule)
+#endif
+ tr = nr;
+ if (tr->src.addr.type == PF_ADDR_TABLE)
+ pfr_update_stats(tr->src.addr.p.tbl,
+ (s == NULL) ? pd.src :
+ &s->key[(s->direction == PF_IN)]->addr[0],
+ pd.af, pd.tot_len, dir == PF_OUT,
+ r->action == PF_PASS, tr->src.neg);
+ if (tr->dst.addr.type == PF_ADDR_TABLE)
+ pfr_update_stats(tr->dst.addr.p.tbl,
+ (s == NULL) ? pd.dst :
+ &s->key[(s->direction == PF_IN)]->addr[1],
+ pd.af, pd.tot_len, dir == PF_OUT,
+ r->action == PF_PASS, tr->dst.neg);
+ }
+
+ switch (action) {
+ case PF_SYNPROXY_DROP:
+ m_freem(*m0);
+ case PF_DEFER:
+ *m0 = NULL;
+ action = PF_PASS;
+ break;
+ default:
+ /* pf_route6 can free the mbuf causing *m0 to become NULL */
+ if (r->rt)
+ pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd);
+ break;
+ }
+
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ return (action);
+}
+#endif /* INET6 */
+
+int
+pf_check_congestion(struct ifqueue *ifq)
+{
+#ifdef __FreeBSD__
+ /* XXX_IMPORT: later */
+ return (0);
+#else
+ if (ifq->ifq_congestion)
+ return (1);
+ else
+ return (0);
+#endif
+}
+
+/*
+ * must be called whenever any addressing information such as
+ * address, port, protocol has changed
+ */
+void
+pf_pkt_addr_changed(struct mbuf *m)
+{
+#ifdef __FreeBSD__
+ struct pf_mtag *pf_tag;
+
+ if ((pf_tag = pf_find_mtag(m)) != NULL)
+ pf_tag->statekey = NULL;
+#else
+ m->m_pkthdr.pf.statekey = NULL;
+#endif
+}
diff --git a/sys/contrib/pf/net/pf_if.c b/sys/contrib/pf/net/pf_if.c
new file mode 100644
index 0000000..6336c79
--- /dev/null
+++ b/sys/contrib/pf/net/pf_if.c
@@ -0,0 +1,1111 @@
+/* $OpenBSD: pf_if.c,v 1.54 2008/06/14 16:55:28 mk Exp $ */
+
+/*
+ * Copyright 2005 Henning Brauer <henning@openbsd.org>
+ * Copyright 2005 Ryan McBride <mcbride@openbsd.org>
+ * Copyright (c) 2001 Daniel Hartmeier
+ * Copyright (c) 2003 Cedric Berger
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__FreeBSD__)
+#include "opt_inet.h"
+#include "opt_inet6.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#ifdef __FreeBSD__
+#include <sys/malloc.h>
+#endif
+#include <sys/mbuf.h>
+#include <sys/filio.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#ifndef __FreeBSD__
+#include <sys/device.h>
+#endif
+#include <sys/time.h>
+#ifndef __FreeBSD__
+#include <sys/pool.h>
+#endif
+
+#include <net/if.h>
+#include <net/if_types.h>
+#ifdef __FreeBSD__
+#include <net/vnet.h>
+#endif
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#include <net/pfvar.h>
+
+#ifdef INET6
+#include <netinet/ip6.h>
+#endif /* INET6 */
+
+#ifdef __FreeBSD__
+VNET_DEFINE(struct pfi_kif *, pfi_all);
+VNET_DEFINE(uma_zone_t, pfi_addr_pl);
+VNET_DEFINE(struct pfi_ifhead, pfi_ifs);
+#define V_pfi_ifs VNET(pfi_ifs)
+VNET_DEFINE(long, pfi_update);
+#define V_pfi_update VNET(pfi_update)
+VNET_DEFINE(struct pfr_addr *, pfi_buffer);
+#define V_pfi_buffer VNET(pfi_buffer)
+VNET_DEFINE(int, pfi_buffer_cnt);
+#define V_pfi_buffer_cnt VNET(pfi_buffer_cnt)
+VNET_DEFINE(int, pfi_buffer_max);
+#define V_pfi_buffer_max VNET(pfi_buffer_max)
+#else
+struct pfi_kif *pfi_all = NULL;
+struct pool pfi_addr_pl;
+struct pfi_ifhead pfi_ifs;
+long pfi_update = 1;
+struct pfr_addr *pfi_buffer;
+int pfi_buffer_cnt;
+int pfi_buffer_max;
+#endif
+#ifdef __FreeBSD__
+eventhandler_tag pfi_attach_cookie;
+eventhandler_tag pfi_detach_cookie;
+eventhandler_tag pfi_attach_group_cookie;
+eventhandler_tag pfi_change_group_cookie;
+eventhandler_tag pfi_detach_group_cookie;
+eventhandler_tag pfi_ifaddr_event_cookie;
+#endif
+
+void pfi_kif_update(struct pfi_kif *);
+void pfi_dynaddr_update(struct pfi_dynaddr *dyn);
+void pfi_table_update(struct pfr_ktable *, struct pfi_kif *,
+ int, int);
+void pfi_kifaddr_update(void *);
+void pfi_instance_add(struct ifnet *, int, int);
+void pfi_address_add(struct sockaddr *, int, int);
+int pfi_if_compare(struct pfi_kif *, struct pfi_kif *);
+int pfi_skip_if(const char *, struct pfi_kif *);
+int pfi_unmask(void *);
+#ifdef __FreeBSD__
+void pfi_attach_ifnet_event(void * __unused, struct ifnet *);
+void pfi_detach_ifnet_event(void * __unused, struct ifnet *);
+void pfi_attach_group_event(void *, struct ifg_group *);
+void pfi_change_group_event(void *, char *);
+void pfi_detach_group_event(void *, struct ifg_group *);
+void pfi_ifaddr_event(void * __unused, struct ifnet *);
+#endif
+
+RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
+RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
+
+#define PFI_BUFFER_MAX 0x10000
+#define PFI_MTYPE M_IFADDR
+
+void
+pfi_initialize(void)
+{
+#ifdef __FreeBSD__
+ if (V_pfi_all != NULL) /* already initialized */
+#else
+ if (pfi_all != NULL) /* already initialized */
+#endif
+ return;
+
+#ifndef __FreeBSD__
+ pool_init(&V_pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0,
+ "pfiaddrpl", &pool_allocator_nointr);
+#endif
+#ifdef __FreeBSD__
+ V_pfi_buffer_max = 64;
+ V_pfi_buffer = malloc(V_pfi_buffer_max * sizeof(*V_pfi_buffer),
+ PFI_MTYPE, M_WAITOK);
+
+ if ((V_pfi_all = pfi_kif_get(IFG_ALL)) == NULL)
+#else
+ pfi_buffer_max = 64;
+ pfi_buffer = malloc(pfi_buffer_max * sizeof(*pfi_buffer),
+ PFI_MTYPE, M_WAITOK);
+
+ if ((pfi_all = pfi_kif_get(IFG_ALL)) == NULL)
+#endif
+ panic("pfi_kif_get for pfi_all failed");
+#ifdef __FreeBSD__
+ struct ifg_group *ifg;
+ struct ifnet *ifp;
+
+ IFNET_RLOCK();
+ TAILQ_FOREACH(ifg, &V_ifg_head, ifg_next)
+ pfi_attach_ifgroup(ifg);
+ TAILQ_FOREACH(ifp, &V_ifnet, if_link)
+ pfi_attach_ifnet(ifp);
+ IFNET_RUNLOCK();
+
+ pfi_attach_cookie = EVENTHANDLER_REGISTER(ifnet_arrival_event,
+ pfi_attach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
+ pfi_detach_cookie = EVENTHANDLER_REGISTER(ifnet_departure_event,
+ pfi_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
+ pfi_attach_group_cookie = EVENTHANDLER_REGISTER(group_attach_event,
+ pfi_attach_group_event, curvnet, EVENTHANDLER_PRI_ANY);
+ pfi_change_group_cookie = EVENTHANDLER_REGISTER(group_change_event,
+ pfi_change_group_event, curvnet, EVENTHANDLER_PRI_ANY);
+ pfi_detach_group_cookie = EVENTHANDLER_REGISTER(group_detach_event,
+ pfi_detach_group_event, curvnet, EVENTHANDLER_PRI_ANY);
+ pfi_ifaddr_event_cookie = EVENTHANDLER_REGISTER(ifaddr_event,
+ pfi_ifaddr_event, NULL, EVENTHANDLER_PRI_ANY);
+#endif
+}
+
+#ifdef __FreeBSD__
+void
+pfi_cleanup(void)
+{
+ struct pfi_kif *p;
+
+ PF_UNLOCK();
+ EVENTHANDLER_DEREGISTER(ifnet_arrival_event, pfi_attach_cookie);
+ EVENTHANDLER_DEREGISTER(ifnet_departure_event, pfi_detach_cookie);
+ EVENTHANDLER_DEREGISTER(group_attach_event, pfi_attach_group_cookie);
+ EVENTHANDLER_DEREGISTER(group_change_event, pfi_change_group_cookie);
+ EVENTHANDLER_DEREGISTER(group_detach_event, pfi_detach_group_cookie);
+ EVENTHANDLER_DEREGISTER(ifaddr_event, pfi_ifaddr_event_cookie);
+ PF_LOCK();
+
+ V_pfi_all = NULL;
+ while ((p = RB_MIN(pfi_ifhead, &V_pfi_ifs))) {
+ if (p->pfik_rules || p->pfik_states) {
+ printf("pfi_cleanup: dangling refs for %s\n",
+ p->pfik_name);
+ }
+
+ RB_REMOVE(pfi_ifhead, &V_pfi_ifs, p);
+ free(p, PFI_MTYPE);
+ }
+
+ free(V_pfi_buffer, PFI_MTYPE);
+}
+#endif
+
+struct pfi_kif *
+pfi_kif_get(const char *kif_name)
+{
+ struct pfi_kif *kif;
+ struct pfi_kif_cmp s;
+
+ bzero(&s, sizeof(s));
+ strlcpy(s.pfik_name, kif_name, sizeof(s.pfik_name));
+#ifdef __FreeBSD__
+ if ((kif = RB_FIND(pfi_ifhead, &V_pfi_ifs, (struct pfi_kif *)&s)) != NULL)
+#else
+ if ((kif = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&s)) != NULL)
+#endif
+ return (kif);
+
+ /* create new one */
+#ifdef __FreeBSD__
+ if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_NOWAIT | M_ZERO)) == NULL)
+#else
+ if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_DONTWAIT|M_ZERO)) == NULL)
+#endif
+ return (NULL);
+
+ strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name));
+#ifdef __FreeBSD__
+ /*
+ * It seems that the value of time_second is in unintialzied state
+ * when pf sets interface statistics clear time in boot phase if pf
+ * was statically linked to kernel. Instead of setting the bogus
+ * time value have pfi_get_ifaces handle this case. In
+ * pfi_get_ifaces it uses boottime.tv_sec if it sees the time is 0.
+ */
+ kif->pfik_tzero = time_second > 1 ? time_second : 0;
+#else
+ kif->pfik_tzero = time_second;
+#endif
+ TAILQ_INIT(&kif->pfik_dynaddrs);
+
+#ifdef __FreeBSD__
+ RB_INSERT(pfi_ifhead, &V_pfi_ifs, kif);
+#else
+ RB_INSERT(pfi_ifhead, &pfi_ifs, kif);
+#endif
+
+ return (kif);
+}
+
+void
+pfi_kif_ref(struct pfi_kif *kif, enum pfi_kif_refs what)
+{
+ switch (what) {
+ case PFI_KIF_REF_RULE:
+ kif->pfik_rules++;
+ break;
+ case PFI_KIF_REF_STATE:
+ kif->pfik_states++;
+ break;
+ default:
+ panic("pfi_kif_ref with unknown type");
+ }
+}
+
+void
+pfi_kif_unref(struct pfi_kif *kif, enum pfi_kif_refs what)
+{
+ if (kif == NULL)
+ return;
+
+ switch (what) {
+ case PFI_KIF_REF_NONE:
+ break;
+ case PFI_KIF_REF_RULE:
+ if (kif->pfik_rules <= 0) {
+ printf("pfi_kif_unref: rules refcount <= 0\n");
+ return;
+ }
+ kif->pfik_rules--;
+ break;
+ case PFI_KIF_REF_STATE:
+ if (kif->pfik_states <= 0) {
+ printf("pfi_kif_unref: state refcount <= 0\n");
+ return;
+ }
+ kif->pfik_states--;
+ break;
+ default:
+ panic("pfi_kif_unref with unknown type");
+ }
+
+#ifdef __FreeBSD__
+ if (kif->pfik_ifp != NULL || kif->pfik_group != NULL || kif == V_pfi_all)
+#else
+ if (kif->pfik_ifp != NULL || kif->pfik_group != NULL || kif == pfi_all)
+#endif
+ return;
+
+ if (kif->pfik_rules || kif->pfik_states)
+ return;
+
+#ifdef __FreeBSD__
+ RB_REMOVE(pfi_ifhead, &V_pfi_ifs, kif);
+#else
+ RB_REMOVE(pfi_ifhead, &pfi_ifs, kif);
+#endif
+ free(kif, PFI_MTYPE);
+}
+
+int
+pfi_kif_match(struct pfi_kif *rule_kif, struct pfi_kif *packet_kif)
+{
+ struct ifg_list *p;
+
+ if (rule_kif == NULL || rule_kif == packet_kif)
+ return (1);
+
+ if (rule_kif->pfik_group != NULL)
+ TAILQ_FOREACH(p, &packet_kif->pfik_ifp->if_groups, ifgl_next)
+ if (p->ifgl_group == rule_kif->pfik_group)
+ return (1);
+
+ return (0);
+}
+
+void
+pfi_attach_ifnet(struct ifnet *ifp)
+{
+ struct pfi_kif *kif;
+ int s;
+
+ pfi_initialize();
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ V_pfi_update++;
+#else
+ pfi_update++;
+#endif
+ if ((kif = pfi_kif_get(ifp->if_xname)) == NULL)
+ panic("pfi_kif_get failed");
+
+ kif->pfik_ifp = ifp;
+ ifp->if_pf_kif = (caddr_t)kif;
+
+#ifndef __FreeBSD__
+ if ((kif->pfik_ah_cookie = hook_establish(ifp->if_addrhooks, 1,
+ pfi_kifaddr_update, kif)) == NULL)
+ panic("pfi_attach_ifnet: cannot allocate '%s' address hook",
+ ifp->if_xname);
+#endif
+
+ pfi_kif_update(kif);
+
+ splx(s);
+}
+
+void
+pfi_detach_ifnet(struct ifnet *ifp)
+{
+ int s;
+ struct pfi_kif *kif;
+
+ if ((kif = (struct pfi_kif *)ifp->if_pf_kif) == NULL)
+ return;
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ V_pfi_update++;
+#else
+ pfi_update++;
+#endif
+#ifndef __FreeBSD__
+ hook_disestablish(ifp->if_addrhooks, kif->pfik_ah_cookie);
+#endif
+ pfi_kif_update(kif);
+
+ kif->pfik_ifp = NULL;
+ ifp->if_pf_kif = NULL;
+ pfi_kif_unref(kif, PFI_KIF_REF_NONE);
+ splx(s);
+}
+
+void
+pfi_attach_ifgroup(struct ifg_group *ifg)
+{
+ struct pfi_kif *kif;
+ int s;
+
+ pfi_initialize();
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ V_pfi_update++;
+#else
+ pfi_update++;
+#endif
+ if ((kif = pfi_kif_get(ifg->ifg_group)) == NULL)
+ panic("pfi_kif_get failed");
+
+ kif->pfik_group = ifg;
+ ifg->ifg_pf_kif = (caddr_t)kif;
+
+ splx(s);
+}
+
+void
+pfi_detach_ifgroup(struct ifg_group *ifg)
+{
+ int s;
+ struct pfi_kif *kif;
+
+ if ((kif = (struct pfi_kif *)ifg->ifg_pf_kif) == NULL)
+ return;
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ V_pfi_update++;
+#else
+ pfi_update++;
+#endif
+
+ kif->pfik_group = NULL;
+ ifg->ifg_pf_kif = NULL;
+ pfi_kif_unref(kif, PFI_KIF_REF_NONE);
+ splx(s);
+}
+
+void
+pfi_group_change(const char *group)
+{
+ struct pfi_kif *kif;
+ int s;
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ V_pfi_update++;
+#else
+ pfi_update++;
+#endif
+ if ((kif = pfi_kif_get(group)) == NULL)
+ panic("pfi_kif_get failed");
+
+ pfi_kif_update(kif);
+
+ splx(s);
+}
+
+int
+pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
+{
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ switch (dyn->pfid_acnt4) {
+ case 0:
+ return (0);
+ case 1:
+ return (PF_MATCHA(0, &dyn->pfid_addr4,
+ &dyn->pfid_mask4, a, AF_INET));
+ default:
+ return (pfr_match_addr(dyn->pfid_kt, a, AF_INET));
+ }
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ switch (dyn->pfid_acnt6) {
+ case 0:
+ return (0);
+ case 1:
+ return (PF_MATCHA(0, &dyn->pfid_addr6,
+ &dyn->pfid_mask6, a, AF_INET6));
+ default:
+ return (pfr_match_addr(dyn->pfid_kt, a, AF_INET6));
+ }
+ break;
+#endif /* INET6 */
+ default:
+ return (0);
+ }
+}
+
+int
+pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
+{
+ struct pfi_dynaddr *dyn;
+ char tblname[PF_TABLE_NAME_SIZE];
+ struct pf_ruleset *ruleset = NULL;
+ int s, rv = 0;
+
+ if (aw->type != PF_ADDR_DYNIFTL)
+ return (0);
+#ifdef __FreeBSD__
+ /* XXX: revisit! */
+ if ((dyn = pool_get(&V_pfi_addr_pl, PR_WAITOK | PR_ZERO))
+#else
+ if ((dyn = pool_get(&pfi_addr_pl, PR_WAITOK | PR_LIMITFAIL | PR_ZERO))
+#endif
+ == NULL)
+ return (1);
+
+ s = splsoftnet();
+ if (!strcmp(aw->v.ifname, "self"))
+ dyn->pfid_kif = pfi_kif_get(IFG_ALL);
+ else
+ dyn->pfid_kif = pfi_kif_get(aw->v.ifname);
+ if (dyn->pfid_kif == NULL) {
+ rv = 1;
+ goto _bad;
+ }
+ pfi_kif_ref(dyn->pfid_kif, PFI_KIF_REF_RULE);
+
+ dyn->pfid_net = pfi_unmask(&aw->v.a.mask);
+ if (af == AF_INET && dyn->pfid_net == 32)
+ dyn->pfid_net = 128;
+ strlcpy(tblname, aw->v.ifname, sizeof(tblname));
+ if (aw->iflags & PFI_AFLAG_NETWORK)
+ strlcat(tblname, ":network", sizeof(tblname));
+ if (aw->iflags & PFI_AFLAG_BROADCAST)
+ strlcat(tblname, ":broadcast", sizeof(tblname));
+ if (aw->iflags & PFI_AFLAG_PEER)
+ strlcat(tblname, ":peer", sizeof(tblname));
+ if (aw->iflags & PFI_AFLAG_NOALIAS)
+ strlcat(tblname, ":0", sizeof(tblname));
+ if (dyn->pfid_net != 128)
+ snprintf(tblname + strlen(tblname),
+ sizeof(tblname) - strlen(tblname), "/%d", dyn->pfid_net);
+ if ((ruleset = pf_find_or_create_ruleset(PF_RESERVED_ANCHOR)) == NULL) {
+ rv = 1;
+ goto _bad;
+ }
+
+ if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, 1)) == NULL) {
+ rv = 1;
+ goto _bad;
+ }
+
+ dyn->pfid_kt->pfrkt_flags |= PFR_TFLAG_ACTIVE;
+ dyn->pfid_iflags = aw->iflags;
+ dyn->pfid_af = af;
+
+ TAILQ_INSERT_TAIL(&dyn->pfid_kif->pfik_dynaddrs, dyn, entry);
+ aw->p.dyn = dyn;
+ pfi_kif_update(dyn->pfid_kif);
+ splx(s);
+ return (0);
+
+_bad:
+ if (dyn->pfid_kt != NULL)
+ pfr_detach_table(dyn->pfid_kt);
+ if (ruleset != NULL)
+ pf_remove_if_empty_ruleset(ruleset);
+ if (dyn->pfid_kif != NULL)
+ pfi_kif_unref(dyn->pfid_kif, PFI_KIF_REF_RULE);
+#ifdef __FreeBSD__
+ pool_put(&V_pfi_addr_pl, dyn);
+#else
+ pool_put(&pfi_addr_pl, dyn);
+#endif
+ splx(s);
+ return (rv);
+}
+
+void
+pfi_kif_update(struct pfi_kif *kif)
+{
+ struct ifg_list *ifgl;
+ struct pfi_dynaddr *p;
+
+ /* update all dynaddr */
+ TAILQ_FOREACH(p, &kif->pfik_dynaddrs, entry)
+ pfi_dynaddr_update(p);
+
+ /* again for all groups kif is member of */
+ if (kif->pfik_ifp != NULL)
+ TAILQ_FOREACH(ifgl, &kif->pfik_ifp->if_groups, ifgl_next)
+ pfi_kif_update((struct pfi_kif *)
+ ifgl->ifgl_group->ifg_pf_kif);
+}
+
+void
+pfi_dynaddr_update(struct pfi_dynaddr *dyn)
+{
+ struct pfi_kif *kif;
+ struct pfr_ktable *kt;
+
+ if (dyn == NULL || dyn->pfid_kif == NULL || dyn->pfid_kt == NULL)
+ panic("pfi_dynaddr_update");
+
+ kif = dyn->pfid_kif;
+ kt = dyn->pfid_kt;
+
+#ifdef __FreeBSD__
+ if (kt->pfrkt_larg != V_pfi_update) {
+#else
+ if (kt->pfrkt_larg != pfi_update) {
+#endif
+ /* this table needs to be brought up-to-date */
+ pfi_table_update(kt, kif, dyn->pfid_net, dyn->pfid_iflags);
+#ifdef __FreeBSD__
+ kt->pfrkt_larg = V_pfi_update;
+#else
+ kt->pfrkt_larg = pfi_update;
+#endif
+ }
+ pfr_dynaddr_update(kt, dyn);
+}
+
+void
+pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, int net, int flags)
+{
+ int e, size2 = 0;
+ struct ifg_member *ifgm;
+
+#ifdef __FreeBSD__
+ V_pfi_buffer_cnt = 0;
+#else
+ pfi_buffer_cnt = 0;
+#endif
+
+ if (kif->pfik_ifp != NULL)
+ pfi_instance_add(kif->pfik_ifp, net, flags);
+ else if (kif->pfik_group != NULL)
+ TAILQ_FOREACH(ifgm, &kif->pfik_group->ifg_members, ifgm_next)
+ pfi_instance_add(ifgm->ifgm_ifp, net, flags);
+
+#ifdef __FreeBSD__
+ if ((e = pfr_set_addrs(&kt->pfrkt_t, V_pfi_buffer, V_pfi_buffer_cnt, &size2,
+ NULL, NULL, NULL, 0, PFR_TFLAG_ALLMASK)))
+ printf("pfi_table_update: cannot set %d new addresses "
+ "into table %s: %d\n", V_pfi_buffer_cnt, kt->pfrkt_name, e);
+#else
+ if ((e = pfr_set_addrs(&kt->pfrkt_t, pfi_buffer, pfi_buffer_cnt, &size2,
+ NULL, NULL, NULL, 0, PFR_TFLAG_ALLMASK)))
+ printf("pfi_table_update: cannot set %d new addresses "
+ "into table %s: %d\n", pfi_buffer_cnt, kt->pfrkt_name, e);
+#endif
+}
+
+void
+pfi_instance_add(struct ifnet *ifp, int net, int flags)
+{
+ struct ifaddr *ia;
+ int got4 = 0, got6 = 0;
+ int net2, af;
+
+ if (ifp == NULL)
+ return;
+ TAILQ_FOREACH(ia, &ifp->if_addrlist, ifa_list) {
+ if (ia->ifa_addr == NULL)
+ continue;
+ af = ia->ifa_addr->sa_family;
+ if (af != AF_INET && af != AF_INET6)
+ continue;
+#ifdef __FreeBSD__
+ /*
+ * XXX: For point-to-point interfaces, (ifname:0) and IPv4,
+ * jump over addresses without a proper route to work
+ * around a problem with ppp not fully removing the
+ * address used during IPCP.
+ */
+ if ((ifp->if_flags & IFF_POINTOPOINT) &&
+ !(ia->ifa_flags & IFA_ROUTE) &&
+ (flags & PFI_AFLAG_NOALIAS) && (af == AF_INET))
+ continue;
+#endif
+ if ((flags & PFI_AFLAG_BROADCAST) && af == AF_INET6)
+ continue;
+ if ((flags & PFI_AFLAG_BROADCAST) &&
+ !(ifp->if_flags & IFF_BROADCAST))
+ continue;
+ if ((flags & PFI_AFLAG_PEER) &&
+ !(ifp->if_flags & IFF_POINTOPOINT))
+ continue;
+ if ((flags & PFI_AFLAG_NETWORK) && af == AF_INET6 &&
+ IN6_IS_ADDR_LINKLOCAL(
+ &((struct sockaddr_in6 *)ia->ifa_addr)->sin6_addr))
+ continue;
+ if (flags & PFI_AFLAG_NOALIAS) {
+ if (af == AF_INET && got4)
+ continue;
+ if (af == AF_INET6 && got6)
+ continue;
+ }
+ if (af == AF_INET)
+ got4 = 1;
+ else if (af == AF_INET6)
+ got6 = 1;
+ net2 = net;
+ if (net2 == 128 && (flags & PFI_AFLAG_NETWORK)) {
+ if (af == AF_INET)
+ net2 = pfi_unmask(&((struct sockaddr_in *)
+ ia->ifa_netmask)->sin_addr);
+ else if (af == AF_INET6)
+ net2 = pfi_unmask(&((struct sockaddr_in6 *)
+ ia->ifa_netmask)->sin6_addr);
+ }
+ if (af == AF_INET && net2 > 32)
+ net2 = 32;
+ if (flags & PFI_AFLAG_BROADCAST)
+ pfi_address_add(ia->ifa_broadaddr, af, net2);
+ else if (flags & PFI_AFLAG_PEER)
+ pfi_address_add(ia->ifa_dstaddr, af, net2);
+ else
+ pfi_address_add(ia->ifa_addr, af, net2);
+ }
+}
+
+void
+pfi_address_add(struct sockaddr *sa, int af, int net)
+{
+ struct pfr_addr *p;
+ int i;
+
+#ifdef __FreeBSD__
+ if (V_pfi_buffer_cnt >= V_pfi_buffer_max) {
+ int new_max = V_pfi_buffer_max * 2;
+#else
+ if (pfi_buffer_cnt >= pfi_buffer_max) {
+ int new_max = pfi_buffer_max * 2;
+#endif
+
+ if (new_max > PFI_BUFFER_MAX) {
+ printf("pfi_address_add: address buffer full (%d/%d)\n",
+#ifdef __FreeBSD__
+ V_pfi_buffer_cnt, PFI_BUFFER_MAX);
+#else
+ pfi_buffer_cnt, PFI_BUFFER_MAX);
+#endif
+ return;
+ }
+ p = malloc(new_max * sizeof(*V_pfi_buffer), PFI_MTYPE,
+#ifdef __FreeBSD__
+ M_NOWAIT);
+#else
+ M_DONTWAIT);
+#endif
+ if (p == NULL) {
+ printf("pfi_address_add: no memory to grow buffer "
+#ifdef __FreeBSD__
+ "(%d/%d)\n", V_pfi_buffer_cnt, PFI_BUFFER_MAX);
+#else
+ "(%d/%d)\n", pfi_buffer_cnt, PFI_BUFFER_MAX);
+#endif
+ return;
+ }
+#ifdef __FreeBSD__
+ memcpy(V_pfi_buffer, p, V_pfi_buffer_cnt * sizeof(*V_pfi_buffer));
+ /* no need to zero buffer */
+ free(V_pfi_buffer, PFI_MTYPE);
+ V_pfi_buffer = p;
+ V_pfi_buffer_max = new_max;
+#else
+ memcpy(pfi_buffer, p, pfi_buffer_cnt * sizeof(*pfi_buffer));
+ /* no need to zero buffer */
+ free(pfi_buffer, PFI_MTYPE);
+ pfi_buffer = p;
+ pfi_buffer_max = new_max;
+#endif
+ }
+ if (af == AF_INET && net > 32)
+ net = 128;
+#ifdef __FreeBSD__
+ p = V_pfi_buffer + V_pfi_buffer_cnt++;
+#else
+ p = pfi_buffer + pfi_buffer_cnt++;
+#endif
+ bzero(p, sizeof(*p));
+ p->pfra_af = af;
+ p->pfra_net = net;
+ if (af == AF_INET)
+ p->pfra_ip4addr = ((struct sockaddr_in *)sa)->sin_addr;
+ else if (af == AF_INET6) {
+ p->pfra_ip6addr = ((struct sockaddr_in6 *)sa)->sin6_addr;
+ if (IN6_IS_SCOPE_EMBED(&p->pfra_ip6addr))
+ p->pfra_ip6addr.s6_addr16[1] = 0;
+ }
+ /* mask network address bits */
+ if (net < 128)
+ ((caddr_t)p)[p->pfra_net/8] &= ~(0xFF >> (p->pfra_net%8));
+ for (i = (p->pfra_net+7)/8; i < sizeof(p->pfra_u); i++)
+ ((caddr_t)p)[i] = 0;
+}
+
+void
+pfi_dynaddr_remove(struct pf_addr_wrap *aw)
+{
+ int s;
+
+ if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL ||
+ aw->p.dyn->pfid_kif == NULL || aw->p.dyn->pfid_kt == NULL)
+ return;
+
+ s = splsoftnet();
+ TAILQ_REMOVE(&aw->p.dyn->pfid_kif->pfik_dynaddrs, aw->p.dyn, entry);
+ pfi_kif_unref(aw->p.dyn->pfid_kif, PFI_KIF_REF_RULE);
+ aw->p.dyn->pfid_kif = NULL;
+ pfr_detach_table(aw->p.dyn->pfid_kt);
+ aw->p.dyn->pfid_kt = NULL;
+#ifdef __FreeBSD__
+ pool_put(&V_pfi_addr_pl, aw->p.dyn);
+#else
+ pool_put(&pfi_addr_pl, aw->p.dyn);
+#endif
+ aw->p.dyn = NULL;
+ splx(s);
+}
+
+void
+pfi_dynaddr_copyout(struct pf_addr_wrap *aw)
+{
+ if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL ||
+ aw->p.dyn->pfid_kif == NULL)
+ return;
+ aw->p.dyncnt = aw->p.dyn->pfid_acnt4 + aw->p.dyn->pfid_acnt6;
+}
+
+void
+pfi_kifaddr_update(void *v)
+{
+ int s;
+ struct pfi_kif *kif = (struct pfi_kif *)v;
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ V_pfi_update++;
+#else
+ pfi_update++;
+#endif
+ pfi_kif_update(kif);
+ splx(s);
+}
+
+int
+pfi_if_compare(struct pfi_kif *p, struct pfi_kif *q)
+{
+ return (strncmp(p->pfik_name, q->pfik_name, IFNAMSIZ));
+}
+
+void
+pfi_update_status(const char *name, struct pf_status *pfs)
+{
+ struct pfi_kif *p;
+ struct pfi_kif_cmp key;
+ struct ifg_member p_member, *ifgm;
+ TAILQ_HEAD(, ifg_member) ifg_members;
+ int i, j, k, s;
+
+ strlcpy(key.pfik_name, name, sizeof(key.pfik_name));
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ p = RB_FIND(pfi_ifhead, &V_pfi_ifs, (struct pfi_kif *)&key);
+#else
+ p = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&key);
+#endif
+ if (p == NULL) {
+ splx(s);
+ return;
+ }
+ if (p->pfik_group != NULL) {
+ bcopy(&p->pfik_group->ifg_members, &ifg_members,
+ sizeof(ifg_members));
+ } else {
+ /* build a temporary list for p only */
+ bzero(&p_member, sizeof(p_member));
+ p_member.ifgm_ifp = p->pfik_ifp;
+ TAILQ_INIT(&ifg_members);
+ TAILQ_INSERT_TAIL(&ifg_members, &p_member, ifgm_next);
+ }
+ if (pfs) {
+ bzero(pfs->pcounters, sizeof(pfs->pcounters));
+ bzero(pfs->bcounters, sizeof(pfs->bcounters));
+ }
+ TAILQ_FOREACH(ifgm, &ifg_members, ifgm_next) {
+ if (ifgm->ifgm_ifp == NULL)
+ continue;
+ p = (struct pfi_kif *)ifgm->ifgm_ifp->if_pf_kif;
+
+ /* just clear statistics */
+ if (pfs == NULL) {
+ bzero(p->pfik_packets, sizeof(p->pfik_packets));
+ bzero(p->pfik_bytes, sizeof(p->pfik_bytes));
+ p->pfik_tzero = time_second;
+ continue;
+ }
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 2; j++)
+ for (k = 0; k < 2; k++) {
+ pfs->pcounters[i][j][k] +=
+ p->pfik_packets[i][j][k];
+ pfs->bcounters[i][j] +=
+ p->pfik_bytes[i][j][k];
+ }
+ }
+ splx(s);
+}
+
+int
+pfi_get_ifaces(const char *name, struct pfi_kif *buf, int *size)
+{
+ struct pfi_kif *p, *nextp;
+ int s, n = 0;
+#ifdef __FreeBSD__
+ int error;
+#endif
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ for (p = RB_MIN(pfi_ifhead, &V_pfi_ifs); p; p = nextp) {
+ nextp = RB_NEXT(pfi_ifhead, &V_pfi_ifs, p);
+#else
+ for (p = RB_MIN(pfi_ifhead, &pfi_ifs); p; p = nextp) {
+ nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p);
+#endif
+ if (pfi_skip_if(name, p))
+ continue;
+ if (*size > n++) {
+ if (!p->pfik_tzero)
+ p->pfik_tzero = time_second;
+ pfi_kif_ref(p, PFI_KIF_REF_RULE);
+#ifdef __FreeBSD__
+ PF_COPYOUT(p, buf++, sizeof(*buf), error);
+ if (error) {
+#else
+ if (copyout(p, buf++, sizeof(*buf))) {
+#endif
+ pfi_kif_unref(p, PFI_KIF_REF_RULE);
+ splx(s);
+ return (EFAULT);
+ }
+#ifdef __FreeBSD__
+ nextp = RB_NEXT(pfi_ifhead, &V_pfi_ifs, p);
+#else
+ nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p);
+#endif
+ pfi_kif_unref(p, PFI_KIF_REF_RULE);
+ }
+ }
+ splx(s);
+ *size = n;
+ return (0);
+}
+
+int
+pfi_skip_if(const char *filter, struct pfi_kif *p)
+{
+ int n;
+
+ if (filter == NULL || !*filter)
+ return (0);
+ if (!strcmp(p->pfik_name, filter))
+ return (0); /* exact match */
+ n = strlen(filter);
+ if (n < 1 || n >= IFNAMSIZ)
+ return (1); /* sanity check */
+ if (filter[n-1] >= '0' && filter[n-1] <= '9')
+ return (1); /* only do exact match in that case */
+ if (strncmp(p->pfik_name, filter, n))
+ return (1); /* prefix doesn't match */
+ return (p->pfik_name[n] < '0' || p->pfik_name[n] > '9');
+}
+
+int
+pfi_set_flags(const char *name, int flags)
+{
+ struct pfi_kif *p;
+ int s;
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ RB_FOREACH(p, pfi_ifhead, &V_pfi_ifs) {
+#else
+ RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
+#endif
+ if (pfi_skip_if(name, p))
+ continue;
+ p->pfik_flags |= flags;
+ }
+ splx(s);
+ return (0);
+}
+
+int
+pfi_clear_flags(const char *name, int flags)
+{
+ struct pfi_kif *p;
+ int s;
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ RB_FOREACH(p, pfi_ifhead, &V_pfi_ifs) {
+#else
+ RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
+#endif
+ if (pfi_skip_if(name, p))
+ continue;
+ p->pfik_flags &= ~flags;
+ }
+ splx(s);
+ return (0);
+}
+
+/* from pf_print_state.c */
+int
+pfi_unmask(void *addr)
+{
+ struct pf_addr *m = addr;
+ int i = 31, j = 0, b = 0;
+ u_int32_t tmp;
+
+ while (j < 4 && m->addr32[j] == 0xffffffff) {
+ b += 32;
+ j++;
+ }
+ if (j < 4) {
+ tmp = ntohl(m->addr32[j]);
+ for (i = 31; tmp & (1 << i); --i)
+ b++;
+ }
+ return (b);
+}
+
+#ifdef __FreeBSD__
+void
+pfi_attach_ifnet_event(void *arg __unused, struct ifnet *ifp)
+{
+
+ CURVNET_SET(ifp->if_vnet);
+ PF_LOCK();
+ pfi_attach_ifnet(ifp);
+#ifdef ALTQ
+ pf_altq_ifnet_event(ifp, 0);
+#endif
+ PF_UNLOCK();
+ CURVNET_RESTORE();
+}
+
+void
+pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp)
+{
+
+ CURVNET_SET(ifp->if_vnet);
+ PF_LOCK();
+ pfi_detach_ifnet(ifp);
+#ifdef ALTQ
+ pf_altq_ifnet_event(ifp, 1);
+#endif
+ PF_UNLOCK();
+ CURVNET_RESTORE();
+}
+
+void
+pfi_attach_group_event(void *arg , struct ifg_group *ifg)
+{
+
+ CURVNET_SET((struct vnet *)arg);
+ PF_LOCK();
+ pfi_attach_ifgroup(ifg);
+ PF_UNLOCK();
+ CURVNET_RESTORE();
+}
+
+void
+pfi_change_group_event(void *arg, char *gname)
+{
+
+ CURVNET_SET((struct vnet *)arg);
+ PF_LOCK();
+ pfi_group_change(gname);
+ PF_UNLOCK();
+ CURVNET_RESTORE();
+}
+
+void
+pfi_detach_group_event(void *arg, struct ifg_group *ifg)
+{
+
+ CURVNET_SET((struct vnet *)arg);
+ PF_LOCK();
+ pfi_detach_ifgroup(ifg);
+ PF_UNLOCK();
+ CURVNET_RESTORE();
+}
+
+void
+pfi_ifaddr_event(void *arg __unused, struct ifnet *ifp)
+{
+
+ CURVNET_SET(ifp->if_vnet);
+ PF_LOCK();
+ if (ifp && ifp->if_pf_kif)
+ pfi_kifaddr_update(ifp->if_pf_kif);
+ PF_UNLOCK();
+ CURVNET_RESTORE();
+}
+#endif /* __FreeBSD__ */
diff --git a/sys/contrib/pf/net/pf_ioctl.c b/sys/contrib/pf/net/pf_ioctl.c
new file mode 100644
index 0000000..6b5d8f5
--- /dev/null
+++ b/sys/contrib/pf/net/pf_ioctl.c
@@ -0,0 +1,4420 @@
+/* $OpenBSD: pf_ioctl.c,v 1.213 2009/02/15 21:46:12 mbalmer Exp $ */
+
+/*
+ * Copyright (c) 2001 Daniel Hartmeier
+ * Copyright (c) 2002,2003 Henning Brauer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Effort sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
+ *
+ */
+
+#ifdef __FreeBSD__
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_inet.h"
+#include "opt_inet6.h"
+#include "opt_bpf.h"
+#include "opt_pf.h"
+
+#define NPFSYNC 1
+
+#ifdef DEV_PFLOG
+#define NPFLOG DEV_PFLOG
+#else
+#define NPFLOG 0
+#endif
+
+#else /* !__FreeBSD__ */
+#include "pfsync.h"
+#include "pflog.h"
+#endif /* __FreeBSD__ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/filio.h>
+#include <sys/fcntl.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/time.h>
+#ifdef __FreeBSD__
+#include <sys/ucred.h>
+#include <sys/jail.h>
+#include <sys/module.h>
+#include <sys/conf.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#else
+#include <sys/timeout.h>
+#include <sys/pool.h>
+#endif
+#include <sys/proc.h>
+#include <sys/malloc.h>
+#include <sys/kthread.h>
+#ifndef __FreeBSD__
+#include <sys/rwlock.h>
+#include <uvm/uvm_extern.h>
+#endif
+
+#include <net/if.h>
+#include <net/if_types.h>
+#ifdef __FreeBSD__
+#include <net/vnet.h>
+#endif
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+
+#ifdef __FreeBSD__
+#include <sys/md5.h>
+#else
+#include <dev/rndvar.h>
+#include <crypto/md5.h>
+#endif
+#include <net/pfvar.h>
+
+#include <net/if_pfsync.h>
+
+#if NPFLOG > 0
+#include <net/if_pflog.h>
+#endif /* NPFLOG > 0 */
+
+#ifdef INET6
+#include <netinet/ip6.h>
+#include <netinet/in_pcb.h>
+#endif /* INET6 */
+
+#ifdef ALTQ
+#include <altq/altq.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <sys/limits.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <net/pfil.h>
+#endif /* __FreeBSD__ */
+
+#ifdef __FreeBSD__
+void init_zone_var(void);
+void cleanup_pf_zone(void);
+int pfattach(void);
+#else
+void pfattach(int);
+void pf_thread_create(void *);
+int pfopen(dev_t, int, int, struct proc *);
+int pfclose(dev_t, int, int, struct proc *);
+#endif
+struct pf_pool *pf_get_pool(char *, u_int32_t, u_int8_t, u_int32_t,
+ u_int8_t, u_int8_t, u_int8_t);
+
+void pf_mv_pool(struct pf_palist *, struct pf_palist *);
+void pf_empty_pool(struct pf_palist *);
+#ifdef __FreeBSD__
+int pfioctl(struct cdev *, u_long, caddr_t, int, struct thread *);
+#else
+int pfioctl(dev_t, u_long, caddr_t, int, struct proc *);
+#endif
+#ifdef ALTQ
+int pf_begin_altq(u_int32_t *);
+int pf_rollback_altq(u_int32_t);
+int pf_commit_altq(u_int32_t);
+int pf_enable_altq(struct pf_altq *);
+int pf_disable_altq(struct pf_altq *);
+#endif /* ALTQ */
+int pf_begin_rules(u_int32_t *, int, const char *);
+int pf_rollback_rules(u_int32_t, int, char *);
+int pf_setup_pfsync_matching(struct pf_ruleset *);
+void pf_hash_rule(MD5_CTX *, struct pf_rule *);
+void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
+int pf_commit_rules(u_int32_t, int, char *);
+int pf_addr_setup(struct pf_ruleset *,
+ struct pf_addr_wrap *, sa_family_t);
+void pf_addr_copyout(struct pf_addr_wrap *);
+
+#define TAGID_MAX 50000
+
+#ifdef __FreeBSD__
+VNET_DEFINE(struct pf_rule, pf_default_rule);
+VNET_DEFINE(struct sx, pf_consistency_lock);
+
+#ifdef ALTQ
+static VNET_DEFINE(int, pf_altq_running);
+#define V_pf_altq_running VNET(pf_altq_running)
+#endif
+
+TAILQ_HEAD(pf_tags, pf_tagname);
+
+#define V_pf_tags VNET(pf_tags)
+VNET_DEFINE(struct pf_tags, pf_tags);
+#define V_pf_qids VNET(pf_qids)
+VNET_DEFINE(struct pf_tags, pf_qids);
+
+#else /* !__FreeBSD__ */
+struct pf_rule pf_default_rule;
+struct rwlock pf_consistency_lock = RWLOCK_INITIALIZER("pfcnslk");
+#ifdef ALTQ
+static int pf_altq_running;
+#endif
+
+TAILQ_HEAD(pf_tags, pf_tagname) pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags),
+ pf_qids = TAILQ_HEAD_INITIALIZER(pf_qids);
+#endif /* __FreeBSD__ */
+
+#if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
+#error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
+#endif
+
+u_int16_t tagname2tag(struct pf_tags *, char *);
+void tag2tagname(struct pf_tags *, u_int16_t, char *);
+void tag_unref(struct pf_tags *, u_int16_t);
+int pf_rtlabel_add(struct pf_addr_wrap *);
+void pf_rtlabel_remove(struct pf_addr_wrap *);
+void pf_rtlabel_copyout(struct pf_addr_wrap *);
+
+#ifdef __FreeBSD__
+#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
+#else
+#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
+#endif
+
+#ifdef __FreeBSD__
+struct cdev *pf_dev;
+
+/*
+ * XXX - These are new and need to be checked when moveing to a new version
+ */
+static void pf_clear_states(void);
+static int pf_clear_tables(void);
+static void pf_clear_srcnodes(void);
+/*
+ * XXX - These are new and need to be checked when moveing to a new version
+ */
+
+/*
+ * Wrapper functions for pfil(9) hooks
+ */
+#ifdef INET
+static int pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp,
+ int dir, struct inpcb *inp);
+static int pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp,
+ int dir, struct inpcb *inp);
+#endif
+#ifdef INET6
+static int pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp,
+ int dir, struct inpcb *inp);
+static int pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp,
+ int dir, struct inpcb *inp);
+#endif
+
+static int hook_pf(void);
+static int dehook_pf(void);
+static int shutdown_pf(void);
+static int pf_load(void);
+static int pf_unload(void);
+
+static struct cdevsw pf_cdevsw = {
+ .d_ioctl = pfioctl,
+ .d_name = PF_NAME,
+ .d_version = D_VERSION,
+};
+
+static volatile VNET_DEFINE(int, pf_pfil_hooked);
+#define V_pf_pfil_hooked VNET(pf_pfil_hooked)
+VNET_DEFINE(int, pf_end_threads);
+struct mtx pf_task_mtx;
+
+/* pfsync */
+pfsync_state_import_t *pfsync_state_import_ptr = NULL;
+pfsync_insert_state_t *pfsync_insert_state_ptr = NULL;
+pfsync_update_state_t *pfsync_update_state_ptr = NULL;
+pfsync_delete_state_t *pfsync_delete_state_ptr = NULL;
+pfsync_clear_states_t *pfsync_clear_states_ptr = NULL;
+pfsync_state_in_use_t *pfsync_state_in_use_ptr = NULL;
+pfsync_defer_t *pfsync_defer_ptr = NULL;
+pfsync_up_t *pfsync_up_ptr = NULL;
+/* pflow */
+export_pflow_t *export_pflow_ptr = NULL;
+/* pflog */
+pflog_packet_t *pflog_packet_ptr = NULL;
+
+VNET_DEFINE(int, debug_pfugidhack);
+SYSCTL_VNET_INT(_debug, OID_AUTO, pfugidhack, CTLFLAG_RW,
+ &VNET_NAME(debug_pfugidhack), 0,
+ "Enable/disable pf user/group rules mpsafe hack");
+
+static void
+init_pf_mutex(void)
+{
+
+ mtx_init(&pf_task_mtx, "pf task mtx", NULL, MTX_DEF);
+}
+
+static void
+destroy_pf_mutex(void)
+{
+
+ mtx_destroy(&pf_task_mtx);
+}
+void
+init_zone_var(void)
+{
+ V_pf_src_tree_pl = V_pf_rule_pl = NULL;
+ V_pf_state_pl = V_pf_state_key_pl = V_pf_state_item_pl = NULL;
+ V_pf_altq_pl = V_pf_pooladdr_pl = NULL;
+ V_pf_frent_pl = V_pf_frag_pl = V_pf_cache_pl = V_pf_cent_pl = NULL;
+ V_pf_state_scrub_pl = NULL;
+ V_pfr_ktable_pl = V_pfr_kentry_pl = V_pfr_kcounters_pl = NULL;
+}
+
+void
+cleanup_pf_zone(void)
+{
+ UMA_DESTROY(V_pf_src_tree_pl);
+ UMA_DESTROY(V_pf_rule_pl);
+ UMA_DESTROY(V_pf_state_pl);
+ UMA_DESTROY(V_pf_state_key_pl);
+ UMA_DESTROY(V_pf_state_item_pl);
+ UMA_DESTROY(V_pf_altq_pl);
+ UMA_DESTROY(V_pf_pooladdr_pl);
+ UMA_DESTROY(V_pf_frent_pl);
+ UMA_DESTROY(V_pf_frag_pl);
+ UMA_DESTROY(V_pf_cache_pl);
+ UMA_DESTROY(V_pf_cent_pl);
+ UMA_DESTROY(V_pfr_ktable_pl);
+ UMA_DESTROY(V_pfr_kentry_pl);
+ UMA_DESTROY(V_pfr_kcounters_pl);
+ UMA_DESTROY(V_pf_state_scrub_pl);
+ UMA_DESTROY(V_pfi_addr_pl);
+}
+
+int
+pfattach(void)
+{
+ u_int32_t *my_timeout = V_pf_default_rule.timeout;
+ int error = 1;
+
+ do {
+ UMA_CREATE(V_pf_src_tree_pl, struct pf_src_node, "pfsrctrpl");
+ UMA_CREATE(V_pf_rule_pl, struct pf_rule, "pfrulepl");
+ UMA_CREATE(V_pf_state_pl, struct pf_state, "pfstatepl");
+ UMA_CREATE(V_pf_state_key_pl, struct pf_state, "pfstatekeypl");
+ UMA_CREATE(V_pf_state_item_pl, struct pf_state, "pfstateitempl");
+ UMA_CREATE(V_pf_altq_pl, struct pf_altq, "pfaltqpl");
+ UMA_CREATE(V_pf_pooladdr_pl, struct pf_pooladdr, "pfpooladdrpl");
+ UMA_CREATE(V_pfr_ktable_pl, struct pfr_ktable, "pfrktable");
+ UMA_CREATE(V_pfr_kentry_pl, struct pfr_kentry, "pfrkentry");
+ UMA_CREATE(V_pfr_kcounters_pl, struct pfr_kcounters, "pfrkcounters");
+ UMA_CREATE(V_pf_frent_pl, struct pf_frent, "pffrent");
+ UMA_CREATE(V_pf_frag_pl, struct pf_fragment, "pffrag");
+ UMA_CREATE(V_pf_cache_pl, struct pf_fragment, "pffrcache");
+ UMA_CREATE(V_pf_cent_pl, struct pf_frcache, "pffrcent");
+ UMA_CREATE(V_pf_state_scrub_pl, struct pf_state_scrub,
+ "pfstatescrub");
+ UMA_CREATE(V_pfi_addr_pl, struct pfi_dynaddr, "pfiaddrpl");
+ error = 0;
+ } while(0);
+ if (error) {
+ cleanup_pf_zone();
+ return (error);
+ }
+ pfr_initialize();
+ pfi_initialize();
+ if ( (error = pf_osfp_initialize()) ) {
+ cleanup_pf_zone();
+ pf_osfp_cleanup();
+ return (error);
+ }
+
+ V_pf_pool_limits[PF_LIMIT_STATES].pp = V_pf_state_pl;
+ V_pf_pool_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT;
+ V_pf_pool_limits[PF_LIMIT_SRC_NODES].pp = V_pf_src_tree_pl;
+ V_pf_pool_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT;
+ V_pf_pool_limits[PF_LIMIT_FRAGS].pp = V_pf_frent_pl;
+ V_pf_pool_limits[PF_LIMIT_FRAGS].limit = PFFRAG_FRENT_HIWAT;
+ V_pf_pool_limits[PF_LIMIT_TABLES].pp = V_pfr_ktable_pl;
+ V_pf_pool_limits[PF_LIMIT_TABLES].limit = PFR_KTABLE_HIWAT;
+ V_pf_pool_limits[PF_LIMIT_TABLE_ENTRIES].pp = V_pfr_kentry_pl;
+ V_pf_pool_limits[PF_LIMIT_TABLE_ENTRIES].limit = PFR_KENTRY_HIWAT;
+ uma_zone_set_max(V_pf_pool_limits[PF_LIMIT_STATES].pp,
+ V_pf_pool_limits[PF_LIMIT_STATES].limit);
+
+ RB_INIT(&V_tree_src_tracking);
+ RB_INIT(&V_pf_anchors);
+ pf_init_ruleset(&pf_main_ruleset);
+
+ TAILQ_INIT(&V_pf_altqs[0]);
+ TAILQ_INIT(&V_pf_altqs[1]);
+ TAILQ_INIT(&V_pf_pabuf);
+ V_pf_altqs_active = &V_pf_altqs[0];
+ V_pf_altqs_inactive = &V_pf_altqs[1];
+ TAILQ_INIT(&V_state_list);
+
+ /* default rule should never be garbage collected */
+ V_pf_default_rule.entries.tqe_prev = &V_pf_default_rule.entries.tqe_next;
+ V_pf_default_rule.action = PF_PASS;
+ V_pf_default_rule.nr = -1;
+ V_pf_default_rule.rtableid = -1;
+
+ /* initialize default timeouts */
+ my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
+ my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
+ my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
+ my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
+ my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
+ my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
+ my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
+ my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
+ my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
+ my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
+ my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
+ my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
+ my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
+ my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
+ my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
+ my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
+ my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
+ my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
+ my_timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START;
+ my_timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END;
+
+ pf_normalize_init();
+
+ bzero(&V_pf_status, sizeof(V_pf_status));
+ V_pf_status.debug = PF_DEBUG_URGENT;
+
+ V_pf_pfil_hooked = 0;
+
+ /* XXX do our best to avoid a conflict */
+ V_pf_status.hostid = arc4random();
+
+ if (kproc_create(pf_purge_thread, curvnet, NULL, 0, 0, "pfpurge"))
+ return (ENXIO);
+
+ m_addr_chg_pf_p = pf_pkt_addr_changed;
+
+ return (error);
+}
+#else /* !__FreeBSD__ */
+
+void
+pfattach(int num)
+{
+ u_int32_t *timeout = pf_default_rule.timeout;
+
+ pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl",
+ &pool_allocator_nointr);
+ pool_init(&pf_src_tree_pl, sizeof(struct pf_src_node), 0, 0, 0,
+ "pfsrctrpl", NULL);
+ pool_init(&pf_state_pl, sizeof(struct pf_state), 0, 0, 0, "pfstatepl",
+ NULL);
+ pool_init(&pf_state_key_pl, sizeof(struct pf_state_key), 0, 0, 0,
+ "pfstatekeypl", NULL);
+ pool_init(&pf_state_item_pl, sizeof(struct pf_state_item), 0, 0, 0,
+ "pfstateitempl", NULL);
+ pool_init(&pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl",
+ &pool_allocator_nointr);
+ pool_init(&pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0,
+ "pfpooladdrpl", &pool_allocator_nointr);
+ pfr_initialize();
+ pfi_initialize();
+ pf_osfp_initialize();
+
+ pool_sethardlimit(pf_pool_limits[PF_LIMIT_STATES].pp,
+ pf_pool_limits[PF_LIMIT_STATES].limit, NULL, 0);
+
+ if (physmem <= atop(100*1024*1024))
+ pf_pool_limits[PF_LIMIT_TABLE_ENTRIES].limit =
+ PFR_KENTRY_HIWAT_SMALL;
+
+ RB_INIT(&tree_src_tracking);
+ RB_INIT(&pf_anchors);
+ pf_init_ruleset(&pf_main_ruleset);
+ TAILQ_INIT(&pf_altqs[0]);
+ TAILQ_INIT(&pf_altqs[1]);
+ TAILQ_INIT(&pf_pabuf);
+ pf_altqs_active = &pf_altqs[0];
+ pf_altqs_inactive = &pf_altqs[1];
+ TAILQ_INIT(&state_list);
+
+ /* default rule should never be garbage collected */
+ pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next;
+ pf_default_rule.action = PF_PASS;
+ pf_default_rule.nr = -1;
+ pf_default_rule.rtableid = -1;
+
+ /* initialize default timeouts */
+ timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
+ timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
+ timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
+ timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
+ timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
+ timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
+ timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
+ timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
+ timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
+ timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
+ timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
+ timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
+ timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
+ timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
+ timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
+ timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
+ timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
+ timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
+ timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START;
+ timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END;
+
+ pf_normalize_init();
+ bzero(&pf_status, sizeof(pf_status));
+ pf_status.debug = PF_DEBUG_URGENT;
+
+ /* XXX do our best to avoid a conflict */
+ pf_status.hostid = arc4random();
+
+ /* require process context to purge states, so perform in a thread */
+ kthread_create_deferred(pf_thread_create, NULL);
+}
+
+void
+pf_thread_create(void *v)
+{
+ if (kthread_create(pf_purge_thread, NULL, NULL, "pfpurge"))
+ panic("pfpurge thread");
+}
+
+int
+pfopen(dev_t dev, int flags, int fmt, struct proc *p)
+{
+ if (minor(dev) >= 1)
+ return (ENXIO);
+ return (0);
+}
+
+int
+pfclose(dev_t dev, int flags, int fmt, struct proc *p)
+{
+ if (minor(dev) >= 1)
+ return (ENXIO);
+ return (0);
+}
+#endif
+
+struct pf_pool *
+pf_get_pool(char *anchor, u_int32_t ticket, u_int8_t rule_action,
+ u_int32_t rule_number, u_int8_t r_last, u_int8_t active,
+ u_int8_t check_ticket)
+{
+ struct pf_ruleset *ruleset;
+ struct pf_rule *rule;
+ int rs_num;
+
+ ruleset = pf_find_ruleset(anchor);
+ if (ruleset == NULL)
+ return (NULL);
+ rs_num = pf_get_ruleset_number(rule_action);
+ if (rs_num >= PF_RULESET_MAX)
+ return (NULL);
+ if (active) {
+ if (check_ticket && ticket !=
+ ruleset->rules[rs_num].active.ticket)
+ return (NULL);
+ if (r_last)
+ rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
+ pf_rulequeue);
+ else
+ rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
+ } else {
+ if (check_ticket && ticket !=
+ ruleset->rules[rs_num].inactive.ticket)
+ return (NULL);
+ if (r_last)
+ rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
+ pf_rulequeue);
+ else
+ rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr);
+ }
+ if (!r_last) {
+ while ((rule != NULL) && (rule->nr != rule_number))
+ rule = TAILQ_NEXT(rule, entries);
+ }
+ if (rule == NULL)
+ return (NULL);
+
+ return (&rule->rpool);
+}
+
+void
+pf_mv_pool(struct pf_palist *poola, struct pf_palist *poolb)
+{
+ struct pf_pooladdr *mv_pool_pa;
+
+ while ((mv_pool_pa = TAILQ_FIRST(poola)) != NULL) {
+ TAILQ_REMOVE(poola, mv_pool_pa, entries);
+ TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries);
+ }
+}
+
+void
+pf_empty_pool(struct pf_palist *poola)
+{
+ struct pf_pooladdr *empty_pool_pa;
+
+ while ((empty_pool_pa = TAILQ_FIRST(poola)) != NULL) {
+ pfi_dynaddr_remove(&empty_pool_pa->addr);
+ pf_tbladdr_remove(&empty_pool_pa->addr);
+ pfi_kif_unref(empty_pool_pa->kif, PFI_KIF_REF_RULE);
+ TAILQ_REMOVE(poola, empty_pool_pa, entries);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_pooladdr_pl, empty_pool_pa);
+#else
+ pool_put(&pf_pooladdr_pl, empty_pool_pa);
+#endif
+ }
+}
+
+void
+pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
+{
+ if (rulequeue != NULL) {
+ if (rule->states_cur <= 0) {
+ /*
+ * XXX - we need to remove the table *before* detaching
+ * the rule to make sure the table code does not delete
+ * the anchor under our feet.
+ */
+ pf_tbladdr_remove(&rule->src.addr);
+ pf_tbladdr_remove(&rule->dst.addr);
+ if (rule->overload_tbl)
+ pfr_detach_table(rule->overload_tbl);
+ }
+ TAILQ_REMOVE(rulequeue, rule, entries);
+ rule->entries.tqe_prev = NULL;
+ rule->nr = -1;
+ }
+
+ if (rule->states_cur > 0 || rule->src_nodes > 0 ||
+ rule->entries.tqe_prev != NULL)
+ return;
+ pf_tag_unref(rule->tag);
+ pf_tag_unref(rule->match_tag);
+#ifdef ALTQ
+ if (rule->pqid != rule->qid)
+ pf_qid_unref(rule->pqid);
+ pf_qid_unref(rule->qid);
+#endif
+ pf_rtlabel_remove(&rule->src.addr);
+ pf_rtlabel_remove(&rule->dst.addr);
+ pfi_dynaddr_remove(&rule->src.addr);
+ pfi_dynaddr_remove(&rule->dst.addr);
+ if (rulequeue == NULL) {
+ pf_tbladdr_remove(&rule->src.addr);
+ pf_tbladdr_remove(&rule->dst.addr);
+ if (rule->overload_tbl)
+ pfr_detach_table(rule->overload_tbl);
+ }
+ pfi_kif_unref(rule->kif, PFI_KIF_REF_RULE);
+ pf_anchor_remove(rule);
+ pf_empty_pool(&rule->rpool.list);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_rule_pl, rule);
+#else
+ pool_put(&pf_rule_pl, rule);
+#endif
+}
+
+u_int16_t
+tagname2tag(struct pf_tags *head, char *tagname)
+{
+ struct pf_tagname *tag, *p = NULL;
+ u_int16_t new_tagid = 1;
+
+ TAILQ_FOREACH(tag, head, entries)
+ if (strcmp(tagname, tag->name) == 0) {
+ tag->ref++;
+ return (tag->tag);
+ }
+
+ /*
+ * to avoid fragmentation, we do a linear search from the beginning
+ * and take the first free slot we find. if there is none or the list
+ * is empty, append a new entry at the end.
+ */
+
+ /* new entry */
+ if (!TAILQ_EMPTY(head))
+ for (p = TAILQ_FIRST(head); p != NULL &&
+ p->tag == new_tagid; p = TAILQ_NEXT(p, entries))
+ new_tagid = p->tag + 1;
+
+ if (new_tagid > TAGID_MAX)
+ return (0);
+
+ /* allocate and fill new struct pf_tagname */
+ tag = malloc(sizeof(*tag), M_TEMP, M_NOWAIT|M_ZERO);
+ if (tag == NULL)
+ return (0);
+ strlcpy(tag->name, tagname, sizeof(tag->name));
+ tag->tag = new_tagid;
+ tag->ref++;
+
+ if (p != NULL) /* insert new entry before p */
+ TAILQ_INSERT_BEFORE(p, tag, entries);
+ else /* either list empty or no free slot in between */
+ TAILQ_INSERT_TAIL(head, tag, entries);
+
+ return (tag->tag);
+}
+
+void
+tag2tagname(struct pf_tags *head, u_int16_t tagid, char *p)
+{
+ struct pf_tagname *tag;
+
+ TAILQ_FOREACH(tag, head, entries)
+ if (tag->tag == tagid) {
+ strlcpy(p, tag->name, PF_TAG_NAME_SIZE);
+ return;
+ }
+}
+
+void
+tag_unref(struct pf_tags *head, u_int16_t tag)
+{
+ struct pf_tagname *p, *next;
+
+ if (tag == 0)
+ return;
+
+ for (p = TAILQ_FIRST(head); p != NULL; p = next) {
+ next = TAILQ_NEXT(p, entries);
+ if (tag == p->tag) {
+ if (--p->ref == 0) {
+ TAILQ_REMOVE(head, p, entries);
+ free(p, M_TEMP);
+ }
+ break;
+ }
+ }
+}
+
+u_int16_t
+pf_tagname2tag(char *tagname)
+{
+#ifdef __FreeBSD__
+ return (tagname2tag(&V_pf_tags, tagname));
+#else
+ return (tagname2tag(&pf_tags, tagname));
+#endif
+}
+
+void
+pf_tag2tagname(u_int16_t tagid, char *p)
+{
+#ifdef __FreeBSD__
+ tag2tagname(&V_pf_tags, tagid, p);
+#else
+ tag2tagname(&pf_tags, tagid, p);
+#endif
+}
+
+void
+pf_tag_ref(u_int16_t tag)
+{
+ struct pf_tagname *t;
+
+#ifdef __FreeBSD__
+ TAILQ_FOREACH(t, &V_pf_tags, entries)
+#else
+ TAILQ_FOREACH(t, &pf_tags, entries)
+#endif
+ if (t->tag == tag)
+ break;
+ if (t != NULL)
+ t->ref++;
+}
+
+void
+pf_tag_unref(u_int16_t tag)
+{
+#ifdef __FreeBSD__
+ tag_unref(&V_pf_tags, tag);
+#else
+ tag_unref(&pf_tags, tag);
+#endif
+}
+
+int
+pf_rtlabel_add(struct pf_addr_wrap *a)
+{
+#ifdef __FreeBSD__
+ /* XXX_IMPORT: later */
+ return (0);
+#else
+ if (a->type == PF_ADDR_RTLABEL &&
+ (a->v.rtlabel = rtlabel_name2id(a->v.rtlabelname)) == 0)
+ return (-1);
+ return (0);
+#endif
+}
+
+void
+pf_rtlabel_remove(struct pf_addr_wrap *a)
+{
+#ifdef __FreeBSD__
+ /* XXX_IMPORT: later */
+#else
+ if (a->type == PF_ADDR_RTLABEL)
+ rtlabel_unref(a->v.rtlabel);
+#endif
+}
+
+void
+pf_rtlabel_copyout(struct pf_addr_wrap *a)
+{
+#ifdef __FreeBSD__
+ /* XXX_IMPORT: later */
+ if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel)
+ strlcpy(a->v.rtlabelname, "?", sizeof(a->v.rtlabelname));
+#else
+ const char *name;
+
+ if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel) {
+ if ((name = rtlabel_id2name(a->v.rtlabel)) == NULL)
+ strlcpy(a->v.rtlabelname, "?",
+ sizeof(a->v.rtlabelname));
+ else
+ strlcpy(a->v.rtlabelname, name,
+ sizeof(a->v.rtlabelname));
+ }
+#endif
+}
+
+#ifdef ALTQ
+u_int32_t
+pf_qname2qid(char *qname)
+{
+#ifdef __FreeBSD__
+ return ((u_int32_t)tagname2tag(&V_pf_qids, qname));
+#else
+ return ((u_int32_t)tagname2tag(&pf_qids, qname));
+#endif
+}
+
+void
+pf_qid2qname(u_int32_t qid, char *p)
+{
+#ifdef __FreeBSD__
+ tag2tagname(&V_pf_qids, (u_int16_t)qid, p);
+#else
+ tag2tagname(&pf_qids, (u_int16_t)qid, p);
+#endif
+}
+
+void
+pf_qid_unref(u_int32_t qid)
+{
+#ifdef __FreeBSD__
+ tag_unref(&V_pf_qids, (u_int16_t)qid);
+#else
+ tag_unref(&pf_qids, (u_int16_t)qid);
+#endif
+}
+
+int
+pf_begin_altq(u_int32_t *ticket)
+{
+ struct pf_altq *altq;
+ int error = 0;
+
+ /* Purge the old altq list */
+#ifdef __FreeBSD__
+ while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)) != NULL) {
+ TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries);
+ if (altq->qname[0] == 0 &&
+ (altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
+#else
+ while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) {
+ TAILQ_REMOVE(pf_altqs_inactive, altq, entries);
+ if (altq->qname[0] == 0) {
+#endif
+ /* detach and destroy the discipline */
+ error = altq_remove(altq);
+ } else
+ pf_qid_unref(altq->qid);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_altq_pl, altq);
+#else
+ pool_put(&pf_altq_pl, altq);
+#endif
+ }
+ if (error)
+ return (error);
+#ifdef __FreeBSD__
+ *ticket = ++V_ticket_altqs_inactive;
+ V_altqs_inactive_open = 1;
+#else
+ *ticket = ++ticket_altqs_inactive;
+ altqs_inactive_open = 1;
+#endif
+ return (0);
+}
+
+int
+pf_rollback_altq(u_int32_t ticket)
+{
+ struct pf_altq *altq;
+ int error = 0;
+
+#ifdef __FreeBSD__
+ if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
+ return (0);
+ /* Purge the old altq list */
+ while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)) != NULL) {
+ TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries);
+ if (altq->qname[0] == 0 &&
+ (altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
+#else
+ if (!altqs_inactive_open || ticket != ticket_altqs_inactive)
+ return (0);
+ /* Purge the old altq list */
+ while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) {
+ TAILQ_REMOVE(pf_altqs_inactive, altq, entries);
+ if (altq->qname[0] == 0) {
+#endif
+ /* detach and destroy the discipline */
+ error = altq_remove(altq);
+ } else
+ pf_qid_unref(altq->qid);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_altq_pl, altq);
+#else
+ pool_put(&pf_altq_pl, altq);
+#endif
+ }
+#ifdef __FreeBSD__
+ V_altqs_inactive_open = 0;
+#else
+ altqs_inactive_open = 0;
+#endif
+ return (error);
+}
+
+int
+pf_commit_altq(u_int32_t ticket)
+{
+ struct pf_altqqueue *old_altqs;
+ struct pf_altq *altq;
+ int s, err, error = 0;
+
+#ifdef __FreeBSD__
+ if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
+#else
+ if (!altqs_inactive_open || ticket != ticket_altqs_inactive)
+#endif
+ return (EBUSY);
+
+ /* swap altqs, keep the old. */
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ old_altqs = V_pf_altqs_active;
+ V_pf_altqs_active = V_pf_altqs_inactive;
+ V_pf_altqs_inactive = old_altqs;
+ V_ticket_altqs_active = V_ticket_altqs_inactive;
+#else
+ old_altqs = pf_altqs_active;
+ pf_altqs_active = pf_altqs_inactive;
+ pf_altqs_inactive = old_altqs;
+ ticket_altqs_active = ticket_altqs_inactive;
+#endif
+
+ /* Attach new disciplines */
+#ifdef __FreeBSD__
+ TAILQ_FOREACH(altq, V_pf_altqs_active, entries) {
+ if (altq->qname[0] == 0 &&
+ (altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
+#else
+ TAILQ_FOREACH(altq, pf_altqs_active, entries) {
+ if (altq->qname[0] == 0) {
+#endif
+ /* attach the discipline */
+ error = altq_pfattach(altq);
+#ifdef __FreeBSD__
+ if (error == 0 && V_pf_altq_running)
+#else
+ if (error == 0 && pf_altq_running)
+#endif
+ error = pf_enable_altq(altq);
+ if (error != 0) {
+ splx(s);
+ return (error);
+ }
+ }
+ }
+
+ /* Purge the old altq list */
+#ifdef __FreeBSD__
+ while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)) != NULL) {
+ TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries);
+ if (altq->qname[0] == 0 &&
+ (altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
+#else
+ while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) {
+ TAILQ_REMOVE(pf_altqs_inactive, altq, entries);
+ if (altq->qname[0] == 0) {
+#endif
+ /* detach and destroy the discipline */
+#ifdef __FreeBSD__
+ if (V_pf_altq_running)
+#else
+ if (pf_altq_running)
+#endif
+ error = pf_disable_altq(altq);
+ err = altq_pfdetach(altq);
+ if (err != 0 && error == 0)
+ error = err;
+ err = altq_remove(altq);
+ if (err != 0 && error == 0)
+ error = err;
+ } else
+ pf_qid_unref(altq->qid);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_altq_pl, altq);
+#else
+ pool_put(&pf_altq_pl, altq);
+#endif
+ }
+ splx(s);
+
+#ifdef __FreeBSD__
+ V_altqs_inactive_open = 0;
+#else
+ altqs_inactive_open = 0;
+#endif
+ return (error);
+}
+
+int
+pf_enable_altq(struct pf_altq *altq)
+{
+ struct ifnet *ifp;
+ struct tb_profile tb;
+ int s, error = 0;
+
+ if ((ifp = ifunit(altq->ifname)) == NULL)
+ return (EINVAL);
+
+ if (ifp->if_snd.altq_type != ALTQT_NONE)
+ error = altq_enable(&ifp->if_snd);
+
+ /* set tokenbucket regulator */
+ if (error == 0 && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
+ tb.rate = altq->ifbandwidth;
+ tb.depth = altq->tbrsize;
+ s = splnet();
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ error = tbr_set(&ifp->if_snd, &tb);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ splx(s);
+ }
+
+ return (error);
+}
+
+int
+pf_disable_altq(struct pf_altq *altq)
+{
+ struct ifnet *ifp;
+ struct tb_profile tb;
+ int s, error;
+
+ if ((ifp = ifunit(altq->ifname)) == NULL)
+ return (EINVAL);
+
+ /*
+ * when the discipline is no longer referenced, it was overridden
+ * by a new one. if so, just return.
+ */
+ if (altq->altq_disc != ifp->if_snd.altq_disc)
+ return (0);
+
+ error = altq_disable(&ifp->if_snd);
+
+ if (error == 0) {
+ /* clear tokenbucket regulator */
+ tb.rate = 0;
+ s = splnet();
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ error = tbr_set(&ifp->if_snd, &tb);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ splx(s);
+ }
+
+ return (error);
+}
+
+#ifdef __FreeBSD__
+void
+pf_altq_ifnet_event(struct ifnet *ifp, int remove)
+{
+ struct ifnet *ifp1;
+ struct pf_altq *a1, *a2, *a3;
+ u_int32_t ticket;
+ int error = 0;
+
+ /* Interrupt userland queue modifications */
+#ifdef __FreeBSD__
+ if (V_altqs_inactive_open)
+ pf_rollback_altq(V_ticket_altqs_inactive);
+#else
+ if (altqs_inactive_open)
+ pf_rollback_altq(ticket_altqs_inactive);
+#endif
+
+ /* Start new altq ruleset */
+ if (pf_begin_altq(&ticket))
+ return;
+
+ /* Copy the current active set */
+#ifdef __FreeBSD__
+ TAILQ_FOREACH(a1, V_pf_altqs_active, entries) {
+ a2 = pool_get(&V_pf_altq_pl, PR_NOWAIT);
+#else
+ TAILQ_FOREACH(a1, pf_altqs_active, entries) {
+ a2 = pool_get(&pf_altq_pl, PR_NOWAIT);
+#endif
+ if (a2 == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ bcopy(a1, a2, sizeof(struct pf_altq));
+
+ if (a2->qname[0] != 0) {
+ if ((a2->qid = pf_qname2qid(a2->qname)) == 0) {
+ error = EBUSY;
+#ifdef __FreeBSD__
+ pool_put(&V_pf_altq_pl, a2);
+#else
+ pool_put(&pf_altq_pl, a2);
+#endif
+ break;
+ }
+ a2->altq_disc = NULL;
+#ifdef __FreeBSD__
+ TAILQ_FOREACH(a3, V_pf_altqs_inactive, entries) {
+#else
+ TAILQ_FOREACH(a3, pf_altqs_inactive, entries) {
+#endif
+ if (strncmp(a3->ifname, a2->ifname,
+ IFNAMSIZ) == 0 && a3->qname[0] == 0) {
+ a2->altq_disc = a3->altq_disc;
+ break;
+ }
+ }
+ }
+ /* Deactivate the interface in question */
+ a2->local_flags &= ~PFALTQ_FLAG_IF_REMOVED;
+ if ((ifp1 = ifunit(a2->ifname)) == NULL ||
+ (remove && ifp1 == ifp)) {
+ a2->local_flags |= PFALTQ_FLAG_IF_REMOVED;
+ } else {
+ PF_UNLOCK();
+ error = altq_add(a2);
+ PF_LOCK();
+
+#ifdef __FreeBSD__
+ if (ticket != V_ticket_altqs_inactive)
+#else
+ if (ticket != ticket_altqs_inactive)
+#endif
+ error = EBUSY;
+
+ if (error) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_altq_pl, a2);
+#else
+ pool_put(&pf_altq_pl, a2);
+#endif
+ break;
+ }
+ }
+
+#ifdef __FreeBSD__
+ TAILQ_INSERT_TAIL(V_pf_altqs_inactive, a2, entries);
+#else
+ TAILQ_INSERT_TAIL(pf_altqs_inactive, a2, entries);
+#endif
+ }
+
+ if (error != 0)
+ pf_rollback_altq(ticket);
+ else
+ pf_commit_altq(ticket);
+ }
+#endif
+#endif /* ALTQ */
+
+int
+pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
+{
+ struct pf_ruleset *rs;
+ struct pf_rule *rule;
+
+ if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
+ return (EINVAL);
+ rs = pf_find_or_create_ruleset(anchor);
+ if (rs == NULL)
+ return (EINVAL);
+ while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
+ pf_rm_rule(rs->rules[rs_num].inactive.ptr, rule);
+ rs->rules[rs_num].inactive.rcount--;
+ }
+ *ticket = ++rs->rules[rs_num].inactive.ticket;
+ rs->rules[rs_num].inactive.open = 1;
+ return (0);
+}
+
+int
+pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor)
+{
+ struct pf_ruleset *rs;
+ struct pf_rule *rule;
+
+ if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
+ return (EINVAL);
+ rs = pf_find_ruleset(anchor);
+ if (rs == NULL || !rs->rules[rs_num].inactive.open ||
+ rs->rules[rs_num].inactive.ticket != ticket)
+ return (0);
+ while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
+ pf_rm_rule(rs->rules[rs_num].inactive.ptr, rule);
+ rs->rules[rs_num].inactive.rcount--;
+ }
+ rs->rules[rs_num].inactive.open = 0;
+ return (0);
+}
+
+#define PF_MD5_UPD(st, elm) \
+ MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm))
+
+#define PF_MD5_UPD_STR(st, elm) \
+ MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm))
+
+#define PF_MD5_UPD_HTONL(st, elm, stor) do { \
+ (stor) = htonl((st)->elm); \
+ MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\
+} while (0)
+
+#define PF_MD5_UPD_HTONS(st, elm, stor) do { \
+ (stor) = htons((st)->elm); \
+ MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\
+} while (0)
+
+void
+pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr)
+{
+ PF_MD5_UPD(pfr, addr.type);
+ switch (pfr->addr.type) {
+ case PF_ADDR_DYNIFTL:
+ PF_MD5_UPD(pfr, addr.v.ifname);
+ PF_MD5_UPD(pfr, addr.iflags);
+ break;
+ case PF_ADDR_TABLE:
+ PF_MD5_UPD(pfr, addr.v.tblname);
+ break;
+ case PF_ADDR_ADDRMASK:
+ /* XXX ignore af? */
+ PF_MD5_UPD(pfr, addr.v.a.addr.addr32);
+ PF_MD5_UPD(pfr, addr.v.a.mask.addr32);
+ break;
+ case PF_ADDR_RTLABEL:
+ PF_MD5_UPD(pfr, addr.v.rtlabelname);
+ break;
+ }
+
+ PF_MD5_UPD(pfr, port[0]);
+ PF_MD5_UPD(pfr, port[1]);
+ PF_MD5_UPD(pfr, neg);
+ PF_MD5_UPD(pfr, port_op);
+}
+
+void
+pf_hash_rule(MD5_CTX *ctx, struct pf_rule *rule)
+{
+ u_int16_t x;
+ u_int32_t y;
+
+ pf_hash_rule_addr(ctx, &rule->src);
+ pf_hash_rule_addr(ctx, &rule->dst);
+ PF_MD5_UPD_STR(rule, label);
+ PF_MD5_UPD_STR(rule, ifname);
+ PF_MD5_UPD_STR(rule, match_tagname);
+ PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
+ PF_MD5_UPD_HTONL(rule, os_fingerprint, y);
+ PF_MD5_UPD_HTONL(rule, prob, y);
+ PF_MD5_UPD_HTONL(rule, uid.uid[0], y);
+ PF_MD5_UPD_HTONL(rule, uid.uid[1], y);
+ PF_MD5_UPD(rule, uid.op);
+ PF_MD5_UPD_HTONL(rule, gid.gid[0], y);
+ PF_MD5_UPD_HTONL(rule, gid.gid[1], y);
+ PF_MD5_UPD(rule, gid.op);
+ PF_MD5_UPD_HTONL(rule, rule_flag, y);
+ PF_MD5_UPD(rule, action);
+ PF_MD5_UPD(rule, direction);
+ PF_MD5_UPD(rule, af);
+ PF_MD5_UPD(rule, quick);
+ PF_MD5_UPD(rule, ifnot);
+ PF_MD5_UPD(rule, match_tag_not);
+ PF_MD5_UPD(rule, natpass);
+ PF_MD5_UPD(rule, keep_state);
+ PF_MD5_UPD(rule, proto);
+ PF_MD5_UPD(rule, type);
+ PF_MD5_UPD(rule, code);
+ PF_MD5_UPD(rule, flags);
+ PF_MD5_UPD(rule, flagset);
+ PF_MD5_UPD(rule, allow_opts);
+ PF_MD5_UPD(rule, rt);
+ PF_MD5_UPD(rule, tos);
+}
+
+int
+pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
+{
+ struct pf_ruleset *rs;
+ struct pf_rule *rule, **old_array;
+ struct pf_rulequeue *old_rules;
+ int s, error;
+ u_int32_t old_rcount;
+
+ if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
+ return (EINVAL);
+ rs = pf_find_ruleset(anchor);
+ if (rs == NULL || !rs->rules[rs_num].inactive.open ||
+ ticket != rs->rules[rs_num].inactive.ticket)
+ return (EBUSY);
+
+ /* Calculate checksum for the main ruleset */
+ if (rs == &pf_main_ruleset) {
+ error = pf_setup_pfsync_matching(rs);
+ if (error != 0)
+ return (error);
+ }
+
+ /* Swap rules, keep the old. */
+ s = splsoftnet();
+ old_rules = rs->rules[rs_num].active.ptr;
+ old_rcount = rs->rules[rs_num].active.rcount;
+ old_array = rs->rules[rs_num].active.ptr_array;
+
+ rs->rules[rs_num].active.ptr =
+ rs->rules[rs_num].inactive.ptr;
+ rs->rules[rs_num].active.ptr_array =
+ rs->rules[rs_num].inactive.ptr_array;
+ rs->rules[rs_num].active.rcount =
+ rs->rules[rs_num].inactive.rcount;
+ rs->rules[rs_num].inactive.ptr = old_rules;
+ rs->rules[rs_num].inactive.ptr_array = old_array;
+ rs->rules[rs_num].inactive.rcount = old_rcount;
+
+ rs->rules[rs_num].active.ticket =
+ rs->rules[rs_num].inactive.ticket;
+ pf_calc_skip_steps(rs->rules[rs_num].active.ptr);
+
+
+ /* Purge the old rule list. */
+ while ((rule = TAILQ_FIRST(old_rules)) != NULL)
+ pf_rm_rule(old_rules, rule);
+ if (rs->rules[rs_num].inactive.ptr_array)
+ free(rs->rules[rs_num].inactive.ptr_array, M_TEMP);
+ rs->rules[rs_num].inactive.ptr_array = NULL;
+ rs->rules[rs_num].inactive.rcount = 0;
+ rs->rules[rs_num].inactive.open = 0;
+ pf_remove_if_empty_ruleset(rs);
+ splx(s);
+ return (0);
+}
+
+int
+pf_setup_pfsync_matching(struct pf_ruleset *rs)
+{
+ MD5_CTX ctx;
+ struct pf_rule *rule;
+ int rs_cnt;
+ u_int8_t digest[PF_MD5_DIGEST_LENGTH];
+
+ MD5Init(&ctx);
+ for (rs_cnt = 0; rs_cnt < PF_RULESET_MAX; rs_cnt++) {
+ /* XXX PF_RULESET_SCRUB as well? */
+ if (rs_cnt == PF_RULESET_SCRUB)
+ continue;
+
+ if (rs->rules[rs_cnt].inactive.ptr_array)
+ free(rs->rules[rs_cnt].inactive.ptr_array, M_TEMP);
+ rs->rules[rs_cnt].inactive.ptr_array = NULL;
+
+ if (rs->rules[rs_cnt].inactive.rcount) {
+ rs->rules[rs_cnt].inactive.ptr_array =
+ malloc(sizeof(caddr_t) *
+ rs->rules[rs_cnt].inactive.rcount,
+ M_TEMP, M_NOWAIT);
+
+ if (!rs->rules[rs_cnt].inactive.ptr_array)
+ return (ENOMEM);
+ }
+
+ TAILQ_FOREACH(rule, rs->rules[rs_cnt].inactive.ptr,
+ entries) {
+ pf_hash_rule(&ctx, rule);
+ (rs->rules[rs_cnt].inactive.ptr_array)[rule->nr] = rule;
+ }
+ }
+
+ MD5Final(digest, &ctx);
+#ifdef __FreeBSD__
+ memcpy(V_pf_status.pf_chksum, digest, sizeof(V_pf_status.pf_chksum));
+#else
+ memcpy(pf_status.pf_chksum, digest, sizeof(pf_status.pf_chksum));
+#endif
+ return (0);
+}
+
+int
+pf_addr_setup(struct pf_ruleset *ruleset, struct pf_addr_wrap *addr,
+ sa_family_t af)
+{
+ if (pfi_dynaddr_setup(addr, af) ||
+ pf_tbladdr_setup(ruleset, addr))
+ return (EINVAL);
+
+ return (0);
+}
+
+void
+pf_addr_copyout(struct pf_addr_wrap *addr)
+{
+ pfi_dynaddr_copyout(addr);
+ pf_tbladdr_copyout(addr);
+ pf_rtlabel_copyout(addr);
+}
+
+int
+#ifdef __FreeBSD__
+pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
+#else
+pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
+#endif
+{
+ struct pf_pooladdr *pa = NULL;
+ struct pf_pool *pool = NULL;
+#ifndef __FreeBSD__
+ int s;
+#endif
+ int error = 0;
+
+ CURVNET_SET(TD_TO_VNET(td));
+
+ /* XXX keep in sync with switch() below */
+#ifdef __FreeBSD__
+ if (securelevel_gt(td->td_ucred, 2))
+#else
+ if (securelevel > 1)
+#endif
+ switch (cmd) {
+ case DIOCGETRULES:
+ case DIOCGETRULE:
+ case DIOCGETADDRS:
+ case DIOCGETADDR:
+ case DIOCGETSTATE:
+ case DIOCSETSTATUSIF:
+ case DIOCGETSTATUS:
+ case DIOCCLRSTATUS:
+ case DIOCNATLOOK:
+ case DIOCSETDEBUG:
+ case DIOCGETSTATES:
+ case DIOCGETTIMEOUT:
+ case DIOCCLRRULECTRS:
+ case DIOCGETLIMIT:
+ case DIOCGETALTQS:
+ case DIOCGETALTQ:
+ case DIOCGETQSTATS:
+ case DIOCGETRULESETS:
+ case DIOCGETRULESET:
+ case DIOCRGETTABLES:
+ case DIOCRGETTSTATS:
+ case DIOCRCLRTSTATS:
+ case DIOCRCLRADDRS:
+ case DIOCRADDADDRS:
+ case DIOCRDELADDRS:
+ case DIOCRSETADDRS:
+ case DIOCRGETADDRS:
+ case DIOCRGETASTATS:
+ case DIOCRCLRASTATS:
+ case DIOCRTSTADDRS:
+ case DIOCOSFPGET:
+ case DIOCGETSRCNODES:
+ case DIOCCLRSRCNODES:
+ case DIOCIGETIFACES:
+#ifdef __FreeBSD__
+ case DIOCGIFSPEED:
+#endif
+ case DIOCSETIFFLAG:
+ case DIOCCLRIFFLAG:
+ break;
+ case DIOCRCLRTABLES:
+ case DIOCRADDTABLES:
+ case DIOCRDELTABLES:
+ case DIOCRSETTFLAGS:
+ if (((struct pfioc_table *)addr)->pfrio_flags &
+ PFR_FLAG_DUMMY)
+ break; /* dummy operation ok */
+ return (EPERM);
+ default:
+ return (EPERM);
+ }
+
+ if (!(flags & FWRITE))
+ switch (cmd) {
+ case DIOCGETRULES:
+ case DIOCGETADDRS:
+ case DIOCGETADDR:
+ case DIOCGETSTATE:
+ case DIOCGETSTATUS:
+ case DIOCGETSTATES:
+ case DIOCGETTIMEOUT:
+ case DIOCGETLIMIT:
+ case DIOCGETALTQS:
+ case DIOCGETALTQ:
+ case DIOCGETQSTATS:
+ case DIOCGETRULESETS:
+ case DIOCGETRULESET:
+ case DIOCNATLOOK:
+ case DIOCRGETTABLES:
+ case DIOCRGETTSTATS:
+ case DIOCRGETADDRS:
+ case DIOCRGETASTATS:
+ case DIOCRTSTADDRS:
+ case DIOCOSFPGET:
+ case DIOCGETSRCNODES:
+ case DIOCIGETIFACES:
+#ifdef __FreeBSD__
+ case DIOCGIFSPEED:
+#endif
+ break;
+ case DIOCRCLRTABLES:
+ case DIOCRADDTABLES:
+ case DIOCRDELTABLES:
+ case DIOCRCLRTSTATS:
+ case DIOCRCLRADDRS:
+ case DIOCRADDADDRS:
+ case DIOCRDELADDRS:
+ case DIOCRSETADDRS:
+ case DIOCRSETTFLAGS:
+ if (((struct pfioc_table *)addr)->pfrio_flags &
+ PFR_FLAG_DUMMY) {
+ flags |= FWRITE; /* need write lock for dummy */
+ break; /* dummy operation ok */
+ }
+ return (EACCES);
+ case DIOCGETRULE:
+ if (((struct pfioc_rule *)addr)->action ==
+ PF_GET_CLR_CNTR)
+ return (EACCES);
+ break;
+ default:
+ return (EACCES);
+ }
+
+ if (flags & FWRITE)
+#ifdef __FreeBSD__
+ sx_xlock(&V_pf_consistency_lock);
+ else
+ sx_slock(&V_pf_consistency_lock);
+#else
+ rw_enter_write(&pf_consistency_lock);
+ else
+ rw_enter_read(&pf_consistency_lock);
+#endif
+
+#ifdef __FreeBSD__
+ PF_LOCK();
+#else
+ s = splsoftnet();
+#endif
+ switch (cmd) {
+
+ case DIOCSTART:
+#ifdef __FreeBSD__
+ if (V_pf_status.running)
+#else
+ if (pf_status.running)
+#endif
+ error = EEXIST;
+ else {
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+ error = hook_pf();
+ PF_LOCK();
+ if (error) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: pfil registeration fail\n"));
+ break;
+ }
+ V_pf_status.running = 1;
+ V_pf_status.since = time_second;
+
+ if (V_pf_status.stateid == 0) {
+ V_pf_status.stateid = time_second;
+ V_pf_status.stateid = V_pf_status.stateid << 32;
+ }
+#else
+ pf_status.running = 1;
+ pf_status.since = time_second;
+
+ if (pf_status.stateid == 0) {
+ pf_status.stateid = time_second;
+ pf_status.stateid = pf_status.stateid << 32;
+ }
+#endif
+ DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
+ }
+ break;
+
+ case DIOCSTOP:
+#ifdef __FreeBSD__
+ if (!V_pf_status.running)
+ error = ENOENT;
+ else {
+ V_pf_status.running = 0;
+ PF_UNLOCK();
+ error = dehook_pf();
+ PF_LOCK();
+ if (error) {
+ V_pf_status.running = 1;
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: pfil unregisteration failed\n"));
+ }
+ V_pf_status.since = time_second;
+#else
+ if (!pf_status.running)
+ error = ENOENT;
+ else {
+ pf_status.running = 0;
+ pf_status.since = time_second;
+#endif
+ DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
+ }
+ break;
+
+ case DIOCADDRULE: {
+ struct pfioc_rule *pr = (struct pfioc_rule *)addr;
+ struct pf_ruleset *ruleset;
+ struct pf_rule *rule, *tail;
+ struct pf_pooladdr *pa;
+ int rs_num;
+
+ pr->anchor[sizeof(pr->anchor) - 1] = 0;
+ ruleset = pf_find_ruleset(pr->anchor);
+ if (ruleset == NULL) {
+ error = EINVAL;
+ break;
+ }
+ rs_num = pf_get_ruleset_number(pr->rule.action);
+ if (rs_num >= PF_RULESET_MAX) {
+ error = EINVAL;
+ break;
+ }
+ if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
+ error = EINVAL;
+ break;
+ }
+ if (pr->ticket != ruleset->rules[rs_num].inactive.ticket) {
+#ifdef __FreeBSD__
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("ticket: %d != [%d]%d\n", pr->ticket, rs_num,
+ ruleset->rules[rs_num].inactive.ticket));
+#endif
+ error = EBUSY;
+ break;
+ }
+#ifdef __FreeBSD__
+ if (pr->pool_ticket != V_ticket_pabuf) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pool_ticket: %d != %d\n", pr->pool_ticket,
+ V_ticket_pabuf));
+#else
+ if (pr->pool_ticket != ticket_pabuf) {
+#endif
+ error = EBUSY;
+ break;
+ }
+#ifdef __FreeBSD__
+ rule = pool_get(&V_pf_rule_pl, PR_NOWAIT);
+#else
+ rule = pool_get(&pf_rule_pl, PR_WAITOK|PR_LIMITFAIL);
+#endif
+ if (rule == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ bcopy(&pr->rule, rule, sizeof(struct pf_rule));
+#ifdef __FreeBSD__
+ rule->cuid = td->td_ucred->cr_ruid;
+ rule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
+#else
+ rule->cuid = p->p_cred->p_ruid;
+ rule->cpid = p->p_pid;
+#endif
+ rule->anchor = NULL;
+ rule->kif = NULL;
+ TAILQ_INIT(&rule->rpool.list);
+ /* initialize refcounting */
+ rule->states_cur = 0;
+ rule->src_nodes = 0;
+ rule->entries.tqe_prev = NULL;
+#ifndef INET
+ if (rule->af == AF_INET) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_rule_pl, rule);
+#else
+ pool_put(&pf_rule_pl, rule);
+#endif
+ error = EAFNOSUPPORT;
+ break;
+ }
+#endif /* INET */
+#ifndef INET6
+ if (rule->af == AF_INET6) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_rule_pl, rule);
+#else
+ pool_put(&pf_rule_pl, rule);
+#endif
+ error = EAFNOSUPPORT;
+ break;
+ }
+#endif /* INET6 */
+ tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
+ pf_rulequeue);
+ if (tail)
+ rule->nr = tail->nr + 1;
+ else
+ rule->nr = 0;
+ if (rule->ifname[0]) {
+ rule->kif = pfi_kif_get(rule->ifname);
+ if (rule->kif == NULL) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_rule_pl, rule);
+#else
+ pool_put(&pf_rule_pl, rule);
+#endif
+ error = EINVAL;
+ break;
+ }
+ pfi_kif_ref(rule->kif, PFI_KIF_REF_RULE);
+ }
+
+#ifdef __FreeBSD__ /* ROUTING */
+ if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs)
+#else
+ if (rule->rtableid > 0 && !rtable_exists(rule->rtableid))
+#endif
+ error = EBUSY;
+
+#ifdef ALTQ
+ /* set queue IDs */
+ if (rule->qname[0] != 0) {
+ if ((rule->qid = pf_qname2qid(rule->qname)) == 0)
+ error = EBUSY;
+ else if (rule->pqname[0] != 0) {
+ if ((rule->pqid =
+ pf_qname2qid(rule->pqname)) == 0)
+ error = EBUSY;
+ } else
+ rule->pqid = rule->qid;
+ }
+#endif
+ if (rule->tagname[0])
+ if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
+ error = EBUSY;
+ if (rule->match_tagname[0])
+ if ((rule->match_tag =
+ pf_tagname2tag(rule->match_tagname)) == 0)
+ error = EBUSY;
+ if (rule->rt && !rule->direction)
+ error = EINVAL;
+#if NPFLOG > 0
+ if (!rule->log)
+ rule->logif = 0;
+ if (rule->logif >= PFLOGIFS_MAX)
+ error = EINVAL;
+#endif
+ if (pf_rtlabel_add(&rule->src.addr) ||
+ pf_rtlabel_add(&rule->dst.addr))
+ error = EBUSY;
+ if (pf_addr_setup(ruleset, &rule->src.addr, rule->af))
+ error = EINVAL;
+ if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af))
+ error = EINVAL;
+ if (pf_anchor_setup(rule, ruleset, pr->anchor_call))
+ error = EINVAL;
+#ifdef __FreeBSD__
+ TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
+#else
+ TAILQ_FOREACH(pa, &pf_pabuf, entries)
+#endif
+ if (pf_tbladdr_setup(ruleset, &pa->addr))
+ error = EINVAL;
+
+ if (rule->overload_tblname[0]) {
+ if ((rule->overload_tbl = pfr_attach_table(ruleset,
+ rule->overload_tblname, 0)) == NULL)
+ error = EINVAL;
+ else
+ rule->overload_tbl->pfrkt_flags |=
+ PFR_TFLAG_ACTIVE;
+ }
+
+#ifdef __FreeBSD__
+ pf_mv_pool(&V_pf_pabuf, &rule->rpool.list);
+#else
+ pf_mv_pool(&pf_pabuf, &rule->rpool.list);
+#endif
+ if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
+ (rule->action == PF_BINAT)) && rule->anchor == NULL) ||
+ (rule->rt > PF_FASTROUTE)) &&
+ (TAILQ_FIRST(&rule->rpool.list) == NULL))
+ error = EINVAL;
+
+ if (error) {
+ pf_rm_rule(NULL, rule);
+ break;
+ }
+
+#ifdef __FreeBSD__
+ if (!V_debug_pfugidhack && (rule->uid.op || rule->gid.op ||
+ rule->log & PF_LOG_SOCKET_LOOKUP)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: debug.pfugidhack enabled\n"));
+ V_debug_pfugidhack = 1;
+ }
+#endif
+ rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list);
+ rule->evaluations = rule->packets[0] = rule->packets[1] =
+ rule->bytes[0] = rule->bytes[1] = 0;
+ TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
+ rule, entries);
+ ruleset->rules[rs_num].inactive.rcount++;
+ break;
+ }
+
+ case DIOCGETRULES: {
+ struct pfioc_rule *pr = (struct pfioc_rule *)addr;
+ struct pf_ruleset *ruleset;
+ struct pf_rule *tail;
+ int rs_num;
+
+ pr->anchor[sizeof(pr->anchor) - 1] = 0;
+ ruleset = pf_find_ruleset(pr->anchor);
+ if (ruleset == NULL) {
+ error = EINVAL;
+ break;
+ }
+ rs_num = pf_get_ruleset_number(pr->rule.action);
+ if (rs_num >= PF_RULESET_MAX) {
+ error = EINVAL;
+ break;
+ }
+ tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
+ pf_rulequeue);
+ if (tail)
+ pr->nr = tail->nr + 1;
+ else
+ pr->nr = 0;
+ pr->ticket = ruleset->rules[rs_num].active.ticket;
+ break;
+ }
+
+ case DIOCGETRULE: {
+ struct pfioc_rule *pr = (struct pfioc_rule *)addr;
+ struct pf_ruleset *ruleset;
+ struct pf_rule *rule;
+ int rs_num, i;
+
+ pr->anchor[sizeof(pr->anchor) - 1] = 0;
+ ruleset = pf_find_ruleset(pr->anchor);
+ if (ruleset == NULL) {
+ error = EINVAL;
+ break;
+ }
+ rs_num = pf_get_ruleset_number(pr->rule.action);
+ if (rs_num >= PF_RULESET_MAX) {
+ error = EINVAL;
+ break;
+ }
+ if (pr->ticket != ruleset->rules[rs_num].active.ticket) {
+ error = EBUSY;
+ break;
+ }
+ rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
+ while ((rule != NULL) && (rule->nr != pr->nr))
+ rule = TAILQ_NEXT(rule, entries);
+ if (rule == NULL) {
+ error = EBUSY;
+ break;
+ }
+ bcopy(rule, &pr->rule, sizeof(struct pf_rule));
+ if (pf_anchor_copyout(ruleset, rule, pr)) {
+ error = EBUSY;
+ break;
+ }
+ pf_addr_copyout(&pr->rule.src.addr);
+ pf_addr_copyout(&pr->rule.dst.addr);
+ for (i = 0; i < PF_SKIP_COUNT; ++i)
+ if (rule->skip[i].ptr == NULL)
+ pr->rule.skip[i].nr = -1;
+ else
+ pr->rule.skip[i].nr =
+ rule->skip[i].ptr->nr;
+
+ if (pr->action == PF_GET_CLR_CNTR) {
+ rule->evaluations = 0;
+ rule->packets[0] = rule->packets[1] = 0;
+ rule->bytes[0] = rule->bytes[1] = 0;
+ rule->states_tot = 0;
+ }
+ break;
+ }
+
+ case DIOCCHANGERULE: {
+ struct pfioc_rule *pcr = (struct pfioc_rule *)addr;
+ struct pf_ruleset *ruleset;
+ struct pf_rule *oldrule = NULL, *newrule = NULL;
+ u_int32_t nr = 0;
+ int rs_num;
+
+ if (!(pcr->action == PF_CHANGE_REMOVE ||
+ pcr->action == PF_CHANGE_GET_TICKET) &&
+#ifdef __FreeBSD__
+ pcr->pool_ticket != V_ticket_pabuf) {
+#else
+ pcr->pool_ticket != ticket_pabuf) {
+#endif
+ error = EBUSY;
+ break;
+ }
+
+ if (pcr->action < PF_CHANGE_ADD_HEAD ||
+ pcr->action > PF_CHANGE_GET_TICKET) {
+ error = EINVAL;
+ break;
+ }
+ ruleset = pf_find_ruleset(pcr->anchor);
+ if (ruleset == NULL) {
+ error = EINVAL;
+ break;
+ }
+ rs_num = pf_get_ruleset_number(pcr->rule.action);
+ if (rs_num >= PF_RULESET_MAX) {
+ error = EINVAL;
+ break;
+ }
+
+ if (pcr->action == PF_CHANGE_GET_TICKET) {
+ pcr->ticket = ++ruleset->rules[rs_num].active.ticket;
+ break;
+ } else {
+ if (pcr->ticket !=
+ ruleset->rules[rs_num].active.ticket) {
+ error = EINVAL;
+ break;
+ }
+ if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
+ error = EINVAL;
+ break;
+ }
+ }
+
+ if (pcr->action != PF_CHANGE_REMOVE) {
+#ifdef __FreeBSD__
+ newrule = pool_get(&V_pf_rule_pl, PR_NOWAIT);
+#else
+ newrule = pool_get(&pf_rule_pl, PR_WAITOK|PR_LIMITFAIL);
+#endif
+ if (newrule == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ bcopy(&pcr->rule, newrule, sizeof(struct pf_rule));
+#ifdef __FreeBSD__
+ newrule->cuid = td->td_ucred->cr_ruid;
+ newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
+#else
+ newrule->cuid = p->p_cred->p_ruid;
+ newrule->cpid = p->p_pid;
+#endif
+ TAILQ_INIT(&newrule->rpool.list);
+ /* initialize refcounting */
+ newrule->states_cur = 0;
+ newrule->entries.tqe_prev = NULL;
+#ifndef INET
+ if (newrule->af == AF_INET) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_rule_pl, newrule);
+#else
+ pool_put(&pf_rule_pl, newrule);
+#endif
+ error = EAFNOSUPPORT;
+ break;
+ }
+#endif /* INET */
+#ifndef INET6
+ if (newrule->af == AF_INET6) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_rule_pl, newrule);
+#else
+ pool_put(&pf_rule_pl, newrule);
+#endif
+ error = EAFNOSUPPORT;
+ break;
+ }
+#endif /* INET6 */
+ if (newrule->ifname[0]) {
+ newrule->kif = pfi_kif_get(newrule->ifname);
+ if (newrule->kif == NULL) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_rule_pl, newrule);
+#else
+ pool_put(&pf_rule_pl, newrule);
+#endif
+ error = EINVAL;
+ break;
+ }
+ pfi_kif_ref(newrule->kif, PFI_KIF_REF_RULE);
+ } else
+ newrule->kif = NULL;
+
+ if (newrule->rtableid > 0 &&
+#ifdef __FreeBSD__ /* ROUTING */
+ newrule->rtableid >= rt_numfibs)
+#else
+ !rtable_exists(newrule->rtableid))
+#endif
+ error = EBUSY;
+
+#ifdef ALTQ
+ /* set queue IDs */
+ if (newrule->qname[0] != 0) {
+ if ((newrule->qid =
+ pf_qname2qid(newrule->qname)) == 0)
+ error = EBUSY;
+ else if (newrule->pqname[0] != 0) {
+ if ((newrule->pqid =
+ pf_qname2qid(newrule->pqname)) == 0)
+ error = EBUSY;
+ } else
+ newrule->pqid = newrule->qid;
+ }
+#endif /* ALTQ */
+ if (newrule->tagname[0])
+ if ((newrule->tag =
+ pf_tagname2tag(newrule->tagname)) == 0)
+ error = EBUSY;
+ if (newrule->match_tagname[0])
+ if ((newrule->match_tag = pf_tagname2tag(
+ newrule->match_tagname)) == 0)
+ error = EBUSY;
+ if (newrule->rt && !newrule->direction)
+ error = EINVAL;
+#if NPFLOG > 0
+ if (!newrule->log)
+ newrule->logif = 0;
+ if (newrule->logif >= PFLOGIFS_MAX)
+ error = EINVAL;
+#endif
+ if (pf_rtlabel_add(&newrule->src.addr) ||
+ pf_rtlabel_add(&newrule->dst.addr))
+ error = EBUSY;
+ if (pf_addr_setup(ruleset, &newrule->src.addr, newrule->af))
+ error = EINVAL;
+ if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af))
+ error = EINVAL;
+ if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call))
+ error = EINVAL;
+#ifdef __FreeBSD__
+ TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
+#else
+ TAILQ_FOREACH(pa, &pf_pabuf, entries)
+#endif
+ if (pf_tbladdr_setup(ruleset, &pa->addr))
+ error = EINVAL;
+
+ if (newrule->overload_tblname[0]) {
+ if ((newrule->overload_tbl = pfr_attach_table(
+ ruleset, newrule->overload_tblname, 0)) ==
+ NULL)
+ error = EINVAL;
+ else
+ newrule->overload_tbl->pfrkt_flags |=
+ PFR_TFLAG_ACTIVE;
+ }
+
+#ifdef __FreeBSD__
+ pf_mv_pool(&V_pf_pabuf, &newrule->rpool.list);
+#else
+ pf_mv_pool(&pf_pabuf, &newrule->rpool.list);
+#endif
+ if (((((newrule->action == PF_NAT) ||
+ (newrule->action == PF_RDR) ||
+ (newrule->action == PF_BINAT) ||
+ (newrule->rt > PF_FASTROUTE)) &&
+ !newrule->anchor)) &&
+ (TAILQ_FIRST(&newrule->rpool.list) == NULL))
+ error = EINVAL;
+
+ if (error) {
+ pf_rm_rule(NULL, newrule);
+ break;
+ }
+
+#ifdef __FreeBSD__
+ if (!V_debug_pfugidhack && (newrule->uid.op ||
+ newrule->gid.op ||
+ newrule->log & PF_LOG_SOCKET_LOOKUP)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: debug.pfugidhack enabled\n"));
+ V_debug_pfugidhack = 1;
+ }
+#endif
+
+ newrule->rpool.cur = TAILQ_FIRST(&newrule->rpool.list);
+ newrule->evaluations = 0;
+ newrule->packets[0] = newrule->packets[1] = 0;
+ newrule->bytes[0] = newrule->bytes[1] = 0;
+ }
+#ifdef __FreeBSD__
+ pf_empty_pool(&V_pf_pabuf);
+#else
+ pf_empty_pool(&pf_pabuf);
+#endif
+
+ if (pcr->action == PF_CHANGE_ADD_HEAD)
+ oldrule = TAILQ_FIRST(
+ ruleset->rules[rs_num].active.ptr);
+ else if (pcr->action == PF_CHANGE_ADD_TAIL)
+ oldrule = TAILQ_LAST(
+ ruleset->rules[rs_num].active.ptr, pf_rulequeue);
+ else {
+ oldrule = TAILQ_FIRST(
+ ruleset->rules[rs_num].active.ptr);
+ while ((oldrule != NULL) && (oldrule->nr != pcr->nr))
+ oldrule = TAILQ_NEXT(oldrule, entries);
+ if (oldrule == NULL) {
+ if (newrule != NULL)
+ pf_rm_rule(NULL, newrule);
+ error = EINVAL;
+ break;
+ }
+ }
+
+ if (pcr->action == PF_CHANGE_REMOVE) {
+ pf_rm_rule(ruleset->rules[rs_num].active.ptr, oldrule);
+ ruleset->rules[rs_num].active.rcount--;
+ } else {
+ if (oldrule == NULL)
+ TAILQ_INSERT_TAIL(
+ ruleset->rules[rs_num].active.ptr,
+ newrule, entries);
+ else if (pcr->action == PF_CHANGE_ADD_HEAD ||
+ pcr->action == PF_CHANGE_ADD_BEFORE)
+ TAILQ_INSERT_BEFORE(oldrule, newrule, entries);
+ else
+ TAILQ_INSERT_AFTER(
+ ruleset->rules[rs_num].active.ptr,
+ oldrule, newrule, entries);
+ ruleset->rules[rs_num].active.rcount++;
+ }
+
+ nr = 0;
+ TAILQ_FOREACH(oldrule,
+ ruleset->rules[rs_num].active.ptr, entries)
+ oldrule->nr = nr++;
+
+ ruleset->rules[rs_num].active.ticket++;
+
+ pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
+ pf_remove_if_empty_ruleset(ruleset);
+
+ break;
+ }
+
+ case DIOCCLRSTATES: {
+ struct pf_state *s, *nexts;
+ struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
+ u_int killed = 0;
+
+#ifdef __FreeBSD__
+ for (s = RB_MIN(pf_state_tree_id, &V_tree_id); s; s = nexts) {
+ nexts = RB_NEXT(pf_state_tree_id, &V_tree_id, s);
+#else
+ for (s = RB_MIN(pf_state_tree_id, &tree_id); s; s = nexts) {
+ nexts = RB_NEXT(pf_state_tree_id, &tree_id, s);
+#endif
+
+ if (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
+ s->kif->pfik_name)) {
+#if NPFSYNC > 0
+ /* don't send out individual delete messages */
+ SET(s->state_flags, PFSTATE_NOSYNC);
+#endif
+ pf_unlink_state(s);
+ killed++;
+ }
+ }
+ psk->psk_killed = killed;
+#if NPFSYNC > 0
+#ifdef __FreeBSD__
+ if (pfsync_clear_states_ptr != NULL)
+ pfsync_clear_states_ptr(V_pf_status.hostid, psk->psk_ifname);
+#else
+ pfsync_clear_states(pf_status.hostid, psk->psk_ifname);
+#endif
+#endif
+ break;
+ }
+
+ case DIOCKILLSTATES: {
+ struct pf_state *s, *nexts;
+ struct pf_state_key *sk;
+ struct pf_addr *srcaddr, *dstaddr;
+ u_int16_t srcport, dstport;
+ struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
+ u_int killed = 0;
+
+ if (psk->psk_pfcmp.id) {
+ if (psk->psk_pfcmp.creatorid == 0)
+#ifdef __FreeBSD__
+ psk->psk_pfcmp.creatorid = V_pf_status.hostid;
+#else
+ psk->psk_pfcmp.creatorid = pf_status.hostid;
+#endif
+ if ((s = pf_find_state_byid(&psk->psk_pfcmp))) {
+ pf_unlink_state(s);
+ psk->psk_killed = 1;
+ }
+ break;
+ }
+
+#ifdef __FreeBSD__
+ for (s = RB_MIN(pf_state_tree_id, &V_tree_id); s;
+ s = nexts) {
+ nexts = RB_NEXT(pf_state_tree_id, &V_tree_id, s);
+#else
+ for (s = RB_MIN(pf_state_tree_id, &tree_id); s;
+ s = nexts) {
+ nexts = RB_NEXT(pf_state_tree_id, &tree_id, s);
+#endif
+ sk = s->key[PF_SK_WIRE];
+
+ if (s->direction == PF_OUT) {
+ srcaddr = &sk->addr[1];
+ dstaddr = &sk->addr[0];
+ srcport = sk->port[0];
+ dstport = sk->port[0];
+ } else {
+ srcaddr = &sk->addr[0];
+ dstaddr = &sk->addr[1];
+ srcport = sk->port[0];
+ dstport = sk->port[0];
+ }
+ if ((!psk->psk_af || sk->af == psk->psk_af)
+ && (!psk->psk_proto || psk->psk_proto ==
+ sk->proto) &&
+ PF_MATCHA(psk->psk_src.neg,
+ &psk->psk_src.addr.v.a.addr,
+ &psk->psk_src.addr.v.a.mask,
+ srcaddr, sk->af) &&
+ PF_MATCHA(psk->psk_dst.neg,
+ &psk->psk_dst.addr.v.a.addr,
+ &psk->psk_dst.addr.v.a.mask,
+ dstaddr, sk->af) &&
+ (psk->psk_src.port_op == 0 ||
+ pf_match_port(psk->psk_src.port_op,
+ psk->psk_src.port[0], psk->psk_src.port[1],
+ srcport)) &&
+ (psk->psk_dst.port_op == 0 ||
+ pf_match_port(psk->psk_dst.port_op,
+ psk->psk_dst.port[0], psk->psk_dst.port[1],
+ dstport)) &&
+ (!psk->psk_label[0] || (s->rule.ptr->label[0] &&
+ !strcmp(psk->psk_label, s->rule.ptr->label))) &&
+ (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
+ s->kif->pfik_name))) {
+ pf_unlink_state(s);
+ killed++;
+ }
+ }
+ psk->psk_killed = killed;
+ break;
+ }
+
+ case DIOCADDSTATE: {
+ struct pfioc_state *ps = (struct pfioc_state *)addr;
+ struct pfsync_state *sp = &ps->state;
+
+ if (sp->timeout >= PFTM_MAX &&
+ sp->timeout != PFTM_UNTIL_PACKET) {
+ error = EINVAL;
+ break;
+ }
+#ifdef __FreeBSD__
+ if (pfsync_state_import_ptr != NULL)
+ error = pfsync_state_import_ptr(sp, PFSYNC_SI_IOCTL);
+#else
+ error = pfsync_state_import(sp, PFSYNC_SI_IOCTL);
+#endif
+ break;
+ }
+
+ case DIOCGETSTATE: {
+ struct pfioc_state *ps = (struct pfioc_state *)addr;
+ struct pf_state *s;
+ struct pf_state_cmp id_key;
+
+ bcopy(ps->state.id, &id_key.id, sizeof(id_key.id));
+ id_key.creatorid = ps->state.creatorid;
+
+ s = pf_find_state_byid(&id_key);
+ if (s == NULL) {
+ error = ENOENT;
+ break;
+ }
+
+ pfsync_state_export(&ps->state, s);
+ break;
+ }
+
+ case DIOCGETSTATES: {
+ struct pfioc_states *ps = (struct pfioc_states *)addr;
+ struct pf_state *state;
+ struct pfsync_state *p, *pstore;
+ u_int32_t nr = 0;
+
+ if (ps->ps_len == 0) {
+#ifdef __FreeBSD__
+ nr = V_pf_status.states;
+#else
+ nr = pf_status.states;
+#endif
+ ps->ps_len = sizeof(struct pfsync_state) * nr;
+ break;
+ }
+
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ pstore = malloc(sizeof(*pstore), M_TEMP, M_WAITOK);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+
+ p = ps->ps_states;
+
+#ifdef __FreeBSD__
+ state = TAILQ_FIRST(&V_state_list);
+#else
+ state = TAILQ_FIRST(&state_list);
+#endif
+ while (state) {
+ if (state->timeout != PFTM_UNLINKED) {
+ if ((nr+1) * sizeof(*p) > (unsigned)ps->ps_len)
+ break;
+ pfsync_state_export(pstore, state);
+#ifdef __FreeBSD__
+ PF_COPYOUT(pstore, p, sizeof(*p), error);
+#else
+ error = copyout(pstore, p, sizeof(*p));
+#endif
+ if (error) {
+ free(pstore, M_TEMP);
+ goto fail;
+ }
+ p++;
+ nr++;
+ }
+ state = TAILQ_NEXT(state, entry_list);
+ }
+
+ ps->ps_len = sizeof(struct pfsync_state) * nr;
+
+ free(pstore, M_TEMP);
+ break;
+ }
+
+ case DIOCGETSTATUS: {
+ struct pf_status *s = (struct pf_status *)addr;
+#ifdef __FreeBSD__
+ bcopy(&V_pf_status, s, sizeof(struct pf_status));
+#else
+ bcopy(&pf_status, s, sizeof(struct pf_status));
+#endif
+ pfi_update_status(s->ifname, s);
+ break;
+ }
+
+ case DIOCSETSTATUSIF: {
+ struct pfioc_if *pi = (struct pfioc_if *)addr;
+
+ if (pi->ifname[0] == 0) {
+#ifdef __FreeBSD__
+ bzero(V_pf_status.ifname, IFNAMSIZ);
+#else
+ bzero(pf_status.ifname, IFNAMSIZ);
+#endif
+ break;
+ }
+#ifdef __FreeBSD__
+ strlcpy(V_pf_status.ifname, pi->ifname, IFNAMSIZ);
+#else
+ strlcpy(pf_status.ifname, pi->ifname, IFNAMSIZ);
+#endif
+ break;
+ }
+
+ case DIOCCLRSTATUS: {
+#ifdef __FreeBSD__
+ bzero(V_pf_status.counters, sizeof(V_pf_status.counters));
+ bzero(V_pf_status.fcounters, sizeof(V_pf_status.fcounters));
+ bzero(V_pf_status.scounters, sizeof(V_pf_status.scounters));
+ V_pf_status.since = time_second;
+ if (*V_pf_status.ifname)
+ pfi_update_status(V_pf_status.ifname, NULL);
+#else
+ bzero(pf_status.counters, sizeof(pf_status.counters));
+ bzero(pf_status.fcounters, sizeof(pf_status.fcounters));
+ bzero(pf_status.scounters, sizeof(pf_status.scounters));
+ pf_status.since = time_second;
+ if (*pf_status.ifname)
+ pfi_update_status(pf_status.ifname, NULL);
+#endif
+ break;
+ }
+
+ case DIOCNATLOOK: {
+ struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr;
+ struct pf_state_key *sk;
+ struct pf_state *state;
+ struct pf_state_key_cmp key;
+ int m = 0, direction = pnl->direction;
+ int sidx, didx;
+
+ /* NATLOOK src and dst are reversed, so reverse sidx/didx */
+ sidx = (direction == PF_IN) ? 1 : 0;
+ didx = (direction == PF_IN) ? 0 : 1;
+
+ if (!pnl->proto ||
+ PF_AZERO(&pnl->saddr, pnl->af) ||
+ PF_AZERO(&pnl->daddr, pnl->af) ||
+ ((pnl->proto == IPPROTO_TCP ||
+ pnl->proto == IPPROTO_UDP) &&
+ (!pnl->dport || !pnl->sport)))
+ error = EINVAL;
+ else {
+ key.af = pnl->af;
+ key.proto = pnl->proto;
+ PF_ACPY(&key.addr[sidx], &pnl->saddr, pnl->af);
+ key.port[sidx] = pnl->sport;
+ PF_ACPY(&key.addr[didx], &pnl->daddr, pnl->af);
+ key.port[didx] = pnl->dport;
+
+ state = pf_find_state_all(&key, direction, &m);
+
+ if (m > 1)
+ error = E2BIG; /* more than one state */
+ else if (state != NULL) {
+ sk = state->key[sidx];
+ PF_ACPY(&pnl->rsaddr, &sk->addr[sidx], sk->af);
+ pnl->rsport = sk->port[sidx];
+ PF_ACPY(&pnl->rdaddr, &sk->addr[didx], sk->af);
+ pnl->rdport = sk->port[didx];
+ } else
+ error = ENOENT;
+ }
+ break;
+ }
+
+ case DIOCSETTIMEOUT: {
+ struct pfioc_tm *pt = (struct pfioc_tm *)addr;
+ int old;
+
+ if (pt->timeout < 0 || pt->timeout >= PFTM_MAX ||
+ pt->seconds < 0) {
+ error = EINVAL;
+ goto fail;
+ }
+#ifdef __FreeBSD__
+ old = V_pf_default_rule.timeout[pt->timeout];
+#else
+ old = pf_default_rule.timeout[pt->timeout];
+#endif
+ if (pt->timeout == PFTM_INTERVAL && pt->seconds == 0)
+ pt->seconds = 1;
+#ifdef __FreeBSD__
+ V_pf_default_rule.timeout[pt->timeout] = pt->seconds;
+#else
+ pf_default_rule.timeout[pt->timeout] = pt->seconds;
+#endif
+ if (pt->timeout == PFTM_INTERVAL && pt->seconds < old)
+ wakeup(pf_purge_thread);
+ pt->seconds = old;
+ break;
+ }
+
+ case DIOCGETTIMEOUT: {
+ struct pfioc_tm *pt = (struct pfioc_tm *)addr;
+
+ if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) {
+ error = EINVAL;
+ goto fail;
+ }
+#ifdef __FreeBSD__
+ pt->seconds = V_pf_default_rule.timeout[pt->timeout];
+#else
+ pt->seconds = pf_default_rule.timeout[pt->timeout];
+#endif
+ break;
+ }
+
+ case DIOCGETLIMIT: {
+ struct pfioc_limit *pl = (struct pfioc_limit *)addr;
+
+ if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) {
+ error = EINVAL;
+ goto fail;
+ }
+#ifdef __FreeBSD__
+ pl->limit = V_pf_pool_limits[pl->index].limit;
+#else
+ pl->limit = pf_pool_limits[pl->index].limit;
+#endif
+ break;
+ }
+
+ case DIOCSETLIMIT: {
+ struct pfioc_limit *pl = (struct pfioc_limit *)addr;
+ int old_limit;
+
+ if (pl->index < 0 || pl->index >= PF_LIMIT_MAX ||
+#ifdef __FreeBSD__
+ V_pf_pool_limits[pl->index].pp == NULL) {
+#else
+ pf_pool_limits[pl->index].pp == NULL) {
+#endif
+ error = EINVAL;
+ goto fail;
+ }
+#ifdef __FreeBSD__
+ uma_zone_set_max(V_pf_pool_limits[pl->index].pp, pl->limit);
+ old_limit = V_pf_pool_limits[pl->index].limit;
+ V_pf_pool_limits[pl->index].limit = pl->limit;
+ pl->limit = old_limit;
+#else
+ if (pool_sethardlimit(pf_pool_limits[pl->index].pp,
+ pl->limit, NULL, 0) != 0) {
+ error = EBUSY;
+ goto fail;
+ }
+ old_limit = pf_pool_limits[pl->index].limit;
+ pf_pool_limits[pl->index].limit = pl->limit;
+ pl->limit = old_limit;
+#endif
+ break;
+ }
+
+ case DIOCSETDEBUG: {
+ u_int32_t *level = (u_int32_t *)addr;
+
+#ifdef __FreeBSD__
+ V_pf_status.debug = *level;
+#else
+ pf_status.debug = *level;
+#endif
+ break;
+ }
+
+ case DIOCCLRRULECTRS: {
+ /* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */
+ struct pf_ruleset *ruleset = &pf_main_ruleset;
+ struct pf_rule *rule;
+
+ TAILQ_FOREACH(rule,
+ ruleset->rules[PF_RULESET_FILTER].active.ptr, entries) {
+ rule->evaluations = 0;
+ rule->packets[0] = rule->packets[1] = 0;
+ rule->bytes[0] = rule->bytes[1] = 0;
+ }
+ break;
+ }
+
+#ifdef __FreeBSD__
+ case DIOCGIFSPEED: {
+ struct pf_ifspeed *psp = (struct pf_ifspeed *)addr;
+ struct pf_ifspeed ps;
+ struct ifnet *ifp;
+
+ if (psp->ifname[0] != 0) {
+ /* Can we completely trust user-land? */
+ strlcpy(ps.ifname, psp->ifname, IFNAMSIZ);
+ ifp = ifunit(ps.ifname);
+ if (ifp != NULL)
+ psp->baudrate = ifp->if_baudrate;
+ else
+ error = EINVAL;
+ } else
+ error = EINVAL;
+ break;
+ }
+#endif /* __FreeBSD__ */
+
+#ifdef ALTQ
+ case DIOCSTARTALTQ: {
+ struct pf_altq *altq;
+
+ /* enable all altq interfaces on active list */
+#ifdef __FreeBSD__
+ TAILQ_FOREACH(altq, V_pf_altqs_active, entries) {
+ if (altq->qname[0] == 0 && (altq->local_flags &
+ PFALTQ_FLAG_IF_REMOVED) == 0) {
+#else
+ TAILQ_FOREACH(altq, pf_altqs_active, entries) {
+ if (altq->qname[0] == 0) {
+#endif
+ error = pf_enable_altq(altq);
+ if (error != 0)
+ break;
+ }
+ }
+ if (error == 0)
+#ifdef __FreeBSD__
+ V_pf_altq_running = 1;
+#else
+ pf_altq_running = 1;
+#endif
+ DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"));
+ break;
+ }
+
+ case DIOCSTOPALTQ: {
+ struct pf_altq *altq;
+
+ /* disable all altq interfaces on active list */
+#ifdef __FreeBSD__
+ TAILQ_FOREACH(altq, V_pf_altqs_active, entries) {
+ if (altq->qname[0] == 0 && (altq->local_flags &
+ PFALTQ_FLAG_IF_REMOVED) == 0) {
+#else
+ TAILQ_FOREACH(altq, pf_altqs_active, entries) {
+ if (altq->qname[0] == 0) {
+#endif
+ error = pf_disable_altq(altq);
+ if (error != 0)
+ break;
+ }
+ }
+ if (error == 0)
+#ifdef __FreeBSD__
+ V_pf_altq_running = 0;
+#else
+ pf_altq_running = 0;
+#endif
+ DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"));
+ break;
+ }
+
+ case DIOCADDALTQ: {
+ struct pfioc_altq *pa = (struct pfioc_altq *)addr;
+ struct pf_altq *altq, *a;
+
+#ifdef __FreeBSD__
+ if (pa->ticket != V_ticket_altqs_inactive) {
+#else
+ if (pa->ticket != ticket_altqs_inactive) {
+#endif
+ error = EBUSY;
+ break;
+ }
+#ifdef __FreeBSD__
+ altq = pool_get(&V_pf_altq_pl, PR_NOWAIT);
+#else
+ altq = pool_get(&pf_altq_pl, PR_WAITOK|PR_LIMITFAIL);
+#endif
+ if (altq == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ bcopy(&pa->altq, altq, sizeof(struct pf_altq));
+#ifdef __FreeBSD__
+ altq->local_flags = 0;
+#endif
+
+ /*
+ * if this is for a queue, find the discipline and
+ * copy the necessary fields
+ */
+ if (altq->qname[0] != 0) {
+ if ((altq->qid = pf_qname2qid(altq->qname)) == 0) {
+ error = EBUSY;
+#ifdef __FreeBSD__
+ pool_put(&V_pf_altq_pl, altq);
+#else
+ pool_put(&pf_altq_pl, altq);
+#endif
+ break;
+ }
+ altq->altq_disc = NULL;
+#ifdef __FreeBSD__
+ TAILQ_FOREACH(a, V_pf_altqs_inactive, entries) {
+#else
+ TAILQ_FOREACH(a, pf_altqs_inactive, entries) {
+#endif
+ if (strncmp(a->ifname, altq->ifname,
+ IFNAMSIZ) == 0 && a->qname[0] == 0) {
+ altq->altq_disc = a->altq_disc;
+ break;
+ }
+ }
+ }
+
+#ifdef __FreeBSD__
+ struct ifnet *ifp;
+
+ if ((ifp = ifunit(altq->ifname)) == NULL) {
+ altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
+ } else {
+ PF_UNLOCK();
+#endif
+ error = altq_add(altq);
+#ifdef __FreeBSD__
+ PF_LOCK();
+ }
+#endif
+ if (error) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_altq_pl, altq);
+#else
+ pool_put(&pf_altq_pl, altq);
+#endif
+ break;
+ }
+
+#ifdef __FreeBSD__
+ TAILQ_INSERT_TAIL(V_pf_altqs_inactive, altq, entries);
+#else
+ TAILQ_INSERT_TAIL(pf_altqs_inactive, altq, entries);
+#endif
+ bcopy(altq, &pa->altq, sizeof(struct pf_altq));
+ break;
+ }
+
+ case DIOCGETALTQS: {
+ struct pfioc_altq *pa = (struct pfioc_altq *)addr;
+ struct pf_altq *altq;
+
+ pa->nr = 0;
+#ifdef __FreeBSD__
+ TAILQ_FOREACH(altq, V_pf_altqs_active, entries)
+ pa->nr++;
+ pa->ticket = V_ticket_altqs_active;
+#else
+ TAILQ_FOREACH(altq, pf_altqs_active, entries)
+ pa->nr++;
+ pa->ticket = ticket_altqs_active;
+#endif
+ break;
+ }
+
+ case DIOCGETALTQ: {
+ struct pfioc_altq *pa = (struct pfioc_altq *)addr;
+ struct pf_altq *altq;
+ u_int32_t nr;
+
+#ifdef __FreeBSD__
+ if (pa->ticket != V_ticket_altqs_active) {
+#else
+ if (pa->ticket != ticket_altqs_active) {
+#endif
+ error = EBUSY;
+ break;
+ }
+ nr = 0;
+#ifdef __FreeBSD__
+ altq = TAILQ_FIRST(V_pf_altqs_active);
+#else
+ altq = TAILQ_FIRST(pf_altqs_active);
+#endif
+ while ((altq != NULL) && (nr < pa->nr)) {
+ altq = TAILQ_NEXT(altq, entries);
+ nr++;
+ }
+ if (altq == NULL) {
+ error = EBUSY;
+ break;
+ }
+ bcopy(altq, &pa->altq, sizeof(struct pf_altq));
+ break;
+ }
+
+ case DIOCCHANGEALTQ:
+ /* CHANGEALTQ not supported yet! */
+ error = ENODEV;
+ break;
+
+ case DIOCGETQSTATS: {
+ struct pfioc_qstats *pq = (struct pfioc_qstats *)addr;
+ struct pf_altq *altq;
+ u_int32_t nr;
+ int nbytes;
+
+#ifdef __FreeBSD__
+ if (pq->ticket != V_ticket_altqs_active) {
+#else
+ if (pq->ticket != ticket_altqs_active) {
+#endif
+ error = EBUSY;
+ break;
+ }
+ nbytes = pq->nbytes;
+ nr = 0;
+#ifdef __FreeBSD__
+ altq = TAILQ_FIRST(V_pf_altqs_active);
+#else
+ altq = TAILQ_FIRST(pf_altqs_active);
+#endif
+ while ((altq != NULL) && (nr < pq->nr)) {
+ altq = TAILQ_NEXT(altq, entries);
+ nr++;
+ }
+ if (altq == NULL) {
+ error = EBUSY;
+ break;
+ }
+
+#ifdef __FreeBSD__
+ if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) != 0) {
+ error = ENXIO;
+ break;
+ }
+ PF_UNLOCK();
+#endif
+ error = altq_getqstats(altq, pq->buf, &nbytes);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ if (error == 0) {
+ pq->scheduler = altq->scheduler;
+ pq->nbytes = nbytes;
+ }
+ break;
+ }
+#endif /* ALTQ */
+
+ case DIOCBEGINADDRS: {
+ struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
+
+#ifdef __FreeBSD__
+ pf_empty_pool(&V_pf_pabuf);
+ pp->ticket = ++V_ticket_pabuf;
+#else
+ pf_empty_pool(&pf_pabuf);
+ pp->ticket = ++ticket_pabuf;
+#endif
+ break;
+ }
+
+ case DIOCADDADDR: {
+ struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
+
+#ifdef __FreeBSD__
+ if (pp->ticket != V_ticket_pabuf) {
+#else
+ if (pp->ticket != ticket_pabuf) {
+#endif
+ error = EBUSY;
+ break;
+ }
+#ifndef INET
+ if (pp->af == AF_INET) {
+ error = EAFNOSUPPORT;
+ break;
+ }
+#endif /* INET */
+#ifndef INET6
+ if (pp->af == AF_INET6) {
+ error = EAFNOSUPPORT;
+ break;
+ }
+#endif /* INET6 */
+ if (pp->addr.addr.type != PF_ADDR_ADDRMASK &&
+ pp->addr.addr.type != PF_ADDR_DYNIFTL &&
+ pp->addr.addr.type != PF_ADDR_TABLE) {
+ error = EINVAL;
+ break;
+ }
+#ifdef __FreeBSD__
+ pa = pool_get(&V_pf_pooladdr_pl, PR_NOWAIT);
+#else
+ pa = pool_get(&pf_pooladdr_pl, PR_WAITOK|PR_LIMITFAIL);
+#endif
+ if (pa == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ bcopy(&pp->addr, pa, sizeof(struct pf_pooladdr));
+ if (pa->ifname[0]) {
+ pa->kif = pfi_kif_get(pa->ifname);
+ if (pa->kif == NULL) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_pooladdr_pl, pa);
+#else
+ pool_put(&pf_pooladdr_pl, pa);
+#endif
+ error = EINVAL;
+ break;
+ }
+ pfi_kif_ref(pa->kif, PFI_KIF_REF_RULE);
+ }
+ if (pfi_dynaddr_setup(&pa->addr, pp->af)) {
+ pfi_dynaddr_remove(&pa->addr);
+ pfi_kif_unref(pa->kif, PFI_KIF_REF_RULE);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_pooladdr_pl, pa);
+#else
+ pool_put(&pf_pooladdr_pl, pa);
+#endif
+ error = EINVAL;
+ break;
+ }
+#ifdef __FreeBSD__
+ TAILQ_INSERT_TAIL(&V_pf_pabuf, pa, entries);
+#else
+ TAILQ_INSERT_TAIL(&pf_pabuf, pa, entries);
+#endif
+ break;
+ }
+
+ case DIOCGETADDRS: {
+ struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
+
+ pp->nr = 0;
+ pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action,
+ pp->r_num, 0, 1, 0);
+ if (pool == NULL) {
+ error = EBUSY;
+ break;
+ }
+ TAILQ_FOREACH(pa, &pool->list, entries)
+ pp->nr++;
+ break;
+ }
+
+ case DIOCGETADDR: {
+ struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
+ u_int32_t nr = 0;
+
+ pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action,
+ pp->r_num, 0, 1, 1);
+ if (pool == NULL) {
+ error = EBUSY;
+ break;
+ }
+ pa = TAILQ_FIRST(&pool->list);
+ while ((pa != NULL) && (nr < pp->nr)) {
+ pa = TAILQ_NEXT(pa, entries);
+ nr++;
+ }
+ if (pa == NULL) {
+ error = EBUSY;
+ break;
+ }
+ bcopy(pa, &pp->addr, sizeof(struct pf_pooladdr));
+ pf_addr_copyout(&pp->addr.addr);
+ break;
+ }
+
+ case DIOCCHANGEADDR: {
+ struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr;
+ struct pf_pooladdr *oldpa = NULL, *newpa = NULL;
+ struct pf_ruleset *ruleset;
+
+ if (pca->action < PF_CHANGE_ADD_HEAD ||
+ pca->action > PF_CHANGE_REMOVE) {
+ error = EINVAL;
+ break;
+ }
+ if (pca->addr.addr.type != PF_ADDR_ADDRMASK &&
+ pca->addr.addr.type != PF_ADDR_DYNIFTL &&
+ pca->addr.addr.type != PF_ADDR_TABLE) {
+ error = EINVAL;
+ break;
+ }
+
+ ruleset = pf_find_ruleset(pca->anchor);
+ if (ruleset == NULL) {
+ error = EBUSY;
+ break;
+ }
+ pool = pf_get_pool(pca->anchor, pca->ticket, pca->r_action,
+ pca->r_num, pca->r_last, 1, 1);
+ if (pool == NULL) {
+ error = EBUSY;
+ break;
+ }
+ if (pca->action != PF_CHANGE_REMOVE) {
+#ifdef __FreeBSD__
+ newpa = pool_get(&V_pf_pooladdr_pl,
+ PR_NOWAIT);
+#else
+ newpa = pool_get(&pf_pooladdr_pl,
+ PR_WAITOK|PR_LIMITFAIL);
+#endif
+ if (newpa == NULL) {
+ error = ENOMEM;
+ break;
+ }
+ bcopy(&pca->addr, newpa, sizeof(struct pf_pooladdr));
+#ifndef INET
+ if (pca->af == AF_INET) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_pooladdr_pl, newpa);
+#else
+ pool_put(&pf_pooladdr_pl, newpa);
+#endif
+ error = EAFNOSUPPORT;
+ break;
+ }
+#endif /* INET */
+#ifndef INET6
+ if (pca->af == AF_INET6) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_pooladdr_pl, newpa);
+#else
+ pool_put(&pf_pooladdr_pl, newpa);
+#endif
+ error = EAFNOSUPPORT;
+ break;
+ }
+#endif /* INET6 */
+ if (newpa->ifname[0]) {
+ newpa->kif = pfi_kif_get(newpa->ifname);
+ if (newpa->kif == NULL) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_pooladdr_pl, newpa);
+#else
+ pool_put(&pf_pooladdr_pl, newpa);
+#endif
+ error = EINVAL;
+ break;
+ }
+ pfi_kif_ref(newpa->kif, PFI_KIF_REF_RULE);
+ } else
+ newpa->kif = NULL;
+ if (pfi_dynaddr_setup(&newpa->addr, pca->af) ||
+ pf_tbladdr_setup(ruleset, &newpa->addr)) {
+ pfi_dynaddr_remove(&newpa->addr);
+ pfi_kif_unref(newpa->kif, PFI_KIF_REF_RULE);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_pooladdr_pl, newpa);
+#else
+ pool_put(&pf_pooladdr_pl, newpa);
+#endif
+ error = EINVAL;
+ break;
+ }
+ }
+
+ if (pca->action == PF_CHANGE_ADD_HEAD)
+ oldpa = TAILQ_FIRST(&pool->list);
+ else if (pca->action == PF_CHANGE_ADD_TAIL)
+ oldpa = TAILQ_LAST(&pool->list, pf_palist);
+ else {
+ int i = 0;
+
+ oldpa = TAILQ_FIRST(&pool->list);
+ while ((oldpa != NULL) && (i < pca->nr)) {
+ oldpa = TAILQ_NEXT(oldpa, entries);
+ i++;
+ }
+ if (oldpa == NULL) {
+ error = EINVAL;
+ break;
+ }
+ }
+
+ if (pca->action == PF_CHANGE_REMOVE) {
+ TAILQ_REMOVE(&pool->list, oldpa, entries);
+ pfi_dynaddr_remove(&oldpa->addr);
+ pf_tbladdr_remove(&oldpa->addr);
+ pfi_kif_unref(oldpa->kif, PFI_KIF_REF_RULE);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_pooladdr_pl, oldpa);
+#else
+ pool_put(&pf_pooladdr_pl, oldpa);
+#endif
+ } else {
+ if (oldpa == NULL)
+ TAILQ_INSERT_TAIL(&pool->list, newpa, entries);
+ else if (pca->action == PF_CHANGE_ADD_HEAD ||
+ pca->action == PF_CHANGE_ADD_BEFORE)
+ TAILQ_INSERT_BEFORE(oldpa, newpa, entries);
+ else
+ TAILQ_INSERT_AFTER(&pool->list, oldpa,
+ newpa, entries);
+ }
+
+ pool->cur = TAILQ_FIRST(&pool->list);
+ PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr,
+ pca->af);
+ break;
+ }
+
+ case DIOCGETRULESETS: {
+ struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
+ struct pf_ruleset *ruleset;
+ struct pf_anchor *anchor;
+
+ pr->path[sizeof(pr->path) - 1] = 0;
+ if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
+ error = EINVAL;
+ break;
+ }
+ pr->nr = 0;
+ if (ruleset->anchor == NULL) {
+ /* XXX kludge for pf_main_ruleset */
+#ifdef __FreeBSD__
+ RB_FOREACH(anchor, pf_anchor_global, &V_pf_anchors)
+#else
+ RB_FOREACH(anchor, pf_anchor_global, &pf_anchors)
+#endif
+ if (anchor->parent == NULL)
+ pr->nr++;
+ } else {
+ RB_FOREACH(anchor, pf_anchor_node,
+ &ruleset->anchor->children)
+ pr->nr++;
+ }
+ break;
+ }
+
+ case DIOCGETRULESET: {
+ struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
+ struct pf_ruleset *ruleset;
+ struct pf_anchor *anchor;
+ u_int32_t nr = 0;
+
+ pr->path[sizeof(pr->path) - 1] = 0;
+ if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
+ error = EINVAL;
+ break;
+ }
+ pr->name[0] = 0;
+ if (ruleset->anchor == NULL) {
+ /* XXX kludge for pf_main_ruleset */
+#ifdef __FreeBSD__
+ RB_FOREACH(anchor, pf_anchor_global, &V_pf_anchors)
+#else
+ RB_FOREACH(anchor, pf_anchor_global, &pf_anchors)
+#endif
+ if (anchor->parent == NULL && nr++ == pr->nr) {
+ strlcpy(pr->name, anchor->name,
+ sizeof(pr->name));
+ break;
+ }
+ } else {
+ RB_FOREACH(anchor, pf_anchor_node,
+ &ruleset->anchor->children)
+ if (nr++ == pr->nr) {
+ strlcpy(pr->name, anchor->name,
+ sizeof(pr->name));
+ break;
+ }
+ }
+ if (!pr->name[0])
+ error = EBUSY;
+ break;
+ }
+
+ case DIOCRCLRTABLES: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != 0) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel,
+ io->pfrio_flags | PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRADDTABLES: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_table)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_add_tables(io->pfrio_buffer, io->pfrio_size,
+ &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRDELTABLES: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_table)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_del_tables(io->pfrio_buffer, io->pfrio_size,
+ &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRGETTABLES: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_table)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_get_tables(&io->pfrio_table, io->pfrio_buffer,
+ &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRGETTSTATS: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_tstats)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_get_tstats(&io->pfrio_table, io->pfrio_buffer,
+ &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRCLRTSTATS: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_table)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_clr_tstats(io->pfrio_buffer, io->pfrio_size,
+ &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRSETTFLAGS: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_table)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_set_tflags(io->pfrio_buffer, io->pfrio_size,
+ io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
+ &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRCLRADDRS: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != 0) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel,
+ io->pfrio_flags | PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRADDADDRS: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_addr)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_add_addrs(&io->pfrio_table, io->pfrio_buffer,
+ io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags |
+ PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRDELADDRS: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_addr)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_del_addrs(&io->pfrio_table, io->pfrio_buffer,
+ io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags |
+ PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRSETADDRS: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_addr)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_set_addrs(&io->pfrio_table, io->pfrio_buffer,
+ io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd,
+ &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags |
+ PFR_FLAG_USERIOCTL, 0);
+ break;
+ }
+
+ case DIOCRGETADDRS: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_addr)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_get_addrs(&io->pfrio_table, io->pfrio_buffer,
+ &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRGETASTATS: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_astats)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_get_astats(&io->pfrio_table, io->pfrio_buffer,
+ &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRCLRASTATS: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_addr)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_clr_astats(&io->pfrio_table, io->pfrio_buffer,
+ io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags |
+ PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRTSTADDRS: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_addr)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_tst_addrs(&io->pfrio_table, io->pfrio_buffer,
+ io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
+ PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCRINADEFINE: {
+ struct pfioc_table *io = (struct pfioc_table *)addr;
+
+ if (io->pfrio_esize != sizeof(struct pfr_addr)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfr_ina_define(&io->pfrio_table, io->pfrio_buffer,
+ io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
+ io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
+ break;
+ }
+
+ case DIOCOSFPADD: {
+ struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
+ error = pf_osfp_add(io);
+ break;
+ }
+
+ case DIOCOSFPGET: {
+ struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
+ error = pf_osfp_get(io);
+ break;
+ }
+
+ case DIOCXBEGIN: {
+ struct pfioc_trans *io = (struct pfioc_trans *)addr;
+ struct pfioc_trans_e *ioe;
+ struct pfr_table *table;
+ int i;
+
+ if (io->esize != sizeof(*ioe)) {
+ error = ENODEV;
+ goto fail;
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
+ table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ for (i = 0; i < io->size; i++) {
+#ifdef __FreeBSD__
+ PF_COPYIN(io->array+i, ioe, sizeof(*ioe), error);
+ if (error) {
+#else
+ if (copyin(io->array+i, ioe, sizeof(*ioe))) {
+#endif
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EFAULT;
+ goto fail;
+ }
+ switch (ioe->rs_num) {
+#ifdef ALTQ
+ case PF_RULESET_ALTQ:
+ if (ioe->anchor[0]) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EINVAL;
+ goto fail;
+ }
+ if ((error = pf_begin_altq(&ioe->ticket))) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ goto fail;
+ }
+ break;
+#endif /* ALTQ */
+ case PF_RULESET_TABLE:
+ bzero(table, sizeof(*table));
+ strlcpy(table->pfrt_anchor, ioe->anchor,
+ sizeof(table->pfrt_anchor));
+ if ((error = pfr_ina_begin(table,
+ &ioe->ticket, NULL, 0))) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ goto fail;
+ }
+ break;
+ default:
+ if ((error = pf_begin_rules(&ioe->ticket,
+ ioe->rs_num, ioe->anchor))) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ goto fail;
+ }
+ break;
+ }
+#ifdef __FreeBSD__
+ PF_COPYOUT(ioe, io->array+i, sizeof(io->array[i]),
+ error);
+ if (error) {
+#else
+ if (copyout(ioe, io->array+i, sizeof(io->array[i]))) {
+#endif
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EFAULT;
+ goto fail;
+ }
+ }
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ break;
+ }
+
+ case DIOCXROLLBACK: {
+ struct pfioc_trans *io = (struct pfioc_trans *)addr;
+ struct pfioc_trans_e *ioe;
+ struct pfr_table *table;
+ int i;
+
+ if (io->esize != sizeof(*ioe)) {
+ error = ENODEV;
+ goto fail;
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
+ table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ for (i = 0; i < io->size; i++) {
+#ifdef __FreeBSD__
+ PF_COPYIN(io->array+i, ioe, sizeof(*ioe), error);
+ if (error) {
+#else
+ if (copyin(io->array+i, ioe, sizeof(*ioe))) {
+#endif
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EFAULT;
+ goto fail;
+ }
+ switch (ioe->rs_num) {
+#ifdef ALTQ
+ case PF_RULESET_ALTQ:
+ if (ioe->anchor[0]) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EINVAL;
+ goto fail;
+ }
+ if ((error = pf_rollback_altq(ioe->ticket))) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ goto fail; /* really bad */
+ }
+ break;
+#endif /* ALTQ */
+ case PF_RULESET_TABLE:
+ bzero(table, sizeof(*table));
+ strlcpy(table->pfrt_anchor, ioe->anchor,
+ sizeof(table->pfrt_anchor));
+ if ((error = pfr_ina_rollback(table,
+ ioe->ticket, NULL, 0))) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ goto fail; /* really bad */
+ }
+ break;
+ default:
+ if ((error = pf_rollback_rules(ioe->ticket,
+ ioe->rs_num, ioe->anchor))) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ goto fail; /* really bad */
+ }
+ break;
+ }
+ }
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ break;
+ }
+
+ case DIOCXCOMMIT: {
+ struct pfioc_trans *io = (struct pfioc_trans *)addr;
+ struct pfioc_trans_e *ioe;
+ struct pfr_table *table;
+ struct pf_ruleset *rs;
+ int i;
+
+ if (io->esize != sizeof(*ioe)) {
+ error = ENODEV;
+ goto fail;
+ }
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
+ table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ /* first makes sure everything will succeed */
+ for (i = 0; i < io->size; i++) {
+#ifdef __FreeBSD__
+ PF_COPYIN(io->array+i, ioe, sizeof(*ioe), error);
+ if (error) {
+#else
+ if (copyin(io->array+i, ioe, sizeof(*ioe))) {
+#endif
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EFAULT;
+ goto fail;
+ }
+ switch (ioe->rs_num) {
+#ifdef ALTQ
+ case PF_RULESET_ALTQ:
+ if (ioe->anchor[0]) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EINVAL;
+ goto fail;
+ }
+#ifdef __FreeBSD__
+ if (!V_altqs_inactive_open || ioe->ticket !=
+ V_ticket_altqs_inactive) {
+#else
+ if (!altqs_inactive_open || ioe->ticket !=
+ ticket_altqs_inactive) {
+#endif
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EBUSY;
+ goto fail;
+ }
+ break;
+#endif /* ALTQ */
+ case PF_RULESET_TABLE:
+ rs = pf_find_ruleset(ioe->anchor);
+ if (rs == NULL || !rs->topen || ioe->ticket !=
+ rs->tticket) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EBUSY;
+ goto fail;
+ }
+ break;
+ default:
+ if (ioe->rs_num < 0 || ioe->rs_num >=
+ PF_RULESET_MAX) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EINVAL;
+ goto fail;
+ }
+ rs = pf_find_ruleset(ioe->anchor);
+ if (rs == NULL ||
+ !rs->rules[ioe->rs_num].inactive.open ||
+ rs->rules[ioe->rs_num].inactive.ticket !=
+ ioe->ticket) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EBUSY;
+ goto fail;
+ }
+ break;
+ }
+ }
+ /* now do the commit - no errors should happen here */
+ for (i = 0; i < io->size; i++) {
+#ifdef __FreeBSD__
+ PF_COPYIN(io->array+i, ioe, sizeof(*ioe), error);
+ if (error) {
+#else
+ if (copyin(io->array+i, ioe, sizeof(*ioe))) {
+#endif
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ error = EFAULT;
+ goto fail;
+ }
+ switch (ioe->rs_num) {
+#ifdef ALTQ
+ case PF_RULESET_ALTQ:
+ if ((error = pf_commit_altq(ioe->ticket))) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ goto fail; /* really bad */
+ }
+ break;
+#endif /* ALTQ */
+ case PF_RULESET_TABLE:
+ bzero(table, sizeof(*table));
+ strlcpy(table->pfrt_anchor, ioe->anchor,
+ sizeof(table->pfrt_anchor));
+ if ((error = pfr_ina_commit(table, ioe->ticket,
+ NULL, NULL, 0))) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ goto fail; /* really bad */
+ }
+ break;
+ default:
+ if ((error = pf_commit_rules(ioe->ticket,
+ ioe->rs_num, ioe->anchor))) {
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ goto fail; /* really bad */
+ }
+ break;
+ }
+ }
+ free(table, M_TEMP);
+ free(ioe, M_TEMP);
+ break;
+ }
+
+ case DIOCGETSRCNODES: {
+ struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr;
+ struct pf_src_node *n, *p, *pstore;
+ u_int32_t nr = 0;
+ int space = psn->psn_len;
+
+ if (space == 0) {
+#ifdef __FreeBSD__
+ RB_FOREACH(n, pf_src_tree, &V_tree_src_tracking)
+#else
+ RB_FOREACH(n, pf_src_tree, &tree_src_tracking)
+#endif
+ nr++;
+ psn->psn_len = sizeof(struct pf_src_node) * nr;
+ break;
+ }
+
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+#endif
+ pstore = malloc(sizeof(*pstore), M_TEMP, M_WAITOK);
+#ifdef __FreeBSD__
+ PF_LOCK();
+#endif
+ p = psn->psn_src_nodes;
+#ifdef __FreeBSD__
+ RB_FOREACH(n, pf_src_tree, &V_tree_src_tracking) {
+#else
+ RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
+#endif
+ int secs = time_second, diff;
+
+ if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
+ break;
+
+ bcopy(n, pstore, sizeof(*pstore));
+ if (n->rule.ptr != NULL)
+ pstore->rule.nr = n->rule.ptr->nr;
+ pstore->creation = secs - pstore->creation;
+ if (pstore->expire > secs)
+ pstore->expire -= secs;
+ else
+ pstore->expire = 0;
+
+ /* adjust the connection rate estimate */
+ diff = secs - n->conn_rate.last;
+ if (diff >= n->conn_rate.seconds)
+ pstore->conn_rate.count = 0;
+ else
+ pstore->conn_rate.count -=
+ n->conn_rate.count * diff /
+ n->conn_rate.seconds;
+
+#ifdef __FreeBSD__
+ PF_COPYOUT(pstore, p, sizeof(*p), error);
+#else
+ error = copyout(pstore, p, sizeof(*p));
+#endif
+ if (error) {
+ free(pstore, M_TEMP);
+ goto fail;
+ }
+ p++;
+ nr++;
+ }
+ psn->psn_len = sizeof(struct pf_src_node) * nr;
+
+ free(pstore, M_TEMP);
+ break;
+ }
+
+ case DIOCCLRSRCNODES: {
+ struct pf_src_node *n;
+ struct pf_state *state;
+
+#ifdef __FreeBSD__
+ RB_FOREACH(state, pf_state_tree_id, &V_tree_id) {
+#else
+ RB_FOREACH(state, pf_state_tree_id, &tree_id) {
+#endif
+ state->src_node = NULL;
+ state->nat_src_node = NULL;
+ }
+#ifdef __FreeBSD__
+ RB_FOREACH(n, pf_src_tree, &V_tree_src_tracking) {
+#else
+ RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
+#endif
+ n->expire = 1;
+ n->states = 0;
+ }
+ pf_purge_expired_src_nodes(1);
+#ifdef __FreeBSD__
+ V_pf_status.src_nodes = 0;
+#else
+ pf_status.src_nodes = 0;
+#endif
+ break;
+ }
+
+ case DIOCKILLSRCNODES: {
+ struct pf_src_node *sn;
+ struct pf_state *s;
+ struct pfioc_src_node_kill *psnk =
+ (struct pfioc_src_node_kill *)addr;
+ u_int killed = 0;
+
+#ifdef __FreeBSD__
+ RB_FOREACH(sn, pf_src_tree, &V_tree_src_tracking) {
+#else
+ RB_FOREACH(sn, pf_src_tree, &tree_src_tracking) {
+#endif
+ if (PF_MATCHA(psnk->psnk_src.neg,
+ &psnk->psnk_src.addr.v.a.addr,
+ &psnk->psnk_src.addr.v.a.mask,
+ &sn->addr, sn->af) &&
+ PF_MATCHA(psnk->psnk_dst.neg,
+ &psnk->psnk_dst.addr.v.a.addr,
+ &psnk->psnk_dst.addr.v.a.mask,
+ &sn->raddr, sn->af)) {
+ /* Handle state to src_node linkage */
+ if (sn->states != 0) {
+ RB_FOREACH(s, pf_state_tree_id,
+#ifdef __FreeBSD__
+ &V_tree_id) {
+#else
+ &tree_id) {
+#endif
+ if (s->src_node == sn)
+ s->src_node = NULL;
+ if (s->nat_src_node == sn)
+ s->nat_src_node = NULL;
+ }
+ sn->states = 0;
+ }
+ sn->expire = 1;
+ killed++;
+ }
+ }
+
+ if (killed > 0)
+ pf_purge_expired_src_nodes(1);
+
+ psnk->psnk_killed = killed;
+ break;
+ }
+
+ case DIOCSETHOSTID: {
+ u_int32_t *hostid = (u_int32_t *)addr;
+
+#ifdef __FreeBSD__
+ if (*hostid == 0)
+ V_pf_status.hostid = arc4random();
+ else
+ V_pf_status.hostid = *hostid;
+#else
+ if (*hostid == 0)
+ pf_status.hostid = arc4random();
+ else
+ pf_status.hostid = *hostid;
+#endif
+ break;
+ }
+
+ case DIOCOSFPFLUSH:
+ pf_osfp_flush();
+ break;
+
+ case DIOCIGETIFACES: {
+ struct pfioc_iface *io = (struct pfioc_iface *)addr;
+
+ if (io->pfiio_esize != sizeof(struct pfi_kif)) {
+ error = ENODEV;
+ break;
+ }
+ error = pfi_get_ifaces(io->pfiio_name, io->pfiio_buffer,
+ &io->pfiio_size);
+ break;
+ }
+
+ case DIOCSETIFFLAG: {
+ struct pfioc_iface *io = (struct pfioc_iface *)addr;
+
+ error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
+ break;
+ }
+
+ case DIOCCLRIFFLAG: {
+ struct pfioc_iface *io = (struct pfioc_iface *)addr;
+
+ error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
+ break;
+ }
+
+ default:
+ error = ENODEV;
+ break;
+ }
+fail:
+#ifdef __FreeBSD__
+ PF_UNLOCK();
+
+ if (flags & FWRITE)
+ sx_xunlock(&V_pf_consistency_lock);
+ else
+ sx_sunlock(&V_pf_consistency_lock);
+#else
+ splx(s);
+ if (flags & FWRITE)
+ rw_exit_write(&pf_consistency_lock);
+ else
+ rw_exit_read(&pf_consistency_lock);
+#endif
+
+ CURVNET_RESTORE();
+
+ return (error);
+}
+
+#ifdef __FreeBSD__
+void
+pfsync_state_export(struct pfsync_state *sp, struct pf_state *st)
+{
+ bzero(sp, sizeof(struct pfsync_state));
+
+ /* copy from state key */
+ sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
+ sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
+ sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
+ sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
+ sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
+ sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
+ sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
+ sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
+ sp->proto = st->key[PF_SK_WIRE]->proto;
+ sp->af = st->key[PF_SK_WIRE]->af;
+
+ /* copy from state */
+ strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
+ bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
+ sp->creation = htonl(time_second - st->creation);
+ sp->expire = pf_state_expires(st);
+ if (sp->expire <= time_second)
+ sp->expire = htonl(0);
+ else
+ sp->expire = htonl(sp->expire - time_second);
+
+ sp->direction = st->direction;
+ sp->log = st->log;
+ sp->timeout = st->timeout;
+ sp->state_flags = st->state_flags;
+ if (st->src_node)
+ sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
+ if (st->nat_src_node)
+ sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
+
+ bcopy(&st->id, &sp->id, sizeof(sp->id));
+ sp->creatorid = st->creatorid;
+ pf_state_peer_hton(&st->src, &sp->src);
+ pf_state_peer_hton(&st->dst, &sp->dst);
+
+ if (st->rule.ptr == NULL)
+ sp->rule = htonl(-1);
+ else
+ sp->rule = htonl(st->rule.ptr->nr);
+ if (st->anchor.ptr == NULL)
+ sp->anchor = htonl(-1);
+ else
+ sp->anchor = htonl(st->anchor.ptr->nr);
+ if (st->nat_rule.ptr == NULL)
+ sp->nat_rule = htonl(-1);
+ else
+ sp->nat_rule = htonl(st->nat_rule.ptr->nr);
+
+ pf_state_counter_hton(st->packets[0], sp->packets[0]);
+ pf_state_counter_hton(st->packets[1], sp->packets[1]);
+ pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
+ pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
+
+}
+
+/*
+ * XXX - Check for version missmatch!!!
+ */
+static void
+pf_clear_states(void)
+{
+ struct pf_state *state;
+
+#ifdef __FreeBSD__
+ RB_FOREACH(state, pf_state_tree_id, &V_tree_id) {
+#else
+ RB_FOREACH(state, pf_state_tree_id, &tree_id) {
+#endif
+ state->timeout = PFTM_PURGE;
+#if NPFSYNC
+ /* don't send out individual delete messages */
+ state->sync_state = PFSTATE_NOSYNC;
+#endif
+ pf_unlink_state(state);
+ }
+
+#if 0 /* NPFSYNC */
+/*
+ * XXX This is called on module unload, we do not want to sync that over? */
+ */
+ pfsync_clear_states(V_pf_status.hostid, psk->psk_ifname);
+#endif
+}
+
+static int
+pf_clear_tables(void)
+{
+ struct pfioc_table io;
+ int error;
+
+ bzero(&io, sizeof(io));
+
+ error = pfr_clr_tables(&io.pfrio_table, &io.pfrio_ndel,
+ io.pfrio_flags);
+
+ return (error);
+}
+
+static void
+pf_clear_srcnodes(void)
+{
+ struct pf_src_node *n;
+ struct pf_state *state;
+
+#ifdef __FreeBSD__
+ RB_FOREACH(state, pf_state_tree_id, &V_tree_id) {
+#else
+ RB_FOREACH(state, pf_state_tree_id, &tree_id) {
+#endif
+ state->src_node = NULL;
+ state->nat_src_node = NULL;
+ }
+#ifdef __FreeBSD__
+ RB_FOREACH(n, pf_src_tree, &V_tree_src_tracking) {
+#else
+ RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
+#endif
+ n->expire = 1;
+ n->states = 0;
+ }
+}
+/*
+ * XXX - Check for version missmatch!!!
+ */
+
+/*
+ * Duplicate pfctl -Fa operation to get rid of as much as we can.
+ */
+static int
+shutdown_pf(void)
+{
+ int error = 0;
+ u_int32_t t[5];
+ char nn = '\0';
+
+ V_pf_status.running = 0;
+ do {
+ if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn))
+ != 0) {
+ DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"));
+ break;
+ }
+ if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn))
+ != 0) {
+ DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"));
+ break; /* XXX: rollback? */
+ }
+ if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn))
+ != 0) {
+ DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"));
+ break; /* XXX: rollback? */
+ }
+ if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn))
+ != 0) {
+ DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"));
+ break; /* XXX: rollback? */
+ }
+ if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn))
+ != 0) {
+ DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"));
+ break; /* XXX: rollback? */
+ }
+
+ /* XXX: these should always succeed here */
+ pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn);
+ pf_commit_rules(t[1], PF_RULESET_FILTER, &nn);
+ pf_commit_rules(t[2], PF_RULESET_NAT, &nn);
+ pf_commit_rules(t[3], PF_RULESET_BINAT, &nn);
+ pf_commit_rules(t[4], PF_RULESET_RDR, &nn);
+
+ if ((error = pf_clear_tables()) != 0)
+ break;
+
+ #ifdef ALTQ
+ if ((error = pf_begin_altq(&t[0])) != 0) {
+ DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: ALTQ\n"));
+ break;
+ }
+ pf_commit_altq(t[0]);
+ #endif
+
+ pf_clear_states();
+
+ pf_clear_srcnodes();
+
+ /* status does not use malloced mem so no need to cleanup */
+ /* fingerprints and interfaces have thier own cleanup code */
+ } while(0);
+
+ return (error);
+}
+
+#ifdef INET
+static int
+pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
+ struct inpcb *inp)
+{
+ /*
+ * XXX Wed Jul 9 22:03:16 2003 UTC
+ * OpenBSD has changed its byte ordering convention on ip_len/ip_off
+ * in network stack. OpenBSD's network stack have converted
+ * ip_len/ip_off to host byte order frist as FreeBSD.
+ * Now this is not true anymore , so we should convert back to network
+ * byte order.
+ */
+ struct ip *h = NULL;
+ int chk;
+
+ if ((*m)->m_pkthdr.len >= (int)sizeof(struct ip)) {
+ /* if m_pkthdr.len is less than ip header, pf will handle. */
+ h = mtod(*m, struct ip *);
+ HTONS(h->ip_len);
+ HTONS(h->ip_off);
+ }
+ CURVNET_SET(ifp->if_vnet);
+ chk = pf_test(PF_IN, ifp, m, NULL, inp);
+ CURVNET_RESTORE();
+ if (chk && *m) {
+ m_freem(*m);
+ *m = NULL;
+ }
+ if (*m != NULL) {
+ /* pf_test can change ip header location */
+ h = mtod(*m, struct ip *);
+ NTOHS(h->ip_len);
+ NTOHS(h->ip_off);
+ }
+ return chk;
+}
+
+static int
+pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
+ struct inpcb *inp)
+{
+ /*
+ * XXX Wed Jul 9 22:03:16 2003 UTC
+ * OpenBSD has changed its byte ordering convention on ip_len/ip_off
+ * in network stack. OpenBSD's network stack have converted
+ * ip_len/ip_off to host byte order frist as FreeBSD.
+ * Now this is not true anymore , so we should convert back to network
+ * byte order.
+ */
+ struct ip *h = NULL;
+ int chk;
+
+ /* We need a proper CSUM befor we start (s. OpenBSD ip_output) */
+ if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ in_delayed_cksum(*m);
+ (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
+ }
+ if ((*m)->m_pkthdr.len >= (int)sizeof(*h)) {
+ /* if m_pkthdr.len is less than ip header, pf will handle. */
+ h = mtod(*m, struct ip *);
+ HTONS(h->ip_len);
+ HTONS(h->ip_off);
+ }
+ CURVNET_SET(ifp->if_vnet);
+ chk = pf_test(PF_OUT, ifp, m, NULL, inp);
+ CURVNET_RESTORE();
+ if (chk && *m) {
+ m_freem(*m);
+ *m = NULL;
+ }
+ if (*m != NULL) {
+ /* pf_test can change ip header location */
+ h = mtod(*m, struct ip *);
+ NTOHS(h->ip_len);
+ NTOHS(h->ip_off);
+ }
+ return chk;
+}
+#endif
+
+#ifdef INET6
+static int
+pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
+ struct inpcb *inp)
+{
+
+ /*
+ * IPv6 is not affected by ip_len/ip_off byte order changes.
+ */
+ int chk;
+
+ /*
+ * In case of loopback traffic IPv6 uses the real interface in
+ * order to support scoped addresses. In order to support stateful
+ * filtering we have change this to lo0 as it is the case in IPv4.
+ */
+ CURVNET_SET(ifp->if_vnet);
+ chk = pf_test6(PF_IN, (*m)->m_flags & M_LOOP ? V_loif : ifp, m,
+ NULL, inp);
+ CURVNET_RESTORE();
+ if (chk && *m) {
+ m_freem(*m);
+ *m = NULL;
+ }
+ return chk;
+}
+
+static int
+pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
+ struct inpcb *inp)
+{
+ /*
+ * IPv6 does not affected ip_len/ip_off byte order changes.
+ */
+ int chk;
+
+ /* We need a proper CSUM before we start (s. OpenBSD ip_output) */
+ if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+#ifdef INET
+ /* XXX-BZ copy&paste error from r126261? */
+ in_delayed_cksum(*m);
+#endif
+ (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
+ }
+ CURVNET_SET(ifp->if_vnet);
+ chk = pf_test6(PF_OUT, ifp, m, NULL, inp);
+ CURVNET_RESTORE();
+ if (chk && *m) {
+ m_freem(*m);
+ *m = NULL;
+ }
+ return chk;
+}
+#endif /* INET6 */
+
+static int
+hook_pf(void)
+{
+#ifdef INET
+ struct pfil_head *pfh_inet;
+#endif
+#ifdef INET6
+ struct pfil_head *pfh_inet6;
+#endif
+
+ PF_UNLOCK_ASSERT();
+
+ if (V_pf_pfil_hooked)
+ return (0);
+
+#ifdef INET
+ pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+ if (pfh_inet == NULL)
+ return (ESRCH); /* XXX */
+ pfil_add_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet);
+ pfil_add_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet);
+#endif
+#ifdef INET6
+ pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+ if (pfh_inet6 == NULL) {
+#ifdef INET
+ pfil_remove_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK,
+ pfh_inet);
+ pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
+ pfh_inet);
+#endif
+ return (ESRCH); /* XXX */
+ }
+ pfil_add_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
+ pfil_add_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
+#endif
+
+ V_pf_pfil_hooked = 1;
+ return (0);
+}
+
+static int
+dehook_pf(void)
+{
+#ifdef INET
+ struct pfil_head *pfh_inet;
+#endif
+#ifdef INET6
+ struct pfil_head *pfh_inet6;
+#endif
+
+ PF_UNLOCK_ASSERT();
+
+ if (V_pf_pfil_hooked == 0)
+ return (0);
+
+#ifdef INET
+ pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
+ if (pfh_inet == NULL)
+ return (ESRCH); /* XXX */
+ pfil_remove_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK,
+ pfh_inet);
+ pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
+ pfh_inet);
+#endif
+#ifdef INET6
+ pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
+ if (pfh_inet6 == NULL)
+ return (ESRCH); /* XXX */
+ pfil_remove_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK,
+ pfh_inet6);
+ pfil_remove_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK,
+ pfh_inet6);
+#endif
+
+ V_pf_pfil_hooked = 0;
+ return (0);
+}
+
+static int
+pf_load(void)
+{
+ VNET_ITERATOR_DECL(vnet_iter);
+
+ VNET_LIST_RLOCK();
+ VNET_FOREACH(vnet_iter) {
+ CURVNET_SET(vnet_iter);
+ V_pf_pfil_hooked = 0;
+ V_pf_end_threads = 0;
+ V_debug_pfugidhack = 0;
+ TAILQ_INIT(&V_pf_tags);
+ TAILQ_INIT(&V_pf_qids);
+ CURVNET_RESTORE();
+ }
+ VNET_LIST_RUNLOCK();
+
+ init_pf_mutex();
+ pf_dev = make_dev(&pf_cdevsw, 0, 0, 0, 0600, PF_NAME);
+ init_zone_var();
+ sx_init(&V_pf_consistency_lock, "pf_statetbl_lock");
+ if (pfattach() < 0)
+ return (ENOMEM);
+
+ return (0);
+}
+
+static int
+pf_unload(void)
+{
+ int error = 0;
+
+ PF_LOCK();
+ V_pf_status.running = 0;
+ PF_UNLOCK();
+ m_addr_chg_pf_p = NULL;
+ error = dehook_pf();
+ if (error) {
+ /*
+ * Should not happen!
+ * XXX Due to error code ESRCH, kldunload will show
+ * a message like 'No such process'.
+ */
+ printf("%s : pfil unregisteration fail\n", __FUNCTION__);
+ return error;
+ }
+ PF_LOCK();
+ shutdown_pf();
+ V_pf_end_threads = 1;
+ while (V_pf_end_threads < 2) {
+ wakeup_one(pf_purge_thread);
+ msleep(pf_purge_thread, &pf_task_mtx, 0, "pftmo", hz);
+ }
+ pfi_cleanup();
+ pf_osfp_flush();
+ pf_osfp_cleanup();
+ cleanup_pf_zone();
+ PF_UNLOCK();
+ destroy_dev(pf_dev);
+ destroy_pf_mutex();
+ sx_destroy(&V_pf_consistency_lock);
+ return error;
+}
+
+static int
+pf_modevent(module_t mod, int type, void *data)
+{
+ int error = 0;
+
+ switch(type) {
+ case MOD_LOAD:
+ error = pf_load();
+ break;
+ case MOD_QUIESCE:
+ /*
+ * Module should not be unloaded due to race conditions.
+ */
+ error = EPERM;
+ break;
+ case MOD_UNLOAD:
+ error = pf_unload();
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ return error;
+}
+
+static moduledata_t pf_mod = {
+ "pf",
+ pf_modevent,
+ 0
+};
+
+DECLARE_MODULE(pf, pf_mod, SI_SUB_PSEUDO, SI_ORDER_FIRST);
+MODULE_VERSION(pf, PF_MODVER);
+#endif /* __FreeBSD__ */
diff --git a/sys/contrib/pf/net/pf_lb.c b/sys/contrib/pf/net/pf_lb.c
new file mode 100644
index 0000000..4adc6f0
--- /dev/null
+++ b/sys/contrib/pf/net/pf_lb.c
@@ -0,0 +1,793 @@
+/* $OpenBSD: pf_lb.c,v 1.2 2009/02/12 02:13:15 sthen Exp $ */
+
+/*
+ * Copyright (c) 2001 Daniel Hartmeier
+ * Copyright (c) 2002 - 2008 Henning Brauer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Effort sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
+ *
+ */
+
+#ifdef __FreeBSD__
+#include "opt_inet.h"
+#include "opt_inet6.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#endif
+
+#ifdef __FreeBSD__
+#include "opt_bpf.h"
+#include "opt_pf.h"
+
+#ifdef DEV_BPF
+#define NBPFILTER DEV_BPF
+#else
+#define NBPFILTER 0
+#endif
+
+#ifdef DEV_PFLOG
+#define NPFLOG DEV_PFLOG
+#else
+#define NPFLOG 0
+#endif
+
+#ifdef DEV_PFSYNC
+#define NPFSYNC DEV_PFSYNC
+#else
+#define NPFSYNC 0
+#endif
+
+#ifdef DEV_PFLOW
+#define NPFLOW DEV_PFLOW
+#else
+#define NPFLOW 0
+#endif
+
+#else
+#include "bpfilter.h"
+#include "pflog.h"
+#include "pfsync.h"
+#include "pflow.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/filio.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/time.h>
+#ifdef __FreeBSD__
+#include <sys/sysctl.h>
+#endif
+#ifndef __FreeBSD__
+#include <sys/pool.h>
+#endif
+#include <sys/proc.h>
+#ifdef __FreeBSD__
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/sx.h>
+#else
+#include <sys/rwlock.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <sys/md5.h>
+#else
+#include <crypto/md5.h>
+#endif
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/bpf.h>
+#include <net/route.h>
+#include <net/radix_mpath.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/in_pcb.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+#include <netinet/icmp_var.h>
+#include <netinet/if_ether.h>
+
+#ifndef __FreeBSD__
+#include <dev/rndvar.h>
+#endif
+#include <net/pfvar.h>
+#include <net/if_pflog.h>
+#include <net/if_pflow.h>
+
+#if NPFSYNC > 0
+#include <net/if_pfsync.h>
+#endif /* NPFSYNC > 0 */
+
+#ifdef INET6
+#include <netinet/ip6.h>
+#include <netinet/in_pcb.h>
+#include <netinet/icmp6.h>
+#include <netinet6/nd6.h>
+#endif /* INET6 */
+
+
+#ifdef __FreeBSD__
+#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
+#else
+#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
+#endif
+
+/*
+ * Global variables
+ */
+
+void pf_hash(struct pf_addr *, struct pf_addr *,
+ struct pf_poolhashkey *, sa_family_t);
+struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
+ int, int, struct pfi_kif *,
+ struct pf_addr *, u_int16_t, struct pf_addr *,
+ u_int16_t, int);
+int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
+ struct pf_addr *, struct pf_addr *, u_int16_t,
+ struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
+ struct pf_src_node **);
+
+#define mix(a,b,c) \
+ do { \
+ a -= b; a -= c; a ^= (c >> 13); \
+ b -= c; b -= a; b ^= (a << 8); \
+ c -= a; c -= b; c ^= (b >> 13); \
+ a -= b; a -= c; a ^= (c >> 12); \
+ b -= c; b -= a; b ^= (a << 16); \
+ c -= a; c -= b; c ^= (b >> 5); \
+ a -= b; a -= c; a ^= (c >> 3); \
+ b -= c; b -= a; b ^= (a << 10); \
+ c -= a; c -= b; c ^= (b >> 15); \
+ } while (0)
+
+/*
+ * hash function based on bridge_hash in if_bridge.c
+ */
+void
+pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
+ struct pf_poolhashkey *key, sa_family_t af)
+{
+ u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ a += inaddr->addr32[0];
+ b += key->key32[1];
+ mix(a, b, c);
+ hash->addr32[0] = c + key->key32[2];
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ a += inaddr->addr32[0];
+ b += inaddr->addr32[2];
+ mix(a, b, c);
+ hash->addr32[0] = c;
+ a += inaddr->addr32[1];
+ b += inaddr->addr32[3];
+ c += key->key32[1];
+ mix(a, b, c);
+ hash->addr32[1] = c;
+ a += inaddr->addr32[2];
+ b += inaddr->addr32[1];
+ c += key->key32[2];
+ mix(a, b, c);
+ hash->addr32[2] = c;
+ a += inaddr->addr32[3];
+ b += inaddr->addr32[0];
+ c += key->key32[3];
+ mix(a, b, c);
+ hash->addr32[3] = c;
+ break;
+#endif /* INET6 */
+ }
+}
+
+struct pf_rule *
+pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
+ int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
+ struct pf_addr *daddr, u_int16_t dport, int rs_num)
+{
+ struct pf_rule *r, *rm = NULL;
+ struct pf_ruleset *ruleset = NULL;
+ int tag = -1;
+ int rtableid = -1;
+ int asd = 0;
+
+ r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
+ while (r && rm == NULL) {
+ struct pf_rule_addr *src = NULL, *dst = NULL;
+ struct pf_addr_wrap *xdst = NULL;
+
+ if (r->action == PF_BINAT && direction == PF_IN) {
+ src = &r->dst;
+ if (r->rpool.cur != NULL)
+ xdst = &r->rpool.cur->addr;
+ } else {
+ src = &r->src;
+ dst = &r->dst;
+ }
+
+ r->evaluations++;
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
+ r = r->skip[PF_SKIP_IFP].ptr;
+ else if (r->direction && r->direction != direction)
+ r = r->skip[PF_SKIP_DIR].ptr;
+ else if (r->af && r->af != pd->af)
+ r = r->skip[PF_SKIP_AF].ptr;
+ else if (r->proto && r->proto != pd->proto)
+ r = r->skip[PF_SKIP_PROTO].ptr;
+ else if (PF_MISMATCHAW(&src->addr, saddr, pd->af,
+ src->neg, kif, M_GETFIB(m)))
+ r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
+ PF_SKIP_DST_ADDR].ptr;
+ else if (src->port_op && !pf_match_port(src->port_op,
+ src->port[0], src->port[1], sport))
+ r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
+ PF_SKIP_DST_PORT].ptr;
+ else if (dst != NULL &&
+ PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL,
+ M_GETFIB(m)))
+ r = r->skip[PF_SKIP_DST_ADDR].ptr;
+ else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af,
+ 0, NULL, M_GETFIB(m)))
+ r = TAILQ_NEXT(r, entries);
+ else if (dst != NULL && dst->port_op &&
+ !pf_match_port(dst->port_op, dst->port[0],
+ dst->port[1], dport))
+ r = r->skip[PF_SKIP_DST_PORT].ptr;
+#ifdef __FreeBSD__
+ else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
+#else
+ else if (r->match_tag && !pf_match_tag(m, r, &tag))
+#endif
+ r = TAILQ_NEXT(r, entries);
+ else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
+ IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
+ off, pd->hdr.tcp), r->os_fingerprint)))
+ r = TAILQ_NEXT(r, entries);
+ else {
+ if (r->tag)
+ tag = r->tag;
+ if (r->rtableid >= 0)
+ rtableid = r->rtableid;
+ if (r->anchor == NULL) {
+ rm = r;
+ } else
+ pf_step_into_anchor(&asd, &ruleset, rs_num,
+ &r, NULL, NULL);
+ }
+ if (r == NULL)
+ pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r,
+ NULL, NULL);
+ }
+#ifdef __FreeBSD__
+ if (pf_tag_packet(m, tag, rtableid, pd->pf_mtag))
+#else
+ if (pf_tag_packet(m, tag, rtableid))
+#endif
+ return (NULL);
+ if (rm != NULL && (rm->action == PF_NONAT ||
+ rm->action == PF_NORDR || rm->action == PF_NOBINAT))
+ return (NULL);
+ return (rm);
+}
+
+int
+pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
+ struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
+ struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
+ struct pf_src_node **sn)
+{
+ struct pf_state_key_cmp key;
+ struct pf_addr init_addr;
+ u_int16_t cut;
+
+ bzero(&init_addr, sizeof(init_addr));
+ if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
+ return (1);
+
+ if (proto == IPPROTO_ICMP) {
+ low = 1;
+ high = 65535;
+ }
+
+ do {
+ key.af = af;
+ key.proto = proto;
+ PF_ACPY(&key.addr[1], daddr, key.af);
+ PF_ACPY(&key.addr[0], naddr, key.af);
+ key.port[1] = dport;
+
+ /*
+ * port search; start random, step;
+ * similar 2 portloop in in_pcbbind
+ */
+ if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
+ proto == IPPROTO_ICMP)) {
+ key.port[0] = dport;
+ if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
+ return (0);
+ } else if (low == 0 && high == 0) {
+ key.port[0] = *nport;
+ if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
+ return (0);
+ } else if (low == high) {
+ key.port[0] = htons(low);
+ if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
+ *nport = htons(low);
+ return (0);
+ }
+ } else {
+ u_int16_t tmp;
+
+ if (low > high) {
+ tmp = low;
+ low = high;
+ high = tmp;
+ }
+ /* low < high */
+#ifdef __FreeBSD__
+ cut = htonl(arc4random()) % (1 + high - low) + low;
+#else
+ cut = arc4random_uniform(1 + high - low) + low;
+#endif
+ /* low <= cut <= high */
+ for (tmp = cut; tmp <= high; ++(tmp)) {
+ key.port[0] = htons(tmp);
+ if (pf_find_state_all(&key, PF_IN, NULL) ==
+#ifdef __FreeBSD__
+ NULL) {
+#else
+ NULL && !in_baddynamic(tmp, proto)) {
+#endif
+ *nport = htons(tmp);
+ return (0);
+ }
+ }
+ for (tmp = cut - 1; tmp >= low; --(tmp)) {
+ key.port[0] = htons(tmp);
+ if (pf_find_state_all(&key, PF_IN, NULL) ==
+#ifdef __FreeBSD__
+ NULL) {
+#else
+ NULL && !in_baddynamic(tmp, proto)) {
+#endif
+ *nport = htons(tmp);
+ return (0);
+ }
+ }
+ }
+
+ switch (r->rpool.opts & PF_POOL_TYPEMASK) {
+ case PF_POOL_RANDOM:
+ case PF_POOL_ROUNDROBIN:
+ if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
+ return (1);
+ break;
+ case PF_POOL_NONE:
+ case PF_POOL_SRCHASH:
+ case PF_POOL_BITMASK:
+ default:
+ return (1);
+ }
+ } while (! PF_AEQ(&init_addr, naddr, af) );
+ return (1); /* none available */
+}
+
+int
+pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
+ struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
+{
+ unsigned char hash[16];
+ struct pf_pool *rpool = &r->rpool;
+ struct pf_addr *raddr = &rpool->cur->addr.v.a.addr;
+ struct pf_addr *rmask = &rpool->cur->addr.v.a.mask;
+ struct pf_pooladdr *acur = rpool->cur;
+ struct pf_src_node k;
+
+ if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
+ (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
+ k.af = af;
+ PF_ACPY(&k.addr, saddr, af);
+ if (r->rule_flag & PFRULE_RULESRCTRACK ||
+ r->rpool.opts & PF_POOL_STICKYADDR)
+ k.rule.ptr = r;
+ else
+ k.rule.ptr = NULL;
+#ifdef __FreeBSD__
+ V_pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
+ *sn = RB_FIND(pf_src_tree, &V_tree_src_tracking, &k);
+#else
+ pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
+ *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
+#endif
+ if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
+ PF_ACPY(naddr, &(*sn)->raddr, af);
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ printf("pf_map_addr: src tracking maps ");
+ pf_print_host(&k.addr, 0, af);
+ printf(" to ");
+ pf_print_host(naddr, 0, af);
+ printf("\n");
+ }
+ return (0);
+ }
+ }
+
+ if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
+ return (1);
+ if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
+ (rpool->opts & PF_POOL_TYPEMASK) !=
+ PF_POOL_ROUNDROBIN)
+ return (1);
+ raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
+ rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
+ (rpool->opts & PF_POOL_TYPEMASK) !=
+ PF_POOL_ROUNDROBIN)
+ return (1);
+ raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
+ rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
+ break;
+#endif /* INET6 */
+ }
+ } else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
+ if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
+ return (1); /* unsupported */
+ } else {
+ raddr = &rpool->cur->addr.v.a.addr;
+ rmask = &rpool->cur->addr.v.a.mask;
+ }
+
+ switch (rpool->opts & PF_POOL_TYPEMASK) {
+ case PF_POOL_NONE:
+ PF_ACPY(naddr, raddr, af);
+ break;
+ case PF_POOL_BITMASK:
+ PF_POOLMASK(naddr, raddr, rmask, saddr, af);
+ break;
+ case PF_POOL_RANDOM:
+ if (init_addr != NULL && PF_AZERO(init_addr, af)) {
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+ rpool->counter.addr32[0] = htonl(arc4random());
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (rmask->addr32[3] != 0xffffffff)
+ rpool->counter.addr32[3] =
+ htonl(arc4random());
+ else
+ break;
+ if (rmask->addr32[2] != 0xffffffff)
+ rpool->counter.addr32[2] =
+ htonl(arc4random());
+ else
+ break;
+ if (rmask->addr32[1] != 0xffffffff)
+ rpool->counter.addr32[1] =
+ htonl(arc4random());
+ else
+ break;
+ if (rmask->addr32[0] != 0xffffffff)
+ rpool->counter.addr32[0] =
+ htonl(arc4random());
+ break;
+#endif /* INET6 */
+ }
+ PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
+ PF_ACPY(init_addr, naddr, af);
+
+ } else {
+ PF_AINC(&rpool->counter, af);
+ PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
+ }
+ break;
+ case PF_POOL_SRCHASH:
+ pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
+ PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
+ break;
+ case PF_POOL_ROUNDROBIN:
+ if (rpool->cur->addr.type == PF_ADDR_TABLE) {
+ if (!pfr_pool_get(rpool->cur->addr.p.tbl,
+ &rpool->tblidx, &rpool->counter,
+ &raddr, &rmask, af))
+ goto get_addr;
+ } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
+ if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
+ &rpool->tblidx, &rpool->counter,
+ &raddr, &rmask, af))
+ goto get_addr;
+ } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
+ goto get_addr;
+
+ try_next:
+ if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
+ rpool->cur = TAILQ_FIRST(&rpool->list);
+ if (rpool->cur->addr.type == PF_ADDR_TABLE) {
+ rpool->tblidx = -1;
+ if (pfr_pool_get(rpool->cur->addr.p.tbl,
+ &rpool->tblidx, &rpool->counter,
+ &raddr, &rmask, af)) {
+ /* table contains no address of type 'af' */
+ if (rpool->cur != acur)
+ goto try_next;
+ return (1);
+ }
+ } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
+ rpool->tblidx = -1;
+ if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
+ &rpool->tblidx, &rpool->counter,
+ &raddr, &rmask, af)) {
+ /* table contains no address of type 'af' */
+ if (rpool->cur != acur)
+ goto try_next;
+ return (1);
+ }
+ } else {
+ raddr = &rpool->cur->addr.v.a.addr;
+ rmask = &rpool->cur->addr.v.a.mask;
+ PF_ACPY(&rpool->counter, raddr, af);
+ }
+
+ get_addr:
+ PF_ACPY(naddr, &rpool->counter, af);
+ if (init_addr != NULL && PF_AZERO(init_addr, af))
+ PF_ACPY(init_addr, naddr, af);
+ PF_AINC(&rpool->counter, af);
+ break;
+ }
+ if (*sn != NULL)
+ PF_ACPY(&(*sn)->raddr, naddr, af);
+
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC &&
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC &&
+#endif
+ (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
+ printf("pf_map_addr: selected address ");
+ pf_print_host(naddr, 0, af);
+ printf("\n");
+ }
+
+ return (0);
+}
+
+struct pf_rule *
+pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
+ struct pfi_kif *kif, struct pf_src_node **sn,
+ struct pf_state_key **skw, struct pf_state_key **sks,
+ struct pf_state_key **skp, struct pf_state_key **nkp,
+ struct pf_addr *saddr, struct pf_addr *daddr,
+ u_int16_t sport, u_int16_t dport)
+{
+ struct pf_rule *r = NULL;
+
+
+ if (direction == PF_OUT) {
+ r = pf_match_translation(pd, m, off, direction, kif, saddr,
+ sport, daddr, dport, PF_RULESET_BINAT);
+ if (r == NULL)
+ r = pf_match_translation(pd, m, off, direction, kif,
+ saddr, sport, daddr, dport, PF_RULESET_NAT);
+ } else {
+ r = pf_match_translation(pd, m, off, direction, kif, saddr,
+ sport, daddr, dport, PF_RULESET_RDR);
+ if (r == NULL)
+ r = pf_match_translation(pd, m, off, direction, kif,
+ saddr, sport, daddr, dport, PF_RULESET_BINAT);
+ }
+
+ if (r != NULL) {
+ struct pf_addr *naddr;
+ u_int16_t *nport;
+
+ if (pf_state_key_setup(pd, r, skw, sks, skp, nkp,
+ saddr, daddr, sport, dport))
+ return r;
+
+ /* XXX We only modify one side for now. */
+ naddr = &(*nkp)->addr[1];
+ nport = &(*nkp)->port[1];
+
+ switch (r->action) {
+ case PF_NONAT:
+ case PF_NOBINAT:
+ case PF_NORDR:
+ return (NULL);
+ case PF_NAT:
+ if (pf_get_sport(pd->af, pd->proto, r, saddr,
+ daddr, dport, naddr, nport, r->rpool.proxy_port[0],
+ r->rpool.proxy_port[1], sn)) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: NAT proxy port allocation "
+ "(%u-%u) failed\n",
+ r->rpool.proxy_port[0],
+ r->rpool.proxy_port[1]));
+ return (NULL);
+ }
+ break;
+ case PF_BINAT:
+ switch (direction) {
+ case PF_OUT:
+ if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
+ switch (pd->af) {
+#ifdef INET
+ case AF_INET:
+ if (r->rpool.cur->addr.p.dyn->
+ pfid_acnt4 < 1)
+ return (NULL);
+ PF_POOLMASK(naddr,
+ &r->rpool.cur->addr.p.dyn->
+ pfid_addr4,
+ &r->rpool.cur->addr.p.dyn->
+ pfid_mask4,
+ saddr, AF_INET);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (r->rpool.cur->addr.p.dyn->
+ pfid_acnt6 < 1)
+ return (NULL);
+ PF_POOLMASK(naddr,
+ &r->rpool.cur->addr.p.dyn->
+ pfid_addr6,
+ &r->rpool.cur->addr.p.dyn->
+ pfid_mask6,
+ saddr, AF_INET6);
+ break;
+#endif /* INET6 */
+ }
+ } else
+ PF_POOLMASK(naddr,
+ &r->rpool.cur->addr.v.a.addr,
+ &r->rpool.cur->addr.v.a.mask,
+ saddr, pd->af);
+ break;
+ case PF_IN:
+ if (r->src.addr.type == PF_ADDR_DYNIFTL) {
+ switch (pd->af) {
+#ifdef INET
+ case AF_INET:
+ if (r->src.addr.p.dyn->
+ pfid_acnt4 < 1)
+ return (NULL);
+ PF_POOLMASK(naddr,
+ &r->src.addr.p.dyn->
+ pfid_addr4,
+ &r->src.addr.p.dyn->
+ pfid_mask4,
+ daddr, AF_INET);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (r->src.addr.p.dyn->
+ pfid_acnt6 < 1)
+ return (NULL);
+ PF_POOLMASK(naddr,
+ &r->src.addr.p.dyn->
+ pfid_addr6,
+ &r->src.addr.p.dyn->
+ pfid_mask6,
+ daddr, AF_INET6);
+ break;
+#endif /* INET6 */
+ }
+ } else
+ PF_POOLMASK(naddr,
+ &r->src.addr.v.a.addr,
+ &r->src.addr.v.a.mask, daddr,
+ pd->af);
+ break;
+ }
+ break;
+ case PF_RDR: {
+ if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
+ return (NULL);
+ if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
+ PF_POOL_BITMASK)
+ PF_POOLMASK(naddr, naddr,
+ &r->rpool.cur->addr.v.a.mask, daddr,
+ pd->af);
+
+ if (r->rpool.proxy_port[1]) {
+ u_int32_t tmp_nport;
+
+ tmp_nport = ((ntohs(dport) -
+ ntohs(r->dst.port[0])) %
+ (r->rpool.proxy_port[1] -
+ r->rpool.proxy_port[0] + 1)) +
+ r->rpool.proxy_port[0];
+
+ /* wrap around if necessary */
+ if (tmp_nport > 65535)
+ tmp_nport -= 65535;
+ *nport = htons((u_int16_t)tmp_nport);
+ } else if (r->rpool.proxy_port[0])
+ *nport = htons(r->rpool.proxy_port[0]);
+ break;
+ }
+ default:
+ return (NULL);
+ }
+ /*
+ * Translation was a NOP.
+ * Pretend there was no match.
+ */
+ if (!bcmp(*skp, *nkp, sizeof(struct pf_state_key_cmp))) {
+#ifdef __FreeBSD__
+ pool_put(&V_pf_state_key_pl, *nkp);
+ pool_put(&V_pf_state_key_pl, *skp);
+#else
+ pool_put(&pf_state_key_pl, *nkp);
+ pool_put(&pf_state_key_pl, *skp);
+#endif
+ *skw = *sks = *nkp = *skp = NULL;
+ return (NULL);
+ }
+ }
+
+ return (r);
+}
+
diff --git a/sys/contrib/pf/net/pf_mtag.h b/sys/contrib/pf/net/pf_mtag.h
new file mode 100644
index 0000000..141a867
--- /dev/null
+++ b/sys/contrib/pf/net/pf_mtag.h
@@ -0,0 +1,84 @@
+/* $FreeBSD$ */
+/*
+ * Copyright (c) 2001 Daniel Hartmeier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef _NET_PF_MTAG_H_
+#define _NET_PF_MTAG_H_
+
+#ifdef _KERNEL
+
+#define PF_TAG_GENERATED 0x01
+#define PF_TAG_FRAGCACHE 0x02
+#define PF_TAG_TRANSLATE_LOCALHOST 0x04
+#define PF_PACKET_LOOPED 0x08
+#define PF_FASTFWD_OURS_PRESENT 0x10
+
+struct pf_mtag {
+ void *hdr; /* saved hdr pos in mbuf, for ECN */
+ void *statekey; /* pf stackside statekey */
+ u_int32_t qid; /* queue id */
+ u_int rtableid; /* alternate routing table id */
+ u_int16_t tag; /* tag id */
+ u_int8_t flags;
+ u_int8_t routed;
+};
+
+static __inline struct pf_mtag *pf_find_mtag(struct mbuf *);
+static __inline struct pf_mtag *pf_get_mtag(struct mbuf *);
+
+static __inline struct pf_mtag *
+pf_find_mtag(struct mbuf *m)
+{
+ struct m_tag *mtag;
+
+ if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL)
+ return (NULL);
+
+ return ((struct pf_mtag *)(mtag + 1));
+}
+
+static __inline struct pf_mtag *
+pf_get_mtag(struct mbuf *m)
+{
+ struct m_tag *mtag;
+
+ if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) {
+ mtag = m_tag_get(PACKET_TAG_PF, sizeof(struct pf_mtag),
+ M_NOWAIT);
+ if (mtag == NULL)
+ return (NULL);
+ bzero(mtag + 1, sizeof(struct pf_mtag));
+ m_tag_prepend(m, mtag);
+ }
+
+ return ((struct pf_mtag *)(mtag + 1));
+}
+#endif /* _KERNEL */
+#endif /* _NET_PF_MTAG_H_ */
diff --git a/sys/contrib/pf/net/pf_norm.c b/sys/contrib/pf/net/pf_norm.c
new file mode 100644
index 0000000..2b20c85
--- /dev/null
+++ b/sys/contrib/pf/net/pf_norm.c
@@ -0,0 +1,2359 @@
+/* $OpenBSD: pf_norm.c,v 1.114 2009/01/29 14:11:45 henning Exp $ */
+
+/*
+ * Copyright 2001 Niels Provos <provos@citi.umich.edu>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef __FreeBSD__
+#include "opt_inet.h"
+#include "opt_inet6.h"
+#include "opt_pf.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#ifdef DEV_PFLOG
+#define NPFLOG DEV_PFLOG
+#else
+#define NPFLOG 0
+#endif
+#else
+#include "pflog.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/filio.h>
+#include <sys/fcntl.h>
+#include <sys/socket.h>
+#include <sys/kernel.h>
+#include <sys/time.h>
+#ifndef __FreeBSD__
+#include <sys/pool.h>
+
+#include <dev/rndvar.h>
+#endif
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/bpf.h>
+#include <net/route.h>
+#include <net/if_pflog.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_seq.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+
+#ifdef INET6
+#include <netinet/ip6.h>
+#endif /* INET6 */
+
+#include <net/pfvar.h>
+
+#ifndef __FreeBSD__
+struct pf_frent {
+ LIST_ENTRY(pf_frent) fr_next;
+ struct ip *fr_ip;
+ struct mbuf *fr_m;
+};
+
+struct pf_frcache {
+ LIST_ENTRY(pf_frcache) fr_next;
+ uint16_t fr_off;
+ uint16_t fr_end;
+};
+#endif
+
+#define PFFRAG_SEENLAST 0x0001 /* Seen the last fragment for this */
+#define PFFRAG_NOBUFFER 0x0002 /* Non-buffering fragment cache */
+#define PFFRAG_DROP 0x0004 /* Drop all fragments */
+#define BUFFER_FRAGMENTS(fr) (!((fr)->fr_flags & PFFRAG_NOBUFFER))
+
+#ifndef __FreeBSD__
+struct pf_fragment {
+ RB_ENTRY(pf_fragment) fr_entry;
+ TAILQ_ENTRY(pf_fragment) frag_next;
+ struct in_addr fr_src;
+ struct in_addr fr_dst;
+ u_int8_t fr_p; /* protocol of this fragment */
+ u_int8_t fr_flags; /* status flags */
+ u_int16_t fr_id; /* fragment id for reassemble */
+ u_int16_t fr_max; /* fragment data max */
+ u_int32_t fr_timeout;
+#define fr_queue fr_u.fru_queue
+#define fr_cache fr_u.fru_cache
+ union {
+ LIST_HEAD(pf_fragq, pf_frent) fru_queue; /* buffering */
+ LIST_HEAD(pf_cacheq, pf_frcache) fru_cache; /* non-buf */
+ } fr_u;
+};
+#endif
+
+#ifdef __FreeBSD__
+TAILQ_HEAD(pf_fragqueue, pf_fragment);
+TAILQ_HEAD(pf_cachequeue, pf_fragment);
+VNET_DEFINE(struct pf_fragqueue, pf_fragqueue);
+#define V_pf_fragqueue VNET(pf_fragqueue)
+VNET_DEFINE(struct pf_cachequeue, pf_cachequeue);
+#define V_pf_cachequeue VNET(pf_cachequeue)
+#else
+TAILQ_HEAD(pf_fragqueue, pf_fragment) pf_fragqueue;
+TAILQ_HEAD(pf_cachequeue, pf_fragment) pf_cachequeue;
+#endif
+
+#ifndef __FreeBSD__
+static __inline int pf_frag_compare(struct pf_fragment *,
+ struct pf_fragment *);
+#else
+static int pf_frag_compare(struct pf_fragment *,
+ struct pf_fragment *);
+#endif
+
+#ifdef __FreeBSD__
+RB_HEAD(pf_frag_tree, pf_fragment);
+VNET_DEFINE(struct pf_frag_tree, pf_frag_tree);
+#define V_pf_frag_tree VNET(pf_frag_tree)
+VNET_DEFINE(struct pf_frag_tree, pf_cache_tree);
+#define V_pf_cache_tree VNET(pf_cache_tree)
+#else
+RB_HEAD(pf_frag_tree, pf_fragment) pf_frag_tree, pf_cache_tree;
+#endif
+RB_PROTOTYPE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
+RB_GENERATE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
+
+/* Private prototypes */
+void pf_ip2key(struct pf_fragment *, struct ip *);
+void pf_remove_fragment(struct pf_fragment *);
+void pf_flush_fragments(void);
+void pf_free_fragment(struct pf_fragment *);
+struct pf_fragment *pf_find_fragment(struct ip *, struct pf_frag_tree *);
+struct mbuf *pf_reassemble(struct mbuf **, struct pf_fragment **,
+ struct pf_frent *, int);
+struct mbuf *pf_fragcache(struct mbuf **, struct ip*,
+ struct pf_fragment **, int, int, int *);
+int pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
+ struct tcphdr *, int, sa_family_t);
+void pf_scrub_ip(struct mbuf **, u_int32_t, u_int8_t,
+ u_int8_t);
+#ifdef INET6
+void pf_scrub_ip6(struct mbuf **, u_int8_t);
+#endif
+#ifdef __FreeBSD__
+#define DPFPRINTF(x) do { \
+ if (V_pf_status.debug >= PF_DEBUG_MISC) { \
+ printf("%s: ", __func__); \
+ printf x ; \
+ } \
+} while(0)
+#else
+#define DPFPRINTF(x) do { \
+ if (pf_status.debug >= PF_DEBUG_MISC) { \
+ printf("%s: ", __func__); \
+ printf x ; \
+ } \
+} while(0)
+#endif
+
+/* Globals */
+#ifdef __FreeBSD__
+VNET_DEFINE(uma_zone_t, pf_frent_pl);
+VNET_DEFINE(uma_zone_t, pf_frag_pl);
+VNET_DEFINE(uma_zone_t, pf_cache_pl);
+VNET_DEFINE(uma_zone_t, pf_cent_pl);
+VNET_DEFINE(uma_zone_t, pf_state_scrub_pl);
+
+VNET_DEFINE(int, pf_nfrents);
+#define V_pf_nfrents VNET(pf_nfrents)
+VNET_DEFINE(int, pf_ncache);
+#define V_pf_ncache VNET(pf_ncache)
+#else
+struct pool pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
+struct pool pf_state_scrub_pl;
+int pf_nfrents, pf_ncache;
+#endif
+
+void
+pf_normalize_init(void)
+{
+#ifdef __FreeBSD__
+ /*
+ * XXX
+ * No high water mark support(It's hint not hard limit).
+ * uma_zone_set_max(pf_frag_pl, PFFRAG_FRAG_HIWAT);
+ */
+ uma_zone_set_max(V_pf_frent_pl, PFFRAG_FRENT_HIWAT);
+ uma_zone_set_max(V_pf_cache_pl, PFFRAG_FRCACHE_HIWAT);
+ uma_zone_set_max(V_pf_cent_pl, PFFRAG_FRCENT_HIWAT);
+#else
+ pool_init(&pf_frent_pl, sizeof(struct pf_frent), 0, 0, 0, "pffrent",
+ NULL);
+ pool_init(&pf_frag_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrag",
+ NULL);
+ pool_init(&pf_cache_pl, sizeof(struct pf_fragment), 0, 0, 0,
+ "pffrcache", NULL);
+ pool_init(&pf_cent_pl, sizeof(struct pf_frcache), 0, 0, 0, "pffrcent",
+ NULL);
+ pool_init(&pf_state_scrub_pl, sizeof(struct pf_state_scrub), 0, 0, 0,
+ "pfstscr", NULL);
+
+ pool_sethiwat(&pf_frag_pl, PFFRAG_FRAG_HIWAT);
+ pool_sethardlimit(&pf_frent_pl, PFFRAG_FRENT_HIWAT, NULL, 0);
+ pool_sethardlimit(&pf_cache_pl, PFFRAG_FRCACHE_HIWAT, NULL, 0);
+ pool_sethardlimit(&pf_cent_pl, PFFRAG_FRCENT_HIWAT, NULL, 0);
+#endif
+
+#ifdef __FreeBSD__
+ TAILQ_INIT(&V_pf_fragqueue);
+ TAILQ_INIT(&V_pf_cachequeue);
+#else
+ TAILQ_INIT(&pf_fragqueue);
+ TAILQ_INIT(&pf_cachequeue);
+#endif
+}
+
+#ifdef __FreeBSD__
+static int
+#else
+static __inline int
+#endif
+pf_frag_compare(struct pf_fragment *a, struct pf_fragment *b)
+{
+ int diff;
+
+ if ((diff = a->fr_id - b->fr_id))
+ return (diff);
+ else if ((diff = a->fr_p - b->fr_p))
+ return (diff);
+ else if (a->fr_src.s_addr < b->fr_src.s_addr)
+ return (-1);
+ else if (a->fr_src.s_addr > b->fr_src.s_addr)
+ return (1);
+ else if (a->fr_dst.s_addr < b->fr_dst.s_addr)
+ return (-1);
+ else if (a->fr_dst.s_addr > b->fr_dst.s_addr)
+ return (1);
+ return (0);
+}
+
+void
+pf_purge_expired_fragments(void)
+{
+ struct pf_fragment *frag;
+#ifdef __FreeBSD__
+ u_int32_t expire = time_second -
+ V_pf_default_rule.timeout[PFTM_FRAG];
+#else
+ u_int32_t expire = time_second -
+ pf_default_rule.timeout[PFTM_FRAG];
+#endif
+
+#ifdef __FreeBSD__
+ while ((frag = TAILQ_LAST(&V_pf_fragqueue, pf_fragqueue)) != NULL) {
+ KASSERT((BUFFER_FRAGMENTS(frag)),
+ ("BUFFER_FRAGMENTS(frag) == 0: %s", __FUNCTION__));
+#else
+ while ((frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue)) != NULL) {
+ KASSERT(BUFFER_FRAGMENTS(frag));
+#endif
+ if (frag->fr_timeout > expire)
+ break;
+
+ DPFPRINTF(("expiring %d(%p)\n", frag->fr_id, frag));
+ pf_free_fragment(frag);
+ }
+
+#ifdef __FreeBSD__
+ while ((frag = TAILQ_LAST(&V_pf_cachequeue, pf_cachequeue)) != NULL) {
+ KASSERT((!BUFFER_FRAGMENTS(frag)),
+ ("BUFFER_FRAGMENTS(frag) != 0: %s", __FUNCTION__));
+#else
+ while ((frag = TAILQ_LAST(&pf_cachequeue, pf_cachequeue)) != NULL) {
+ KASSERT(!BUFFER_FRAGMENTS(frag));
+#endif
+ if (frag->fr_timeout > expire)
+ break;
+
+ DPFPRINTF(("expiring %d(%p)\n", frag->fr_id, frag));
+ pf_free_fragment(frag);
+#ifdef __FreeBSD__
+ KASSERT((TAILQ_EMPTY(&V_pf_cachequeue) ||
+ TAILQ_LAST(&V_pf_cachequeue, pf_cachequeue) != frag),
+ ("!(TAILQ_EMPTY() || TAILQ_LAST() == farg): %s",
+ __FUNCTION__));
+#else
+ KASSERT(TAILQ_EMPTY(&pf_cachequeue) ||
+ TAILQ_LAST(&pf_cachequeue, pf_cachequeue) != frag);
+#endif
+ }
+}
+
+/*
+ * Try to flush old fragments to make space for new ones
+ */
+
+void
+pf_flush_fragments(void)
+{
+ struct pf_fragment *frag;
+ int goal;
+
+#ifdef __FreeBSD__
+ goal = V_pf_nfrents * 9 / 10;
+ DPFPRINTF(("trying to free > %d frents\n",
+ V_pf_nfrents - goal));
+ while (goal < V_pf_nfrents) {
+#else
+ goal = pf_nfrents * 9 / 10;
+ DPFPRINTF(("trying to free > %d frents\n",
+ pf_nfrents - goal));
+ while (goal < pf_nfrents) {
+#endif
+#ifdef __FreeBSD__
+ frag = TAILQ_LAST(&V_pf_fragqueue, pf_fragqueue);
+#else
+ frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue);
+#endif
+ if (frag == NULL)
+ break;
+ pf_free_fragment(frag);
+ }
+
+
+#ifdef __FreeBSD__
+ goal = V_pf_ncache * 9 / 10;
+ DPFPRINTF(("trying to free > %d cache entries\n",
+ V_pf_ncache - goal));
+ while (goal < V_pf_ncache) {
+#else
+ goal = pf_ncache * 9 / 10;
+ DPFPRINTF(("trying to free > %d cache entries\n",
+ pf_ncache - goal));
+ while (goal < pf_ncache) {
+#endif
+#ifdef __FreeBSD__
+ frag = TAILQ_LAST(&V_pf_cachequeue, pf_cachequeue);
+#else
+ frag = TAILQ_LAST(&pf_cachequeue, pf_cachequeue);
+#endif
+ if (frag == NULL)
+ break;
+ pf_free_fragment(frag);
+ }
+}
+
+/* Frees the fragments and all associated entries */
+
+void
+pf_free_fragment(struct pf_fragment *frag)
+{
+ struct pf_frent *frent;
+ struct pf_frcache *frcache;
+
+ /* Free all fragments */
+ if (BUFFER_FRAGMENTS(frag)) {
+ for (frent = LIST_FIRST(&frag->fr_queue); frent;
+ frent = LIST_FIRST(&frag->fr_queue)) {
+ LIST_REMOVE(frent, fr_next);
+
+ m_freem(frent->fr_m);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_frent_pl, frent);
+ V_pf_nfrents--;
+#else
+ pool_put(&pf_frent_pl, frent);
+ pf_nfrents--;
+#endif
+ }
+ } else {
+ for (frcache = LIST_FIRST(&frag->fr_cache); frcache;
+ frcache = LIST_FIRST(&frag->fr_cache)) {
+ LIST_REMOVE(frcache, fr_next);
+
+#ifdef __FreeBSD__
+ KASSERT((LIST_EMPTY(&frag->fr_cache) ||
+ LIST_FIRST(&frag->fr_cache)->fr_off >
+ frcache->fr_end),
+ ("! (LIST_EMPTY() || LIST_FIRST()->fr_off >"
+ " frcache->fr_end): %s", __FUNCTION__));
+
+ pool_put(&V_pf_cent_pl, frcache);
+ V_pf_ncache--;
+#else
+ KASSERT(LIST_EMPTY(&frag->fr_cache) ||
+ LIST_FIRST(&frag->fr_cache)->fr_off >
+ frcache->fr_end);
+
+ pool_put(&pf_cent_pl, frcache);
+ pf_ncache--;
+#endif
+ }
+ }
+
+ pf_remove_fragment(frag);
+}
+
+void
+pf_ip2key(struct pf_fragment *key, struct ip *ip)
+{
+ key->fr_p = ip->ip_p;
+ key->fr_id = ip->ip_id;
+ key->fr_src.s_addr = ip->ip_src.s_addr;
+ key->fr_dst.s_addr = ip->ip_dst.s_addr;
+}
+
+struct pf_fragment *
+pf_find_fragment(struct ip *ip, struct pf_frag_tree *tree)
+{
+ struct pf_fragment key;
+ struct pf_fragment *frag;
+
+ pf_ip2key(&key, ip);
+
+ frag = RB_FIND(pf_frag_tree, tree, &key);
+ if (frag != NULL) {
+ /* XXX Are we sure we want to update the timeout? */
+ frag->fr_timeout = time_second;
+ if (BUFFER_FRAGMENTS(frag)) {
+#ifdef __FreeBSD__
+ TAILQ_REMOVE(&V_pf_fragqueue, frag, frag_next);
+ TAILQ_INSERT_HEAD(&V_pf_fragqueue, frag, frag_next);
+#else
+ TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
+ TAILQ_INSERT_HEAD(&pf_fragqueue, frag, frag_next);
+#endif
+ } else {
+#ifdef __FreeBSD__
+ TAILQ_REMOVE(&V_pf_cachequeue, frag, frag_next);
+ TAILQ_INSERT_HEAD(&V_pf_cachequeue, frag, frag_next);
+#else
+ TAILQ_REMOVE(&pf_cachequeue, frag, frag_next);
+ TAILQ_INSERT_HEAD(&pf_cachequeue, frag, frag_next);
+#endif
+ }
+ }
+
+ return (frag);
+}
+
+/* Removes a fragment from the fragment queue and frees the fragment */
+
+void
+pf_remove_fragment(struct pf_fragment *frag)
+{
+ if (BUFFER_FRAGMENTS(frag)) {
+#ifdef __FreeBSD__
+ RB_REMOVE(pf_frag_tree, &V_pf_frag_tree, frag);
+ TAILQ_REMOVE(&V_pf_fragqueue, frag, frag_next);
+ pool_put(&V_pf_frag_pl, frag);
+#else
+ RB_REMOVE(pf_frag_tree, &pf_frag_tree, frag);
+ TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
+ pool_put(&pf_frag_pl, frag);
+#endif
+ } else {
+#ifdef __FreeBSD__
+ RB_REMOVE(pf_frag_tree, &V_pf_cache_tree, frag);
+ TAILQ_REMOVE(&V_pf_cachequeue, frag, frag_next);
+ pool_put(&V_pf_cache_pl, frag);
+#else
+ RB_REMOVE(pf_frag_tree, &pf_cache_tree, frag);
+ TAILQ_REMOVE(&pf_cachequeue, frag, frag_next);
+ pool_put(&pf_cache_pl, frag);
+#endif
+ }
+}
+
+#define FR_IP_OFF(fr) ((ntohs((fr)->fr_ip->ip_off) & IP_OFFMASK) << 3)
+struct mbuf *
+pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
+ struct pf_frent *frent, int mff)
+{
+ struct mbuf *m = *m0, *m2;
+ struct pf_frent *frea, *next;
+ struct pf_frent *frep = NULL;
+ struct ip *ip = frent->fr_ip;
+ int hlen = ip->ip_hl << 2;
+ u_int16_t off = (ntohs(ip->ip_off) & IP_OFFMASK) << 3;
+ u_int16_t ip_len = ntohs(ip->ip_len) - ip->ip_hl * 4;
+ u_int16_t max = ip_len + off;
+
+#ifdef __FreeBSD__
+ KASSERT((*frag == NULL || BUFFER_FRAGMENTS(*frag)),
+ ("! (*frag == NULL || BUFFER_FRAGMENTS(*frag)): %s", __FUNCTION__));
+#else
+ KASSERT(*frag == NULL || BUFFER_FRAGMENTS(*frag));
+#endif
+
+ /* Strip off ip header */
+ m->m_data += hlen;
+ m->m_len -= hlen;
+
+ /* Create a new reassembly queue for this packet */
+ if (*frag == NULL) {
+#ifdef __FreeBSD__
+ *frag = pool_get(&V_pf_frag_pl, PR_NOWAIT);
+#else
+ *frag = pool_get(&pf_frag_pl, PR_NOWAIT);
+#endif
+ if (*frag == NULL) {
+ pf_flush_fragments();
+#ifdef __FreeBSD__
+ *frag = pool_get(&V_pf_frag_pl, PR_NOWAIT);
+#else
+ *frag = pool_get(&pf_frag_pl, PR_NOWAIT);
+#endif
+ if (*frag == NULL)
+ goto drop_fragment;
+ }
+
+ (*frag)->fr_flags = 0;
+ (*frag)->fr_max = 0;
+ (*frag)->fr_src = frent->fr_ip->ip_src;
+ (*frag)->fr_dst = frent->fr_ip->ip_dst;
+ (*frag)->fr_p = frent->fr_ip->ip_p;
+ (*frag)->fr_id = frent->fr_ip->ip_id;
+ (*frag)->fr_timeout = time_second;
+ LIST_INIT(&(*frag)->fr_queue);
+
+#ifdef __FreeBSD__
+ RB_INSERT(pf_frag_tree, &V_pf_frag_tree, *frag);
+ TAILQ_INSERT_HEAD(&V_pf_fragqueue, *frag, frag_next);
+#else
+ RB_INSERT(pf_frag_tree, &pf_frag_tree, *frag);
+ TAILQ_INSERT_HEAD(&pf_fragqueue, *frag, frag_next);
+#endif
+
+ /* We do not have a previous fragment */
+ frep = NULL;
+ goto insert;
+ }
+
+ /*
+ * Find a fragment after the current one:
+ * - off contains the real shifted offset.
+ */
+ LIST_FOREACH(frea, &(*frag)->fr_queue, fr_next) {
+ if (FR_IP_OFF(frea) > off)
+ break;
+ frep = frea;
+ }
+
+#ifdef __FreeBSD__
+ KASSERT((frep != NULL || frea != NULL),
+ ("!(frep != NULL || frea != NULL): %s", __FUNCTION__));;
+#else
+ KASSERT(frep != NULL || frea != NULL);
+#endif
+
+ if (frep != NULL &&
+ FR_IP_OFF(frep) + ntohs(frep->fr_ip->ip_len) - frep->fr_ip->ip_hl *
+ 4 > off)
+ {
+ u_int16_t precut;
+
+ precut = FR_IP_OFF(frep) + ntohs(frep->fr_ip->ip_len) -
+ frep->fr_ip->ip_hl * 4 - off;
+ if (precut >= ip_len)
+ goto drop_fragment;
+ m_adj(frent->fr_m, precut);
+ DPFPRINTF(("overlap -%d\n", precut));
+ /* Enforce 8 byte boundaries */
+ ip->ip_off = htons(ntohs(ip->ip_off) + (precut >> 3));
+ off = (ntohs(ip->ip_off) & IP_OFFMASK) << 3;
+ ip_len -= precut;
+ ip->ip_len = htons(ip_len);
+ }
+
+ for (; frea != NULL && ip_len + off > FR_IP_OFF(frea);
+ frea = next)
+ {
+ u_int16_t aftercut;
+
+ aftercut = ip_len + off - FR_IP_OFF(frea);
+ DPFPRINTF(("adjust overlap %d\n", aftercut));
+ if (aftercut < ntohs(frea->fr_ip->ip_len) - frea->fr_ip->ip_hl
+ * 4)
+ {
+ frea->fr_ip->ip_len =
+ htons(ntohs(frea->fr_ip->ip_len) - aftercut);
+ frea->fr_ip->ip_off = htons(ntohs(frea->fr_ip->ip_off) +
+ (aftercut >> 3));
+ m_adj(frea->fr_m, aftercut);
+ break;
+ }
+
+ /* This fragment is completely overlapped, lose it */
+ next = LIST_NEXT(frea, fr_next);
+ m_freem(frea->fr_m);
+ LIST_REMOVE(frea, fr_next);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_frent_pl, frea);
+ V_pf_nfrents--;
+#else
+ pool_put(&pf_frent_pl, frea);
+ pf_nfrents--;
+#endif
+ }
+
+ insert:
+ /* Update maximum data size */
+ if ((*frag)->fr_max < max)
+ (*frag)->fr_max = max;
+ /* This is the last segment */
+ if (!mff)
+ (*frag)->fr_flags |= PFFRAG_SEENLAST;
+
+ if (frep == NULL)
+ LIST_INSERT_HEAD(&(*frag)->fr_queue, frent, fr_next);
+ else
+ LIST_INSERT_AFTER(frep, frent, fr_next);
+
+ /* Check if we are completely reassembled */
+ if (!((*frag)->fr_flags & PFFRAG_SEENLAST))
+ return (NULL);
+
+ /* Check if we have all the data */
+ off = 0;
+ for (frep = LIST_FIRST(&(*frag)->fr_queue); frep; frep = next) {
+ next = LIST_NEXT(frep, fr_next);
+
+ off += ntohs(frep->fr_ip->ip_len) - frep->fr_ip->ip_hl * 4;
+ if (off < (*frag)->fr_max &&
+ (next == NULL || FR_IP_OFF(next) != off))
+ {
+ DPFPRINTF(("missing fragment at %d, next %d, max %d\n",
+ off, next == NULL ? -1 : FR_IP_OFF(next),
+ (*frag)->fr_max));
+ return (NULL);
+ }
+ }
+ DPFPRINTF(("%d < %d?\n", off, (*frag)->fr_max));
+ if (off < (*frag)->fr_max)
+ return (NULL);
+
+ /* We have all the data */
+ frent = LIST_FIRST(&(*frag)->fr_queue);
+#ifdef __FreeBSD__
+ KASSERT((frent != NULL), ("frent == NULL: %s", __FUNCTION__));
+#else
+ KASSERT(frent != NULL);
+#endif
+ if ((frent->fr_ip->ip_hl << 2) + off > IP_MAXPACKET) {
+ DPFPRINTF(("drop: too big: %d\n", off));
+ pf_free_fragment(*frag);
+ *frag = NULL;
+ return (NULL);
+ }
+ next = LIST_NEXT(frent, fr_next);
+
+ /* Magic from ip_input */
+ ip = frent->fr_ip;
+ m = frent->fr_m;
+ m2 = m->m_next;
+ m->m_next = NULL;
+ m_cat(m, m2);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_frent_pl, frent);
+ V_pf_nfrents--;
+#else
+ pool_put(&pf_frent_pl, frent);
+ pf_nfrents--;
+#endif
+ for (frent = next; frent != NULL; frent = next) {
+ next = LIST_NEXT(frent, fr_next);
+
+ m2 = frent->fr_m;
+#ifdef __FreeBSD__
+ pool_put(&V_pf_frent_pl, frent);
+ V_pf_nfrents--;
+#else
+ pool_put(&pf_frent_pl, frent);
+ pf_nfrents--;
+#endif
+#ifdef __FreeBSD__
+ m->m_pkthdr.csum_flags &= m2->m_pkthdr.csum_flags;
+ m->m_pkthdr.csum_data += m2->m_pkthdr.csum_data;
+#endif
+ m_cat(m, m2);
+ }
+
+#ifdef __FreeBSD__
+ while (m->m_pkthdr.csum_data & 0xffff0000)
+ m->m_pkthdr.csum_data = (m->m_pkthdr.csum_data & 0xffff) +
+ (m->m_pkthdr.csum_data >> 16);
+#endif
+ ip->ip_src = (*frag)->fr_src;
+ ip->ip_dst = (*frag)->fr_dst;
+
+ /* Remove from fragment queue */
+ pf_remove_fragment(*frag);
+ *frag = NULL;
+
+ hlen = ip->ip_hl << 2;
+ ip->ip_len = htons(off + hlen);
+ m->m_len += hlen;
+ m->m_data -= hlen;
+
+ /* some debugging cruft by sklower, below, will go away soon */
+ /* XXX this should be done elsewhere */
+ if (m->m_flags & M_PKTHDR) {
+ int plen = 0;
+ for (m2 = m; m2; m2 = m2->m_next)
+ plen += m2->m_len;
+ m->m_pkthdr.len = plen;
+ }
+
+ DPFPRINTF(("complete: %p(%d)\n", m, ntohs(ip->ip_len)));
+ return (m);
+
+ drop_fragment:
+ /* Oops - fail safe - drop packet */
+#ifdef __FreeBSD__
+ pool_put(&V_pf_frent_pl, frent);
+ V_pf_nfrents--;
+#else
+ pool_put(&pf_frent_pl, frent);
+ pf_nfrents--;
+#endif
+ m_freem(m);
+ return (NULL);
+}
+
+struct mbuf *
+pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
+ int drop, int *nomem)
+{
+ struct mbuf *m = *m0;
+ struct pf_frcache *frp, *fra, *cur = NULL;
+ int ip_len = ntohs(h->ip_len) - (h->ip_hl << 2);
+ u_int16_t off = ntohs(h->ip_off) << 3;
+ u_int16_t max = ip_len + off;
+ int hosed = 0;
+
+#ifdef __FreeBSD__
+ KASSERT((*frag == NULL || !BUFFER_FRAGMENTS(*frag)),
+ ("!(*frag == NULL || !BUFFER_FRAGMENTS(*frag)): %s", __FUNCTION__));
+#else
+ KASSERT(*frag == NULL || !BUFFER_FRAGMENTS(*frag));
+#endif
+
+ /* Create a new range queue for this packet */
+ if (*frag == NULL) {
+#ifdef __FreeBSD__
+ *frag = pool_get(&V_pf_cache_pl, PR_NOWAIT);
+#else
+ *frag = pool_get(&pf_cache_pl, PR_NOWAIT);
+#endif
+ if (*frag == NULL) {
+ pf_flush_fragments();
+#ifdef __FreeBSD__
+ *frag = pool_get(&V_pf_cache_pl, PR_NOWAIT);
+#else
+ *frag = pool_get(&pf_cache_pl, PR_NOWAIT);
+#endif
+ if (*frag == NULL)
+ goto no_mem;
+ }
+
+ /* Get an entry for the queue */
+#ifdef __FreeBSD__
+ cur = pool_get(&V_pf_cent_pl, PR_NOWAIT);
+ if (cur == NULL) {
+ pool_put(&V_pf_cache_pl, *frag);
+#else
+ cur = pool_get(&pf_cent_pl, PR_NOWAIT);
+ if (cur == NULL) {
+ pool_put(&pf_cache_pl, *frag);
+#endif
+ *frag = NULL;
+ goto no_mem;
+ }
+#ifdef __FreeBSD__
+ V_pf_ncache++;
+#else
+ pf_ncache++;
+#endif
+
+ (*frag)->fr_flags = PFFRAG_NOBUFFER;
+ (*frag)->fr_max = 0;
+ (*frag)->fr_src = h->ip_src;
+ (*frag)->fr_dst = h->ip_dst;
+ (*frag)->fr_p = h->ip_p;
+ (*frag)->fr_id = h->ip_id;
+ (*frag)->fr_timeout = time_second;
+
+ cur->fr_off = off;
+ cur->fr_end = max;
+ LIST_INIT(&(*frag)->fr_cache);
+ LIST_INSERT_HEAD(&(*frag)->fr_cache, cur, fr_next);
+
+#ifdef __FreeBSD__
+ RB_INSERT(pf_frag_tree, &V_pf_cache_tree, *frag);
+ TAILQ_INSERT_HEAD(&V_pf_cachequeue, *frag, frag_next);
+#else
+ RB_INSERT(pf_frag_tree, &pf_cache_tree, *frag);
+ TAILQ_INSERT_HEAD(&pf_cachequeue, *frag, frag_next);
+#endif
+
+ DPFPRINTF(("fragcache[%d]: new %d-%d\n", h->ip_id, off, max));
+
+ goto pass;
+ }
+
+ /*
+ * Find a fragment after the current one:
+ * - off contains the real shifted offset.
+ */
+ frp = NULL;
+ LIST_FOREACH(fra, &(*frag)->fr_cache, fr_next) {
+ if (fra->fr_off > off)
+ break;
+ frp = fra;
+ }
+
+#ifdef __FreeBSD__
+ KASSERT((frp != NULL || fra != NULL),
+ ("!(frp != NULL || fra != NULL): %s", __FUNCTION__));
+#else
+ KASSERT(frp != NULL || fra != NULL);
+#endif
+
+ if (frp != NULL) {
+ int precut;
+
+ precut = frp->fr_end - off;
+ if (precut >= ip_len) {
+ /* Fragment is entirely a duplicate */
+ DPFPRINTF(("fragcache[%d]: dead (%d-%d) %d-%d\n",
+ h->ip_id, frp->fr_off, frp->fr_end, off, max));
+ goto drop_fragment;
+ }
+ if (precut == 0) {
+ /* They are adjacent. Fixup cache entry */
+ DPFPRINTF(("fragcache[%d]: adjacent (%d-%d) %d-%d\n",
+ h->ip_id, frp->fr_off, frp->fr_end, off, max));
+ frp->fr_end = max;
+ } else if (precut > 0) {
+ /* The first part of this payload overlaps with a
+ * fragment that has already been passed.
+ * Need to trim off the first part of the payload.
+ * But to do so easily, we need to create another
+ * mbuf to throw the original header into.
+ */
+
+ DPFPRINTF(("fragcache[%d]: chop %d (%d-%d) %d-%d\n",
+ h->ip_id, precut, frp->fr_off, frp->fr_end, off,
+ max));
+
+ off += precut;
+ max -= precut;
+ /* Update the previous frag to encompass this one */
+ frp->fr_end = max;
+
+ if (!drop) {
+ /* XXX Optimization opportunity
+ * This is a very heavy way to trim the payload.
+ * we could do it much faster by diddling mbuf
+ * internals but that would be even less legible
+ * than this mbuf magic. For my next trick,
+ * I'll pull a rabbit out of my laptop.
+ */
+#ifdef __FreeBSD__
+ *m0 = m_dup(m, M_DONTWAIT);
+#else
+ *m0 = m_copym2(m, 0, h->ip_hl << 2, M_NOWAIT);
+#endif
+ if (*m0 == NULL)
+ goto no_mem;
+#ifdef __FreeBSD__
+ /* From KAME Project : We have missed this! */
+ m_adj(*m0, (h->ip_hl << 2) -
+ (*m0)->m_pkthdr.len);
+
+ KASSERT(((*m0)->m_next == NULL),
+ ("(*m0)->m_next != NULL: %s",
+ __FUNCTION__));
+#else
+ KASSERT((*m0)->m_next == NULL);
+#endif
+ m_adj(m, precut + (h->ip_hl << 2));
+ m_cat(*m0, m);
+ m = *m0;
+ if (m->m_flags & M_PKTHDR) {
+ int plen = 0;
+ struct mbuf *t;
+ for (t = m; t; t = t->m_next)
+ plen += t->m_len;
+ m->m_pkthdr.len = plen;
+ }
+
+
+ h = mtod(m, struct ip *);
+
+#ifdef __FreeBSD__
+ KASSERT(((int)m->m_len ==
+ ntohs(h->ip_len) - precut),
+ ("m->m_len != ntohs(h->ip_len) - precut: %s",
+ __FUNCTION__));
+#else
+ KASSERT((int)m->m_len ==
+ ntohs(h->ip_len) - precut);
+#endif
+ h->ip_off = htons(ntohs(h->ip_off) +
+ (precut >> 3));
+ h->ip_len = htons(ntohs(h->ip_len) - precut);
+ } else {
+ hosed++;
+ }
+ } else {
+ /* There is a gap between fragments */
+
+ DPFPRINTF(("fragcache[%d]: gap %d (%d-%d) %d-%d\n",
+ h->ip_id, -precut, frp->fr_off, frp->fr_end, off,
+ max));
+
+#ifdef __FreeBSD__
+ cur = pool_get(&V_pf_cent_pl, PR_NOWAIT);
+#else
+ cur = pool_get(&pf_cent_pl, PR_NOWAIT);
+#endif
+ if (cur == NULL)
+ goto no_mem;
+#ifdef __FreeBSD__
+ V_pf_ncache++;
+#else
+ pf_ncache++;
+#endif
+
+ cur->fr_off = off;
+ cur->fr_end = max;
+ LIST_INSERT_AFTER(frp, cur, fr_next);
+ }
+ }
+
+ if (fra != NULL) {
+ int aftercut;
+ int merge = 0;
+
+ aftercut = max - fra->fr_off;
+ if (aftercut == 0) {
+ /* Adjacent fragments */
+ DPFPRINTF(("fragcache[%d]: adjacent %d-%d (%d-%d)\n",
+ h->ip_id, off, max, fra->fr_off, fra->fr_end));
+ fra->fr_off = off;
+ merge = 1;
+ } else if (aftercut > 0) {
+ /* Need to chop off the tail of this fragment */
+ DPFPRINTF(("fragcache[%d]: chop %d %d-%d (%d-%d)\n",
+ h->ip_id, aftercut, off, max, fra->fr_off,
+ fra->fr_end));
+ fra->fr_off = off;
+ max -= aftercut;
+
+ merge = 1;
+
+ if (!drop) {
+ m_adj(m, -aftercut);
+ if (m->m_flags & M_PKTHDR) {
+ int plen = 0;
+ struct mbuf *t;
+ for (t = m; t; t = t->m_next)
+ plen += t->m_len;
+ m->m_pkthdr.len = plen;
+ }
+ h = mtod(m, struct ip *);
+#ifdef __FreeBSD__
+ KASSERT(((int)m->m_len == ntohs(h->ip_len) - aftercut),
+ ("m->m_len != ntohs(h->ip_len) - aftercut: %s",
+ __FUNCTION__));
+#else
+ KASSERT((int)m->m_len ==
+ ntohs(h->ip_len) - aftercut);
+#endif
+ h->ip_len = htons(ntohs(h->ip_len) - aftercut);
+ } else {
+ hosed++;
+ }
+ } else if (frp == NULL) {
+ /* There is a gap between fragments */
+ DPFPRINTF(("fragcache[%d]: gap %d %d-%d (%d-%d)\n",
+ h->ip_id, -aftercut, off, max, fra->fr_off,
+ fra->fr_end));
+
+#ifdef __FreeBSD__
+ cur = pool_get(&V_pf_cent_pl, PR_NOWAIT);
+#else
+ cur = pool_get(&pf_cent_pl, PR_NOWAIT);
+#endif
+ if (cur == NULL)
+ goto no_mem;
+#ifdef __FreeBSD__
+ V_pf_ncache++;
+#else
+ pf_ncache++;
+#endif
+
+ cur->fr_off = off;
+ cur->fr_end = max;
+ LIST_INSERT_BEFORE(fra, cur, fr_next);
+ }
+
+
+ /* Need to glue together two separate fragment descriptors */
+ if (merge) {
+ if (cur && fra->fr_off <= cur->fr_end) {
+ /* Need to merge in a previous 'cur' */
+ DPFPRINTF(("fragcache[%d]: adjacent(merge "
+ "%d-%d) %d-%d (%d-%d)\n",
+ h->ip_id, cur->fr_off, cur->fr_end, off,
+ max, fra->fr_off, fra->fr_end));
+ fra->fr_off = cur->fr_off;
+ LIST_REMOVE(cur, fr_next);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_cent_pl, cur);
+ V_pf_ncache--;
+#else
+ pool_put(&pf_cent_pl, cur);
+ pf_ncache--;
+#endif
+ cur = NULL;
+
+ } else if (frp && fra->fr_off <= frp->fr_end) {
+ /* Need to merge in a modified 'frp' */
+#ifdef __FreeBSD__
+ KASSERT((cur == NULL), ("cur != NULL: %s",
+ __FUNCTION__));
+#else
+ KASSERT(cur == NULL);
+#endif
+ DPFPRINTF(("fragcache[%d]: adjacent(merge "
+ "%d-%d) %d-%d (%d-%d)\n",
+ h->ip_id, frp->fr_off, frp->fr_end, off,
+ max, fra->fr_off, fra->fr_end));
+ fra->fr_off = frp->fr_off;
+ LIST_REMOVE(frp, fr_next);
+#ifdef __FreeBSD__
+ pool_put(&V_pf_cent_pl, frp);
+ V_pf_ncache--;
+#else
+ pool_put(&pf_cent_pl, frp);
+ pf_ncache--;
+#endif
+ frp = NULL;
+
+ }
+ }
+ }
+
+ if (hosed) {
+ /*
+ * We must keep tracking the overall fragment even when
+ * we're going to drop it anyway so that we know when to
+ * free the overall descriptor. Thus we drop the frag late.
+ */
+ goto drop_fragment;
+ }
+
+
+ pass:
+ /* Update maximum data size */
+ if ((*frag)->fr_max < max)
+ (*frag)->fr_max = max;
+
+ /* This is the last segment */
+ if (!mff)
+ (*frag)->fr_flags |= PFFRAG_SEENLAST;
+
+ /* Check if we are completely reassembled */
+ if (((*frag)->fr_flags & PFFRAG_SEENLAST) &&
+ LIST_FIRST(&(*frag)->fr_cache)->fr_off == 0 &&
+ LIST_FIRST(&(*frag)->fr_cache)->fr_end == (*frag)->fr_max) {
+ /* Remove from fragment queue */
+ DPFPRINTF(("fragcache[%d]: done 0-%d\n", h->ip_id,
+ (*frag)->fr_max));
+ pf_free_fragment(*frag);
+ *frag = NULL;
+ }
+
+ return (m);
+
+ no_mem:
+ *nomem = 1;
+
+ /* Still need to pay attention to !IP_MF */
+ if (!mff && *frag != NULL)
+ (*frag)->fr_flags |= PFFRAG_SEENLAST;
+
+ m_freem(m);
+ return (NULL);
+
+ drop_fragment:
+
+ /* Still need to pay attention to !IP_MF */
+ if (!mff && *frag != NULL)
+ (*frag)->fr_flags |= PFFRAG_SEENLAST;
+
+ if (drop) {
+ /* This fragment has been deemed bad. Don't reass */
+ if (((*frag)->fr_flags & PFFRAG_DROP) == 0)
+ DPFPRINTF(("fragcache[%d]: dropping overall fragment\n",
+ h->ip_id));
+ (*frag)->fr_flags |= PFFRAG_DROP;
+ }
+
+ m_freem(m);
+ return (NULL);
+}
+
+#ifdef INET
+int
+pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
+ struct pf_pdesc *pd)
+{
+ struct mbuf *m = *m0;
+ struct pf_rule *r;
+ struct pf_frent *frent;
+ struct pf_fragment *frag = NULL;
+ struct ip *h = mtod(m, struct ip *);
+ int mff = (ntohs(h->ip_off) & IP_MF);
+ int hlen = h->ip_hl << 2;
+ u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
+ u_int16_t max;
+ int ip_len;
+ int ip_off;
+ int tag = -1;
+
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
+ while (r != NULL) {
+ r->evaluations++;
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
+ r = r->skip[PF_SKIP_IFP].ptr;
+ else if (r->direction && r->direction != dir)
+ r = r->skip[PF_SKIP_DIR].ptr;
+ else if (r->af && r->af != AF_INET)
+ r = r->skip[PF_SKIP_AF].ptr;
+ else if (r->proto && r->proto != h->ip_p)
+ r = r->skip[PF_SKIP_PROTO].ptr;
+ else if (PF_MISMATCHAW(&r->src.addr,
+ (struct pf_addr *)&h->ip_src.s_addr, AF_INET,
+ r->src.neg, kif, M_GETFIB(m)))
+ r = r->skip[PF_SKIP_SRC_ADDR].ptr;
+ else if (PF_MISMATCHAW(&r->dst.addr,
+ (struct pf_addr *)&h->ip_dst.s_addr, AF_INET,
+ r->dst.neg, NULL, M_GETFIB(m)))
+ r = r->skip[PF_SKIP_DST_ADDR].ptr;
+#ifdef __FreeBSD__
+ else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
+#else
+ else if (r->match_tag && !pf_match_tag(m, r, &tag))
+#endif
+ r = TAILQ_NEXT(r, entries);
+ else
+ break;
+ }
+
+ if (r == NULL || r->action == PF_NOSCRUB)
+ return (PF_PASS);
+ else {
+ r->packets[dir == PF_OUT]++;
+ r->bytes[dir == PF_OUT] += pd->tot_len;
+ }
+
+ /* Check for illegal packets */
+ if (hlen < (int)sizeof(struct ip))
+ goto drop;
+
+ if (hlen > ntohs(h->ip_len))
+ goto drop;
+
+ /* Clear IP_DF if the rule uses the no-df option */
+ if (r->rule_flag & PFRULE_NODF && h->ip_off & htons(IP_DF)) {
+ u_int16_t ip_off = h->ip_off;
+
+ h->ip_off &= htons(~IP_DF);
+ h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
+ }
+
+ /* We will need other tests here */
+ if (!fragoff && !mff)
+ goto no_fragment;
+
+ /* We're dealing with a fragment now. Don't allow fragments
+ * with IP_DF to enter the cache. If the flag was cleared by
+ * no-df above, fine. Otherwise drop it.
+ */
+ if (h->ip_off & htons(IP_DF)) {
+ DPFPRINTF(("IP_DF\n"));
+ goto bad;
+ }
+
+ ip_len = ntohs(h->ip_len) - hlen;
+ ip_off = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
+
+ /* All fragments are 8 byte aligned */
+ if (mff && (ip_len & 0x7)) {
+ DPFPRINTF(("mff and %d\n", ip_len));
+ goto bad;
+ }
+
+ /* Respect maximum length */
+ if (fragoff + ip_len > IP_MAXPACKET) {
+ DPFPRINTF(("max packet %d\n", fragoff + ip_len));
+ goto bad;
+ }
+ max = fragoff + ip_len;
+
+ if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0) {
+ /* Fully buffer all of the fragments */
+
+#ifdef __FreeBSD__
+ frag = pf_find_fragment(h, &V_pf_frag_tree);
+#else
+ frag = pf_find_fragment(h, &pf_frag_tree);
+#endif
+
+ /* Check if we saw the last fragment already */
+ if (frag != NULL && (frag->fr_flags & PFFRAG_SEENLAST) &&
+ max > frag->fr_max)
+ goto bad;
+
+ /* Get an entry for the fragment queue */
+#ifdef __FreeBSD__
+ frent = pool_get(&V_pf_frent_pl, PR_NOWAIT);
+#else
+ frent = pool_get(&pf_frent_pl, PR_NOWAIT);
+#endif
+ if (frent == NULL) {
+ REASON_SET(reason, PFRES_MEMORY);
+ return (PF_DROP);
+ }
+#ifdef __FreeBSD__
+ V_pf_nfrents++;
+#else
+ pf_nfrents++;
+#endif
+ frent->fr_ip = h;
+ frent->fr_m = m;
+
+ /* Might return a completely reassembled mbuf, or NULL */
+ DPFPRINTF(("reass frag %d @ %d-%d\n", h->ip_id, fragoff, max));
+ *m0 = m = pf_reassemble(m0, &frag, frent, mff);
+
+ if (m == NULL)
+ return (PF_DROP);
+
+ /* use mtag from concatenated mbuf chain */
+ pd->pf_mtag = pf_find_mtag(m);
+#ifdef DIAGNOSTIC
+ if (pd->pf_mtag == NULL) {
+ printf("%s: pf_find_mtag returned NULL(1)\n", __func__);
+ if ((pd->pf_mtag = pf_get_mtag(m)) == NULL) {
+ m_freem(m);
+ *m0 = NULL;
+ goto no_mem;
+ }
+ }
+#endif
+ if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
+ goto drop;
+
+ h = mtod(m, struct ip *);
+ } else {
+ /* non-buffering fragment cache (drops or masks overlaps) */
+ int nomem = 0;
+
+#ifdef __FreeBSD__
+ if (dir == PF_OUT && pd->pf_mtag->flags & PF_TAG_FRAGCACHE) {
+#else
+ if (dir == PF_OUT && m->m_pkthdr.pf.flags & PF_TAG_FRAGCACHE) {
+#endif
+ /*
+ * Already passed the fragment cache in the
+ * input direction. If we continued, it would
+ * appear to be a dup and would be dropped.
+ */
+ goto fragment_pass;
+ }
+
+#ifdef __FreeBSD__
+ frag = pf_find_fragment(h, &V_pf_cache_tree);
+#else
+ frag = pf_find_fragment(h, &pf_cache_tree);
+#endif
+
+ /* Check if we saw the last fragment already */
+ if (frag != NULL && (frag->fr_flags & PFFRAG_SEENLAST) &&
+ max > frag->fr_max) {
+ if (r->rule_flag & PFRULE_FRAGDROP)
+ frag->fr_flags |= PFFRAG_DROP;
+ goto bad;
+ }
+
+ *m0 = m = pf_fragcache(m0, h, &frag, mff,
+ (r->rule_flag & PFRULE_FRAGDROP) ? 1 : 0, &nomem);
+ if (m == NULL) {
+ if (nomem)
+ goto no_mem;
+ goto drop;
+ }
+
+ /* use mtag from copied and trimmed mbuf chain */
+ pd->pf_mtag = pf_find_mtag(m);
+#ifdef DIAGNOSTIC
+ if (pd->pf_mtag == NULL) {
+ printf("%s: pf_find_mtag returned NULL(2)\n", __func__);
+ if ((pd->pf_mtag = pf_get_mtag(m)) == NULL) {
+ m_freem(m);
+ *m0 = NULL;
+ goto no_mem;
+ }
+ }
+#endif
+ if (dir == PF_IN)
+#ifdef __FreeBSD__
+ pd->pf_mtag->flags |= PF_TAG_FRAGCACHE;
+#else
+ m->m_pkthdr.pf.flags |= PF_TAG_FRAGCACHE;
+#endif
+
+ if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
+ goto drop;
+ goto fragment_pass;
+ }
+
+ no_fragment:
+ /* At this point, only IP_DF is allowed in ip_off */
+ if (h->ip_off & ~htons(IP_DF)) {
+ u_int16_t ip_off = h->ip_off;
+
+ h->ip_off &= htons(IP_DF);
+ h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
+ }
+
+ /* not missing a return here */
+
+ fragment_pass:
+ pf_scrub_ip(&m, r->rule_flag, r->min_ttl, r->set_tos);
+
+ if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
+ pd->flags |= PFDESC_IP_REAS;
+ return (PF_PASS);
+
+ no_mem:
+ REASON_SET(reason, PFRES_MEMORY);
+ if (r != NULL && r->log)
+ PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
+ return (PF_DROP);
+
+ drop:
+ REASON_SET(reason, PFRES_NORM);
+ if (r != NULL && r->log)
+ PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
+ return (PF_DROP);
+
+ bad:
+ DPFPRINTF(("dropping bad fragment\n"));
+
+ /* Free associated fragments */
+ if (frag != NULL)
+ pf_free_fragment(frag);
+
+ REASON_SET(reason, PFRES_FRAG);
+ if (r != NULL && r->log)
+ PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
+
+ return (PF_DROP);
+}
+#endif
+
+#ifdef INET6
+int
+pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
+ u_short *reason, struct pf_pdesc *pd)
+{
+ struct mbuf *m = *m0;
+ struct pf_rule *r;
+ struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
+ int off;
+ struct ip6_ext ext;
+ struct ip6_opt opt;
+ struct ip6_opt_jumbo jumbo;
+ struct ip6_frag frag;
+ u_int32_t jumbolen = 0, plen;
+ u_int16_t fragoff = 0;
+ int optend;
+ int ooff;
+ u_int8_t proto;
+ int terminal;
+
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
+ while (r != NULL) {
+ r->evaluations++;
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
+ r = r->skip[PF_SKIP_IFP].ptr;
+ else if (r->direction && r->direction != dir)
+ r = r->skip[PF_SKIP_DIR].ptr;
+ else if (r->af && r->af != AF_INET6)
+ r = r->skip[PF_SKIP_AF].ptr;
+#if 0 /* header chain! */
+ else if (r->proto && r->proto != h->ip6_nxt)
+ r = r->skip[PF_SKIP_PROTO].ptr;
+#endif
+ else if (PF_MISMATCHAW(&r->src.addr,
+ (struct pf_addr *)&h->ip6_src, AF_INET6,
+ r->src.neg, kif, M_GETFIB(m)))
+ r = r->skip[PF_SKIP_SRC_ADDR].ptr;
+ else if (PF_MISMATCHAW(&r->dst.addr,
+ (struct pf_addr *)&h->ip6_dst, AF_INET6,
+ r->dst.neg, NULL, M_GETFIB(m)))
+ r = r->skip[PF_SKIP_DST_ADDR].ptr;
+ else
+ break;
+ }
+
+ if (r == NULL || r->action == PF_NOSCRUB)
+ return (PF_PASS);
+ else {
+ r->packets[dir == PF_OUT]++;
+ r->bytes[dir == PF_OUT] += pd->tot_len;
+ }
+
+ /* Check for illegal packets */
+ if (sizeof(struct ip6_hdr) + IPV6_MAXPACKET < m->m_pkthdr.len)
+ goto drop;
+
+ off = sizeof(struct ip6_hdr);
+ proto = h->ip6_nxt;
+ terminal = 0;
+ do {
+ switch (proto) {
+ case IPPROTO_FRAGMENT:
+ goto fragment;
+ break;
+ case IPPROTO_AH:
+ case IPPROTO_ROUTING:
+ case IPPROTO_DSTOPTS:
+ if (!pf_pull_hdr(m, off, &ext, sizeof(ext), NULL,
+ NULL, AF_INET6))
+ goto shortpkt;
+ if (proto == IPPROTO_AH)
+ off += (ext.ip6e_len + 2) * 4;
+ else
+ off += (ext.ip6e_len + 1) * 8;
+ proto = ext.ip6e_nxt;
+ break;
+ case IPPROTO_HOPOPTS:
+ if (!pf_pull_hdr(m, off, &ext, sizeof(ext), NULL,
+ NULL, AF_INET6))
+ goto shortpkt;
+ optend = off + (ext.ip6e_len + 1) * 8;
+ ooff = off + sizeof(ext);
+ do {
+ if (!pf_pull_hdr(m, ooff, &opt.ip6o_type,
+ sizeof(opt.ip6o_type), NULL, NULL,
+ AF_INET6))
+ goto shortpkt;
+ if (opt.ip6o_type == IP6OPT_PAD1) {
+ ooff++;
+ continue;
+ }
+ if (!pf_pull_hdr(m, ooff, &opt, sizeof(opt),
+ NULL, NULL, AF_INET6))
+ goto shortpkt;
+ if (ooff + sizeof(opt) + opt.ip6o_len > optend)
+ goto drop;
+ switch (opt.ip6o_type) {
+ case IP6OPT_JUMBO:
+ if (h->ip6_plen != 0)
+ goto drop;
+ if (!pf_pull_hdr(m, ooff, &jumbo,
+ sizeof(jumbo), NULL, NULL,
+ AF_INET6))
+ goto shortpkt;
+ memcpy(&jumbolen, jumbo.ip6oj_jumbo_len,
+ sizeof(jumbolen));
+ jumbolen = ntohl(jumbolen);
+ if (jumbolen <= IPV6_MAXPACKET)
+ goto drop;
+ if (sizeof(struct ip6_hdr) + jumbolen !=
+ m->m_pkthdr.len)
+ goto drop;
+ break;
+ default:
+ break;
+ }
+ ooff += sizeof(opt) + opt.ip6o_len;
+ } while (ooff < optend);
+
+ off = optend;
+ proto = ext.ip6e_nxt;
+ break;
+ default:
+ terminal = 1;
+ break;
+ }
+ } while (!terminal);
+
+ /* jumbo payload option must be present, or plen > 0 */
+ if (ntohs(h->ip6_plen) == 0)
+ plen = jumbolen;
+ else
+ plen = ntohs(h->ip6_plen);
+ if (plen == 0)
+ goto drop;
+ if (sizeof(struct ip6_hdr) + plen > m->m_pkthdr.len)
+ goto shortpkt;
+
+ pf_scrub_ip6(&m, r->min_ttl);
+
+ return (PF_PASS);
+
+ fragment:
+ if (ntohs(h->ip6_plen) == 0 || jumbolen)
+ goto drop;
+ plen = ntohs(h->ip6_plen);
+
+ if (!pf_pull_hdr(m, off, &frag, sizeof(frag), NULL, NULL, AF_INET6))
+ goto shortpkt;
+ fragoff = ntohs(frag.ip6f_offlg & IP6F_OFF_MASK);
+ if (fragoff + (plen - off - sizeof(frag)) > IPV6_MAXPACKET)
+ goto badfrag;
+
+ /* do something about it */
+ /* remember to set pd->flags |= PFDESC_IP_REAS */
+ return (PF_PASS);
+
+ shortpkt:
+ REASON_SET(reason, PFRES_SHORT);
+ if (r != NULL && r->log)
+ PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
+ return (PF_DROP);
+
+ drop:
+ REASON_SET(reason, PFRES_NORM);
+ if (r != NULL && r->log)
+ PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
+ return (PF_DROP);
+
+ badfrag:
+ REASON_SET(reason, PFRES_FRAG);
+ if (r != NULL && r->log)
+ PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
+ return (PF_DROP);
+}
+#endif /* INET6 */
+
+int
+pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
+ int off, void *h, struct pf_pdesc *pd)
+{
+ struct pf_rule *r, *rm = NULL;
+ struct tcphdr *th = pd->hdr.tcp;
+ int rewrite = 0;
+ u_short reason;
+ u_int8_t flags;
+ sa_family_t af = pd->af;
+
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
+ while (r != NULL) {
+ r->evaluations++;
+ if (pfi_kif_match(r->kif, kif) == r->ifnot)
+ r = r->skip[PF_SKIP_IFP].ptr;
+ else if (r->direction && r->direction != dir)
+ r = r->skip[PF_SKIP_DIR].ptr;
+ else if (r->af && r->af != af)
+ r = r->skip[PF_SKIP_AF].ptr;
+ else if (r->proto && r->proto != pd->proto)
+ r = r->skip[PF_SKIP_PROTO].ptr;
+ else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
+ r->src.neg, kif, M_GETFIB(m)))
+ r = r->skip[PF_SKIP_SRC_ADDR].ptr;
+ else if (r->src.port_op && !pf_match_port(r->src.port_op,
+ r->src.port[0], r->src.port[1], th->th_sport))
+ r = r->skip[PF_SKIP_SRC_PORT].ptr;
+ else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
+ r->dst.neg, NULL, M_GETFIB(m)))
+ r = r->skip[PF_SKIP_DST_ADDR].ptr;
+ else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
+ r->dst.port[0], r->dst.port[1], th->th_dport))
+ r = r->skip[PF_SKIP_DST_PORT].ptr;
+ else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
+ pf_osfp_fingerprint(pd, m, off, th),
+ r->os_fingerprint))
+ r = TAILQ_NEXT(r, entries);
+ else {
+ rm = r;
+ break;
+ }
+ }
+
+ if (rm == NULL || rm->action == PF_NOSCRUB)
+ return (PF_PASS);
+ else {
+ r->packets[dir == PF_OUT]++;
+ r->bytes[dir == PF_OUT] += pd->tot_len;
+ }
+
+ if (rm->rule_flag & PFRULE_REASSEMBLE_TCP)
+ pd->flags |= PFDESC_TCP_NORM;
+
+ flags = th->th_flags;
+ if (flags & TH_SYN) {
+ /* Illegal packet */
+ if (flags & TH_RST)
+ goto tcp_drop;
+
+ if (flags & TH_FIN)
+ flags &= ~TH_FIN;
+ } else {
+ /* Illegal packet */
+ if (!(flags & (TH_ACK|TH_RST)))
+ goto tcp_drop;
+ }
+
+ if (!(flags & TH_ACK)) {
+ /* These flags are only valid if ACK is set */
+ if ((flags & TH_FIN) || (flags & TH_PUSH) || (flags & TH_URG))
+ goto tcp_drop;
+ }
+
+ /* Check for illegal header length */
+ if (th->th_off < (sizeof(struct tcphdr) >> 2))
+ goto tcp_drop;
+
+ /* If flags changed, or reserved data set, then adjust */
+ if (flags != th->th_flags || th->th_x2 != 0) {
+ u_int16_t ov, nv;
+
+ ov = *(u_int16_t *)(&th->th_ack + 1);
+ th->th_flags = flags;
+ th->th_x2 = 0;
+ nv = *(u_int16_t *)(&th->th_ack + 1);
+
+ th->th_sum = pf_cksum_fixup(th->th_sum, ov, nv, 0);
+ rewrite = 1;
+ }
+
+ /* Remove urgent pointer, if TH_URG is not set */
+ if (!(flags & TH_URG) && th->th_urp) {
+ th->th_sum = pf_cksum_fixup(th->th_sum, th->th_urp, 0, 0);
+ th->th_urp = 0;
+ rewrite = 1;
+ }
+
+ /* Process options */
+ if (r->max_mss && pf_normalize_tcpopt(r, m, th, off, pd->af))
+ rewrite = 1;
+
+ /* copy back packet headers if we sanitized */
+ if (rewrite)
+#ifdef __FreeBSD__
+ m_copyback(m, off, sizeof(*th), (caddr_t)th);
+#else
+ m_copyback(m, off, sizeof(*th), th);
+#endif
+
+ return (PF_PASS);
+
+ tcp_drop:
+ REASON_SET(&reason, PFRES_NORM);
+ if (rm != NULL && r->log)
+ PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, NULL, NULL, pd);
+ return (PF_DROP);
+}
+
+int
+pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
+ struct tcphdr *th, struct pf_state_peer *src, struct pf_state_peer *dst)
+{
+ u_int32_t tsval, tsecr;
+ u_int8_t hdr[60];
+ u_int8_t *opt;
+
+#ifdef __FreeBSD__
+ KASSERT((src->scrub == NULL),
+ ("pf_normalize_tcp_init: src->scrub != NULL"));
+
+ src->scrub = pool_get(&V_pf_state_scrub_pl, PR_NOWAIT);
+#else
+ KASSERT(src->scrub == NULL);
+
+ src->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT);
+#endif
+ if (src->scrub == NULL)
+ return (1);
+ bzero(src->scrub, sizeof(*src->scrub));
+
+ switch (pd->af) {
+#ifdef INET
+ case AF_INET: {
+ struct ip *h = mtod(m, struct ip *);
+ src->scrub->pfss_ttl = h->ip_ttl;
+ break;
+ }
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6: {
+ struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
+ src->scrub->pfss_ttl = h->ip6_hlim;
+ break;
+ }
+#endif /* INET6 */
+ }
+
+
+ /*
+ * All normalizations below are only begun if we see the start of
+ * the connections. They must all set an enabled bit in pfss_flags
+ */
+ if ((th->th_flags & TH_SYN) == 0)
+ return (0);
+
+
+ if (th->th_off > (sizeof(struct tcphdr) >> 2) && src->scrub &&
+ pf_pull_hdr(m, off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
+ /* Diddle with TCP options */
+ int hlen;
+ opt = hdr + sizeof(struct tcphdr);
+ hlen = (th->th_off << 2) - sizeof(struct tcphdr);
+ while (hlen >= TCPOLEN_TIMESTAMP) {
+ switch (*opt) {
+ case TCPOPT_EOL: /* FALLTHROUGH */
+ case TCPOPT_NOP:
+ opt++;
+ hlen--;
+ break;
+ case TCPOPT_TIMESTAMP:
+ if (opt[1] >= TCPOLEN_TIMESTAMP) {
+ src->scrub->pfss_flags |=
+ PFSS_TIMESTAMP;
+ src->scrub->pfss_ts_mod =
+ htonl(arc4random());
+
+ /* note PFSS_PAWS not set yet */
+ memcpy(&tsval, &opt[2],
+ sizeof(u_int32_t));
+ memcpy(&tsecr, &opt[6],
+ sizeof(u_int32_t));
+ src->scrub->pfss_tsval0 = ntohl(tsval);
+ src->scrub->pfss_tsval = ntohl(tsval);
+ src->scrub->pfss_tsecr = ntohl(tsecr);
+ getmicrouptime(&src->scrub->pfss_last);
+ }
+ /* FALLTHROUGH */
+ default:
+ hlen -= MAX(opt[1], 2);
+ opt += MAX(opt[1], 2);
+ break;
+ }
+ }
+ }
+
+ return (0);
+}
+
+void
+pf_normalize_tcp_cleanup(struct pf_state *state)
+{
+#ifdef __FreeBSD__
+ if (state->src.scrub)
+ pool_put(&V_pf_state_scrub_pl, state->src.scrub);
+ if (state->dst.scrub)
+ pool_put(&V_pf_state_scrub_pl, state->dst.scrub);
+#else
+ if (state->src.scrub)
+ pool_put(&pf_state_scrub_pl, state->src.scrub);
+ if (state->dst.scrub)
+ pool_put(&pf_state_scrub_pl, state->dst.scrub);
+#endif
+
+ /* Someday... flush the TCP segment reassembly descriptors. */
+}
+
+int
+pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
+ u_short *reason, struct tcphdr *th, struct pf_state *state,
+ struct pf_state_peer *src, struct pf_state_peer *dst, int *writeback)
+{
+ struct timeval uptime;
+ u_int32_t tsval, tsecr;
+ u_int tsval_from_last;
+ u_int8_t hdr[60];
+ u_int8_t *opt;
+ int copyback = 0;
+ int got_ts = 0;
+
+#ifdef __FreeBSD__
+ KASSERT((src->scrub || dst->scrub),
+ ("pf_normalize_tcp_statefull: src->scrub && dst->scrub!"));
+#else
+ KASSERT(src->scrub || dst->scrub);
+#endif
+
+ /*
+ * Enforce the minimum TTL seen for this connection. Negate a common
+ * technique to evade an intrusion detection system and confuse
+ * firewall state code.
+ */
+ switch (pd->af) {
+#ifdef INET
+ case AF_INET: {
+ if (src->scrub) {
+ struct ip *h = mtod(m, struct ip *);
+ if (h->ip_ttl > src->scrub->pfss_ttl)
+ src->scrub->pfss_ttl = h->ip_ttl;
+ h->ip_ttl = src->scrub->pfss_ttl;
+ }
+ break;
+ }
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6: {
+ if (src->scrub) {
+ struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
+ if (h->ip6_hlim > src->scrub->pfss_ttl)
+ src->scrub->pfss_ttl = h->ip6_hlim;
+ h->ip6_hlim = src->scrub->pfss_ttl;
+ }
+ break;
+ }
+#endif /* INET6 */
+ }
+
+ if (th->th_off > (sizeof(struct tcphdr) >> 2) &&
+ ((src->scrub && (src->scrub->pfss_flags & PFSS_TIMESTAMP)) ||
+ (dst->scrub && (dst->scrub->pfss_flags & PFSS_TIMESTAMP))) &&
+ pf_pull_hdr(m, off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
+ /* Diddle with TCP options */
+ int hlen;
+ opt = hdr + sizeof(struct tcphdr);
+ hlen = (th->th_off << 2) - sizeof(struct tcphdr);
+ while (hlen >= TCPOLEN_TIMESTAMP) {
+ switch (*opt) {
+ case TCPOPT_EOL: /* FALLTHROUGH */
+ case TCPOPT_NOP:
+ opt++;
+ hlen--;
+ break;
+ case TCPOPT_TIMESTAMP:
+ /* Modulate the timestamps. Can be used for
+ * NAT detection, OS uptime determination or
+ * reboot detection.
+ */
+
+ if (got_ts) {
+ /* Huh? Multiple timestamps!? */
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ DPFPRINTF(("multiple TS??"));
+ pf_print_state(state);
+ printf("\n");
+ }
+ REASON_SET(reason, PFRES_TS);
+ return (PF_DROP);
+ }
+ if (opt[1] >= TCPOLEN_TIMESTAMP) {
+ memcpy(&tsval, &opt[2],
+ sizeof(u_int32_t));
+ if (tsval && src->scrub &&
+ (src->scrub->pfss_flags &
+ PFSS_TIMESTAMP)) {
+ tsval = ntohl(tsval);
+ pf_change_a(&opt[2],
+ &th->th_sum,
+ htonl(tsval +
+ src->scrub->pfss_ts_mod),
+ 0);
+ copyback = 1;
+ }
+
+ /* Modulate TS reply iff valid (!0) */
+ memcpy(&tsecr, &opt[6],
+ sizeof(u_int32_t));
+ if (tsecr && dst->scrub &&
+ (dst->scrub->pfss_flags &
+ PFSS_TIMESTAMP)) {
+ tsecr = ntohl(tsecr)
+ - dst->scrub->pfss_ts_mod;
+ pf_change_a(&opt[6],
+ &th->th_sum, htonl(tsecr),
+ 0);
+ copyback = 1;
+ }
+ got_ts = 1;
+ }
+ /* FALLTHROUGH */
+ default:
+ hlen -= MAX(opt[1], 2);
+ opt += MAX(opt[1], 2);
+ break;
+ }
+ }
+ if (copyback) {
+ /* Copyback the options, caller copys back header */
+ *writeback = 1;
+ m_copyback(m, off + sizeof(struct tcphdr),
+ (th->th_off << 2) - sizeof(struct tcphdr), hdr +
+ sizeof(struct tcphdr));
+ }
+ }
+
+
+ /*
+ * Must invalidate PAWS checks on connections idle for too long.
+ * The fastest allowed timestamp clock is 1ms. That turns out to
+ * be about 24 days before it wraps. XXX Right now our lowerbound
+ * TS echo check only works for the first 12 days of a connection
+ * when the TS has exhausted half its 32bit space
+ */
+#define TS_MAX_IDLE (24*24*60*60)
+#define TS_MAX_CONN (12*24*60*60) /* XXX remove when better tsecr check */
+
+ getmicrouptime(&uptime);
+ if (src->scrub && (src->scrub->pfss_flags & PFSS_PAWS) &&
+ (uptime.tv_sec - src->scrub->pfss_last.tv_sec > TS_MAX_IDLE ||
+ time_second - state->creation > TS_MAX_CONN)) {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ DPFPRINTF(("src idled out of PAWS\n"));
+ pf_print_state(state);
+ printf("\n");
+ }
+ src->scrub->pfss_flags = (src->scrub->pfss_flags & ~PFSS_PAWS)
+ | PFSS_PAWS_IDLED;
+ }
+ if (dst->scrub && (dst->scrub->pfss_flags & PFSS_PAWS) &&
+ uptime.tv_sec - dst->scrub->pfss_last.tv_sec > TS_MAX_IDLE) {
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ DPFPRINTF(("dst idled out of PAWS\n"));
+ pf_print_state(state);
+ printf("\n");
+ }
+ dst->scrub->pfss_flags = (dst->scrub->pfss_flags & ~PFSS_PAWS)
+ | PFSS_PAWS_IDLED;
+ }
+
+ if (got_ts && src->scrub && dst->scrub &&
+ (src->scrub->pfss_flags & PFSS_PAWS) &&
+ (dst->scrub->pfss_flags & PFSS_PAWS)) {
+ /* Validate that the timestamps are "in-window".
+ * RFC1323 describes TCP Timestamp options that allow
+ * measurement of RTT (round trip time) and PAWS
+ * (protection against wrapped sequence numbers). PAWS
+ * gives us a set of rules for rejecting packets on
+ * long fat pipes (packets that were somehow delayed
+ * in transit longer than the time it took to send the
+ * full TCP sequence space of 4Gb). We can use these
+ * rules and infer a few others that will let us treat
+ * the 32bit timestamp and the 32bit echoed timestamp
+ * as sequence numbers to prevent a blind attacker from
+ * inserting packets into a connection.
+ *
+ * RFC1323 tells us:
+ * - The timestamp on this packet must be greater than
+ * or equal to the last value echoed by the other
+ * endpoint. The RFC says those will be discarded
+ * since it is a dup that has already been acked.
+ * This gives us a lowerbound on the timestamp.
+ * timestamp >= other last echoed timestamp
+ * - The timestamp will be less than or equal to
+ * the last timestamp plus the time between the
+ * last packet and now. The RFC defines the max
+ * clock rate as 1ms. We will allow clocks to be
+ * up to 10% fast and will allow a total difference
+ * or 30 seconds due to a route change. And this
+ * gives us an upperbound on the timestamp.
+ * timestamp <= last timestamp + max ticks
+ * We have to be careful here. Windows will send an
+ * initial timestamp of zero and then initialize it
+ * to a random value after the 3whs; presumably to
+ * avoid a DoS by having to call an expensive RNG
+ * during a SYN flood. Proof MS has at least one
+ * good security geek.
+ *
+ * - The TCP timestamp option must also echo the other
+ * endpoints timestamp. The timestamp echoed is the
+ * one carried on the earliest unacknowledged segment
+ * on the left edge of the sequence window. The RFC
+ * states that the host will reject any echoed
+ * timestamps that were larger than any ever sent.
+ * This gives us an upperbound on the TS echo.
+ * tescr <= largest_tsval
+ * - The lowerbound on the TS echo is a little more
+ * tricky to determine. The other endpoint's echoed
+ * values will not decrease. But there may be
+ * network conditions that re-order packets and
+ * cause our view of them to decrease. For now the
+ * only lowerbound we can safely determine is that
+ * the TS echo will never be less than the original
+ * TS. XXX There is probably a better lowerbound.
+ * Remove TS_MAX_CONN with better lowerbound check.
+ * tescr >= other original TS
+ *
+ * It is also important to note that the fastest
+ * timestamp clock of 1ms will wrap its 32bit space in
+ * 24 days. So we just disable TS checking after 24
+ * days of idle time. We actually must use a 12d
+ * connection limit until we can come up with a better
+ * lowerbound to the TS echo check.
+ */
+ struct timeval delta_ts;
+ int ts_fudge;
+
+
+ /*
+ * PFTM_TS_DIFF is how many seconds of leeway to allow
+ * a host's timestamp. This can happen if the previous
+ * packet got delayed in transit for much longer than
+ * this packet.
+ */
+ if ((ts_fudge = state->rule.ptr->timeout[PFTM_TS_DIFF]) == 0)
+#ifdef __FreeBSD__
+ ts_fudge = V_pf_default_rule.timeout[PFTM_TS_DIFF];
+#else
+ ts_fudge = pf_default_rule.timeout[PFTM_TS_DIFF];
+#endif
+
+
+ /* Calculate max ticks since the last timestamp */
+#define TS_MAXFREQ 1100 /* RFC max TS freq of 1Khz + 10% skew */
+#define TS_MICROSECS 1000000 /* microseconds per second */
+#ifdef __FreeBSD__
+#ifndef timersub
+#define timersub(tvp, uvp, vvp) \
+ do { \
+ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
+ if ((vvp)->tv_usec < 0) { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_usec += 1000000; \
+ } \
+ } while (0)
+#endif
+#endif
+ timersub(&uptime, &src->scrub->pfss_last, &delta_ts);
+ tsval_from_last = (delta_ts.tv_sec + ts_fudge) * TS_MAXFREQ;
+ tsval_from_last += delta_ts.tv_usec / (TS_MICROSECS/TS_MAXFREQ);
+
+
+ if ((src->state >= TCPS_ESTABLISHED &&
+ dst->state >= TCPS_ESTABLISHED) &&
+ (SEQ_LT(tsval, dst->scrub->pfss_tsecr) ||
+ SEQ_GT(tsval, src->scrub->pfss_tsval + tsval_from_last) ||
+ (tsecr && (SEQ_GT(tsecr, dst->scrub->pfss_tsval) ||
+ SEQ_LT(tsecr, dst->scrub->pfss_tsval0))))) {
+ /* Bad RFC1323 implementation or an insertion attack.
+ *
+ * - Solaris 2.6 and 2.7 are known to send another ACK
+ * after the FIN,FIN|ACK,ACK closing that carries
+ * an old timestamp.
+ */
+
+ DPFPRINTF(("Timestamp failed %c%c%c%c\n",
+ SEQ_LT(tsval, dst->scrub->pfss_tsecr) ? '0' : ' ',
+ SEQ_GT(tsval, src->scrub->pfss_tsval +
+ tsval_from_last) ? '1' : ' ',
+ SEQ_GT(tsecr, dst->scrub->pfss_tsval) ? '2' : ' ',
+ SEQ_LT(tsecr, dst->scrub->pfss_tsval0)? '3' : ' '));
+#ifdef __FreeBSD__
+ DPFPRINTF((" tsval: %u tsecr: %u +ticks: %u "
+ "idle: %jus %lums\n",
+ tsval, tsecr, tsval_from_last,
+ (uintmax_t)delta_ts.tv_sec,
+ delta_ts.tv_usec / 1000));
+ DPFPRINTF((" src->tsval: %u tsecr: %u\n",
+ src->scrub->pfss_tsval, src->scrub->pfss_tsecr));
+ DPFPRINTF((" dst->tsval: %u tsecr: %u tsval0: %u"
+ "\n", dst->scrub->pfss_tsval,
+ dst->scrub->pfss_tsecr, dst->scrub->pfss_tsval0));
+#else
+ DPFPRINTF((" tsval: %lu tsecr: %lu +ticks: %lu "
+ "idle: %lus %lums\n",
+ tsval, tsecr, tsval_from_last, delta_ts.tv_sec,
+ delta_ts.tv_usec / 1000));
+ DPFPRINTF((" src->tsval: %lu tsecr: %lu\n",
+ src->scrub->pfss_tsval, src->scrub->pfss_tsecr));
+ DPFPRINTF((" dst->tsval: %lu tsecr: %lu tsval0: %lu"
+ "\n", dst->scrub->pfss_tsval,
+ dst->scrub->pfss_tsecr, dst->scrub->pfss_tsval0));
+#endif
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ pf_print_state(state);
+ pf_print_flags(th->th_flags);
+ printf("\n");
+ }
+ REASON_SET(reason, PFRES_TS);
+ return (PF_DROP);
+ }
+
+ /* XXX I'd really like to require tsecr but it's optional */
+
+ } else if (!got_ts && (th->th_flags & TH_RST) == 0 &&
+ ((src->state == TCPS_ESTABLISHED && dst->state == TCPS_ESTABLISHED)
+ || pd->p_len > 0 || (th->th_flags & TH_SYN)) &&
+ src->scrub && dst->scrub &&
+ (src->scrub->pfss_flags & PFSS_PAWS) &&
+ (dst->scrub->pfss_flags & PFSS_PAWS)) {
+ /* Didn't send a timestamp. Timestamps aren't really useful
+ * when:
+ * - connection opening or closing (often not even sent).
+ * but we must not let an attacker to put a FIN on a
+ * data packet to sneak it through our ESTABLISHED check.
+ * - on a TCP reset. RFC suggests not even looking at TS.
+ * - on an empty ACK. The TS will not be echoed so it will
+ * probably not help keep the RTT calculation in sync and
+ * there isn't as much danger when the sequence numbers
+ * got wrapped. So some stacks don't include TS on empty
+ * ACKs :-(
+ *
+ * To minimize the disruption to mostly RFC1323 conformant
+ * stacks, we will only require timestamps on data packets.
+ *
+ * And what do ya know, we cannot require timestamps on data
+ * packets. There appear to be devices that do legitimate
+ * TCP connection hijacking. There are HTTP devices that allow
+ * a 3whs (with timestamps) and then buffer the HTTP request.
+ * If the intermediate device has the HTTP response cache, it
+ * will spoof the response but not bother timestamping its
+ * packets. So we can look for the presence of a timestamp in
+ * the first data packet and if there, require it in all future
+ * packets.
+ */
+
+ if (pd->p_len > 0 && (src->scrub->pfss_flags & PFSS_DATA_TS)) {
+ /*
+ * Hey! Someone tried to sneak a packet in. Or the
+ * stack changed its RFC1323 behavior?!?!
+ */
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC) {
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+#endif
+ DPFPRINTF(("Did not receive expected RFC1323 "
+ "timestamp\n"));
+ pf_print_state(state);
+ pf_print_flags(th->th_flags);
+ printf("\n");
+ }
+ REASON_SET(reason, PFRES_TS);
+ return (PF_DROP);
+ }
+ }
+
+
+ /*
+ * We will note if a host sends his data packets with or without
+ * timestamps. And require all data packets to contain a timestamp
+ * if the first does. PAWS implicitly requires that all data packets be
+ * timestamped. But I think there are middle-man devices that hijack
+ * TCP streams immediately after the 3whs and don't timestamp their
+ * packets (seen in a WWW accelerator or cache).
+ */
+ if (pd->p_len > 0 && src->scrub && (src->scrub->pfss_flags &
+ (PFSS_TIMESTAMP|PFSS_DATA_TS|PFSS_DATA_NOTS)) == PFSS_TIMESTAMP) {
+ if (got_ts)
+ src->scrub->pfss_flags |= PFSS_DATA_TS;
+ else {
+ src->scrub->pfss_flags |= PFSS_DATA_NOTS;
+#ifdef __FreeBSD__
+ if (V_pf_status.debug >= PF_DEBUG_MISC && dst->scrub &&
+#else
+ if (pf_status.debug >= PF_DEBUG_MISC && dst->scrub &&
+#endif
+ (dst->scrub->pfss_flags & PFSS_TIMESTAMP)) {
+ /* Don't warn if other host rejected RFC1323 */
+ DPFPRINTF(("Broken RFC1323 stack did not "
+ "timestamp data packet. Disabled PAWS "
+ "security.\n"));
+ pf_print_state(state);
+ pf_print_flags(th->th_flags);
+ printf("\n");
+ }
+ }
+ }
+
+
+ /*
+ * Update PAWS values
+ */
+ if (got_ts && src->scrub && PFSS_TIMESTAMP == (src->scrub->pfss_flags &
+ (PFSS_PAWS_IDLED|PFSS_TIMESTAMP))) {
+ getmicrouptime(&src->scrub->pfss_last);
+ if (SEQ_GEQ(tsval, src->scrub->pfss_tsval) ||
+ (src->scrub->pfss_flags & PFSS_PAWS) == 0)
+ src->scrub->pfss_tsval = tsval;
+
+ if (tsecr) {
+ if (SEQ_GEQ(tsecr, src->scrub->pfss_tsecr) ||
+ (src->scrub->pfss_flags & PFSS_PAWS) == 0)
+ src->scrub->pfss_tsecr = tsecr;
+
+ if ((src->scrub->pfss_flags & PFSS_PAWS) == 0 &&
+ (SEQ_LT(tsval, src->scrub->pfss_tsval0) ||
+ src->scrub->pfss_tsval0 == 0)) {
+ /* tsval0 MUST be the lowest timestamp */
+ src->scrub->pfss_tsval0 = tsval;
+ }
+
+ /* Only fully initialized after a TS gets echoed */
+ if ((src->scrub->pfss_flags & PFSS_PAWS) == 0)
+ src->scrub->pfss_flags |= PFSS_PAWS;
+ }
+ }
+
+ /* I have a dream.... TCP segment reassembly.... */
+ return (0);
+}
+
+int
+pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
+ int off, sa_family_t af)
+{
+ u_int16_t *mss;
+ int thoff;
+ int opt, cnt, optlen = 0;
+ int rewrite = 0;
+#ifdef __FreeBSD__
+ u_char opts[TCP_MAXOLEN];
+#else
+ u_char opts[MAX_TCPOPTLEN];
+#endif
+ u_char *optp = opts;
+
+ thoff = th->th_off << 2;
+ cnt = thoff - sizeof(struct tcphdr);
+
+ if (cnt > 0 && !pf_pull_hdr(m, off + sizeof(*th), opts, cnt,
+ NULL, NULL, af))
+ return (rewrite);
+
+ for (; cnt > 0; cnt -= optlen, optp += optlen) {
+ opt = optp[0];
+ if (opt == TCPOPT_EOL)
+ break;
+ if (opt == TCPOPT_NOP)
+ optlen = 1;
+ else {
+ if (cnt < 2)
+ break;
+ optlen = optp[1];
+ if (optlen < 2 || optlen > cnt)
+ break;
+ }
+ switch (opt) {
+ case TCPOPT_MAXSEG:
+ mss = (u_int16_t *)(optp + 2);
+ if ((ntohs(*mss)) > r->max_mss) {
+ th->th_sum = pf_cksum_fixup(th->th_sum,
+ *mss, htons(r->max_mss), 0);
+ *mss = htons(r->max_mss);
+ rewrite = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (rewrite)
+ m_copyback(m, off + sizeof(*th), thoff - sizeof(*th), opts);
+
+ return (rewrite);
+}
+
+void
+pf_scrub_ip(struct mbuf **m0, u_int32_t flags, u_int8_t min_ttl, u_int8_t tos)
+{
+ struct mbuf *m = *m0;
+ struct ip *h = mtod(m, struct ip *);
+
+ /* Clear IP_DF if no-df was requested */
+ if (flags & PFRULE_NODF && h->ip_off & htons(IP_DF)) {
+ u_int16_t ip_off = h->ip_off;
+
+ h->ip_off &= htons(~IP_DF);
+ h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
+ }
+
+ /* Enforce a minimum ttl, may cause endless packet loops */
+ if (min_ttl && h->ip_ttl < min_ttl) {
+ u_int16_t ip_ttl = h->ip_ttl;
+
+ h->ip_ttl = min_ttl;
+ h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
+ }
+
+ /* Enforce tos */
+ if (flags & PFRULE_SET_TOS) {
+ u_int16_t ov, nv;
+
+ ov = *(u_int16_t *)h;
+ h->ip_tos = tos;
+ nv = *(u_int16_t *)h;
+
+ h->ip_sum = pf_cksum_fixup(h->ip_sum, ov, nv, 0);
+ }
+
+ /* random-id, but not for fragments */
+ if (flags & PFRULE_RANDOMID && !(h->ip_off & ~htons(IP_DF))) {
+ u_int16_t ip_id = h->ip_id;
+
+ h->ip_id = ip_randomid();
+ h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
+ }
+}
+
+#ifdef INET6
+void
+pf_scrub_ip6(struct mbuf **m0, u_int8_t min_ttl)
+{
+ struct mbuf *m = *m0;
+ struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
+
+ /* Enforce a minimum ttl, may cause endless packet loops */
+ if (min_ttl && h->ip6_hlim < min_ttl)
+ h->ip6_hlim = min_ttl;
+}
+#endif
diff --git a/sys/contrib/pf/net/pf_osfp.c b/sys/contrib/pf/net/pf_osfp.c
new file mode 100644
index 0000000..dcd8af7
--- /dev/null
+++ b/sys/contrib/pf/net/pf_osfp.c
@@ -0,0 +1,698 @@
+/* $OpenBSD: pf_osfp.c,v 1.14 2008/06/12 18:17:01 henning Exp $ */
+
+/*
+ * Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifdef __FreeBSD__
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#endif
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#ifdef _KERNEL
+#include <sys/systm.h>
+#ifndef __FreeBSD__
+#include <sys/pool.h>
+#endif
+#endif /* _KERNEL */
+#include <sys/mbuf.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include <net/if.h>
+#include <net/pfvar.h>
+
+#include <netinet/ip6.h>
+#ifdef _KERNEL
+#include <netinet6/in6_var.h>
+#endif
+
+
+#ifdef _KERNEL
+#ifdef __FreeBSD__
+#define DPFPRINTF(format, x...) \
+ if (V_pf_status.debug >= PF_DEBUG_NOISY) \
+ printf(format , ##x)
+#else
+#define DPFPRINTF(format, x...) \
+ if (pf_status.debug >= PF_DEBUG_NOISY) \
+ printf(format , ##x)
+#endif
+#ifdef __FreeBSD__
+typedef uma_zone_t pool_t;
+#else
+typedef struct pool pool_t;
+#endif
+
+#else
+/* Userland equivalents so we can lend code to tcpdump et al. */
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#define pool_t int
+#define pool_get(pool, flags) malloc(*(pool))
+#define pool_put(pool, item) free(item)
+#define pool_init(pool, size, a, ao, f, m, p) (*(pool)) = (size)
+
+#ifdef __FreeBSD__
+#define NTOHS(x) (x) = ntohs((u_int16_t)(x))
+#endif
+
+#ifdef PFDEBUG
+#include <sys/stdarg.h>
+#define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
+#else
+#define DPFPRINTF(format, x...) ((void)0)
+#endif /* PFDEBUG */
+#endif /* _KERNEL */
+
+
+#ifdef __FreeBSD__
+SLIST_HEAD(pf_osfp_list, pf_os_fingerprint);
+VNET_DEFINE(struct pf_osfp_list, pf_osfp_list);
+#define V_pf_osfp_list VNET(pf_osfp_list)
+VNET_DEFINE(pool_t, pf_osfp_entry_pl);
+#define pf_osfp_entry_pl VNET(pf_osfp_entry_pl)
+VNET_DEFINE(pool_t, pf_osfp_pl);
+#define pf_osfp_pl VNET(pf_osfp_pl)
+#else
+SLIST_HEAD(pf_osfp_list, pf_os_fingerprint) pf_osfp_list;
+pool_t pf_osfp_entry_pl;
+pool_t pf_osfp_pl;
+#endif
+
+struct pf_os_fingerprint *pf_osfp_find(struct pf_osfp_list *,
+ struct pf_os_fingerprint *, u_int8_t);
+struct pf_os_fingerprint *pf_osfp_find_exact(struct pf_osfp_list *,
+ struct pf_os_fingerprint *);
+void pf_osfp_insert(struct pf_osfp_list *,
+ struct pf_os_fingerprint *);
+
+
+#ifdef _KERNEL
+/*
+ * Passively fingerprint the OS of the host (IPv4 TCP SYN packets only)
+ * Returns the list of possible OSes.
+ */
+struct pf_osfp_enlist *
+pf_osfp_fingerprint(struct pf_pdesc *pd, struct mbuf *m, int off,
+ const struct tcphdr *tcp)
+{
+ struct ip *ip;
+ struct ip6_hdr *ip6;
+ char hdr[60];
+
+ if ((pd->af != PF_INET && pd->af != PF_INET6) ||
+ pd->proto != IPPROTO_TCP || (tcp->th_off << 2) < sizeof(*tcp))
+ return (NULL);
+
+ if (pd->af == PF_INET) {
+ ip = mtod(m, struct ip *);
+ ip6 = (struct ip6_hdr *)NULL;
+ } else {
+ ip = (struct ip *)NULL;
+ ip6 = mtod(m, struct ip6_hdr *);
+ }
+ if (!pf_pull_hdr(m, off, hdr, tcp->th_off << 2, NULL, NULL,
+ pd->af)) return (NULL);
+
+ return (pf_osfp_fingerprint_hdr(ip, ip6, (struct tcphdr *)hdr));
+}
+#endif /* _KERNEL */
+
+struct pf_osfp_enlist *
+pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcp)
+{
+ struct pf_os_fingerprint fp, *fpresult;
+ int cnt, optlen = 0;
+ const u_int8_t *optp;
+#ifdef _KERNEL
+ char srcname[128];
+#else
+ char srcname[NI_MAXHOST];
+#endif
+
+ if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN)
+ return (NULL);
+ if (ip) {
+ if ((ip->ip_off & htons(IP_OFFMASK)) != 0)
+ return (NULL);
+ }
+
+ memset(&fp, 0, sizeof(fp));
+
+ if (ip) {
+#ifndef _KERNEL
+ struct sockaddr_in sin;
+#endif
+
+ fp.fp_psize = ntohs(ip->ip_len);
+ fp.fp_ttl = ip->ip_ttl;
+ if (ip->ip_off & htons(IP_DF))
+ fp.fp_flags |= PF_OSFP_DF;
+#ifdef _KERNEL
+ strlcpy(srcname, inet_ntoa(ip->ip_src), sizeof(srcname));
+#else
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_len = sizeof(struct sockaddr_in);
+ sin.sin_addr = ip->ip_src;
+ (void)getnameinfo((struct sockaddr *)&sin,
+ sizeof(struct sockaddr_in), srcname, sizeof(srcname),
+ NULL, 0, NI_NUMERICHOST);
+#endif
+ }
+#ifdef INET6
+ else if (ip6) {
+#ifndef _KERNEL
+ struct sockaddr_in6 sin6;
+#endif
+
+ /* jumbo payload? */
+ fp.fp_psize = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
+ fp.fp_ttl = ip6->ip6_hlim;
+ fp.fp_flags |= PF_OSFP_DF;
+ fp.fp_flags |= PF_OSFP_INET6;
+#ifdef _KERNEL
+ strlcpy(srcname, ip6_sprintf((struct in6_addr *)&ip6->ip6_src),
+ sizeof(srcname));
+#else
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_len = sizeof(struct sockaddr_in6);
+ sin6.sin6_addr = ip6->ip6_src;
+ (void)getnameinfo((struct sockaddr *)&sin6,
+ sizeof(struct sockaddr_in6), srcname, sizeof(srcname),
+ NULL, 0, NI_NUMERICHOST);
+#endif
+ }
+#endif
+ else
+ return (NULL);
+ fp.fp_wsize = ntohs(tcp->th_win);
+
+
+ cnt = (tcp->th_off << 2) - sizeof(*tcp);
+ optp = (const u_int8_t *)((const char *)tcp + sizeof(*tcp));
+ for (; cnt > 0; cnt -= optlen, optp += optlen) {
+ if (*optp == TCPOPT_EOL)
+ break;
+
+ fp.fp_optcnt++;
+ if (*optp == TCPOPT_NOP) {
+ fp.fp_tcpopts = (fp.fp_tcpopts << PF_OSFP_TCPOPT_BITS) |
+ PF_OSFP_TCPOPT_NOP;
+ optlen = 1;
+ } else {
+ if (cnt < 2)
+ return (NULL);
+ optlen = optp[1];
+ if (optlen > cnt || optlen < 2)
+ return (NULL);
+ switch (*optp) {
+ case TCPOPT_MAXSEG:
+ if (optlen >= TCPOLEN_MAXSEG)
+ memcpy(&fp.fp_mss, &optp[2],
+ sizeof(fp.fp_mss));
+ fp.fp_tcpopts = (fp.fp_tcpopts <<
+ PF_OSFP_TCPOPT_BITS) | PF_OSFP_TCPOPT_MSS;
+ NTOHS(fp.fp_mss);
+ break;
+ case TCPOPT_WINDOW:
+ if (optlen >= TCPOLEN_WINDOW)
+ memcpy(&fp.fp_wscale, &optp[2],
+ sizeof(fp.fp_wscale));
+ NTOHS(fp.fp_wscale);
+ fp.fp_tcpopts = (fp.fp_tcpopts <<
+ PF_OSFP_TCPOPT_BITS) |
+ PF_OSFP_TCPOPT_WSCALE;
+ break;
+ case TCPOPT_SACK_PERMITTED:
+ fp.fp_tcpopts = (fp.fp_tcpopts <<
+ PF_OSFP_TCPOPT_BITS) | PF_OSFP_TCPOPT_SACK;
+ break;
+ case TCPOPT_TIMESTAMP:
+ if (optlen >= TCPOLEN_TIMESTAMP) {
+ u_int32_t ts;
+ memcpy(&ts, &optp[2], sizeof(ts));
+ if (ts == 0)
+ fp.fp_flags |= PF_OSFP_TS0;
+
+ }
+ fp.fp_tcpopts = (fp.fp_tcpopts <<
+ PF_OSFP_TCPOPT_BITS) | PF_OSFP_TCPOPT_TS;
+ break;
+ default:
+ return (NULL);
+ }
+ }
+ optlen = MAX(optlen, 1); /* paranoia */
+ }
+
+ DPFPRINTF("fingerprinted %s:%d %d:%d:%d:%d:%llx (%d) "
+ "(TS=%s,M=%s%d,W=%s%d)\n",
+ srcname, ntohs(tcp->th_sport),
+ fp.fp_wsize, fp.fp_ttl, (fp.fp_flags & PF_OSFP_DF) != 0,
+ fp.fp_psize, (long long int)fp.fp_tcpopts, fp.fp_optcnt,
+ (fp.fp_flags & PF_OSFP_TS0) ? "0" : "",
+ (fp.fp_flags & PF_OSFP_MSS_MOD) ? "%" :
+ (fp.fp_flags & PF_OSFP_MSS_DC) ? "*" : "",
+ fp.fp_mss,
+ (fp.fp_flags & PF_OSFP_WSCALE_MOD) ? "%" :
+ (fp.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "",
+ fp.fp_wscale);
+
+#ifdef __FreeBSD__
+ if ((fpresult = pf_osfp_find(&V_pf_osfp_list, &fp,
+#else
+ if ((fpresult = pf_osfp_find(&pf_osfp_list, &fp,
+#endif
+ PF_OSFP_MAXTTL_OFFSET)))
+ return (&fpresult->fp_oses);
+ return (NULL);
+}
+
+/* Match a fingerprint ID against a list of OSes */
+int
+pf_osfp_match(struct pf_osfp_enlist *list, pf_osfp_t os)
+{
+ struct pf_osfp_entry *entry;
+ int os_class, os_version, os_subtype;
+ int en_class, en_version, en_subtype;
+
+ if (os == PF_OSFP_ANY)
+ return (1);
+ if (list == NULL) {
+ DPFPRINTF("osfp no match against %x\n", os);
+ return (os == PF_OSFP_UNKNOWN);
+ }
+ PF_OSFP_UNPACK(os, os_class, os_version, os_subtype);
+ SLIST_FOREACH(entry, list, fp_entry) {
+ PF_OSFP_UNPACK(entry->fp_os, en_class, en_version, en_subtype);
+ if ((os_class == PF_OSFP_ANY || en_class == os_class) &&
+ (os_version == PF_OSFP_ANY || en_version == os_version) &&
+ (os_subtype == PF_OSFP_ANY || en_subtype == os_subtype)) {
+ DPFPRINTF("osfp matched %s %s %s %x==%x\n",
+ entry->fp_class_nm, entry->fp_version_nm,
+ entry->fp_subtype_nm, os, entry->fp_os);
+ return (1);
+ }
+ }
+ DPFPRINTF("fingerprint 0x%x didn't match\n", os);
+ return (0);
+}
+
+/* Initialize the OS fingerprint system */
+#ifdef __FreeBSD__
+int
+#else
+void
+#endif
+pf_osfp_initialize(void)
+{
+#if defined(__FreeBSD__) && defined(_KERNEL)
+ int error = ENOMEM;
+
+ do {
+ pf_osfp_entry_pl = pf_osfp_pl = NULL;
+ UMA_CREATE(pf_osfp_entry_pl, struct pf_osfp_entry, "pfospfen");
+ UMA_CREATE(pf_osfp_pl, struct pf_os_fingerprint, "pfosfp");
+ error = 0;
+ } while(0);
+
+ SLIST_INIT(&V_pf_osfp_list);
+#else
+ pool_init(&pf_osfp_entry_pl, sizeof(struct pf_osfp_entry), 0, 0, 0,
+ "pfosfpen", &pool_allocator_nointr);
+ pool_init(&pf_osfp_pl, sizeof(struct pf_os_fingerprint), 0, 0, 0,
+ "pfosfp", &pool_allocator_nointr);
+ SLIST_INIT(&pf_osfp_list);
+#endif
+
+#ifdef __FreeBSD__
+#ifdef _KERNEL
+ return (error);
+#else
+ return (0);
+#endif
+#endif
+}
+
+#if defined(__FreeBSD__) && (_KERNEL)
+void
+pf_osfp_cleanup(void)
+{
+
+ UMA_DESTROY(pf_osfp_entry_pl);
+ UMA_DESTROY(pf_osfp_pl);
+}
+#endif
+
+/* Flush the fingerprint list */
+void
+pf_osfp_flush(void)
+{
+ struct pf_os_fingerprint *fp;
+ struct pf_osfp_entry *entry;
+
+#ifdef __FreeBSD__
+ while ((fp = SLIST_FIRST(&V_pf_osfp_list))) {
+ SLIST_REMOVE_HEAD(&V_pf_osfp_list, fp_next);
+#else
+ while ((fp = SLIST_FIRST(&pf_osfp_list))) {
+ SLIST_REMOVE_HEAD(&pf_osfp_list, fp_next);
+#endif
+ while ((entry = SLIST_FIRST(&fp->fp_oses))) {
+ SLIST_REMOVE_HEAD(&fp->fp_oses, fp_entry);
+ pool_put(&pf_osfp_entry_pl, entry);
+ }
+ pool_put(&pf_osfp_pl, fp);
+ }
+}
+
+
+/* Add a fingerprint */
+int
+pf_osfp_add(struct pf_osfp_ioctl *fpioc)
+{
+ struct pf_os_fingerprint *fp, fpadd;
+ struct pf_osfp_entry *entry;
+
+ memset(&fpadd, 0, sizeof(fpadd));
+ fpadd.fp_tcpopts = fpioc->fp_tcpopts;
+ fpadd.fp_wsize = fpioc->fp_wsize;
+ fpadd.fp_psize = fpioc->fp_psize;
+ fpadd.fp_mss = fpioc->fp_mss;
+ fpadd.fp_flags = fpioc->fp_flags;
+ fpadd.fp_optcnt = fpioc->fp_optcnt;
+ fpadd.fp_wscale = fpioc->fp_wscale;
+ fpadd.fp_ttl = fpioc->fp_ttl;
+
+#if 0 /* XXX RYAN wants to fix logging */
+ DPFPRINTF("adding osfp %s %s %s = %s%d:%d:%d:%s%d:0x%llx %d "
+ "(TS=%s,M=%s%d,W=%s%d) %x\n",
+ fpioc->fp_os.fp_class_nm, fpioc->fp_os.fp_version_nm,
+ fpioc->fp_os.fp_subtype_nm,
+ (fpadd.fp_flags & PF_OSFP_WSIZE_MOD) ? "%" :
+ (fpadd.fp_flags & PF_OSFP_WSIZE_MSS) ? "S" :
+ (fpadd.fp_flags & PF_OSFP_WSIZE_MTU) ? "T" :
+ (fpadd.fp_flags & PF_OSFP_WSIZE_DC) ? "*" : "",
+ fpadd.fp_wsize,
+ fpadd.fp_ttl,
+ (fpadd.fp_flags & PF_OSFP_DF) ? 1 : 0,
+ (fpadd.fp_flags & PF_OSFP_PSIZE_MOD) ? "%" :
+ (fpadd.fp_flags & PF_OSFP_PSIZE_DC) ? "*" : "",
+ fpadd.fp_psize,
+ (long long int)fpadd.fp_tcpopts, fpadd.fp_optcnt,
+ (fpadd.fp_flags & PF_OSFP_TS0) ? "0" : "",
+ (fpadd.fp_flags & PF_OSFP_MSS_MOD) ? "%" :
+ (fpadd.fp_flags & PF_OSFP_MSS_DC) ? "*" : "",
+ fpadd.fp_mss,
+ (fpadd.fp_flags & PF_OSFP_WSCALE_MOD) ? "%" :
+ (fpadd.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "",
+ fpadd.fp_wscale,
+ fpioc->fp_os.fp_os);
+#endif
+
+#ifdef __FreeBSD__
+ if ((fp = pf_osfp_find_exact(&V_pf_osfp_list, &fpadd))) {
+#else
+ if ((fp = pf_osfp_find_exact(&pf_osfp_list, &fpadd))) {
+#endif
+ SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) {
+ if (PF_OSFP_ENTRY_EQ(entry, &fpioc->fp_os))
+ return (EEXIST);
+ }
+ if ((entry = pool_get(&pf_osfp_entry_pl,
+#ifdef __FreeBSD__
+ PR_NOWAIT)) == NULL)
+#else
+ PR_WAITOK|PR_LIMITFAIL)) == NULL)
+#endif
+ return (ENOMEM);
+ } else {
+ if ((fp = pool_get(&pf_osfp_pl,
+#ifdef __FreeBSD__
+ PR_NOWAIT)) == NULL)
+#else
+ PR_WAITOK|PR_LIMITFAIL)) == NULL)
+#endif
+ return (ENOMEM);
+ memset(fp, 0, sizeof(*fp));
+ fp->fp_tcpopts = fpioc->fp_tcpopts;
+ fp->fp_wsize = fpioc->fp_wsize;
+ fp->fp_psize = fpioc->fp_psize;
+ fp->fp_mss = fpioc->fp_mss;
+ fp->fp_flags = fpioc->fp_flags;
+ fp->fp_optcnt = fpioc->fp_optcnt;
+ fp->fp_wscale = fpioc->fp_wscale;
+ fp->fp_ttl = fpioc->fp_ttl;
+ SLIST_INIT(&fp->fp_oses);
+ if ((entry = pool_get(&pf_osfp_entry_pl,
+#ifdef __FreeBSD__
+ PR_NOWAIT)) == NULL) {
+#else
+ PR_WAITOK|PR_LIMITFAIL)) == NULL) {
+#endif
+ pool_put(&pf_osfp_pl, fp);
+ return (ENOMEM);
+ }
+#ifdef __FreeBSD__
+ pf_osfp_insert(&V_pf_osfp_list, fp);
+#else
+ pf_osfp_insert(&pf_osfp_list, fp);
+#endif
+ }
+ memcpy(entry, &fpioc->fp_os, sizeof(*entry));
+
+ /* Make sure the strings are NUL terminated */
+ entry->fp_class_nm[sizeof(entry->fp_class_nm)-1] = '\0';
+ entry->fp_version_nm[sizeof(entry->fp_version_nm)-1] = '\0';
+ entry->fp_subtype_nm[sizeof(entry->fp_subtype_nm)-1] = '\0';
+
+ SLIST_INSERT_HEAD(&fp->fp_oses, entry, fp_entry);
+
+#ifdef PFDEBUG
+ if ((fp = pf_osfp_validate()))
+ printf("Invalid fingerprint list\n");
+#endif /* PFDEBUG */
+ return (0);
+}
+
+
+/* Find a fingerprint in the list */
+struct pf_os_fingerprint *
+pf_osfp_find(struct pf_osfp_list *list, struct pf_os_fingerprint *find,
+ u_int8_t ttldiff)
+{
+ struct pf_os_fingerprint *f;
+
+#define MATCH_INT(_MOD, _DC, _field) \
+ if ((f->fp_flags & _DC) == 0) { \
+ if ((f->fp_flags & _MOD) == 0) { \
+ if (f->_field != find->_field) \
+ continue; \
+ } else { \
+ if (f->_field == 0 || find->_field % f->_field) \
+ continue; \
+ } \
+ }
+
+ SLIST_FOREACH(f, list, fp_next) {
+ if (f->fp_tcpopts != find->fp_tcpopts ||
+ f->fp_optcnt != find->fp_optcnt ||
+ f->fp_ttl < find->fp_ttl ||
+ f->fp_ttl - find->fp_ttl > ttldiff ||
+ (f->fp_flags & (PF_OSFP_DF|PF_OSFP_TS0)) !=
+ (find->fp_flags & (PF_OSFP_DF|PF_OSFP_TS0)))
+ continue;
+
+ MATCH_INT(PF_OSFP_PSIZE_MOD, PF_OSFP_PSIZE_DC, fp_psize)
+ MATCH_INT(PF_OSFP_MSS_MOD, PF_OSFP_MSS_DC, fp_mss)
+ MATCH_INT(PF_OSFP_WSCALE_MOD, PF_OSFP_WSCALE_DC, fp_wscale)
+ if ((f->fp_flags & PF_OSFP_WSIZE_DC) == 0) {
+ if (f->fp_flags & PF_OSFP_WSIZE_MSS) {
+ if (find->fp_mss == 0)
+ continue;
+
+/*
+ * Some "smart" NAT devices and DSL routers will tweak the MSS size and
+ * will set it to whatever is suitable for the link type.
+ */
+#define SMART_MSS 1460
+ if ((find->fp_wsize % find->fp_mss ||
+ find->fp_wsize / find->fp_mss !=
+ f->fp_wsize) &&
+ (find->fp_wsize % SMART_MSS ||
+ find->fp_wsize / SMART_MSS !=
+ f->fp_wsize))
+ continue;
+ } else if (f->fp_flags & PF_OSFP_WSIZE_MTU) {
+ if (find->fp_mss == 0)
+ continue;
+
+#define MTUOFF (sizeof(struct ip) + sizeof(struct tcphdr))
+#define SMART_MTU (SMART_MSS + MTUOFF)
+ if ((find->fp_wsize % (find->fp_mss + MTUOFF) ||
+ find->fp_wsize / (find->fp_mss + MTUOFF) !=
+ f->fp_wsize) &&
+ (find->fp_wsize % SMART_MTU ||
+ find->fp_wsize / SMART_MTU !=
+ f->fp_wsize))
+ continue;
+ } else if (f->fp_flags & PF_OSFP_WSIZE_MOD) {
+ if (f->fp_wsize == 0 || find->fp_wsize %
+ f->fp_wsize)
+ continue;
+ } else {
+ if (f->fp_wsize != find->fp_wsize)
+ continue;
+ }
+ }
+ return (f);
+ }
+
+ return (NULL);
+}
+
+/* Find an exact fingerprint in the list */
+struct pf_os_fingerprint *
+pf_osfp_find_exact(struct pf_osfp_list *list, struct pf_os_fingerprint *find)
+{
+ struct pf_os_fingerprint *f;
+
+ SLIST_FOREACH(f, list, fp_next) {
+ if (f->fp_tcpopts == find->fp_tcpopts &&
+ f->fp_wsize == find->fp_wsize &&
+ f->fp_psize == find->fp_psize &&
+ f->fp_mss == find->fp_mss &&
+ f->fp_flags == find->fp_flags &&
+ f->fp_optcnt == find->fp_optcnt &&
+ f->fp_wscale == find->fp_wscale &&
+ f->fp_ttl == find->fp_ttl)
+ return (f);
+ }
+
+ return (NULL);
+}
+
+/* Insert a fingerprint into the list */
+void
+pf_osfp_insert(struct pf_osfp_list *list, struct pf_os_fingerprint *ins)
+{
+ struct pf_os_fingerprint *f, *prev = NULL;
+
+ /* XXX need to go semi tree based. can key on tcp options */
+
+ SLIST_FOREACH(f, list, fp_next)
+ prev = f;
+ if (prev)
+ SLIST_INSERT_AFTER(prev, ins, fp_next);
+ else
+ SLIST_INSERT_HEAD(list, ins, fp_next);
+}
+
+/* Fill a fingerprint by its number (from an ioctl) */
+int
+pf_osfp_get(struct pf_osfp_ioctl *fpioc)
+{
+ struct pf_os_fingerprint *fp;
+ struct pf_osfp_entry *entry;
+ int num = fpioc->fp_getnum;
+ int i = 0;
+
+
+ memset(fpioc, 0, sizeof(*fpioc));
+#ifdef __FreeBSD__
+ SLIST_FOREACH(fp, &V_pf_osfp_list, fp_next) {
+#else
+ SLIST_FOREACH(fp, &pf_osfp_list, fp_next) {
+#endif
+ SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) {
+ if (i++ == num) {
+ fpioc->fp_mss = fp->fp_mss;
+ fpioc->fp_wsize = fp->fp_wsize;
+ fpioc->fp_flags = fp->fp_flags;
+ fpioc->fp_psize = fp->fp_psize;
+ fpioc->fp_ttl = fp->fp_ttl;
+ fpioc->fp_wscale = fp->fp_wscale;
+ fpioc->fp_getnum = num;
+ memcpy(&fpioc->fp_os, entry,
+ sizeof(fpioc->fp_os));
+ return (0);
+ }
+ }
+ }
+
+ return (EBUSY);
+}
+
+
+/* Validate that each signature is reachable */
+struct pf_os_fingerprint *
+pf_osfp_validate(void)
+{
+ struct pf_os_fingerprint *f, *f2, find;
+
+#ifdef __FreeBSD__
+ SLIST_FOREACH(f, &V_pf_osfp_list, fp_next) {
+#else
+ SLIST_FOREACH(f, &pf_osfp_list, fp_next) {
+#endif
+ memcpy(&find, f, sizeof(find));
+
+ /* We do a few MSS/th_win percolations to make things unique */
+ if (find.fp_mss == 0)
+ find.fp_mss = 128;
+ if (f->fp_flags & PF_OSFP_WSIZE_MSS)
+ find.fp_wsize *= find.fp_mss;
+ else if (f->fp_flags & PF_OSFP_WSIZE_MTU)
+ find.fp_wsize *= (find.fp_mss + 40);
+ else if (f->fp_flags & PF_OSFP_WSIZE_MOD)
+ find.fp_wsize *= 2;
+#ifdef __FreeBSD__
+ if (f != (f2 = pf_osfp_find(&V_pf_osfp_list, &find, 0))) {
+#else
+ if (f != (f2 = pf_osfp_find(&pf_osfp_list, &find, 0))) {
+#endif
+ if (f2)
+ printf("Found \"%s %s %s\" instead of "
+ "\"%s %s %s\"\n",
+ SLIST_FIRST(&f2->fp_oses)->fp_class_nm,
+ SLIST_FIRST(&f2->fp_oses)->fp_version_nm,
+ SLIST_FIRST(&f2->fp_oses)->fp_subtype_nm,
+ SLIST_FIRST(&f->fp_oses)->fp_class_nm,
+ SLIST_FIRST(&f->fp_oses)->fp_version_nm,
+ SLIST_FIRST(&f->fp_oses)->fp_subtype_nm);
+ else
+ printf("Couldn't find \"%s %s %s\"\n",
+ SLIST_FIRST(&f->fp_oses)->fp_class_nm,
+ SLIST_FIRST(&f->fp_oses)->fp_version_nm,
+ SLIST_FIRST(&f->fp_oses)->fp_subtype_nm);
+ return (f);
+ }
+ }
+ return (NULL);
+}
diff --git a/sys/contrib/pf/net/pf_ruleset.c b/sys/contrib/pf/net/pf_ruleset.c
new file mode 100644
index 0000000..ca8667c
--- /dev/null
+++ b/sys/contrib/pf/net/pf_ruleset.c
@@ -0,0 +1,457 @@
+/* $OpenBSD: pf_ruleset.c,v 1.2 2008/12/18 15:31:37 dhill Exp $ */
+
+/*
+ * Copyright (c) 2001 Daniel Hartmeier
+ * Copyright (c) 2002,2003 Henning Brauer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Effort sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F30602-01-2-0537.
+ *
+ */
+
+#ifdef __FreeBSD__
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#endif
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#ifdef _KERNEL
+# include <sys/systm.h>
+#endif /* _KERNEL */
+#include <sys/mbuf.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include <net/if.h>
+#include <net/pfvar.h>
+
+#ifdef INET6
+#include <netinet/ip6.h>
+#endif /* INET6 */
+
+
+#ifdef _KERNEL
+#ifdef __FreeBSD__
+#define DPFPRINTF(format, x...) \
+ if (V_pf_status.debug >= PF_DEBUG_NOISY) \
+ printf(format , ##x)
+#else
+#define DPFPRINTF(format, x...) \
+ if (pf_status.debug >= PF_DEBUG_NOISY) \
+ printf(format , ##x)
+#endif
+#ifdef __FreeBSD__
+#define rs_malloc(x) malloc(x, M_TEMP, M_NOWAIT|M_ZERO)
+#else
+#define rs_malloc(x) malloc(x, M_TEMP, M_WAITOK|M_CANFAIL|M_ZERO)
+#endif
+#define rs_free(x) free(x, M_TEMP)
+
+#else
+/* Userland equivalents so we can lend code to pfctl et al. */
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define rs_malloc(x) calloc(1, x)
+#define rs_free(x) free(x)
+
+#ifdef PFDEBUG
+#include <sys/stdarg.h>
+#define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
+#else
+#define DPFPRINTF(format, x...) ((void)0)
+#endif /* PFDEBUG */
+#endif /* _KERNEL */
+
+#if defined(__FreeBSD__) && !defined(_KERNEL)
+#undef V_pf_anchors
+#define V_pf_anchors pf_anchors
+
+#undef pf_main_ruleset
+#define pf_main_ruleset pf_main_anchor.ruleset
+#endif
+
+#if defined(__FreeBSD__) && defined(_KERNEL)
+VNET_DEFINE(struct pf_anchor_global, pf_anchors);
+VNET_DEFINE(struct pf_anchor, pf_main_anchor);
+#else
+struct pf_anchor_global pf_anchors;
+struct pf_anchor pf_main_anchor;
+#endif
+
+static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
+
+RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
+RB_GENERATE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
+
+static __inline int
+pf_anchor_compare(struct pf_anchor *a, struct pf_anchor *b)
+{
+ int c = strcmp(a->path, b->path);
+
+ return (c ? (c < 0 ? -1 : 1) : 0);
+}
+
+int
+pf_get_ruleset_number(u_int8_t action)
+{
+ switch (action) {
+ case PF_SCRUB:
+ case PF_NOSCRUB:
+ return (PF_RULESET_SCRUB);
+ break;
+ case PF_PASS:
+ case PF_DROP:
+ return (PF_RULESET_FILTER);
+ break;
+ case PF_NAT:
+ case PF_NONAT:
+ return (PF_RULESET_NAT);
+ break;
+ case PF_BINAT:
+ case PF_NOBINAT:
+ return (PF_RULESET_BINAT);
+ break;
+ case PF_RDR:
+ case PF_NORDR:
+ return (PF_RULESET_RDR);
+ break;
+ default:
+ return (PF_RULESET_MAX);
+ break;
+ }
+}
+
+void
+pf_init_ruleset(struct pf_ruleset *ruleset)
+{
+ int i;
+
+ memset(ruleset, 0, sizeof(struct pf_ruleset));
+ for (i = 0; i < PF_RULESET_MAX; i++) {
+ TAILQ_INIT(&ruleset->rules[i].queues[0]);
+ TAILQ_INIT(&ruleset->rules[i].queues[1]);
+ ruleset->rules[i].active.ptr = &ruleset->rules[i].queues[0];
+ ruleset->rules[i].inactive.ptr = &ruleset->rules[i].queues[1];
+ }
+}
+
+struct pf_anchor *
+pf_find_anchor(const char *path)
+{
+ struct pf_anchor *key, *found;
+
+ key = (struct pf_anchor *)rs_malloc(sizeof(*key));
+ if (key == NULL)
+ return (NULL);
+ strlcpy(key->path, path, sizeof(key->path));
+#ifdef __FreeBSD__
+ found = RB_FIND(pf_anchor_global, &V_pf_anchors, key);
+#else
+ found = RB_FIND(pf_anchor_global, &pf_anchors, key);
+#endif
+ rs_free(key);
+ return (found);
+}
+
+struct pf_ruleset *
+pf_find_ruleset(const char *path)
+{
+ struct pf_anchor *anchor;
+
+ while (*path == '/')
+ path++;
+ if (!*path)
+ return (&pf_main_ruleset);
+ anchor = pf_find_anchor(path);
+ if (anchor == NULL)
+ return (NULL);
+ else
+ return (&anchor->ruleset);
+}
+
+struct pf_ruleset *
+pf_find_or_create_ruleset(const char *path)
+{
+ char *p, *q, *r;
+ struct pf_ruleset *ruleset;
+#ifdef __FreeBSD__
+ struct pf_anchor *anchor = NULL, *dup, *parent = NULL;
+#else
+ struct pf_anchor *anchor, *dup, *parent = NULL;
+#endif
+
+ if (path[0] == 0)
+ return (&pf_main_ruleset);
+ while (*path == '/')
+ path++;
+ ruleset = pf_find_ruleset(path);
+ if (ruleset != NULL)
+ return (ruleset);
+ p = (char *)rs_malloc(MAXPATHLEN);
+ if (p == NULL)
+ return (NULL);
+ strlcpy(p, path, MAXPATHLEN);
+ while (parent == NULL && (q = strrchr(p, '/')) != NULL) {
+ *q = 0;
+ if ((ruleset = pf_find_ruleset(p)) != NULL) {
+ parent = ruleset->anchor;
+ break;
+ }
+ }
+ if (q == NULL)
+ q = p;
+ else
+ q++;
+ strlcpy(p, path, MAXPATHLEN);
+ if (!*q) {
+ rs_free(p);
+ return (NULL);
+ }
+ while ((r = strchr(q, '/')) != NULL || *q) {
+ if (r != NULL)
+ *r = 0;
+ if (!*q || strlen(q) >= PF_ANCHOR_NAME_SIZE ||
+ (parent != NULL && strlen(parent->path) >=
+ MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1)) {
+ rs_free(p);
+ return (NULL);
+ }
+ anchor = (struct pf_anchor *)rs_malloc(sizeof(*anchor));
+ if (anchor == NULL) {
+ rs_free(p);
+ return (NULL);
+ }
+ RB_INIT(&anchor->children);
+ strlcpy(anchor->name, q, sizeof(anchor->name));
+ if (parent != NULL) {
+ strlcpy(anchor->path, parent->path,
+ sizeof(anchor->path));
+ strlcat(anchor->path, "/", sizeof(anchor->path));
+ }
+ strlcat(anchor->path, anchor->name, sizeof(anchor->path));
+#ifdef __FreeBSD__
+ if ((dup = RB_INSERT(pf_anchor_global, &V_pf_anchors, anchor)) !=
+#else
+ if ((dup = RB_INSERT(pf_anchor_global, &pf_anchors, anchor)) !=
+#endif
+ NULL) {
+ printf("pf_find_or_create_ruleset: RB_INSERT1 "
+ "'%s' '%s' collides with '%s' '%s'\n",
+ anchor->path, anchor->name, dup->path, dup->name);
+ rs_free(anchor);
+ rs_free(p);
+ return (NULL);
+ }
+ if (parent != NULL) {
+ anchor->parent = parent;
+ if ((dup = RB_INSERT(pf_anchor_node, &parent->children,
+ anchor)) != NULL) {
+ printf("pf_find_or_create_ruleset: "
+ "RB_INSERT2 '%s' '%s' collides with "
+ "'%s' '%s'\n", anchor->path, anchor->name,
+ dup->path, dup->name);
+#ifdef __FreeBSD__
+ RB_REMOVE(pf_anchor_global, &V_pf_anchors,
+#else
+ RB_REMOVE(pf_anchor_global, &pf_anchors,
+#endif
+ anchor);
+ rs_free(anchor);
+ rs_free(p);
+ return (NULL);
+ }
+ }
+ pf_init_ruleset(&anchor->ruleset);
+ anchor->ruleset.anchor = anchor;
+ parent = anchor;
+ if (r != NULL)
+ q = r + 1;
+ else
+ *q = 0;
+ }
+ rs_free(p);
+ return (&anchor->ruleset);
+}
+
+void
+pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
+{
+ struct pf_anchor *parent;
+ int i;
+
+ while (ruleset != NULL) {
+ if (ruleset == &pf_main_ruleset || ruleset->anchor == NULL ||
+ !RB_EMPTY(&ruleset->anchor->children) ||
+ ruleset->anchor->refcnt > 0 || ruleset->tables > 0 ||
+ ruleset->topen)
+ return;
+ for (i = 0; i < PF_RULESET_MAX; ++i)
+ if (!TAILQ_EMPTY(ruleset->rules[i].active.ptr) ||
+ !TAILQ_EMPTY(ruleset->rules[i].inactive.ptr) ||
+ ruleset->rules[i].inactive.open)
+ return;
+#ifdef __FreeBSD__
+ RB_REMOVE(pf_anchor_global, &V_pf_anchors, ruleset->anchor);
+#else
+ RB_REMOVE(pf_anchor_global, &pf_anchors, ruleset->anchor);
+#endif
+ if ((parent = ruleset->anchor->parent) != NULL)
+ RB_REMOVE(pf_anchor_node, &parent->children,
+ ruleset->anchor);
+ rs_free(ruleset->anchor);
+ if (parent == NULL)
+ return;
+ ruleset = &parent->ruleset;
+ }
+}
+
+int
+pf_anchor_setup(struct pf_rule *r, const struct pf_ruleset *s,
+ const char *name)
+{
+ char *p, *path;
+ struct pf_ruleset *ruleset;
+
+ r->anchor = NULL;
+ r->anchor_relative = 0;
+ r->anchor_wildcard = 0;
+ if (!name[0])
+ return (0);
+ path = (char *)rs_malloc(MAXPATHLEN);
+ if (path == NULL)
+ return (1);
+ if (name[0] == '/')
+ strlcpy(path, name + 1, MAXPATHLEN);
+ else {
+ /* relative path */
+ r->anchor_relative = 1;
+ if (s->anchor == NULL || !s->anchor->path[0])
+ path[0] = 0;
+ else
+ strlcpy(path, s->anchor->path, MAXPATHLEN);
+ while (name[0] == '.' && name[1] == '.' && name[2] == '/') {
+ if (!path[0]) {
+ printf("pf_anchor_setup: .. beyond root\n");
+ rs_free(path);
+ return (1);
+ }
+ if ((p = strrchr(path, '/')) != NULL)
+ *p = 0;
+ else
+ path[0] = 0;
+ r->anchor_relative++;
+ name += 3;
+ }
+ if (path[0])
+ strlcat(path, "/", MAXPATHLEN);
+ strlcat(path, name, MAXPATHLEN);
+ }
+ if ((p = strrchr(path, '/')) != NULL && !strcmp(p, "/*")) {
+ r->anchor_wildcard = 1;
+ *p = 0;
+ }
+ ruleset = pf_find_or_create_ruleset(path);
+ rs_free(path);
+ if (ruleset == NULL || ruleset->anchor == NULL) {
+ printf("pf_anchor_setup: ruleset\n");
+ return (1);
+ }
+ r->anchor = ruleset->anchor;
+ r->anchor->refcnt++;
+ return (0);
+}
+
+int
+pf_anchor_copyout(const struct pf_ruleset *rs, const struct pf_rule *r,
+ struct pfioc_rule *pr)
+{
+ pr->anchor_call[0] = 0;
+ if (r->anchor == NULL)
+ return (0);
+ if (!r->anchor_relative) {
+ strlcpy(pr->anchor_call, "/", sizeof(pr->anchor_call));
+ strlcat(pr->anchor_call, r->anchor->path,
+ sizeof(pr->anchor_call));
+ } else {
+ char *a, *p;
+ int i;
+
+ a = (char *)rs_malloc(MAXPATHLEN);
+ if (a == NULL)
+ return (1);
+ if (rs->anchor == NULL)
+ a[0] = 0;
+ else
+ strlcpy(a, rs->anchor->path, MAXPATHLEN);
+ for (i = 1; i < r->anchor_relative; ++i) {
+ if ((p = strrchr(a, '/')) == NULL)
+ p = a;
+ *p = 0;
+ strlcat(pr->anchor_call, "../",
+ sizeof(pr->anchor_call));
+ }
+ if (strncmp(a, r->anchor->path, strlen(a))) {
+ printf("pf_anchor_copyout: '%s' '%s'\n", a,
+ r->anchor->path);
+ rs_free(a);
+ return (1);
+ }
+ if (strlen(r->anchor->path) > strlen(a))
+ strlcat(pr->anchor_call, r->anchor->path + (a[0] ?
+ strlen(a) + 1 : 0), sizeof(pr->anchor_call));
+ rs_free(a);
+ }
+ if (r->anchor_wildcard)
+ strlcat(pr->anchor_call, pr->anchor_call[0] ? "/*" : "*",
+ sizeof(pr->anchor_call));
+ return (0);
+}
+
+void
+pf_anchor_remove(struct pf_rule *r)
+{
+ if (r->anchor == NULL)
+ return;
+ if (r->anchor->refcnt <= 0) {
+ printf("pf_anchor_remove: broken refcount\n");
+ r->anchor = NULL;
+ return;
+ }
+ if (!--r->anchor->refcnt)
+ pf_remove_if_empty_ruleset(&r->anchor->ruleset);
+ r->anchor = NULL;
+}
diff --git a/sys/contrib/pf/net/pf_table.c b/sys/contrib/pf/net/pf_table.c
new file mode 100644
index 0000000..ea77e31
--- /dev/null
+++ b/sys/contrib/pf/net/pf_table.c
@@ -0,0 +1,2516 @@
+/* $OpenBSD: pf_table.c,v 1.79 2008/10/08 06:24:50 mcbride Exp $ */
+
+/*
+ * Copyright (c) 2002 Cedric Berger
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifdef __FreeBSD__
+#include "opt_inet.h"
+#include "opt_inet6.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/socket.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#ifdef __FreeBSD__
+#include <sys/malloc.h>
+#else
+#include <sys/pool.h>
+#endif
+
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#ifndef __FreeBSD__
+#include <netinet/ip_ipsp.h>
+#endif
+#include <net/pfvar.h>
+
+#define ACCEPT_FLAGS(flags, oklist) \
+ do { \
+ if ((flags & ~(oklist)) & \
+ PFR_FLAG_ALLMASK) \
+ return (EINVAL); \
+ } while (0)
+
+#ifdef __FreeBSD__
+static inline int
+_copyin(const void *uaddr, void *kaddr, size_t len)
+{
+ int r;
+
+ PF_UNLOCK();
+ r = copyin(uaddr, kaddr, len);
+ PF_LOCK();
+
+ return (r);
+}
+
+static inline int
+_copyout(const void *uaddr, void *kaddr, size_t len)
+{
+ int r;
+
+ PF_UNLOCK();
+ r = copyout(uaddr, kaddr, len);
+ PF_LOCK();
+
+ return (r);
+}
+
+#define COPYIN(from, to, size, flags) \
+ ((flags & PFR_FLAG_USERIOCTL) ? \
+ _copyin((from), (to), (size)) : \
+ (bcopy((from), (to), (size)), 0))
+
+#define COPYOUT(from, to, size, flags) \
+ ((flags & PFR_FLAG_USERIOCTL) ? \
+ _copyout((from), (to), (size)) : \
+ (bcopy((from), (to), (size)), 0))
+
+#else
+#define COPYIN(from, to, size, flags) \
+ ((flags & PFR_FLAG_USERIOCTL) ? \
+ copyin((from), (to), (size)) : \
+ (bcopy((from), (to), (size)), 0))
+
+#define COPYOUT(from, to, size, flags) \
+ ((flags & PFR_FLAG_USERIOCTL) ? \
+ copyout((from), (to), (size)) : \
+ (bcopy((from), (to), (size)), 0))
+#endif
+
+#define FILLIN_SIN(sin, addr) \
+ do { \
+ (sin).sin_len = sizeof(sin); \
+ (sin).sin_family = AF_INET; \
+ (sin).sin_addr = (addr); \
+ } while (0)
+
+#define FILLIN_SIN6(sin6, addr) \
+ do { \
+ (sin6).sin6_len = sizeof(sin6); \
+ (sin6).sin6_family = AF_INET6; \
+ (sin6).sin6_addr = (addr); \
+ } while (0)
+
+#define SWAP(type, a1, a2) \
+ do { \
+ type tmp = a1; \
+ a1 = a2; \
+ a2 = tmp; \
+ } while (0)
+
+#define SUNION2PF(su, af) (((af)==AF_INET) ? \
+ (struct pf_addr *)&(su)->sin.sin_addr : \
+ (struct pf_addr *)&(su)->sin6.sin6_addr)
+
+#define AF_BITS(af) (((af)==AF_INET)?32:128)
+#define ADDR_NETWORK(ad) ((ad)->pfra_net < AF_BITS((ad)->pfra_af))
+#define KENTRY_NETWORK(ke) ((ke)->pfrke_net < AF_BITS((ke)->pfrke_af))
+#define KENTRY_RNF_ROOT(ke) \
+ ((((struct radix_node *)(ke))->rn_flags & RNF_ROOT) != 0)
+
+#define NO_ADDRESSES (-1)
+#define ENQUEUE_UNMARKED_ONLY (1)
+#define INVERT_NEG_FLAG (1)
+
+struct pfr_walktree {
+ enum pfrw_op {
+ PFRW_MARK,
+ PFRW_SWEEP,
+ PFRW_ENQUEUE,
+ PFRW_GET_ADDRS,
+ PFRW_GET_ASTATS,
+ PFRW_POOL_GET,
+ PFRW_DYNADDR_UPDATE
+ } pfrw_op;
+ union {
+ struct pfr_addr *pfrw1_addr;
+ struct pfr_astats *pfrw1_astats;
+ struct pfr_kentryworkq *pfrw1_workq;
+ struct pfr_kentry *pfrw1_kentry;
+ struct pfi_dynaddr *pfrw1_dyn;
+ } pfrw_1;
+ int pfrw_free;
+ int pfrw_flags;
+};
+#define pfrw_addr pfrw_1.pfrw1_addr
+#define pfrw_astats pfrw_1.pfrw1_astats
+#define pfrw_workq pfrw_1.pfrw1_workq
+#define pfrw_kentry pfrw_1.pfrw1_kentry
+#define pfrw_dyn pfrw_1.pfrw1_dyn
+#define pfrw_cnt pfrw_free
+
+#define senderr(e) do { rv = (e); goto _bad; } while (0)
+
+#ifdef __FreeBSD__
+VNET_DEFINE(uma_zone_t, pfr_ktable_pl);
+VNET_DEFINE(uma_zone_t, pfr_kentry_pl);
+VNET_DEFINE(uma_zone_t, pfr_kcounters_pl);
+VNET_DEFINE(struct sockaddr_in, pfr_sin);
+#define V_pfr_sin VNET(pfr_sin)
+VNET_DEFINE(struct sockaddr_in6, pfr_sin6);
+#define V_pfr_sin6 VNET(pfr_sin6)
+VNET_DEFINE(union sockaddr_union, pfr_mask);
+#define V_pfr_mask VNET(pfr_mask)
+VNET_DEFINE(struct pf_addr, pfr_ffaddr);
+#define V_pfr_ffaddr VNET(pfr_ffaddr)
+#else
+struct pool pfr_ktable_pl;
+struct pool pfr_kentry_pl;
+struct pool pfr_kcounters_pl;
+struct sockaddr_in pfr_sin;
+struct sockaddr_in6 pfr_sin6;
+union sockaddr_union pfr_mask;
+struct pf_addr pfr_ffaddr;
+#endif
+
+void pfr_copyout_addr(struct pfr_addr *,
+ struct pfr_kentry *ke);
+int pfr_validate_addr(struct pfr_addr *);
+void pfr_enqueue_addrs(struct pfr_ktable *,
+ struct pfr_kentryworkq *, int *, int);
+void pfr_mark_addrs(struct pfr_ktable *);
+struct pfr_kentry *pfr_lookup_addr(struct pfr_ktable *,
+ struct pfr_addr *, int);
+struct pfr_kentry *pfr_create_kentry(struct pfr_addr *, int);
+void pfr_destroy_kentries(struct pfr_kentryworkq *);
+void pfr_destroy_kentry(struct pfr_kentry *);
+void pfr_insert_kentries(struct pfr_ktable *,
+ struct pfr_kentryworkq *, long);
+void pfr_remove_kentries(struct pfr_ktable *,
+ struct pfr_kentryworkq *);
+void pfr_clstats_kentries(struct pfr_kentryworkq *, long,
+ int);
+void pfr_reset_feedback(struct pfr_addr *, int, int);
+void pfr_prepare_network(union sockaddr_union *, int, int);
+int pfr_route_kentry(struct pfr_ktable *,
+ struct pfr_kentry *);
+int pfr_unroute_kentry(struct pfr_ktable *,
+ struct pfr_kentry *);
+int pfr_walktree(struct radix_node *, void *);
+int pfr_validate_table(struct pfr_table *, int, int);
+int pfr_fix_anchor(char *);
+void pfr_commit_ktable(struct pfr_ktable *, long);
+void pfr_insert_ktables(struct pfr_ktableworkq *);
+void pfr_insert_ktable(struct pfr_ktable *);
+void pfr_setflags_ktables(struct pfr_ktableworkq *);
+void pfr_setflags_ktable(struct pfr_ktable *, int);
+void pfr_clstats_ktables(struct pfr_ktableworkq *, long,
+ int);
+void pfr_clstats_ktable(struct pfr_ktable *, long, int);
+struct pfr_ktable *pfr_create_ktable(struct pfr_table *, long, int, int);
+void pfr_destroy_ktables(struct pfr_ktableworkq *, int);
+void pfr_destroy_ktable(struct pfr_ktable *, int);
+int pfr_ktable_compare(struct pfr_ktable *,
+ struct pfr_ktable *);
+struct pfr_ktable *pfr_lookup_table(struct pfr_table *);
+void pfr_clean_node_mask(struct pfr_ktable *,
+ struct pfr_kentryworkq *);
+int pfr_table_count(struct pfr_table *, int);
+int pfr_skip_table(struct pfr_table *,
+ struct pfr_ktable *, int);
+struct pfr_kentry *pfr_kentry_byidx(struct pfr_ktable *, int, int);
+
+RB_PROTOTYPE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
+RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
+
+struct pfr_ktablehead pfr_ktables;
+struct pfr_table pfr_nulltable;
+int pfr_ktable_cnt;
+
+void
+pfr_initialize(void)
+{
+#ifndef __FreeBSD__
+ pool_init(&pfr_ktable_pl, sizeof(struct pfr_ktable), 0, 0, 0,
+ "pfrktable", NULL);
+ pool_init(&pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0,
+ "pfrkentry", NULL);
+ pool_init(&pfr_kcounters_pl, sizeof(struct pfr_kcounters), 0, 0, 0,
+ "pfrkcounters", NULL);
+
+ pfr_sin.sin_len = sizeof(pfr_sin);
+ pfr_sin.sin_family = AF_INET;
+ pfr_sin6.sin6_len = sizeof(pfr_sin6);
+ pfr_sin6.sin6_family = AF_INET6;
+
+ memset(&pfr_ffaddr, 0xff, sizeof(pfr_ffaddr));
+#else
+ V_pfr_sin.sin_len = sizeof(V_pfr_sin);
+ V_pfr_sin.sin_family = AF_INET;
+ V_pfr_sin6.sin6_len = sizeof(V_pfr_sin6);
+ V_pfr_sin6.sin6_family = AF_INET6;
+
+ memset(&V_pfr_ffaddr, 0xff, sizeof(V_pfr_ffaddr));
+#endif
+}
+
+int
+pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags)
+{
+ struct pfr_ktable *kt;
+ struct pfr_kentryworkq workq;
+ int s;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
+ if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
+ return (EINVAL);
+ kt = pfr_lookup_table(tbl);
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return (ESRCH);
+ if (kt->pfrkt_flags & PFR_TFLAG_CONST)
+ return (EPERM);
+ pfr_enqueue_addrs(kt, &workq, ndel, 0);
+
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ pfr_remove_kentries(kt, &workq);
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ if (kt->pfrkt_cnt) {
+ printf("pfr_clr_addrs: corruption detected (%d).\n",
+ kt->pfrkt_cnt);
+ kt->pfrkt_cnt = 0;
+ }
+ }
+ return (0);
+}
+
+int
+pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
+ int *nadd, int flags)
+{
+ struct pfr_ktable *kt, *tmpkt;
+ struct pfr_kentryworkq workq;
+ struct pfr_kentry *p, *q;
+ struct pfr_addr ad;
+ int i, rv, s, xadd = 0;
+ long tzero = time_second;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
+ PFR_FLAG_FEEDBACK);
+ if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
+ return (EINVAL);
+ kt = pfr_lookup_table(tbl);
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return (ESRCH);
+ if (kt->pfrkt_flags & PFR_TFLAG_CONST)
+ return (EPERM);
+ tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0,
+ !(flags & PFR_FLAG_USERIOCTL));
+ if (tmpkt == NULL)
+ return (ENOMEM);
+ SLIST_INIT(&workq);
+ for (i = 0; i < size; i++) {
+ if (COPYIN(addr+i, &ad, sizeof(ad), flags))
+ senderr(EFAULT);
+ if (pfr_validate_addr(&ad))
+ senderr(EINVAL);
+ p = pfr_lookup_addr(kt, &ad, 1);
+ q = pfr_lookup_addr(tmpkt, &ad, 1);
+ if (flags & PFR_FLAG_FEEDBACK) {
+ if (q != NULL)
+ ad.pfra_fback = PFR_FB_DUPLICATE;
+ else if (p == NULL)
+ ad.pfra_fback = PFR_FB_ADDED;
+ else if (p->pfrke_not != ad.pfra_not)
+ ad.pfra_fback = PFR_FB_CONFLICT;
+ else
+ ad.pfra_fback = PFR_FB_NONE;
+ }
+ if (p == NULL && q == NULL) {
+ p = pfr_create_kentry(&ad,
+ !(flags & PFR_FLAG_USERIOCTL));
+ if (p == NULL)
+ senderr(ENOMEM);
+ if (pfr_route_kentry(tmpkt, p)) {
+ pfr_destroy_kentry(p);
+ ad.pfra_fback = PFR_FB_NONE;
+ } else {
+ SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
+ xadd++;
+ }
+ }
+ if (flags & PFR_FLAG_FEEDBACK)
+ if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
+ senderr(EFAULT);
+ }
+ pfr_clean_node_mask(tmpkt, &workq);
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ pfr_insert_kentries(kt, &workq, tzero);
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ } else
+ pfr_destroy_kentries(&workq);
+ if (nadd != NULL)
+ *nadd = xadd;
+ pfr_destroy_ktable(tmpkt, 0);
+ return (0);
+_bad:
+ pfr_clean_node_mask(tmpkt, &workq);
+ pfr_destroy_kentries(&workq);
+ if (flags & PFR_FLAG_FEEDBACK)
+ pfr_reset_feedback(addr, size, flags);
+ pfr_destroy_ktable(tmpkt, 0);
+ return (rv);
+}
+
+int
+pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
+ int *ndel, int flags)
+{
+ struct pfr_ktable *kt;
+ struct pfr_kentryworkq workq;
+ struct pfr_kentry *p;
+ struct pfr_addr ad;
+ int i, rv, s, xdel = 0, log = 1;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
+ PFR_FLAG_FEEDBACK);
+ if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
+ return (EINVAL);
+ kt = pfr_lookup_table(tbl);
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return (ESRCH);
+ if (kt->pfrkt_flags & PFR_TFLAG_CONST)
+ return (EPERM);
+ /*
+ * there are two algorithms to choose from here.
+ * with:
+ * n: number of addresses to delete
+ * N: number of addresses in the table
+ *
+ * one is O(N) and is better for large 'n'
+ * one is O(n*LOG(N)) and is better for small 'n'
+ *
+ * following code try to decide which one is best.
+ */
+ for (i = kt->pfrkt_cnt; i > 0; i >>= 1)
+ log++;
+ if (size > kt->pfrkt_cnt/log) {
+ /* full table scan */
+ pfr_mark_addrs(kt);
+ } else {
+ /* iterate over addresses to delete */
+ for (i = 0; i < size; i++) {
+ if (COPYIN(addr+i, &ad, sizeof(ad), flags))
+ return (EFAULT);
+ if (pfr_validate_addr(&ad))
+ return (EINVAL);
+ p = pfr_lookup_addr(kt, &ad, 1);
+ if (p != NULL)
+ p->pfrke_mark = 0;
+ }
+ }
+ SLIST_INIT(&workq);
+ for (i = 0; i < size; i++) {
+ if (COPYIN(addr+i, &ad, sizeof(ad), flags))
+ senderr(EFAULT);
+ if (pfr_validate_addr(&ad))
+ senderr(EINVAL);
+ p = pfr_lookup_addr(kt, &ad, 1);
+ if (flags & PFR_FLAG_FEEDBACK) {
+ if (p == NULL)
+ ad.pfra_fback = PFR_FB_NONE;
+ else if (p->pfrke_not != ad.pfra_not)
+ ad.pfra_fback = PFR_FB_CONFLICT;
+ else if (p->pfrke_mark)
+ ad.pfra_fback = PFR_FB_DUPLICATE;
+ else
+ ad.pfra_fback = PFR_FB_DELETED;
+ }
+ if (p != NULL && p->pfrke_not == ad.pfra_not &&
+ !p->pfrke_mark) {
+ p->pfrke_mark = 1;
+ SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
+ xdel++;
+ }
+ if (flags & PFR_FLAG_FEEDBACK)
+ if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
+ senderr(EFAULT);
+ }
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ pfr_remove_kentries(kt, &workq);
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ }
+ if (ndel != NULL)
+ *ndel = xdel;
+ return (0);
+_bad:
+ if (flags & PFR_FLAG_FEEDBACK)
+ pfr_reset_feedback(addr, size, flags);
+ return (rv);
+}
+
+int
+pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
+ int *size2, int *nadd, int *ndel, int *nchange, int flags,
+ u_int32_t ignore_pfrt_flags)
+{
+ struct pfr_ktable *kt, *tmpkt;
+ struct pfr_kentryworkq addq, delq, changeq;
+ struct pfr_kentry *p, *q;
+ struct pfr_addr ad;
+ int i, rv, s, xadd = 0, xdel = 0, xchange = 0;
+ long tzero = time_second;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
+ PFR_FLAG_FEEDBACK);
+ if (pfr_validate_table(tbl, ignore_pfrt_flags, flags &
+ PFR_FLAG_USERIOCTL))
+ return (EINVAL);
+ kt = pfr_lookup_table(tbl);
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return (ESRCH);
+ if (kt->pfrkt_flags & PFR_TFLAG_CONST)
+ return (EPERM);
+ tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0,
+ !(flags & PFR_FLAG_USERIOCTL));
+ if (tmpkt == NULL)
+ return (ENOMEM);
+ pfr_mark_addrs(kt);
+ SLIST_INIT(&addq);
+ SLIST_INIT(&delq);
+ SLIST_INIT(&changeq);
+ for (i = 0; i < size; i++) {
+ if (COPYIN(addr+i, &ad, sizeof(ad), flags))
+ senderr(EFAULT);
+ if (pfr_validate_addr(&ad))
+ senderr(EINVAL);
+ ad.pfra_fback = PFR_FB_NONE;
+ p = pfr_lookup_addr(kt, &ad, 1);
+ if (p != NULL) {
+ if (p->pfrke_mark) {
+ ad.pfra_fback = PFR_FB_DUPLICATE;
+ goto _skip;
+ }
+ p->pfrke_mark = 1;
+ if (p->pfrke_not != ad.pfra_not) {
+ SLIST_INSERT_HEAD(&changeq, p, pfrke_workq);
+ ad.pfra_fback = PFR_FB_CHANGED;
+ xchange++;
+ }
+ } else {
+ q = pfr_lookup_addr(tmpkt, &ad, 1);
+ if (q != NULL) {
+ ad.pfra_fback = PFR_FB_DUPLICATE;
+ goto _skip;
+ }
+ p = pfr_create_kentry(&ad,
+ !(flags & PFR_FLAG_USERIOCTL));
+ if (p == NULL)
+ senderr(ENOMEM);
+ if (pfr_route_kentry(tmpkt, p)) {
+ pfr_destroy_kentry(p);
+ ad.pfra_fback = PFR_FB_NONE;
+ } else {
+ SLIST_INSERT_HEAD(&addq, p, pfrke_workq);
+ ad.pfra_fback = PFR_FB_ADDED;
+ xadd++;
+ }
+ }
+_skip:
+ if (flags & PFR_FLAG_FEEDBACK)
+ if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
+ senderr(EFAULT);
+ }
+ pfr_enqueue_addrs(kt, &delq, &xdel, ENQUEUE_UNMARKED_ONLY);
+ if ((flags & PFR_FLAG_FEEDBACK) && *size2) {
+ if (*size2 < size+xdel) {
+ *size2 = size+xdel;
+ senderr(0);
+ }
+ i = 0;
+ SLIST_FOREACH(p, &delq, pfrke_workq) {
+ pfr_copyout_addr(&ad, p);
+ ad.pfra_fback = PFR_FB_DELETED;
+ if (COPYOUT(&ad, addr+size+i, sizeof(ad), flags))
+ senderr(EFAULT);
+ i++;
+ }
+ }
+ pfr_clean_node_mask(tmpkt, &addq);
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ pfr_insert_kentries(kt, &addq, tzero);
+ pfr_remove_kentries(kt, &delq);
+ pfr_clstats_kentries(&changeq, tzero, INVERT_NEG_FLAG);
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ } else
+ pfr_destroy_kentries(&addq);
+ if (nadd != NULL)
+ *nadd = xadd;
+ if (ndel != NULL)
+ *ndel = xdel;
+ if (nchange != NULL)
+ *nchange = xchange;
+ if ((flags & PFR_FLAG_FEEDBACK) && size2)
+ *size2 = size+xdel;
+ pfr_destroy_ktable(tmpkt, 0);
+ return (0);
+_bad:
+ pfr_clean_node_mask(tmpkt, &addq);
+ pfr_destroy_kentries(&addq);
+ if (flags & PFR_FLAG_FEEDBACK)
+ pfr_reset_feedback(addr, size, flags);
+ pfr_destroy_ktable(tmpkt, 0);
+ return (rv);
+}
+
+int
+pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
+ int *nmatch, int flags)
+{
+ struct pfr_ktable *kt;
+ struct pfr_kentry *p;
+ struct pfr_addr ad;
+ int i, xmatch = 0;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_REPLACE);
+ if (pfr_validate_table(tbl, 0, 0))
+ return (EINVAL);
+ kt = pfr_lookup_table(tbl);
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return (ESRCH);
+
+ for (i = 0; i < size; i++) {
+ if (COPYIN(addr+i, &ad, sizeof(ad), flags))
+ return (EFAULT);
+ if (pfr_validate_addr(&ad))
+ return (EINVAL);
+ if (ADDR_NETWORK(&ad))
+ return (EINVAL);
+ p = pfr_lookup_addr(kt, &ad, 0);
+ if (flags & PFR_FLAG_REPLACE)
+ pfr_copyout_addr(&ad, p);
+ ad.pfra_fback = (p == NULL) ? PFR_FB_NONE :
+ (p->pfrke_not ? PFR_FB_NOTMATCH : PFR_FB_MATCH);
+ if (p != NULL && !p->pfrke_not)
+ xmatch++;
+ if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
+ return (EFAULT);
+ }
+ if (nmatch != NULL)
+ *nmatch = xmatch;
+ return (0);
+}
+
+int
+pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size,
+ int flags)
+{
+ struct pfr_ktable *kt;
+ struct pfr_walktree w;
+ int rv;
+
+ ACCEPT_FLAGS(flags, 0);
+ if (pfr_validate_table(tbl, 0, 0))
+ return (EINVAL);
+ kt = pfr_lookup_table(tbl);
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return (ESRCH);
+ if (kt->pfrkt_cnt > *size) {
+ *size = kt->pfrkt_cnt;
+ return (0);
+ }
+
+ bzero(&w, sizeof(w));
+ w.pfrw_op = PFRW_GET_ADDRS;
+ w.pfrw_addr = addr;
+ w.pfrw_free = kt->pfrkt_cnt;
+ w.pfrw_flags = flags;
+#ifdef __FreeBSD__
+ rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+#else
+ rv = rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+#endif
+ if (!rv)
+#ifdef __FreeBSD__
+ rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
+ &w);
+#else
+ rv = rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
+#endif
+ if (rv)
+ return (rv);
+
+ if (w.pfrw_free) {
+ printf("pfr_get_addrs: corruption detected (%d).\n",
+ w.pfrw_free);
+ return (ENOTTY);
+ }
+ *size = kt->pfrkt_cnt;
+ return (0);
+}
+
+int
+pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
+ int flags)
+{
+ struct pfr_ktable *kt;
+ struct pfr_walktree w;
+ struct pfr_kentryworkq workq;
+ int rv, s;
+ long tzero = time_second;
+
+ /* XXX PFR_FLAG_CLSTATS disabled */
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC);
+ if (pfr_validate_table(tbl, 0, 0))
+ return (EINVAL);
+ kt = pfr_lookup_table(tbl);
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return (ESRCH);
+ if (kt->pfrkt_cnt > *size) {
+ *size = kt->pfrkt_cnt;
+ return (0);
+ }
+
+ bzero(&w, sizeof(w));
+ w.pfrw_op = PFRW_GET_ASTATS;
+ w.pfrw_astats = addr;
+ w.pfrw_free = kt->pfrkt_cnt;
+ w.pfrw_flags = flags;
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+#else
+ rv = rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+#endif
+ if (!rv)
+#ifdef __FreeBSD__
+ rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
+ &w);
+#else
+ rv = rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
+#endif
+ if (!rv && (flags & PFR_FLAG_CLSTATS)) {
+ pfr_enqueue_addrs(kt, &workq, NULL, 0);
+ pfr_clstats_kentries(&workq, tzero, 0);
+ }
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ if (rv)
+ return (rv);
+
+ if (w.pfrw_free) {
+ printf("pfr_get_astats: corruption detected (%d).\n",
+ w.pfrw_free);
+ return (ENOTTY);
+ }
+ *size = kt->pfrkt_cnt;
+ return (0);
+}
+
+int
+pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
+ int *nzero, int flags)
+{
+ struct pfr_ktable *kt;
+ struct pfr_kentryworkq workq;
+ struct pfr_kentry *p;
+ struct pfr_addr ad;
+ int i, rv, s, xzero = 0;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
+ PFR_FLAG_FEEDBACK);
+ if (pfr_validate_table(tbl, 0, 0))
+ return (EINVAL);
+ kt = pfr_lookup_table(tbl);
+ if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return (ESRCH);
+ SLIST_INIT(&workq);
+ for (i = 0; i < size; i++) {
+ if (COPYIN(addr+i, &ad, sizeof(ad), flags))
+ senderr(EFAULT);
+ if (pfr_validate_addr(&ad))
+ senderr(EINVAL);
+ p = pfr_lookup_addr(kt, &ad, 1);
+ if (flags & PFR_FLAG_FEEDBACK) {
+ ad.pfra_fback = (p != NULL) ?
+ PFR_FB_CLEARED : PFR_FB_NONE;
+ if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
+ senderr(EFAULT);
+ }
+ if (p != NULL) {
+ SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
+ xzero++;
+ }
+ }
+
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ pfr_clstats_kentries(&workq, 0, 0);
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ }
+ if (nzero != NULL)
+ *nzero = xzero;
+ return (0);
+_bad:
+ if (flags & PFR_FLAG_FEEDBACK)
+ pfr_reset_feedback(addr, size, flags);
+ return (rv);
+}
+
+int
+pfr_validate_addr(struct pfr_addr *ad)
+{
+ int i;
+
+ switch (ad->pfra_af) {
+#ifdef INET
+ case AF_INET:
+ if (ad->pfra_net > 32)
+ return (-1);
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ if (ad->pfra_net > 128)
+ return (-1);
+ break;
+#endif /* INET6 */
+ default:
+ return (-1);
+ }
+ if (ad->pfra_net < 128 &&
+ (((caddr_t)ad)[ad->pfra_net/8] & (0xFF >> (ad->pfra_net%8))))
+ return (-1);
+ for (i = (ad->pfra_net+7)/8; i < sizeof(ad->pfra_u); i++)
+ if (((caddr_t)ad)[i])
+ return (-1);
+ if (ad->pfra_not && ad->pfra_not != 1)
+ return (-1);
+ if (ad->pfra_fback)
+ return (-1);
+ return (0);
+}
+
+void
+pfr_enqueue_addrs(struct pfr_ktable *kt, struct pfr_kentryworkq *workq,
+ int *naddr, int sweep)
+{
+ struct pfr_walktree w;
+
+ SLIST_INIT(workq);
+ bzero(&w, sizeof(w));
+ w.pfrw_op = sweep ? PFRW_SWEEP : PFRW_ENQUEUE;
+ w.pfrw_workq = workq;
+ if (kt->pfrkt_ip4 != NULL)
+#ifdef __FreeBSD__
+ if (kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree,
+ &w))
+#else
+ if (rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
+#endif
+ printf("pfr_enqueue_addrs: IPv4 walktree failed.\n");
+ if (kt->pfrkt_ip6 != NULL)
+#ifdef __FreeBSD__
+ if (kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
+ &w))
+#else
+ if (rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
+#endif
+ printf("pfr_enqueue_addrs: IPv6 walktree failed.\n");
+ if (naddr != NULL)
+ *naddr = w.pfrw_cnt;
+}
+
+void
+pfr_mark_addrs(struct pfr_ktable *kt)
+{
+ struct pfr_walktree w;
+
+ bzero(&w, sizeof(w));
+ w.pfrw_op = PFRW_MARK;
+#ifdef __FreeBSD__
+ if (kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
+#else
+ if (rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
+#endif
+ printf("pfr_mark_addrs: IPv4 walktree failed.\n");
+#ifdef __FreeBSD__
+ if (kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
+#else
+ if (rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
+#endif
+ printf("pfr_mark_addrs: IPv6 walktree failed.\n");
+}
+
+
+struct pfr_kentry *
+pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
+{
+ union sockaddr_union sa, mask;
+#ifdef __FreeBSD__
+ struct radix_node_head *head = NULL;
+#else
+ struct radix_node_head *head;
+#endif
+ struct pfr_kentry *ke;
+ int s;
+
+ bzero(&sa, sizeof(sa));
+ if (ad->pfra_af == AF_INET) {
+ FILLIN_SIN(sa.sin, ad->pfra_ip4addr);
+ head = kt->pfrkt_ip4;
+ } else if ( ad->pfra_af == AF_INET6 ) {
+ FILLIN_SIN6(sa.sin6, ad->pfra_ip6addr);
+ head = kt->pfrkt_ip6;
+ }
+ if (ADDR_NETWORK(ad)) {
+ pfr_prepare_network(&mask, ad->pfra_af, ad->pfra_net);
+ s = splsoftnet(); /* rn_lookup makes use of globals */
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+#endif
+ ke = (struct pfr_kentry *)rn_lookup(&sa, &mask, head);
+ splx(s);
+ if (ke && KENTRY_RNF_ROOT(ke))
+ ke = NULL;
+ } else {
+ ke = (struct pfr_kentry *)rn_match(&sa, head);
+ if (ke && KENTRY_RNF_ROOT(ke))
+ ke = NULL;
+ if (exact && ke && KENTRY_NETWORK(ke))
+ ke = NULL;
+ }
+ return (ke);
+}
+
+struct pfr_kentry *
+pfr_create_kentry(struct pfr_addr *ad, int intr)
+{
+ struct pfr_kentry *ke;
+
+#ifdef __FreeBSD__
+ ke = pool_get(&V_pfr_kentry_pl, PR_NOWAIT | PR_ZERO);
+#else
+ if (intr)
+ ke = pool_get(&pfr_kentry_pl, PR_NOWAIT | PR_ZERO);
+ else
+ ke = pool_get(&pfr_kentry_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL);
+#endif
+ if (ke == NULL)
+ return (NULL);
+
+ if (ad->pfra_af == AF_INET)
+ FILLIN_SIN(ke->pfrke_sa.sin, ad->pfra_ip4addr);
+ else if (ad->pfra_af == AF_INET6)
+ FILLIN_SIN6(ke->pfrke_sa.sin6, ad->pfra_ip6addr);
+ ke->pfrke_af = ad->pfra_af;
+ ke->pfrke_net = ad->pfra_net;
+ ke->pfrke_not = ad->pfra_not;
+ return (ke);
+}
+
+void
+pfr_destroy_kentries(struct pfr_kentryworkq *workq)
+{
+ struct pfr_kentry *p, *q;
+
+ for (p = SLIST_FIRST(workq); p != NULL; p = q) {
+ q = SLIST_NEXT(p, pfrke_workq);
+ pfr_destroy_kentry(p);
+ }
+}
+
+void
+pfr_destroy_kentry(struct pfr_kentry *ke)
+{
+ if (ke->pfrke_counters)
+#ifdef __FreeBSD__
+ pool_put(&V_pfr_kcounters_pl, ke->pfrke_counters);
+ pool_put(&V_pfr_kentry_pl, ke);
+#else
+ pool_put(&pfr_kcounters_pl, ke->pfrke_counters);
+ pool_put(&pfr_kentry_pl, ke);
+#endif
+}
+
+void
+pfr_insert_kentries(struct pfr_ktable *kt,
+ struct pfr_kentryworkq *workq, long tzero)
+{
+ struct pfr_kentry *p;
+ int rv, n = 0;
+
+ SLIST_FOREACH(p, workq, pfrke_workq) {
+ rv = pfr_route_kentry(kt, p);
+ if (rv) {
+ printf("pfr_insert_kentries: cannot route entry "
+ "(code=%d).\n", rv);
+ break;
+ }
+ p->pfrke_tzero = tzero;
+ n++;
+ }
+ kt->pfrkt_cnt += n;
+}
+
+int
+pfr_insert_kentry(struct pfr_ktable *kt, struct pfr_addr *ad, long tzero)
+{
+ struct pfr_kentry *p;
+ int rv;
+
+ p = pfr_lookup_addr(kt, ad, 1);
+ if (p != NULL)
+ return (0);
+ p = pfr_create_kentry(ad, 1);
+ if (p == NULL)
+ return (EINVAL);
+
+ rv = pfr_route_kentry(kt, p);
+ if (rv)
+ return (rv);
+
+ p->pfrke_tzero = tzero;
+ kt->pfrkt_cnt++;
+
+ return (0);
+}
+
+void
+pfr_remove_kentries(struct pfr_ktable *kt,
+ struct pfr_kentryworkq *workq)
+{
+ struct pfr_kentry *p;
+ int n = 0;
+
+ SLIST_FOREACH(p, workq, pfrke_workq) {
+ pfr_unroute_kentry(kt, p);
+ n++;
+ }
+ kt->pfrkt_cnt -= n;
+ pfr_destroy_kentries(workq);
+}
+
+void
+pfr_clean_node_mask(struct pfr_ktable *kt,
+ struct pfr_kentryworkq *workq)
+{
+ struct pfr_kentry *p;
+
+ SLIST_FOREACH(p, workq, pfrke_workq)
+ pfr_unroute_kentry(kt, p);
+}
+
+void
+pfr_clstats_kentries(struct pfr_kentryworkq *workq, long tzero, int negchange)
+{
+ struct pfr_kentry *p;
+ int s;
+
+ SLIST_FOREACH(p, workq, pfrke_workq) {
+ s = splsoftnet();
+ if (negchange)
+ p->pfrke_not = !p->pfrke_not;
+ if (p->pfrke_counters) {
+#ifdef __FreeBSD__
+ pool_put(&V_pfr_kcounters_pl, p->pfrke_counters);
+#else
+ pool_put(&pfr_kcounters_pl, p->pfrke_counters);
+#endif
+ p->pfrke_counters = NULL;
+ }
+ splx(s);
+ p->pfrke_tzero = tzero;
+ }
+}
+
+void
+pfr_reset_feedback(struct pfr_addr *addr, int size, int flags)
+{
+ struct pfr_addr ad;
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (COPYIN(addr+i, &ad, sizeof(ad), flags))
+ break;
+ ad.pfra_fback = PFR_FB_NONE;
+ if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
+ break;
+ }
+}
+
+void
+pfr_prepare_network(union sockaddr_union *sa, int af, int net)
+{
+ int i;
+
+ bzero(sa, sizeof(*sa));
+ if (af == AF_INET) {
+ sa->sin.sin_len = sizeof(sa->sin);
+ sa->sin.sin_family = AF_INET;
+ sa->sin.sin_addr.s_addr = net ? htonl(-1 << (32-net)) : 0;
+ } else if (af == AF_INET6) {
+ sa->sin6.sin6_len = sizeof(sa->sin6);
+ sa->sin6.sin6_family = AF_INET6;
+ for (i = 0; i < 4; i++) {
+ if (net <= 32) {
+ sa->sin6.sin6_addr.s6_addr32[i] =
+ net ? htonl(-1 << (32-net)) : 0;
+ break;
+ }
+ sa->sin6.sin6_addr.s6_addr32[i] = 0xFFFFFFFF;
+ net -= 32;
+ }
+ }
+}
+
+int
+pfr_route_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
+{
+ union sockaddr_union mask;
+ struct radix_node *rn;
+#ifdef __FreeBSD__
+ struct radix_node_head *head = NULL;
+#else
+ struct radix_node_head *head;
+#endif
+ int s;
+
+ bzero(ke->pfrke_node, sizeof(ke->pfrke_node));
+ if (ke->pfrke_af == AF_INET)
+ head = kt->pfrkt_ip4;
+ else if (ke->pfrke_af == AF_INET6)
+ head = kt->pfrkt_ip6;
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+#endif
+ if (KENTRY_NETWORK(ke)) {
+ pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
+#ifdef __FreeBSD__
+ rn = rn_addroute(&ke->pfrke_sa, &mask, head, ke->pfrke_node);
+#else
+ rn = rn_addroute(&ke->pfrke_sa, &mask, head, ke->pfrke_node, 0);
+#endif
+ } else
+#ifdef __FreeBSD__
+ rn = rn_addroute(&ke->pfrke_sa, NULL, head, ke->pfrke_node);
+#else
+ rn = rn_addroute(&ke->pfrke_sa, NULL, head, ke->pfrke_node, 0);
+#endif
+ splx(s);
+
+ return (rn == NULL ? -1 : 0);
+}
+
+int
+pfr_unroute_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
+{
+ union sockaddr_union mask;
+ struct radix_node *rn;
+#ifdef __FreeBSD__
+ struct radix_node_head *head = NULL;
+#else
+ struct radix_node_head *head;
+#endif
+ int s;
+
+ if (ke->pfrke_af == AF_INET)
+ head = kt->pfrkt_ip4;
+ else if (ke->pfrke_af == AF_INET6)
+ head = kt->pfrkt_ip6;
+
+ s = splsoftnet();
+#ifdef __FreeBSD__
+ PF_LOCK_ASSERT();
+#endif
+ if (KENTRY_NETWORK(ke)) {
+ pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
+#ifdef __FreeBSD__
+ rn = rn_delete(&ke->pfrke_sa, &mask, head);
+#else
+ rn = rn_delete(&ke->pfrke_sa, &mask, head, NULL);
+#endif
+ } else
+#ifdef __FreeBSD__
+ rn = rn_delete(&ke->pfrke_sa, NULL, head);
+#else
+ rn = rn_delete(&ke->pfrke_sa, NULL, head, NULL);
+#endif
+ splx(s);
+
+ if (rn == NULL) {
+ printf("pfr_unroute_kentry: delete failed.\n");
+ return (-1);
+ }
+ return (0);
+}
+
+void
+pfr_copyout_addr(struct pfr_addr *ad, struct pfr_kentry *ke)
+{
+ bzero(ad, sizeof(*ad));
+ if (ke == NULL)
+ return;
+ ad->pfra_af = ke->pfrke_af;
+ ad->pfra_net = ke->pfrke_net;
+ ad->pfra_not = ke->pfrke_not;
+ if (ad->pfra_af == AF_INET)
+ ad->pfra_ip4addr = ke->pfrke_sa.sin.sin_addr;
+ else if (ad->pfra_af == AF_INET6)
+ ad->pfra_ip6addr = ke->pfrke_sa.sin6.sin6_addr;
+}
+
+int
+pfr_walktree(struct radix_node *rn, void *arg)
+{
+ struct pfr_kentry *ke = (struct pfr_kentry *)rn;
+ struct pfr_walktree *w = arg;
+ int s, flags = w->pfrw_flags;
+
+ switch (w->pfrw_op) {
+ case PFRW_MARK:
+ ke->pfrke_mark = 0;
+ break;
+ case PFRW_SWEEP:
+ if (ke->pfrke_mark)
+ break;
+ /* FALLTHROUGH */
+ case PFRW_ENQUEUE:
+ SLIST_INSERT_HEAD(w->pfrw_workq, ke, pfrke_workq);
+ w->pfrw_cnt++;
+ break;
+ case PFRW_GET_ADDRS:
+ if (w->pfrw_free-- > 0) {
+ struct pfr_addr ad;
+
+ pfr_copyout_addr(&ad, ke);
+ if (copyout(&ad, w->pfrw_addr, sizeof(ad)))
+ return (EFAULT);
+ w->pfrw_addr++;
+ }
+ break;
+ case PFRW_GET_ASTATS:
+ if (w->pfrw_free-- > 0) {
+ struct pfr_astats as;
+
+ pfr_copyout_addr(&as.pfras_a, ke);
+
+ s = splsoftnet();
+ if (ke->pfrke_counters) {
+ bcopy(ke->pfrke_counters->pfrkc_packets,
+ as.pfras_packets, sizeof(as.pfras_packets));
+ bcopy(ke->pfrke_counters->pfrkc_bytes,
+ as.pfras_bytes, sizeof(as.pfras_bytes));
+ } else {
+ bzero(as.pfras_packets, sizeof(as.pfras_packets));
+ bzero(as.pfras_bytes, sizeof(as.pfras_bytes));
+ as.pfras_a.pfra_fback = PFR_FB_NOCOUNT;
+ }
+ splx(s);
+ as.pfras_tzero = ke->pfrke_tzero;
+
+ if (COPYOUT(&as, w->pfrw_astats, sizeof(as), flags))
+ return (EFAULT);
+ w->pfrw_astats++;
+ }
+ break;
+ case PFRW_POOL_GET:
+ if (ke->pfrke_not)
+ break; /* negative entries are ignored */
+ if (!w->pfrw_cnt--) {
+ w->pfrw_kentry = ke;
+ return (1); /* finish search */
+ }
+ break;
+ case PFRW_DYNADDR_UPDATE:
+ if (ke->pfrke_af == AF_INET) {
+ if (w->pfrw_dyn->pfid_acnt4++ > 0)
+ break;
+#ifdef __FreeBSD__
+ pfr_prepare_network(&V_pfr_mask, AF_INET, ke->pfrke_net);
+#else
+ pfr_prepare_network(&pfr_mask, AF_INET, ke->pfrke_net);
+#endif
+ w->pfrw_dyn->pfid_addr4 = *SUNION2PF(
+ &ke->pfrke_sa, AF_INET);
+ w->pfrw_dyn->pfid_mask4 = *SUNION2PF(
+#ifdef __FreeBSD__
+ &V_pfr_mask, AF_INET);
+#else
+ &pfr_mask, AF_INET);
+#endif
+ } else if (ke->pfrke_af == AF_INET6){
+ if (w->pfrw_dyn->pfid_acnt6++ > 0)
+ break;
+#ifdef __FreeBSD__
+ pfr_prepare_network(&V_pfr_mask, AF_INET6, ke->pfrke_net);
+#else
+ pfr_prepare_network(&pfr_mask, AF_INET6, ke->pfrke_net);
+#endif
+ w->pfrw_dyn->pfid_addr6 = *SUNION2PF(
+ &ke->pfrke_sa, AF_INET6);
+ w->pfrw_dyn->pfid_mask6 = *SUNION2PF(
+#ifdef __FreeBSD__
+ &V_pfr_mask, AF_INET6);
+#else
+ &pfr_mask, AF_INET6);
+#endif
+ }
+ break;
+ }
+ return (0);
+}
+
+int
+pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags)
+{
+ struct pfr_ktableworkq workq;
+ struct pfr_ktable *p;
+ int s, xdel = 0;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
+ PFR_FLAG_ALLRSETS);
+ if (pfr_fix_anchor(filter->pfrt_anchor))
+ return (EINVAL);
+ if (pfr_table_count(filter, flags) < 0)
+ return (ENOENT);
+
+ SLIST_INIT(&workq);
+ RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
+ if (pfr_skip_table(filter, p, flags))
+ continue;
+ if (!strcmp(p->pfrkt_anchor, PF_RESERVED_ANCHOR))
+ continue;
+ if (!(p->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ continue;
+ p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_ACTIVE;
+ SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
+ xdel++;
+ }
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ pfr_setflags_ktables(&workq);
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ }
+ if (ndel != NULL)
+ *ndel = xdel;
+ return (0);
+}
+
+int
+pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
+{
+ struct pfr_ktableworkq addq, changeq;
+ struct pfr_ktable *p, *q, *r, key;
+ int i, rv, s, xadd = 0;
+ long tzero = time_second;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
+ SLIST_INIT(&addq);
+ SLIST_INIT(&changeq);
+ for (i = 0; i < size; i++) {
+ if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
+ senderr(EFAULT);
+ if (pfr_validate_table(&key.pfrkt_t, PFR_TFLAG_USRMASK,
+ flags & PFR_FLAG_USERIOCTL))
+ senderr(EINVAL);
+ key.pfrkt_flags |= PFR_TFLAG_ACTIVE;
+ p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
+ if (p == NULL) {
+ p = pfr_create_ktable(&key.pfrkt_t, tzero, 1,
+ !(flags & PFR_FLAG_USERIOCTL));
+ if (p == NULL)
+ senderr(ENOMEM);
+ SLIST_FOREACH(q, &addq, pfrkt_workq) {
+ if (!pfr_ktable_compare(p, q))
+ goto _skip;
+ }
+ SLIST_INSERT_HEAD(&addq, p, pfrkt_workq);
+ xadd++;
+ if (!key.pfrkt_anchor[0])
+ goto _skip;
+
+ /* find or create root table */
+ bzero(key.pfrkt_anchor, sizeof(key.pfrkt_anchor));
+ r = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
+ if (r != NULL) {
+ p->pfrkt_root = r;
+ goto _skip;
+ }
+ SLIST_FOREACH(q, &addq, pfrkt_workq) {
+ if (!pfr_ktable_compare(&key, q)) {
+ p->pfrkt_root = q;
+ goto _skip;
+ }
+ }
+ key.pfrkt_flags = 0;
+ r = pfr_create_ktable(&key.pfrkt_t, 0, 1,
+ !(flags & PFR_FLAG_USERIOCTL));
+ if (r == NULL)
+ senderr(ENOMEM);
+ SLIST_INSERT_HEAD(&addq, r, pfrkt_workq);
+ p->pfrkt_root = r;
+ } else if (!(p->pfrkt_flags & PFR_TFLAG_ACTIVE)) {
+ SLIST_FOREACH(q, &changeq, pfrkt_workq)
+ if (!pfr_ktable_compare(&key, q))
+ goto _skip;
+ p->pfrkt_nflags = (p->pfrkt_flags &
+ ~PFR_TFLAG_USRMASK) | key.pfrkt_flags;
+ SLIST_INSERT_HEAD(&changeq, p, pfrkt_workq);
+ xadd++;
+ }
+_skip:
+ ;
+ }
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ pfr_insert_ktables(&addq);
+ pfr_setflags_ktables(&changeq);
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ } else
+ pfr_destroy_ktables(&addq, 0);
+ if (nadd != NULL)
+ *nadd = xadd;
+ return (0);
+_bad:
+ pfr_destroy_ktables(&addq, 0);
+ return (rv);
+}
+
+int
+pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags)
+{
+ struct pfr_ktableworkq workq;
+ struct pfr_ktable *p, *q, key;
+ int i, s, xdel = 0;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
+ SLIST_INIT(&workq);
+ for (i = 0; i < size; i++) {
+ if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
+ return (EFAULT);
+ if (pfr_validate_table(&key.pfrkt_t, 0,
+ flags & PFR_FLAG_USERIOCTL))
+ return (EINVAL);
+ p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
+ if (p != NULL && (p->pfrkt_flags & PFR_TFLAG_ACTIVE)) {
+ SLIST_FOREACH(q, &workq, pfrkt_workq)
+ if (!pfr_ktable_compare(p, q))
+ goto _skip;
+ p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_ACTIVE;
+ SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
+ xdel++;
+ }
+_skip:
+ ;
+ }
+
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ pfr_setflags_ktables(&workq);
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ }
+ if (ndel != NULL)
+ *ndel = xdel;
+ return (0);
+}
+
+int
+pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size,
+ int flags)
+{
+ struct pfr_ktable *p;
+ int n, nn;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ALLRSETS);
+ if (pfr_fix_anchor(filter->pfrt_anchor))
+ return (EINVAL);
+ n = nn = pfr_table_count(filter, flags);
+ if (n < 0)
+ return (ENOENT);
+ if (n > *size) {
+ *size = n;
+ return (0);
+ }
+ RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
+ if (pfr_skip_table(filter, p, flags))
+ continue;
+ if (n-- <= 0)
+ continue;
+ if (COPYOUT(&p->pfrkt_t, tbl++, sizeof(*tbl), flags))
+ return (EFAULT);
+ }
+ if (n) {
+ printf("pfr_get_tables: corruption detected (%d).\n", n);
+ return (ENOTTY);
+ }
+ *size = nn;
+ return (0);
+}
+
+int
+pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
+ int flags)
+{
+ struct pfr_ktable *p;
+ struct pfr_ktableworkq workq;
+ int s, n, nn;
+ long tzero = time_second;
+
+ /* XXX PFR_FLAG_CLSTATS disabled */
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_ALLRSETS);
+ if (pfr_fix_anchor(filter->pfrt_anchor))
+ return (EINVAL);
+ n = nn = pfr_table_count(filter, flags);
+ if (n < 0)
+ return (ENOENT);
+ if (n > *size) {
+ *size = n;
+ return (0);
+ }
+ SLIST_INIT(&workq);
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
+ if (pfr_skip_table(filter, p, flags))
+ continue;
+ if (n-- <= 0)
+ continue;
+ if (!(flags & PFR_FLAG_ATOMIC))
+ s = splsoftnet();
+ if (COPYOUT(&p->pfrkt_ts, tbl++, sizeof(*tbl), flags)) {
+ splx(s);
+ return (EFAULT);
+ }
+ if (!(flags & PFR_FLAG_ATOMIC))
+ splx(s);
+ SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
+ }
+ if (flags & PFR_FLAG_CLSTATS)
+ pfr_clstats_ktables(&workq, tzero,
+ flags & PFR_FLAG_ADDRSTOO);
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ if (n) {
+ printf("pfr_get_tstats: corruption detected (%d).\n", n);
+ return (ENOTTY);
+ }
+ *size = nn;
+ return (0);
+}
+
+int
+pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
+{
+ struct pfr_ktableworkq workq;
+ struct pfr_ktable *p, key;
+ int i, s, xzero = 0;
+ long tzero = time_second;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
+ PFR_FLAG_ADDRSTOO);
+ SLIST_INIT(&workq);
+ for (i = 0; i < size; i++) {
+ if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
+ return (EFAULT);
+ if (pfr_validate_table(&key.pfrkt_t, 0, 0))
+ return (EINVAL);
+ p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
+ if (p != NULL) {
+ SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
+ xzero++;
+ }
+ }
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ pfr_clstats_ktables(&workq, tzero, flags & PFR_FLAG_ADDRSTOO);
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ }
+ if (nzero != NULL)
+ *nzero = xzero;
+ return (0);
+}
+
+int
+pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag,
+ int *nchange, int *ndel, int flags)
+{
+ struct pfr_ktableworkq workq;
+ struct pfr_ktable *p, *q, key;
+ int i, s, xchange = 0, xdel = 0;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
+ if ((setflag & ~PFR_TFLAG_USRMASK) ||
+ (clrflag & ~PFR_TFLAG_USRMASK) ||
+ (setflag & clrflag))
+ return (EINVAL);
+ SLIST_INIT(&workq);
+ for (i = 0; i < size; i++) {
+ if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
+ return (EFAULT);
+ if (pfr_validate_table(&key.pfrkt_t, 0,
+ flags & PFR_FLAG_USERIOCTL))
+ return (EINVAL);
+ p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
+ if (p != NULL && (p->pfrkt_flags & PFR_TFLAG_ACTIVE)) {
+ p->pfrkt_nflags = (p->pfrkt_flags | setflag) &
+ ~clrflag;
+ if (p->pfrkt_nflags == p->pfrkt_flags)
+ goto _skip;
+ SLIST_FOREACH(q, &workq, pfrkt_workq)
+ if (!pfr_ktable_compare(p, q))
+ goto _skip;
+ SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
+ if ((p->pfrkt_flags & PFR_TFLAG_PERSIST) &&
+ (clrflag & PFR_TFLAG_PERSIST) &&
+ !(p->pfrkt_flags & PFR_TFLAG_REFERENCED))
+ xdel++;
+ else
+ xchange++;
+ }
+_skip:
+ ;
+ }
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ pfr_setflags_ktables(&workq);
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ }
+ if (nchange != NULL)
+ *nchange = xchange;
+ if (ndel != NULL)
+ *ndel = xdel;
+ return (0);
+}
+
+int
+pfr_ina_begin(struct pfr_table *trs, u_int32_t *ticket, int *ndel, int flags)
+{
+ struct pfr_ktableworkq workq;
+ struct pfr_ktable *p;
+ struct pf_ruleset *rs;
+ int xdel = 0;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
+ rs = pf_find_or_create_ruleset(trs->pfrt_anchor);
+ if (rs == NULL)
+ return (ENOMEM);
+ SLIST_INIT(&workq);
+ RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
+ if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) ||
+ pfr_skip_table(trs, p, 0))
+ continue;
+ p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_INACTIVE;
+ SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
+ xdel++;
+ }
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ pfr_setflags_ktables(&workq);
+ if (ticket != NULL)
+ *ticket = ++rs->tticket;
+ rs->topen = 1;
+ } else
+ pf_remove_if_empty_ruleset(rs);
+ if (ndel != NULL)
+ *ndel = xdel;
+ return (0);
+}
+
+int
+pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
+ int *nadd, int *naddr, u_int32_t ticket, int flags)
+{
+ struct pfr_ktableworkq tableq;
+ struct pfr_kentryworkq addrq;
+ struct pfr_ktable *kt, *rt, *shadow, key;
+ struct pfr_kentry *p;
+ struct pfr_addr ad;
+ struct pf_ruleset *rs;
+ int i, rv, xadd = 0, xaddr = 0;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_ADDRSTOO);
+ if (size && !(flags & PFR_FLAG_ADDRSTOO))
+ return (EINVAL);
+ if (pfr_validate_table(tbl, PFR_TFLAG_USRMASK,
+ flags & PFR_FLAG_USERIOCTL))
+ return (EINVAL);
+ rs = pf_find_ruleset(tbl->pfrt_anchor);
+ if (rs == NULL || !rs->topen || ticket != rs->tticket)
+ return (EBUSY);
+ tbl->pfrt_flags |= PFR_TFLAG_INACTIVE;
+ SLIST_INIT(&tableq);
+ kt = RB_FIND(pfr_ktablehead, &pfr_ktables, (struct pfr_ktable *)tbl);
+ if (kt == NULL) {
+ kt = pfr_create_ktable(tbl, 0, 1,
+ !(flags & PFR_FLAG_USERIOCTL));
+ if (kt == NULL)
+ return (ENOMEM);
+ SLIST_INSERT_HEAD(&tableq, kt, pfrkt_workq);
+ xadd++;
+ if (!tbl->pfrt_anchor[0])
+ goto _skip;
+
+ /* find or create root table */
+ bzero(&key, sizeof(key));
+ strlcpy(key.pfrkt_name, tbl->pfrt_name, sizeof(key.pfrkt_name));
+ rt = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
+ if (rt != NULL) {
+ kt->pfrkt_root = rt;
+ goto _skip;
+ }
+ rt = pfr_create_ktable(&key.pfrkt_t, 0, 1,
+ !(flags & PFR_FLAG_USERIOCTL));
+ if (rt == NULL) {
+ pfr_destroy_ktables(&tableq, 0);
+ return (ENOMEM);
+ }
+ SLIST_INSERT_HEAD(&tableq, rt, pfrkt_workq);
+ kt->pfrkt_root = rt;
+ } else if (!(kt->pfrkt_flags & PFR_TFLAG_INACTIVE))
+ xadd++;
+_skip:
+ shadow = pfr_create_ktable(tbl, 0, 0, !(flags & PFR_FLAG_USERIOCTL));
+ if (shadow == NULL) {
+ pfr_destroy_ktables(&tableq, 0);
+ return (ENOMEM);
+ }
+ SLIST_INIT(&addrq);
+ for (i = 0; i < size; i++) {
+ if (COPYIN(addr+i, &ad, sizeof(ad), flags))
+ senderr(EFAULT);
+ if (pfr_validate_addr(&ad))
+ senderr(EINVAL);
+ if (pfr_lookup_addr(shadow, &ad, 1) != NULL)
+ continue;
+ p = pfr_create_kentry(&ad, 0);
+ if (p == NULL)
+ senderr(ENOMEM);
+ if (pfr_route_kentry(shadow, p)) {
+ pfr_destroy_kentry(p);
+ continue;
+ }
+ SLIST_INSERT_HEAD(&addrq, p, pfrke_workq);
+ xaddr++;
+ }
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (kt->pfrkt_shadow != NULL)
+ pfr_destroy_ktable(kt->pfrkt_shadow, 1);
+ kt->pfrkt_flags |= PFR_TFLAG_INACTIVE;
+ pfr_insert_ktables(&tableq);
+ shadow->pfrkt_cnt = (flags & PFR_FLAG_ADDRSTOO) ?
+ xaddr : NO_ADDRESSES;
+ kt->pfrkt_shadow = shadow;
+ } else {
+ pfr_clean_node_mask(shadow, &addrq);
+ pfr_destroy_ktable(shadow, 0);
+ pfr_destroy_ktables(&tableq, 0);
+ pfr_destroy_kentries(&addrq);
+ }
+ if (nadd != NULL)
+ *nadd = xadd;
+ if (naddr != NULL)
+ *naddr = xaddr;
+ return (0);
+_bad:
+ pfr_destroy_ktable(shadow, 0);
+ pfr_destroy_ktables(&tableq, 0);
+ pfr_destroy_kentries(&addrq);
+ return (rv);
+}
+
+int
+pfr_ina_rollback(struct pfr_table *trs, u_int32_t ticket, int *ndel, int flags)
+{
+ struct pfr_ktableworkq workq;
+ struct pfr_ktable *p;
+ struct pf_ruleset *rs;
+ int xdel = 0;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
+ rs = pf_find_ruleset(trs->pfrt_anchor);
+ if (rs == NULL || !rs->topen || ticket != rs->tticket)
+ return (0);
+ SLIST_INIT(&workq);
+ RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
+ if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) ||
+ pfr_skip_table(trs, p, 0))
+ continue;
+ p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_INACTIVE;
+ SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
+ xdel++;
+ }
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ pfr_setflags_ktables(&workq);
+ rs->topen = 0;
+ pf_remove_if_empty_ruleset(rs);
+ }
+ if (ndel != NULL)
+ *ndel = xdel;
+ return (0);
+}
+
+int
+pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
+ int *nchange, int flags)
+{
+ struct pfr_ktable *p, *q;
+ struct pfr_ktableworkq workq;
+ struct pf_ruleset *rs;
+ int s, xadd = 0, xchange = 0;
+ long tzero = time_second;
+
+ ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
+ rs = pf_find_ruleset(trs->pfrt_anchor);
+ if (rs == NULL || !rs->topen || ticket != rs->tticket)
+ return (EBUSY);
+
+ SLIST_INIT(&workq);
+ RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
+ if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) ||
+ pfr_skip_table(trs, p, 0))
+ continue;
+ SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
+ if (p->pfrkt_flags & PFR_TFLAG_ACTIVE)
+ xchange++;
+ else
+ xadd++;
+ }
+
+ if (!(flags & PFR_FLAG_DUMMY)) {
+ if (flags & PFR_FLAG_ATOMIC)
+ s = splsoftnet();
+ for (p = SLIST_FIRST(&workq); p != NULL; p = q) {
+ q = SLIST_NEXT(p, pfrkt_workq);
+ pfr_commit_ktable(p, tzero);
+ }
+ if (flags & PFR_FLAG_ATOMIC)
+ splx(s);
+ rs->topen = 0;
+ pf_remove_if_empty_ruleset(rs);
+ }
+ if (nadd != NULL)
+ *nadd = xadd;
+ if (nchange != NULL)
+ *nchange = xchange;
+
+ return (0);
+}
+
+void
+pfr_commit_ktable(struct pfr_ktable *kt, long tzero)
+{
+ struct pfr_ktable *shadow = kt->pfrkt_shadow;
+ int nflags;
+
+ if (shadow->pfrkt_cnt == NO_ADDRESSES) {
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ pfr_clstats_ktable(kt, tzero, 1);
+ } else if (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) {
+ /* kt might contain addresses */
+ struct pfr_kentryworkq addrq, addq, changeq, delq, garbageq;
+ struct pfr_kentry *p, *q, *next;
+ struct pfr_addr ad;
+
+ pfr_enqueue_addrs(shadow, &addrq, NULL, 0);
+ pfr_mark_addrs(kt);
+ SLIST_INIT(&addq);
+ SLIST_INIT(&changeq);
+ SLIST_INIT(&delq);
+ SLIST_INIT(&garbageq);
+ pfr_clean_node_mask(shadow, &addrq);
+ for (p = SLIST_FIRST(&addrq); p != NULL; p = next) {
+ next = SLIST_NEXT(p, pfrke_workq); /* XXX */
+ pfr_copyout_addr(&ad, p);
+ q = pfr_lookup_addr(kt, &ad, 1);
+ if (q != NULL) {
+ if (q->pfrke_not != p->pfrke_not)
+ SLIST_INSERT_HEAD(&changeq, q,
+ pfrke_workq);
+ q->pfrke_mark = 1;
+ SLIST_INSERT_HEAD(&garbageq, p, pfrke_workq);
+ } else {
+ p->pfrke_tzero = tzero;
+ SLIST_INSERT_HEAD(&addq, p, pfrke_workq);
+ }
+ }
+ pfr_enqueue_addrs(kt, &delq, NULL, ENQUEUE_UNMARKED_ONLY);
+ pfr_insert_kentries(kt, &addq, tzero);
+ pfr_remove_kentries(kt, &delq);
+ pfr_clstats_kentries(&changeq, tzero, INVERT_NEG_FLAG);
+ pfr_destroy_kentries(&garbageq);
+ } else {
+ /* kt cannot contain addresses */
+ SWAP(struct radix_node_head *, kt->pfrkt_ip4,
+ shadow->pfrkt_ip4);
+ SWAP(struct radix_node_head *, kt->pfrkt_ip6,
+ shadow->pfrkt_ip6);
+ SWAP(int, kt->pfrkt_cnt, shadow->pfrkt_cnt);
+ pfr_clstats_ktable(kt, tzero, 1);
+ }
+ nflags = ((shadow->pfrkt_flags & PFR_TFLAG_USRMASK) |
+ (kt->pfrkt_flags & PFR_TFLAG_SETMASK) | PFR_TFLAG_ACTIVE)
+ & ~PFR_TFLAG_INACTIVE;
+ pfr_destroy_ktable(shadow, 0);
+ kt->pfrkt_shadow = NULL;
+ pfr_setflags_ktable(kt, nflags);
+}
+
+int
+pfr_validate_table(struct pfr_table *tbl, int allowedflags, int no_reserved)
+{
+ int i;
+
+ if (!tbl->pfrt_name[0])
+ return (-1);
+ if (no_reserved && !strcmp(tbl->pfrt_anchor, PF_RESERVED_ANCHOR))
+ return (-1);
+ if (tbl->pfrt_name[PF_TABLE_NAME_SIZE-1])
+ return (-1);
+ for (i = strlen(tbl->pfrt_name); i < PF_TABLE_NAME_SIZE; i++)
+ if (tbl->pfrt_name[i])
+ return (-1);
+ if (pfr_fix_anchor(tbl->pfrt_anchor))
+ return (-1);
+ if (tbl->pfrt_flags & ~allowedflags)
+ return (-1);
+ return (0);
+}
+
+/*
+ * Rewrite anchors referenced by tables to remove slashes
+ * and check for validity.
+ */
+int
+pfr_fix_anchor(char *anchor)
+{
+ size_t siz = MAXPATHLEN;
+ int i;
+
+ if (anchor[0] == '/') {
+ char *path;
+ int off;
+
+ path = anchor;
+ off = 1;
+ while (*++path == '/')
+ off++;
+ bcopy(path, anchor, siz - off);
+ memset(anchor + siz - off, 0, off);
+ }
+ if (anchor[siz - 1])
+ return (-1);
+ for (i = strlen(anchor); i < siz; i++)
+ if (anchor[i])
+ return (-1);
+ return (0);
+}
+
+int
+pfr_table_count(struct pfr_table *filter, int flags)
+{
+ struct pf_ruleset *rs;
+
+ if (flags & PFR_FLAG_ALLRSETS)
+ return (pfr_ktable_cnt);
+ if (filter->pfrt_anchor[0]) {
+ rs = pf_find_ruleset(filter->pfrt_anchor);
+ return ((rs != NULL) ? rs->tables : -1);
+ }
+ return (pf_main_ruleset.tables);
+}
+
+int
+pfr_skip_table(struct pfr_table *filter, struct pfr_ktable *kt, int flags)
+{
+ if (flags & PFR_FLAG_ALLRSETS)
+ return (0);
+ if (strcmp(filter->pfrt_anchor, kt->pfrkt_anchor))
+ return (1);
+ return (0);
+}
+
+void
+pfr_insert_ktables(struct pfr_ktableworkq *workq)
+{
+ struct pfr_ktable *p;
+
+ SLIST_FOREACH(p, workq, pfrkt_workq)
+ pfr_insert_ktable(p);
+}
+
+void
+pfr_insert_ktable(struct pfr_ktable *kt)
+{
+ RB_INSERT(pfr_ktablehead, &pfr_ktables, kt);
+ pfr_ktable_cnt++;
+ if (kt->pfrkt_root != NULL)
+ if (!kt->pfrkt_root->pfrkt_refcnt[PFR_REFCNT_ANCHOR]++)
+ pfr_setflags_ktable(kt->pfrkt_root,
+ kt->pfrkt_root->pfrkt_flags|PFR_TFLAG_REFDANCHOR);
+}
+
+void
+pfr_setflags_ktables(struct pfr_ktableworkq *workq)
+{
+ struct pfr_ktable *p, *q;
+
+ for (p = SLIST_FIRST(workq); p; p = q) {
+ q = SLIST_NEXT(p, pfrkt_workq);
+ pfr_setflags_ktable(p, p->pfrkt_nflags);
+ }
+}
+
+void
+pfr_setflags_ktable(struct pfr_ktable *kt, int newf)
+{
+ struct pfr_kentryworkq addrq;
+
+ if (!(newf & PFR_TFLAG_REFERENCED) &&
+ !(newf & PFR_TFLAG_PERSIST))
+ newf &= ~PFR_TFLAG_ACTIVE;
+ if (!(newf & PFR_TFLAG_ACTIVE))
+ newf &= ~PFR_TFLAG_USRMASK;
+ if (!(newf & PFR_TFLAG_SETMASK)) {
+ RB_REMOVE(pfr_ktablehead, &pfr_ktables, kt);
+ if (kt->pfrkt_root != NULL)
+ if (!--kt->pfrkt_root->pfrkt_refcnt[PFR_REFCNT_ANCHOR])
+ pfr_setflags_ktable(kt->pfrkt_root,
+ kt->pfrkt_root->pfrkt_flags &
+ ~PFR_TFLAG_REFDANCHOR);
+ pfr_destroy_ktable(kt, 1);
+ pfr_ktable_cnt--;
+ return;
+ }
+ if (!(newf & PFR_TFLAG_ACTIVE) && kt->pfrkt_cnt) {
+ pfr_enqueue_addrs(kt, &addrq, NULL, 0);
+ pfr_remove_kentries(kt, &addrq);
+ }
+ if (!(newf & PFR_TFLAG_INACTIVE) && kt->pfrkt_shadow != NULL) {
+ pfr_destroy_ktable(kt->pfrkt_shadow, 1);
+ kt->pfrkt_shadow = NULL;
+ }
+ kt->pfrkt_flags = newf;
+}
+
+void
+pfr_clstats_ktables(struct pfr_ktableworkq *workq, long tzero, int recurse)
+{
+ struct pfr_ktable *p;
+
+ SLIST_FOREACH(p, workq, pfrkt_workq)
+ pfr_clstats_ktable(p, tzero, recurse);
+}
+
+void
+pfr_clstats_ktable(struct pfr_ktable *kt, long tzero, int recurse)
+{
+ struct pfr_kentryworkq addrq;
+ int s;
+
+ if (recurse) {
+ pfr_enqueue_addrs(kt, &addrq, NULL, 0);
+ pfr_clstats_kentries(&addrq, tzero, 0);
+ }
+ s = splsoftnet();
+ bzero(kt->pfrkt_packets, sizeof(kt->pfrkt_packets));
+ bzero(kt->pfrkt_bytes, sizeof(kt->pfrkt_bytes));
+ kt->pfrkt_match = kt->pfrkt_nomatch = 0;
+ splx(s);
+ kt->pfrkt_tzero = tzero;
+}
+
+struct pfr_ktable *
+pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset,
+ int intr)
+{
+ struct pfr_ktable *kt;
+ struct pf_ruleset *rs;
+
+#ifdef __FreeBSD__
+ kt = pool_get(&V_pfr_ktable_pl, PR_NOWAIT|PR_ZERO);
+#else
+ if (intr)
+ kt = pool_get(&pfr_ktable_pl, PR_NOWAIT|PR_ZERO|PR_LIMITFAIL);
+ else
+ kt = pool_get(&pfr_ktable_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL);
+#endif
+ if (kt == NULL)
+ return (NULL);
+ kt->pfrkt_t = *tbl;
+
+ if (attachruleset) {
+ rs = pf_find_or_create_ruleset(tbl->pfrt_anchor);
+ if (!rs) {
+ pfr_destroy_ktable(kt, 0);
+ return (NULL);
+ }
+ kt->pfrkt_rs = rs;
+ rs->tables++;
+ }
+
+ if (!rn_inithead((void **)&kt->pfrkt_ip4,
+ offsetof(struct sockaddr_in, sin_addr) * 8) ||
+ !rn_inithead((void **)&kt->pfrkt_ip6,
+ offsetof(struct sockaddr_in6, sin6_addr) * 8)) {
+ pfr_destroy_ktable(kt, 0);
+ return (NULL);
+ }
+ kt->pfrkt_tzero = tzero;
+
+ return (kt);
+}
+
+void
+pfr_destroy_ktables(struct pfr_ktableworkq *workq, int flushaddr)
+{
+ struct pfr_ktable *p, *q;
+
+ for (p = SLIST_FIRST(workq); p; p = q) {
+ q = SLIST_NEXT(p, pfrkt_workq);
+ pfr_destroy_ktable(p, flushaddr);
+ }
+}
+
+void
+pfr_destroy_ktable(struct pfr_ktable *kt, int flushaddr)
+{
+ struct pfr_kentryworkq addrq;
+
+ if (flushaddr) {
+ pfr_enqueue_addrs(kt, &addrq, NULL, 0);
+ pfr_clean_node_mask(kt, &addrq);
+ pfr_destroy_kentries(&addrq);
+ }
+#if defined(__FreeBSD__) && (__FreeBSD_version >= 500100)
+ if (kt->pfrkt_ip4 != NULL) {
+ RADIX_NODE_HEAD_DESTROY(kt->pfrkt_ip4);
+ free((caddr_t)kt->pfrkt_ip4, M_RTABLE);
+ }
+ if (kt->pfrkt_ip6 != NULL) {
+ RADIX_NODE_HEAD_DESTROY(kt->pfrkt_ip6);
+ free((caddr_t)kt->pfrkt_ip6, M_RTABLE);
+ }
+#else
+ if (kt->pfrkt_ip4 != NULL)
+ free((caddr_t)kt->pfrkt_ip4, M_RTABLE);
+ if (kt->pfrkt_ip6 != NULL)
+ free((caddr_t)kt->pfrkt_ip6, M_RTABLE);
+#endif
+ if (kt->pfrkt_shadow != NULL)
+ pfr_destroy_ktable(kt->pfrkt_shadow, flushaddr);
+ if (kt->pfrkt_rs != NULL) {
+ kt->pfrkt_rs->tables--;
+ pf_remove_if_empty_ruleset(kt->pfrkt_rs);
+ }
+#ifdef __FreeBSD__
+ pool_put(&V_pfr_ktable_pl, kt);
+#else
+ pool_put(&pfr_ktable_pl, kt);
+#endif
+}
+
+int
+pfr_ktable_compare(struct pfr_ktable *p, struct pfr_ktable *q)
+{
+ int d;
+
+ if ((d = strncmp(p->pfrkt_name, q->pfrkt_name, PF_TABLE_NAME_SIZE)))
+ return (d);
+ return (strcmp(p->pfrkt_anchor, q->pfrkt_anchor));
+}
+
+struct pfr_ktable *
+pfr_lookup_table(struct pfr_table *tbl)
+{
+ /* struct pfr_ktable start like a struct pfr_table */
+ return (RB_FIND(pfr_ktablehead, &pfr_ktables,
+ (struct pfr_ktable *)tbl));
+}
+
+int
+pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
+{
+ struct pfr_kentry *ke = NULL;
+ int match;
+
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
+ kt = kt->pfrkt_root;
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return (0);
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+#ifdef __FreeBSD__
+ V_pfr_sin.sin_addr.s_addr = a->addr32[0];
+ ke = (struct pfr_kentry *)rn_match(&V_pfr_sin, kt->pfrkt_ip4);
+#else
+ pfr_sin.sin_addr.s_addr = a->addr32[0];
+ ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4);
+#endif
+ if (ke && KENTRY_RNF_ROOT(ke))
+ ke = NULL;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+#ifdef __FreeBSD__
+ bcopy(a, &V_pfr_sin6.sin6_addr, sizeof(V_pfr_sin6.sin6_addr));
+ ke = (struct pfr_kentry *)rn_match(&V_pfr_sin6, kt->pfrkt_ip6);
+#else
+ bcopy(a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
+ ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6);
+#endif
+ if (ke && KENTRY_RNF_ROOT(ke))
+ ke = NULL;
+ break;
+#endif /* INET6 */
+ }
+ match = (ke && !ke->pfrke_not);
+ if (match)
+ kt->pfrkt_match++;
+ else
+ kt->pfrkt_nomatch++;
+ return (match);
+}
+
+void
+pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
+ u_int64_t len, int dir_out, int op_pass, int notrule)
+{
+ struct pfr_kentry *ke = NULL;
+
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
+ kt = kt->pfrkt_root;
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return;
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+#ifdef __FreeBSD__
+ V_pfr_sin.sin_addr.s_addr = a->addr32[0];
+ ke = (struct pfr_kentry *)rn_match(&V_pfr_sin, kt->pfrkt_ip4);
+#else
+ pfr_sin.sin_addr.s_addr = a->addr32[0];
+ ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4);
+#endif
+ if (ke && KENTRY_RNF_ROOT(ke))
+ ke = NULL;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+#ifdef __FreeBSD__
+ bcopy(a, &V_pfr_sin6.sin6_addr, sizeof(V_pfr_sin6.sin6_addr));
+ ke = (struct pfr_kentry *)rn_match(&V_pfr_sin6, kt->pfrkt_ip6);
+#else
+ bcopy(a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
+ ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6);
+#endif
+ if (ke && KENTRY_RNF_ROOT(ke))
+ ke = NULL;
+ break;
+#endif /* INET6 */
+ default:
+ ;
+ }
+ if ((ke == NULL || ke->pfrke_not) != notrule) {
+ if (op_pass != PFR_OP_PASS)
+ printf("pfr_update_stats: assertion failed.\n");
+ op_pass = PFR_OP_XPASS;
+ }
+ kt->pfrkt_packets[dir_out][op_pass]++;
+ kt->pfrkt_bytes[dir_out][op_pass] += len;
+ if (ke != NULL && op_pass != PFR_OP_XPASS &&
+ (kt->pfrkt_flags & PFR_TFLAG_COUNTERS)) {
+ if (ke->pfrke_counters == NULL)
+#ifdef __FreeBSD__
+ ke->pfrke_counters = pool_get(&V_pfr_kcounters_pl,
+#else
+ ke->pfrke_counters = pool_get(&pfr_kcounters_pl,
+#endif
+ PR_NOWAIT | PR_ZERO);
+ if (ke->pfrke_counters != NULL) {
+ ke->pfrke_counters->pfrkc_packets[dir_out][op_pass]++;
+ ke->pfrke_counters->pfrkc_bytes[dir_out][op_pass] += len;
+ }
+ }
+}
+
+struct pfr_ktable *
+pfr_attach_table(struct pf_ruleset *rs, char *name, int intr)
+{
+ struct pfr_ktable *kt, *rt;
+ struct pfr_table tbl;
+ struct pf_anchor *ac = rs->anchor;
+
+ bzero(&tbl, sizeof(tbl));
+ strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name));
+ if (ac != NULL)
+ strlcpy(tbl.pfrt_anchor, ac->path, sizeof(tbl.pfrt_anchor));
+ kt = pfr_lookup_table(&tbl);
+ if (kt == NULL) {
+ kt = pfr_create_ktable(&tbl, time_second, 1, intr);
+ if (kt == NULL)
+ return (NULL);
+ if (ac != NULL) {
+ bzero(tbl.pfrt_anchor, sizeof(tbl.pfrt_anchor));
+ rt = pfr_lookup_table(&tbl);
+ if (rt == NULL) {
+ rt = pfr_create_ktable(&tbl, 0, 1, intr);
+ if (rt == NULL) {
+ pfr_destroy_ktable(kt, 0);
+ return (NULL);
+ }
+ pfr_insert_ktable(rt);
+ }
+ kt->pfrkt_root = rt;
+ }
+ pfr_insert_ktable(kt);
+ }
+ if (!kt->pfrkt_refcnt[PFR_REFCNT_RULE]++)
+ pfr_setflags_ktable(kt, kt->pfrkt_flags|PFR_TFLAG_REFERENCED);
+ return (kt);
+}
+
+void
+pfr_detach_table(struct pfr_ktable *kt)
+{
+ if (kt->pfrkt_refcnt[PFR_REFCNT_RULE] <= 0)
+ printf("pfr_detach_table: refcount = %d.\n",
+ kt->pfrkt_refcnt[PFR_REFCNT_RULE]);
+ else if (!--kt->pfrkt_refcnt[PFR_REFCNT_RULE])
+ pfr_setflags_ktable(kt, kt->pfrkt_flags&~PFR_TFLAG_REFERENCED);
+}
+
+int
+pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
+ struct pf_addr **raddr, struct pf_addr **rmask, sa_family_t af)
+{
+#ifdef __FreeBSD__
+ struct pfr_kentry *ke, *ke2 = NULL;
+ struct pf_addr *addr = NULL;
+#else
+ struct pfr_kentry *ke, *ke2;
+ struct pf_addr *addr;
+#endif
+ union sockaddr_union mask;
+ int idx = -1, use_counter = 0;
+
+#ifdef __FreeBSD__
+ if (af == AF_INET)
+ addr = (struct pf_addr *)&V_pfr_sin.sin_addr;
+ else if (af == AF_INET6)
+ addr = (struct pf_addr *)&V_pfr_sin6.sin6_addr;
+#else
+ if (af == AF_INET)
+ addr = (struct pf_addr *)&pfr_sin.sin_addr;
+ else if (af == AF_INET6)
+ addr = (struct pf_addr *)&pfr_sin6.sin6_addr;
+#endif
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
+ kt = kt->pfrkt_root;
+ if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+ return (-1);
+
+ if (pidx != NULL)
+ idx = *pidx;
+ if (counter != NULL && idx >= 0)
+ use_counter = 1;
+ if (idx < 0)
+ idx = 0;
+
+_next_block:
+ ke = pfr_kentry_byidx(kt, idx, af);
+ if (ke == NULL) {
+ kt->pfrkt_nomatch++;
+ return (1);
+ }
+#ifdef __FreeBSD__
+ pfr_prepare_network(&V_pfr_mask, af, ke->pfrke_net);
+#else
+ pfr_prepare_network(&pfr_mask, af, ke->pfrke_net);
+#endif
+ *raddr = SUNION2PF(&ke->pfrke_sa, af);
+#ifdef __FreeBSD__
+ *rmask = SUNION2PF(&V_pfr_mask, af);
+#else
+ *rmask = SUNION2PF(&pfr_mask, af);
+#endif
+
+ if (use_counter) {
+ /* is supplied address within block? */
+ if (!PF_MATCHA(0, *raddr, *rmask, counter, af)) {
+ /* no, go to next block in table */
+ idx++;
+ use_counter = 0;
+ goto _next_block;
+ }
+ PF_ACPY(addr, counter, af);
+ } else {
+ /* use first address of block */
+ PF_ACPY(addr, *raddr, af);
+ }
+
+ if (!KENTRY_NETWORK(ke)) {
+ /* this is a single IP address - no possible nested block */
+ PF_ACPY(counter, addr, af);
+ *pidx = idx;
+ kt->pfrkt_match++;
+ return (0);
+ }
+ for (;;) {
+ /* we don't want to use a nested block */
+#ifdef __FreeBSD__
+ if (af == AF_INET)
+ ke2 = (struct pfr_kentry *)rn_match(&V_pfr_sin,
+ kt->pfrkt_ip4);
+ else if (af == AF_INET6)
+ ke2 = (struct pfr_kentry *)rn_match(&V_pfr_sin6,
+ kt->pfrkt_ip6);
+#else
+ if (af == AF_INET)
+ ke2 = (struct pfr_kentry *)rn_match(&pfr_sin,
+ kt->pfrkt_ip4);
+ else if (af == AF_INET6)
+ ke2 = (struct pfr_kentry *)rn_match(&pfr_sin6,
+ kt->pfrkt_ip6);
+#endif
+ /* no need to check KENTRY_RNF_ROOT() here */
+ if (ke2 == ke) {
+ /* lookup return the same block - perfect */
+ PF_ACPY(counter, addr, af);
+ *pidx = idx;
+ kt->pfrkt_match++;
+ return (0);
+ }
+
+ /* we need to increase the counter past the nested block */
+ pfr_prepare_network(&mask, AF_INET, ke2->pfrke_net);
+#ifdef __FreeBSD__
+ PF_POOLMASK(addr, addr, SUNION2PF(&mask, af), &V_pfr_ffaddr, af);
+#else
+ PF_POOLMASK(addr, addr, SUNION2PF(&mask, af), &pfr_ffaddr, af);
+#endif
+ PF_AINC(addr, af);
+ if (!PF_MATCHA(0, *raddr, *rmask, addr, af)) {
+ /* ok, we reached the end of our main block */
+ /* go to next block in table */
+ idx++;
+ use_counter = 0;
+ goto _next_block;
+ }
+ }
+}
+
+struct pfr_kentry *
+pfr_kentry_byidx(struct pfr_ktable *kt, int idx, int af)
+{
+ struct pfr_walktree w;
+
+ bzero(&w, sizeof(w));
+ w.pfrw_op = PFRW_POOL_GET;
+ w.pfrw_cnt = idx;
+
+ switch (af) {
+#ifdef INET
+ case AF_INET:
+#ifdef __FreeBSD__
+ kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+#else
+ rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+#endif
+ return (w.pfrw_kentry);
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+#ifdef __FreeBSD__
+ kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
+#else
+ rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
+#endif
+ return (w.pfrw_kentry);
+#endif /* INET6 */
+ default:
+ return (NULL);
+ }
+}
+
+void
+pfr_dynaddr_update(struct pfr_ktable *kt, struct pfi_dynaddr *dyn)
+{
+ struct pfr_walktree w;
+ int s;
+
+ bzero(&w, sizeof(w));
+ w.pfrw_op = PFRW_DYNADDR_UPDATE;
+ w.pfrw_dyn = dyn;
+
+ s = splsoftnet();
+ dyn->pfid_acnt4 = 0;
+ dyn->pfid_acnt6 = 0;
+ if (!dyn->pfid_af || dyn->pfid_af == AF_INET)
+#ifdef __FreeBSD__
+ kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+#else
+ rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+#endif
+ if (!dyn->pfid_af || dyn->pfid_af == AF_INET6)
+#ifdef __FreeBSD__
+ kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
+#else
+ rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
+#endif
+ splx(s);
+}
diff --git a/sys/contrib/pf/net/pfvar.h b/sys/contrib/pf/net/pfvar.h
new file mode 100644
index 0000000..dab70c5
--- /dev/null
+++ b/sys/contrib/pf/net/pfvar.h
@@ -0,0 +1,2234 @@
+/* $OpenBSD: pfvar.h,v 1.282 2009/01/29 15:12:28 pyr Exp $ */
+
+/*
+ * Copyright (c) 2001 Daniel Hartmeier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef _NET_PFVAR_H_
+#define _NET_PFVAR_H_
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+#ifdef __FreeBSD__
+#include <sys/lock.h>
+#include <sys/sx.h>
+#else
+#include <sys/rwlock.h>
+#endif
+
+#include <net/radix.h>
+#include <net/route.h>
+#ifdef __FreeBSD__
+#include <net/if_clone.h>
+#include <net/pf_mtag.h>
+#include <vm/uma.h>
+#else
+#include <netinet/ip_ipsp.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <netinet/in.h>
+#endif
+
+#include <netinet/tcp_fsm.h>
+
+struct ip;
+struct ip6_hdr;
+#ifdef __FreeBSD__
+struct inpcb;
+#endif
+
+#define PF_TCPS_PROXY_SRC ((TCP_NSTATES)+0)
+#define PF_TCPS_PROXY_DST ((TCP_NSTATES)+1)
+
+#define PF_MD5_DIGEST_LENGTH 16
+#ifdef MD5_DIGEST_LENGTH
+#if PF_MD5_DIGEST_LENGTH != MD5_DIGEST_LENGTH
+#error
+#endif
+#endif
+
+enum { PF_INOUT, PF_IN, PF_OUT };
+enum { PF_PASS, PF_DROP, PF_SCRUB, PF_NOSCRUB, PF_NAT, PF_NONAT,
+ PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP, PF_DEFER };
+enum { PF_RULESET_SCRUB, PF_RULESET_FILTER, PF_RULESET_NAT,
+ PF_RULESET_BINAT, PF_RULESET_RDR, PF_RULESET_MAX };
+enum { PF_OP_NONE, PF_OP_IRG, PF_OP_EQ, PF_OP_NE, PF_OP_LT,
+ PF_OP_LE, PF_OP_GT, PF_OP_GE, PF_OP_XRG, PF_OP_RRG };
+enum { PF_DEBUG_NONE, PF_DEBUG_URGENT, PF_DEBUG_MISC, PF_DEBUG_NOISY };
+enum { PF_CHANGE_NONE, PF_CHANGE_ADD_HEAD, PF_CHANGE_ADD_TAIL,
+ PF_CHANGE_ADD_BEFORE, PF_CHANGE_ADD_AFTER,
+ PF_CHANGE_REMOVE, PF_CHANGE_GET_TICKET };
+enum { PF_GET_NONE, PF_GET_CLR_CNTR };
+enum { PF_SK_WIRE, PF_SK_STACK, PF_SK_BOTH };
+
+/*
+ * Note about PFTM_*: real indices into pf_rule.timeout[] come before
+ * PFTM_MAX, special cases afterwards. See pf_state_expires().
+ */
+enum { PFTM_TCP_FIRST_PACKET, PFTM_TCP_OPENING, PFTM_TCP_ESTABLISHED,
+ PFTM_TCP_CLOSING, PFTM_TCP_FIN_WAIT, PFTM_TCP_CLOSED,
+ PFTM_UDP_FIRST_PACKET, PFTM_UDP_SINGLE, PFTM_UDP_MULTIPLE,
+ PFTM_ICMP_FIRST_PACKET, PFTM_ICMP_ERROR_REPLY,
+ PFTM_OTHER_FIRST_PACKET, PFTM_OTHER_SINGLE,
+ PFTM_OTHER_MULTIPLE, PFTM_FRAG, PFTM_INTERVAL,
+ PFTM_ADAPTIVE_START, PFTM_ADAPTIVE_END, PFTM_SRC_NODE,
+ PFTM_TS_DIFF, PFTM_MAX, PFTM_PURGE, PFTM_UNLINKED,
+ PFTM_UNTIL_PACKET };
+
+/* PFTM default values */
+#define PFTM_TCP_FIRST_PACKET_VAL 120 /* First TCP packet */
+#define PFTM_TCP_OPENING_VAL 30 /* No response yet */
+#define PFTM_TCP_ESTABLISHED_VAL 24*60*60/* Established */
+#define PFTM_TCP_CLOSING_VAL 15 * 60 /* Half closed */
+#define PFTM_TCP_FIN_WAIT_VAL 45 /* Got both FINs */
+#define PFTM_TCP_CLOSED_VAL 90 /* Got a RST */
+#define PFTM_UDP_FIRST_PACKET_VAL 60 /* First UDP packet */
+#define PFTM_UDP_SINGLE_VAL 30 /* Unidirectional */
+#define PFTM_UDP_MULTIPLE_VAL 60 /* Bidirectional */
+#define PFTM_ICMP_FIRST_PACKET_VAL 20 /* First ICMP packet */
+#define PFTM_ICMP_ERROR_REPLY_VAL 10 /* Got error response */
+#define PFTM_OTHER_FIRST_PACKET_VAL 60 /* First packet */
+#define PFTM_OTHER_SINGLE_VAL 30 /* Unidirectional */
+#define PFTM_OTHER_MULTIPLE_VAL 60 /* Bidirectional */
+#define PFTM_FRAG_VAL 30 /* Fragment expire */
+#define PFTM_INTERVAL_VAL 10 /* Expire interval */
+#define PFTM_SRC_NODE_VAL 0 /* Source tracking */
+#define PFTM_TS_DIFF_VAL 30 /* Allowed TS diff */
+
+enum { PF_NOPFROUTE, PF_FASTROUTE, PF_ROUTETO, PF_DUPTO, PF_REPLYTO };
+enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS,
+ PF_LIMIT_TABLES, PF_LIMIT_TABLE_ENTRIES, PF_LIMIT_MAX };
+#define PF_POOL_IDMASK 0x0f
+enum { PF_POOL_NONE, PF_POOL_BITMASK, PF_POOL_RANDOM,
+ PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN };
+enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
+ PF_ADDR_TABLE, PF_ADDR_RTLABEL, PF_ADDR_URPFFAILED,
+ PF_ADDR_RANGE };
+#define PF_POOL_TYPEMASK 0x0f
+#define PF_POOL_STICKYADDR 0x20
+#define PF_WSCALE_FLAG 0x80
+#define PF_WSCALE_MASK 0x0f
+
+#define PF_LOG 0x01
+#define PF_LOG_ALL 0x02
+#define PF_LOG_SOCKET_LOOKUP 0x04
+
+struct pf_addr {
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ u_int8_t addr8[16];
+ u_int16_t addr16[8];
+ u_int32_t addr32[4];
+ } pfa; /* 128-bit address */
+#define v4 pfa.v4
+#define v6 pfa.v6
+#define addr8 pfa.addr8
+#define addr16 pfa.addr16
+#define addr32 pfa.addr32
+};
+
+#define PF_TABLE_NAME_SIZE 32
+
+#define PFI_AFLAG_NETWORK 0x01
+#define PFI_AFLAG_BROADCAST 0x02
+#define PFI_AFLAG_PEER 0x04
+#define PFI_AFLAG_MODEMASK 0x07
+#define PFI_AFLAG_NOALIAS 0x08
+
+struct pf_addr_wrap {
+ union {
+ struct {
+ struct pf_addr addr;
+ struct pf_addr mask;
+ } a;
+ char ifname[IFNAMSIZ];
+ char tblname[PF_TABLE_NAME_SIZE];
+#ifdef __FreeBSD__
+#define RTLABEL_LEN 32
+#endif
+ char rtlabelname[RTLABEL_LEN];
+ u_int32_t rtlabel;
+ } v;
+ union {
+ struct pfi_dynaddr *dyn;
+ struct pfr_ktable *tbl;
+ int dyncnt;
+ int tblcnt;
+ } p;
+ u_int8_t type; /* PF_ADDR_* */
+ u_int8_t iflags; /* PFI_AFLAG_* */
+};
+
+#ifdef _KERNEL
+
+struct pfi_dynaddr {
+ TAILQ_ENTRY(pfi_dynaddr) entry;
+ struct pf_addr pfid_addr4;
+ struct pf_addr pfid_mask4;
+ struct pf_addr pfid_addr6;
+ struct pf_addr pfid_mask6;
+ struct pfr_ktable *pfid_kt;
+ struct pfi_kif *pfid_kif;
+ void *pfid_hook_cookie;
+ int pfid_net; /* mask or 128 */
+ int pfid_acnt4; /* address count IPv4 */
+ int pfid_acnt6; /* address count IPv6 */
+ sa_family_t pfid_af; /* rule af */
+ u_int8_t pfid_iflags; /* PFI_AFLAG_* */
+};
+
+/*
+ * Address manipulation macros
+ */
+
+#ifdef __FreeBSD__
+#define splsoftnet() splnet()
+
+#define HTONL(x) (x) = htonl((__uint32_t)(x))
+#define HTONS(x) (x) = htons((__uint16_t)(x))
+#define NTOHL(x) (x) = ntohl((__uint32_t)(x))
+#define NTOHS(x) (x) = ntohs((__uint16_t)(x))
+
+#define PF_NAME "pf"
+
+#define PR_NOWAIT M_NOWAIT
+#define PR_WAITOK M_WAITOK
+#define PR_ZERO M_ZERO
+#define pool_get(p, f) uma_zalloc(*(p), (f))
+#define pool_put(p, o) uma_zfree(*(p), (o))
+
+#define UMA_CREATE(var, type, desc) \
+ var = uma_zcreate(desc, sizeof(type), \
+ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); \
+ if (var == NULL) \
+ break
+#define UMA_DESTROY(var) \
+ if (var) \
+ uma_zdestroy(var)
+
+#ifdef __FreeBSD__
+extern struct mtx pf_task_mtx;
+
+#define PF_LOCK_ASSERT() mtx_assert(&pf_task_mtx, MA_OWNED)
+#define PF_UNLOCK_ASSERT() mtx_assert(&pf_task_mtx, MA_NOTOWNED)
+#define PF_LOCK() mtx_lock(&pf_task_mtx)
+#define PF_UNLOCK() mtx_unlock(&pf_task_mtx)
+#else
+#define PF_LOCK_ASSERT()
+#define PF_UNLOCK_ASSERT()
+#define PF_LOCK()
+#define PF_UNLOCK()
+#endif /* __FreeBSD__ */
+
+#define PF_COPYIN(uaddr, kaddr, len, r) do { \
+ PF_UNLOCK(); \
+ r = copyin((uaddr), (kaddr), (len)); \
+ PF_LOCK(); \
+} while(0)
+
+#define PF_COPYOUT(kaddr, uaddr, len, r) do { \
+ PF_UNLOCK(); \
+ r = copyout((kaddr), (uaddr), (len)); \
+ PF_LOCK(); \
+} while(0)
+
+#define PF_MODVER 1
+#define PFLOG_MODVER 1
+#define PFSYNC_MODVER 1
+
+#define PFLOG_MINVER 1
+#define PFLOG_PREFVER PFLOG_MODVER
+#define PFLOG_MAXVER 1
+#define PFSYNC_MINVER 1
+#define PFSYNC_PREFVER PFSYNC_MODVER
+#define PFSYNC_MAXVER 1
+#endif /* __FreeBSD__ */
+#ifdef INET
+#ifndef INET6
+#define PF_INET_ONLY
+#endif /* ! INET6 */
+#endif /* INET */
+
+#ifdef INET6
+#ifndef INET
+#define PF_INET6_ONLY
+#endif /* ! INET */
+#endif /* INET6 */
+
+#ifdef INET
+#ifdef INET6
+#define PF_INET_INET6
+#endif /* INET6 */
+#endif /* INET */
+
+#else
+
+#define PF_INET_INET6
+
+#endif /* _KERNEL */
+
+/* Both IPv4 and IPv6 */
+#ifdef PF_INET_INET6
+
+#define PF_AEQ(a, b, c) \
+ ((c == AF_INET && (a)->addr32[0] == (b)->addr32[0]) || \
+ ((a)->addr32[3] == (b)->addr32[3] && \
+ (a)->addr32[2] == (b)->addr32[2] && \
+ (a)->addr32[1] == (b)->addr32[1] && \
+ (a)->addr32[0] == (b)->addr32[0])) \
+
+#define PF_ANEQ(a, b, c) \
+ ((c == AF_INET && (a)->addr32[0] != (b)->addr32[0]) || \
+ ((a)->addr32[3] != (b)->addr32[3] || \
+ (a)->addr32[2] != (b)->addr32[2] || \
+ (a)->addr32[1] != (b)->addr32[1] || \
+ (a)->addr32[0] != (b)->addr32[0])) \
+
+#define PF_AZERO(a, c) \
+ ((c == AF_INET && !(a)->addr32[0]) || \
+ (!(a)->addr32[0] && !(a)->addr32[1] && \
+ !(a)->addr32[2] && !(a)->addr32[3] )) \
+
+#define PF_MATCHA(n, a, m, b, f) \
+ pf_match_addr(n, a, m, b, f)
+
+#define PF_ACPY(a, b, f) \
+ pf_addrcpy(a, b, f)
+
+#define PF_AINC(a, f) \
+ pf_addr_inc(a, f)
+
+#define PF_POOLMASK(a, b, c, d, f) \
+ pf_poolmask(a, b, c, d, f)
+
+#else
+
+/* Just IPv6 */
+
+#ifdef PF_INET6_ONLY
+
+#define PF_AEQ(a, b, c) \
+ ((a)->addr32[3] == (b)->addr32[3] && \
+ (a)->addr32[2] == (b)->addr32[2] && \
+ (a)->addr32[1] == (b)->addr32[1] && \
+ (a)->addr32[0] == (b)->addr32[0]) \
+
+#define PF_ANEQ(a, b, c) \
+ ((a)->addr32[3] != (b)->addr32[3] || \
+ (a)->addr32[2] != (b)->addr32[2] || \
+ (a)->addr32[1] != (b)->addr32[1] || \
+ (a)->addr32[0] != (b)->addr32[0]) \
+
+#define PF_AZERO(a, c) \
+ (!(a)->addr32[0] && \
+ !(a)->addr32[1] && \
+ !(a)->addr32[2] && \
+ !(a)->addr32[3] ) \
+
+#define PF_MATCHA(n, a, m, b, f) \
+ pf_match_addr(n, a, m, b, f)
+
+#define PF_ACPY(a, b, f) \
+ pf_addrcpy(a, b, f)
+
+#define PF_AINC(a, f) \
+ pf_addr_inc(a, f)
+
+#define PF_POOLMASK(a, b, c, d, f) \
+ pf_poolmask(a, b, c, d, f)
+
+#else
+
+/* Just IPv4 */
+#ifdef PF_INET_ONLY
+
+#define PF_AEQ(a, b, c) \
+ ((a)->addr32[0] == (b)->addr32[0])
+
+#define PF_ANEQ(a, b, c) \
+ ((a)->addr32[0] != (b)->addr32[0])
+
+#define PF_AZERO(a, c) \
+ (!(a)->addr32[0])
+
+#define PF_MATCHA(n, a, m, b, f) \
+ pf_match_addr(n, a, m, b, f)
+
+#define PF_ACPY(a, b, f) \
+ (a)->v4.s_addr = (b)->v4.s_addr
+
+#define PF_AINC(a, f) \
+ do { \
+ (a)->addr32[0] = htonl(ntohl((a)->addr32[0]) + 1); \
+ } while (0)
+
+#define PF_POOLMASK(a, b, c, d, f) \
+ do { \
+ (a)->addr32[0] = ((b)->addr32[0] & (c)->addr32[0]) | \
+ (((c)->addr32[0] ^ 0xffffffff ) & (d)->addr32[0]); \
+ } while (0)
+
+#endif /* PF_INET_ONLY */
+#endif /* PF_INET6_ONLY */
+#endif /* PF_INET_INET6 */
+
+/*
+ * XXX callers not FIB-aware in our version of pf yet.
+ * OpenBSD fixed it later it seems, 2010/05/07 13:33:16 claudio.
+ */
+#define PF_MISMATCHAW(aw, x, af, neg, ifp, rtid) \
+ ( \
+ (((aw)->type == PF_ADDR_NOROUTE && \
+ pf_routable((x), (af), NULL, (rtid))) || \
+ (((aw)->type == PF_ADDR_URPFFAILED && (ifp) != NULL && \
+ pf_routable((x), (af), (ifp), (rtid))) || \
+ ((aw)->type == PF_ADDR_RTLABEL && \
+ !pf_rtlabel_match((x), (af), (aw), (rtid))) || \
+ ((aw)->type == PF_ADDR_TABLE && \
+ !pfr_match_addr((aw)->p.tbl, (x), (af))) || \
+ ((aw)->type == PF_ADDR_DYNIFTL && \
+ !pfi_match_addr((aw)->p.dyn, (x), (af))) || \
+ ((aw)->type == PF_ADDR_RANGE && \
+ !pf_match_addr_range(&(aw)->v.a.addr, \
+ &(aw)->v.a.mask, (x), (af))) || \
+ ((aw)->type == PF_ADDR_ADDRMASK && \
+ !PF_AZERO(&(aw)->v.a.mask, (af)) && \
+ !PF_MATCHA(0, &(aw)->v.a.addr, \
+ &(aw)->v.a.mask, (x), (af))))) != \
+ (neg) \
+ )
+
+
+struct pf_rule_uid {
+ uid_t uid[2];
+ u_int8_t op;
+};
+
+struct pf_rule_gid {
+ uid_t gid[2];
+ u_int8_t op;
+};
+
+struct pf_rule_addr {
+ struct pf_addr_wrap addr;
+ u_int16_t port[2];
+ u_int8_t neg;
+ u_int8_t port_op;
+};
+
+struct pf_pooladdr {
+ struct pf_addr_wrap addr;
+ TAILQ_ENTRY(pf_pooladdr) entries;
+ char ifname[IFNAMSIZ];
+ struct pfi_kif *kif;
+};
+
+TAILQ_HEAD(pf_palist, pf_pooladdr);
+
+struct pf_poolhashkey {
+ union {
+ u_int8_t key8[16];
+ u_int16_t key16[8];
+ u_int32_t key32[4];
+ } pfk; /* 128-bit hash key */
+#define key8 pfk.key8
+#define key16 pfk.key16
+#define key32 pfk.key32
+};
+
+struct pf_pool {
+ struct pf_palist list;
+ struct pf_pooladdr *cur;
+ struct pf_poolhashkey key;
+ struct pf_addr counter;
+ int tblidx;
+ u_int16_t proxy_port[2];
+ u_int8_t port_op;
+ u_int8_t opts;
+};
+
+
+/* A packed Operating System description for fingerprinting */
+typedef u_int32_t pf_osfp_t;
+#define PF_OSFP_ANY ((pf_osfp_t)0)
+#define PF_OSFP_UNKNOWN ((pf_osfp_t)-1)
+#define PF_OSFP_NOMATCH ((pf_osfp_t)-2)
+
+struct pf_osfp_entry {
+ SLIST_ENTRY(pf_osfp_entry) fp_entry;
+ pf_osfp_t fp_os;
+ int fp_enflags;
+#define PF_OSFP_EXPANDED 0x001 /* expanded entry */
+#define PF_OSFP_GENERIC 0x002 /* generic signature */
+#define PF_OSFP_NODETAIL 0x004 /* no p0f details */
+#define PF_OSFP_LEN 32
+ char fp_class_nm[PF_OSFP_LEN];
+ char fp_version_nm[PF_OSFP_LEN];
+ char fp_subtype_nm[PF_OSFP_LEN];
+};
+#define PF_OSFP_ENTRY_EQ(a, b) \
+ ((a)->fp_os == (b)->fp_os && \
+ memcmp((a)->fp_class_nm, (b)->fp_class_nm, PF_OSFP_LEN) == 0 && \
+ memcmp((a)->fp_version_nm, (b)->fp_version_nm, PF_OSFP_LEN) == 0 && \
+ memcmp((a)->fp_subtype_nm, (b)->fp_subtype_nm, PF_OSFP_LEN) == 0)
+
+/* handle pf_osfp_t packing */
+#define _FP_RESERVED_BIT 1 /* For the special negative #defines */
+#define _FP_UNUSED_BITS 1
+#define _FP_CLASS_BITS 10 /* OS Class (Windows, Linux) */
+#define _FP_VERSION_BITS 10 /* OS version (95, 98, NT, 2.4.54, 3.2) */
+#define _FP_SUBTYPE_BITS 10 /* patch level (NT SP4, SP3, ECN patch) */
+#define PF_OSFP_UNPACK(osfp, class, version, subtype) do { \
+ (class) = ((osfp) >> (_FP_VERSION_BITS+_FP_SUBTYPE_BITS)) & \
+ ((1 << _FP_CLASS_BITS) - 1); \
+ (version) = ((osfp) >> _FP_SUBTYPE_BITS) & \
+ ((1 << _FP_VERSION_BITS) - 1);\
+ (subtype) = (osfp) & ((1 << _FP_SUBTYPE_BITS) - 1); \
+} while(0)
+#define PF_OSFP_PACK(osfp, class, version, subtype) do { \
+ (osfp) = ((class) & ((1 << _FP_CLASS_BITS) - 1)) << (_FP_VERSION_BITS \
+ + _FP_SUBTYPE_BITS); \
+ (osfp) |= ((version) & ((1 << _FP_VERSION_BITS) - 1)) << \
+ _FP_SUBTYPE_BITS; \
+ (osfp) |= (subtype) & ((1 << _FP_SUBTYPE_BITS) - 1); \
+} while(0)
+
+/* the fingerprint of an OSes TCP SYN packet */
+typedef u_int64_t pf_tcpopts_t;
+struct pf_os_fingerprint {
+ SLIST_HEAD(pf_osfp_enlist, pf_osfp_entry) fp_oses; /* list of matches */
+ pf_tcpopts_t fp_tcpopts; /* packed TCP options */
+ u_int16_t fp_wsize; /* TCP window size */
+ u_int16_t fp_psize; /* ip->ip_len */
+ u_int16_t fp_mss; /* TCP MSS */
+ u_int16_t fp_flags;
+#define PF_OSFP_WSIZE_MOD 0x0001 /* Window modulus */
+#define PF_OSFP_WSIZE_DC 0x0002 /* Window don't care */
+#define PF_OSFP_WSIZE_MSS 0x0004 /* Window multiple of MSS */
+#define PF_OSFP_WSIZE_MTU 0x0008 /* Window multiple of MTU */
+#define PF_OSFP_PSIZE_MOD 0x0010 /* packet size modulus */
+#define PF_OSFP_PSIZE_DC 0x0020 /* packet size don't care */
+#define PF_OSFP_WSCALE 0x0040 /* TCP window scaling */
+#define PF_OSFP_WSCALE_MOD 0x0080 /* TCP window scale modulus */
+#define PF_OSFP_WSCALE_DC 0x0100 /* TCP window scale dont-care */
+#define PF_OSFP_MSS 0x0200 /* TCP MSS */
+#define PF_OSFP_MSS_MOD 0x0400 /* TCP MSS modulus */
+#define PF_OSFP_MSS_DC 0x0800 /* TCP MSS dont-care */
+#define PF_OSFP_DF 0x1000 /* IPv4 don't fragment bit */
+#define PF_OSFP_TS0 0x2000 /* Zero timestamp */
+#define PF_OSFP_INET6 0x4000 /* IPv6 */
+ u_int8_t fp_optcnt; /* TCP option count */
+ u_int8_t fp_wscale; /* TCP window scaling */
+ u_int8_t fp_ttl; /* IPv4 TTL */
+#define PF_OSFP_MAXTTL_OFFSET 40
+/* TCP options packing */
+#define PF_OSFP_TCPOPT_NOP 0x0 /* TCP NOP option */
+#define PF_OSFP_TCPOPT_WSCALE 0x1 /* TCP window scaling option */
+#define PF_OSFP_TCPOPT_MSS 0x2 /* TCP max segment size opt */
+#define PF_OSFP_TCPOPT_SACK 0x3 /* TCP SACK OK option */
+#define PF_OSFP_TCPOPT_TS 0x4 /* TCP timestamp option */
+#define PF_OSFP_TCPOPT_BITS 3 /* bits used by each option */
+#define PF_OSFP_MAX_OPTS \
+ (sizeof(((struct pf_os_fingerprint *)0)->fp_tcpopts) * 8) \
+ / PF_OSFP_TCPOPT_BITS
+
+ SLIST_ENTRY(pf_os_fingerprint) fp_next;
+};
+
+struct pf_osfp_ioctl {
+ struct pf_osfp_entry fp_os;
+ pf_tcpopts_t fp_tcpopts; /* packed TCP options */
+ u_int16_t fp_wsize; /* TCP window size */
+ u_int16_t fp_psize; /* ip->ip_len */
+ u_int16_t fp_mss; /* TCP MSS */
+ u_int16_t fp_flags;
+ u_int8_t fp_optcnt; /* TCP option count */
+ u_int8_t fp_wscale; /* TCP window scaling */
+ u_int8_t fp_ttl; /* IPv4 TTL */
+
+ int fp_getnum; /* DIOCOSFPGET number */
+};
+
+
+union pf_rule_ptr {
+ struct pf_rule *ptr;
+ u_int32_t nr;
+};
+
+#define PF_ANCHOR_NAME_SIZE 64
+
+struct pf_rule {
+ struct pf_rule_addr src;
+ struct pf_rule_addr dst;
+#define PF_SKIP_IFP 0
+#define PF_SKIP_DIR 1
+#define PF_SKIP_AF 2
+#define PF_SKIP_PROTO 3
+#define PF_SKIP_SRC_ADDR 4
+#define PF_SKIP_SRC_PORT 5
+#define PF_SKIP_DST_ADDR 6
+#define PF_SKIP_DST_PORT 7
+#define PF_SKIP_COUNT 8
+ union pf_rule_ptr skip[PF_SKIP_COUNT];
+#define PF_RULE_LABEL_SIZE 64
+ char label[PF_RULE_LABEL_SIZE];
+#define PF_QNAME_SIZE 64
+ char ifname[IFNAMSIZ];
+ char qname[PF_QNAME_SIZE];
+ char pqname[PF_QNAME_SIZE];
+#define PF_TAG_NAME_SIZE 64
+ char tagname[PF_TAG_NAME_SIZE];
+ char match_tagname[PF_TAG_NAME_SIZE];
+
+ char overload_tblname[PF_TABLE_NAME_SIZE];
+
+ TAILQ_ENTRY(pf_rule) entries;
+ struct pf_pool rpool;
+
+ u_int64_t evaluations;
+ u_int64_t packets[2];
+ u_int64_t bytes[2];
+
+ struct pfi_kif *kif;
+ struct pf_anchor *anchor;
+ struct pfr_ktable *overload_tbl;
+
+ pf_osfp_t os_fingerprint;
+
+ int rtableid;
+ u_int32_t timeout[PFTM_MAX];
+ u_int32_t states_cur;
+ u_int32_t states_tot;
+ u_int32_t max_states;
+ u_int32_t src_nodes;
+ u_int32_t max_src_nodes;
+ u_int32_t max_src_states;
+ u_int32_t spare1; /* netgraph */
+ u_int32_t max_src_conn;
+ struct {
+ u_int32_t limit;
+ u_int32_t seconds;
+ } max_src_conn_rate;
+ u_int32_t qid;
+ u_int32_t pqid;
+ u_int32_t rt_listid;
+ u_int32_t nr;
+ u_int32_t prob;
+ uid_t cuid;
+ pid_t cpid;
+
+ u_int16_t return_icmp;
+ u_int16_t return_icmp6;
+ u_int16_t max_mss;
+ u_int16_t tag;
+ u_int16_t match_tag;
+ u_int16_t spare2; /* netgraph */
+
+ struct pf_rule_uid uid;
+ struct pf_rule_gid gid;
+
+ u_int32_t rule_flag;
+ u_int8_t action;
+ u_int8_t direction;
+ u_int8_t log;
+ u_int8_t logif;
+ u_int8_t quick;
+ u_int8_t ifnot;
+ u_int8_t match_tag_not;
+ u_int8_t natpass;
+
+#define PF_STATE_NORMAL 0x1
+#define PF_STATE_MODULATE 0x2
+#define PF_STATE_SYNPROXY 0x3
+ u_int8_t keep_state;
+ sa_family_t af;
+ u_int8_t proto;
+ u_int8_t type;
+ u_int8_t code;
+ u_int8_t flags;
+ u_int8_t flagset;
+ u_int8_t min_ttl;
+ u_int8_t allow_opts;
+ u_int8_t rt;
+ u_int8_t return_ttl;
+ u_int8_t tos;
+ u_int8_t set_tos;
+ u_int8_t anchor_relative;
+ u_int8_t anchor_wildcard;
+
+#define PF_FLUSH 0x01
+#define PF_FLUSH_GLOBAL 0x02
+ u_int8_t flush;
+
+ struct {
+ struct pf_addr addr;
+ u_int16_t port;
+ } divert;
+};
+
+/* rule flags */
+#define PFRULE_DROP 0x0000
+#define PFRULE_RETURNRST 0x0001
+#define PFRULE_FRAGMENT 0x0002
+#define PFRULE_RETURNICMP 0x0004
+#define PFRULE_RETURN 0x0008
+#define PFRULE_NOSYNC 0x0010
+#define PFRULE_SRCTRACK 0x0020 /* track source states */
+#define PFRULE_RULESRCTRACK 0x0040 /* per rule */
+
+/* scrub flags */
+#define PFRULE_NODF 0x0100
+#define PFRULE_FRAGCROP 0x0200 /* non-buffering frag cache */
+#define PFRULE_FRAGDROP 0x0400 /* drop funny fragments */
+#define PFRULE_RANDOMID 0x0800
+#define PFRULE_REASSEMBLE_TCP 0x1000
+#define PFRULE_SET_TOS 0x2000
+
+/* rule flags again */
+#define PFRULE_IFBOUND 0x00010000 /* if-bound */
+#define PFRULE_STATESLOPPY 0x00020000 /* sloppy state tracking */
+#define PFRULE_PFLOW 0x00040000
+
+#define PFSTATE_HIWAT 10000 /* default state table size */
+#define PFSTATE_ADAPT_START 6000 /* default adaptive timeout start */
+#define PFSTATE_ADAPT_END 12000 /* default adaptive timeout end */
+
+
+struct pf_threshold {
+ u_int32_t limit;
+#define PF_THRESHOLD_MULT 1000
+#define PF_THRESHOLD_MAX 0xffffffff / PF_THRESHOLD_MULT
+ u_int32_t seconds;
+ u_int32_t count;
+ u_int32_t last;
+};
+
+struct pf_src_node {
+ RB_ENTRY(pf_src_node) entry;
+ struct pf_addr addr;
+ struct pf_addr raddr;
+ union pf_rule_ptr rule;
+ struct pfi_kif *kif;
+ u_int64_t bytes[2];
+ u_int64_t packets[2];
+ u_int32_t states;
+ u_int32_t conn;
+ struct pf_threshold conn_rate;
+ u_int32_t creation;
+ u_int32_t expire;
+ sa_family_t af;
+ u_int8_t ruletype;
+};
+
+#define PFSNODE_HIWAT 10000 /* default source node table size */
+
+struct pf_state_scrub {
+ struct timeval pfss_last; /* time received last packet */
+ u_int32_t pfss_tsecr; /* last echoed timestamp */
+ u_int32_t pfss_tsval; /* largest timestamp */
+ u_int32_t pfss_tsval0; /* original timestamp */
+ u_int16_t pfss_flags;
+#define PFSS_TIMESTAMP 0x0001 /* modulate timestamp */
+#define PFSS_PAWS 0x0010 /* stricter PAWS checks */
+#define PFSS_PAWS_IDLED 0x0020 /* was idle too long. no PAWS */
+#define PFSS_DATA_TS 0x0040 /* timestamp on data packets */
+#define PFSS_DATA_NOTS 0x0080 /* no timestamp on data packets */
+ u_int8_t pfss_ttl; /* stashed TTL */
+ u_int8_t pad;
+ u_int32_t pfss_ts_mod; /* timestamp modulation */
+};
+
+struct pf_state_host {
+ struct pf_addr addr;
+ u_int16_t port;
+ u_int16_t pad;
+};
+
+struct pf_state_peer {
+ struct pf_state_scrub *scrub; /* state is scrubbed */
+ u_int32_t seqlo; /* Max sequence number sent */
+ u_int32_t seqhi; /* Max the other end ACKd + win */
+ u_int32_t seqdiff; /* Sequence number modulator */
+ u_int16_t max_win; /* largest window (pre scaling) */
+ u_int16_t mss; /* Maximum segment size option */
+ u_int8_t state; /* active state level */
+ u_int8_t wscale; /* window scaling factor */
+ u_int8_t tcp_est; /* Did we reach TCPS_ESTABLISHED */
+ u_int8_t pad[1];
+};
+
+TAILQ_HEAD(pf_state_queue, pf_state);
+
+/* keep synced with struct pf_state_key, used in RB_FIND */
+struct pf_state_key_cmp {
+ struct pf_addr addr[2];
+ u_int16_t port[2];
+ sa_family_t af;
+ u_int8_t proto;
+ u_int8_t pad[2];
+};
+
+struct pf_state_item {
+ TAILQ_ENTRY(pf_state_item) entry;
+ struct pf_state *s;
+};
+
+TAILQ_HEAD(pf_statelisthead, pf_state_item);
+
+struct pf_state_key {
+ struct pf_addr addr[2];
+ u_int16_t port[2];
+ sa_family_t af;
+ u_int8_t proto;
+ u_int8_t pad[2];
+
+ RB_ENTRY(pf_state_key) entry;
+ struct pf_statelisthead states;
+ struct pf_state_key *reverse;
+ struct inpcb *inp;
+};
+
+/* keep synced with struct pf_state, used in RB_FIND */
+struct pf_state_cmp {
+ u_int64_t id;
+ u_int32_t creatorid;
+ u_int8_t direction;
+ u_int8_t pad[3];
+};
+
+struct pf_state {
+ u_int64_t id;
+ u_int32_t creatorid;
+ u_int8_t direction;
+#ifdef __FreeBSD__
+ u_int8_t pad[2];
+ u_int8_t local_flags;
+#define PFSTATE_EXPIRING 0x01
+#else
+ u_int8_t pad[3];
+#endif
+
+ TAILQ_ENTRY(pf_state) sync_list;
+ TAILQ_ENTRY(pf_state) entry_list;
+ RB_ENTRY(pf_state) entry_id;
+ struct pf_state_peer src;
+ struct pf_state_peer dst;
+ union pf_rule_ptr rule;
+ union pf_rule_ptr anchor;
+ union pf_rule_ptr nat_rule;
+ struct pf_addr rt_addr;
+ struct pf_state_key *key[2]; /* addresses stack and wire */
+ struct pfi_kif *kif;
+ struct pfi_kif *rt_kif;
+ struct pf_src_node *src_node;
+ struct pf_src_node *nat_src_node;
+ u_int64_t packets[2];
+ u_int64_t bytes[2];
+ u_int32_t creation;
+ u_int32_t expire;
+ u_int32_t pfsync_time;
+ u_int16_t tag;
+ u_int8_t log;
+ u_int8_t state_flags;
+#define PFSTATE_ALLOWOPTS 0x01
+#define PFSTATE_SLOPPY 0x02
+#define PFSTATE_PFLOW 0x04
+#define PFSTATE_NOSYNC 0x08
+#define PFSTATE_ACK 0x10
+ u_int8_t timeout;
+ u_int8_t sync_state; /* PFSYNC_S_x */
+
+ /* XXX */
+ u_int8_t sync_updates;
+ u_int8_t _tail[3];
+};
+
+/*
+ * Unified state structures for pulling states out of the kernel
+ * used by pfsync(4) and the pf(4) ioctl.
+ */
+struct pfsync_state_scrub {
+ u_int16_t pfss_flags;
+ u_int8_t pfss_ttl; /* stashed TTL */
+#define PFSYNC_SCRUB_FLAG_VALID 0x01
+ u_int8_t scrub_flag;
+ u_int32_t pfss_ts_mod; /* timestamp modulation */
+} __packed;
+
+struct pfsync_state_peer {
+ struct pfsync_state_scrub scrub; /* state is scrubbed */
+ u_int32_t seqlo; /* Max sequence number sent */
+ u_int32_t seqhi; /* Max the other end ACKd + win */
+ u_int32_t seqdiff; /* Sequence number modulator */
+ u_int16_t max_win; /* largest window (pre scaling) */
+ u_int16_t mss; /* Maximum segment size option */
+ u_int8_t state; /* active state level */
+ u_int8_t wscale; /* window scaling factor */
+ u_int8_t pad[6];
+} __packed;
+
+struct pfsync_state_key {
+ struct pf_addr addr[2];
+ u_int16_t port[2];
+};
+
+struct pfsync_state {
+ u_int32_t id[2];
+ char ifname[IFNAMSIZ];
+ struct pfsync_state_key key[2];
+ struct pfsync_state_peer src;
+ struct pfsync_state_peer dst;
+ struct pf_addr rt_addr;
+ u_int32_t rule;
+ u_int32_t anchor;
+ u_int32_t nat_rule;
+ u_int32_t creation;
+ u_int32_t expire;
+ u_int32_t packets[2][2];
+ u_int32_t bytes[2][2];
+ u_int32_t creatorid;
+ sa_family_t af;
+ u_int8_t proto;
+ u_int8_t direction;
+#ifdef __FreeBSD__
+ u_int8_t local_flags;
+#define PFSTATE_EXPIRING 0x01
+ u_int8_t pad;
+#endif
+ u_int8_t log;
+ u_int8_t state_flags;
+ u_int8_t timeout;
+ u_int8_t sync_flags;
+ u_int8_t updates;
+} __packed;
+
+#ifdef __FreeBSD__
+#ifdef _KERNEL
+/* pfsync */
+typedef int pfsync_state_import_t(struct pfsync_state *, u_int8_t);
+typedef void pfsync_insert_state_t(struct pf_state *);
+typedef void pfsync_update_state_t(struct pf_state *);
+typedef void pfsync_delete_state_t(struct pf_state *);
+typedef void pfsync_clear_states_t(u_int32_t, const char *);
+typedef int pfsync_state_in_use_t(struct pf_state *);
+typedef int pfsync_defer_t(struct pf_state *, struct mbuf *);
+typedef int pfsync_up_t(void);
+
+extern pfsync_state_import_t *pfsync_state_import_ptr;
+extern pfsync_insert_state_t *pfsync_insert_state_ptr;
+extern pfsync_update_state_t *pfsync_update_state_ptr;
+extern pfsync_delete_state_t *pfsync_delete_state_ptr;
+extern pfsync_clear_states_t *pfsync_clear_states_ptr;
+extern pfsync_state_in_use_t *pfsync_state_in_use_ptr;
+extern pfsync_defer_t *pfsync_defer_ptr;
+extern pfsync_up_t *pfsync_up_ptr;
+
+void pfsync_state_export(struct pfsync_state *,
+ struct pf_state *);
+
+/* pflow */
+typedef int export_pflow_t(struct pf_state *);
+
+extern export_pflow_t *export_pflow_ptr;
+
+/* pflog */
+struct pf_ruleset;
+struct pf_pdesc;
+typedef int pflog_packet_t(struct pfi_kif *, struct mbuf *, sa_family_t,
+ u_int8_t, u_int8_t, struct pf_rule *, struct pf_rule *,
+ struct pf_ruleset *, struct pf_pdesc *);
+
+extern pflog_packet_t *pflog_packet_ptr;
+
+/* pf uid hack */
+VNET_DECLARE(int, debug_pfugidhack);
+#define V_debug_pfugidhack VNET(debug_pfugidhack)
+
+#define V_pf_end_threads VNET(pf_end_threads)
+#endif
+
+/* Macros to set/clear/test flags. */
+#ifdef _KERNEL
+#define SET(t, f) ((t) |= (f))
+#define CLR(t, f) ((t) &= ~(f))
+#define ISSET(t, f) ((t) & (f))
+#endif
+#endif
+
+#define PFSYNC_FLAG_SRCNODE 0x04
+#define PFSYNC_FLAG_NATSRCNODE 0x08
+
+/* for copies to/from network byte order */
+/* ioctl interface also uses network byte order */
+#define pf_state_peer_hton(s,d) do { \
+ (d)->seqlo = htonl((s)->seqlo); \
+ (d)->seqhi = htonl((s)->seqhi); \
+ (d)->seqdiff = htonl((s)->seqdiff); \
+ (d)->max_win = htons((s)->max_win); \
+ (d)->mss = htons((s)->mss); \
+ (d)->state = (s)->state; \
+ (d)->wscale = (s)->wscale; \
+ if ((s)->scrub) { \
+ (d)->scrub.pfss_flags = \
+ htons((s)->scrub->pfss_flags & PFSS_TIMESTAMP); \
+ (d)->scrub.pfss_ttl = (s)->scrub->pfss_ttl; \
+ (d)->scrub.pfss_ts_mod = htonl((s)->scrub->pfss_ts_mod);\
+ (d)->scrub.scrub_flag = PFSYNC_SCRUB_FLAG_VALID; \
+ } \
+} while (0)
+
+#define pf_state_peer_ntoh(s,d) do { \
+ (d)->seqlo = ntohl((s)->seqlo); \
+ (d)->seqhi = ntohl((s)->seqhi); \
+ (d)->seqdiff = ntohl((s)->seqdiff); \
+ (d)->max_win = ntohs((s)->max_win); \
+ (d)->mss = ntohs((s)->mss); \
+ (d)->state = (s)->state; \
+ (d)->wscale = (s)->wscale; \
+ if ((s)->scrub.scrub_flag == PFSYNC_SCRUB_FLAG_VALID && \
+ (d)->scrub != NULL) { \
+ (d)->scrub->pfss_flags = \
+ ntohs((s)->scrub.pfss_flags) & PFSS_TIMESTAMP; \
+ (d)->scrub->pfss_ttl = (s)->scrub.pfss_ttl; \
+ (d)->scrub->pfss_ts_mod = ntohl((s)->scrub.pfss_ts_mod);\
+ } \
+} while (0)
+
+#define pf_state_counter_hton(s,d) do { \
+ d[0] = htonl((s>>32)&0xffffffff); \
+ d[1] = htonl(s&0xffffffff); \
+} while (0)
+
+#define pf_state_counter_from_pfsync(s) \
+ (((u_int64_t)(s[0])<<32) | (u_int64_t)(s[1]))
+
+#define pf_state_counter_ntoh(s,d) do { \
+ d = ntohl(s[0]); \
+ d = d<<32; \
+ d += ntohl(s[1]); \
+} while (0)
+
+TAILQ_HEAD(pf_rulequeue, pf_rule);
+
+struct pf_anchor;
+
+struct pf_ruleset {
+ struct {
+ struct pf_rulequeue queues[2];
+ struct {
+ struct pf_rulequeue *ptr;
+ struct pf_rule **ptr_array;
+ u_int32_t rcount;
+ u_int32_t ticket;
+ int open;
+ } active, inactive;
+ } rules[PF_RULESET_MAX];
+ struct pf_anchor *anchor;
+ u_int32_t tticket;
+ int tables;
+ int topen;
+};
+
+RB_HEAD(pf_anchor_global, pf_anchor);
+RB_HEAD(pf_anchor_node, pf_anchor);
+struct pf_anchor {
+ RB_ENTRY(pf_anchor) entry_global;
+ RB_ENTRY(pf_anchor) entry_node;
+ struct pf_anchor *parent;
+ struct pf_anchor_node children;
+ char name[PF_ANCHOR_NAME_SIZE];
+ char path[MAXPATHLEN];
+ struct pf_ruleset ruleset;
+ int refcnt; /* anchor rules */
+ int match;
+};
+RB_PROTOTYPE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
+RB_PROTOTYPE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
+
+#define PF_RESERVED_ANCHOR "_pf"
+
+#define PFR_TFLAG_PERSIST 0x00000001
+#define PFR_TFLAG_CONST 0x00000002
+#define PFR_TFLAG_ACTIVE 0x00000004
+#define PFR_TFLAG_INACTIVE 0x00000008
+#define PFR_TFLAG_REFERENCED 0x00000010
+#define PFR_TFLAG_REFDANCHOR 0x00000020
+#define PFR_TFLAG_COUNTERS 0x00000040
+/* Adjust masks below when adding flags. */
+#define PFR_TFLAG_USRMASK 0x00000043
+#define PFR_TFLAG_SETMASK 0x0000003C
+#define PFR_TFLAG_ALLMASK 0x0000007F
+
+struct pfr_table {
+ char pfrt_anchor[MAXPATHLEN];
+ char pfrt_name[PF_TABLE_NAME_SIZE];
+ u_int32_t pfrt_flags;
+ u_int8_t pfrt_fback;
+};
+
+enum { PFR_FB_NONE, PFR_FB_MATCH, PFR_FB_ADDED, PFR_FB_DELETED,
+ PFR_FB_CHANGED, PFR_FB_CLEARED, PFR_FB_DUPLICATE,
+ PFR_FB_NOTMATCH, PFR_FB_CONFLICT, PFR_FB_NOCOUNT, PFR_FB_MAX };
+
+struct pfr_addr {
+ union {
+ struct in_addr _pfra_ip4addr;
+ struct in6_addr _pfra_ip6addr;
+ } pfra_u;
+ u_int8_t pfra_af;
+ u_int8_t pfra_net;
+ u_int8_t pfra_not;
+ u_int8_t pfra_fback;
+};
+#define pfra_ip4addr pfra_u._pfra_ip4addr
+#define pfra_ip6addr pfra_u._pfra_ip6addr
+
+enum { PFR_DIR_IN, PFR_DIR_OUT, PFR_DIR_MAX };
+enum { PFR_OP_BLOCK, PFR_OP_PASS, PFR_OP_ADDR_MAX, PFR_OP_TABLE_MAX };
+#define PFR_OP_XPASS PFR_OP_ADDR_MAX
+
+struct pfr_astats {
+ struct pfr_addr pfras_a;
+ u_int64_t pfras_packets[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
+ u_int64_t pfras_bytes[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
+ long pfras_tzero;
+};
+
+enum { PFR_REFCNT_RULE, PFR_REFCNT_ANCHOR, PFR_REFCNT_MAX };
+
+struct pfr_tstats {
+ struct pfr_table pfrts_t;
+ u_int64_t pfrts_packets[PFR_DIR_MAX][PFR_OP_TABLE_MAX];
+ u_int64_t pfrts_bytes[PFR_DIR_MAX][PFR_OP_TABLE_MAX];
+ u_int64_t pfrts_match;
+ u_int64_t pfrts_nomatch;
+ long pfrts_tzero;
+ int pfrts_cnt;
+ int pfrts_refcnt[PFR_REFCNT_MAX];
+};
+#define pfrts_name pfrts_t.pfrt_name
+#define pfrts_flags pfrts_t.pfrt_flags
+
+#ifndef _SOCKADDR_UNION_DEFINED
+#define _SOCKADDR_UNION_DEFINED
+union sockaddr_union {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+};
+#endif /* _SOCKADDR_UNION_DEFINED */
+
+struct pfr_kcounters {
+ u_int64_t pfrkc_packets[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
+ u_int64_t pfrkc_bytes[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
+};
+
+SLIST_HEAD(pfr_kentryworkq, pfr_kentry);
+struct pfr_kentry {
+ struct radix_node pfrke_node[2];
+ union sockaddr_union pfrke_sa;
+ SLIST_ENTRY(pfr_kentry) pfrke_workq;
+ union {
+
+ struct pfr_kcounters *pfrke_counters;
+#if 0
+ struct pfr_kroute *pfrke_route;
+#endif
+ } u;
+ long pfrke_tzero;
+ u_int8_t pfrke_af;
+ u_int8_t pfrke_net;
+ u_int8_t pfrke_not;
+ u_int8_t pfrke_mark;
+};
+#define pfrke_counters u.pfrke_counters
+#define pfrke_route u.pfrke_route
+
+
+SLIST_HEAD(pfr_ktableworkq, pfr_ktable);
+RB_HEAD(pfr_ktablehead, pfr_ktable);
+struct pfr_ktable {
+ struct pfr_tstats pfrkt_ts;
+ RB_ENTRY(pfr_ktable) pfrkt_tree;
+ SLIST_ENTRY(pfr_ktable) pfrkt_workq;
+ struct radix_node_head *pfrkt_ip4;
+ struct radix_node_head *pfrkt_ip6;
+ struct pfr_ktable *pfrkt_shadow;
+ struct pfr_ktable *pfrkt_root;
+ struct pf_ruleset *pfrkt_rs;
+ long pfrkt_larg;
+ int pfrkt_nflags;
+};
+#define pfrkt_t pfrkt_ts.pfrts_t
+#define pfrkt_name pfrkt_t.pfrt_name
+#define pfrkt_anchor pfrkt_t.pfrt_anchor
+#define pfrkt_ruleset pfrkt_t.pfrt_ruleset
+#define pfrkt_flags pfrkt_t.pfrt_flags
+#define pfrkt_cnt pfrkt_ts.pfrts_cnt
+#define pfrkt_refcnt pfrkt_ts.pfrts_refcnt
+#define pfrkt_packets pfrkt_ts.pfrts_packets
+#define pfrkt_bytes pfrkt_ts.pfrts_bytes
+#define pfrkt_match pfrkt_ts.pfrts_match
+#define pfrkt_nomatch pfrkt_ts.pfrts_nomatch
+#define pfrkt_tzero pfrkt_ts.pfrts_tzero
+
+RB_HEAD(pf_state_tree, pf_state_key);
+RB_PROTOTYPE(pf_state_tree, pf_state_key, entry, pf_state_compare_key);
+
+RB_HEAD(pf_state_tree_ext_gwy, pf_state_key);
+RB_PROTOTYPE(pf_state_tree_ext_gwy, pf_state_key,
+ entry_ext_gwy, pf_state_compare_ext_gwy);
+
+RB_HEAD(pfi_ifhead, pfi_kif);
+
+/* state tables */
+#ifdef __FreeBSD__
+#ifdef _KERNEL
+VNET_DECLARE(struct pf_state_tree, pf_statetbl);
+#define V_pf_statetbl VNET(pf_statetbl)
+#endif
+#else
+extern struct pf_state_tree pf_statetbl;
+#endif
+
+/* keep synced with pfi_kif, used in RB_FIND */
+struct pfi_kif_cmp {
+ char pfik_name[IFNAMSIZ];
+};
+
+struct pfi_kif {
+ char pfik_name[IFNAMSIZ];
+ RB_ENTRY(pfi_kif) pfik_tree;
+ u_int64_t pfik_packets[2][2][2];
+ u_int64_t pfik_bytes[2][2][2];
+ u_int32_t pfik_tzero;
+ int pfik_flags;
+ void *pfik_ah_cookie;
+ struct ifnet *pfik_ifp;
+ struct ifg_group *pfik_group;
+ int pfik_states;
+ int pfik_rules;
+ TAILQ_HEAD(, pfi_dynaddr) pfik_dynaddrs;
+};
+
+enum pfi_kif_refs {
+ PFI_KIF_REF_NONE,
+ PFI_KIF_REF_STATE,
+ PFI_KIF_REF_RULE
+};
+
+#define PFI_IFLAG_SKIP 0x0100 /* skip filtering on interface */
+
+struct pf_pdesc {
+ struct {
+ int done;
+ uid_t uid;
+ gid_t gid;
+ pid_t pid;
+ } lookup;
+ u_int64_t tot_len; /* Make Mickey money */
+ union {
+ struct tcphdr *tcp;
+ struct udphdr *udp;
+ struct icmp *icmp;
+#ifdef INET6
+ struct icmp6_hdr *icmp6;
+#endif /* INET6 */
+ void *any;
+ } hdr;
+
+ struct pf_rule *nat_rule; /* nat/rdr rule applied to packet */
+ struct ether_header
+ *eh;
+ struct pf_addr *src; /* src address */
+ struct pf_addr *dst; /* dst address */
+ u_int16_t *sport;
+ u_int16_t *dport;
+#ifdef __FreeBSD__
+ struct pf_mtag *pf_mtag;
+#endif
+
+ u_int32_t p_len; /* total length of payload */
+
+ u_int16_t *ip_sum;
+ u_int16_t *proto_sum;
+ u_int16_t flags; /* Let SCRUB trigger behavior in
+ * state code. Easier than tags */
+#define PFDESC_TCP_NORM 0x0001 /* TCP shall be statefully scrubbed */
+#define PFDESC_IP_REAS 0x0002 /* IP frags would've been reassembled */
+ sa_family_t af;
+ u_int8_t proto;
+ u_int8_t tos;
+ u_int8_t dir; /* direction */
+ u_int8_t sidx; /* key index for source */
+ u_int8_t didx; /* key index for destination */
+};
+
+/* flags for RDR options */
+#define PF_DPORT_RANGE 0x01 /* Dest port uses range */
+#define PF_RPORT_RANGE 0x02 /* RDR'ed port uses range */
+
+/* Reasons code for passing/dropping a packet */
+#define PFRES_MATCH 0 /* Explicit match of a rule */
+#define PFRES_BADOFF 1 /* Bad offset for pull_hdr */
+#define PFRES_FRAG 2 /* Dropping following fragment */
+#define PFRES_SHORT 3 /* Dropping short packet */
+#define PFRES_NORM 4 /* Dropping by normalizer */
+#define PFRES_MEMORY 5 /* Dropped due to lacking mem */
+#define PFRES_TS 6 /* Bad TCP Timestamp (RFC1323) */
+#define PFRES_CONGEST 7 /* Congestion (of ipintrq) */
+#define PFRES_IPOPTIONS 8 /* IP option */
+#define PFRES_PROTCKSUM 9 /* Protocol checksum invalid */
+#define PFRES_BADSTATE 10 /* State mismatch */
+#define PFRES_STATEINS 11 /* State insertion failure */
+#define PFRES_MAXSTATES 12 /* State limit */
+#define PFRES_SRCLIMIT 13 /* Source node/conn limit */
+#define PFRES_SYNPROXY 14 /* SYN proxy */
+#define PFRES_MAX 15 /* total+1 */
+
+#define PFRES_NAMES { \
+ "match", \
+ "bad-offset", \
+ "fragment", \
+ "short", \
+ "normalize", \
+ "memory", \
+ "bad-timestamp", \
+ "congestion", \
+ "ip-option", \
+ "proto-cksum", \
+ "state-mismatch", \
+ "state-insert", \
+ "state-limit", \
+ "src-limit", \
+ "synproxy", \
+ NULL \
+}
+
+/* Counters for other things we want to keep track of */
+#define LCNT_STATES 0 /* states */
+#define LCNT_SRCSTATES 1 /* max-src-states */
+#define LCNT_SRCNODES 2 /* max-src-nodes */
+#define LCNT_SRCCONN 3 /* max-src-conn */
+#define LCNT_SRCCONNRATE 4 /* max-src-conn-rate */
+#define LCNT_OVERLOAD_TABLE 5 /* entry added to overload table */
+#define LCNT_OVERLOAD_FLUSH 6 /* state entries flushed */
+#define LCNT_MAX 7 /* total+1 */
+
+#define LCNT_NAMES { \
+ "max states per rule", \
+ "max-src-states", \
+ "max-src-nodes", \
+ "max-src-conn", \
+ "max-src-conn-rate", \
+ "overload table insertion", \
+ "overload flush states", \
+ NULL \
+}
+
+/* UDP state enumeration */
+#define PFUDPS_NO_TRAFFIC 0
+#define PFUDPS_SINGLE 1
+#define PFUDPS_MULTIPLE 2
+
+#define PFUDPS_NSTATES 3 /* number of state levels */
+
+#define PFUDPS_NAMES { \
+ "NO_TRAFFIC", \
+ "SINGLE", \
+ "MULTIPLE", \
+ NULL \
+}
+
+/* Other protocol state enumeration */
+#define PFOTHERS_NO_TRAFFIC 0
+#define PFOTHERS_SINGLE 1
+#define PFOTHERS_MULTIPLE 2
+
+#define PFOTHERS_NSTATES 3 /* number of state levels */
+
+#define PFOTHERS_NAMES { \
+ "NO_TRAFFIC", \
+ "SINGLE", \
+ "MULTIPLE", \
+ NULL \
+}
+
+#define FCNT_STATE_SEARCH 0
+#define FCNT_STATE_INSERT 1
+#define FCNT_STATE_REMOVALS 2
+#define FCNT_MAX 3
+
+#define SCNT_SRC_NODE_SEARCH 0
+#define SCNT_SRC_NODE_INSERT 1
+#define SCNT_SRC_NODE_REMOVALS 2
+#define SCNT_MAX 3
+
+#define ACTION_SET(a, x) \
+ do { \
+ if ((a) != NULL) \
+ *(a) = (x); \
+ } while (0)
+
+#ifdef __FreeBSD__
+#define REASON_SET(a, x) \
+ do { \
+ if ((a) != NULL) \
+ *(a) = (x); \
+ if (x < PFRES_MAX) \
+ V_pf_status.counters[x]++; \
+ } while (0)
+#else
+#define REASON_SET(a, x) \
+ do { \
+ if ((a) != NULL) \
+ *(a) = (x); \
+ if (x < PFRES_MAX) \
+ pf_status.counters[x]++; \
+ } while (0)
+#endif
+
+struct pf_status {
+ u_int64_t counters[PFRES_MAX];
+ u_int64_t lcounters[LCNT_MAX]; /* limit counters */
+ u_int64_t fcounters[FCNT_MAX];
+ u_int64_t scounters[SCNT_MAX];
+ u_int64_t pcounters[2][2][3];
+ u_int64_t bcounters[2][2];
+ u_int64_t stateid;
+ u_int32_t running;
+ u_int32_t states;
+ u_int32_t src_nodes;
+ u_int32_t since;
+ u_int32_t debug;
+ u_int32_t hostid;
+ char ifname[IFNAMSIZ];
+ u_int8_t pf_chksum[PF_MD5_DIGEST_LENGTH];
+};
+
+struct cbq_opts {
+ u_int minburst;
+ u_int maxburst;
+ u_int pktsize;
+ u_int maxpktsize;
+ u_int ns_per_byte;
+ u_int maxidle;
+ int minidle;
+ u_int offtime;
+ int flags;
+};
+
+struct priq_opts {
+ int flags;
+};
+
+struct hfsc_opts {
+ /* real-time service curve */
+ u_int rtsc_m1; /* slope of the 1st segment in bps */
+ u_int rtsc_d; /* the x-projection of m1 in msec */
+ u_int rtsc_m2; /* slope of the 2nd segment in bps */
+ /* link-sharing service curve */
+ u_int lssc_m1;
+ u_int lssc_d;
+ u_int lssc_m2;
+ /* upper-limit service curve */
+ u_int ulsc_m1;
+ u_int ulsc_d;
+ u_int ulsc_m2;
+ int flags;
+};
+
+struct pf_altq {
+ char ifname[IFNAMSIZ];
+
+ void *altq_disc; /* discipline-specific state */
+ TAILQ_ENTRY(pf_altq) entries;
+
+ /* scheduler spec */
+ u_int8_t scheduler; /* scheduler type */
+ u_int16_t tbrsize; /* tokenbucket regulator size */
+ u_int32_t ifbandwidth; /* interface bandwidth */
+
+ /* queue spec */
+ char qname[PF_QNAME_SIZE]; /* queue name */
+ char parent[PF_QNAME_SIZE]; /* parent name */
+ u_int32_t parent_qid; /* parent queue id */
+ u_int32_t bandwidth; /* queue bandwidth */
+ u_int8_t priority; /* priority */
+#ifdef __FreeBSD__
+ u_int8_t local_flags; /* dynamic interface */
+#define PFALTQ_FLAG_IF_REMOVED 0x01
+#endif
+ u_int16_t qlimit; /* queue size limit */
+ u_int16_t flags; /* misc flags */
+ union {
+ struct cbq_opts cbq_opts;
+ struct priq_opts priq_opts;
+ struct hfsc_opts hfsc_opts;
+ } pq_u;
+
+ u_int32_t qid; /* return value */
+};
+
+struct pf_tagname {
+ TAILQ_ENTRY(pf_tagname) entries;
+ char name[PF_TAG_NAME_SIZE];
+ u_int16_t tag;
+ int ref;
+};
+
+struct pf_divert {
+ union {
+ struct in_addr ipv4;
+ struct in6_addr ipv6;
+ } addr;
+ u_int16_t port;
+};
+
+#define PFFRAG_FRENT_HIWAT 5000 /* Number of fragment entries */
+#define PFFRAG_FRAG_HIWAT 1000 /* Number of fragmented packets */
+#define PFFRAG_FRCENT_HIWAT 50000 /* Number of fragment cache entries */
+#define PFFRAG_FRCACHE_HIWAT 10000 /* Number of fragment descriptors */
+
+#define PFR_KTABLE_HIWAT 1000 /* Number of tables */
+#define PFR_KENTRY_HIWAT 200000 /* Number of table entries */
+#define PFR_KENTRY_HIWAT_SMALL 100000 /* Number of table entries (tiny hosts) */
+
+/*
+ * ioctl parameter structures
+ */
+
+struct pfioc_pooladdr {
+ u_int32_t action;
+ u_int32_t ticket;
+ u_int32_t nr;
+ u_int32_t r_num;
+ u_int8_t r_action;
+ u_int8_t r_last;
+ u_int8_t af;
+ char anchor[MAXPATHLEN];
+ struct pf_pooladdr addr;
+};
+
+struct pfioc_rule {
+ u_int32_t action;
+ u_int32_t ticket;
+ u_int32_t pool_ticket;
+ u_int32_t nr;
+ char anchor[MAXPATHLEN];
+ char anchor_call[MAXPATHLEN];
+ struct pf_rule rule;
+};
+
+struct pfioc_natlook {
+ struct pf_addr saddr;
+ struct pf_addr daddr;
+ struct pf_addr rsaddr;
+ struct pf_addr rdaddr;
+ u_int16_t sport;
+ u_int16_t dport;
+ u_int16_t rsport;
+ u_int16_t rdport;
+ sa_family_t af;
+ u_int8_t proto;
+ u_int8_t direction;
+};
+
+struct pfioc_state {
+ struct pfsync_state state;
+};
+
+struct pfioc_src_node_kill {
+ sa_family_t psnk_af;
+ struct pf_rule_addr psnk_src;
+ struct pf_rule_addr psnk_dst;
+ u_int psnk_killed;
+};
+
+struct pfioc_state_kill {
+ struct pf_state_cmp psk_pfcmp;
+ sa_family_t psk_af;
+ int psk_proto;
+ struct pf_rule_addr psk_src;
+ struct pf_rule_addr psk_dst;
+ char psk_ifname[IFNAMSIZ];
+ char psk_label[PF_RULE_LABEL_SIZE];
+ u_int psk_killed;
+};
+
+struct pfioc_states {
+ int ps_len;
+ union {
+ caddr_t psu_buf;
+ struct pfsync_state *psu_states;
+ } ps_u;
+#define ps_buf ps_u.psu_buf
+#define ps_states ps_u.psu_states
+};
+
+struct pfioc_src_nodes {
+ int psn_len;
+ union {
+ caddr_t psu_buf;
+ struct pf_src_node *psu_src_nodes;
+ } psn_u;
+#define psn_buf psn_u.psu_buf
+#define psn_src_nodes psn_u.psu_src_nodes
+};
+
+struct pfioc_if {
+ char ifname[IFNAMSIZ];
+};
+
+struct pfioc_tm {
+ int timeout;
+ int seconds;
+};
+
+struct pfioc_limit {
+ int index;
+ unsigned limit;
+};
+
+struct pfioc_altq {
+ u_int32_t action;
+ u_int32_t ticket;
+ u_int32_t nr;
+ struct pf_altq altq;
+};
+
+struct pfioc_qstats {
+ u_int32_t ticket;
+ u_int32_t nr;
+ void *buf;
+ int nbytes;
+ u_int8_t scheduler;
+};
+
+struct pfioc_ruleset {
+ u_int32_t nr;
+ char path[MAXPATHLEN];
+ char name[PF_ANCHOR_NAME_SIZE];
+};
+
+#define PF_RULESET_ALTQ (PF_RULESET_MAX)
+#define PF_RULESET_TABLE (PF_RULESET_MAX+1)
+struct pfioc_trans {
+ int size; /* number of elements */
+ int esize; /* size of each element in bytes */
+ struct pfioc_trans_e {
+ int rs_num;
+ char anchor[MAXPATHLEN];
+ u_int32_t ticket;
+ } *array;
+};
+
+#define PFR_FLAG_ATOMIC 0x00000001
+#define PFR_FLAG_DUMMY 0x00000002
+#define PFR_FLAG_FEEDBACK 0x00000004
+#define PFR_FLAG_CLSTATS 0x00000008
+#define PFR_FLAG_ADDRSTOO 0x00000010
+#define PFR_FLAG_REPLACE 0x00000020
+#define PFR_FLAG_ALLRSETS 0x00000040
+#define PFR_FLAG_ALLMASK 0x0000007F
+#ifdef _KERNEL
+#define PFR_FLAG_USERIOCTL 0x10000000
+#endif
+
+struct pfioc_table {
+ struct pfr_table pfrio_table;
+ void *pfrio_buffer;
+ int pfrio_esize;
+ int pfrio_size;
+ int pfrio_size2;
+ int pfrio_nadd;
+ int pfrio_ndel;
+ int pfrio_nchange;
+ int pfrio_flags;
+ u_int32_t pfrio_ticket;
+};
+#define pfrio_exists pfrio_nadd
+#define pfrio_nzero pfrio_nadd
+#define pfrio_nmatch pfrio_nadd
+#define pfrio_naddr pfrio_size2
+#define pfrio_setflag pfrio_size2
+#define pfrio_clrflag pfrio_nadd
+
+struct pfioc_iface {
+ char pfiio_name[IFNAMSIZ];
+ void *pfiio_buffer;
+ int pfiio_esize;
+ int pfiio_size;
+ int pfiio_nzero;
+ int pfiio_flags;
+};
+
+
+/*
+ * ioctl operations
+ */
+
+#define DIOCSTART _IO ('D', 1)
+#define DIOCSTOP _IO ('D', 2)
+#define DIOCADDRULE _IOWR('D', 4, struct pfioc_rule)
+#define DIOCGETRULES _IOWR('D', 6, struct pfioc_rule)
+#define DIOCGETRULE _IOWR('D', 7, struct pfioc_rule)
+/* XXX cut 8 - 17 */
+#define DIOCCLRSTATES _IOWR('D', 18, struct pfioc_state_kill)
+#define DIOCGETSTATE _IOWR('D', 19, struct pfioc_state)
+#define DIOCSETSTATUSIF _IOWR('D', 20, struct pfioc_if)
+#define DIOCGETSTATUS _IOWR('D', 21, struct pf_status)
+#define DIOCCLRSTATUS _IO ('D', 22)
+#define DIOCNATLOOK _IOWR('D', 23, struct pfioc_natlook)
+#define DIOCSETDEBUG _IOWR('D', 24, u_int32_t)
+#define DIOCGETSTATES _IOWR('D', 25, struct pfioc_states)
+#define DIOCCHANGERULE _IOWR('D', 26, struct pfioc_rule)
+/* XXX cut 26 - 28 */
+#define DIOCSETTIMEOUT _IOWR('D', 29, struct pfioc_tm)
+#define DIOCGETTIMEOUT _IOWR('D', 30, struct pfioc_tm)
+#define DIOCADDSTATE _IOWR('D', 37, struct pfioc_state)
+#define DIOCCLRRULECTRS _IO ('D', 38)
+#define DIOCGETLIMIT _IOWR('D', 39, struct pfioc_limit)
+#define DIOCSETLIMIT _IOWR('D', 40, struct pfioc_limit)
+#define DIOCKILLSTATES _IOWR('D', 41, struct pfioc_state_kill)
+#define DIOCSTARTALTQ _IO ('D', 42)
+#define DIOCSTOPALTQ _IO ('D', 43)
+#define DIOCADDALTQ _IOWR('D', 45, struct pfioc_altq)
+#define DIOCGETALTQS _IOWR('D', 47, struct pfioc_altq)
+#define DIOCGETALTQ _IOWR('D', 48, struct pfioc_altq)
+#define DIOCCHANGEALTQ _IOWR('D', 49, struct pfioc_altq)
+#define DIOCGETQSTATS _IOWR('D', 50, struct pfioc_qstats)
+#define DIOCBEGINADDRS _IOWR('D', 51, struct pfioc_pooladdr)
+#define DIOCADDADDR _IOWR('D', 52, struct pfioc_pooladdr)
+#define DIOCGETADDRS _IOWR('D', 53, struct pfioc_pooladdr)
+#define DIOCGETADDR _IOWR('D', 54, struct pfioc_pooladdr)
+#define DIOCCHANGEADDR _IOWR('D', 55, struct pfioc_pooladdr)
+/* XXX cut 55 - 57 */
+#define DIOCGETRULESETS _IOWR('D', 58, struct pfioc_ruleset)
+#define DIOCGETRULESET _IOWR('D', 59, struct pfioc_ruleset)
+#define DIOCRCLRTABLES _IOWR('D', 60, struct pfioc_table)
+#define DIOCRADDTABLES _IOWR('D', 61, struct pfioc_table)
+#define DIOCRDELTABLES _IOWR('D', 62, struct pfioc_table)
+#define DIOCRGETTABLES _IOWR('D', 63, struct pfioc_table)
+#define DIOCRGETTSTATS _IOWR('D', 64, struct pfioc_table)
+#define DIOCRCLRTSTATS _IOWR('D', 65, struct pfioc_table)
+#define DIOCRCLRADDRS _IOWR('D', 66, struct pfioc_table)
+#define DIOCRADDADDRS _IOWR('D', 67, struct pfioc_table)
+#define DIOCRDELADDRS _IOWR('D', 68, struct pfioc_table)
+#define DIOCRSETADDRS _IOWR('D', 69, struct pfioc_table)
+#define DIOCRGETADDRS _IOWR('D', 70, struct pfioc_table)
+#define DIOCRGETASTATS _IOWR('D', 71, struct pfioc_table)
+#define DIOCRCLRASTATS _IOWR('D', 72, struct pfioc_table)
+#define DIOCRTSTADDRS _IOWR('D', 73, struct pfioc_table)
+#define DIOCRSETTFLAGS _IOWR('D', 74, struct pfioc_table)
+#define DIOCRINADEFINE _IOWR('D', 77, struct pfioc_table)
+#define DIOCOSFPFLUSH _IO('D', 78)
+#define DIOCOSFPADD _IOWR('D', 79, struct pf_osfp_ioctl)
+#define DIOCOSFPGET _IOWR('D', 80, struct pf_osfp_ioctl)
+#define DIOCXBEGIN _IOWR('D', 81, struct pfioc_trans)
+#define DIOCXCOMMIT _IOWR('D', 82, struct pfioc_trans)
+#define DIOCXROLLBACK _IOWR('D', 83, struct pfioc_trans)
+#define DIOCGETSRCNODES _IOWR('D', 84, struct pfioc_src_nodes)
+#define DIOCCLRSRCNODES _IO('D', 85)
+#define DIOCSETHOSTID _IOWR('D', 86, u_int32_t)
+#define DIOCIGETIFACES _IOWR('D', 87, struct pfioc_iface)
+#define DIOCSETIFFLAG _IOWR('D', 89, struct pfioc_iface)
+#define DIOCCLRIFFLAG _IOWR('D', 90, struct pfioc_iface)
+#define DIOCKILLSRCNODES _IOWR('D', 91, struct pfioc_src_node_kill)
+#ifdef __FreeBSD__
+struct pf_ifspeed {
+ char ifname[IFNAMSIZ];
+ u_int32_t baudrate;
+};
+#define DIOCGIFSPEED _IOWR('D', 92, struct pf_ifspeed)
+#endif
+
+#ifdef _KERNEL
+RB_HEAD(pf_src_tree, pf_src_node);
+RB_PROTOTYPE(pf_src_tree, pf_src_node, entry, pf_src_compare);
+#ifdef __FreeBSD__
+VNET_DECLARE(struct pf_src_tree, tree_src_tracking);
+#define V_tree_src_tracking VNET(tree_src_tracking)
+#else
+extern struct pf_src_tree tree_src_tracking;
+#endif
+
+RB_HEAD(pf_state_tree_id, pf_state);
+RB_PROTOTYPE(pf_state_tree_id, pf_state,
+ entry_id, pf_state_compare_id);
+#ifdef __FreeBSD__
+VNET_DECLARE(struct pf_state_tree_id, tree_id);
+#define V_tree_id VNET(tree_id)
+VNET_DECLARE(struct pf_state_queue, state_list);
+#define V_state_list VNET(state_list)
+#else
+extern struct pf_state_tree_id tree_id;
+extern struct pf_state_queue state_list;
+#endif
+
+TAILQ_HEAD(pf_poolqueue, pf_pool);
+#ifdef __FreeBSD__
+VNET_DECLARE(struct pf_poolqueue, pf_pools[2]);
+#define V_pf_pools VNET(pf_pools)
+#else
+extern struct pf_poolqueue pf_pools[2];
+#endif
+TAILQ_HEAD(pf_altqqueue, pf_altq);
+#ifdef __FreeBSD__
+VNET_DECLARE(struct pf_altqqueue, pf_altqs[2]);
+#define V_pf_altqs VNET(pf_altqs)
+VNET_DECLARE(struct pf_palist, pf_pabuf);
+#define V_pf_pabuf VNET(pf_pabuf)
+#else
+extern struct pf_altqqueue pf_altqs[2];
+extern struct pf_palist pf_pabuf;
+#endif
+
+#ifdef __FreeBSD__
+VNET_DECLARE(u_int32_t, ticket_altqs_active);
+#define V_ticket_altqs_active VNET(ticket_altqs_active)
+VNET_DECLARE(u_int32_t, ticket_altqs_inactive);
+#define V_ticket_altqs_inactive VNET(ticket_altqs_inactive)
+VNET_DECLARE(int, altqs_inactive_open);
+#define V_altqs_inactive_open VNET(altqs_inactive_open)
+VNET_DECLARE(u_int32_t, ticket_pabuf);
+#define V_ticket_pabuf VNET(ticket_pabuf)
+VNET_DECLARE(struct pf_altqqueue *, pf_altqs_active);
+#define V_pf_altqs_active VNET(pf_altqs_active)
+VNET_DECLARE(struct pf_altqqueue *, pf_altqs_inactive);
+#define V_pf_altqs_inactive VNET(pf_altqs_inactive)
+VNET_DECLARE(struct pf_poolqueue *, pf_pools_active);
+#define V_pf_pools_active VNET(pf_pools_active)
+VNET_DECLARE(struct pf_poolqueue *, pf_pools_inactive);
+#define V_pf_pools_inactive VNET(pf_pools_inactive)
+#else
+extern u_int32_t ticket_altqs_active;
+extern u_int32_t ticket_altqs_inactive;
+extern int altqs_inactive_open;
+extern u_int32_t ticket_pabuf;
+extern struct pf_altqqueue *pf_altqs_active;
+extern struct pf_altqqueue *pf_altqs_inactive;
+extern struct pf_poolqueue *pf_pools_active;
+extern struct pf_poolqueue *pf_pools_inactive;
+#endif
+extern int pf_tbladdr_setup(struct pf_ruleset *,
+ struct pf_addr_wrap *);
+extern void pf_tbladdr_remove(struct pf_addr_wrap *);
+extern void pf_tbladdr_copyout(struct pf_addr_wrap *);
+extern void pf_calc_skip_steps(struct pf_rulequeue *);
+#ifdef __FreeBSD__
+#ifdef ALTQ
+extern void pf_altq_ifnet_event(struct ifnet *, int);
+#endif
+VNET_DECLARE(uma_zone_t, pf_src_tree_pl);
+#define V_pf_src_tree_pl VNET(pf_src_tree_pl)
+VNET_DECLARE(uma_zone_t, pf_rule_pl);
+#define V_pf_rule_pl VNET(pf_rule_pl)
+VNET_DECLARE(uma_zone_t, pf_state_pl);
+#define V_pf_state_pl VNET(pf_state_pl)
+VNET_DECLARE(uma_zone_t, pf_state_key_pl);
+#define V_pf_state_key_pl VNET(pf_state_key_pl)
+VNET_DECLARE(uma_zone_t, pf_state_item_pl);
+#define V_pf_state_item_pl VNET(pf_state_item_pl)
+VNET_DECLARE(uma_zone_t, pf_altq_pl);
+#define V_pf_altq_pl VNET(pf_altq_pl)
+VNET_DECLARE(uma_zone_t, pf_pooladdr_pl);
+#define V_pf_pooladdr_pl VNET(pf_pooladdr_pl)
+VNET_DECLARE(uma_zone_t, pfr_ktable_pl);
+#define V_pfr_ktable_pl VNET(pfr_ktable_pl)
+VNET_DECLARE(uma_zone_t, pfr_kentry_pl);
+#define V_pfr_kentry_pl VNET(pfr_kentry_pl)
+VNET_DECLARE(uma_zone_t, pfr_kcounters_pl);
+#define V_pfr_kcounters_pl VNET(pfr_kcounters_pl)
+VNET_DECLARE(uma_zone_t, pf_cache_pl);
+#define V_pf_cache_pl VNET(pf_cache_pl)
+VNET_DECLARE(uma_zone_t, pf_cent_pl);
+#define V_pf_cent_pl VNET(pf_cent_pl)
+VNET_DECLARE(uma_zone_t, pf_state_scrub_pl);
+#define V_pf_state_scrub_pl VNET(pf_state_scrub_pl)
+VNET_DECLARE(uma_zone_t, pfi_addr_pl);
+#define V_pfi_addr_pl VNET(pfi_addr_pl)
+#else
+extern struct pool pf_src_tree_pl, pf_rule_pl;
+extern struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl,
+ pf_altq_pl, pf_pooladdr_pl;
+extern struct pool pf_state_scrub_pl;
+#endif
+extern void pf_purge_thread(void *);
+#ifdef __FreeBSD__
+extern int pf_purge_expired_src_nodes(int);
+extern int pf_purge_expired_states(u_int32_t , int);
+#else
+extern void pf_purge_expired_src_nodes(int);
+extern void pf_purge_expired_states(u_int32_t);
+#endif
+extern void pf_unlink_state(struct pf_state *);
+extern void pf_free_state(struct pf_state *);
+extern int pf_state_insert(struct pfi_kif *,
+ struct pf_state_key *,
+ struct pf_state_key *,
+ struct pf_state *);
+extern int pf_insert_src_node(struct pf_src_node **,
+ struct pf_rule *, struct pf_addr *,
+ sa_family_t);
+void pf_src_tree_remove_state(struct pf_state *);
+extern struct pf_state *pf_find_state_byid(struct pf_state_cmp *);
+extern struct pf_state *pf_find_state_all(struct pf_state_key_cmp *,
+ u_int, int *);
+extern void pf_print_state(struct pf_state *);
+extern void pf_print_flags(u_int8_t);
+extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,
+ u_int8_t);
+
+#ifdef __FreeBSD__
+VNET_DECLARE(struct ifnet *, sync_ifp);
+#define V_sync_ifp VNET(sync_ifp);
+VNET_DECLARE(struct pf_rule, pf_default_rule);
+#define V_pf_default_rule VNET(pf_default_rule)
+#else
+extern struct ifnet *sync_ifp;
+extern struct pf_rule pf_default_rule;
+#endif
+extern void pf_addrcpy(struct pf_addr *, struct pf_addr *,
+ u_int8_t);
+void pf_rm_rule(struct pf_rulequeue *,
+ struct pf_rule *);
+#ifndef __FreeBSD__
+struct pf_divert *pf_find_divert(struct mbuf *);
+#endif
+
+#ifdef INET
+#ifdef __FreeBSD__
+int pf_test(int, struct ifnet *, struct mbuf **, struct ether_header *,
+ struct inpcb *);
+#else
+int pf_test(int, struct ifnet *, struct mbuf **, struct ether_header *);
+#endif
+#endif /* INET */
+
+#ifdef INET6
+#ifdef __FreeBSD__
+int pf_test6(int, struct ifnet *, struct mbuf **, struct ether_header *,
+ struct inpcb *);
+#else
+int pf_test6(int, struct ifnet *, struct mbuf **, struct ether_header *);
+#endif
+void pf_poolmask(struct pf_addr *, struct pf_addr*,
+ struct pf_addr *, struct pf_addr *, u_int8_t);
+void pf_addr_inc(struct pf_addr *, sa_family_t);
+#endif /* INET6 */
+
+#ifdef __FreeBSD__
+u_int32_t pf_new_isn(struct pf_state *);
+#endif
+void *pf_pull_hdr(struct mbuf *, int, void *, int, u_short *, u_short *,
+ sa_family_t);
+void pf_change_a(void *, u_int16_t *, u_int32_t, u_int8_t);
+int pflog_packet(struct pfi_kif *, struct mbuf *, sa_family_t, u_int8_t,
+ u_int8_t, struct pf_rule *, struct pf_rule *, struct pf_ruleset *,
+ struct pf_pdesc *);
+void pf_send_deferred_syn(struct pf_state *);
+int pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *,
+ struct pf_addr *, sa_family_t);
+int pf_match_addr_range(struct pf_addr *, struct pf_addr *,
+ struct pf_addr *, sa_family_t);
+int pf_match(u_int8_t, u_int32_t, u_int32_t, u_int32_t);
+int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t);
+int pf_match_uid(u_int8_t, uid_t, uid_t, uid_t);
+int pf_match_gid(u_int8_t, gid_t, gid_t, gid_t);
+
+void pf_normalize_init(void);
+int pf_normalize_ip(struct mbuf **, int, struct pfi_kif *, u_short *,
+ struct pf_pdesc *);
+int pf_normalize_ip6(struct mbuf **, int, struct pfi_kif *, u_short *,
+ struct pf_pdesc *);
+int pf_normalize_tcp(int, struct pfi_kif *, struct mbuf *, int, int, void *,
+ struct pf_pdesc *);
+void pf_normalize_tcp_cleanup(struct pf_state *);
+int pf_normalize_tcp_init(struct mbuf *, int, struct pf_pdesc *,
+ struct tcphdr *, struct pf_state_peer *, struct pf_state_peer *);
+int pf_normalize_tcp_stateful(struct mbuf *, int, struct pf_pdesc *,
+ u_short *, struct tcphdr *, struct pf_state *,
+ struct pf_state_peer *, struct pf_state_peer *, int *);
+u_int32_t
+ pf_state_expires(const struct pf_state *);
+void pf_purge_expired_fragments(void);
+int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *,
+ int);
+int pf_rtlabel_match(struct pf_addr *, sa_family_t, struct pf_addr_wrap *,
+ int);
+#ifdef __FreeBSD__
+int pf_socket_lookup(int, struct pf_pdesc *, struct inpcb *);
+#else
+int pf_socket_lookup(int, struct pf_pdesc *);
+#endif
+struct pf_state_key *pf_alloc_state_key(int);
+void pf_pkt_addr_changed(struct mbuf *);
+int pf_state_key_attach(struct pf_state_key *, struct pf_state *, int);
+void pfr_initialize(void);
+int pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t);
+void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t,
+ u_int64_t, int, int, int);
+int pfr_pool_get(struct pfr_ktable *, int *, struct pf_addr *,
+ struct pf_addr **, struct pf_addr **, sa_family_t);
+void pfr_dynaddr_update(struct pfr_ktable *, struct pfi_dynaddr *);
+struct pfr_ktable *
+ pfr_attach_table(struct pf_ruleset *, char *, int);
+void pfr_detach_table(struct pfr_ktable *);
+int pfr_clr_tables(struct pfr_table *, int *, int);
+int pfr_add_tables(struct pfr_table *, int, int *, int);
+int pfr_del_tables(struct pfr_table *, int, int *, int);
+int pfr_get_tables(struct pfr_table *, struct pfr_table *, int *, int);
+int pfr_get_tstats(struct pfr_table *, struct pfr_tstats *, int *, int);
+int pfr_clr_tstats(struct pfr_table *, int, int *, int);
+int pfr_set_tflags(struct pfr_table *, int, int, int, int *, int *, int);
+int pfr_clr_addrs(struct pfr_table *, int *, int);
+int pfr_insert_kentry(struct pfr_ktable *, struct pfr_addr *, long);
+int pfr_add_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
+ int);
+int pfr_del_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
+ int);
+int pfr_set_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
+ int *, int *, int *, int, u_int32_t);
+int pfr_get_addrs(struct pfr_table *, struct pfr_addr *, int *, int);
+int pfr_get_astats(struct pfr_table *, struct pfr_astats *, int *, int);
+int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *,
+ int);
+int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
+ int);
+int pfr_ina_begin(struct pfr_table *, u_int32_t *, int *, int);
+int pfr_ina_rollback(struct pfr_table *, u_int32_t, int *, int);
+int pfr_ina_commit(struct pfr_table *, u_int32_t, int *, int *, int);
+int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
+ int *, u_int32_t, int);
+
+#ifdef __FreeBSD__
+VNET_DECLARE(struct pfi_kif *, pfi_all);
+#define V_pfi_all VNET(pfi_all)
+#else
+extern struct pfi_kif *pfi_all;
+#endif
+
+void pfi_initialize(void);
+#ifdef __FreeBSD__
+void pfi_cleanup(void);
+#endif
+struct pfi_kif *pfi_kif_get(const char *);
+void pfi_kif_ref(struct pfi_kif *, enum pfi_kif_refs);
+void pfi_kif_unref(struct pfi_kif *, enum pfi_kif_refs);
+int pfi_kif_match(struct pfi_kif *, struct pfi_kif *);
+void pfi_attach_ifnet(struct ifnet *);
+void pfi_detach_ifnet(struct ifnet *);
+void pfi_attach_ifgroup(struct ifg_group *);
+void pfi_detach_ifgroup(struct ifg_group *);
+void pfi_group_change(const char *);
+int pfi_match_addr(struct pfi_dynaddr *, struct pf_addr *,
+ sa_family_t);
+int pfi_dynaddr_setup(struct pf_addr_wrap *, sa_family_t);
+void pfi_dynaddr_remove(struct pf_addr_wrap *);
+void pfi_dynaddr_copyout(struct pf_addr_wrap *);
+void pfi_update_status(const char *, struct pf_status *);
+int pfi_get_ifaces(const char *, struct pfi_kif *, int *);
+int pfi_set_flags(const char *, int);
+int pfi_clear_flags(const char *, int);
+
+#ifdef __FreeBSD__
+int pf_match_tag(struct mbuf *, struct pf_rule *, int *,
+ struct pf_mtag *);
+#else
+int pf_match_tag(struct mbuf *, struct pf_rule *, int *);
+#endif
+u_int16_t pf_tagname2tag(char *);
+void pf_tag2tagname(u_int16_t, char *);
+void pf_tag_ref(u_int16_t);
+void pf_tag_unref(u_int16_t);
+#ifdef __FreeBSD__
+int pf_tag_packet(struct mbuf *, int, int, struct pf_mtag *);
+#else
+int pf_tag_packet(struct mbuf *, int, int);
+#endif
+u_int32_t pf_qname2qid(char *);
+void pf_qid2qname(u_int32_t, char *);
+void pf_qid_unref(u_int32_t);
+
+#ifdef __FreeBSD__
+VNET_DECLARE(struct pf_status, pf_status);
+#define V_pf_status VNET(pf_status)
+#else
+extern struct pf_status pf_status;
+#endif
+
+#ifdef __FreeBSD__
+VNET_DECLARE(uma_zone_t, pf_frent_pl);
+#define V_pf_frent_pl VNET(pf_frent_pl)
+VNET_DECLARE(uma_zone_t, pf_frag_pl);
+#define V_pf_frag_pl VNET(pf_frag_pl)
+VNET_DECLARE(struct sx, pf_consistency_lock);
+#define V_pf_consistency_lock VNET(pf_consistency_lock)
+#else
+extern struct pool pf_frent_pl, pf_frag_pl;
+extern struct rwlock pf_consistency_lock;
+#endif
+
+struct pf_pool_limit {
+ void *pp;
+ unsigned limit;
+};
+#ifdef __FreeBSD__
+VNET_DECLARE(struct pf_pool_limit, pf_pool_limits[PF_LIMIT_MAX]);
+#define V_pf_pool_limits VNET(pf_pool_limits)
+#else
+extern struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX];
+#endif
+
+#ifdef __FreeBSD__
+struct pf_frent {
+ LIST_ENTRY(pf_frent) fr_next;
+ struct ip *fr_ip;
+ struct mbuf *fr_m;
+};
+
+struct pf_frcache {
+ LIST_ENTRY(pf_frcache) fr_next;
+ uint16_t fr_off;
+ uint16_t fr_end;
+};
+
+struct pf_fragment {
+ RB_ENTRY(pf_fragment) fr_entry;
+ TAILQ_ENTRY(pf_fragment) frag_next;
+ struct in_addr fr_src;
+ struct in_addr fr_dst;
+ u_int8_t fr_p; /* protocol of this fragment */
+ u_int8_t fr_flags; /* status flags */
+ u_int16_t fr_id; /* fragment id for reassemble */
+ u_int16_t fr_max; /* fragment data max */
+ u_int32_t fr_timeout;
+#define fr_queue fr_u.fru_queue
+#define fr_cache fr_u.fru_cache
+ union {
+ LIST_HEAD(pf_fragq, pf_frent) fru_queue; /* buffering */
+ LIST_HEAD(pf_cacheq, pf_frcache) fru_cache; /* non-buf */
+ } fr_u;
+};
+#endif /* (__FreeBSD__) */
+
+#endif /* _KERNEL */
+
+#ifdef __FreeBSD__
+#ifdef _KERNEL
+VNET_DECLARE(struct pf_anchor_global, pf_anchors);
+#define V_pf_anchors VNET(pf_anchors)
+VNET_DECLARE(struct pf_anchor, pf_main_anchor);
+#define V_pf_main_anchor VNET(pf_main_anchor)
+#define pf_main_ruleset V_pf_main_anchor.ruleset
+#endif
+#else
+extern struct pf_anchor_global pf_anchors;
+extern struct pf_anchor pf_main_anchor;
+#define pf_main_ruleset pf_main_anchor.ruleset
+#endif
+
+/* these ruleset functions can be linked into userland programs (pfctl) */
+int pf_get_ruleset_number(u_int8_t);
+void pf_init_ruleset(struct pf_ruleset *);
+int pf_anchor_setup(struct pf_rule *,
+ const struct pf_ruleset *, const char *);
+int pf_anchor_copyout(const struct pf_ruleset *,
+ const struct pf_rule *, struct pfioc_rule *);
+void pf_anchor_remove(struct pf_rule *);
+void pf_remove_if_empty_ruleset(struct pf_ruleset *);
+struct pf_anchor *pf_find_anchor(const char *);
+struct pf_ruleset *pf_find_ruleset(const char *);
+struct pf_ruleset *pf_find_or_create_ruleset(const char *);
+void pf_rs_initialize(void);
+
+#ifndef __FreeBSD__
+#ifdef _KERNEL
+int pf_anchor_copyout(const struct pf_ruleset *,
+ const struct pf_rule *, struct pfioc_rule *);
+void pf_anchor_remove(struct pf_rule *);
+
+#endif /* _KERNEL */
+#endif
+
+/* The fingerprint functions can be linked into userland programs (tcpdump) */
+int pf_osfp_add(struct pf_osfp_ioctl *);
+#ifdef _KERNEL
+struct pf_osfp_enlist *
+ pf_osfp_fingerprint(struct pf_pdesc *, struct mbuf *, int,
+ const struct tcphdr *);
+#endif /* _KERNEL */
+struct pf_osfp_enlist *
+ pf_osfp_fingerprint_hdr(const struct ip *, const struct ip6_hdr *,
+ const struct tcphdr *);
+void pf_osfp_flush(void);
+int pf_osfp_get(struct pf_osfp_ioctl *);
+#ifdef __FreeBSD__
+int pf_osfp_initialize(void);
+void pf_osfp_cleanup(void);
+#else
+void pf_osfp_initialize(void);
+#endif
+int pf_osfp_match(struct pf_osfp_enlist *, pf_osfp_t);
+struct pf_os_fingerprint *
+ pf_osfp_validate(void);
+
+#ifdef _KERNEL
+void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
+
+void pf_step_into_anchor(int *, struct pf_ruleset **, int,
+ struct pf_rule **, struct pf_rule **, int *);
+int pf_step_out_of_anchor(int *, struct pf_ruleset **,
+ int, struct pf_rule **, struct pf_rule **,
+ int *);
+
+int pf_map_addr(u_int8_t, struct pf_rule *,
+ struct pf_addr *, struct pf_addr *,
+ struct pf_addr *, struct pf_src_node **);
+struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
+ int, int, struct pfi_kif *, struct pf_src_node **,
+ struct pf_state_key **, struct pf_state_key **,
+ struct pf_state_key **, struct pf_state_key **,
+ struct pf_addr *, struct pf_addr *,
+ u_int16_t, u_int16_t);
+
+int pf_state_key_setup(struct pf_pdesc *, struct pf_rule *,
+ struct pf_state_key **, struct pf_state_key **,
+ struct pf_state_key **, struct pf_state_key **,
+ struct pf_addr *, struct pf_addr *,
+ u_int16_t, u_int16_t);
+#endif /* _KERNEL */
+
+
+#endif /* _NET_PFVAR_H_ */
diff --git a/sys/contrib/pf/netinet/in4_cksum.c b/sys/contrib/pf/netinet/in4_cksum.c
new file mode 100644
index 0000000..bf25baf
--- /dev/null
+++ b/sys/contrib/pf/netinet/in4_cksum.c
@@ -0,0 +1,120 @@
+/* $FreeBSD$ */
+/* $OpenBSD: in4_cksum.c,v 1.7 2003/06/02 23:28:13 millert Exp $ */
+/* $KAME: in4_cksum.c,v 1.10 2001/11/30 10:06:15 itojun Exp $ */
+/* $NetBSD: in_cksum.c,v 1.13 1996/10/13 02:03:03 christos Exp $ */
+
+/*
+ * Copyright (C) 1999 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1988, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#include <machine/in_cksum.h>
+
+#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
+#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; (void)ADDCARRY(sum);}
+
+int in4_cksum(struct mbuf *, u_int8_t, int, int);
+
+int
+in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len)
+{
+ union {
+ struct ipovly ipov;
+ u_int16_t w[10];
+ } u;
+ union {
+ u_int16_t s[2];
+ u_int32_t l;
+ } l_util;
+
+ u_int16_t *w;
+ int psum;
+ int sum = 0;
+
+ if (nxt != 0) {
+ /* pseudo header */
+ if (off < sizeof(struct ipovly))
+ panic("in4_cksum: offset too short");
+ if (m->m_len < sizeof(struct ip))
+ panic("in4_cksum: bad mbuf chain");
+ bzero(&u.ipov, sizeof(u.ipov));
+ u.ipov.ih_len = htons(len);
+ u.ipov.ih_pr = nxt;
+ u.ipov.ih_src = mtod(m, struct ip *)->ip_src;
+ u.ipov.ih_dst = mtod(m, struct ip *)->ip_dst;
+ w = u.w;
+ /* assumes sizeof(ipov) == 20 */
+ sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; sum += w[4];
+ sum += w[5]; sum += w[6]; sum += w[7]; sum += w[8]; sum += w[9];
+ }
+
+ psum = in_cksum_skip(m, len + off, off);
+ psum = ~psum & 0xffff;
+ sum += psum;
+ REDUCE;
+ return (~sum & 0xffff);
+}
diff --git a/sys/netinet/ipfw/dn_heap.c b/sys/netinet/ipfw/dn_heap.c
new file mode 100644
index 0000000..3bdfd9d
--- /dev/null
+++ b/sys/netinet/ipfw/dn_heap.c
@@ -0,0 +1,552 @@
+/*-
+ * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Binary heap and hash tables, used in dummynet
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#ifdef _KERNEL
+__FBSDID("$FreeBSD$");
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <netinet/ipfw/dn_heap.h>
+#ifndef log
+#define log(x, arg...)
+#endif
+
+#else /* !_KERNEL */
+
+#include <stdio.h>
+#include <dn_test.h>
+#include <strings.h>
+#include <stdlib.h>
+
+#include "dn_heap.h"
+#define log(x, arg...) fprintf(stderr, ## arg)
+#define panic(x...) fprintf(stderr, ## x), exit(1)
+#define MALLOC_DEFINE(a, b, c)
+static void *my_malloc(int s) { return malloc(s); }
+static void my_free(void *p) { free(p); }
+#define malloc(s, t, w) my_malloc(s)
+#define free(p, t) my_free(p)
+#endif /* !_KERNEL */
+
+static MALLOC_DEFINE(M_DN_HEAP, "dummynet", "dummynet heap");
+
+/*
+ * Heap management functions.
+ *
+ * In the heap, first node is element 0. Children of i are 2i+1 and 2i+2.
+ * Some macros help finding parent/children so we can optimize them.
+ *
+ * heap_init() is called to expand the heap when needed.
+ * Increment size in blocks of 16 entries.
+ * Returns 1 on error, 0 on success
+ */
+#define HEAP_FATHER(x) ( ( (x) - 1 ) / 2 )
+#define HEAP_LEFT(x) ( (x)+(x) + 1 )
+#define HEAP_SWAP(a, b, buffer) { buffer = a ; a = b ; b = buffer ; }
+#define HEAP_INCREMENT 15
+
+static int
+heap_resize(struct dn_heap *h, unsigned int new_size)
+{
+ struct dn_heap_entry *p;
+
+ if (h->size >= new_size ) /* have enough room */
+ return 0;
+#if 1 /* round to the next power of 2 */
+ new_size |= new_size >> 1;
+ new_size |= new_size >> 2;
+ new_size |= new_size >> 4;
+ new_size |= new_size >> 8;
+ new_size |= new_size >> 16;
+#else
+ new_size = (new_size + HEAP_INCREMENT ) & ~HEAP_INCREMENT;
+#endif
+ p = malloc(new_size * sizeof(*p), M_DN_HEAP, M_NOWAIT);
+ if (p == NULL) {
+ printf("--- %s, resize %d failed\n", __func__, new_size );
+ return 1; /* error */
+ }
+ if (h->size > 0) {
+ bcopy(h->p, p, h->size * sizeof(*p) );
+ free(h->p, M_DN_HEAP);
+ }
+ h->p = p;
+ h->size = new_size;
+ return 0;
+}
+
+int
+heap_init(struct dn_heap *h, int size, int ofs)
+{
+ if (heap_resize(h, size))
+ return 1;
+ h->elements = 0;
+ h->ofs = ofs;
+ return 0;
+}
+
+/*
+ * Insert element in heap. Normally, p != NULL, we insert p in
+ * a new position and bubble up. If p == NULL, then the element is
+ * already in place, and key is the position where to start the
+ * bubble-up.
+ * Returns 1 on failure (cannot allocate new heap entry)
+ *
+ * If ofs > 0 the position (index, int) of the element in the heap is
+ * also stored in the element itself at the given offset in bytes.
+ */
+#define SET_OFFSET(h, i) do { \
+ if (h->ofs > 0) \
+ *((int32_t *)((char *)(h->p[i].object) + h->ofs)) = i; \
+ } while (0)
+/*
+ * RESET_OFFSET is used for sanity checks. It sets ofs
+ * to an invalid value.
+ */
+#define RESET_OFFSET(h, i) do { \
+ if (h->ofs > 0) \
+ *((int32_t *)((char *)(h->p[i].object) + h->ofs)) = -16; \
+ } while (0)
+
+int
+heap_insert(struct dn_heap *h, uint64_t key1, void *p)
+{
+ int son = h->elements;
+
+ //log("%s key %llu p %p\n", __FUNCTION__, key1, p);
+ if (p == NULL) { /* data already there, set starting point */
+ son = key1;
+ } else { /* insert new element at the end, possibly resize */
+ son = h->elements;
+ if (son == h->size) /* need resize... */
+ // XXX expand by 16 or so
+ if (heap_resize(h, h->elements+16) )
+ return 1; /* failure... */
+ h->p[son].object = p;
+ h->p[son].key = key1;
+ h->elements++;
+ }
+ /* make sure that son >= father along the path */
+ while (son > 0) {
+ int father = HEAP_FATHER(son);
+ struct dn_heap_entry tmp;
+
+ if (DN_KEY_LT( h->p[father].key, h->p[son].key ) )
+ break; /* found right position */
+ /* son smaller than father, swap and repeat */
+ HEAP_SWAP(h->p[son], h->p[father], tmp);
+ SET_OFFSET(h, son);
+ son = father;
+ }
+ SET_OFFSET(h, son);
+ return 0;
+}
+
+/*
+ * remove top element from heap, or obj if obj != NULL
+ */
+void
+heap_extract(struct dn_heap *h, void *obj)
+{
+ int child, father, max = h->elements - 1;
+
+ if (max < 0) {
+ printf("--- %s: empty heap 0x%p\n", __FUNCTION__, h);
+ return;
+ }
+ if (obj == NULL)
+ father = 0; /* default: move up smallest child */
+ else { /* extract specific element, index is at offset */
+ if (h->ofs <= 0)
+ panic("%s: extract from middle not set on %p\n",
+ __FUNCTION__, h);
+ father = *((int *)((char *)obj + h->ofs));
+ if (father < 0 || father >= h->elements) {
+ panic("%s: father %d out of bound 0..%d\n",
+ __FUNCTION__, father, h->elements);
+ }
+ }
+ /*
+ * below, father is the index of the empty element, which
+ * we replace at each step with the smallest child until we
+ * reach the bottom level.
+ */
+ // XXX why removing RESET_OFFSET increases runtime by 10% ?
+ RESET_OFFSET(h, father);
+ while ( (child = HEAP_LEFT(father)) <= max ) {
+ if (child != max &&
+ DN_KEY_LT(h->p[child+1].key, h->p[child].key) )
+ child++; /* take right child, otherwise left */
+ h->p[father] = h->p[child];
+ SET_OFFSET(h, father);
+ father = child;
+ }
+ h->elements--;
+ if (father != max) {
+ /*
+ * Fill hole with last entry and bubble up,
+ * reusing the insert code
+ */
+ h->p[father] = h->p[max];
+ heap_insert(h, father, NULL);
+ }
+}
+
+#if 0
+/*
+ * change object position and update references
+ * XXX this one is never used!
+ */
+static void
+heap_move(struct dn_heap *h, uint64_t new_key, void *object)
+{
+ int temp, i, max = h->elements-1;
+ struct dn_heap_entry *p, buf;
+
+ if (h->ofs <= 0)
+ panic("cannot move items on this heap");
+ p = h->p; /* shortcut */
+
+ i = *((int *)((char *)object + h->ofs));
+ if (DN_KEY_LT(new_key, p[i].key) ) { /* must move up */
+ p[i].key = new_key;
+ for (; i>0 &&
+ DN_KEY_LT(new_key, p[(temp = HEAP_FATHER(i))].key);
+ i = temp ) { /* bubble up */
+ HEAP_SWAP(p[i], p[temp], buf);
+ SET_OFFSET(h, i);
+ }
+ } else { /* must move down */
+ p[i].key = new_key;
+ while ( (temp = HEAP_LEFT(i)) <= max ) {
+ /* found left child */
+ if (temp != max &&
+ DN_KEY_LT(p[temp+1].key, p[temp].key))
+ temp++; /* select child with min key */
+ if (DN_KEY_LT(>p[temp].key, new_key)) {
+ /* go down */
+ HEAP_SWAP(p[i], p[temp], buf);
+ SET_OFFSET(h, i);
+ } else
+ break;
+ i = temp;
+ }
+ }
+ SET_OFFSET(h, i);
+}
+#endif /* heap_move, unused */
+
+/*
+ * heapify() will reorganize data inside an array to maintain the
+ * heap property. It is needed when we delete a bunch of entries.
+ */
+static void
+heapify(struct dn_heap *h)
+{
+ int i;
+
+ for (i = 0; i < h->elements; i++ )
+ heap_insert(h, i , NULL);
+}
+
+int
+heap_scan(struct dn_heap *h, int (*fn)(void *, uintptr_t),
+ uintptr_t arg)
+{
+ int i, ret, found;
+
+ for (i = found = 0 ; i < h->elements ;) {
+ ret = fn(h->p[i].object, arg);
+ if (ret & HEAP_SCAN_DEL) {
+ h->elements-- ;
+ h->p[i] = h->p[h->elements] ;
+ found++ ;
+ } else
+ i++ ;
+ if (ret & HEAP_SCAN_END)
+ break;
+ }
+ if (found)
+ heapify(h);
+ return found;
+}
+
+/*
+ * cleanup the heap and free data structure
+ */
+void
+heap_free(struct dn_heap *h)
+{
+ if (h->size >0 )
+ free(h->p, M_DN_HEAP);
+ bzero(h, sizeof(*h) );
+}
+
+/*
+ * hash table support.
+ */
+
+struct dn_ht {
+ int buckets; /* how many buckets, really buckets - 1*/
+ int entries; /* how many entries */
+ int ofs; /* offset of link field */
+ uint32_t (*hash)(uintptr_t, int, void *arg);
+ int (*match)(void *_el, uintptr_t key, int, void *);
+ void *(*newh)(uintptr_t, int, void *);
+ void **ht; /* bucket heads */
+};
+/*
+ * Initialize, allocating bucket pointers inline.
+ * Recycle previous record if possible.
+ * If the 'newh' function is not supplied, we assume that the
+ * key passed to ht_find is the same object to be stored in.
+ */
+struct dn_ht *
+dn_ht_init(struct dn_ht *ht, int buckets, int ofs,
+ uint32_t (*h)(uintptr_t, int, void *),
+ int (*match)(void *, uintptr_t, int, void *),
+ void *(*newh)(uintptr_t, int, void *))
+{
+ int l;
+
+ /*
+ * Notes about rounding bucket size to a power of two.
+ * Given the original bucket size, we compute the nearest lower and
+ * higher power of two, minus 1 (respectively b_min and b_max) because
+ * this value will be used to do an AND with the index returned
+ * by hash function.
+ * To choice between these two values, the original bucket size is
+ * compared with b_min. If the original size is greater than 4/3 b_min,
+ * we round the bucket size to b_max, else to b_min.
+ * This ratio try to round to the nearest power of two, advantaging
+ * the greater size if the different between two power is relatively
+ * big.
+ * Rounding the bucket size to a power of two avoid the use of
+ * module when calculating the correct bucket.
+ * The ht->buckets variable store the bucket size - 1 to simply
+ * do an AND between the index returned by hash function and ht->bucket
+ * instead of a module.
+ */
+ int b_min; /* min buckets */
+ int b_max; /* max buckets */
+ int b_ori; /* original buckets */
+
+ if (h == NULL || match == NULL) {
+ printf("--- missing hash or match function");
+ return NULL;
+ }
+ if (buckets < 1 || buckets > 65536)
+ return NULL;
+
+ b_ori = buckets;
+ /* calculate next power of 2, - 1*/
+ buckets |= buckets >> 1;
+ buckets |= buckets >> 2;
+ buckets |= buckets >> 4;
+ buckets |= buckets >> 8;
+ buckets |= buckets >> 16;
+
+ b_max = buckets; /* Next power */
+ b_min = buckets >> 1; /* Previous power */
+
+ /* Calculate the 'nearest' bucket size */
+ if (b_min * 4000 / 3000 < b_ori)
+ buckets = b_max;
+ else
+ buckets = b_min;
+
+ if (ht) { /* see if we can reuse */
+ if (buckets <= ht->buckets) {
+ ht->buckets = buckets;
+ } else {
+ /* free pointers if not allocated inline */
+ if (ht->ht != (void *)(ht + 1))
+ free(ht->ht, M_DN_HEAP);
+ free(ht, M_DN_HEAP);
+ ht = NULL;
+ }
+ }
+ if (ht == NULL) {
+ /* Allocate buckets + 1 entries because buckets is use to
+ * do the AND with the index returned by hash function
+ */
+ l = sizeof(*ht) + (buckets + 1) * sizeof(void **);
+ ht = malloc(l, M_DN_HEAP, M_NOWAIT | M_ZERO);
+ }
+ if (ht) {
+ ht->ht = (void **)(ht + 1);
+ ht->buckets = buckets;
+ ht->ofs = ofs;
+ ht->hash = h;
+ ht->match = match;
+ ht->newh = newh;
+ }
+ return ht;
+}
+
+/* dummy callback for dn_ht_free to unlink all */
+static int
+do_del(void *obj, void *arg)
+{
+ return DNHT_SCAN_DEL;
+}
+
+void
+dn_ht_free(struct dn_ht *ht, int flags)
+{
+ if (ht == NULL)
+ return;
+ if (flags & DNHT_REMOVE) {
+ (void)dn_ht_scan(ht, do_del, NULL);
+ } else {
+ if (ht->ht && ht->ht != (void *)(ht + 1))
+ free(ht->ht, M_DN_HEAP);
+ free(ht, M_DN_HEAP);
+ }
+}
+
+int
+dn_ht_entries(struct dn_ht *ht)
+{
+ return ht ? ht->entries : 0;
+}
+
+/* lookup and optionally create or delete element */
+void *
+dn_ht_find(struct dn_ht *ht, uintptr_t key, int flags, void *arg)
+{
+ int i;
+ void **pp, *p;
+
+ if (ht == NULL) /* easy on an empty hash */
+ return NULL;
+ i = (ht->buckets == 1) ? 0 :
+ (ht->hash(key, flags, arg) & ht->buckets);
+
+ for (pp = &ht->ht[i]; (p = *pp); pp = (void **)((char *)p + ht->ofs)) {
+ if (flags & DNHT_MATCH_PTR) {
+ if (key == (uintptr_t)p)
+ break;
+ } else if (ht->match(p, key, flags, arg)) /* found match */
+ break;
+ }
+ if (p) {
+ if (flags & DNHT_REMOVE) {
+ /* link in the next element */
+ *pp = *(void **)((char *)p + ht->ofs);
+ *(void **)((char *)p + ht->ofs) = NULL;
+ ht->entries--;
+ }
+ } else if (flags & DNHT_INSERT) {
+ // printf("%s before calling new, bucket %d ofs %d\n",
+ // __FUNCTION__, i, ht->ofs);
+ p = ht->newh ? ht->newh(key, flags, arg) : (void *)key;
+ // printf("%s newh returns %p\n", __FUNCTION__, p);
+ if (p) {
+ ht->entries++;
+ *(void **)((char *)p + ht->ofs) = ht->ht[i];
+ ht->ht[i] = p;
+ }
+ }
+ return p;
+}
+
+/*
+ * do a scan with the option to delete the object. Extract next before
+ * running the callback because the element may be destroyed there.
+ */
+int
+dn_ht_scan(struct dn_ht *ht, int (*fn)(void *, void *), void *arg)
+{
+ int i, ret, found = 0;
+ void **curp, *cur, *next;
+
+ if (ht == NULL || fn == NULL)
+ return 0;
+ for (i = 0; i <= ht->buckets; i++) {
+ curp = &ht->ht[i];
+ while ( (cur = *curp) != NULL) {
+ next = *(void **)((char *)cur + ht->ofs);
+ ret = fn(cur, arg);
+ if (ret & DNHT_SCAN_DEL) {
+ found++;
+ ht->entries--;
+ *curp = next;
+ } else {
+ curp = (void **)((char *)cur + ht->ofs);
+ }
+ if (ret & DNHT_SCAN_END)
+ return found;
+ }
+ }
+ return found;
+}
+
+/*
+ * Similar to dn_ht_scan(), except that the scan is performed only
+ * in the bucket 'bucket'. The function returns a correct bucket number if
+ * the original is invalid.
+ * If the callback returns DNHT_SCAN_END, the function move the ht->ht[i]
+ * pointer to the last entry processed. Moreover, the bucket number passed
+ * by caller is decremented, because usually the caller increment it.
+ */
+int
+dn_ht_scan_bucket(struct dn_ht *ht, int *bucket, int (*fn)(void *, void *),
+ void *arg)
+{
+ int i, ret, found = 0;
+ void **curp, *cur, *next;
+
+ if (ht == NULL || fn == NULL)
+ return 0;
+ if (*bucket > ht->buckets)
+ *bucket = 0;
+ i = *bucket;
+
+ curp = &ht->ht[i];
+ while ( (cur = *curp) != NULL) {
+ next = *(void **)((char *)cur + ht->ofs);
+ ret = fn(cur, arg);
+ if (ret & DNHT_SCAN_DEL) {
+ found++;
+ ht->entries--;
+ *curp = next;
+ } else {
+ curp = (void **)((char *)cur + ht->ofs);
+ }
+ if (ret & DNHT_SCAN_END)
+ return found;
+ }
+ return found;
+}
diff --git a/sys/netinet/ipfw/dn_heap.h b/sys/netinet/ipfw/dn_heap.h
new file mode 100644
index 0000000..c95473a
--- /dev/null
+++ b/sys/netinet/ipfw/dn_heap.h
@@ -0,0 +1,191 @@
+/*-
+ * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Binary heap and hash tables, header file
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _IP_DN_HEAP_H
+#define _IP_DN_HEAP_H
+
+#define DN_KEY_LT(a,b) ((int64_t)((a)-(b)) < 0)
+#define DN_KEY_LEQ(a,b) ((int64_t)((a)-(b)) <= 0)
+
+/*
+ * This module implements a binary heap supporting random extraction.
+ *
+ * A heap entry contains an uint64_t key and a pointer to object.
+ * DN_KEY_LT(a,b) returns true if key 'a' is smaller than 'b'
+ *
+ * The heap is a struct dn_heap plus a dynamically allocated
+ * array of dn_heap_entry entries. 'size' represents the size of
+ * the array, 'elements' count entries in use. The topmost
+ * element has the smallest key.
+ * The heap supports ordered insert, and extract from the top.
+ * To extract an object from the middle of the heap, we the object
+ * must reserve an 'int32_t' to store the position of the object
+ * in the heap itself, and the location of this field must be
+ * passed as an argument to heap_init() -- use -1 if the feature
+ * is not used.
+ */
+struct dn_heap_entry {
+ uint64_t key; /* sorting key, smallest comes first */
+ void *object; /* object pointer */
+};
+
+struct dn_heap {
+ int size; /* the size of the array */
+ int elements; /* elements in use */
+ int ofs; /* offset in the object of heap index */
+ struct dn_heap_entry *p; /* array of "size" entries */
+};
+
+enum {
+ HEAP_SCAN_DEL = 1,
+ HEAP_SCAN_END = 2,
+};
+
+/*
+ * heap_init() reinitializes the heap setting the size and the offset
+ * of the index for random extraction (use -1 if not used).
+ * The 'elements' counter is set to 0.
+ *
+ * SET_HEAP_OFS() indicates where, in the object, is stored the index
+ * for random extractions from the heap.
+ *
+ * heap_free() frees the memory associated to a heap.
+ *
+ * heap_insert() adds a key-pointer pair to the heap
+ *
+ * HEAP_TOP() returns a pointer to the top element of the heap,
+ * but makes no checks on its existance (XXX should we change ?)
+ *
+ * heap_extract() removes the entry at the top, returing the pointer.
+ * (the key should have been read before).
+ *
+ * heap_scan() invokes a callback on each entry of the heap.
+ * The callback can return a combination of HEAP_SCAN_DEL and
+ * HEAP_SCAN_END. HEAP_SCAN_DEL means the current element must
+ * be removed, and HEAP_SCAN_END means to terminate the scan.
+ * heap_scan() returns the number of elements removed.
+ * Because the order is not guaranteed, we should use heap_scan()
+ * only as a last resort mechanism.
+ */
+#define HEAP_TOP(h) ((h)->p)
+#define SET_HEAP_OFS(h, n) do { (h)->ofs = n; } while (0)
+int heap_init(struct dn_heap *h, int size, int ofs);
+int heap_insert(struct dn_heap *h, uint64_t key1, void *p);
+void heap_extract(struct dn_heap *h, void *obj);
+void heap_free(struct dn_heap *h);
+int heap_scan(struct dn_heap *, int (*)(void *, uintptr_t), uintptr_t);
+
+/*------------------------------------------------------
+ * This module implements a generic hash table with support for
+ * running callbacks on the entire table. To avoid allocating
+ * memory during hash table operations, objects must reserve
+ * space for a link field. XXX if the heap is moderately full,
+ * an SLIST suffices, and we can tolerate the cost of a hash
+ * computation on each removal.
+ *
+ * dn_ht_init() initializes the table, setting the number of
+ * buckets, the offset of the link field, the main callbacks.
+ * Callbacks are:
+ *
+ * hash(key, flags, arg) called to return a bucket index.
+ * match(obj, key, flags, arg) called to determine if key
+ * matches the current 'obj' in the heap
+ * newh(key, flags, arg) optional, used to allocate a new
+ * object during insertions.
+ *
+ * dn_ht_free() frees the heap or unlink elements.
+ * DNHT_REMOVE unlink elements, 0 frees the heap.
+ * You need two calls to do both.
+ *
+ * dn_ht_find() is the main lookup function, which can also be
+ * used to insert or delete elements in the hash table.
+ * The final 'arg' is passed to all callbacks.
+ *
+ * dn_ht_scan() is used to invoke a callback on all entries of
+ * the heap, or possibly on just one bucket. The callback
+ * is invoked with a pointer to the object, and must return
+ * one of DNHT_SCAN_DEL or DNHT_SCAN_END to request the
+ * removal of the object from the heap and the end of the
+ * scan, respectively.
+ *
+ * dn_ht_scan_bucket() is similar to dn_ht_scan(), except that it scans
+ * only the specific bucket of the table. The bucket is a in-out
+ * parameter and return a valid bucket number if the original
+ * is invalid.
+ *
+ * A combination of flags can be used to modify the operation
+ * of the dn_ht_find(), and of the callbacks:
+ *
+ * DNHT_KEY_IS_OBJ means the key is the object pointer.
+ * It is usally of interest for the hash and match functions.
+ *
+ * DNHT_MATCH_PTR during a lookup, match pointers instead
+ * of calling match(). Normally used when removing specific
+ * entries. Does not imply KEY_IS_OBJ as the latter _is_ used
+ * by the match function.
+ *
+ * DNHT_INSERT insert the element if not found.
+ * Calls new() to allocates a new object unless
+ * DNHT_KEY_IS_OBJ is set.
+ *
+ * DNHT_UNIQUE only insert if object not found.
+ * XXX should it imply DNHT_INSERT ?
+ *
+ * DNHT_REMOVE remove objects if we find them.
+ */
+struct dn_ht; /* should be opaque */
+
+struct dn_ht *dn_ht_init(struct dn_ht *, int buckets, int ofs,
+ uint32_t (*hash)(uintptr_t, int, void *),
+ int (*match)(void *, uintptr_t, int, void *),
+ void *(*newh)(uintptr_t, int, void *));
+void dn_ht_free(struct dn_ht *, int flags);
+
+void *dn_ht_find(struct dn_ht *, uintptr_t, int, void *);
+int dn_ht_scan(struct dn_ht *, int (*)(void *, void *), void *);
+int dn_ht_scan_bucket(struct dn_ht *, int * , int (*)(void *, void *), void *);
+int dn_ht_entries(struct dn_ht *);
+
+enum { /* flags values.
+ * first two are returned by the scan callback to indicate
+ * to delete the matching element or to end the scan
+ */
+ DNHT_SCAN_DEL = 0x0001,
+ DNHT_SCAN_END = 0x0002,
+ DNHT_KEY_IS_OBJ = 0x0004, /* key is the obj pointer */
+ DNHT_MATCH_PTR = 0x0008, /* match by pointer, not match() */
+ DNHT_INSERT = 0x0010, /* insert if not found */
+ DNHT_UNIQUE = 0x0020, /* report error if already there */
+ DNHT_REMOVE = 0x0040, /* remove on find or dn_ht_free */
+};
+
+#endif /* _IP_DN_HEAP_H */
diff --git a/sys/netinet/ipfw/dn_sched.h b/sys/netinet/ipfw/dn_sched.h
new file mode 100644
index 0000000..ab823fe
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2010 Riccardo Panicucci, Luigi Rizzo, Universita` di Pisa
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * The API to write a packet scheduling algorithm for dummynet.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _DN_SCHED_H
+#define _DN_SCHED_H
+
+#define DN_MULTIQUEUE 0x01
+/*
+ * Descriptor for a scheduling algorithm.
+ * Contains all function pointers for a given scheduler
+ * This is typically created when a module is loaded, and stored
+ * in a global list of schedulers.
+ */
+struct dn_alg {
+ uint32_t type; /* the scheduler type */
+ const char *name; /* scheduler name */
+ uint32_t flags; /* DN_MULTIQUEUE if supports multiple queues */
+
+ /*
+ * The following define the size of 3 optional data structures
+ * that may need to be allocated at runtime, and are appended
+ * to each of the base data structures: scheduler, sched.inst,
+ * and queue. We don't have a per-flowset structure.
+ */
+ /* + parameters attached to the template, e.g.
+ * default queue sizes, weights, quantum size, and so on;
+ */
+ size_t schk_datalen;
+
+ /* + per-instance parameters, such as timestamps,
+ * containers for queues, etc;
+ */
+ size_t si_datalen;
+
+ size_t q_datalen; /* per-queue parameters (e.g. S,F) */
+
+ /*
+ * Methods implemented by the scheduler:
+ * enqueue enqueue packet 'm' on scheduler 's', queue 'q'.
+ * q is NULL for !MULTIQUEUE.
+ * Return 0 on success, 1 on drop (packet consumed anyways).
+ * Note that q should be interpreted only as a hint
+ * on the flow that the mbuf belongs to: while a
+ * scheduler will normally enqueue m into q, it is ok
+ * to leave q alone and put the mbuf elsewhere.
+ * This function is called in two cases:
+ * - when a new packet arrives to the scheduler;
+ * - when a scheduler is reconfigured. In this case the
+ * call is issued by the new_queue callback, with a
+ * non empty queue (q) and m pointing to the first
+ * mbuf in the queue. For this reason, the function
+ * should internally check for (m != q->mq.head)
+ * before calling dn_enqueue().
+ *
+ * dequeue Called when scheduler instance 's' can
+ * dequeue a packet. Return NULL if none are available.
+ * XXX what about non work-conserving ?
+ *
+ * config called on 'sched X config ...', normally writes
+ * in the area of size sch_arg
+ *
+ * destroy called on 'sched delete', frees everything
+ * in sch_arg (other parts are handled by more specific
+ * functions)
+ *
+ * new_sched called when a new instance is created, e.g.
+ * to create the local queue for !MULTIQUEUE, set V or
+ * copy parameters for WFQ, and so on.
+ *
+ * free_sched called when deleting an instance, cleans
+ * extra data in the per-instance area.
+ *
+ * new_fsk called when a flowset is linked to a scheduler,
+ * e.g. to validate parameters such as weights etc.
+ * free_fsk when a flowset is unlinked from a scheduler.
+ * (probably unnecessary)
+ *
+ * new_queue called to set the per-queue parameters,
+ * e.g. S and F, adjust sum of weights in the parent, etc.
+ *
+ * The new_queue callback is normally called from when
+ * creating a new queue. In some cases (such as a
+ * scheduler change or reconfiguration) it can be called
+ * with a non empty queue. In this case, the queue
+ * In case of non empty queue, the new_queue callback could
+ * need to call the enqueue function. In this case,
+ * the callback should eventually call enqueue() passing
+ * as m the first element in the queue.
+ *
+ * free_queue actions related to a queue removal, e.g. undo
+ * all the above. If the queue has data in it, also remove
+ * from the scheduler. This can e.g. happen during a reconfigure.
+ */
+ int (*enqueue)(struct dn_sch_inst *, struct dn_queue *,
+ struct mbuf *);
+ struct mbuf * (*dequeue)(struct dn_sch_inst *);
+
+ int (*config)(struct dn_schk *);
+ int (*destroy)(struct dn_schk*);
+ int (*new_sched)(struct dn_sch_inst *);
+ int (*free_sched)(struct dn_sch_inst *);
+ int (*new_fsk)(struct dn_fsk *f);
+ int (*free_fsk)(struct dn_fsk *f);
+ int (*new_queue)(struct dn_queue *q);
+ int (*free_queue)(struct dn_queue *q);
+
+ /* run-time fields */
+ int ref_count; /* XXX number of instances in the system */
+ SLIST_ENTRY(dn_alg) next; /* Next scheduler in the list */
+};
+
+/* MSVC does not support initializers so we need this ugly macro */
+#ifdef _WIN32
+#define _SI(fld)
+#else
+#define _SI(fld) fld
+#endif
+
+/*
+ * Additionally, dummynet exports some functions and macros
+ * to be used by schedulers:
+ */
+
+void dn_free_pkts(struct mbuf *mnext);
+int dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop);
+/* bound a variable between min and max */
+int ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg);
+
+/*
+ * Extract the head of a queue, update stats. Must be the very last
+ * thing done on a dequeue as the queue itself may go away.
+ */
+static __inline struct mbuf*
+dn_dequeue(struct dn_queue *q)
+{
+ struct mbuf *m = q->mq.head;
+ if (m == NULL)
+ return NULL;
+ q->mq.head = m->m_nextpkt;
+
+ /* Update stats for the queue */
+ q->ni.length--;
+ q->ni.len_bytes -= m->m_pkthdr.len;
+ if (q->_si) {
+ q->_si->ni.length--;
+ q->_si->ni.len_bytes -= m->m_pkthdr.len;
+ }
+ if (q->ni.length == 0) /* queue is now idle */
+ q->q_time = dn_cfg.curr_time;
+ return m;
+}
+
+int dn_sched_modevent(module_t mod, int cmd, void *arg);
+
+#define DECLARE_DNSCHED_MODULE(name, dnsched) \
+ static moduledata_t name##_mod = { \
+ #name, dn_sched_modevent, dnsched \
+ }; \
+ DECLARE_MODULE(name, name##_mod, \
+ SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); \
+ MODULE_DEPEND(name, dummynet, 3, 3, 3);
+#endif /* _DN_SCHED_H */
diff --git a/sys/netinet/ipfw/dn_sched_fifo.c b/sys/netinet/ipfw/dn_sched_fifo.c
new file mode 100644
index 0000000..0bb3800
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched_fifo.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $FreeBSD$
+ */
+
+#ifdef _KERNEL
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <net/if.h> /* IFNAMSIZ */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ipfw_rule_ref */
+#include <netinet/ip_fw.h> /* flow_id */
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+#else
+#include <dn_test.h>
+#endif
+
+/*
+ * This file implements a FIFO scheduler for a single queue.
+ * The queue is allocated as part of the scheduler instance,
+ * and there is a single flowset is in the template which stores
+ * queue size and policy.
+ * Enqueue and dequeue use the default library functions.
+ */
+static int
+fifo_enqueue(struct dn_sch_inst *si, struct dn_queue *q, struct mbuf *m)
+{
+ /* XXX if called with q != NULL and m=NULL, this is a
+ * re-enqueue from an existing scheduler, which we should
+ * handle.
+ */
+ return dn_enqueue((struct dn_queue *)(si+1), m, 0);
+}
+
+static struct mbuf *
+fifo_dequeue(struct dn_sch_inst *si)
+{
+ return dn_dequeue((struct dn_queue *)(si + 1));
+}
+
+static int
+fifo_new_sched(struct dn_sch_inst *si)
+{
+ /* This scheduler instance contains the queue */
+ struct dn_queue *q = (struct dn_queue *)(si + 1);
+
+ set_oid(&q->ni.oid, DN_QUEUE, sizeof(*q));
+ q->_si = si;
+ q->fs = si->sched->fs;
+ return 0;
+}
+
+static int
+fifo_free_sched(struct dn_sch_inst *si)
+{
+ struct dn_queue *q = (struct dn_queue *)(si + 1);
+ dn_free_pkts(q->mq.head);
+ bzero(q, sizeof(*q));
+ return 0;
+}
+
+/*
+ * FIFO scheduler descriptor
+ * contains the type of the scheduler, the name, the size of extra
+ * data structures, and function pointers.
+ */
+static struct dn_alg fifo_desc = {
+ _SI( .type = ) DN_SCHED_FIFO,
+ _SI( .name = ) "FIFO",
+ _SI( .flags = ) 0,
+
+ _SI( .schk_datalen = ) 0,
+ _SI( .si_datalen = ) sizeof(struct dn_queue),
+ _SI( .q_datalen = ) 0,
+
+ _SI( .enqueue = ) fifo_enqueue,
+ _SI( .dequeue = ) fifo_dequeue,
+ _SI( .config = ) NULL,
+ _SI( .destroy = ) NULL,
+ _SI( .new_sched = ) fifo_new_sched,
+ _SI( .free_sched = ) fifo_free_sched,
+ _SI( .new_fsk = ) NULL,
+ _SI( .free_fsk = ) NULL,
+ _SI( .new_queue = ) NULL,
+ _SI( .free_queue = ) NULL,
+};
+
+DECLARE_DNSCHED_MODULE(dn_fifo, &fifo_desc);
diff --git a/sys/netinet/ipfw/dn_sched_prio.c b/sys/netinet/ipfw/dn_sched_prio.c
new file mode 100644
index 0000000..28f6006
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched_prio.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $FreeBSD$
+ */
+#ifdef _KERNEL
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <net/if.h> /* IFNAMSIZ */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ipfw_rule_ref */
+#include <netinet/ip_fw.h> /* flow_id */
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+#else
+#include <dn_test.h>
+#endif
+
+#define DN_SCHED_PRIO 5 //XXX
+
+#if !defined(_KERNEL) || !defined(__linux__)
+#define test_bit(ix, pData) ((*pData) & (1<<(ix)))
+#define __set_bit(ix, pData) (*pData) |= (1<<(ix))
+#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
+#endif
+
+#ifdef __MIPSEL__
+#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
+#endif
+
+/* Size of the array of queues pointers. */
+#define BITMAP_T unsigned long
+#define MAXPRIO (sizeof(BITMAP_T) * 8)
+
+/*
+ * The scheduler instance contains an array of pointers to queues,
+ * one for each priority, and a bitmap listing backlogged queues.
+ */
+struct prio_si {
+ BITMAP_T bitmap; /* array bitmap */
+ struct dn_queue *q_array[MAXPRIO]; /* Array of queues pointers */
+};
+
+/*
+ * If a queue with the same priority is already backlogged, use
+ * that one instead of the queue passed as argument.
+ */
+static int
+prio_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
+{
+ struct prio_si *si = (struct prio_si *)(_si + 1);
+ int prio = q->fs->fs.par[0];
+
+ if (test_bit(prio, &si->bitmap) == 0) {
+ /* No queue with this priority, insert */
+ __set_bit(prio, &si->bitmap);
+ si->q_array[prio] = q;
+ } else { /* use the existing queue */
+ q = si->q_array[prio];
+ }
+ if (dn_enqueue(q, m, 0))
+ return 1;
+ return 0;
+}
+
+/*
+ * Packets are dequeued only from the highest priority queue.
+ * The function ffs() return the lowest bit in the bitmap that rapresent
+ * the array index (-1) which contains the pointer to the highest priority
+ * queue.
+ * After the dequeue, if this queue become empty, it is index is removed
+ * from the bitmap.
+ * Scheduler is idle if the bitmap is empty
+ *
+ * NOTE: highest priority is 0, lowest is sched->max_prio_q
+ */
+static struct mbuf *
+prio_dequeue(struct dn_sch_inst *_si)
+{
+ struct prio_si *si = (struct prio_si *)(_si + 1);
+ struct mbuf *m;
+ struct dn_queue *q;
+ int prio;
+
+ if (si->bitmap == 0) /* scheduler idle */
+ return NULL;
+
+ prio = ffs(si->bitmap) - 1;
+
+ /* Take the highest priority queue in the scheduler */
+ q = si->q_array[prio];
+ // assert(q)
+
+ m = dn_dequeue(q);
+ if (q->mq.head == NULL) {
+ /* Queue is now empty, remove from scheduler
+ * and mark it
+ */
+ si->q_array[prio] = NULL;
+ __clear_bit(prio, &si->bitmap);
+ }
+ return m;
+}
+
+static int
+prio_new_sched(struct dn_sch_inst *_si)
+{
+ struct prio_si *si = (struct prio_si *)(_si + 1);
+
+ bzero(si->q_array, sizeof(si->q_array));
+ si->bitmap = 0;
+
+ return 0;
+}
+
+static int
+prio_new_fsk(struct dn_fsk *fs)
+{
+ /* Check if the prioritiy is between 0 and MAXPRIO-1 */
+ ipdn_bound_var(&fs->fs.par[0], 0, 0, MAXPRIO - 1, "PRIO priority");
+ return 0;
+}
+
+static int
+prio_new_queue(struct dn_queue *q)
+{
+ struct prio_si *si = (struct prio_si *)(q->_si + 1);
+ int prio = q->fs->fs.par[0];
+ struct dn_queue *oldq;
+
+ q->ni.oid.subtype = DN_SCHED_PRIO;
+
+ if (q->mq.head == NULL)
+ return 0;
+
+ /* Queue already full, must insert in the scheduler or append
+ * mbufs to existing queue. This partly duplicates prio_enqueue
+ */
+ if (test_bit(prio, &si->bitmap) == 0) {
+ /* No queue with this priority, insert */
+ __set_bit(prio, &si->bitmap);
+ si->q_array[prio] = q;
+ } else if ( (oldq = si->q_array[prio]) != q) {
+ /* must append to the existing queue.
+ * can simply append q->mq.head to q2->...
+ * and add the counters to those of q2
+ */
+ oldq->mq.tail->m_nextpkt = q->mq.head;
+ oldq->mq.tail = q->mq.tail;
+ oldq->ni.length += q->ni.length;
+ q->ni.length = 0;
+ oldq->ni.len_bytes += q->ni.len_bytes;
+ q->ni.len_bytes = 0;
+ q->mq.tail = q->mq.head = NULL;
+ }
+ return 0;
+}
+
+static int
+prio_free_queue(struct dn_queue *q)
+{
+ int prio = q->fs->fs.par[0];
+ struct prio_si *si = (struct prio_si *)(q->_si + 1);
+
+ if (si->q_array[prio] == q) {
+ si->q_array[prio] = NULL;
+ __clear_bit(prio, &si->bitmap);
+ }
+ return 0;
+}
+
+
+static struct dn_alg prio_desc = {
+ _SI( .type = ) DN_SCHED_PRIO,
+ _SI( .name = ) "PRIO",
+ _SI( .flags = ) DN_MULTIQUEUE,
+
+ /* we need extra space in the si and the queue */
+ _SI( .schk_datalen = ) 0,
+ _SI( .si_datalen = ) sizeof(struct prio_si),
+ _SI( .q_datalen = ) 0,
+
+ _SI( .enqueue = ) prio_enqueue,
+ _SI( .dequeue = ) prio_dequeue,
+
+ _SI( .config = ) NULL,
+ _SI( .destroy = ) NULL,
+ _SI( .new_sched = ) prio_new_sched,
+ _SI( .free_sched = ) NULL,
+
+ _SI( .new_fsk = ) prio_new_fsk,
+ _SI( .free_fsk = ) NULL,
+
+ _SI( .new_queue = ) prio_new_queue,
+ _SI( .free_queue = ) prio_free_queue,
+};
+
+
+DECLARE_DNSCHED_MODULE(dn_prio, &prio_desc);
diff --git a/sys/netinet/ipfw/dn_sched_qfq.c b/sys/netinet/ipfw/dn_sched_qfq.c
new file mode 100644
index 0000000..be7fba3
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched_qfq.c
@@ -0,0 +1,864 @@
+/*
+ * Copyright (c) 2010 Fabio Checconi, Luigi Rizzo, Paolo Valente
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $FreeBSD$
+ */
+
+#ifdef _KERNEL
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <net/if.h> /* IFNAMSIZ */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ipfw_rule_ref */
+#include <netinet/ip_fw.h> /* flow_id */
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+#else
+#include <dn_test.h>
+#endif
+
+#ifdef QFQ_DEBUG
+struct qfq_sched;
+static void dump_sched(struct qfq_sched *q, const char *msg);
+#define NO(x) x
+#else
+#define NO(x)
+#endif
+#define DN_SCHED_QFQ 4 // XXX Where?
+typedef unsigned long bitmap;
+
+/*
+ * bitmaps ops are critical. Some linux versions have __fls
+ * and the bitmap ops. Some machines have ffs
+ */
+#if defined(_WIN32) || (defined(__MIPSEL__) && defined(LINUX_24))
+int fls(unsigned int n)
+{
+ int i = 0;
+ for (i = 0; n > 0; n >>= 1, i++)
+ ;
+ return i;
+}
+#endif
+
+#if !defined(_KERNEL) || defined( __FreeBSD__ ) || defined(_WIN32) || (defined(__MIPSEL__) && defined(LINUX_24))
+static inline unsigned long __fls(unsigned long word)
+{
+ return fls(word) - 1;
+}
+#endif
+
+#if !defined(_KERNEL) || !defined(__linux__)
+#ifdef QFQ_DEBUG
+int test_bit(int ix, bitmap *p)
+{
+ if (ix < 0 || ix > 31)
+ D("bad index %d", ix);
+ return *p & (1<<ix);
+}
+void __set_bit(int ix, bitmap *p)
+{
+ if (ix < 0 || ix > 31)
+ D("bad index %d", ix);
+ *p |= (1<<ix);
+}
+void __clear_bit(int ix, bitmap *p)
+{
+ if (ix < 0 || ix > 31)
+ D("bad index %d", ix);
+ *p &= ~(1<<ix);
+}
+#else /* !QFQ_DEBUG */
+/* XXX do we have fast version, or leave it to the compiler ? */
+#define test_bit(ix, pData) ((*pData) & (1<<(ix)))
+#define __set_bit(ix, pData) (*pData) |= (1<<(ix))
+#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
+#endif /* !QFQ_DEBUG */
+#endif /* !__linux__ */
+
+#ifdef __MIPSEL__
+#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
+#endif
+
+/*-------------------------------------------*/
+/*
+
+Virtual time computations.
+
+S, F and V are all computed in fixed point arithmetic with
+FRAC_BITS decimal bits.
+
+ QFQ_MAX_INDEX is the maximum index allowed for a group. We need
+ one bit per index.
+ QFQ_MAX_WSHIFT is the maximum power of two supported as a weight.
+ The layout of the bits is as below:
+
+ [ MTU_SHIFT ][ FRAC_BITS ]
+ [ MAX_INDEX ][ MIN_SLOT_SHIFT ]
+ ^.__grp->index = 0
+ *.__grp->slot_shift
+
+ where MIN_SLOT_SHIFT is derived by difference from the others.
+
+The max group index corresponds to Lmax/w_min, where
+Lmax=1<<MTU_SHIFT, w_min = 1 .
+From this, and knowing how many groups (MAX_INDEX) we want,
+we can derive the shift corresponding to each group.
+
+Because we often need to compute
+ F = S + len/w_i and V = V + len/wsum
+instead of storing w_i store the value
+ inv_w = (1<<FRAC_BITS)/w_i
+so we can do F = S + len * inv_w * wsum.
+We use W_TOT in the formulas so we can easily move between
+static and adaptive weight sum.
+
+The per-scheduler-instance data contain all the data structures
+for the scheduler: bitmaps and bucket lists.
+
+ */
+/*
+ * Maximum number of consecutive slots occupied by backlogged classes
+ * inside a group. This is approx lmax/lmin + 5.
+ * XXX check because it poses constraints on MAX_INDEX
+ */
+#define QFQ_MAX_SLOTS 32
+/*
+ * Shifts used for class<->group mapping. Class weights are
+ * in the range [1, QFQ_MAX_WEIGHT], we to map each class i to the
+ * group with the smallest index that can support the L_i / r_i
+ * configured for the class.
+ *
+ * grp->index is the index of the group; and grp->slot_shift
+ * is the shift for the corresponding (scaled) sigma_i.
+ *
+ * When computing the group index, we do (len<<FP_SHIFT)/weight,
+ * then compute an FLS (which is like a log2()), and if the result
+ * is below the MAX_INDEX region we use 0 (which is the same as
+ * using a larger len).
+ */
+#define QFQ_MAX_INDEX 19
+#define QFQ_MAX_WSHIFT 16 /* log2(max_weight) */
+
+#define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT)
+#define QFQ_MAX_WSUM (2*QFQ_MAX_WEIGHT)
+//#define IWSUM (q->i_wsum)
+#define IWSUM ((1<<FRAC_BITS)/QFQ_MAX_WSUM)
+
+#define FRAC_BITS 30 /* fixed point arithmetic */
+#define ONE_FP (1UL << FRAC_BITS)
+
+#define QFQ_MTU_SHIFT 11 /* log2(max_len) */
+#define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX)
+
+/*
+ * Possible group states, also indexes for the bitmaps array in
+ * struct qfq_queue. We rely on ER, IR, EB, IB being numbered 0..3
+ */
+enum qfq_state { ER, IR, EB, IB, QFQ_MAX_STATE };
+
+struct qfq_group;
+/*
+ * additional queue info. Some of this info should come from
+ * the flowset, we copy them here for faster processing.
+ * This is an overlay of the struct dn_queue
+ */
+struct qfq_class {
+ struct dn_queue _q;
+ uint64_t S, F; /* flow timestamps (exact) */
+ struct qfq_class *next; /* Link for the slot list. */
+
+ /* group we belong to. In principle we would need the index,
+ * which is log_2(lmax/weight), but we never reference it
+ * directly, only the group.
+ */
+ struct qfq_group *grp;
+
+ /* these are copied from the flowset. */
+ uint32_t inv_w; /* ONE_FP/weight */
+ uint32_t lmax; /* Max packet size for this flow. */
+};
+
+/* Group descriptor, see the paper for details.
+ * Basically this contains the bucket lists
+ */
+struct qfq_group {
+ uint64_t S, F; /* group timestamps (approx). */
+ unsigned int slot_shift; /* Slot shift. */
+ unsigned int index; /* Group index. */
+ unsigned int front; /* Index of the front slot. */
+ bitmap full_slots; /* non-empty slots */
+
+ /* Array of lists of active classes. */
+ struct qfq_class *slots[QFQ_MAX_SLOTS];
+};
+
+/* scheduler instance descriptor. */
+struct qfq_sched {
+ uint64_t V; /* Precise virtual time. */
+ uint32_t wsum; /* weight sum */
+ NO(uint32_t i_wsum; /* ONE_FP/w_sum */
+ uint32_t _queued; /* debugging */
+ uint32_t loops; /* debugging */)
+ bitmap bitmaps[QFQ_MAX_STATE]; /* Group bitmaps. */
+ struct qfq_group groups[QFQ_MAX_INDEX + 1]; /* The groups. */
+};
+
+/*---- support functions ----------------------------*/
+
+/* Generic comparison function, handling wraparound. */
+static inline int qfq_gt(uint64_t a, uint64_t b)
+{
+ return (int64_t)(a - b) > 0;
+}
+
+/* Round a precise timestamp to its slotted value. */
+static inline uint64_t qfq_round_down(uint64_t ts, unsigned int shift)
+{
+ return ts & ~((1ULL << shift) - 1);
+}
+
+/* return the pointer to the group with lowest index in the bitmap */
+static inline struct qfq_group *qfq_ffs(struct qfq_sched *q,
+ unsigned long bitmap)
+{
+ int index = ffs(bitmap) - 1; // zero-based
+ return &q->groups[index];
+}
+
+/*
+ * Calculate a flow index, given its weight and maximum packet length.
+ * index = log_2(maxlen/weight) but we need to apply the scaling.
+ * This is used only once at flow creation.
+ */
+static int qfq_calc_index(uint32_t inv_w, unsigned int maxlen)
+{
+ uint64_t slot_size = (uint64_t)maxlen *inv_w;
+ unsigned long size_map;
+ int index = 0;
+
+ size_map = (unsigned long)(slot_size >> QFQ_MIN_SLOT_SHIFT);
+ if (!size_map)
+ goto out;
+
+ index = __fls(size_map) + 1; // basically a log_2()
+ index -= !(slot_size - (1ULL << (index + QFQ_MIN_SLOT_SHIFT - 1)));
+
+ if (index < 0)
+ index = 0;
+
+out:
+ ND("W = %d, L = %d, I = %d\n", ONE_FP/inv_w, maxlen, index);
+ return index;
+}
+/*---- end support functions ----*/
+
+/*-------- API calls --------------------------------*/
+/*
+ * Validate and copy parameters from flowset.
+ */
+static int
+qfq_new_queue(struct dn_queue *_q)
+{
+ struct qfq_sched *q = (struct qfq_sched *)(_q->_si + 1);
+ struct qfq_class *cl = (struct qfq_class *)_q;
+ int i;
+ uint32_t w; /* approximated weight */
+
+ /* import parameters from the flowset. They should be correct
+ * already.
+ */
+ w = _q->fs->fs.par[0];
+ cl->lmax = _q->fs->fs.par[1];
+ if (!w || w > QFQ_MAX_WEIGHT) {
+ w = 1;
+ D("rounding weight to 1");
+ }
+ cl->inv_w = ONE_FP/w;
+ w = ONE_FP/cl->inv_w;
+ if (q->wsum + w > QFQ_MAX_WSUM)
+ return EINVAL;
+
+ i = qfq_calc_index(cl->inv_w, cl->lmax);
+ cl->grp = &q->groups[i];
+ q->wsum += w;
+ // XXX cl->S = q->V; ?
+ // XXX compute q->i_wsum
+ return 0;
+}
+
+/* remove an empty queue */
+static int
+qfq_free_queue(struct dn_queue *_q)
+{
+ struct qfq_sched *q = (struct qfq_sched *)(_q->_si + 1);
+ struct qfq_class *cl = (struct qfq_class *)_q;
+ if (cl->inv_w) {
+ q->wsum -= ONE_FP/cl->inv_w;
+ cl->inv_w = 0; /* reset weight to avoid run twice */
+ }
+ return 0;
+}
+
+/* Calculate a mask to mimic what would be ffs_from(). */
+static inline unsigned long
+mask_from(unsigned long bitmap, int from)
+{
+ return bitmap & ~((1UL << from) - 1);
+}
+
+/*
+ * The state computation relies on ER=0, IR=1, EB=2, IB=3
+ * First compute eligibility comparing grp->S, q->V,
+ * then check if someone is blocking us and possibly add EB
+ */
+static inline unsigned int
+qfq_calc_state(struct qfq_sched *q, struct qfq_group *grp)
+{
+ /* if S > V we are not eligible */
+ unsigned int state = qfq_gt(grp->S, q->V);
+ unsigned long mask = mask_from(q->bitmaps[ER], grp->index);
+ struct qfq_group *next;
+
+ if (mask) {
+ next = qfq_ffs(q, mask);
+ if (qfq_gt(grp->F, next->F))
+ state |= EB;
+ }
+
+ return state;
+}
+
+/*
+ * In principle
+ * q->bitmaps[dst] |= q->bitmaps[src] & mask;
+ * q->bitmaps[src] &= ~mask;
+ * but we should make sure that src != dst
+ */
+static inline void
+qfq_move_groups(struct qfq_sched *q, unsigned long mask, int src, int dst)
+{
+ q->bitmaps[dst] |= q->bitmaps[src] & mask;
+ q->bitmaps[src] &= ~mask;
+}
+
+static inline void
+qfq_unblock_groups(struct qfq_sched *q, int index, uint64_t old_finish)
+{
+ unsigned long mask = mask_from(q->bitmaps[ER], index + 1);
+ struct qfq_group *next;
+
+ if (mask) {
+ next = qfq_ffs(q, mask);
+ if (!qfq_gt(next->F, old_finish))
+ return;
+ }
+
+ mask = (1UL << index) - 1;
+ qfq_move_groups(q, mask, EB, ER);
+ qfq_move_groups(q, mask, IB, IR);
+}
+
+/*
+ * perhaps
+ *
+ old_V ^= q->V;
+ old_V >>= QFQ_MIN_SLOT_SHIFT;
+ if (old_V) {
+ ...
+ }
+ *
+ */
+static inline void
+qfq_make_eligible(struct qfq_sched *q, uint64_t old_V)
+{
+ unsigned long mask, vslot, old_vslot;
+
+ vslot = q->V >> QFQ_MIN_SLOT_SHIFT;
+ old_vslot = old_V >> QFQ_MIN_SLOT_SHIFT;
+
+ if (vslot != old_vslot) {
+ mask = (2UL << (__fls(vslot ^ old_vslot))) - 1;
+ qfq_move_groups(q, mask, IR, ER);
+ qfq_move_groups(q, mask, IB, EB);
+ }
+}
+
+/*
+ * XXX we should make sure that slot becomes less than 32.
+ * This is guaranteed by the input values.
+ * roundedS is always cl->S rounded on grp->slot_shift bits.
+ */
+static inline void
+qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, uint64_t roundedS)
+{
+ uint64_t slot = (roundedS - grp->S) >> grp->slot_shift;
+ unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS;
+
+ cl->next = grp->slots[i];
+ grp->slots[i] = cl;
+ __set_bit(slot, &grp->full_slots);
+}
+
+/*
+ * remove the entry from the slot
+ */
+static inline void
+qfq_front_slot_remove(struct qfq_group *grp)
+{
+ struct qfq_class **h = &grp->slots[grp->front];
+
+ *h = (*h)->next;
+ if (!*h)
+ __clear_bit(0, &grp->full_slots);
+}
+
+/*
+ * Returns the first full queue in a group. As a side effect,
+ * adjust the bucket list so the first non-empty bucket is at
+ * position 0 in full_slots.
+ */
+static inline struct qfq_class *
+qfq_slot_scan(struct qfq_group *grp)
+{
+ int i;
+
+ ND("grp %d full %x", grp->index, grp->full_slots);
+ if (!grp->full_slots)
+ return NULL;
+
+ i = ffs(grp->full_slots) - 1; // zero-based
+ if (i > 0) {
+ grp->front = (grp->front + i) % QFQ_MAX_SLOTS;
+ grp->full_slots >>= i;
+ }
+
+ return grp->slots[grp->front];
+}
+
+/*
+ * adjust the bucket list. When the start time of a group decreases,
+ * we move the index down (modulo QFQ_MAX_SLOTS) so we don't need to
+ * move the objects. The mask of occupied slots must be shifted
+ * because we use ffs() to find the first non-empty slot.
+ * This covers decreases in the group's start time, but what about
+ * increases of the start time ?
+ * Here too we should make sure that i is less than 32
+ */
+static inline void
+qfq_slot_rotate(struct qfq_sched *q, struct qfq_group *grp, uint64_t roundedS)
+{
+ unsigned int i = (grp->S - roundedS) >> grp->slot_shift;
+
+ grp->full_slots <<= i;
+ grp->front = (grp->front - i) % QFQ_MAX_SLOTS;
+}
+
+
+static inline void
+qfq_update_eligible(struct qfq_sched *q, uint64_t old_V)
+{
+ bitmap ineligible;
+
+ ineligible = q->bitmaps[IR] | q->bitmaps[IB];
+ if (ineligible) {
+ if (!q->bitmaps[ER]) {
+ struct qfq_group *grp;
+ grp = qfq_ffs(q, ineligible);
+ if (qfq_gt(grp->S, q->V))
+ q->V = grp->S;
+ }
+ qfq_make_eligible(q, old_V);
+ }
+}
+
+/*
+ * Updates the class, returns true if also the group needs to be updated.
+ */
+static inline int
+qfq_update_class(struct qfq_sched *q, struct qfq_group *grp,
+ struct qfq_class *cl)
+{
+
+ cl->S = cl->F;
+ if (cl->_q.mq.head == NULL) {
+ qfq_front_slot_remove(grp);
+ } else {
+ unsigned int len;
+ uint64_t roundedS;
+
+ len = cl->_q.mq.head->m_pkthdr.len;
+ cl->F = cl->S + (uint64_t)len * cl->inv_w;
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ if (roundedS == grp->S)
+ return 0;
+
+ qfq_front_slot_remove(grp);
+ qfq_slot_insert(grp, cl, roundedS);
+ }
+ return 1;
+}
+
+static struct mbuf *
+qfq_dequeue(struct dn_sch_inst *si)
+{
+ struct qfq_sched *q = (struct qfq_sched *)(si + 1);
+ struct qfq_group *grp;
+ struct qfq_class *cl;
+ struct mbuf *m;
+ uint64_t old_V;
+
+ NO(q->loops++;)
+ if (!q->bitmaps[ER]) {
+ NO(if (q->queued)
+ dump_sched(q, "start dequeue");)
+ return NULL;
+ }
+
+ grp = qfq_ffs(q, q->bitmaps[ER]);
+
+ cl = grp->slots[grp->front];
+ /* extract from the first bucket in the bucket list */
+ m = dn_dequeue(&cl->_q);
+
+ if (!m) {
+ D("BUG/* non-workconserving leaf */");
+ return NULL;
+ }
+ NO(q->queued--;)
+ old_V = q->V;
+ q->V += (uint64_t)m->m_pkthdr.len * IWSUM;
+ ND("m is %p F 0x%llx V now 0x%llx", m, cl->F, q->V);
+
+ if (qfq_update_class(q, grp, cl)) {
+ uint64_t old_F = grp->F;
+ cl = qfq_slot_scan(grp);
+ if (!cl) { /* group gone, remove from ER */
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ // grp->S = grp->F + 1; // XXX debugging only
+ } else {
+ uint64_t roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ unsigned int s;
+
+ if (grp->S == roundedS)
+ goto skip_unblock;
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift);
+ /* remove from ER and put in the new set */
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+ }
+ /* we need to unblock even if the group has gone away */
+ qfq_unblock_groups(q, grp->index, old_F);
+ }
+
+skip_unblock:
+ qfq_update_eligible(q, old_V);
+ NO(if (!q->bitmaps[ER] && q->queued)
+ dump_sched(q, "end dequeue");)
+
+ return m;
+}
+
+/*
+ * Assign a reasonable start time for a new flow k in group i.
+ * Admissible values for \hat(F) are multiples of \sigma_i
+ * no greater than V+\sigma_i . Larger values mean that
+ * we had a wraparound so we consider the timestamp to be stale.
+ *
+ * If F is not stale and F >= V then we set S = F.
+ * Otherwise we should assign S = V, but this may violate
+ * the ordering in ER. So, if we have groups in ER, set S to
+ * the F_j of the first group j which would be blocking us.
+ * We are guaranteed not to move S backward because
+ * otherwise our group i would still be blocked.
+ */
+static inline void
+qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
+{
+ unsigned long mask;
+ uint64_t limit, roundedF;
+ int slot_shift = cl->grp->slot_shift;
+
+ roundedF = qfq_round_down(cl->F, slot_shift);
+ limit = qfq_round_down(q->V, slot_shift) + (1UL << slot_shift);
+
+ if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) {
+ /* timestamp was stale */
+ mask = mask_from(q->bitmaps[ER], cl->grp->index);
+ if (mask) {
+ struct qfq_group *next = qfq_ffs(q, mask);
+ if (qfq_gt(roundedF, next->F)) {
+ cl->S = next->F;
+ return;
+ }
+ }
+ cl->S = q->V;
+ } else { /* timestamp is not stale */
+ cl->S = cl->F;
+ }
+}
+
+static int
+qfq_enqueue(struct dn_sch_inst *si, struct dn_queue *_q, struct mbuf *m)
+{
+ struct qfq_sched *q = (struct qfq_sched *)(si + 1);
+ struct qfq_group *grp;
+ struct qfq_class *cl = (struct qfq_class *)_q;
+ uint64_t roundedS;
+ int s;
+
+ NO(q->loops++;)
+ DX(4, "len %d flow %p inv_w 0x%x grp %d", m->m_pkthdr.len,
+ _q, cl->inv_w, cl->grp->index);
+ /* XXX verify that the packet obeys the parameters */
+ if (m != _q->mq.head) {
+ if (dn_enqueue(_q, m, 0)) /* packet was dropped */
+ return 1;
+ NO(q->queued++;)
+ if (m != _q->mq.head)
+ return 0;
+ }
+ /* If reach this point, queue q was idle */
+ grp = cl->grp;
+ qfq_update_start(q, cl); /* adjust start time */
+ /* compute new finish time and rounded start. */
+ cl->F = cl->S + (uint64_t)(m->m_pkthdr.len) * cl->inv_w;
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+
+ /*
+ * insert cl in the correct bucket.
+ * If cl->S >= grp->S we don't need to adjust the
+ * bucket list and simply go to the insertion phase.
+ * Otherwise grp->S is decreasing, we must make room
+ * in the bucket list, and also recompute the group state.
+ * Finally, if there were no flows in this group and nobody
+ * was in ER make sure to adjust V.
+ */
+ if (grp->full_slots) {
+ if (!qfq_gt(grp->S, cl->S))
+ goto skip_update;
+ /* create a slot for this cl->S */
+ qfq_slot_rotate(q, grp, roundedS);
+ /* group was surely ineligible, remove */
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+ } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V))
+ q->V = roundedS;
+
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift); // i.e. 2\sigma_i
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+ ND("new state %d 0x%x", s, q->bitmaps[s]);
+ ND("S %llx F %llx V %llx", cl->S, cl->F, q->V);
+skip_update:
+ qfq_slot_insert(grp, cl, roundedS);
+
+ return 0;
+}
+
+
+#if 0
+static inline void
+qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp,
+ struct qfq_class *cl, struct qfq_class **pprev)
+{
+ unsigned int i, offset;
+ uint64_t roundedS;
+
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ offset = (roundedS - grp->S) >> grp->slot_shift;
+ i = (grp->front + offset) % QFQ_MAX_SLOTS;
+
+#ifdef notyet
+ if (!pprev) {
+ pprev = &grp->slots[i];
+ while (*pprev && *pprev != cl)
+ pprev = &(*pprev)->next;
+ }
+#endif
+
+ *pprev = cl->next;
+ if (!grp->slots[i])
+ __clear_bit(offset, &grp->full_slots);
+}
+
+/*
+ * called to forcibly destroy a queue.
+ * If the queue is not in the front bucket, or if it has
+ * other queues in the front bucket, we can simply remove
+ * the queue with no other side effects.
+ * Otherwise we must propagate the event up.
+ * XXX description to be completed.
+ */
+static void
+qfq_deactivate_class(struct qfq_sched *q, struct qfq_class *cl,
+ struct qfq_class **pprev)
+{
+ struct qfq_group *grp = &q->groups[cl->index];
+ unsigned long mask;
+ uint64_t roundedS;
+ int s;
+
+ cl->F = cl->S; // not needed if the class goes away.
+ qfq_slot_remove(q, grp, cl, pprev);
+
+ if (!grp->full_slots) {
+ /* nothing left in the group, remove from all sets.
+ * Do ER last because if we were blocking other groups
+ * we must unblock them.
+ */
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[EB]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+
+ if (test_bit(grp->index, &q->bitmaps[ER]) &&
+ !(q->bitmaps[ER] & ~((1UL << grp->index) - 1))) {
+ mask = q->bitmaps[ER] & ((1UL << grp->index) - 1);
+ if (mask)
+ mask = ~((1UL << __fls(mask)) - 1);
+ else
+ mask = ~0UL;
+ qfq_move_groups(q, mask, EB, ER);
+ qfq_move_groups(q, mask, IB, IR);
+ }
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ } else if (!grp->slots[grp->front]) {
+ cl = qfq_slot_scan(grp);
+ roundedS = qfq_round_down(cl->S, grp->slot_shift);
+ if (grp->S != roundedS) {
+ __clear_bit(grp->index, &q->bitmaps[ER]);
+ __clear_bit(grp->index, &q->bitmaps[IR]);
+ __clear_bit(grp->index, &q->bitmaps[EB]);
+ __clear_bit(grp->index, &q->bitmaps[IB]);
+ grp->S = roundedS;
+ grp->F = roundedS + (2ULL << grp->slot_shift);
+ s = qfq_calc_state(q, grp);
+ __set_bit(grp->index, &q->bitmaps[s]);
+ }
+ }
+ qfq_update_eligible(q, q->V);
+}
+#endif
+
+static int
+qfq_new_fsk(struct dn_fsk *f)
+{
+ ipdn_bound_var(&f->fs.par[0], 1, 1, QFQ_MAX_WEIGHT, "qfq weight");
+ ipdn_bound_var(&f->fs.par[1], 1500, 1, 2000, "qfq maxlen");
+ ND("weight %d len %d\n", f->fs.par[0], f->fs.par[1]);
+ return 0;
+}
+
+/*
+ * initialize a new scheduler instance
+ */
+static int
+qfq_new_sched(struct dn_sch_inst *si)
+{
+ struct qfq_sched *q = (struct qfq_sched *)(si + 1);
+ struct qfq_group *grp;
+ int i;
+
+ for (i = 0; i <= QFQ_MAX_INDEX; i++) {
+ grp = &q->groups[i];
+ grp->index = i;
+ grp->slot_shift = QFQ_MTU_SHIFT + FRAC_BITS -
+ (QFQ_MAX_INDEX - i);
+ }
+ return 0;
+}
+
+/*
+ * QFQ scheduler descriptor
+ */
+static struct dn_alg qfq_desc = {
+ _SI( .type = ) DN_SCHED_QFQ,
+ _SI( .name = ) "QFQ",
+ _SI( .flags = ) DN_MULTIQUEUE,
+
+ _SI( .schk_datalen = ) 0,
+ _SI( .si_datalen = ) sizeof(struct qfq_sched),
+ _SI( .q_datalen = ) sizeof(struct qfq_class) - sizeof(struct dn_queue),
+
+ _SI( .enqueue = ) qfq_enqueue,
+ _SI( .dequeue = ) qfq_dequeue,
+
+ _SI( .config = ) NULL,
+ _SI( .destroy = ) NULL,
+ _SI( .new_sched = ) qfq_new_sched,
+ _SI( .free_sched = ) NULL,
+ _SI( .new_fsk = ) qfq_new_fsk,
+ _SI( .free_fsk = ) NULL,
+ _SI( .new_queue = ) qfq_new_queue,
+ _SI( .free_queue = ) qfq_free_queue,
+};
+
+DECLARE_DNSCHED_MODULE(dn_qfq, &qfq_desc);
+
+#ifdef QFQ_DEBUG
+static void
+dump_groups(struct qfq_sched *q, uint32_t mask)
+{
+ int i, j;
+
+ for (i = 0; i < QFQ_MAX_INDEX + 1; i++) {
+ struct qfq_group *g = &q->groups[i];
+
+ if (0 == (mask & (1<<i)))
+ continue;
+ for (j = 0; j < QFQ_MAX_SLOTS; j++) {
+ if (g->slots[j])
+ D(" bucket %d %p", j, g->slots[j]);
+ }
+ D("full_slots 0x%x", g->full_slots);
+ D(" %2d S 0x%20llx F 0x%llx %c", i,
+ g->S, g->F,
+ mask & (1<<i) ? '1' : '0');
+ }
+}
+
+static void
+dump_sched(struct qfq_sched *q, const char *msg)
+{
+ D("--- in %s: ---", msg);
+ ND("loops %d queued %d V 0x%llx", q->loops, q->queued, q->V);
+ D(" ER 0x%08x", q->bitmaps[ER]);
+ D(" EB 0x%08x", q->bitmaps[EB]);
+ D(" IR 0x%08x", q->bitmaps[IR]);
+ D(" IB 0x%08x", q->bitmaps[IB]);
+ dump_groups(q, 0xffffffff);
+};
+#endif /* QFQ_DEBUG */
diff --git a/sys/netinet/ipfw/dn_sched_rr.c b/sys/netinet/ipfw/dn_sched_rr.c
new file mode 100644
index 0000000..1bbd800
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched_rr.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $FreeBSD$
+ */
+
+#ifdef _KERNEL
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <net/if.h> /* IFNAMSIZ */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ipfw_rule_ref */
+#include <netinet/ip_fw.h> /* flow_id */
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+#else
+#include <dn_test.h>
+#endif
+
+#define DN_SCHED_RR 3 // XXX Where?
+
+struct rr_queue {
+ struct dn_queue q; /* Standard queue */
+ int status; /* 1: queue is in the list */
+ int credit; /* Number of bytes to transmit */
+ int quantum; /* quantum * C */
+ struct rr_queue *qnext; /* */
+};
+
+/* struct rr_schk contains global config parameters
+ * and is right after dn_schk
+ */
+struct rr_schk {
+ int min_q; /* Min quantum */
+ int max_q; /* Max quantum */
+ int q_bytes; /* Bytes per quantum */
+};
+
+/* per-instance round robin list, right after dn_sch_inst */
+struct rr_si {
+ struct rr_queue *head, *tail; /* Pointer to current queue */
+};
+
+/* Append a queue to the rr list */
+static inline void
+rr_append(struct rr_queue *q, struct rr_si *si)
+{
+ q->status = 1; /* mark as in-rr_list */
+ q->credit = q->quantum; /* initialize credit */
+
+ /* append to the tail */
+ if (si->head == NULL)
+ si->head = q;
+ else
+ si->tail->qnext = q;
+ si->tail = q; /* advance the tail pointer */
+ q->qnext = si->head; /* make it circular */
+}
+
+/* Remove the head queue from circular list. */
+static inline void
+rr_remove_head(struct rr_si *si)
+{
+ if (si->head == NULL)
+ return; /* empty queue */
+ si->head->status = 0;
+
+ if (si->head == si->tail) {
+ si->head = si->tail = NULL;
+ return;
+ }
+
+ si->head = si->head->qnext;
+ si->tail->qnext = si->head;
+}
+
+/* Remove a queue from circular list.
+ * XXX see if ti can be merge with remove_queue()
+ */
+static inline void
+remove_queue_q(struct rr_queue *q, struct rr_si *si)
+{
+ struct rr_queue *prev;
+
+ if (q->status != 1)
+ return;
+ if (q == si->head) {
+ rr_remove_head(si);
+ return;
+ }
+
+ for (prev = si->head; prev; prev = prev->qnext) {
+ if (prev->qnext != q)
+ continue;
+ prev->qnext = q->qnext;
+ if (q == si->tail)
+ si->tail = prev;
+ q->status = 0;
+ break;
+ }
+}
+
+
+static inline void
+next_pointer(struct rr_si *si)
+{
+ if (si->head == NULL)
+ return; /* empty queue */
+
+ si->head = si->head->qnext;
+ si->tail = si->tail->qnext;
+}
+
+static int
+rr_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
+{
+ struct rr_si *si;
+ struct rr_queue *rrq;
+
+ if (m != q->mq.head) {
+ if (dn_enqueue(q, m, 0)) /* packet was dropped */
+ return 1;
+ if (m != q->mq.head)
+ return 0;
+ }
+
+ /* If reach this point, queue q was idle */
+ si = (struct rr_si *)(_si + 1);
+ rrq = (struct rr_queue *)q;
+
+ if (rrq->status == 1) /* Queue is already in the queue list */
+ return 0;
+
+ /* Insert the queue in the queue list */
+ rr_append(rrq, si);
+
+ return 0;
+}
+
+static struct mbuf *
+rr_dequeue(struct dn_sch_inst *_si)
+{
+ /* Access scheduler instance private data */
+ struct rr_si *si = (struct rr_si *)(_si + 1);
+ struct rr_queue *rrq;
+ uint64_t len;
+
+ while ( (rrq = si->head) ) {
+ struct mbuf *m = rrq->q.mq.head;
+ if ( m == NULL) {
+ /* empty queue, remove from list */
+ rr_remove_head(si);
+ continue;
+ }
+ len = m->m_pkthdr.len;
+
+ if (len > rrq->credit) {
+ /* Packet too big */
+ rrq->credit += rrq->quantum;
+ /* Try next queue */
+ next_pointer(si);
+ } else {
+ rrq->credit -= len;
+ return dn_dequeue(&rrq->q);
+ }
+ }
+
+ /* no packet to dequeue*/
+ return NULL;
+}
+
+static int
+rr_config(struct dn_schk *_schk)
+{
+ struct rr_schk *schk = (struct rr_schk *)(_schk + 1);
+ ND("called");
+
+ /* use reasonable quantums (64..2k bytes, default 1500) */
+ schk->min_q = 64;
+ schk->max_q = 2048;
+ schk->q_bytes = 1500; /* quantum */
+
+ return 0;
+}
+
+static int
+rr_new_sched(struct dn_sch_inst *_si)
+{
+ struct rr_si *si = (struct rr_si *)(_si + 1);
+
+ ND("called");
+ si->head = si->tail = NULL;
+
+ return 0;
+}
+
+static int
+rr_free_sched(struct dn_sch_inst *_si)
+{
+ ND("called");
+ /* Nothing to do? */
+ return 0;
+}
+
+static int
+rr_new_fsk(struct dn_fsk *fs)
+{
+ struct rr_schk *schk = (struct rr_schk *)(fs->sched + 1);
+ /* par[0] is the weight, par[1] is the quantum step */
+ ipdn_bound_var(&fs->fs.par[0], 1,
+ 1, 65536, "RR weight");
+ ipdn_bound_var(&fs->fs.par[1], schk->q_bytes,
+ schk->min_q, schk->max_q, "RR quantum");
+ return 0;
+}
+
+static int
+rr_new_queue(struct dn_queue *_q)
+{
+ struct rr_queue *q = (struct rr_queue *)_q;
+
+ _q->ni.oid.subtype = DN_SCHED_RR;
+
+ q->quantum = _q->fs->fs.par[0] * _q->fs->fs.par[1];
+ ND("called, q->quantum %d", q->quantum);
+ q->credit = q->quantum;
+ q->status = 0;
+
+ if (_q->mq.head != NULL) {
+ /* Queue NOT empty, insert in the queue list */
+ rr_append(q, (struct rr_si *)(_q->_si + 1));
+ }
+ return 0;
+}
+
+static int
+rr_free_queue(struct dn_queue *_q)
+{
+ struct rr_queue *q = (struct rr_queue *)_q;
+
+ ND("called");
+ if (q->status == 1) {
+ struct rr_si *si = (struct rr_si *)(_q->_si + 1);
+ remove_queue_q(q, si);
+ }
+ return 0;
+}
+
+/*
+ * RR scheduler descriptor
+ * contains the type of the scheduler, the name, the size of the
+ * structures and function pointers.
+ */
+static struct dn_alg rr_desc = {
+ _SI( .type = ) DN_SCHED_RR,
+ _SI( .name = ) "RR",
+ _SI( .flags = ) DN_MULTIQUEUE,
+
+ _SI( .schk_datalen = ) 0,
+ _SI( .si_datalen = ) sizeof(struct rr_si),
+ _SI( .q_datalen = ) sizeof(struct rr_queue) - sizeof(struct dn_queue),
+
+ _SI( .enqueue = ) rr_enqueue,
+ _SI( .dequeue = ) rr_dequeue,
+
+ _SI( .config = ) rr_config,
+ _SI( .destroy = ) NULL,
+ _SI( .new_sched = ) rr_new_sched,
+ _SI( .free_sched = ) rr_free_sched,
+ _SI( .new_fsk = ) rr_new_fsk,
+ _SI( .free_fsk = ) NULL,
+ _SI( .new_queue = ) rr_new_queue,
+ _SI( .free_queue = ) rr_free_queue,
+};
+
+
+DECLARE_DNSCHED_MODULE(dn_rr, &rr_desc);
diff --git a/sys/netinet/ipfw/dn_sched_wf2q.c b/sys/netinet/ipfw/dn_sched_wf2q.c
new file mode 100644
index 0000000..7f16719
--- /dev/null
+++ b/sys/netinet/ipfw/dn_sched_wf2q.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
+ * Copyright (c) 2000-2002 Luigi Rizzo, Universita` di Pisa
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $FreeBSD$
+ */
+
+#ifdef _KERNEL
+#include <sys/malloc.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <net/if.h> /* IFNAMSIZ */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ipfw_rule_ref */
+#include <netinet/ip_fw.h> /* flow_id */
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+#else
+#include <dn_test.h>
+#endif
+
+#ifndef MAX64
+#define MAX64(x,y) (( (int64_t) ( (y)-(x) )) > 0 ) ? (y) : (x)
+#endif
+
+/*
+ * timestamps are computed on 64 bit using fixed point arithmetic.
+ * LMAX_BITS, WMAX_BITS are the max number of bits for the packet len
+ * and sum of weights, respectively. FRAC_BITS is the number of
+ * fractional bits. We want FRAC_BITS >> WMAX_BITS to avoid too large
+ * errors when computing the inverse, FRAC_BITS < 32 so we can do 1/w
+ * using an unsigned 32-bit division, and to avoid wraparounds we need
+ * LMAX_BITS + WMAX_BITS + FRAC_BITS << 64
+ * As an example
+ * FRAC_BITS = 26, LMAX_BITS=14, WMAX_BITS = 19
+ */
+#ifndef FRAC_BITS
+#define FRAC_BITS 28 /* shift for fixed point arithmetic */
+#define ONE_FP (1UL << FRAC_BITS)
+#endif
+
+/*
+ * Private information for the scheduler instance:
+ * sch_heap (key is Finish time) returns the next queue to serve
+ * ne_heap (key is Start time) stores not-eligible queues
+ * idle_heap (key=start/finish time) stores idle flows. It must
+ * support extract-from-middle.
+ * A flow is only in 1 of the three heaps.
+ * XXX todo: use a more efficient data structure, e.g. a tree sorted
+ * by F with min_subtree(S) in each node
+ */
+struct wf2qp_si {
+ struct dn_heap sch_heap; /* top extract - key Finish time */
+ struct dn_heap ne_heap; /* top extract - key Start time */
+ struct dn_heap idle_heap; /* random extract - key Start=Finish time */
+ uint64_t V; /* virtual time */
+ uint32_t inv_wsum; /* inverse of sum of weights */
+ uint32_t wsum; /* sum of weights */
+};
+
+struct wf2qp_queue {
+ struct dn_queue _q;
+ uint64_t S, F; /* start time, finish time */
+ uint32_t inv_w; /* ONE_FP / weight */
+ int32_t heap_pos; /* position (index) of struct in heap */
+};
+
+/*
+ * This file implements a WF2Q+ scheduler as it has been in dummynet
+ * since 2000.
+ * The scheduler supports per-flow queues and has O(log N) complexity.
+ *
+ * WF2Q+ needs to drain entries from the idle heap so that we
+ * can keep the sum of weights up to date. We can do it whenever
+ * we get a chance, or periodically, or following some other
+ * strategy. The function idle_check() drains at most N elements
+ * from the idle heap.
+ */
+static void
+idle_check(struct wf2qp_si *si, int n, int force)
+{
+ struct dn_heap *h = &si->idle_heap;
+ while (n-- > 0 && h->elements > 0 &&
+ (force || DN_KEY_LT(HEAP_TOP(h)->key, si->V))) {
+ struct dn_queue *q = HEAP_TOP(h)->object;
+ struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q;
+
+ heap_extract(h, NULL);
+ /* XXX to let the flowset delete the queue we should
+ * mark it as 'unused' by the scheduler.
+ */
+ alg_fq->S = alg_fq->F + 1; /* Mark timestamp as invalid. */
+ si->wsum -= q->fs->fs.par[0]; /* adjust sum of weights */
+ if (si->wsum > 0)
+ si->inv_wsum = ONE_FP/si->wsum;
+ }
+}
+
+static int
+wf2qp_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
+{
+ struct dn_fsk *fs = q->fs;
+ struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
+ struct wf2qp_queue *alg_fq;
+ uint64_t len = m->m_pkthdr.len;
+
+ if (m != q->mq.head) {
+ if (dn_enqueue(q, m, 0)) /* packet was dropped */
+ return 1;
+ if (m != q->mq.head) /* queue was already busy */
+ return 0;
+ }
+
+ /* If reach this point, queue q was idle */
+ alg_fq = (struct wf2qp_queue *)q;
+
+ if (DN_KEY_LT(alg_fq->F, alg_fq->S)) {
+ /* F<S means timestamps are invalid ->brand new queue. */
+ alg_fq->S = si->V; /* init start time */
+ si->wsum += fs->fs.par[0]; /* add weight of new queue. */
+ si->inv_wsum = ONE_FP/si->wsum;
+ } else { /* if it was idle then it was in the idle heap */
+ heap_extract(&si->idle_heap, q);
+ alg_fq->S = MAX64(alg_fq->F, si->V); /* compute new S */
+ }
+ alg_fq->F = alg_fq->S + len * alg_fq->inv_w;
+
+ /* if nothing is backlogged, make sure this flow is eligible */
+ if (si->ne_heap.elements == 0 && si->sch_heap.elements == 0)
+ si->V = MAX64(alg_fq->S, si->V);
+
+ /*
+ * Look at eligibility. A flow is not eligibile if S>V (when
+ * this happens, it means that there is some other flow already
+ * scheduled for the same pipe, so the sch_heap cannot be
+ * empty). If the flow is not eligible we just store it in the
+ * ne_heap. Otherwise, we store in the sch_heap.
+ * Note that for all flows in sch_heap (SCH), S_i <= V,
+ * and for all flows in ne_heap (NEH), S_i > V.
+ * So when we need to compute max(V, min(S_i)) forall i in
+ * SCH+NEH, we only need to look into NEH.
+ */
+ if (DN_KEY_LT(si->V, alg_fq->S)) {
+ /* S>V means flow Not eligible. */
+ if (si->sch_heap.elements == 0)
+ D("++ ouch! not eligible but empty scheduler!");
+ heap_insert(&si->ne_heap, alg_fq->S, q);
+ } else {
+ heap_insert(&si->sch_heap, alg_fq->F, q);
+ }
+ return 0;
+}
+
+/* XXX invariant: sch > 0 || V >= min(S in neh) */
+static struct mbuf *
+wf2qp_dequeue(struct dn_sch_inst *_si)
+{
+ /* Access scheduler instance private data */
+ struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
+ struct mbuf *m;
+ struct dn_queue *q;
+ struct dn_heap *sch = &si->sch_heap;
+ struct dn_heap *neh = &si->ne_heap;
+ struct wf2qp_queue *alg_fq;
+
+ if (sch->elements == 0 && neh->elements == 0) {
+ /* we have nothing to do. We could kill the idle heap
+ * altogether and reset V
+ */
+ idle_check(si, 0x7fffffff, 1);
+ si->V = 0;
+ si->wsum = 0; /* should be set already */
+ return NULL; /* quick return if nothing to do */
+ }
+ idle_check(si, 1, 0); /* drain something from the idle heap */
+
+ /* make sure at least one element is eligible, bumping V
+ * and moving entries that have become eligible.
+ * We need to repeat the first part twice, before and
+ * after extracting the candidate, or enqueue() will
+ * find the data structure in a wrong state.
+ */
+ m = NULL;
+ for(;;) {
+ /*
+ * Compute V = max(V, min(S_i)). Remember that all elements
+ * in sch have by definition S_i <= V so if sch is not empty,
+ * V is surely the max and we must not update it. Conversely,
+ * if sch is empty we only need to look at neh.
+ * We don't need to move the queues, as it will be done at the
+ * next enqueue
+ */
+ if (sch->elements == 0 && neh->elements > 0) {
+ si->V = MAX64(si->V, HEAP_TOP(neh)->key);
+ }
+ while (neh->elements > 0 &&
+ DN_KEY_LEQ(HEAP_TOP(neh)->key, si->V)) {
+ q = HEAP_TOP(neh)->object;
+ alg_fq = (struct wf2qp_queue *)q;
+ heap_extract(neh, NULL);
+ heap_insert(sch, alg_fq->F, q);
+ }
+ if (m) /* pkt found in previous iteration */
+ break;
+ /* ok we have at least one eligible pkt */
+ q = HEAP_TOP(sch)->object;
+ alg_fq = (struct wf2qp_queue *)q;
+ m = dn_dequeue(q);
+ heap_extract(sch, NULL); /* Remove queue from heap. */
+ si->V += (uint64_t)(m->m_pkthdr.len) * si->inv_wsum;
+ alg_fq->S = alg_fq->F; /* Update start time. */
+ if (q->mq.head == 0) { /* not backlogged any more. */
+ heap_insert(&si->idle_heap, alg_fq->F, q);
+ } else { /* Still backlogged. */
+ /* Update F, store in neh or sch */
+ uint64_t len = q->mq.head->m_pkthdr.len;
+ alg_fq->F += len * alg_fq->inv_w;
+ if (DN_KEY_LEQ(alg_fq->S, si->V)) {
+ heap_insert(sch, alg_fq->F, q);
+ } else {
+ heap_insert(neh, alg_fq->S, q);
+ }
+ }
+ }
+ return m;
+}
+
+static int
+wf2qp_new_sched(struct dn_sch_inst *_si)
+{
+ struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
+ int ofs = offsetof(struct wf2qp_queue, heap_pos);
+
+ /* all heaps support extract from middle */
+ if (heap_init(&si->idle_heap, 16, ofs) ||
+ heap_init(&si->sch_heap, 16, ofs) ||
+ heap_init(&si->ne_heap, 16, ofs)) {
+ heap_free(&si->ne_heap);
+ heap_free(&si->sch_heap);
+ heap_free(&si->idle_heap);
+ return ENOMEM;
+ }
+ return 0;
+}
+
+static int
+wf2qp_free_sched(struct dn_sch_inst *_si)
+{
+ struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
+
+ heap_free(&si->sch_heap);
+ heap_free(&si->ne_heap);
+ heap_free(&si->idle_heap);
+
+ return 0;
+}
+
+static int
+wf2qp_new_fsk(struct dn_fsk *fs)
+{
+ ipdn_bound_var(&fs->fs.par[0], 1,
+ 1, 100, "WF2Q+ weight");
+ return 0;
+}
+
+static int
+wf2qp_new_queue(struct dn_queue *_q)
+{
+ struct wf2qp_queue *q = (struct wf2qp_queue *)_q;
+
+ _q->ni.oid.subtype = DN_SCHED_WF2QP;
+ q->F = 0; /* not strictly necessary */
+ q->S = q->F + 1; /* mark timestamp as invalid. */
+ q->inv_w = ONE_FP / _q->fs->fs.par[0];
+ if (_q->mq.head != NULL) {
+ wf2qp_enqueue(_q->_si, _q, _q->mq.head);
+ }
+ return 0;
+}
+
+/*
+ * Called when the infrastructure removes a queue (e.g. flowset
+ * is reconfigured). Nothing to do if we did not 'own' the queue,
+ * otherwise remove it from the right heap and adjust the sum
+ * of weights.
+ */
+static int
+wf2qp_free_queue(struct dn_queue *q)
+{
+ struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q;
+ struct wf2qp_si *si = (struct wf2qp_si *)(q->_si + 1);
+
+ if (alg_fq->S >= alg_fq->F + 1)
+ return 0; /* nothing to do, not in any heap */
+ si->wsum -= q->fs->fs.par[0];
+ if (si->wsum > 0)
+ si->inv_wsum = ONE_FP/si->wsum;
+
+ /* extract from the heap. XXX TODO we may need to adjust V
+ * to make sure the invariants hold.
+ */
+ if (q->mq.head == NULL) {
+ heap_extract(&si->idle_heap, q);
+ } else if (DN_KEY_LT(si->V, alg_fq->S)) {
+ heap_extract(&si->ne_heap, q);
+ } else {
+ heap_extract(&si->sch_heap, q);
+ }
+ return 0;
+}
+
+/*
+ * WF2Q+ scheduler descriptor
+ * contains the type of the scheduler, the name, the size of the
+ * structures and function pointers.
+ */
+static struct dn_alg wf2qp_desc = {
+ _SI( .type = ) DN_SCHED_WF2QP,
+ _SI( .name = ) "WF2Q+",
+ _SI( .flags = ) DN_MULTIQUEUE,
+
+ /* we need extra space in the si and the queue */
+ _SI( .schk_datalen = ) 0,
+ _SI( .si_datalen = ) sizeof(struct wf2qp_si),
+ _SI( .q_datalen = ) sizeof(struct wf2qp_queue) -
+ sizeof(struct dn_queue),
+
+ _SI( .enqueue = ) wf2qp_enqueue,
+ _SI( .dequeue = ) wf2qp_dequeue,
+
+ _SI( .config = ) NULL,
+ _SI( .destroy = ) NULL,
+ _SI( .new_sched = ) wf2qp_new_sched,
+ _SI( .free_sched = ) wf2qp_free_sched,
+
+ _SI( .new_fsk = ) wf2qp_new_fsk,
+ _SI( .free_fsk = ) NULL,
+
+ _SI( .new_queue = ) wf2qp_new_queue,
+ _SI( .free_queue = ) wf2qp_free_queue,
+};
+
+
+DECLARE_DNSCHED_MODULE(dn_wf2qp, &wf2qp_desc);
diff --git a/sys/netinet/ipfw/dummynet.txt b/sys/netinet/ipfw/dummynet.txt
new file mode 100644
index 0000000..e4f3075
--- /dev/null
+++ b/sys/netinet/ipfw/dummynet.txt
@@ -0,0 +1,860 @@
+#
+# $FreeBSD$
+#
+
+Notes on the internal structure of dummynet (2010 version)
+by Riccardo Panicucci and Luigi Rizzo
+Work supported by the EC project ONELAB2
+
+
+*********
+* INDEX *
+*********
+Implementation of new dummynet
+ Internal structure
+ Files
+Packet arrival
+ The reconfiguration routine
+dummynet_task()
+Configuration
+ Add a pipe
+ Add a scheduler
+ Add a flowset
+Listing object
+Delete of object
+ Delete a pipe
+ Delete a flowset
+ Delete a scheduler
+Compatibility with FreeBSD7.2 and FreeBSD 8 ipfw binary
+ ip_dummynet_glue.c
+ ip_fw_glue.c
+How to configure dummynet
+How to implement a new scheduler
+
+
+
+OPEN ISSUES
+------------------------------
+20100131 deleting RR causes infinite loop
+ presumably in the rr_free_queue() call -- seems to hang
+ forever when deleting a live flow
+------------------------------
+
+Dummynet is a traffic shaper and network emulator. Packets are
+selected by an external filter such as ipfw, and passed to the emulator
+with a tag such as "pipe 10" or "queue 5" which tells what to
+do with the packet. As an example
+
+ ipfw add queue 5 icmp from 10.0.0.2 to all
+
+All packets with the same tag belong to a "flowset", or a set
+of flows which can be further partitioned according to a mask.
+Flowsets are then passed to a scheduler for processing. The
+association of flowsets and schedulers is configurable e.g.
+
+ ipfw queue 5 config sched 10 weight 3 flow_mask xxxx
+ ipfw queue 8 config sched 10 weight 1 ...
+ ipfw queue 3 config sched 20 weight 1 ...
+
+"sched 10" represents one or more scheduler instances,
+selected through a mask on the 5-tuple itself.
+
+ ipfw sched 20 config type FIFO sched_mask yyy ...
+
+There are in fact two masks applied to each packet:
++ the "sched_mask" sends packets arriving to a scheduler_id to
+ one of many instances.
++ the "flow_mask" together with the flowset_id is used to
+ collect packets into independent flows on each scheduler.
+
+As an example, we can have
+ ipfw queue 5 config sched 10 flow_mask src-ip 0x000000ff
+ ipfw sched 10 config type WF2Q+ sched_mask src-ip 0xffffff00
+
+means that sched 10 will have one instance per /24 source subnet,
+and within that, each individual source will be a flow.
+
+Internal structure
+-----------------
+Dummynet-related data is split into several data structures,
+part of them constituting the userland-kernel API, and others
+specific to the kernel.
+NOTE: for up-to-date details please look at the relevant source
+ headers (ip_dummynet.h, ip_dn_private.h, dn_sched.h)
+
+USERLAND-KERNEL API (ip_dummynet.h)
+
+ struct dn_link:
+ contains data about the physical link such as
+ bandwith, delay, burst size;
+
+ struct dn_fs:
+ describes a flowset, i.e. a template for queues.
+ Main parameters are the scheduler we attach to, a flow_mask,
+ buckets, queue size, plr, weight, and other scheduler-specific
+ parameters.
+
+ struct dn_flow
+ contains information on a flow, including masks and
+ statistics
+
+ struct dn_sch:
+ defines a scheduler (and a link attached to it).
+ Parameters include scheduler type, sched_mask, number of
+ buckets, and possibly other scheduler-specific parameters,
+
+ struct dn_profile:
+ fields to simulate a delay profile
+
+
+KERNEL REPRESENTATION (ip_dn_private.h)
+
+ struct mq
+ a queue of mbufs with head and tail.
+
+ struct dn_queue
+ individual queue of packets, created by a flowset using
+ flow_mask and attached to a scheduler instance selected
+ through sched_mask.
+ A dn_queue has a pointer to the dn_fsk (which in turn counts
+ how many queues point to it), a pointer to the
+ dn_sch_inst it attaches to, and is in a hash table in the
+ flowset. scheduler instances also should store queues in
+ their own containers used for scheduling (lists, trees, etc.)
+ CREATE: done on packet arrivals when a flow matches a flowset.
+ DELETE: done only when deleting the parent dn_sch_inst
+ or draining memory.
+
+ struct dn_fsk
+ includes a dn_fs; a pointer to the dn_schk; a link field
+ for the list of dn_fsk attached to the same scheduler,
+ or for the unlinked list;
+ a refcount for the number of queues pointing to it;
+ The dn_fsk is in a hash table, fshash.
+ CREATE: done on configuration commands.
+ DELETE: on configuration commands.
+
+ struct dn_sch_inst
+ a scheduler instance, created from a dn_schk applying sched_mask.
+ Contains a delay line, a reference to the parent, and scheduler-
+ specific info. Both dn_sch_inst and its delay line can be in the
+ evheap if they have events to be processed.
+ CREATE: created from a dn_schk applying sched_mask
+ DELETE: configuration command delete a scheduler which in turn
+ sweeps the hash table of instances deleting them
+
+ struct dn_schk
+ includes dn_sch, dn_link, a pointer to dn_profile,
+ a hash table of dn_sch_inst, a list of dn_fsk
+ attached to it.
+ CREATE: configuration command. If there are flowsets that
+ refer to this number, they are attached and moved
+ to the hash table
+ DELETE: manual, see dn_sch_inst
+
+
+ fshash schedhash
+ +---------------+ sched +--------------+
+ | sched-------------------->| NEW_SCHK|
+ -<----*sch_chain |<-----------------*fsk_list |
+ |NEW_FSK |<----. | [dn_link] |
+ +---------------+ | +--------------+
+ |qht (hash) | | | siht(hash) |
+ | [dn_queue] | | | [dn_si] |
+ | [dn_queue] | | | [dn_si] |
+ | ... | | | ... |
+ | +--------+ | | | +---------+ |
+ | |dn_queue| | | | |dn_si | |
+ | | fs *----------' | | | |
+ | | si *---------------------->| | |
+ | +---------+ | | +---------+ |
+ +---------------+ +--------------+
+
+The following global data structures contain all
+schedulers and flowsets.
+
+- schedhash[x]: contains all scheduler templates in the system.
+ Looked up only on manual configurations, where flowsets
+ are attached to matching schedulers.
+ We have one entry per 'sched X config' command
+ (plus one for each 'pipe X config').
+
+- fshash[x]: contains all flowsets.
+ We do a lookup on this for each packet.
+ We have one entry for each 'queue X config'
+ (plus one for each 'pipe X config').
+
+Additionally, a list that contains all unlinked flowset:
+- fsu: contains flowset that are not linked with any scheduler.
+ Flowset are put in this list when they refer to a non
+ existing scheduler.
+ We don't need an efficient data structure as we never search
+ here on a packet arrivals.
+
+Scheduler instances and the delay lines associated with each scheduler
+instance need to be woken up at certain times. Because we have many
+such objects, we keep them in a priority heap (system_heap).
+
+Almost all objects in this implementation are preceded by a structure
+(struct dn_id) which makes it easier to identify them.
+
+
+Files
+-----
+The dummynet code is split in several files.
+All kernel code is in sys/netinet/ipfw except ip_dummynet.h
+All userland code is in sbin/ipfw.
+Files are
+- sys/netinet/ip_dummynet.h defines the kernel-userland API
+- ip_dn_private.h contains the kernel-specific APIs
+ and data structures
+- dn_sched.h defines the scheduler API
+- ip_dummynet.c cointains module glue and sockopt handlers, with all
+ functions to configure and list objects.
+- ip_dn_io.c contains the functions directly related to packet processing,
+ and run in the critical path. It also contains some functions
+ exported to the schedulers.
+- dn_heap.[ch] implement a binary heap and a generic hash table
+- dn_sched_* implement the various scheduler modules
+
+- dummynet.c is the file used to implement the user side of dummynet.
+ It contains the function to parsing command line, and functions to
+ show the output of dummynet objects.
+Moreover, there are two new file (ip_dummynet_glue.c and ip_fw_glue.c) that
+are used to allow compatibility with the "ipfw" binary from FreeBSD 7.2 and
+FreeBSD 8.
+
+LOCKING
+=======
+At the moment the entire processing occurs under a single lock
+which is expected to be acquired in exclusive mode
+DN_BH_WLOCK() / DN_BH_WUNLOCK().
+
+In perspective we aim at the following:
+- the 'busy' flag, 'pending' list and all structures modified by packet
+ arrivals and departures are protected by the BH_WLOCK.
+ This is normally acquired in exclusive mode by the packet processing
+ functions for short sections of code (exception -- the timer).
+ If 'busy' is not set, we can do regular packet processing.
+ If 'busy' is set, no pieces can be accessed.
+ We must enqueue the packet on 'pending' and return immediately.
+
+- the 'busy' flag is set/cleared by long sections of code as follows:
+ UH_WLOCK(); KASSERT(busy == 0);
+ BH_WLOCK(); busy=1; BH_WUNLOCK();
+ ... do processing ...
+ BH_WLOCK(); busy=0; drain_queue(pending); BH_WUNLOCK();
+ UH_WUNLOCK();
+ this normally happens when the upper half has something heavy
+ to do. The prologue and epilogue are not in the critical path.
+
+- the main containers (fshash, schedhash, ...) are protected by
+ UH_WLOCK.
+
+Packet processing
+=================
+A packet enters dummynet through dummynet_io(). We first lookup
+the flowset number in fshash using dn_ht_find(), then find the scheduler
+instance using ipdn_si_find(), then possibly identify the correct
+queue with ipdn_q_find().
+If successful, we call the scheduler's enqueue function(), and
+if needed start I/O on the link calling serve_sched().
+If the packet can be returned immediately, this is done by
+leaving *m0 set. Otherwise, the packet is absorbed by dummynet
+and we simply return, possibly with some appropriate error code.
+
+Reconfiguration
+---------------
+Reconfiguration is the complex part of the system because we need to
+keep track of the various objects and containers.
+At the moment we do not use reference counts for objects so all
+processing must be done under a lock.
+
+The main entry points for configuration is the ip_dn_ctl() handler
+for the IP_DUMMYNET3 sockopt (others are provided only for backward
+compatibility). Modifications to the configuration call do_config().
+The argument is a sequence of blocks each starting with a struct dn_id
+which specifies its content.
+The first dn_id must contain as obj.id the DN_API_VERSION
+The obj.type is DN_CMD_CONFIG (followed by actual objects),
+DN_CMD_DELETE (with the correct subtype and list of objects), or
+DN_CMD_FLUSH.
+
+DN_CMD_CONFIG is followed by objects to add/reconfigure. In general,
+if an object already exists it is reconfigured, otherwise it is
+created in a way that keeps the structure consistent.
+We have the following objects in the system, normally numbered with
+an identifier N between 1 and 65535. For certain objects we have
+"shadow" copies numbered I+NMAX and I+ 2*NMAX which are used to
+implement certain backward compatibility features.
+
+In general we have the following linking
+
+ TRADITIONAL DUMMYNET QUEUES "queue N config ... pipe M ..."
+ corresponds to a dn_fs object numbered N
+
+ TRADITIONAL DUMMYNET PIPES "pipe N config ..."
+ dn_fs N+2*NMAX --> dn_sch N+NMAX type FIFO --> dn_link N+NMAX
+
+ GENERIC SCHEDULER "sched N config ... "
+ [dn_fs N+NMAX] --> dn_sch N --> dn_link N
+ The flowset N+NMAX is created only if the scheduler is not
+ of type MULTIQUEUE.
+
+ DELAY PROFILE "pipe N config profile ..."
+ it is always attached to an existing dn_link N
+
+Because traditional dummynet pipes actually configure both a
+'standalone' instance and one that can be used by queues,
+we do the following:
+
+ "pipe N config ..." configures:
+ dn_sched N type WF2Q+
+ dn_sched N+NMAX type FIFO
+ dn_fs N+2NMAX attached to dn_sched N+NMAX
+ dn_pipe N
+ dn_pipe N+NMAX
+
+ "queue N config" configures
+ dn_fs N
+
+ "sched N config" configures
+ dn_sched N type as desired
+ dn_fs N+NMAX attached to dn_sched N
+
+
+dummynet_task()
+===============
+The dummynet_task() function is the main dummynet processing function and is
+called every tick. This function first calculate the new current time, then
+it checks if it is the time to wake up object from the system_heap comparing
+the current time and the key of the heap. Two types of object (really the
+heap contains pointer to objects) are in the
+system_heap:
+
+- scheduler instance: if a scheduler instance is waked up, the dequeue()
+ function is called until it has credit. If the dequeue() returns packets,
+ the scheduler instance is inserted in the heap with a new key depending of
+ the data that will be send out. If the scheduler instance remains with
+ some credit, it means that is hasn't other packet to send and so the
+ instance is no longer inserted in the heap.
+
+ If the scheduler instance extracted from the heap has the DELETE flag set,
+ the dequeue() is not called and the instance is destroyed now.
+
+- delay line: when extracting a delay line, the function transmit_event() is
+ called to send out packet from delay line.
+
+ If the scheduler instance associated with this delay line doesn't exists,
+ the delay line will be delete now.
+
+Configuration
+=============
+To create a pipe, queue or scheduler, the user should type commands like:
+"ipfw pipe x config"
+"ipfw queue y config pipe x"
+"ipfw pipe x config sched <type>"
+
+The userland side of dummynet will prepare a buffer contains data to pass to
+kernel side.
+The buffer contains all struct needed to configure an object. In more detail,
+to configure a pipe all three structs (dn_link, dn_sch, dn_fs) are needed,
+plus the delay profile struct if the pipe has a delay profile.
+
+If configuring a scheduler only the struct dn_sch is wrote in the buffer,
+while if configuring a flowset only the dn_fs struct is wrote.
+
+The first struct in the buffer contains the type of command request, that is
+if it is configuring a pipe, a queue, or a scheduler. Then there are structs
+need to configure the object, and finally there is the struct that mark
+the end of the buffer.
+
+To support the insertion of pipe and queue using the old syntax, when adding
+a pipe it's necessary to create a FIFO flowset and a FIFO scheduler, which
+have a number x + DN_PIPEOFFSET.
+
+Add a pipe
+----------
+A pipe is only a template for a link.
+If the pipe already exists, parameters are updated. If a delay profile exists
+it is deleted and a new one is created.
+If the pipe doesn't exist a new one is created. After the creation, the
+flowset unlinked list is scanned to see if there are some flowset that would
+be linked with this pipe. If so, these flowset will be of wf2q+ type (for
+compatibility) and a new wf2q+ scheduler is created now.
+
+Add a scheduler
+---------------
+If the scheduler already exists, and the type and the mask are the same, the
+scheduler is simply reconfigured calling the config_scheduler() scheduler
+function with the RECONFIGURE flag active.
+If the type or the mask differ, it is necessary to delete the old scheduler
+and create a new one.
+If the scheduler doesn't exists, a new one is created. If the scheduler has
+a mask, the hash table is created to store pointers to scheduler instances.
+When a new scheduler is created, it is necessary to scan the unlinked
+flowset list to search eventually flowset that would be linked with this
+scheduler number. If some are found, flowsets became of the type of this
+scheduler and they are configured properly.
+
+Add a flowset
+-------------
+Flowset pointers are store in the system in two list. The unlinked flowset list
+contains all flowset that aren't linked with a scheduler, the flowset list
+contains flowset linked to a scheduler, and so they have a type.
+When adding a new flowset, first it is checked if the flowset exists (that is,
+it is in the flowset list) and if it doesn't exists a new flowset is created
+and added to unlinked flowset list if the scheduler which the flowset would be
+linked doesn't exists, or added in the flowset list and configured properly if
+the scheduler exists. If the flowset (before to be created) was in the
+unlinked flowset list, it is removed and deleted, and then recreated.
+If the flowset exists, to allow reconfiguration of this flowset, the
+scheduler number and types must match with the one in memory. If this isn't
+so, the flowset is deleted and a new one will be created. Really, the flowset
+it isn't deleted now, but it is removed from flowset list and it will be
+deleted later because there could be some queues that are using it.
+
+Listing of object
+=================
+The user can request a list of object present in dummynet through the command
+"ipfw [-v] pipe|queue [x] list|show"
+The kernel side of dummynet send a buffer to user side that contains all
+pipe, all scheduler, all flowset, plus all scheduler instances and all queues.
+The dummynet user land will format the output and show only the relevant
+information.
+The buffer sent start with all pipe from the system. The entire struct dn_link
+is passed, except the delay_profile struct that is useless in user space.
+After pipes, all flowset are wrote in the buffer. The struct contains
+scheduler flowset specific data is linked with the flowset writing the
+'obj' id of the extension into the 'alg_fs' pointer.
+Then schedulers are wrote. If a scheduler has one or more scheduler instance,
+these are linked to the parent scheduler writing the id of the parent in the
+'ptr_sched' pointer. If a scheduler instance has queues, there are wrote in
+the buffer and linked thorugh the 'obj' and 'sched_inst' pointer.
+Finally, flowsets in the unlinked flowset list are write in the buffer, and
+then a struct gen in saved in the buffer to mark the last struct in the buffer.
+
+
+Delete of object
+================
+An object is usually removed by user through a command like
+"ipfw pipe|queue x delete". XXX sched?
+ipfw pass to the kernel a struct gen that contains the type and the number
+of the object to remove
+
+Delete of pipe x
+----------------
+A pipe can be deleted by the user throught the command 'ipfw pipe x delete'.
+To delete a pipe, the pipe is removed from the pipe list, and then deleted.
+Also the scheduler associated with this pipe should be deleted.
+For compatibility with old dummynet syntax, the associated FIFO scheduler and
+FIFO flowset must be deleted.
+
+Delete of flowset x
+-------------------
+To remove a flowset, we must be sure that is no loger referenced by any object.
+If the flowset to remove is in the unlinked flowset list, there is not any
+issue, the flowset can be safely removed calling a free() (the flowset
+extension is not yet created if the flowset is in this list).
+If the flowset is in the flowset list, first we remove from it so new packet
+are discarded when arrive. Next, the flowset is marked as delete.
+Now we must check if some queue is using this flowset.
+To do this, a counter (active_f) is provided. This counter indicate how many
+queues exist using this flowset.
+The active_f counter is automatically incremented when a queue is created
+and decremented when a queue is deleted.
+If the counter is 0, the flowset can be safely deleted, and the delete_alg_fs()
+scheduler function is called before deallocate memory.
+If the counter is not 0, the flowset remain in memory until the counter become
+zero. When a queue is delete (by dn_delete_queue() function) it is checked if
+the linked flowset is deleting and if so the counter is decrementing. If the
+counter reaches 0, the flowset is deleted.
+The deletion of a queue can be done only by the scheduler, or when the scheduler
+is destroyed.
+
+Delete of scheduler x
+---------------------
+To delete a scheduler we must be sure that any scheduler instance of this type
+are in the system_heap. To do so, a counter (inst_counter) is provided.
+This counter is managed by the system: it is incremented every time it is
+inserted in the system_heap, and decremented every time it is extracted from it.
+To delete the scheduler, first we remove it from the scheduler list, so new
+packet are discarded when they arrive, and mark the scheduler as deleting.
+
+If the counter is 0, we can remove the scheduler safely calling the
+really_deletescheduler() function. This function will scan all scheduler
+instances and call the delete_scheduler_instance() function that will delete
+the instance. When all instance are deleted, the scheduler template is
+deleted calling the delete_scheduler_template(). If the delay line associate
+with the scheduler is empty, it is deleted now, else it will be deleted when
+it will became empy.
+If the counter was not 0, we wait for it. Every time the dummynet_task()
+function extract a scheduler from the system_heap, the counter is decremented.
+If the scheduler has the delete flag enabled the dequeue() is not called and
+delete_scheduler_instance() is called to delete the instance.
+Obviously this scheduler instance is no loger inserted in the system_heap.
+If the counter reaches 0, the delete_scheduler_template() function is called
+all memory is released.
+NOTE: Flowsets that belong to this scheduler are not deleted, so if a new
+ scheduler with the same number is inserted will use these flowsets.
+ To do so, the best approach would be insert these flowset in the
+ unlinked flowset list, but doing this now will be very expensive.
+ So flowsets will remain in memory and linked with a scheduler that no
+ longer exists until a packet belonging to this flowset arrives. When
+ this packet arrives, the reconfigure() function is called because the
+ generation number mismatch with one contains in the flowset and so
+ the flowset will be moved into the flowset unlinked list, or will be
+ linked with the new scheduler if a new one was created.
+
+
+COMPATIBILITY WITH FREEBSD 7.2 AND FREEBSD 8 'IPFW' BINARY
+==========================================================
+Dummynet is not compatible with old ipfw binary because internal structs are
+changed. Moreover, the old ipfw binary is not compatible with new kernels
+because the struct that represents a firewall rule has changed. So, if a user
+install a new kernel on a FreeBSD 7.2, the ipfw (and possibly many other
+commands) will not work.
+New dummynet uses a new socket option: IP_DUMMYNET3, used for both set and get.
+The old option can be used to allow compatibility with the 'ipfw' binary of
+older version (tested with 7.2 and 8.0) of FreeBSD.
+Two file are provided for this purpose:
+- ip_dummynet_glue.c translates old dummynet requests to the new ones,
+- ip_fw_glue.c converts the rule format between 7.2 and 8 versions.
+Let see in detail these two files.
+
+IP_DUMMYNET_GLUE.C
+------------------
+The internal structs of new dummynet are very different from the original.
+Because of there are some difference from between dummynet in FreeBSD 7.2 and
+dummynet in FreeBSD 8 (the FreeBSD 8 version includes support to pipe delay
+profile and burst option), I have to include both header files. I copied
+the revision 191715 (for version 7.2) and the revision 196045 (for version 8)
+and I appended a number to each struct to mark them.
+
+The main function of this file is ip_dummynet_compat() that is called by
+ip_dn_ctl() when it receive a request of old socket option.
+
+A global variabile ('is7') store the version of 'ipfw' that FreeBSD is using.
+This variable is set every time a request of configuration is done, because
+with this request we receive a buffer of which size depending of ipfw version.
+Because of in general the first action is a configuration, this variable is
+usually set accordly. If the first action is a request of listing of pipes
+or queues, the system cannot know the version of ipfw, and we suppose that
+version 7.2 is used. If version is wrong, the output can be senseless, but
+the application should not crash.
+
+There are four request for old dummynet:
+- IP_DUMMYNET_FLUSH: the flush options have no parameter, so simply the
+ dummynet_flush() function is called;
+- IP_DUMMYNET_DEL: the delete option need to be translate.
+ It is only necessary to extract the number and the type of the object
+ (pipe or queue) to delete from the buffer received and build a new struct
+ gen contains the right parameters, then call the delete_object() function;
+- IP_DUMMYNET_CONFIGURE: the configure command receive a buffer depending of
+ the ipfw version. After the properly extraction of all data, that depends
+ by the ipfw version used, new structures are filled and then the dummynet
+ config_link() function is properly called. Note that the 7.2 version does
+ not support some parameter as burst or delay profile.
+- IP_DUMMYNET_GET: The get command should send to the ipfw the correct buffer
+ depending of its version. There are two function that build the
+ corrected buffer, ip_dummynet_get7() and ip_dummynet_get8(). These
+ functions reproduce the buffer exactly as 'ipfw' expect. The only difference
+ is that the weight parameter for a queue is no loger sent by dummynet and so
+ it is set to 0.
+ Moreover, because of the internal structure has changed, the bucket size
+ of a queue could not be correct, because now all flowset share the hash
+ table.
+ If the version of ipfw is wrong, the output could be senseless or truncated,
+ but the application should not crash.
+
+IP_FW_GLUE.C
+------------
+The ipfw binary also is used to add rules to FreeBSD firewall. Because of the
+struct ip_fw is changed from FreeBsd 7.2 to FreeBSD 8, it is necessary
+to write some glue code to allow use ipfw from FreeBSD 7.2 with the kernel
+provided with FreeBSD 8.
+This file contains two functions to convert a rule from FreeBSD 7.2 format to
+FreeBSD 8 format, and viceversa.
+The conversion should be done when a rule passes from userspace to kernel space
+and viceversa.
+I have to modify the ip_fw2.c file to manage these two case, and added a
+variable (is7) to store the ipfw version used, using an approach like the
+previous file:
+- when a new rule is added (option IP_FW_ADD) the is7 variable is set if the
+ size of the rule received corrispond to FreeBSD 7.2 ipfw version. If so, the
+ rule is converted to version 8 calling the function convert_rule_to_8().
+ Moreover, after the insertion of the rule, the rule is now reconverted to
+ version 7 because the ipfw binary will print it.
+- when the user request a list of rules (option IP_FW_GET) the is7 variable
+ should be set correctly because we suppose that a configure command was done,
+ else we suppose that the FreeBSD version is 8. The function ipfw_getrules()
+ in ip_fw2.c file return all rules, eventually converted to version 7 (if
+ the is7 is set) to the ipfw binary.
+The conversion of a rule is quite simple. The only difference between the
+two structures (struct ip_fw) is that in the new there is a new field
+(uint32_t id). So, I copy the entire rule in a buffer and the copy the rule in
+the right position in the new (or old) struct. The size of commands are not
+changed, and the copy is done into a cicle.
+
+How to configure dummynet
+=========================
+It is possible to configure dummynet through two main commands:
+'ipfw pipe' and 'ipfw queue'.
+To allow compatibility with old version, it is possible configure dummynet
+using the old command syntax. Doing so, obviously, it is only possible to
+configure a FIFO scheduler or a wf2q+ scheduler.
+A new command, 'ipfw pipe x config sched <type>' is supported to add a new
+scheduler to the system.
+
+- ipfw pipe x config ...
+ create a new pipe with the link parameters
+ create a new scheduler fifo (x + offset)
+ create a new flowset fifo (x + offset)
+ the mask is eventually stored in the FIFO scheduler
+
+- ipfw queue y config pipe x ...
+ create a new flowset y linked to sched x.
+ The type of flowset depends by the specified scheduler.
+ If the scheduler does not exist, this flowset is inserted in a special
+ list and will be not active.
+ If pipe x exists and sched does not exist, a new wf2q+ scheduler is
+ created and the flowset will be linked to this new scheduler (this is
+ done for compatibility with old syntax).
+
+- ipfw pipe x config sched <type> ...
+ create a new scheduler x of type <type>.
+ Search into the flowset unlinked list if there are some flowset that
+ should be linked with this new scheduler.
+
+- ipfw pipe x delete
+ delete the pipe x
+ delete the scheduler fifo (x + offset)
+ delete the scheduler x
+ delete the flowset fifo (x + offset)
+
+- ipfw queue x delete
+ delete the flowset x
+
+- ipfw sched x delete ///XXX
+ delete the scheduler x
+
+Follow now some examples to how configure dummynet:
+- Ex1:
+ ipfw pipe 10 config bw 1M delay 15 // create a pipe with band and delay
+ A FIFO flowset and scheduler is
+ also created
+ ipfw queue 5 config pipe 10 weight 56 // create a flowset. This flowset
+ will be of wf2q+ because a pipe 10
+ exists. Moreover, the wf2q+
+ scheduler is created now.
+- Ex2:
+ ipfw queue 5 config pipe 10 weight 56 // Create a flowset. Scheduler 10
+ does not exist, so this flowset
+ is inserted in the unlinked
+ flowset list.
+ ipfw pipe 10 config bw... // Create a pipe, a FIFO flowset and scheduler.
+ Because of a flowset with 'pipe 10' exists,
+ a wf2q+ scheduler is created now and that
+ flowset is linked with this sceduler.
+
+- Ex3:
+ ipfw pipe 10 config bw... // Create a pipe, a FIFO flowset and scheduler.
+ ipfw pipe 10 config sched rr // Create a scheduler of type RR, linked to
+ pipe 10
+ ipfw queue 5 config pipe 10 weight 56 // Create a flowset 5. This flowset
+ will belong to scheduler 10 and
+ it is of type RR
+
+- Ex4:
+ ipfw pipe 10 config sched rr // Create a scheduler of type RR, linked to
+ pipe 10 (not exist yet)
+ ipfw pipe 10 config bw... // Create a pipe, a FIFO flowset and scheduler.
+ ipfw queue 5 config pipe 10 weight 56 // Create a flowset 5.This flowset
+ will belong to scheduler 10 and
+ it is of type RR
+ ipfw pipe 10 config sched wf2q+ // Modify the type of scheduler 10. It
+ becomes a wf2q+ scheduler.
+ When a new packet of flowset 5 arrives,
+ the flowset 5 becomes to wf2q+ type.
+
+How to implement a new scheduler
+================================
+In dummynet, a scheduler algorithm is represented by two main structs, some
+functions and other minor structs.
+- A struct dn_sch_xyz (where xyz is the 'type' of scheduler algorithm
+ implemented) contains data relative to scheduler, as global parameter that
+ are common to all instances of the scheduler
+- A struct dn_sch_inst_xyz contains data relative to a single scheduler
+ instance, as local status variable depending for example by flows that
+ are linked with the scheduler, and so on.
+To add a scheduler to dummynet, the user should type a command like:
+'ipfw pipe x config sched <type> [mask ... ...]'
+This command creates a new struct dn_sch_xyz of type <type>, and
+store the optional parameter in that struct.
+
+The parameter mask determines how many scheduler instance of this
+scheduler may exist. For example, it is possible to divide traffic
+depending on the source port (or destination, or ip address...),
+so that every scheduler instance act as an independent scheduler.
+If the mask is not set, all traffic goes to the same instance.
+
+When a packet arrives to a scheduler, the system search the corrected
+scheduler instance, and if it does not exist it is created now (the
+struct dn_sch_inst_xyz is allocated by the system, and the scheduler
+fills the field correctly). It is a task of the scheduler to create
+the struct that contains all queues for a scheduler instance.
+Dummynet provides some function to create an hash table to store
+queues, but the schedule algorithm can choice the own struct.
+
+To link a flow to a scheduler, the user should type a command like:
+'ipfw queue z config pipe x [mask... ...]'
+
+This command creates a new 'dn_fs' struct that will be inserted
+in the system. If the scheduler x exists, this flowset will be
+linked to that scheduler and the flowset type become the same as
+the scheduler type. At this point, the function create_alg_fs_xyz()
+is called to allow store eventually parameter for the flowset that
+depend by scheduler (for example the 'weight' parameter for a wf2q+
+scheduler, or some priority...). A parameter mask can be used for
+a flowset. If the mask parameter is set, the scheduler instance can
+separate packet according to its flow id (src and dst ip, ports...)
+and assign it to a separate queue. This is done by the scheduler,
+so it can ignore the mask if it wants.
+
+See now the two main structs:
+struct dn_sch_xyz {
+ struct gen g; /* important the name g */
+ /* global params */
+};
+struct dn_sch_inst_xyz {
+ struct gen g; /* important the name g */
+ /* params of the instance */
+};
+It is important to embed the struct gen as first parameter. The struct gen
+contains some values that the scheduler instance must fill (the 'type' of
+scheduler, the 'len' of the struct...)
+The function create_scheduler_xyz() should be implemented to initialize global
+parameters in the first struct, and if memory allocation is done it is
+mandatory to implement the delete_scheduler_template() function to free that
+memory.
+The function create_scheduler_instance_xyz() must be implemented even if the
+scheduler instance does not use extra parameters. In this function the struct
+gen fields must be filled with corrected infos. The
+delete_scheduler_instance_xyz() function must bu implemented if the instance
+has allocated some memory in the previous function.
+
+To store data belonging to a flowset the follow struct is used:
+struct alg_fs_xyz {
+ struct gen g;
+ /* fill correctly the gen struct
+ g.subtype = DN_XYZ;
+ g.len = sizeof(struct alg_fs_xyz)
+ ...
+ */
+ /* params for the flow */
+};
+The create_alg_fs_xyz() function is mandatory, because it must fill the struct
+gen, but the delete_alg_fs_xyz() is mandatory only if the previous function
+has allocated some memory.
+
+A struct dn_queue contains packets belonging to a queue and some statistical
+data. The scheduler could have to store data in this struct, so it must define
+a dn_queue_xyz struct:
+struct dn_queue_xyz {
+ struct dn_queue q;
+ /* parameter for a queue */
+}
+
+All structures are allocated by the system. To do so, the scheduler must
+set the size of its structs in the scheduler descriptor:
+scheduler_size: sizeof(dn_sch_xyz)
+scheduler_i_size: sizeof(dn_sch_inst_xyz)
+flowset_size: sizeof(alg_fs_xyz)
+queue_size: sizeof(dn_queue_xyz);
+The scheduler_size could be 0, but other struct must have at least a struct gen.
+
+
+After the definition of structs, it is necessary to implement the
+scheduler functions.
+
+- int (*config_scheduler)(char *command, void *sch, int reconfigure);
+ Configure a scheduler, or reconfigure if 'reconfigure' == 1.
+ This function performs additional allocation and initialization of global
+ parameter for this scheduler.
+ If memory is allocated here, the delete_scheduler_template() function
+ should be implemented to remove this memory.
+- int (*delete_scheduler_template)(void* sch);
+ Delete a scheduler template. This function is mandatory if the scheduler
+ uses extra data respect the struct dn_sch.
+- int (*create_scheduler_instance)(void *s);
+ Create a new scheduler instance. The system allocate the necessary memory
+ and the schedulet can access it using the 's' pointer.
+ The scheduler instance stores all queues, and to do this can use the
+ hash table provided by the system.
+- int (*delete_scheduler_instance)(void *s);
+ Delete a scheduler instance. It is important to free memory allocated
+ by create_scheduler_instance() function. The memory allocated by system
+ is freed by the system itself. The struct contains all queue also has
+ to be deleted.
+- int (*enqueue)(void *s, struct gen *f, struct mbuf *m,
+ struct ipfw_flow_id *id);
+ Called when a packet arrives. The packet 'm' belongs to the scheduler
+ instance 's', has a flowset 'f' and the flowid 'id' has already been
+ masked. The enqueue() must call dn_queue_packet(q, m) function to really
+ enqueue packet in the queue q. The queue 'q' is chosen by the scheduler
+ and if it does not exist should be created calling the dn_create_queue()
+ function. If the schedule want to drop the packet, it must call the
+ dn_drop_packet() function and then return 1.
+- struct mbuf * (*dequeue)(void *s);
+ Called when the timer expires (or when a packet arrives and the scheduler
+ instance is idle).
+ This function is called when at least a packet can be send out. The
+ scheduler choices the packet and returns it; if no packet are in the
+ schedulerinstance, the function must return NULL.
+ Before return a packet, it is important to call the function
+ dn_return_packet() to update some statistic of the queue and update the
+ queue counters.
+- int (*drain_queue)(void *s, int flag);
+ The system request to scheduler to delete all queues that is not using
+ to free memory. The flag parameter indicate if a queue must be deleted
+ even if it is active.
+
+- int (*create_alg_fs)(char *command, struct gen *g, int reconfigure);
+ It is called when a flowset is linked with a scheduler. This is done
+ when the scheduler is defined, so we can know the type of flowset.
+ The function initialize the flowset paramenter parsing the command
+ line. The parameter will be stored in the g struct that have the right
+ size allocated by the system. If the reconfigure flag is set, it means
+ that the flowset is reconfiguring
+- int (*delete_alg_fs)(struct gen *f);
+ It is called when a flowset is deleting. Must remove the memory allocate
+ by the create_alg_fs() function.
+
+- int (*create_queue_alg)(struct dn_queue *q, struct gen *f);
+ Called when a queue is created. The function should link the queue
+ to the struct used by the scheduler instance to store all queues.
+- int (*delete_queue_alg)(struct dn_queue *q);
+ Called when a queue is deleting. The function should remove extra data
+ and update the struct contains all queues in the scheduler instance.
+
+The struct scheduler represent the scheduler descriptor that is passed to
+dummynet when a scheduler module is loaded.
+This struct contains the type of scheduler, the lenght of all structs and
+all function pointers.
+If a function is not implemented should be initialize to NULL. Some functions
+are mandatory, other are mandatory if some memory should be freed.
+Mandatory functions:
+- create_scheduler_instance()
+- enqueue()
+- dequeue()
+- create_alg_fs()
+- drain_queue()
+Optional functions:
+- config_scheduler()
+- create_queue_alg()
+Mandatory functions if the corresponding create...() has allocated memory:
+- delete_scheduler_template()
+- delete_scheduler_instance()
+- delete_alg_fs()
+- delete_queue_alg()
+
diff --git a/sys/netinet/ipfw/ip_dn_glue.c b/sys/netinet/ipfw/ip_dn_glue.c
new file mode 100644
index 0000000..9fc6b23
--- /dev/null
+++ b/sys/netinet/ipfw/ip_dn_glue.c
@@ -0,0 +1,845 @@
+/*-
+ * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * $FreeBSD$
+ *
+ * Binary compatibility support for /sbin/ipfw RELENG_7 and RELENG_8
+ */
+
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/time.h>
+#include <sys/taskqueue.h>
+#include <net/if.h> /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ip_output(), IP_FORWARDING */
+#include <netinet/ip_fw.h>
+#include <netinet/ipfw/ip_fw_private.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+
+/* FREEBSD7.2 ip_dummynet.h r191715*/
+
+struct dn_heap_entry7 {
+ int64_t key; /* sorting key. Topmost element is smallest one */
+ void *object; /* object pointer */
+};
+
+struct dn_heap7 {
+ int size;
+ int elements;
+ int offset; /* XXX if > 0 this is the offset of direct ptr to obj */
+ struct dn_heap_entry7 *p; /* really an array of "size" entries */
+};
+
+/* Common to 7.2 and 8 */
+struct dn_flow_set {
+ SLIST_ENTRY(dn_flow_set) next; /* linked list in a hash slot */
+
+ u_short fs_nr ; /* flow_set number */
+ u_short flags_fs;
+#define DNOLD_HAVE_FLOW_MASK 0x0001
+#define DNOLD_IS_RED 0x0002
+#define DNOLD_IS_GENTLE_RED 0x0004
+#define DNOLD_QSIZE_IS_BYTES 0x0008 /* queue size is measured in bytes */
+#define DNOLD_NOERROR 0x0010 /* do not report ENOBUFS on drops */
+#define DNOLD_HAS_PROFILE 0x0020 /* the pipe has a delay profile. */
+#define DNOLD_IS_PIPE 0x4000
+#define DNOLD_IS_QUEUE 0x8000
+
+ struct dn_pipe7 *pipe ; /* pointer to parent pipe */
+ u_short parent_nr ; /* parent pipe#, 0 if local to a pipe */
+
+ int weight ; /* WFQ queue weight */
+ int qsize ; /* queue size in slots or bytes */
+ int plr ; /* pkt loss rate (2^31-1 means 100%) */
+
+ struct ipfw_flow_id flow_mask ;
+
+ /* hash table of queues onto this flow_set */
+ int rq_size ; /* number of slots */
+ int rq_elements ; /* active elements */
+ struct dn_flow_queue7 **rq; /* array of rq_size entries */
+
+ u_int32_t last_expired ; /* do not expire too frequently */
+ int backlogged ; /* #active queues for this flowset */
+
+ /* RED parameters */
+#define SCALE_RED 16
+#define SCALE(x) ( (x) << SCALE_RED )
+#define SCALE_VAL(x) ( (x) >> SCALE_RED )
+#define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED )
+ int w_q ; /* queue weight (scaled) */
+ int max_th ; /* maximum threshold for queue (scaled) */
+ int min_th ; /* minimum threshold for queue (scaled) */
+ int max_p ; /* maximum value for p_b (scaled) */
+ u_int c_1 ; /* max_p/(max_th-min_th) (scaled) */
+ u_int c_2 ; /* max_p*min_th/(max_th-min_th) (scaled) */
+ u_int c_3 ; /* for GRED, (1-max_p)/max_th (scaled) */
+ u_int c_4 ; /* for GRED, 1 - 2*max_p (scaled) */
+ u_int * w_q_lookup ; /* lookup table for computing (1-w_q)^t */
+ u_int lookup_depth ; /* depth of lookup table */
+ int lookup_step ; /* granularity inside the lookup table */
+ int lookup_weight ; /* equal to (1-w_q)^t / (1-w_q)^(t+1) */
+ int avg_pkt_size ; /* medium packet size */
+ int max_pkt_size ; /* max packet size */
+};
+SLIST_HEAD(dn_flow_set_head, dn_flow_set);
+
+#define DN_IS_PIPE 0x4000
+#define DN_IS_QUEUE 0x8000
+struct dn_flow_queue7 {
+ struct dn_flow_queue7 *next ;
+ struct ipfw_flow_id id ;
+
+ struct mbuf *head, *tail ; /* queue of packets */
+ u_int len ;
+ u_int len_bytes ;
+
+ u_long numbytes;
+
+ u_int64_t tot_pkts ; /* statistics counters */
+ u_int64_t tot_bytes ;
+ u_int32_t drops ;
+
+ int hash_slot ; /* debugging/diagnostic */
+
+ /* RED parameters */
+ int avg ; /* average queue length est. (scaled) */
+ int count ; /* arrivals since last RED drop */
+ int random ; /* random value (scaled) */
+ u_int32_t q_time; /* start of queue idle time */
+
+ /* WF2Q+ support */
+ struct dn_flow_set *fs ; /* parent flow set */
+ int heap_pos ; /* position (index) of struct in heap */
+ int64_t sched_time ; /* current time when queue enters ready_heap */
+
+ int64_t S,F ; /* start time, finish time */
+};
+
+struct dn_pipe7 { /* a pipe */
+ SLIST_ENTRY(dn_pipe7) next; /* linked list in a hash slot */
+
+ int pipe_nr ; /* number */
+ int bandwidth; /* really, bytes/tick. */
+ int delay ; /* really, ticks */
+
+ struct mbuf *head, *tail ; /* packets in delay line */
+
+ /* WF2Q+ */
+ struct dn_heap7 scheduler_heap ; /* top extract - key Finish time*/
+ struct dn_heap7 not_eligible_heap; /* top extract- key Start time */
+ struct dn_heap7 idle_heap ; /* random extract - key Start=Finish time */
+
+ int64_t V ; /* virtual time */
+ int sum; /* sum of weights of all active sessions */
+
+ int numbytes;
+
+ int64_t sched_time ; /* time pipe was scheduled in ready_heap */
+
+ /*
+ * When the tx clock come from an interface (if_name[0] != '\0'), its name
+ * is stored below, whereas the ifp is filled when the rule is configured.
+ */
+ char if_name[IFNAMSIZ];
+ struct ifnet *ifp ;
+ int ready ; /* set if ifp != NULL and we got a signal from it */
+
+ struct dn_flow_set fs ; /* used with fixed-rate flows */
+};
+SLIST_HEAD(dn_pipe_head7, dn_pipe7);
+
+
+/* FREEBSD8 ip_dummynet.h r196045 */
+struct dn_flow_queue8 {
+ struct dn_flow_queue8 *next ;
+ struct ipfw_flow_id id ;
+
+ struct mbuf *head, *tail ; /* queue of packets */
+ u_int len ;
+ u_int len_bytes ;
+
+ uint64_t numbytes ; /* credit for transmission (dynamic queues) */
+ int64_t extra_bits; /* extra bits simulating unavailable channel */
+
+ u_int64_t tot_pkts ; /* statistics counters */
+ u_int64_t tot_bytes ;
+ u_int32_t drops ;
+
+ int hash_slot ; /* debugging/diagnostic */
+
+ /* RED parameters */
+ int avg ; /* average queue length est. (scaled) */
+ int count ; /* arrivals since last RED drop */
+ int random ; /* random value (scaled) */
+ int64_t idle_time; /* start of queue idle time */
+
+ /* WF2Q+ support */
+ struct dn_flow_set *fs ; /* parent flow set */
+ int heap_pos ; /* position (index) of struct in heap */
+ int64_t sched_time ; /* current time when queue enters ready_heap */
+
+ int64_t S,F ; /* start time, finish time */
+};
+
+struct dn_pipe8 { /* a pipe */
+ SLIST_ENTRY(dn_pipe8) next; /* linked list in a hash slot */
+
+ int pipe_nr ; /* number */
+ int bandwidth; /* really, bytes/tick. */
+ int delay ; /* really, ticks */
+
+ struct mbuf *head, *tail ; /* packets in delay line */
+
+ /* WF2Q+ */
+ struct dn_heap7 scheduler_heap ; /* top extract - key Finish time*/
+ struct dn_heap7 not_eligible_heap; /* top extract- key Start time */
+ struct dn_heap7 idle_heap ; /* random extract - key Start=Finish time */
+
+ int64_t V ; /* virtual time */
+ int sum; /* sum of weights of all active sessions */
+
+ /* Same as in dn_flow_queue, numbytes can become large */
+ int64_t numbytes; /* bits I can transmit (more or less). */
+ uint64_t burst; /* burst size, scaled: bits * hz */
+
+ int64_t sched_time ; /* time pipe was scheduled in ready_heap */
+ int64_t idle_time; /* start of pipe idle time */
+
+ char if_name[IFNAMSIZ];
+ struct ifnet *ifp ;
+ int ready ; /* set if ifp != NULL and we got a signal from it */
+
+ struct dn_flow_set fs ; /* used with fixed-rate flows */
+
+ /* fields to simulate a delay profile */
+#define ED_MAX_NAME_LEN 32
+ char name[ED_MAX_NAME_LEN];
+ int loss_level;
+ int samples_no;
+ int *samples;
+};
+
+#define ED_MAX_SAMPLES_NO 1024
+struct dn_pipe_max8 {
+ struct dn_pipe8 pipe;
+ int samples[ED_MAX_SAMPLES_NO];
+};
+SLIST_HEAD(dn_pipe_head8, dn_pipe8);
+
+/*
+ * Changes from 7.2 to 8:
+ * dn_pipe:
+ * numbytes from int to int64_t
+ * add burst (int64_t)
+ * add idle_time (int64_t)
+ * add profile
+ * add struct dn_pipe_max
+ * add flag DN_HAS_PROFILE
+ *
+ * dn_flow_queue
+ * numbytes from u_long to int64_t
+ * add extra_bits (int64_t)
+ * q_time from u_int32_t to int64_t and name idle_time
+ *
+ * dn_flow_set unchanged
+ *
+ */
+
+/* NOTE:XXX copied from dummynet.c */
+#define O_NEXT(p, len) ((void *)((char *)p + len))
+static void
+oid_fill(struct dn_id *oid, int len, int type, uintptr_t id)
+{
+ oid->len = len;
+ oid->type = type;
+ oid->subtype = 0;
+ oid->id = id;
+}
+/* make room in the buffer and move the pointer forward */
+static void *
+o_next(struct dn_id **o, int len, int type)
+{
+ struct dn_id *ret = *o;
+ oid_fill(ret, len, type, 0);
+ *o = O_NEXT(*o, len);
+ return ret;
+}
+
+
+static size_t pipesize7 = sizeof(struct dn_pipe7);
+static size_t pipesize8 = sizeof(struct dn_pipe8);
+static size_t pipesizemax8 = sizeof(struct dn_pipe_max8);
+
+/* Indicate 'ipfw' version
+ * 1: from FreeBSD 7.2
+ * 0: from FreeBSD 8
+ * -1: unknow (for now is unused)
+ *
+ * It is update when a IP_DUMMYNET_DEL or IP_DUMMYNET_CONFIGURE request arrives
+ * NOTE: if a IP_DUMMYNET_GET arrives and the 'ipfw' version is unknow,
+ * it is suppose to be the FreeBSD 8 version.
+ */
+static int is7 = 0;
+
+static int
+convertflags2new(int src)
+{
+ int dst = 0;
+
+ if (src & DNOLD_HAVE_FLOW_MASK)
+ dst |= DN_HAVE_MASK;
+ if (src & DNOLD_QSIZE_IS_BYTES)
+ dst |= DN_QSIZE_BYTES;
+ if (src & DNOLD_NOERROR)
+ dst |= DN_NOERROR;
+ if (src & DNOLD_IS_RED)
+ dst |= DN_IS_RED;
+ if (src & DNOLD_IS_GENTLE_RED)
+ dst |= DN_IS_GENTLE_RED;
+ if (src & DNOLD_HAS_PROFILE)
+ dst |= DN_HAS_PROFILE;
+
+ return dst;
+}
+
+static int
+convertflags2old(int src)
+{
+ int dst = 0;
+
+ if (src & DN_HAVE_MASK)
+ dst |= DNOLD_HAVE_FLOW_MASK;
+ if (src & DN_IS_RED)
+ dst |= DNOLD_IS_RED;
+ if (src & DN_IS_GENTLE_RED)
+ dst |= DNOLD_IS_GENTLE_RED;
+ if (src & DN_NOERROR)
+ dst |= DNOLD_NOERROR;
+ if (src & DN_HAS_PROFILE)
+ dst |= DNOLD_HAS_PROFILE;
+ if (src & DN_QSIZE_BYTES)
+ dst |= DNOLD_QSIZE_IS_BYTES;
+
+ return dst;
+}
+
+static int
+dn_compat_del(void *v)
+{
+ struct dn_pipe7 *p = (struct dn_pipe7 *) v;
+ struct dn_pipe8 *p8 = (struct dn_pipe8 *) v;
+ struct {
+ struct dn_id oid;
+ uintptr_t a[1]; /* add more if we want a list */
+ } cmd;
+
+ /* XXX DN_API_VERSION ??? */
+ oid_fill((void *)&cmd, sizeof(cmd), DN_CMD_DELETE, DN_API_VERSION);
+
+ if (is7) {
+ if (p->pipe_nr == 0 && p->fs.fs_nr == 0)
+ return EINVAL;
+ if (p->pipe_nr != 0 && p->fs.fs_nr != 0)
+ return EINVAL;
+ } else {
+ if (p8->pipe_nr == 0 && p8->fs.fs_nr == 0)
+ return EINVAL;
+ if (p8->pipe_nr != 0 && p8->fs.fs_nr != 0)
+ return EINVAL;
+ }
+
+ if (p->pipe_nr != 0) { /* pipe x delete */
+ cmd.a[0] = p->pipe_nr;
+ cmd.oid.subtype = DN_LINK;
+ } else { /* queue x delete */
+ cmd.oid.subtype = DN_FS;
+ cmd.a[0] = (is7) ? p->fs.fs_nr : p8->fs.fs_nr;
+ }
+
+ return do_config(&cmd, cmd.oid.len);
+}
+
+static int
+dn_compat_config_queue(struct dn_fs *fs, void* v)
+{
+ struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
+ struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
+ struct dn_flow_set *f;
+
+ if (is7)
+ f = &p7->fs;
+ else
+ f = &p8->fs;
+
+ fs->fs_nr = f->fs_nr;
+ fs->sched_nr = f->parent_nr;
+ fs->flow_mask = f->flow_mask;
+ fs->buckets = f->rq_size;
+ fs->qsize = f->qsize;
+ fs->plr = f->plr;
+ fs->par[0] = f->weight;
+ fs->flags = convertflags2new(f->flags_fs);
+ if (fs->flags & DN_IS_GENTLE_RED || fs->flags & DN_IS_RED) {
+ fs->w_q = f->w_q;
+ fs->max_th = f->max_th;
+ fs->min_th = f->min_th;
+ fs->max_p = f->max_p;
+ }
+
+ return 0;
+}
+
+static int
+dn_compat_config_pipe(struct dn_sch *sch, struct dn_link *p,
+ struct dn_fs *fs, void* v)
+{
+ struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
+ struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
+ int i = p7->pipe_nr;
+
+ sch->sched_nr = i;
+ sch->oid.subtype = 0;
+ p->link_nr = i;
+ fs->fs_nr = i + 2*DN_MAX_ID;
+ fs->sched_nr = i + DN_MAX_ID;
+
+ /* Common to 7 and 8 */
+ p->bandwidth = p7->bandwidth;
+ p->delay = p7->delay;
+ if (!is7) {
+ /* FreeBSD 8 has burst */
+ p->burst = p8->burst;
+ }
+
+ /* fill the fifo flowset */
+ dn_compat_config_queue(fs, v);
+ fs->fs_nr = i + 2*DN_MAX_ID;
+ fs->sched_nr = i + DN_MAX_ID;
+
+ /* Move scheduler related parameter from fs to sch */
+ sch->buckets = fs->buckets; /*XXX*/
+ fs->buckets = 0;
+ if (fs->flags & DN_HAVE_MASK) {
+ sch->flags |= DN_HAVE_MASK;
+ fs->flags &= ~DN_HAVE_MASK;
+ sch->sched_mask = fs->flow_mask;
+ bzero(&fs->flow_mask, sizeof(struct ipfw_flow_id));
+ }
+
+ return 0;
+}
+
+static int
+dn_compat_config_profile(struct dn_profile *pf, struct dn_link *p,
+ void *v)
+{
+ struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
+
+ p8->samples = &(((struct dn_pipe_max8 *)p8)->samples[0]);
+
+ pf->link_nr = p->link_nr;
+ pf->loss_level = p8->loss_level;
+// pf->bandwidth = p->bandwidth; //XXX bandwidth redundant?
+ pf->samples_no = p8->samples_no;
+ strncpy(pf->name, p8->name,sizeof(pf->name));
+ bcopy(p8->samples, pf->samples, sizeof(pf->samples));
+
+ return 0;
+}
+
+/*
+ * If p->pipe_nr != 0 the command is 'pipe x config', so need to create
+ * the three main struct, else only a flowset is created
+ */
+static int
+dn_compat_configure(void *v)
+{
+ struct dn_id *buf = NULL, *base;
+ struct dn_sch *sch = NULL;
+ struct dn_link *p = NULL;
+ struct dn_fs *fs = NULL;
+ struct dn_profile *pf = NULL;
+ int lmax;
+ int error;
+
+ struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
+ struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
+
+ int i; /* number of object to configure */
+
+ lmax = sizeof(struct dn_id); /* command header */
+ lmax += sizeof(struct dn_sch) + sizeof(struct dn_link) +
+ sizeof(struct dn_fs) + sizeof(struct dn_profile);
+
+ base = buf = malloc(lmax, M_DUMMYNET, M_WAIT|M_ZERO);
+ o_next(&buf, sizeof(struct dn_id), DN_CMD_CONFIG);
+ base->id = DN_API_VERSION;
+
+ /* pipe_nr is the same in p7 and p8 */
+ i = p7->pipe_nr;
+ if (i != 0) { /* pipe config */
+ sch = o_next(&buf, sizeof(*sch), DN_SCH);
+ p = o_next(&buf, sizeof(*p), DN_LINK);
+ fs = o_next(&buf, sizeof(*fs), DN_FS);
+
+ error = dn_compat_config_pipe(sch, p, fs, v);
+ if (error) {
+ free(buf, M_DUMMYNET);
+ return error;
+ }
+ if (!is7 && p8->samples_no > 0) {
+ /* Add profiles*/
+ pf = o_next(&buf, sizeof(*pf), DN_PROFILE);
+ error = dn_compat_config_profile(pf, p, v);
+ if (error) {
+ free(buf, M_DUMMYNET);
+ return error;
+ }
+ }
+ } else { /* queue config */
+ fs = o_next(&buf, sizeof(*fs), DN_FS);
+ error = dn_compat_config_queue(fs, v);
+ if (error) {
+ free(buf, M_DUMMYNET);
+ return error;
+ }
+ }
+ error = do_config(base, (char *)buf - (char *)base);
+
+ if (buf)
+ free(buf, M_DUMMYNET);
+ return error;
+}
+
+int
+dn_compat_calc_size(void)
+{
+ int need = 0;
+ /* XXX use FreeBSD 8 struct size */
+ /* NOTE:
+ * - half scheduler: schk_count/2
+ * - all flowset: fsk_count
+ * - all flowset queues: queue_count
+ * - all pipe queue: si_count
+ */
+ need += dn_cfg.schk_count * sizeof(struct dn_pipe8) / 2;
+ need += dn_cfg.fsk_count * sizeof(struct dn_flow_set);
+ need += dn_cfg.si_count * sizeof(struct dn_flow_queue8);
+ need += dn_cfg.queue_count * sizeof(struct dn_flow_queue8);
+
+ return need;
+}
+
+int
+dn_c_copy_q (void *_ni, void *arg)
+{
+ struct copy_args *a = arg;
+ struct dn_flow_queue7 *fq7 = (struct dn_flow_queue7 *)*a->start;
+ struct dn_flow_queue8 *fq8 = (struct dn_flow_queue8 *)*a->start;
+ struct dn_flow *ni = (struct dn_flow *)_ni;
+ int size = 0;
+
+ /* XXX hash slot not set */
+ /* No difference between 7.2/8 */
+ fq7->len = ni->length;
+ fq7->len_bytes = ni->len_bytes;
+ fq7->id = ni->fid;
+
+ if (is7) {
+ size = sizeof(struct dn_flow_queue7);
+ fq7->tot_pkts = ni->tot_pkts;
+ fq7->tot_bytes = ni->tot_bytes;
+ fq7->drops = ni->drops;
+ } else {
+ size = sizeof(struct dn_flow_queue8);
+ fq8->tot_pkts = ni->tot_pkts;
+ fq8->tot_bytes = ni->tot_bytes;
+ fq8->drops = ni->drops;
+ }
+
+ *a->start += size;
+ return 0;
+}
+
+int
+dn_c_copy_pipe(struct dn_schk *s, struct copy_args *a, int nq)
+{
+ struct dn_link *l = &s->link;
+ struct dn_fsk *f = s->fs;
+
+ struct dn_pipe7 *pipe7 = (struct dn_pipe7 *)*a->start;
+ struct dn_pipe8 *pipe8 = (struct dn_pipe8 *)*a->start;
+ struct dn_flow_set *fs;
+ int size = 0;
+
+ if (is7) {
+ fs = &pipe7->fs;
+ size = sizeof(struct dn_pipe7);
+ } else {
+ fs = &pipe8->fs;
+ size = sizeof(struct dn_pipe8);
+ }
+
+ /* These 4 field are the same in pipe7 and pipe8 */
+ pipe7->next.sle_next = (struct dn_pipe7 *)DN_IS_PIPE;
+ pipe7->bandwidth = l->bandwidth;
+ pipe7->delay = l->delay * 1000 / hz;
+ pipe7->pipe_nr = l->link_nr - DN_MAX_ID;
+
+ if (!is7) {
+ if (s->profile) {
+ struct dn_profile *pf = s->profile;
+ strncpy(pipe8->name, pf->name, sizeof(pf->name));
+ pipe8->loss_level = pf->loss_level;
+ pipe8->samples_no = pf->samples_no;
+ }
+ pipe8->burst = div64(l->burst , 8 * hz);
+ }
+
+ fs->flow_mask = s->sch.sched_mask;
+ fs->rq_size = s->sch.buckets ? s->sch.buckets : 1;
+
+ fs->parent_nr = l->link_nr - DN_MAX_ID;
+ fs->qsize = f->fs.qsize;
+ fs->plr = f->fs.plr;
+ fs->w_q = f->fs.w_q;
+ fs->max_th = f->max_th;
+ fs->min_th = f->min_th;
+ fs->max_p = f->fs.max_p;
+ fs->rq_elements = nq;
+
+ fs->flags_fs = convertflags2old(f->fs.flags);
+
+ *a->start += size;
+ return 0;
+}
+
+
+int
+dn_compat_copy_pipe(struct copy_args *a, void *_o)
+{
+ int have = a->end - *a->start;
+ int need = 0;
+ int pipe_size = sizeof(struct dn_pipe8);
+ int queue_size = sizeof(struct dn_flow_queue8);
+ int n_queue = 0; /* number of queues */
+
+ struct dn_schk *s = (struct dn_schk *)_o;
+ /* calculate needed space:
+ * - struct dn_pipe
+ * - if there are instances, dn_queue * n_instances
+ */
+ n_queue = (s->sch.flags & DN_HAVE_MASK ? dn_ht_entries(s->siht) :
+ (s->siht ? 1 : 0));
+ need = pipe_size + queue_size * n_queue;
+ if (have < need) {
+ D("have %d < need %d", have, need);
+ return 1;
+ }
+ /* copy pipe */
+ dn_c_copy_pipe(s, a, n_queue);
+
+ /* copy queues */
+ if (s->sch.flags & DN_HAVE_MASK)
+ dn_ht_scan(s->siht, dn_c_copy_q, a);
+ else if (s->siht)
+ dn_c_copy_q(s->siht, a);
+ return 0;
+}
+
+int
+dn_c_copy_fs(struct dn_fsk *f, struct copy_args *a, int nq)
+{
+ struct dn_flow_set *fs = (struct dn_flow_set *)*a->start;
+
+ fs->next.sle_next = (struct dn_flow_set *)DN_IS_QUEUE;
+ fs->fs_nr = f->fs.fs_nr;
+ fs->qsize = f->fs.qsize;
+ fs->plr = f->fs.plr;
+ fs->w_q = f->fs.w_q;
+ fs->max_th = f->max_th;
+ fs->min_th = f->min_th;
+ fs->max_p = f->fs.max_p;
+ fs->flow_mask = f->fs.flow_mask;
+ fs->rq_elements = nq;
+ fs->rq_size = (f->fs.buckets ? f->fs.buckets : 1);
+ fs->parent_nr = f->fs.sched_nr;
+ fs->weight = f->fs.par[0];
+
+ fs->flags_fs = convertflags2old(f->fs.flags);
+ *a->start += sizeof(struct dn_flow_set);
+ return 0;
+}
+
+int
+dn_compat_copy_queue(struct copy_args *a, void *_o)
+{
+ int have = a->end - *a->start;
+ int need = 0;
+ int fs_size = sizeof(struct dn_flow_set);
+ int queue_size = sizeof(struct dn_flow_queue8);
+
+ struct dn_fsk *fs = (struct dn_fsk *)_o;
+ int n_queue = 0; /* number of queues */
+
+ n_queue = (fs->fs.flags & DN_HAVE_MASK ? dn_ht_entries(fs->qht) :
+ (fs->qht ? 1 : 0));
+
+ need = fs_size + queue_size * n_queue;
+ if (have < need) {
+ D("have < need");
+ return 1;
+ }
+
+ /* copy flowset */
+ dn_c_copy_fs(fs, a, n_queue);
+
+ /* copy queues */
+ if (fs->fs.flags & DN_HAVE_MASK)
+ dn_ht_scan(fs->qht, dn_c_copy_q, a);
+ else if (fs->qht)
+ dn_c_copy_q(fs->qht, a);
+
+ return 0;
+}
+
+int
+copy_data_helper_compat(void *_o, void *_arg)
+{
+ struct copy_args *a = _arg;
+
+ if (a->type == DN_COMPAT_PIPE) {
+ struct dn_schk *s = _o;
+ if (s->sch.oid.subtype != 1 || s->sch.sched_nr <= DN_MAX_ID) {
+ return 0; /* not old type */
+ }
+ /* copy pipe parameters, and if instance exists, copy
+ * other parameters and eventually queues.
+ */
+ if(dn_compat_copy_pipe(a, _o))
+ return DNHT_SCAN_END;
+ } else if (a->type == DN_COMPAT_QUEUE) {
+ struct dn_fsk *fs = _o;
+ if (fs->fs.fs_nr >= DN_MAX_ID)
+ return 0;
+ if (dn_compat_copy_queue(a, _o))
+ return DNHT_SCAN_END;
+ }
+ return 0;
+}
+
+/* Main function to manage old requests */
+int
+ip_dummynet_compat(struct sockopt *sopt)
+{
+ int error=0;
+ void *v = NULL;
+ struct dn_id oid;
+
+ /* Lenght of data, used to found ipfw version... */
+ int len = sopt->sopt_valsize;
+
+ /* len can be 0 if command was dummynet_flush */
+ if (len == pipesize7) {
+ D("setting compatibility with FreeBSD 7.2");
+ is7 = 1;
+ }
+ else if (len == pipesize8 || len == pipesizemax8) {
+ D("setting compatibility with FreeBSD 8");
+ is7 = 0;
+ }
+
+ switch (sopt->sopt_name) {
+ default:
+ printf("dummynet: -- unknown option %d", sopt->sopt_name);
+ error = EINVAL;
+ break;
+
+ case IP_DUMMYNET_FLUSH:
+ oid_fill(&oid, sizeof(oid), DN_CMD_FLUSH, DN_API_VERSION);
+ do_config(&oid, oid.len);
+ break;
+
+ case IP_DUMMYNET_DEL:
+ v = malloc(len, M_TEMP, M_WAITOK);
+ error = sooptcopyin(sopt, v, len, len);
+ if (error)
+ break;
+ error = dn_compat_del(v);
+ free(v, M_TEMP);
+ break;
+
+ case IP_DUMMYNET_CONFIGURE:
+ v = malloc(len, M_TEMP, M_WAITOK);
+ error = sooptcopyin(sopt, v, len, len);
+ if (error)
+ break;
+ error = dn_compat_configure(v);
+ free(v, M_TEMP);
+ break;
+
+ case IP_DUMMYNET_GET: {
+ void *buf;
+ int ret;
+ int original_size = sopt->sopt_valsize;
+ int size;
+
+ ret = dummynet_get(sopt, &buf);
+ if (ret)
+ return 0;//XXX ?
+ size = sopt->sopt_valsize;
+ sopt->sopt_valsize = original_size;
+ D("size=%d, buf=%p", size, buf);
+ ret = sooptcopyout(sopt, buf, size);
+ if (ret)
+ printf(" %s ERROR sooptcopyout\n", __FUNCTION__);
+ if (buf)
+ free(buf, M_DUMMYNET);
+ }
+ }
+
+ return error;
+}
+
+
diff --git a/sys/netinet/ipfw/ip_dn_io.c b/sys/netinet/ipfw/ip_dn_io.c
new file mode 100644
index 0000000..a39f169
--- /dev/null
+++ b/sys/netinet/ipfw/ip_dn_io.c
@@ -0,0 +1,851 @@
+/*-
+ * Copyright (c) 2010 Luigi Rizzo, Riccardo Panicucci, Universita` di Pisa
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Dummynet portions related to packet handling.
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h> /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
+#include <net/netisr.h>
+#include <net/vnet.h>
+
+#include <netinet/in.h>
+#include <netinet/ip.h> /* ip_len, ip_off */
+#include <netinet/ip_var.h> /* ip_output(), IP_FORWARDING */
+#include <netinet/ip_fw.h>
+#include <netinet/ipfw/ip_fw_private.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+
+#include <netinet/if_ether.h> /* various ether_* routines */
+
+#include <netinet/ip6.h> /* for ip6_input, ip6_output prototypes */
+#include <netinet6/ip6_var.h>
+
+/*
+ * We keep a private variable for the simulation time, but we could
+ * probably use an existing one ("softticks" in sys/kern/kern_timeout.c)
+ * instead of dn_cfg.curr_time
+ */
+
+struct dn_parms dn_cfg;
+//VNET_DEFINE(struct dn_parms, _base_dn_cfg);
+
+static long tick_last; /* Last tick duration (usec). */
+static long tick_delta; /* Last vs standard tick diff (usec). */
+static long tick_delta_sum; /* Accumulated tick difference (usec).*/
+static long tick_adjustment; /* Tick adjustments done. */
+static long tick_lost; /* Lost(coalesced) ticks number. */
+/* Adjusted vs non-adjusted curr_time difference (ticks). */
+static long tick_diff;
+
+static unsigned long io_pkt;
+static unsigned long io_pkt_fast;
+static unsigned long io_pkt_drop;
+
+/*
+ * We use a heap to store entities for which we have pending timer events.
+ * The heap is checked at every tick and all entities with expired events
+ * are extracted.
+ */
+
+MALLOC_DEFINE(M_DUMMYNET, "dummynet", "dummynet heap");
+
+extern void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
+
+#ifdef SYSCTL_NODE
+
+SYSBEGIN(f4)
+
+SYSCTL_DECL(_net_inet);
+SYSCTL_DECL(_net_inet_ip);
+static SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet");
+
+/* wrapper to pass dn_cfg fields to SYSCTL_* */
+//#define DC(x) (&(VNET_NAME(_base_dn_cfg).x))
+#define DC(x) (&(dn_cfg.x))
+/* parameters */
+
+static int
+sysctl_hash_size(SYSCTL_HANDLER_ARGS)
+{
+ int error, value;
+
+ value = dn_cfg.hash_size;
+ error = sysctl_handle_int(oidp, &value, 0, req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+ if (value < 16 || value > 65536)
+ return (EINVAL);
+ dn_cfg.hash_size = value;
+ return (0);
+}
+
+SYSCTL_PROC(_net_inet_ip_dummynet, OID_AUTO, hash_size,
+ CTLTYPE_INT | CTLFLAG_RW, 0, 0, sysctl_hash_size,
+ "I", "Default hash table size");
+
+static int
+sysctl_limits(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ long value;
+
+ if (arg2 != 0)
+ value = dn_cfg.slot_limit;
+ else
+ value = dn_cfg.byte_limit;
+ error = sysctl_handle_long(oidp, &value, 0, req);
+
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+ if (arg2 != 0) {
+ if (value < 1)
+ return (EINVAL);
+ dn_cfg.slot_limit = value;
+ } else {
+ if (value < 1500)
+ return (EINVAL);
+ dn_cfg.byte_limit = value;
+ }
+ return (0);
+}
+
+SYSCTL_PROC(_net_inet_ip_dummynet, OID_AUTO, pipe_slot_limit,
+ CTLTYPE_LONG | CTLFLAG_RW, 0, 1, sysctl_limits,
+ "L", "Upper limit in slots for pipe queue.");
+SYSCTL_PROC(_net_inet_ip_dummynet, OID_AUTO, pipe_byte_limit,
+ CTLTYPE_LONG | CTLFLAG_RW, 0, 0, sysctl_limits,
+ "L", "Upper limit in bytes for pipe queue.");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, io_fast,
+ CTLFLAG_RW, DC(io_fast), 0, "Enable fast dummynet io.");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, debug,
+ CTLFLAG_RW, DC(debug), 0, "Dummynet debug level");
+
+/* RED parameters */
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_lookup_depth,
+ CTLFLAG_RD, DC(red_lookup_depth), 0, "Depth of RED lookup table");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_avg_pkt_size,
+ CTLFLAG_RD, DC(red_avg_pkt_size), 0, "RED Medium packet size");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_max_pkt_size,
+ CTLFLAG_RD, DC(red_max_pkt_size), 0, "RED Max packet size");
+
+/* time adjustment */
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta,
+ CTLFLAG_RD, &tick_delta, 0, "Last vs standard tick difference (usec).");
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta_sum,
+ CTLFLAG_RD, &tick_delta_sum, 0, "Accumulated tick difference (usec).");
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_adjustment,
+ CTLFLAG_RD, &tick_adjustment, 0, "Tick adjustments done.");
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_diff,
+ CTLFLAG_RD, &tick_diff, 0,
+ "Adjusted vs non-adjusted curr_time difference (ticks).");
+SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_lost,
+ CTLFLAG_RD, &tick_lost, 0,
+ "Number of ticks coalesced by dummynet taskqueue.");
+
+/* Drain parameters */
+SYSCTL_UINT(_net_inet_ip_dummynet, OID_AUTO, expire,
+ CTLFLAG_RW, DC(expire), 0, "Expire empty queues/pipes");
+SYSCTL_UINT(_net_inet_ip_dummynet, OID_AUTO, expire_cycle,
+ CTLFLAG_RD, DC(expire_cycle), 0, "Expire cycle for queues/pipes");
+
+/* statistics */
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, schk_count,
+ CTLFLAG_RD, DC(schk_count), 0, "Number of schedulers");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, si_count,
+ CTLFLAG_RD, DC(si_count), 0, "Number of scheduler instances");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, fsk_count,
+ CTLFLAG_RD, DC(fsk_count), 0, "Number of flowsets");
+SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, queue_count,
+ CTLFLAG_RD, DC(queue_count), 0, "Number of queues");
+SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt,
+ CTLFLAG_RD, &io_pkt, 0,
+ "Number of packets passed to dummynet.");
+SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_fast,
+ CTLFLAG_RD, &io_pkt_fast, 0,
+ "Number of packets bypassed dummynet scheduler.");
+SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_drop,
+ CTLFLAG_RD, &io_pkt_drop, 0,
+ "Number of packets dropped by dummynet.");
+#undef DC
+SYSEND
+
+#endif
+
+static void dummynet_send(struct mbuf *);
+
+/*
+ * Packets processed by dummynet have an mbuf tag associated with
+ * them that carries their dummynet state.
+ * Outside dummynet, only the 'rule' field is relevant, and it must
+ * be at the beginning of the structure.
+ */
+struct dn_pkt_tag {
+ struct ipfw_rule_ref rule; /* matching rule */
+
+ /* second part, dummynet specific */
+ int dn_dir; /* action when packet comes out.*/
+ /* see ip_fw_private.h */
+ uint64_t output_time; /* when the pkt is due for delivery*/
+ struct ifnet *ifp; /* interface, for ip_output */
+ struct _ip6dn_args ip6opt; /* XXX ipv6 options */
+};
+
+/*
+ * Return the mbuf tag holding the dummynet state (it should
+ * be the first one on the list).
+ */
+static struct dn_pkt_tag *
+dn_tag_get(struct mbuf *m)
+{
+ struct m_tag *mtag = m_tag_first(m);
+ KASSERT(mtag != NULL &&
+ mtag->m_tag_cookie == MTAG_ABI_COMPAT &&
+ mtag->m_tag_id == PACKET_TAG_DUMMYNET,
+ ("packet on dummynet queue w/o dummynet tag!"));
+ return (struct dn_pkt_tag *)(mtag+1);
+}
+
+static inline void
+mq_append(struct mq *q, struct mbuf *m)
+{
+ if (q->head == NULL)
+ q->head = m;
+ else
+ q->tail->m_nextpkt = m;
+ q->tail = m;
+ m->m_nextpkt = NULL;
+}
+
+/*
+ * Dispose a list of packet. Use a functions so if we need to do
+ * more work, this is a central point to do it.
+ */
+void dn_free_pkts(struct mbuf *mnext)
+{
+ struct mbuf *m;
+
+ while ((m = mnext) != NULL) {
+ mnext = m->m_nextpkt;
+ FREE_PKT(m);
+ }
+}
+
+static int
+red_drops (struct dn_queue *q, int len)
+{
+ /*
+ * RED algorithm
+ *
+ * RED calculates the average queue size (avg) using a low-pass filter
+ * with an exponential weighted (w_q) moving average:
+ * avg <- (1-w_q) * avg + w_q * q_size
+ * where q_size is the queue length (measured in bytes or * packets).
+ *
+ * If q_size == 0, we compute the idle time for the link, and set
+ * avg = (1 - w_q)^(idle/s)
+ * where s is the time needed for transmitting a medium-sized packet.
+ *
+ * Now, if avg < min_th the packet is enqueued.
+ * If avg > max_th the packet is dropped. Otherwise, the packet is
+ * dropped with probability P function of avg.
+ */
+
+ struct dn_fsk *fs = q->fs;
+ int64_t p_b = 0;
+
+ /* Queue in bytes or packets? */
+ uint32_t q_size = (fs->fs.flags & DN_QSIZE_BYTES) ?
+ q->ni.len_bytes : q->ni.length;
+
+ /* Average queue size estimation. */
+ if (q_size != 0) {
+ /* Queue is not empty, avg <- avg + (q_size - avg) * w_q */
+ int diff = SCALE(q_size) - q->avg;
+ int64_t v = SCALE_MUL((int64_t)diff, (int64_t)fs->w_q);
+
+ q->avg += (int)v;
+ } else {
+ /*
+ * Queue is empty, find for how long the queue has been
+ * empty and use a lookup table for computing
+ * (1 - * w_q)^(idle_time/s) where s is the time to send a
+ * (small) packet.
+ * XXX check wraps...
+ */
+ if (q->avg) {
+ u_int t = div64((dn_cfg.curr_time - q->q_time), fs->lookup_step);
+
+ q->avg = (t < fs->lookup_depth) ?
+ SCALE_MUL(q->avg, fs->w_q_lookup[t]) : 0;
+ }
+ }
+
+ /* Should i drop? */
+ if (q->avg < fs->min_th) {
+ q->count = -1;
+ return (0); /* accept packet */
+ }
+ if (q->avg >= fs->max_th) { /* average queue >= max threshold */
+ if (fs->fs.flags & DN_IS_GENTLE_RED) {
+ /*
+ * According to Gentle-RED, if avg is greater than
+ * max_th the packet is dropped with a probability
+ * p_b = c_3 * avg - c_4
+ * where c_3 = (1 - max_p) / max_th
+ * c_4 = 1 - 2 * max_p
+ */
+ p_b = SCALE_MUL((int64_t)fs->c_3, (int64_t)q->avg) -
+ fs->c_4;
+ } else {
+ q->count = -1;
+ return (1);
+ }
+ } else if (q->avg > fs->min_th) {
+ /*
+ * We compute p_b using the linear dropping function
+ * p_b = c_1 * avg - c_2
+ * where c_1 = max_p / (max_th - min_th)
+ * c_2 = max_p * min_th / (max_th - min_th)
+ */
+ p_b = SCALE_MUL((int64_t)fs->c_1, (int64_t)q->avg) - fs->c_2;
+ }
+
+ if (fs->fs.flags & DN_QSIZE_BYTES)
+ p_b = div64((p_b * len) , fs->max_pkt_size);
+ if (++q->count == 0)
+ q->random = random() & 0xffff;
+ else {
+ /*
+ * q->count counts packets arrived since last drop, so a greater
+ * value of q->count means a greater packet drop probability.
+ */
+ if (SCALE_MUL(p_b, SCALE((int64_t)q->count)) > q->random) {
+ q->count = 0;
+ /* After a drop we calculate a new random value. */
+ q->random = random() & 0xffff;
+ return (1); /* drop */
+ }
+ }
+ /* End of RED algorithm. */
+
+ return (0); /* accept */
+
+}
+
+/*
+ * Enqueue a packet in q, subject to space and queue management policy
+ * (whose parameters are in q->fs).
+ * Update stats for the queue and the scheduler.
+ * Return 0 on success, 1 on drop. The packet is consumed anyways.
+ */
+int
+dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop)
+{
+ struct dn_fs *f;
+ struct dn_flow *ni; /* stats for scheduler instance */
+ uint64_t len;
+
+ if (q->fs == NULL || q->_si == NULL) {
+ printf("%s fs %p si %p, dropping\n",
+ __FUNCTION__, q->fs, q->_si);
+ FREE_PKT(m);
+ return 1;
+ }
+ f = &(q->fs->fs);
+ ni = &q->_si->ni;
+ len = m->m_pkthdr.len;
+ /* Update statistics, then check reasons to drop pkt. */
+ q->ni.tot_bytes += len;
+ q->ni.tot_pkts++;
+ ni->tot_bytes += len;
+ ni->tot_pkts++;
+ if (drop)
+ goto drop;
+ if (f->plr && random() < f->plr)
+ goto drop;
+ if (f->flags & DN_IS_RED && red_drops(q, m->m_pkthdr.len))
+ goto drop;
+ if (f->flags & DN_QSIZE_BYTES) {
+ if (q->ni.len_bytes > f->qsize)
+ goto drop;
+ } else if (q->ni.length >= f->qsize) {
+ goto drop;
+ }
+ mq_append(&q->mq, m);
+ q->ni.length++;
+ q->ni.len_bytes += len;
+ ni->length++;
+ ni->len_bytes += len;
+ return 0;
+
+drop:
+ io_pkt_drop++;
+ q->ni.drops++;
+ ni->drops++;
+ FREE_PKT(m);
+ return 1;
+}
+
+/*
+ * Fetch packets from the delay line which are due now. If there are
+ * leftover packets, reinsert the delay line in the heap.
+ * Runs under scheduler lock.
+ */
+static void
+transmit_event(struct mq *q, struct delay_line *dline, uint64_t now)
+{
+ struct mbuf *m;
+ struct dn_pkt_tag *pkt = NULL;
+
+ dline->oid.subtype = 0; /* not in heap */
+ while ((m = dline->mq.head) != NULL) {
+ pkt = dn_tag_get(m);
+ if (!DN_KEY_LEQ(pkt->output_time, now))
+ break;
+ dline->mq.head = m->m_nextpkt;
+ mq_append(q, m);
+ }
+ if (m != NULL) {
+ dline->oid.subtype = 1; /* in heap */
+ heap_insert(&dn_cfg.evheap, pkt->output_time, dline);
+ }
+}
+
+/*
+ * Convert the additional MAC overheads/delays into an equivalent
+ * number of bits for the given data rate. The samples are
+ * in milliseconds so we need to divide by 1000.
+ */
+static uint64_t
+extra_bits(struct mbuf *m, struct dn_schk *s)
+{
+ int index;
+ uint64_t bits;
+ struct dn_profile *pf = s->profile;
+
+ if (!pf || pf->samples_no == 0)
+ return 0;
+ index = random() % pf->samples_no;
+ bits = div64((uint64_t)pf->samples[index] * s->link.bandwidth, 1000);
+ if (index >= pf->loss_level) {
+ struct dn_pkt_tag *dt = dn_tag_get(m);
+ if (dt)
+ dt->dn_dir = DIR_DROP;
+ }
+ return bits;
+}
+
+/*
+ * Send traffic from a scheduler instance due by 'now'.
+ * Return a pointer to the head of the queue.
+ */
+static struct mbuf *
+serve_sched(struct mq *q, struct dn_sch_inst *si, uint64_t now)
+{
+ struct mq def_q;
+ struct dn_schk *s = si->sched;
+ struct mbuf *m = NULL;
+ int delay_line_idle = (si->dline.mq.head == NULL);
+ int done, bw;
+
+ if (q == NULL) {
+ q = &def_q;
+ q->head = NULL;
+ }
+
+ bw = s->link.bandwidth;
+ si->kflags &= ~DN_ACTIVE;
+
+ if (bw > 0)
+ si->credit += (now - si->sched_time) * bw;
+ else
+ si->credit = 0;
+ si->sched_time = now;
+ done = 0;
+ while (si->credit >= 0 && (m = s->fp->dequeue(si)) != NULL) {
+ uint64_t len_scaled;
+
+ done++;
+ len_scaled = (bw == 0) ? 0 : hz *
+ (m->m_pkthdr.len * 8 + extra_bits(m, s));
+ si->credit -= len_scaled;
+ /* Move packet in the delay line */
+ dn_tag_get(m)->output_time = dn_cfg.curr_time + s->link.delay ;
+ mq_append(&si->dline.mq, m);
+ }
+
+ /*
+ * If credit >= 0 the instance is idle, mark time.
+ * Otherwise put back in the heap, and adjust the output
+ * time of the last inserted packet, m, which was too early.
+ */
+ if (si->credit >= 0) {
+ si->idle_time = now;
+ } else {
+ uint64_t t;
+ KASSERT (bw > 0, ("bw=0 and credit<0 ?"));
+ t = div64(bw - 1 - si->credit, bw);
+ if (m)
+ dn_tag_get(m)->output_time += t;
+ si->kflags |= DN_ACTIVE;
+ heap_insert(&dn_cfg.evheap, now + t, si);
+ }
+ if (delay_line_idle && done)
+ transmit_event(q, &si->dline, now);
+ return q->head;
+}
+
+/*
+ * The timer handler for dummynet. Time is computed in ticks, but
+ * but the code is tolerant to the actual rate at which this is called.
+ * Once complete, the function reschedules itself for the next tick.
+ */
+void
+dummynet_task(void *context, int pending)
+{
+ struct timeval t;
+ struct mq q = { NULL, NULL }; /* queue to accumulate results */
+
+ CURVNET_SET((struct vnet *)context);
+
+ DN_BH_WLOCK();
+
+ /* Update number of lost(coalesced) ticks. */
+ tick_lost += pending - 1;
+
+ getmicrouptime(&t);
+ /* Last tick duration (usec). */
+ tick_last = (t.tv_sec - dn_cfg.prev_t.tv_sec) * 1000000 +
+ (t.tv_usec - dn_cfg.prev_t.tv_usec);
+ /* Last tick vs standard tick difference (usec). */
+ tick_delta = (tick_last * hz - 1000000) / hz;
+ /* Accumulated tick difference (usec). */
+ tick_delta_sum += tick_delta;
+
+ dn_cfg.prev_t = t;
+
+ /*
+ * Adjust curr_time if the accumulated tick difference is
+ * greater than the 'standard' tick. Since curr_time should
+ * be monotonically increasing, we do positive adjustments
+ * as required, and throttle curr_time in case of negative
+ * adjustment.
+ */
+ dn_cfg.curr_time++;
+ if (tick_delta_sum - tick >= 0) {
+ int diff = tick_delta_sum / tick;
+
+ dn_cfg.curr_time += diff;
+ tick_diff += diff;
+ tick_delta_sum %= tick;
+ tick_adjustment++;
+ } else if (tick_delta_sum + tick <= 0) {
+ dn_cfg.curr_time--;
+ tick_diff--;
+ tick_delta_sum += tick;
+ tick_adjustment++;
+ }
+
+ /* serve pending events, accumulate in q */
+ for (;;) {
+ struct dn_id *p; /* generic parameter to handler */
+
+ if (dn_cfg.evheap.elements == 0 ||
+ DN_KEY_LT(dn_cfg.curr_time, HEAP_TOP(&dn_cfg.evheap)->key))
+ break;
+ p = HEAP_TOP(&dn_cfg.evheap)->object;
+ heap_extract(&dn_cfg.evheap, NULL);
+
+ if (p->type == DN_SCH_I) {
+ serve_sched(&q, (struct dn_sch_inst *)p, dn_cfg.curr_time);
+ } else { /* extracted a delay line */
+ transmit_event(&q, (struct delay_line *)p, dn_cfg.curr_time);
+ }
+ }
+ if (dn_cfg.expire && ++dn_cfg.expire_cycle >= dn_cfg.expire) {
+ dn_cfg.expire_cycle = 0;
+ dn_drain_scheduler();
+ dn_drain_queue();
+ }
+
+ DN_BH_WUNLOCK();
+ dn_reschedule();
+ if (q.head != NULL)
+ dummynet_send(q.head);
+ CURVNET_RESTORE();
+}
+
+/*
+ * forward a chain of packets to the proper destination.
+ * This runs outside the dummynet lock.
+ */
+static void
+dummynet_send(struct mbuf *m)
+{
+ struct mbuf *n;
+
+ for (; m != NULL; m = n) {
+ struct ifnet *ifp = NULL; /* gcc 3.4.6 complains */
+ struct m_tag *tag;
+ int dst;
+
+ n = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ tag = m_tag_first(m);
+ if (tag == NULL) { /* should not happen */
+ dst = DIR_DROP;
+ } else {
+ struct dn_pkt_tag *pkt = dn_tag_get(m);
+ /* extract the dummynet info, rename the tag
+ * to carry reinject info.
+ */
+ dst = pkt->dn_dir;
+ ifp = pkt->ifp;
+ tag->m_tag_cookie = MTAG_IPFW_RULE;
+ tag->m_tag_id = 0;
+ }
+
+ switch (dst) {
+ case DIR_OUT:
+ SET_HOST_IPLEN(mtod(m, struct ip *));
+ ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
+ break ;
+
+ case DIR_IN :
+ /* put header in network format for ip_input() */
+ //SET_NET_IPLEN(mtod(m, struct ip *));
+ netisr_dispatch(NETISR_IP, m);
+ break;
+
+#ifdef INET6
+ case DIR_IN | PROTO_IPV6:
+ netisr_dispatch(NETISR_IPV6, m);
+ break;
+
+ case DIR_OUT | PROTO_IPV6:
+ ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL);
+ break;
+#endif
+
+ case DIR_FWD | PROTO_IFB: /* DN_TO_IFB_FWD: */
+ if (bridge_dn_p != NULL)
+ ((*bridge_dn_p)(m, ifp));
+ else
+ printf("dummynet: if_bridge not loaded\n");
+
+ break;
+
+ case DIR_IN | PROTO_LAYER2: /* DN_TO_ETH_DEMUX: */
+ /*
+ * The Ethernet code assumes the Ethernet header is
+ * contiguous in the first mbuf header.
+ * Insure this is true.
+ */
+ if (m->m_len < ETHER_HDR_LEN &&
+ (m = m_pullup(m, ETHER_HDR_LEN)) == NULL) {
+ printf("dummynet/ether: pullup failed, "
+ "dropping packet\n");
+ break;
+ }
+ ether_demux(m->m_pkthdr.rcvif, m);
+ break;
+
+ case DIR_OUT | PROTO_LAYER2: /* N_TO_ETH_OUT: */
+ ether_output_frame(ifp, m);
+ break;
+
+ case DIR_DROP:
+ /* drop the packet after some time */
+ FREE_PKT(m);
+ break;
+
+ default:
+ printf("dummynet: bad switch %d!\n", dst);
+ FREE_PKT(m);
+ break;
+ }
+ }
+}
+
+static inline int
+tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *fwa)
+{
+ struct dn_pkt_tag *dt;
+ struct m_tag *mtag;
+
+ mtag = m_tag_get(PACKET_TAG_DUMMYNET,
+ sizeof(*dt), M_NOWAIT | M_ZERO);
+ if (mtag == NULL)
+ return 1; /* Cannot allocate packet header. */
+ m_tag_prepend(m, mtag); /* Attach to mbuf chain. */
+ dt = (struct dn_pkt_tag *)(mtag + 1);
+ dt->rule = fwa->rule;
+ dt->rule.info &= IPFW_ONEPASS; /* only keep this info */
+ dt->dn_dir = dir;
+ dt->ifp = fwa->oif;
+ /* dt->output tame is updated as we move through */
+ dt->output_time = dn_cfg.curr_time;
+ return 0;
+}
+
+
+/*
+ * dummynet hook for packets.
+ * We use the argument to locate the flowset fs and the sched_set sch
+ * associated to it. The we apply flow_mask and sched_mask to
+ * determine the queue and scheduler instances.
+ *
+ * dir where shall we send the packet after dummynet.
+ * *m0 the mbuf with the packet
+ * ifp the 'ifp' parameter from the caller.
+ * NULL in ip_input, destination interface in ip_output,
+ */
+int
+dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa)
+{
+ struct mbuf *m = *m0;
+ struct dn_fsk *fs = NULL;
+ struct dn_sch_inst *si;
+ struct dn_queue *q = NULL; /* default */
+
+ int fs_id = (fwa->rule.info & IPFW_INFO_MASK) +
+ ((fwa->rule.info & IPFW_IS_PIPE) ? 2*DN_MAX_ID : 0);
+ DN_BH_WLOCK();
+ io_pkt++;
+ /* we could actually tag outside the lock, but who cares... */
+ if (tag_mbuf(m, dir, fwa))
+ goto dropit;
+ if (dn_cfg.busy) {
+ /* if the upper half is busy doing something expensive,
+ * lets queue the packet and move forward
+ */
+ mq_append(&dn_cfg.pending, m);
+ m = *m0 = NULL; /* consumed */
+ goto done; /* already active, nothing to do */
+ }
+ /* XXX locate_flowset could be optimised with a direct ref. */
+ fs = dn_ht_find(dn_cfg.fshash, fs_id, 0, NULL);
+ if (fs == NULL)
+ goto dropit; /* This queue/pipe does not exist! */
+ if (fs->sched == NULL) /* should not happen */
+ goto dropit;
+ /* find scheduler instance, possibly applying sched_mask */
+ si = ipdn_si_find(fs->sched, &(fwa->f_id));
+ if (si == NULL)
+ goto dropit;
+ /*
+ * If the scheduler supports multiple queues, find the right one
+ * (otherwise it will be ignored by enqueue).
+ */
+ if (fs->sched->fp->flags & DN_MULTIQUEUE) {
+ q = ipdn_q_find(fs, si, &(fwa->f_id));
+ if (q == NULL)
+ goto dropit;
+ }
+ if (fs->sched->fp->enqueue(si, q, m)) {
+ /* packet was dropped by enqueue() */
+ m = *m0 = NULL;
+ goto dropit;
+ }
+
+ if (si->kflags & DN_ACTIVE) {
+ m = *m0 = NULL; /* consumed */
+ goto done; /* already active, nothing to do */
+ }
+
+ /* compute the initial allowance */
+ if (si->idle_time < dn_cfg.curr_time) {
+ /* Do this only on the first packet on an idle pipe */
+ struct dn_link *p = &fs->sched->link;
+
+ si->sched_time = dn_cfg.curr_time;
+ si->credit = dn_cfg.io_fast ? p->bandwidth : 0;
+ if (p->burst) {
+ uint64_t burst = (dn_cfg.curr_time - si->idle_time) * p->bandwidth;
+ if (burst > p->burst)
+ burst = p->burst;
+ si->credit += burst;
+ }
+ }
+ /* pass through scheduler and delay line */
+ m = serve_sched(NULL, si, dn_cfg.curr_time);
+
+ /* optimization -- pass it back to ipfw for immediate send */
+ /* XXX Don't call dummynet_send() if scheduler return the packet
+ * just enqueued. This avoid a lock order reversal.
+ *
+ */
+ if (/*dn_cfg.io_fast &&*/ m == *m0 && (dir & PROTO_LAYER2) == 0 ) {
+ /* fast io, rename the tag * to carry reinject info. */
+ struct m_tag *tag = m_tag_first(m);
+
+ tag->m_tag_cookie = MTAG_IPFW_RULE;
+ tag->m_tag_id = 0;
+ io_pkt_fast++;
+ if (m->m_nextpkt != NULL) {
+ printf("dummynet: fast io: pkt chain detected!\n");
+ m->m_nextpkt = NULL;
+ }
+ m = NULL;
+ } else {
+ *m0 = NULL;
+ }
+done:
+ DN_BH_WUNLOCK();
+ if (m)
+ dummynet_send(m);
+ return 0;
+
+dropit:
+ io_pkt_drop++;
+ DN_BH_WUNLOCK();
+ if (m)
+ FREE_PKT(m);
+ *m0 = NULL;
+ return (fs && (fs->fs.flags & DN_NOERROR)) ? 0 : ENOBUFS;
+}
diff --git a/sys/netinet/ipfw/ip_dn_private.h b/sys/netinet/ipfw/ip_dn_private.h
new file mode 100644
index 0000000..159ddc9
--- /dev/null
+++ b/sys/netinet/ipfw/ip_dn_private.h
@@ -0,0 +1,403 @@
+/*-
+ * Copyright (c) 2010 Luigi Rizzo, Riccardo Panicucci, Universita` di Pisa
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * internal dummynet APIs.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _IP_DN_PRIVATE_H
+#define _IP_DN_PRIVATE_H
+
+/* debugging support
+ * use ND() to remove debugging, D() to print a line,
+ * DX(level, ...) to print above a certain level
+ * If you redefine D() you are expected to redefine all.
+ */
+#ifndef D
+#define ND(fmt, ...) do {} while (0)
+#define D1(fmt, ...) do {} while (0)
+#define D(fmt, ...) printf("%-10s " fmt "\n", \
+ __FUNCTION__, ## __VA_ARGS__)
+#define DX(lev, fmt, ...) do { \
+ if (dn_cfg.debug > lev) D(fmt, ## __VA_ARGS__); } while (0)
+#endif
+
+MALLOC_DECLARE(M_DUMMYNET);
+
+#ifndef __linux__
+#define div64(a, b) ((int64_t)(a) / (int64_t)(b))
+#endif
+
+#define DN_LOCK_INIT() do { \
+ mtx_init(&dn_cfg.uh_mtx, "dn_uh", NULL, MTX_DEF); \
+ mtx_init(&dn_cfg.bh_mtx, "dn_bh", NULL, MTX_DEF); \
+ } while (0)
+#define DN_LOCK_DESTROY() do { \
+ mtx_destroy(&dn_cfg.uh_mtx); \
+ mtx_destroy(&dn_cfg.bh_mtx); \
+ } while (0)
+#if 0 /* not used yet */
+#define DN_UH_RLOCK() mtx_lock(&dn_cfg.uh_mtx)
+#define DN_UH_RUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
+#define DN_UH_WLOCK() mtx_lock(&dn_cfg.uh_mtx)
+#define DN_UH_WUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
+#define DN_UH_LOCK_ASSERT() mtx_assert(&dn_cfg.uh_mtx, MA_OWNED)
+#endif
+
+#define DN_BH_RLOCK() mtx_lock(&dn_cfg.uh_mtx)
+#define DN_BH_RUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
+#define DN_BH_WLOCK() mtx_lock(&dn_cfg.uh_mtx)
+#define DN_BH_WUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
+#define DN_BH_LOCK_ASSERT() mtx_assert(&dn_cfg.uh_mtx, MA_OWNED)
+
+SLIST_HEAD(dn_schk_head, dn_schk);
+SLIST_HEAD(dn_sch_inst_head, dn_sch_inst);
+SLIST_HEAD(dn_fsk_head, dn_fsk);
+SLIST_HEAD(dn_queue_head, dn_queue);
+SLIST_HEAD(dn_alg_head, dn_alg);
+
+struct mq { /* a basic queue of packets*/
+ struct mbuf *head, *tail;
+};
+
+static inline void
+set_oid(struct dn_id *o, int type, int len)
+{
+ o->type = type;
+ o->len = len;
+ o->subtype = 0;
+};
+
+/*
+ * configuration and global data for a dummynet instance
+ *
+ * When a configuration is modified from userland, 'id' is incremented
+ * so we can use the value to check for stale pointers.
+ */
+struct dn_parms {
+ uint32_t id; /* configuration version */
+
+ /* defaults (sysctl-accessible) */
+ int red_lookup_depth;
+ int red_avg_pkt_size;
+ int red_max_pkt_size;
+ int hash_size;
+ int max_hash_size;
+ long byte_limit; /* max queue sizes */
+ long slot_limit;
+
+ int io_fast;
+ int debug;
+
+ /* timekeeping */
+ struct timeval prev_t; /* last time dummynet_tick ran */
+ struct dn_heap evheap; /* scheduled events */
+
+ /* counters of objects -- used for reporting space */
+ int schk_count;
+ int si_count;
+ int fsk_count;
+ int queue_count;
+
+ /* ticks and other stuff */
+ uint64_t curr_time;
+ /* flowsets and schedulers are in hash tables, with 'hash_size'
+ * buckets. fshash is looked up at every packet arrival
+ * so better be generous if we expect many entries.
+ */
+ struct dn_ht *fshash;
+ struct dn_ht *schedhash;
+ /* list of flowsets without a scheduler -- use sch_chain */
+ struct dn_fsk_head fsu; /* list of unlinked flowsets */
+ struct dn_alg_head schedlist; /* list of algorithms */
+
+ /* Store the fs/sch to scan when draining. The value is the
+ * bucket number of the hash table. Expire can be disabled
+ * with net.inet.ip.dummynet.expire=0, or it happens every
+ * expire ticks.
+ **/
+ int drain_fs;
+ int drain_sch;
+ uint32_t expire;
+ uint32_t expire_cycle; /* tick count */
+
+ int init_done;
+
+ /* if the upper half is busy doing something long,
+ * can set the busy flag and we will enqueue packets in
+ * a queue for later processing.
+ */
+ int busy;
+ struct mq pending;
+
+#ifdef _KERNEL
+ /*
+ * This file is normally used in the kernel, unless we do
+ * some userland tests, in which case we do not need a mtx.
+ * uh_mtx arbitrates between system calls and also
+ * protects fshash, schedhash and fsunlinked.
+ * These structures are readonly for the lower half.
+ * bh_mtx protects all other structures which may be
+ * modified upon packet arrivals
+ */
+#if defined( __linux__ ) || defined( _WIN32 )
+ spinlock_t uh_mtx;
+ spinlock_t bh_mtx;
+#else
+ struct mtx uh_mtx;
+ struct mtx bh_mtx;
+#endif
+
+#endif /* _KERNEL */
+};
+
+/*
+ * Delay line, contains all packets on output from a link.
+ * Every scheduler instance has one.
+ */
+struct delay_line {
+ struct dn_id oid;
+ struct dn_sch_inst *si;
+ struct mq mq;
+};
+
+/*
+ * The kernel side of a flowset. It is linked in a hash table
+ * of flowsets, and in a list of children of their parent scheduler.
+ * qht is either the queue or (if HAVE_MASK) a hash table queues.
+ * Note that the mask to use is the (flow_mask|sched_mask), which
+ * changes as we attach/detach schedulers. So we store it here.
+ *
+ * XXX If we want to add scheduler-specific parameters, we need to
+ * put them in external storage because the scheduler may not be
+ * available when the fsk is created.
+ */
+struct dn_fsk { /* kernel side of a flowset */
+ struct dn_fs fs;
+ SLIST_ENTRY(dn_fsk) fsk_next; /* hash chain for fshash */
+
+ struct ipfw_flow_id fsk_mask;
+
+ /* qht is a hash table of queues, or just a single queue
+ * a bit in fs.flags tells us which one
+ */
+ struct dn_ht *qht;
+ struct dn_schk *sched; /* Sched we are linked to */
+ SLIST_ENTRY(dn_fsk) sch_chain; /* list of fsk attached to sched */
+
+ /* bucket index used by drain routine to drain queues for this
+ * flowset
+ */
+ int drain_bucket;
+ /* Parameter realted to RED / GRED */
+ /* original values are in dn_fs*/
+ int w_q ; /* queue weight (scaled) */
+ int max_th ; /* maximum threshold for queue (scaled) */
+ int min_th ; /* minimum threshold for queue (scaled) */
+ int max_p ; /* maximum value for p_b (scaled) */
+
+ u_int c_1 ; /* max_p/(max_th-min_th) (scaled) */
+ u_int c_2 ; /* max_p*min_th/(max_th-min_th) (scaled) */
+ u_int c_3 ; /* for GRED, (1-max_p)/max_th (scaled) */
+ u_int c_4 ; /* for GRED, 1 - 2*max_p (scaled) */
+ u_int * w_q_lookup ; /* lookup table for computing (1-w_q)^t */
+ u_int lookup_depth ; /* depth of lookup table */
+ int lookup_step ; /* granularity inside the lookup table */
+ int lookup_weight ; /* equal to (1-w_q)^t / (1-w_q)^(t+1) */
+ int avg_pkt_size ; /* medium packet size */
+ int max_pkt_size ; /* max packet size */
+};
+
+/*
+ * A queue is created as a child of a flowset unless it belongs to
+ * a !MULTIQUEUE scheduler. It is normally in a hash table in the
+ * flowset. fs always points to the parent flowset.
+ * si normally points to the sch_inst, unless the flowset has been
+ * detached from the scheduler -- in this case si == NULL and we
+ * should not enqueue.
+ */
+struct dn_queue {
+ struct dn_flow ni; /* oid, flow_id, stats */
+ struct mq mq; /* packets queue */
+ struct dn_sch_inst *_si; /* owner scheduler instance */
+ SLIST_ENTRY(dn_queue) q_next; /* hash chain list for qht */
+ struct dn_fsk *fs; /* parent flowset. */
+
+ /* RED parameters */
+ int avg; /* average queue length est. (scaled) */
+ int count; /* arrivals since last RED drop */
+ int random; /* random value (scaled) */
+ uint64_t q_time; /* start of queue idle time */
+
+};
+
+/*
+ * The kernel side of a scheduler. Contains the userland config,
+ * a link, pointer to extra config arguments from command line,
+ * kernel flags, and a pointer to the scheduler methods.
+ * It is stored in a hash table, and holds a list of all
+ * flowsets and scheduler instances.
+ * XXX sch must be at the beginning, see schk_hash().
+ */
+struct dn_schk {
+ struct dn_sch sch;
+ struct dn_alg *fp; /* Pointer to scheduler functions */
+ struct dn_link link; /* The link, embedded */
+ struct dn_profile *profile; /* delay profile, if any */
+ struct dn_id *cfg; /* extra config arguments */
+
+ SLIST_ENTRY(dn_schk) schk_next; /* hash chain for schedhash */
+
+ struct dn_fsk_head fsk_list; /* all fsk linked to me */
+ struct dn_fsk *fs; /* Flowset for !MULTIQUEUE */
+
+ /* bucket index used by the drain routine to drain the scheduler
+ * instance for this flowset.
+ */
+ int drain_bucket;
+
+ /* Hash table of all instances (through sch.sched_mask)
+ * or single instance if no mask. Always valid.
+ */
+ struct dn_ht *siht;
+};
+
+
+/*
+ * Scheduler instance.
+ * Contains variables and all queues relative to a this instance.
+ * This struct is created a runtime.
+ */
+struct dn_sch_inst {
+ struct dn_flow ni; /* oid, flowid and stats */
+ SLIST_ENTRY(dn_sch_inst) si_next; /* hash chain for siht */
+ struct delay_line dline;
+ struct dn_schk *sched; /* the template */
+ int kflags; /* DN_ACTIVE */
+
+ int64_t credit; /* bits I can transmit (more or less). */
+ uint64_t sched_time; /* time link was scheduled in ready_heap */
+ uint64_t idle_time; /* start of scheduler instance idle time */
+
+ /* q_count is the number of queues that this instance is using.
+ * The counter is incremented or decremented when
+ * a reference from the queue is created or deleted.
+ * It is used to make sure that a scheduler instance can be safely
+ * deleted by the drain routine. See notes below.
+ */
+ int q_count;
+
+};
+
+/*
+ * NOTE about object drain.
+ * The system will automatically (XXX check when) drain queues and
+ * scheduler instances when they are idle.
+ * A queue is idle when it has no packets; an instance is idle when
+ * it is not in the evheap heap, and the corresponding delay line is empty.
+ * A queue can be safely deleted when it is idle because of the scheduler
+ * function xxx_free_queue() will remove any references to it.
+ * An instance can be only deleted when no queues reference it. To be sure
+ * of that, a counter (q_count) stores the number of queues that are pointing
+ * to the instance.
+ *
+ * XXX
+ * Order of scan:
+ * - take all flowset in a bucket for the flowset hash table
+ * - take all queues in a bucket for the flowset
+ * - increment the queue bucket
+ * - scan next flowset bucket
+ * Nothing is done if a bucket contains no entries.
+ *
+ * The same schema is used for sceduler instances
+ */
+
+
+/* kernel-side flags. Linux has DN_DELETE in fcntl.h
+ */
+enum {
+ /* 1 and 2 are reserved for the SCAN flags */
+ DN_DESTROY = 0x0004, /* destroy */
+ DN_DELETE_FS = 0x0008, /* destroy flowset */
+ DN_DETACH = 0x0010,
+ DN_ACTIVE = 0x0020, /* object is in evheap */
+ DN_F_DLINE = 0x0040, /* object is a delay line */
+ DN_DEL_SAFE = 0x0080, /* delete a queue only if no longer needed
+ * by scheduler */
+ DN_QHT_IS_Q = 0x0100, /* in flowset, qht is a single queue */
+};
+
+extern struct dn_parms dn_cfg;
+//VNET_DECLARE(struct dn_parms, _base_dn_cfg);
+//#define dn_cfg VNET(_base_dn_cfg)
+
+int dummynet_io(struct mbuf **, int , struct ip_fw_args *);
+void dummynet_task(void *context, int pending);
+void dn_reschedule(void);
+
+struct dn_queue *ipdn_q_find(struct dn_fsk *, struct dn_sch_inst *,
+ struct ipfw_flow_id *);
+struct dn_sch_inst *ipdn_si_find(struct dn_schk *, struct ipfw_flow_id *);
+
+/*
+ * copy_range is a template for requests for ranges of pipes/queues/scheds.
+ * The number of ranges is variable and can be derived by o.len.
+ * As a default, we use a small number of entries so that the struct
+ * fits easily on the stack and is sufficient for most common requests.
+ */
+#define DEFAULT_RANGES 5
+struct copy_range {
+ struct dn_id o;
+ uint32_t r[ 2 * DEFAULT_RANGES ];
+};
+
+struct copy_args {
+ char **start;
+ char *end;
+ int flags;
+ int type;
+ struct copy_range *extra; /* extra filtering */
+};
+
+struct sockopt;
+int ip_dummynet_compat(struct sockopt *sopt);
+int dummynet_get(struct sockopt *sopt, void **compat);
+int dn_c_copy_q (void *_ni, void *arg);
+int dn_c_copy_pipe(struct dn_schk *s, struct copy_args *a, int nq);
+int dn_c_copy_fs(struct dn_fsk *f, struct copy_args *a, int nq);
+int dn_compat_copy_queue(struct copy_args *a, void *_o);
+int dn_compat_copy_pipe(struct copy_args *a, void *_o);
+int copy_data_helper_compat(void *_o, void *_arg);
+int dn_compat_calc_size(void);
+int do_config(void *p, int l);
+
+/* function to drain idle object */
+void dn_drain_scheduler(void);
+void dn_drain_queue(void);
+
+#endif /* _IP_DN_PRIVATE_H */
diff --git a/sys/netinet/ipfw/ip_dummynet.c b/sys/netinet/ipfw/ip_dummynet.c
new file mode 100644
index 0000000..928176e
--- /dev/null
+++ b/sys/netinet/ipfw/ip_dummynet.c
@@ -0,0 +1,2313 @@
+/*-
+ * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
+ * Portions Copyright (c) 2000 Akamba Corp.
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Configuration and internal object management for dummynet.
+ */
+
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/time.h>
+#include <sys/taskqueue.h>
+#include <net/if.h> /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* ip_output(), IP_FORWARDING */
+#include <netinet/ip_fw.h>
+#include <netinet/ipfw/ip_fw_private.h>
+#include <netinet/ipfw/dn_heap.h>
+#include <netinet/ip_dummynet.h>
+#include <netinet/ipfw/ip_dn_private.h>
+#include <netinet/ipfw/dn_sched.h>
+
+/* which objects to copy */
+#define DN_C_LINK 0x01
+#define DN_C_SCH 0x02
+#define DN_C_FLOW 0x04
+#define DN_C_FS 0x08
+#define DN_C_QUEUE 0x10
+
+/* we use this argument in case of a schk_new */
+struct schk_new_arg {
+ struct dn_alg *fp;
+ struct dn_sch *sch;
+};
+
+/*---- callout hooks. ----*/
+static struct callout dn_timeout;
+static struct task dn_task;
+static struct taskqueue *dn_tq = NULL;
+
+static void
+dummynet(void * __unused unused)
+{
+
+ taskqueue_enqueue(dn_tq, &dn_task);
+}
+
+void
+dn_reschedule(void)
+{
+ callout_reset(&dn_timeout, 1, dummynet, NULL);
+}
+/*----- end of callout hooks -----*/
+
+/* Return a scheduler descriptor given the type or name. */
+static struct dn_alg *
+find_sched_type(int type, char *name)
+{
+ struct dn_alg *d;
+
+ SLIST_FOREACH(d, &dn_cfg.schedlist, next) {
+ if (d->type == type || (name && !strcasecmp(d->name, name)))
+ return d;
+ }
+ return NULL; /* not found */
+}
+
+int
+ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg)
+{
+ int oldv = *v;
+ const char *op = NULL;
+ if (dflt < lo)
+ dflt = lo;
+ if (dflt > hi)
+ dflt = hi;
+ if (oldv < lo) {
+ *v = dflt;
+ op = "Bump";
+ } else if (oldv > hi) {
+ *v = hi;
+ op = "Clamp";
+ } else
+ return *v;
+ if (op && msg)
+ printf("%s %s to %d (was %d)\n", op, msg, *v, oldv);
+ return *v;
+}
+
+/*---- flow_id mask, hash and compare functions ---*/
+/*
+ * The flow_id includes the 5-tuple, the queue/pipe number
+ * which we store in the extra area in host order,
+ * and for ipv6 also the flow_id6.
+ * XXX see if we want the tos byte (can store in 'flags')
+ */
+static struct ipfw_flow_id *
+flow_id_mask(struct ipfw_flow_id *mask, struct ipfw_flow_id *id)
+{
+ int is_v6 = IS_IP6_FLOW_ID(id);
+
+ id->dst_port &= mask->dst_port;
+ id->src_port &= mask->src_port;
+ id->proto &= mask->proto;
+ id->extra &= mask->extra;
+ if (is_v6) {
+ APPLY_MASK(&id->dst_ip6, &mask->dst_ip6);
+ APPLY_MASK(&id->src_ip6, &mask->src_ip6);
+ id->flow_id6 &= mask->flow_id6;
+ } else {
+ id->dst_ip &= mask->dst_ip;
+ id->src_ip &= mask->src_ip;
+ }
+ return id;
+}
+
+/* computes an OR of two masks, result in dst and also returned */
+static struct ipfw_flow_id *
+flow_id_or(struct ipfw_flow_id *src, struct ipfw_flow_id *dst)
+{
+ int is_v6 = IS_IP6_FLOW_ID(dst);
+
+ dst->dst_port |= src->dst_port;
+ dst->src_port |= src->src_port;
+ dst->proto |= src->proto;
+ dst->extra |= src->extra;
+ if (is_v6) {
+#define OR_MASK(_d, _s) \
+ (_d)->__u6_addr.__u6_addr32[0] |= (_s)->__u6_addr.__u6_addr32[0]; \
+ (_d)->__u6_addr.__u6_addr32[1] |= (_s)->__u6_addr.__u6_addr32[1]; \
+ (_d)->__u6_addr.__u6_addr32[2] |= (_s)->__u6_addr.__u6_addr32[2]; \
+ (_d)->__u6_addr.__u6_addr32[3] |= (_s)->__u6_addr.__u6_addr32[3];
+ OR_MASK(&dst->dst_ip6, &src->dst_ip6);
+ OR_MASK(&dst->src_ip6, &src->src_ip6);
+#undef OR_MASK
+ dst->flow_id6 |= src->flow_id6;
+ } else {
+ dst->dst_ip |= src->dst_ip;
+ dst->src_ip |= src->src_ip;
+ }
+ return dst;
+}
+
+static int
+nonzero_mask(struct ipfw_flow_id *m)
+{
+ if (m->dst_port || m->src_port || m->proto || m->extra)
+ return 1;
+ if (IS_IP6_FLOW_ID(m)) {
+ return
+ m->dst_ip6.__u6_addr.__u6_addr32[0] ||
+ m->dst_ip6.__u6_addr.__u6_addr32[1] ||
+ m->dst_ip6.__u6_addr.__u6_addr32[2] ||
+ m->dst_ip6.__u6_addr.__u6_addr32[3] ||
+ m->src_ip6.__u6_addr.__u6_addr32[0] ||
+ m->src_ip6.__u6_addr.__u6_addr32[1] ||
+ m->src_ip6.__u6_addr.__u6_addr32[2] ||
+ m->src_ip6.__u6_addr.__u6_addr32[3] ||
+ m->flow_id6;
+ } else {
+ return m->dst_ip || m->src_ip;
+ }
+}
+
+/* XXX we may want a better hash function */
+static uint32_t
+flow_id_hash(struct ipfw_flow_id *id)
+{
+ uint32_t i;
+
+ if (IS_IP6_FLOW_ID(id)) {
+ uint32_t *d = (uint32_t *)&id->dst_ip6;
+ uint32_t *s = (uint32_t *)&id->src_ip6;
+ i = (d[0] ) ^ (d[1]) ^
+ (d[2] ) ^ (d[3]) ^
+ (d[0] >> 15) ^ (d[1] >> 15) ^
+ (d[2] >> 15) ^ (d[3] >> 15) ^
+ (s[0] << 1) ^ (s[1] << 1) ^
+ (s[2] << 1) ^ (s[3] << 1) ^
+ (s[0] << 16) ^ (s[1] << 16) ^
+ (s[2] << 16) ^ (s[3] << 16) ^
+ (id->dst_port << 1) ^ (id->src_port) ^
+ (id->extra) ^
+ (id->proto ) ^ (id->flow_id6);
+ } else {
+ i = (id->dst_ip) ^ (id->dst_ip >> 15) ^
+ (id->src_ip << 1) ^ (id->src_ip >> 16) ^
+ (id->extra) ^
+ (id->dst_port << 1) ^ (id->src_port) ^ (id->proto);
+ }
+ return i;
+}
+
+/* Like bcmp, returns 0 if ids match, 1 otherwise. */
+static int
+flow_id_cmp(struct ipfw_flow_id *id1, struct ipfw_flow_id *id2)
+{
+ int is_v6 = IS_IP6_FLOW_ID(id1);
+
+ if (!is_v6) {
+ if (IS_IP6_FLOW_ID(id2))
+ return 1; /* different address families */
+
+ return (id1->dst_ip == id2->dst_ip &&
+ id1->src_ip == id2->src_ip &&
+ id1->dst_port == id2->dst_port &&
+ id1->src_port == id2->src_port &&
+ id1->proto == id2->proto &&
+ id1->extra == id2->extra) ? 0 : 1;
+ }
+ /* the ipv6 case */
+ return (
+ !bcmp(&id1->dst_ip6,&id2->dst_ip6, sizeof(id1->dst_ip6)) &&
+ !bcmp(&id1->src_ip6,&id2->src_ip6, sizeof(id1->src_ip6)) &&
+ id1->dst_port == id2->dst_port &&
+ id1->src_port == id2->src_port &&
+ id1->proto == id2->proto &&
+ id1->extra == id2->extra &&
+ id1->flow_id6 == id2->flow_id6) ? 0 : 1;
+}
+/*--------- end of flow-id mask, hash and compare ---------*/
+
+/*--- support functions for the qht hashtable ----
+ * Entries are hashed by flow-id
+ */
+static uint32_t
+q_hash(uintptr_t key, int flags, void *arg)
+{
+ /* compute the hash slot from the flow id */
+ struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ?
+ &((struct dn_queue *)key)->ni.fid :
+ (struct ipfw_flow_id *)key;
+
+ return flow_id_hash(id);
+}
+
+static int
+q_match(void *obj, uintptr_t key, int flags, void *arg)
+{
+ struct dn_queue *o = (struct dn_queue *)obj;
+ struct ipfw_flow_id *id2;
+
+ if (flags & DNHT_KEY_IS_OBJ) {
+ /* compare pointers */
+ id2 = &((struct dn_queue *)key)->ni.fid;
+ } else {
+ id2 = (struct ipfw_flow_id *)key;
+ }
+ return (0 == flow_id_cmp(&o->ni.fid, id2));
+}
+
+/*
+ * create a new queue instance for the given 'key'.
+ */
+static void *
+q_new(uintptr_t key, int flags, void *arg)
+{
+ struct dn_queue *q, *template = arg;
+ struct dn_fsk *fs = template->fs;
+ int size = sizeof(*q) + fs->sched->fp->q_datalen;
+
+ q = malloc(size, M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (q == NULL) {
+ D("no memory for new queue");
+ return NULL;
+ }
+
+ set_oid(&q->ni.oid, DN_QUEUE, size);
+ if (fs->fs.flags & DN_QHT_HASH)
+ q->ni.fid = *(struct ipfw_flow_id *)key;
+ q->fs = fs;
+ q->_si = template->_si;
+ q->_si->q_count++;
+
+ if (fs->sched->fp->new_queue)
+ fs->sched->fp->new_queue(q);
+ dn_cfg.queue_count++;
+ return q;
+}
+
+/*
+ * Notify schedulers that a queue is going away.
+ * If (flags & DN_DESTROY), also free the packets.
+ * The version for callbacks is called q_delete_cb().
+ */
+static void
+dn_delete_queue(struct dn_queue *q, int flags)
+{
+ struct dn_fsk *fs = q->fs;
+
+ // D("fs %p si %p\n", fs, q->_si);
+ /* notify the parent scheduler that the queue is going away */
+ if (fs && fs->sched->fp->free_queue)
+ fs->sched->fp->free_queue(q);
+ q->_si->q_count--;
+ q->_si = NULL;
+ if (flags & DN_DESTROY) {
+ if (q->mq.head)
+ dn_free_pkts(q->mq.head);
+ bzero(q, sizeof(*q)); // safety
+ free(q, M_DUMMYNET);
+ dn_cfg.queue_count--;
+ }
+}
+
+static int
+q_delete_cb(void *q, void *arg)
+{
+ int flags = (int)(uintptr_t)arg;
+ dn_delete_queue(q, flags);
+ return (flags & DN_DESTROY) ? DNHT_SCAN_DEL : 0;
+}
+
+/*
+ * calls dn_delete_queue/q_delete_cb on all queues,
+ * which notifies the parent scheduler and possibly drains packets.
+ * flags & DN_DESTROY: drains queues and destroy qht;
+ */
+static void
+qht_delete(struct dn_fsk *fs, int flags)
+{
+ ND("fs %d start flags %d qht %p",
+ fs->fs.fs_nr, flags, fs->qht);
+ if (!fs->qht)
+ return;
+ if (fs->fs.flags & DN_QHT_HASH) {
+ dn_ht_scan(fs->qht, q_delete_cb, (void *)(uintptr_t)flags);
+ if (flags & DN_DESTROY) {
+ dn_ht_free(fs->qht, 0);
+ fs->qht = NULL;
+ }
+ } else {
+ dn_delete_queue((struct dn_queue *)(fs->qht), flags);
+ if (flags & DN_DESTROY)
+ fs->qht = NULL;
+ }
+}
+
+/*
+ * Find and possibly create the queue for a MULTIQUEUE scheduler.
+ * We never call it for !MULTIQUEUE (the queue is in the sch_inst).
+ */
+struct dn_queue *
+ipdn_q_find(struct dn_fsk *fs, struct dn_sch_inst *si,
+ struct ipfw_flow_id *id)
+{
+ struct dn_queue template;
+
+ template._si = si;
+ template.fs = fs;
+
+ if (fs->fs.flags & DN_QHT_HASH) {
+ struct ipfw_flow_id masked_id;
+ if (fs->qht == NULL) {
+ fs->qht = dn_ht_init(NULL, fs->fs.buckets,
+ offsetof(struct dn_queue, q_next),
+ q_hash, q_match, q_new);
+ if (fs->qht == NULL)
+ return NULL;
+ }
+ masked_id = *id;
+ flow_id_mask(&fs->fsk_mask, &masked_id);
+ return dn_ht_find(fs->qht, (uintptr_t)&masked_id,
+ DNHT_INSERT, &template);
+ } else {
+ if (fs->qht == NULL)
+ fs->qht = q_new(0, 0, &template);
+ return (struct dn_queue *)fs->qht;
+ }
+}
+/*--- end of queue hash table ---*/
+
+/*--- support functions for the sch_inst hashtable ----
+ *
+ * These are hashed by flow-id
+ */
+static uint32_t
+si_hash(uintptr_t key, int flags, void *arg)
+{
+ /* compute the hash slot from the flow id */
+ struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ?
+ &((struct dn_sch_inst *)key)->ni.fid :
+ (struct ipfw_flow_id *)key;
+
+ return flow_id_hash(id);
+}
+
+static int
+si_match(void *obj, uintptr_t key, int flags, void *arg)
+{
+ struct dn_sch_inst *o = obj;
+ struct ipfw_flow_id *id2;
+
+ id2 = (flags & DNHT_KEY_IS_OBJ) ?
+ &((struct dn_sch_inst *)key)->ni.fid :
+ (struct ipfw_flow_id *)key;
+ return flow_id_cmp(&o->ni.fid, id2) == 0;
+}
+
+/*
+ * create a new instance for the given 'key'
+ * Allocate memory for instance, delay line and scheduler private data.
+ */
+static void *
+si_new(uintptr_t key, int flags, void *arg)
+{
+ struct dn_schk *s = arg;
+ struct dn_sch_inst *si;
+ int l = sizeof(*si) + s->fp->si_datalen;
+
+ si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (si == NULL)
+ goto error;
+
+ /* Set length only for the part passed up to userland. */
+ set_oid(&si->ni.oid, DN_SCH_I, sizeof(struct dn_flow));
+ set_oid(&(si->dline.oid), DN_DELAY_LINE,
+ sizeof(struct delay_line));
+ /* mark si and dline as outside the event queue */
+ si->ni.oid.id = si->dline.oid.id = -1;
+
+ si->sched = s;
+ si->dline.si = si;
+
+ if (s->fp->new_sched && s->fp->new_sched(si)) {
+ D("new_sched error");
+ goto error;
+ }
+ if (s->sch.flags & DN_HAVE_MASK)
+ si->ni.fid = *(struct ipfw_flow_id *)key;
+
+ dn_cfg.si_count++;
+ return si;
+
+error:
+ if (si) {
+ bzero(si, sizeof(*si)); // safety
+ free(si, M_DUMMYNET);
+ }
+ return NULL;
+}
+
+/*
+ * Callback from siht to delete all scheduler instances. Remove
+ * si and delay line from the system heap, destroy all queues.
+ * We assume that all flowset have been notified and do not
+ * point to us anymore.
+ */
+static int
+si_destroy(void *_si, void *arg)
+{
+ struct dn_sch_inst *si = _si;
+ struct dn_schk *s = si->sched;
+ struct delay_line *dl = &si->dline;
+
+ if (dl->oid.subtype) /* remove delay line from event heap */
+ heap_extract(&dn_cfg.evheap, dl);
+ dn_free_pkts(dl->mq.head); /* drain delay line */
+ if (si->kflags & DN_ACTIVE) /* remove si from event heap */
+ heap_extract(&dn_cfg.evheap, si);
+ if (s->fp->free_sched)
+ s->fp->free_sched(si);
+ bzero(si, sizeof(*si)); /* safety */
+ free(si, M_DUMMYNET);
+ dn_cfg.si_count--;
+ return DNHT_SCAN_DEL;
+}
+
+/*
+ * Find the scheduler instance for this packet. If we need to apply
+ * a mask, do on a local copy of the flow_id to preserve the original.
+ * Assume siht is always initialized if we have a mask.
+ */
+struct dn_sch_inst *
+ipdn_si_find(struct dn_schk *s, struct ipfw_flow_id *id)
+{
+
+ if (s->sch.flags & DN_HAVE_MASK) {
+ struct ipfw_flow_id id_t = *id;
+ flow_id_mask(&s->sch.sched_mask, &id_t);
+ return dn_ht_find(s->siht, (uintptr_t)&id_t,
+ DNHT_INSERT, s);
+ }
+ if (!s->siht)
+ s->siht = si_new(0, 0, s);
+ return (struct dn_sch_inst *)s->siht;
+}
+
+/* callback to flush credit for the scheduler instance */
+static int
+si_reset_credit(void *_si, void *arg)
+{
+ struct dn_sch_inst *si = _si;
+ struct dn_link *p = &si->sched->link;
+
+ si->credit = p->burst + (dn_cfg.io_fast ? p->bandwidth : 0);
+ return 0;
+}
+
+static void
+schk_reset_credit(struct dn_schk *s)
+{
+ if (s->sch.flags & DN_HAVE_MASK)
+ dn_ht_scan(s->siht, si_reset_credit, NULL);
+ else if (s->siht)
+ si_reset_credit(s->siht, NULL);
+}
+/*---- end of sch_inst hashtable ---------------------*/
+
+/*-------------------------------------------------------
+ * flowset hash (fshash) support. Entries are hashed by fs_nr.
+ * New allocations are put in the fsunlinked list, from which
+ * they are removed when they point to a specific scheduler.
+ */
+static uint32_t
+fsk_hash(uintptr_t key, int flags, void *arg)
+{
+ uint32_t i = !(flags & DNHT_KEY_IS_OBJ) ? key :
+ ((struct dn_fsk *)key)->fs.fs_nr;
+
+ return ( (i>>8)^(i>>4)^i );
+}
+
+static int
+fsk_match(void *obj, uintptr_t key, int flags, void *arg)
+{
+ struct dn_fsk *fs = obj;
+ int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
+ ((struct dn_fsk *)key)->fs.fs_nr;
+
+ return (fs->fs.fs_nr == i);
+}
+
+static void *
+fsk_new(uintptr_t key, int flags, void *arg)
+{
+ struct dn_fsk *fs;
+
+ fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (fs) {
+ set_oid(&fs->fs.oid, DN_FS, sizeof(fs->fs));
+ dn_cfg.fsk_count++;
+ fs->drain_bucket = 0;
+ SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain);
+ }
+ return fs;
+}
+
+/*
+ * detach flowset from its current scheduler. Flags as follows:
+ * DN_DETACH removes from the fsk_list
+ * DN_DESTROY deletes individual queues
+ * DN_DELETE_FS destroys the flowset (otherwise goes in unlinked).
+ */
+static void
+fsk_detach(struct dn_fsk *fs, int flags)
+{
+ if (flags & DN_DELETE_FS)
+ flags |= DN_DESTROY;
+ ND("fs %d from sched %d flags %s %s %s",
+ fs->fs.fs_nr, fs->fs.sched_nr,
+ (flags & DN_DELETE_FS) ? "DEL_FS":"",
+ (flags & DN_DESTROY) ? "DEL":"",
+ (flags & DN_DETACH) ? "DET":"");
+ if (flags & DN_DETACH) { /* detach from the list */
+ struct dn_fsk_head *h;
+ h = fs->sched ? &fs->sched->fsk_list : &dn_cfg.fsu;
+ SLIST_REMOVE(h, fs, dn_fsk, sch_chain);
+ }
+ /* Free the RED parameters, they will be recomputed on
+ * subsequent attach if needed.
+ */
+ if (fs->w_q_lookup)
+ free(fs->w_q_lookup, M_DUMMYNET);
+ fs->w_q_lookup = NULL;
+ qht_delete(fs, flags);
+ if (fs->sched && fs->sched->fp->free_fsk)
+ fs->sched->fp->free_fsk(fs);
+ fs->sched = NULL;
+ if (flags & DN_DELETE_FS) {
+ bzero(fs, sizeof(fs)); /* safety */
+ free(fs, M_DUMMYNET);
+ dn_cfg.fsk_count--;
+ } else {
+ SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain);
+ }
+}
+
+/*
+ * Detach or destroy all flowsets in a list.
+ * flags specifies what to do:
+ * DN_DESTROY: flush all queues
+ * DN_DELETE_FS: DN_DESTROY + destroy flowset
+ * DN_DELETE_FS implies DN_DESTROY
+ */
+static void
+fsk_detach_list(struct dn_fsk_head *h, int flags)
+{
+ struct dn_fsk *fs;
+ int n = 0; /* only for stats */
+
+ ND("head %p flags %x", h, flags);
+ while ((fs = SLIST_FIRST(h))) {
+ SLIST_REMOVE_HEAD(h, sch_chain);
+ n++;
+ fsk_detach(fs, flags);
+ }
+ ND("done %d flowsets", n);
+}
+
+/*
+ * called on 'queue X delete' -- removes the flowset from fshash,
+ * deletes all queues for the flowset, and removes the flowset.
+ */
+static int
+delete_fs(int i, int locked)
+{
+ struct dn_fsk *fs;
+ int err = 0;
+
+ if (!locked)
+ DN_BH_WLOCK();
+ fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL);
+ ND("fs %d found %p", i, fs);
+ if (fs) {
+ fsk_detach(fs, DN_DETACH | DN_DELETE_FS);
+ err = 0;
+ } else
+ err = EINVAL;
+ if (!locked)
+ DN_BH_WUNLOCK();
+ return err;
+}
+
+/*----- end of flowset hashtable support -------------*/
+
+/*------------------------------------------------------------
+ * Scheduler hash. When searching by index we pass sched_nr,
+ * otherwise we pass struct dn_sch * which is the first field in
+ * struct dn_schk so we can cast between the two. We use this trick
+ * because in the create phase (but it should be fixed).
+ */
+static uint32_t
+schk_hash(uintptr_t key, int flags, void *_arg)
+{
+ uint32_t i = !(flags & DNHT_KEY_IS_OBJ) ? key :
+ ((struct dn_schk *)key)->sch.sched_nr;
+ return ( (i>>8)^(i>>4)^i );
+}
+
+static int
+schk_match(void *obj, uintptr_t key, int flags, void *_arg)
+{
+ struct dn_schk *s = (struct dn_schk *)obj;
+ int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
+ ((struct dn_schk *)key)->sch.sched_nr;
+ return (s->sch.sched_nr == i);
+}
+
+/*
+ * Create the entry and intialize with the sched hash if needed.
+ * Leave s->fp unset so we can tell whether a dn_ht_find() returns
+ * a new object or a previously existing one.
+ */
+static void *
+schk_new(uintptr_t key, int flags, void *arg)
+{
+ struct schk_new_arg *a = arg;
+ struct dn_schk *s;
+ int l = sizeof(*s) +a->fp->schk_datalen;
+
+ s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (s == NULL)
+ return NULL;
+ set_oid(&s->link.oid, DN_LINK, sizeof(s->link));
+ s->sch = *a->sch; // copy initial values
+ s->link.link_nr = s->sch.sched_nr;
+ SLIST_INIT(&s->fsk_list);
+ /* initialize the hash table or create the single instance */
+ s->fp = a->fp; /* si_new needs this */
+ s->drain_bucket = 0;
+ if (s->sch.flags & DN_HAVE_MASK) {
+ s->siht = dn_ht_init(NULL, s->sch.buckets,
+ offsetof(struct dn_sch_inst, si_next),
+ si_hash, si_match, si_new);
+ if (s->siht == NULL) {
+ free(s, M_DUMMYNET);
+ return NULL;
+ }
+ }
+ s->fp = NULL; /* mark as a new scheduler */
+ dn_cfg.schk_count++;
+ return s;
+}
+
+/*
+ * Callback for sched delete. Notify all attached flowsets to
+ * detach from the scheduler, destroy the internal flowset, and
+ * all instances. The scheduler goes away too.
+ * arg is 0 (only detach flowsets and destroy instances)
+ * DN_DESTROY (detach & delete queues, delete schk)
+ * or DN_DELETE_FS (delete queues and flowsets, delete schk)
+ */
+static int
+schk_delete_cb(void *obj, void *arg)
+{
+ struct dn_schk *s = obj;
+#if 0
+ int a = (int)arg;
+ ND("sched %d arg %s%s",
+ s->sch.sched_nr,
+ a&DN_DESTROY ? "DEL ":"",
+ a&DN_DELETE_FS ? "DEL_FS":"");
+#endif
+ fsk_detach_list(&s->fsk_list, arg ? DN_DESTROY : 0);
+ /* no more flowset pointing to us now */
+ if (s->sch.flags & DN_HAVE_MASK) {
+ dn_ht_scan(s->siht, si_destroy, NULL);
+ dn_ht_free(s->siht, 0);
+ } else if (s->siht)
+ si_destroy(s->siht, NULL);
+ if (s->profile) {
+ free(s->profile, M_DUMMYNET);
+ s->profile = NULL;
+ }
+ s->siht = NULL;
+ if (s->fp->destroy)
+ s->fp->destroy(s);
+ bzero(s, sizeof(*s)); // safety
+ free(obj, M_DUMMYNET);
+ dn_cfg.schk_count--;
+ return DNHT_SCAN_DEL;
+}
+
+/*
+ * called on a 'sched X delete' command. Deletes a single scheduler.
+ * This is done by removing from the schedhash, unlinking all
+ * flowsets and deleting their traffic.
+ */
+static int
+delete_schk(int i)
+{
+ struct dn_schk *s;
+
+ s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
+ ND("%d %p", i, s);
+ if (!s)
+ return EINVAL;
+ delete_fs(i + DN_MAX_ID, 1); /* first delete internal fs */
+ /* then detach flowsets, delete traffic */
+ schk_delete_cb(s, (void*)(uintptr_t)DN_DESTROY);
+ return 0;
+}
+/*--- end of schk hashtable support ---*/
+
+static int
+copy_obj(char **start, char *end, void *_o, const char *msg, int i)
+{
+ struct dn_id *o = _o;
+ int have = end - *start;
+
+ if (have < o->len || o->len == 0 || o->type == 0) {
+ D("(WARN) type %d %s %d have %d need %d",
+ o->type, msg, i, have, o->len);
+ return 1;
+ }
+ ND("type %d %s %d len %d", o->type, msg, i, o->len);
+ bcopy(_o, *start, o->len);
+ if (o->type == DN_LINK) {
+ /* Adjust burst parameter for link */
+ struct dn_link *l = (struct dn_link *)*start;
+ l->burst = div64(l->burst, 8 * hz);
+ l->delay = l->delay * 1000 / hz;
+ } else if (o->type == DN_SCH) {
+ /* Set id->id to the number of instances */
+ struct dn_schk *s = _o;
+ struct dn_id *id = (struct dn_id *)(*start);
+ id->id = (s->sch.flags & DN_HAVE_MASK) ?
+ dn_ht_entries(s->siht) : (s->siht ? 1 : 0);
+ }
+ *start += o->len;
+ return 0;
+}
+
+/* Specific function to copy a queue.
+ * Copies only the user-visible part of a queue (which is in
+ * a struct dn_flow), and sets len accordingly.
+ */
+static int
+copy_obj_q(char **start, char *end, void *_o, const char *msg, int i)
+{
+ struct dn_id *o = _o;
+ int have = end - *start;
+ int len = sizeof(struct dn_flow); /* see above comment */
+
+ if (have < len || o->len == 0 || o->type != DN_QUEUE) {
+ D("ERROR type %d %s %d have %d need %d",
+ o->type, msg, i, have, len);
+ return 1;
+ }
+ ND("type %d %s %d len %d", o->type, msg, i, len);
+ bcopy(_o, *start, len);
+ ((struct dn_id*)(*start))->len = len;
+ *start += len;
+ return 0;
+}
+
+static int
+copy_q_cb(void *obj, void *arg)
+{
+ struct dn_queue *q = obj;
+ struct copy_args *a = arg;
+ struct dn_flow *ni = (struct dn_flow *)(*a->start);
+ if (copy_obj_q(a->start, a->end, &q->ni, "queue", -1))
+ return DNHT_SCAN_END;
+ ni->oid.type = DN_FLOW; /* override the DN_QUEUE */
+ ni->oid.id = si_hash((uintptr_t)&ni->fid, 0, NULL);
+ return 0;
+}
+
+static int
+copy_q(struct copy_args *a, struct dn_fsk *fs, int flags)
+{
+ if (!fs->qht)
+ return 0;
+ if (fs->fs.flags & DN_QHT_HASH)
+ dn_ht_scan(fs->qht, copy_q_cb, a);
+ else
+ copy_q_cb(fs->qht, a);
+ return 0;
+}
+
+/*
+ * This routine only copies the initial part of a profile ? XXX
+ */
+static int
+copy_profile(struct copy_args *a, struct dn_profile *p)
+{
+ int have = a->end - *a->start;
+ /* XXX here we check for max length */
+ int profile_len = sizeof(struct dn_profile) -
+ ED_MAX_SAMPLES_NO*sizeof(int);
+
+ if (p == NULL)
+ return 0;
+ if (have < profile_len) {
+ D("error have %d need %d", have, profile_len);
+ return 1;
+ }
+ bcopy(p, *a->start, profile_len);
+ ((struct dn_id *)(*a->start))->len = profile_len;
+ *a->start += profile_len;
+ return 0;
+}
+
+static int
+copy_flowset(struct copy_args *a, struct dn_fsk *fs, int flags)
+{
+ struct dn_fs *ufs = (struct dn_fs *)(*a->start);
+ if (!fs)
+ return 0;
+ ND("flowset %d", fs->fs.fs_nr);
+ if (copy_obj(a->start, a->end, &fs->fs, "flowset", fs->fs.fs_nr))
+ return DNHT_SCAN_END;
+ ufs->oid.id = (fs->fs.flags & DN_QHT_HASH) ?
+ dn_ht_entries(fs->qht) : (fs->qht ? 1 : 0);
+ if (flags) { /* copy queues */
+ copy_q(a, fs, 0);
+ }
+ return 0;
+}
+
+static int
+copy_si_cb(void *obj, void *arg)
+{
+ struct dn_sch_inst *si = obj;
+ struct copy_args *a = arg;
+ struct dn_flow *ni = (struct dn_flow *)(*a->start);
+ if (copy_obj(a->start, a->end, &si->ni, "inst",
+ si->sched->sch.sched_nr))
+ return DNHT_SCAN_END;
+ ni->oid.type = DN_FLOW; /* override the DN_SCH_I */
+ ni->oid.id = si_hash((uintptr_t)si, DNHT_KEY_IS_OBJ, NULL);
+ return 0;
+}
+
+static int
+copy_si(struct copy_args *a, struct dn_schk *s, int flags)
+{
+ if (s->sch.flags & DN_HAVE_MASK)
+ dn_ht_scan(s->siht, copy_si_cb, a);
+ else if (s->siht)
+ copy_si_cb(s->siht, a);
+ return 0;
+}
+
+/*
+ * compute a list of children of a scheduler and copy up
+ */
+static int
+copy_fsk_list(struct copy_args *a, struct dn_schk *s, int flags)
+{
+ struct dn_fsk *fs;
+ struct dn_id *o;
+ uint32_t *p;
+
+ int n = 0, space = sizeof(*o);
+ SLIST_FOREACH(fs, &s->fsk_list, sch_chain) {
+ if (fs->fs.fs_nr < DN_MAX_ID)
+ n++;
+ }
+ space += n * sizeof(uint32_t);
+ DX(3, "sched %d has %d flowsets", s->sch.sched_nr, n);
+ if (a->end - *(a->start) < space)
+ return DNHT_SCAN_END;
+ o = (struct dn_id *)(*(a->start));
+ o->len = space;
+ *a->start += o->len;
+ o->type = DN_TEXT;
+ p = (uint32_t *)(o+1);
+ SLIST_FOREACH(fs, &s->fsk_list, sch_chain)
+ if (fs->fs.fs_nr < DN_MAX_ID)
+ *p++ = fs->fs.fs_nr;
+ return 0;
+}
+
+static int
+copy_data_helper(void *_o, void *_arg)
+{
+ struct copy_args *a = _arg;
+ uint32_t *r = a->extra->r; /* start of first range */
+ uint32_t *lim; /* first invalid pointer */
+ int n;
+
+ lim = (uint32_t *)((char *)(a->extra) + a->extra->o.len);
+
+ if (a->type == DN_LINK || a->type == DN_SCH) {
+ /* pipe|sched show, we receive a dn_schk */
+ struct dn_schk *s = _o;
+
+ n = s->sch.sched_nr;
+ if (a->type == DN_SCH && n >= DN_MAX_ID)
+ return 0; /* not a scheduler */
+ if (a->type == DN_LINK && n <= DN_MAX_ID)
+ return 0; /* not a pipe */
+
+ /* see if the object is within one of our ranges */
+ for (;r < lim; r += 2) {
+ if (n < r[0] || n > r[1])
+ continue;
+ /* Found a valid entry, copy and we are done */
+ if (a->flags & DN_C_LINK) {
+ if (copy_obj(a->start, a->end,
+ &s->link, "link", n))
+ return DNHT_SCAN_END;
+ if (copy_profile(a, s->profile))
+ return DNHT_SCAN_END;
+ if (copy_flowset(a, s->fs, 0))
+ return DNHT_SCAN_END;
+ }
+ if (a->flags & DN_C_SCH) {
+ if (copy_obj(a->start, a->end,
+ &s->sch, "sched", n))
+ return DNHT_SCAN_END;
+ /* list all attached flowsets */
+ if (copy_fsk_list(a, s, 0))
+ return DNHT_SCAN_END;
+ }
+ if (a->flags & DN_C_FLOW)
+ copy_si(a, s, 0);
+ break;
+ }
+ } else if (a->type == DN_FS) {
+ /* queue show, skip internal flowsets */
+ struct dn_fsk *fs = _o;
+
+ n = fs->fs.fs_nr;
+ if (n >= DN_MAX_ID)
+ return 0;
+ /* see if the object is within one of our ranges */
+ for (;r < lim; r += 2) {
+ if (n < r[0] || n > r[1])
+ continue;
+ if (copy_flowset(a, fs, 0))
+ return DNHT_SCAN_END;
+ copy_q(a, fs, 0);
+ break; /* we are done */
+ }
+ }
+ return 0;
+}
+
+static inline struct dn_schk *
+locate_scheduler(int i)
+{
+ return dn_ht_find(dn_cfg.schedhash, i, 0, NULL);
+}
+
+/*
+ * red parameters are in fixed point arithmetic.
+ */
+static int
+config_red(struct dn_fsk *fs)
+{
+ int64_t s, idle, weight, w0;
+ int t, i;
+
+ fs->w_q = fs->fs.w_q;
+ fs->max_p = fs->fs.max_p;
+ ND("called");
+ /* Doing stuff that was in userland */
+ i = fs->sched->link.bandwidth;
+ s = (i <= 0) ? 0 :
+ hz * dn_cfg.red_avg_pkt_size * 8 * SCALE(1) / i;
+
+ idle = div64((s * 3) , fs->w_q); /* s, fs->w_q scaled; idle not scaled */
+ fs->lookup_step = div64(idle , dn_cfg.red_lookup_depth);
+ /* fs->lookup_step not scaled, */
+ if (!fs->lookup_step)
+ fs->lookup_step = 1;
+ w0 = weight = SCALE(1) - fs->w_q; //fs->w_q scaled
+
+ for (t = fs->lookup_step; t > 1; --t)
+ weight = SCALE_MUL(weight, w0);
+ fs->lookup_weight = (int)(weight); // scaled
+
+ /* Now doing stuff that was in kerneland */
+ fs->min_th = SCALE(fs->fs.min_th);
+ fs->max_th = SCALE(fs->fs.max_th);
+
+ fs->c_1 = fs->max_p / (fs->fs.max_th - fs->fs.min_th);
+ fs->c_2 = SCALE_MUL(fs->c_1, SCALE(fs->fs.min_th));
+
+ if (fs->fs.flags & DN_IS_GENTLE_RED) {
+ fs->c_3 = (SCALE(1) - fs->max_p) / fs->fs.max_th;
+ fs->c_4 = SCALE(1) - 2 * fs->max_p;
+ }
+
+ /* If the lookup table already exist, free and create it again. */
+ if (fs->w_q_lookup) {
+ free(fs->w_q_lookup, M_DUMMYNET);
+ fs->w_q_lookup = NULL;
+ }
+ if (dn_cfg.red_lookup_depth == 0) {
+ printf("\ndummynet: net.inet.ip.dummynet.red_lookup_depth"
+ "must be > 0\n");
+ fs->fs.flags &= ~DN_IS_RED;
+ fs->fs.flags &= ~DN_IS_GENTLE_RED;
+ return (EINVAL);
+ }
+ fs->lookup_depth = dn_cfg.red_lookup_depth;
+ fs->w_q_lookup = (u_int *)malloc(fs->lookup_depth * sizeof(int),
+ M_DUMMYNET, M_NOWAIT);
+ if (fs->w_q_lookup == NULL) {
+ printf("dummynet: sorry, cannot allocate red lookup table\n");
+ fs->fs.flags &= ~DN_IS_RED;
+ fs->fs.flags &= ~DN_IS_GENTLE_RED;
+ return(ENOSPC);
+ }
+
+ /* Fill the lookup table with (1 - w_q)^x */
+ fs->w_q_lookup[0] = SCALE(1) - fs->w_q;
+
+ for (i = 1; i < fs->lookup_depth; i++)
+ fs->w_q_lookup[i] =
+ SCALE_MUL(fs->w_q_lookup[i - 1], fs->lookup_weight);
+
+ if (dn_cfg.red_avg_pkt_size < 1)
+ dn_cfg.red_avg_pkt_size = 512;
+ fs->avg_pkt_size = dn_cfg.red_avg_pkt_size;
+ if (dn_cfg.red_max_pkt_size < 1)
+ dn_cfg.red_max_pkt_size = 1500;
+ fs->max_pkt_size = dn_cfg.red_max_pkt_size;
+ ND("exit");
+ return 0;
+}
+
+/* Scan all flowset attached to this scheduler and update red */
+static void
+update_red(struct dn_schk *s)
+{
+ struct dn_fsk *fs;
+ SLIST_FOREACH(fs, &s->fsk_list, sch_chain) {
+ if (fs && (fs->fs.flags & DN_IS_RED))
+ config_red(fs);
+ }
+}
+
+/* attach flowset to scheduler s, possibly requeue */
+static void
+fsk_attach(struct dn_fsk *fs, struct dn_schk *s)
+{
+ ND("remove fs %d from fsunlinked, link to sched %d",
+ fs->fs.fs_nr, s->sch.sched_nr);
+ SLIST_REMOVE(&dn_cfg.fsu, fs, dn_fsk, sch_chain);
+ fs->sched = s;
+ SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain);
+ if (s->fp->new_fsk)
+ s->fp->new_fsk(fs);
+ /* XXX compute fsk_mask */
+ fs->fsk_mask = fs->fs.flow_mask;
+ if (fs->sched->sch.flags & DN_HAVE_MASK)
+ flow_id_or(&fs->sched->sch.sched_mask, &fs->fsk_mask);
+ if (fs->qht) {
+ /*
+ * we must drain qht according to the old
+ * type, and reinsert according to the new one.
+ * The requeue is complex -- in general we need to
+ * reclassify every single packet.
+ * For the time being, let's hope qht is never set
+ * when we reach this point.
+ */
+ D("XXX TODO requeue from fs %d to sch %d",
+ fs->fs.fs_nr, s->sch.sched_nr);
+ fs->qht = NULL;
+ }
+ /* set the new type for qht */
+ if (nonzero_mask(&fs->fsk_mask))
+ fs->fs.flags |= DN_QHT_HASH;
+ else
+ fs->fs.flags &= ~DN_QHT_HASH;
+
+ /* XXX config_red() can fail... */
+ if (fs->fs.flags & DN_IS_RED)
+ config_red(fs);
+}
+
+/* update all flowsets which may refer to this scheduler */
+static void
+update_fs(struct dn_schk *s)
+{
+ struct dn_fsk *fs, *tmp;
+
+ SLIST_FOREACH_SAFE(fs, &dn_cfg.fsu, sch_chain, tmp) {
+ if (s->sch.sched_nr != fs->fs.sched_nr) {
+ D("fs %d for sch %d not %d still unlinked",
+ fs->fs.fs_nr, fs->fs.sched_nr,
+ s->sch.sched_nr);
+ continue;
+ }
+ fsk_attach(fs, s);
+ }
+}
+
+/*
+ * Configuration -- to preserve backward compatibility we use
+ * the following scheme (N is 65536)
+ * NUMBER SCHED LINK FLOWSET
+ * 1 .. N-1 (1)WFQ (2)WFQ (3)queue
+ * N+1 .. 2N-1 (4)FIFO (5)FIFO (6)FIFO for sched 1..N-1
+ * 2N+1 .. 3N-1 -- -- (7)FIFO for sched N+1..2N-1
+ *
+ * "pipe i config" configures #1, #2 and #3
+ * "sched i config" configures #1 and possibly #6
+ * "queue i config" configures #3
+ * #1 is configured with 'pipe i config' or 'sched i config'
+ * #2 is configured with 'pipe i config', and created if not
+ * existing with 'sched i config'
+ * #3 is configured with 'queue i config'
+ * #4 is automatically configured after #1, can only be FIFO
+ * #5 is automatically configured after #2
+ * #6 is automatically created when #1 is !MULTIQUEUE,
+ * and can be updated.
+ * #7 is automatically configured after #2
+ */
+
+/*
+ * configure a link (and its FIFO instance)
+ */
+static int
+config_link(struct dn_link *p, struct dn_id *arg)
+{
+ int i;
+
+ if (p->oid.len != sizeof(*p)) {
+ D("invalid pipe len %d", p->oid.len);
+ return EINVAL;
+ }
+ i = p->link_nr;
+ if (i <= 0 || i >= DN_MAX_ID)
+ return EINVAL;
+ /*
+ * The config program passes parameters as follows:
+ * bw = bits/second (0 means no limits),
+ * delay = ms, must be translated into ticks.
+ * qsize = slots/bytes
+ * burst ???
+ */
+ p->delay = (p->delay * hz) / 1000;
+ /* Scale burst size: bytes -> bits * hz */
+ p->burst *= 8 * hz;
+
+ DN_BH_WLOCK();
+ /* do it twice, base link and FIFO link */
+ for (; i < 2*DN_MAX_ID; i += DN_MAX_ID) {
+ struct dn_schk *s = locate_scheduler(i);
+ if (s == NULL) {
+ DN_BH_WUNLOCK();
+ D("sched %d not found", i);
+ return EINVAL;
+ }
+ /* remove profile if exists */
+ if (s->profile) {
+ free(s->profile, M_DUMMYNET);
+ s->profile = NULL;
+ }
+ /* copy all parameters */
+ s->link.oid = p->oid;
+ s->link.link_nr = i;
+ s->link.delay = p->delay;
+ if (s->link.bandwidth != p->bandwidth) {
+ /* XXX bandwidth changes, need to update red params */
+ s->link.bandwidth = p->bandwidth;
+ update_red(s);
+ }
+ s->link.burst = p->burst;
+ schk_reset_credit(s);
+ }
+ dn_cfg.id++;
+ DN_BH_WUNLOCK();
+ return 0;
+}
+
+/*
+ * configure a flowset. Can be called from inside with locked=1,
+ */
+static struct dn_fsk *
+config_fs(struct dn_fs *nfs, struct dn_id *arg, int locked)
+{
+ int i;
+ struct dn_fsk *fs;
+
+ if (nfs->oid.len != sizeof(*nfs)) {
+ D("invalid flowset len %d", nfs->oid.len);
+ return NULL;
+ }
+ i = nfs->fs_nr;
+ if (i <= 0 || i >= 3*DN_MAX_ID)
+ return NULL;
+ ND("flowset %d", i);
+ /* XXX other sanity checks */
+ if (nfs->flags & DN_QSIZE_BYTES) {
+ ipdn_bound_var(&nfs->qsize, 16384,
+ 1500, dn_cfg.byte_limit, NULL); // "queue byte size");
+ } else {
+ ipdn_bound_var(&nfs->qsize, 50,
+ 1, dn_cfg.slot_limit, NULL); // "queue slot size");
+ }
+ if (nfs->flags & DN_HAVE_MASK) {
+ /* make sure we have some buckets */
+ ipdn_bound_var(&nfs->buckets, dn_cfg.hash_size,
+ 1, dn_cfg.max_hash_size, "flowset buckets");
+ } else {
+ nfs->buckets = 1; /* we only need 1 */
+ }
+ if (!locked)
+ DN_BH_WLOCK();
+ do { /* exit with break when done */
+ struct dn_schk *s;
+ int flags = nfs->sched_nr ? DNHT_INSERT : 0;
+ int j;
+ int oldc = dn_cfg.fsk_count;
+ fs = dn_ht_find(dn_cfg.fshash, i, flags, NULL);
+ if (fs == NULL) {
+ D("missing sched for flowset %d", i);
+ break;
+ }
+ /* grab some defaults from the existing one */
+ if (nfs->sched_nr == 0) /* reuse */
+ nfs->sched_nr = fs->fs.sched_nr;
+ for (j = 0; j < sizeof(nfs->par)/sizeof(nfs->par[0]); j++) {
+ if (nfs->par[j] == -1) /* reuse */
+ nfs->par[j] = fs->fs.par[j];
+ }
+ if (bcmp(&fs->fs, nfs, sizeof(*nfs)) == 0) {
+ ND("flowset %d unchanged", i);
+ break; /* no change, nothing to do */
+ }
+ if (oldc != dn_cfg.fsk_count) /* new item */
+ dn_cfg.id++;
+ s = locate_scheduler(nfs->sched_nr);
+ /* detach from old scheduler if needed, preserving
+ * queues if we need to reattach. Then update the
+ * configuration, and possibly attach to the new sched.
+ */
+ DX(2, "fs %d changed sched %d@%p to %d@%p",
+ fs->fs.fs_nr,
+ fs->fs.sched_nr, fs->sched, nfs->sched_nr, s);
+ if (fs->sched) {
+ int flags = s ? DN_DETACH : (DN_DETACH | DN_DESTROY);
+ flags |= DN_DESTROY; /* XXX temporary */
+ fsk_detach(fs, flags);
+ }
+ fs->fs = *nfs; /* copy configuration */
+ if (s != NULL)
+ fsk_attach(fs, s);
+ } while (0);
+ if (!locked)
+ DN_BH_WUNLOCK();
+ return fs;
+}
+
+/*
+ * config/reconfig a scheduler and its FIFO variant.
+ * For !MULTIQUEUE schedulers, also set up the flowset.
+ *
+ * On reconfigurations (detected because s->fp is set),
+ * detach existing flowsets preserving traffic, preserve link,
+ * and delete the old scheduler creating a new one.
+ */
+static int
+config_sched(struct dn_sch *_nsch, struct dn_id *arg)
+{
+ struct dn_schk *s;
+ struct schk_new_arg a; /* argument for schk_new */
+ int i;
+ struct dn_link p; /* copy of oldlink */
+ struct dn_profile *pf = NULL; /* copy of old link profile */
+ /* Used to preserv mask parameter */
+ struct ipfw_flow_id new_mask;
+ int new_buckets = 0;
+ int new_flags = 0;
+ int pipe_cmd;
+ int err = ENOMEM;
+
+ a.sch = _nsch;
+ if (a.sch->oid.len != sizeof(*a.sch)) {
+ D("bad sched len %d", a.sch->oid.len);
+ return EINVAL;
+ }
+ i = a.sch->sched_nr;
+ if (i <= 0 || i >= DN_MAX_ID)
+ return EINVAL;
+ /* make sure we have some buckets */
+ if (a.sch->flags & DN_HAVE_MASK)
+ ipdn_bound_var(&a.sch->buckets, dn_cfg.hash_size,
+ 1, dn_cfg.max_hash_size, "sched buckets");
+ /* XXX other sanity checks */
+ bzero(&p, sizeof(p));
+
+ pipe_cmd = a.sch->flags & DN_PIPE_CMD;
+ a.sch->flags &= ~DN_PIPE_CMD; //XXX do it even if is not set?
+ if (pipe_cmd) {
+ /* Copy mask parameter */
+ new_mask = a.sch->sched_mask;
+ new_buckets = a.sch->buckets;
+ new_flags = a.sch->flags;
+ }
+ DN_BH_WLOCK();
+again: /* run twice, for wfq and fifo */
+ /*
+ * lookup the type. If not supplied, use the previous one
+ * or default to WF2Q+. Otherwise, return an error.
+ */
+ dn_cfg.id++;
+ a.fp = find_sched_type(a.sch->oid.subtype, a.sch->name);
+ if (a.fp != NULL) {
+ /* found. Lookup or create entry */
+ s = dn_ht_find(dn_cfg.schedhash, i, DNHT_INSERT, &a);
+ } else if (a.sch->oid.subtype == 0 && !a.sch->name[0]) {
+ /* No type. search existing s* or retry with WF2Q+ */
+ s = dn_ht_find(dn_cfg.schedhash, i, 0, &a);
+ if (s != NULL) {
+ a.fp = s->fp;
+ /* Scheduler exists, skip to FIFO scheduler
+ * if command was pipe config...
+ */
+ if (pipe_cmd)
+ goto next;
+ } else {
+ /* New scheduler, create a wf2q+ with no mask
+ * if command was pipe config...
+ */
+ if (pipe_cmd) {
+ /* clear mask parameter */
+ bzero(&a.sch->sched_mask, sizeof(new_mask));
+ a.sch->buckets = 0;
+ a.sch->flags &= ~DN_HAVE_MASK;
+ }
+ a.sch->oid.subtype = DN_SCHED_WF2QP;
+ goto again;
+ }
+ } else {
+ D("invalid scheduler type %d %s",
+ a.sch->oid.subtype, a.sch->name);
+ err = EINVAL;
+ goto error;
+ }
+ /* normalize name and subtype */
+ a.sch->oid.subtype = a.fp->type;
+ bzero(a.sch->name, sizeof(a.sch->name));
+ strlcpy(a.sch->name, a.fp->name, sizeof(a.sch->name));
+ if (s == NULL) {
+ D("cannot allocate scheduler %d", i);
+ goto error;
+ }
+ /* restore existing link if any */
+ if (p.link_nr) {
+ s->link = p;
+ if (!pf || pf->link_nr != p.link_nr) { /* no saved value */
+ s->profile = NULL; /* XXX maybe not needed */
+ } else {
+ s->profile = malloc(sizeof(struct dn_profile),
+ M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (s->profile == NULL) {
+ D("cannot allocate profile");
+ goto error; //XXX
+ }
+ bcopy(pf, s->profile, sizeof(*pf));
+ }
+ }
+ p.link_nr = 0;
+ if (s->fp == NULL) {
+ DX(2, "sched %d new type %s", i, a.fp->name);
+ } else if (s->fp != a.fp ||
+ bcmp(a.sch, &s->sch, sizeof(*a.sch)) ) {
+ /* already existing. */
+ DX(2, "sched %d type changed from %s to %s",
+ i, s->fp->name, a.fp->name);
+ DX(4, " type/sub %d/%d -> %d/%d",
+ s->sch.oid.type, s->sch.oid.subtype,
+ a.sch->oid.type, a.sch->oid.subtype);
+ if (s->link.link_nr == 0)
+ D("XXX WARNING link 0 for sched %d", i);
+ p = s->link; /* preserve link */
+ if (s->profile) {/* preserve profile */
+ if (!pf)
+ pf = malloc(sizeof(*pf),
+ M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (pf) /* XXX should issue a warning otherwise */
+ bcopy(s->profile, pf, sizeof(*pf));
+ }
+ /* remove from the hash */
+ dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
+ /* Detach flowsets, preserve queues. */
+ // schk_delete_cb(s, NULL);
+ // XXX temporarily, kill queues
+ schk_delete_cb(s, (void *)DN_DESTROY);
+ goto again;
+ } else {
+ DX(4, "sched %d unchanged type %s", i, a.fp->name);
+ }
+ /* complete initialization */
+ s->sch = *a.sch;
+ s->fp = a.fp;
+ s->cfg = arg;
+ // XXX schk_reset_credit(s);
+ /* create the internal flowset if needed,
+ * trying to reuse existing ones if available
+ */
+ if (!(s->fp->flags & DN_MULTIQUEUE) && !s->fs) {
+ s->fs = dn_ht_find(dn_cfg.fshash, i, 0, NULL);
+ if (!s->fs) {
+ struct dn_fs fs;
+ bzero(&fs, sizeof(fs));
+ set_oid(&fs.oid, DN_FS, sizeof(fs));
+ fs.fs_nr = i + DN_MAX_ID;
+ fs.sched_nr = i;
+ s->fs = config_fs(&fs, NULL, 1 /* locked */);
+ }
+ if (!s->fs) {
+ schk_delete_cb(s, (void *)DN_DESTROY);
+ D("error creating internal fs for %d", i);
+ goto error;
+ }
+ }
+ /* call init function after the flowset is created */
+ if (s->fp->config)
+ s->fp->config(s);
+ update_fs(s);
+next:
+ if (i < DN_MAX_ID) { /* now configure the FIFO instance */
+ i += DN_MAX_ID;
+ if (pipe_cmd) {
+ /* Restore mask parameter for FIFO */
+ a.sch->sched_mask = new_mask;
+ a.sch->buckets = new_buckets;
+ a.sch->flags = new_flags;
+ } else {
+ /* sched config shouldn't modify the FIFO scheduler */
+ if (dn_ht_find(dn_cfg.schedhash, i, 0, &a) != NULL) {
+ /* FIFO already exist, don't touch it */
+ err = 0; /* and this is not an error */
+ goto error;
+ }
+ }
+ a.sch->sched_nr = i;
+ a.sch->oid.subtype = DN_SCHED_FIFO;
+ bzero(a.sch->name, sizeof(a.sch->name));
+ goto again;
+ }
+ err = 0;
+error:
+ DN_BH_WUNLOCK();
+ if (pf)
+ free(pf, M_DUMMYNET);
+ return err;
+}
+
+/*
+ * attach a profile to a link
+ */
+static int
+config_profile(struct dn_profile *pf, struct dn_id *arg)
+{
+ struct dn_schk *s;
+ int i, olen, err = 0;
+
+ if (pf->oid.len < sizeof(*pf)) {
+ D("short profile len %d", pf->oid.len);
+ return EINVAL;
+ }
+ i = pf->link_nr;
+ if (i <= 0 || i >= DN_MAX_ID)
+ return EINVAL;
+ /* XXX other sanity checks */
+ DN_BH_WLOCK();
+ for (; i < 2*DN_MAX_ID; i += DN_MAX_ID) {
+ s = locate_scheduler(i);
+
+ if (s == NULL) {
+ err = EINVAL;
+ break;
+ }
+ dn_cfg.id++;
+ /*
+ * If we had a profile and the new one does not fit,
+ * or it is deleted, then we need to free memory.
+ */
+ if (s->profile && (pf->samples_no == 0 ||
+ s->profile->oid.len < pf->oid.len)) {
+ free(s->profile, M_DUMMYNET);
+ s->profile = NULL;
+ }
+ if (pf->samples_no == 0)
+ continue;
+ /*
+ * new profile, possibly allocate memory
+ * and copy data.
+ */
+ if (s->profile == NULL)
+ s->profile = malloc(pf->oid.len,
+ M_DUMMYNET, M_NOWAIT | M_ZERO);
+ if (s->profile == NULL) {
+ D("no memory for profile %d", i);
+ err = ENOMEM;
+ break;
+ }
+ /* preserve larger length XXX double check */
+ olen = s->profile->oid.len;
+ if (olen < pf->oid.len)
+ olen = pf->oid.len;
+ bcopy(pf, s->profile, pf->oid.len);
+ s->profile->oid.len = olen;
+ }
+ DN_BH_WUNLOCK();
+ return err;
+}
+
+/*
+ * Delete all objects:
+ */
+static void
+dummynet_flush(void)
+{
+
+ /* delete all schedulers and related links/queues/flowsets */
+ dn_ht_scan(dn_cfg.schedhash, schk_delete_cb,
+ (void *)(uintptr_t)DN_DELETE_FS);
+ /* delete all remaining (unlinked) flowsets */
+ DX(4, "still %d unlinked fs", dn_cfg.fsk_count);
+ dn_ht_free(dn_cfg.fshash, DNHT_REMOVE);
+ fsk_detach_list(&dn_cfg.fsu, DN_DELETE_FS);
+ /* Reinitialize system heap... */
+ heap_init(&dn_cfg.evheap, 16, offsetof(struct dn_id, id));
+}
+
+/*
+ * Main handler for configuration. We are guaranteed to be called
+ * with an oid which is at least a dn_id.
+ * - the first object is the command (config, delete, flush, ...)
+ * - config_link must be issued after the corresponding config_sched
+ * - parameters (DN_TXT) for an object must preceed the object
+ * processed on a config_sched.
+ */
+int
+do_config(void *p, int l)
+{
+ struct dn_id *next, *o;
+ int err = 0, err2 = 0;
+ struct dn_id *arg = NULL;
+ uintptr_t *a;
+
+ o = p;
+ if (o->id != DN_API_VERSION) {
+ D("invalid api version got %d need %d",
+ o->id, DN_API_VERSION);
+ return EINVAL;
+ }
+ for (; l >= sizeof(*o); o = next) {
+ struct dn_id *prev = arg;
+ if (o->len < sizeof(*o) || l < o->len) {
+ D("bad len o->len %d len %d", o->len, l);
+ err = EINVAL;
+ break;
+ }
+ l -= o->len;
+ next = (struct dn_id *)((char *)o + o->len);
+ err = 0;
+ switch (o->type) {
+ default:
+ D("cmd %d not implemented", o->type);
+ break;
+
+#ifdef EMULATE_SYSCTL
+ /* sysctl emulation.
+ * if we recognize the command, jump to the correct
+ * handler and return
+ */
+ case DN_SYSCTL_SET:
+ err = kesysctl_emu_set(p, l);
+ return err;
+#endif
+
+ case DN_CMD_CONFIG: /* simply a header */
+ break;
+
+ case DN_CMD_DELETE:
+ /* the argument is in the first uintptr_t after o */
+ a = (uintptr_t *)(o+1);
+ if (o->len < sizeof(*o) + sizeof(*a)) {
+ err = EINVAL;
+ break;
+ }
+ switch (o->subtype) {
+ case DN_LINK:
+ /* delete base and derived schedulers */
+ DN_BH_WLOCK();
+ err = delete_schk(*a);
+ err2 = delete_schk(*a + DN_MAX_ID);
+ DN_BH_WUNLOCK();
+ if (!err)
+ err = err2;
+ break;
+
+ default:
+ D("invalid delete type %d",
+ o->subtype);
+ err = EINVAL;
+ break;
+
+ case DN_FS:
+ err = (*a <1 || *a >= DN_MAX_ID) ?
+ EINVAL : delete_fs(*a, 0) ;
+ break;
+ }
+ break;
+
+ case DN_CMD_FLUSH:
+ DN_BH_WLOCK();
+ dummynet_flush();
+ DN_BH_WUNLOCK();
+ break;
+ case DN_TEXT: /* store argument the next block */
+ prev = NULL;
+ arg = o;
+ break;
+ case DN_LINK:
+ err = config_link((struct dn_link *)o, arg);
+ break;
+ case DN_PROFILE:
+ err = config_profile((struct dn_profile *)o, arg);
+ break;
+ case DN_SCH:
+ err = config_sched((struct dn_sch *)o, arg);
+ break;
+ case DN_FS:
+ err = (NULL==config_fs((struct dn_fs *)o, arg, 0));
+ break;
+ }
+ if (prev)
+ arg = NULL;
+ if (err != 0)
+ break;
+ }
+ return err;
+}
+
+static int
+compute_space(struct dn_id *cmd, struct copy_args *a)
+{
+ int x = 0, need = 0;
+ int profile_size = sizeof(struct dn_profile) -
+ ED_MAX_SAMPLES_NO*sizeof(int);
+
+ /* NOTE about compute space:
+ * NP = dn_cfg.schk_count
+ * NSI = dn_cfg.si_count
+ * NF = dn_cfg.fsk_count
+ * NQ = dn_cfg.queue_count
+ * - ipfw pipe show
+ * (NP/2)*(dn_link + dn_sch + dn_id + dn_fs) only half scheduler
+ * link, scheduler template, flowset
+ * integrated in scheduler and header
+ * for flowset list
+ * (NSI)*(dn_flow) all scheduler instance (includes
+ * the queue instance)
+ * - ipfw sched show
+ * (NP/2)*(dn_link + dn_sch + dn_id + dn_fs) only half scheduler
+ * link, scheduler template, flowset
+ * integrated in scheduler and header
+ * for flowset list
+ * (NSI * dn_flow) all scheduler instances
+ * (NF * sizeof(uint_32)) space for flowset list linked to scheduler
+ * (NQ * dn_queue) all queue [XXXfor now not listed]
+ * - ipfw queue show
+ * (NF * dn_fs) all flowset
+ * (NQ * dn_queue) all queues
+ */
+ switch (cmd->subtype) {
+ default:
+ return -1;
+ /* XXX where do LINK and SCH differ ? */
+ /* 'ipfw sched show' could list all queues associated to
+ * a scheduler. This feature for now is disabled
+ */
+ case DN_LINK: /* pipe show */
+ x = DN_C_LINK | DN_C_SCH | DN_C_FLOW;
+ need += dn_cfg.schk_count *
+ (sizeof(struct dn_fs) + profile_size) / 2;
+ need += dn_cfg.fsk_count * sizeof(uint32_t);
+ break;
+ case DN_SCH: /* sched show */
+ need += dn_cfg.schk_count *
+ (sizeof(struct dn_fs) + profile_size) / 2;
+ need += dn_cfg.fsk_count * sizeof(uint32_t);
+ x = DN_C_SCH | DN_C_LINK | DN_C_FLOW;
+ break;
+ case DN_FS: /* queue show */
+ x = DN_C_FS | DN_C_QUEUE;
+ break;
+ case DN_GET_COMPAT: /* compatibility mode */
+ need = dn_compat_calc_size();
+ break;
+ }
+ a->flags = x;
+ if (x & DN_C_SCH) {
+ need += dn_cfg.schk_count * sizeof(struct dn_sch) / 2;
+ /* NOT also, each fs might be attached to a sched */
+ need += dn_cfg.schk_count * sizeof(struct dn_id) / 2;
+ }
+ if (x & DN_C_FS)
+ need += dn_cfg.fsk_count * sizeof(struct dn_fs);
+ if (x & DN_C_LINK) {
+ need += dn_cfg.schk_count * sizeof(struct dn_link) / 2;
+ }
+ /*
+ * When exporting a queue to userland, only pass up the
+ * struct dn_flow, which is the only visible part.
+ */
+
+ if (x & DN_C_QUEUE)
+ need += dn_cfg.queue_count * sizeof(struct dn_flow);
+ if (x & DN_C_FLOW)
+ need += dn_cfg.si_count * (sizeof(struct dn_flow));
+ return need;
+}
+
+/*
+ * If compat != NULL dummynet_get is called in compatibility mode.
+ * *compat will be the pointer to the buffer to pass to ipfw
+ */
+int
+dummynet_get(struct sockopt *sopt, void **compat)
+{
+ int have, i, need, error;
+ char *start = NULL, *buf;
+ size_t sopt_valsize;
+ struct dn_id *cmd;
+ struct copy_args a;
+ struct copy_range r;
+ int l = sizeof(struct dn_id);
+
+ bzero(&a, sizeof(a));
+ bzero(&r, sizeof(r));
+
+ /* save and restore original sopt_valsize around copyin */
+ sopt_valsize = sopt->sopt_valsize;
+
+ cmd = &r.o;
+
+ if (!compat) {
+ /* copy at least an oid, and possibly a full object */
+ error = sooptcopyin(sopt, cmd, sizeof(r), sizeof(*cmd));
+ sopt->sopt_valsize = sopt_valsize;
+ if (error)
+ goto done;
+ l = cmd->len;
+#ifdef EMULATE_SYSCTL
+ /* sysctl emulation. */
+ if (cmd->type == DN_SYSCTL_GET)
+ return kesysctl_emu_get(sopt);
+#endif
+ if (l > sizeof(r)) {
+ /* request larger than default, allocate buffer */
+ cmd = malloc(l, M_DUMMYNET, M_WAITOK);
+ error = sooptcopyin(sopt, cmd, l, l);
+ sopt->sopt_valsize = sopt_valsize;
+ if (error)
+ goto done;
+ }
+ } else { /* compatibility */
+ error = 0;
+ cmd->type = DN_CMD_GET;
+ cmd->len = sizeof(struct dn_id);
+ cmd->subtype = DN_GET_COMPAT;
+ // cmd->id = sopt_valsize;
+ D("compatibility mode");
+ }
+ a.extra = (struct copy_range *)cmd;
+ if (cmd->len == sizeof(*cmd)) { /* no range, create a default */
+ uint32_t *rp = (uint32_t *)(cmd + 1);
+ cmd->len += 2* sizeof(uint32_t);
+ rp[0] = 1;
+ rp[1] = DN_MAX_ID - 1;
+ if (cmd->subtype == DN_LINK) {
+ rp[0] += DN_MAX_ID;
+ rp[1] += DN_MAX_ID;
+ }
+ }
+ /* Count space (under lock) and allocate (outside lock).
+ * Exit with lock held if we manage to get enough buffer.
+ * Try a few times then give up.
+ */
+ for (have = 0, i = 0; i < 10; i++) {
+ DN_BH_WLOCK();
+ need = compute_space(cmd, &a);
+
+ /* if there is a range, ignore value from compute_space() */
+ if (l > sizeof(*cmd))
+ need = sopt_valsize - sizeof(*cmd);
+
+ if (need < 0) {
+ DN_BH_WUNLOCK();
+ error = EINVAL;
+ goto done;
+ }
+ need += sizeof(*cmd);
+ cmd->id = need;
+ if (have >= need)
+ break;
+
+ DN_BH_WUNLOCK();
+ if (start)
+ free(start, M_DUMMYNET);
+ start = NULL;
+ if (need > sopt_valsize)
+ break;
+
+ have = need;
+ start = malloc(have, M_DUMMYNET, M_WAITOK | M_ZERO);
+ }
+
+ if (start == NULL) {
+ if (compat) {
+ *compat = NULL;
+ error = 1; // XXX
+ } else {
+ error = sooptcopyout(sopt, cmd, sizeof(*cmd));
+ }
+ goto done;
+ }
+ ND("have %d:%d sched %d, %d:%d links %d, %d:%d flowsets %d, "
+ "%d:%d si %d, %d:%d queues %d",
+ dn_cfg.schk_count, sizeof(struct dn_sch), DN_SCH,
+ dn_cfg.schk_count, sizeof(struct dn_link), DN_LINK,
+ dn_cfg.fsk_count, sizeof(struct dn_fs), DN_FS,
+ dn_cfg.si_count, sizeof(struct dn_flow), DN_SCH_I,
+ dn_cfg.queue_count, sizeof(struct dn_queue), DN_QUEUE);
+ sopt->sopt_valsize = sopt_valsize;
+ a.type = cmd->subtype;
+
+ if (compat == NULL) {
+ bcopy(cmd, start, sizeof(*cmd));
+ ((struct dn_id*)(start))->len = sizeof(struct dn_id);
+ buf = start + sizeof(*cmd);
+ } else
+ buf = start;
+ a.start = &buf;
+ a.end = start + have;
+ /* start copying other objects */
+ if (compat) {
+ a.type = DN_COMPAT_PIPE;
+ dn_ht_scan(dn_cfg.schedhash, copy_data_helper_compat, &a);
+ a.type = DN_COMPAT_QUEUE;
+ dn_ht_scan(dn_cfg.fshash, copy_data_helper_compat, &a);
+ } else if (a.type == DN_FS) {
+ dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a);
+ } else {
+ dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a);
+ }
+ DN_BH_WUNLOCK();
+
+ if (compat) {
+ *compat = start;
+ sopt->sopt_valsize = buf - start;
+ /* free() is done by ip_dummynet_compat() */
+ start = NULL; //XXX hack
+ } else {
+ error = sooptcopyout(sopt, start, buf - start);
+ }
+done:
+ if (cmd && cmd != &r.o)
+ free(cmd, M_DUMMYNET);
+ if (start)
+ free(start, M_DUMMYNET);
+ return error;
+}
+
+/* Callback called on scheduler instance to delete it if idle */
+static int
+drain_scheduler_cb(void *_si, void *arg)
+{
+ struct dn_sch_inst *si = _si;
+
+ if ((si->kflags & DN_ACTIVE) || si->dline.mq.head != NULL)
+ return 0;
+
+ if (si->sched->fp->flags & DN_MULTIQUEUE) {
+ if (si->q_count == 0)
+ return si_destroy(si, NULL);
+ else
+ return 0;
+ } else { /* !DN_MULTIQUEUE */
+ if ((si+1)->ni.length == 0)
+ return si_destroy(si, NULL);
+ else
+ return 0;
+ }
+ return 0; /* unreachable */
+}
+
+/* Callback called on scheduler to check if it has instances */
+static int
+drain_scheduler_sch_cb(void *_s, void *arg)
+{
+ struct dn_schk *s = _s;
+
+ if (s->sch.flags & DN_HAVE_MASK) {
+ dn_ht_scan_bucket(s->siht, &s->drain_bucket,
+ drain_scheduler_cb, NULL);
+ s->drain_bucket++;
+ } else {
+ if (s->siht) {
+ if (drain_scheduler_cb(s->siht, NULL) == DNHT_SCAN_DEL)
+ s->siht = NULL;
+ }
+ }
+ return 0;
+}
+
+/* Called every tick, try to delete a 'bucket' of scheduler */
+void
+dn_drain_scheduler(void)
+{
+ dn_ht_scan_bucket(dn_cfg.schedhash, &dn_cfg.drain_sch,
+ drain_scheduler_sch_cb, NULL);
+ dn_cfg.drain_sch++;
+}
+
+/* Callback called on queue to delete if it is idle */
+static int
+drain_queue_cb(void *_q, void *arg)
+{
+ struct dn_queue *q = _q;
+
+ if (q->ni.length == 0) {
+ dn_delete_queue(q, DN_DESTROY);
+ return DNHT_SCAN_DEL; /* queue is deleted */
+ }
+
+ return 0; /* queue isn't deleted */
+}
+
+/* Callback called on flowset used to check if it has queues */
+static int
+drain_queue_fs_cb(void *_fs, void *arg)
+{
+ struct dn_fsk *fs = _fs;
+
+ if (fs->fs.flags & DN_QHT_HASH) {
+ /* Flowset has a hash table for queues */
+ dn_ht_scan_bucket(fs->qht, &fs->drain_bucket,
+ drain_queue_cb, NULL);
+ fs->drain_bucket++;
+ } else {
+ /* No hash table for this flowset, null the pointer
+ * if the queue is deleted
+ */
+ if (fs->qht) {
+ if (drain_queue_cb(fs->qht, NULL) == DNHT_SCAN_DEL)
+ fs->qht = NULL;
+ }
+ }
+ return 0;
+}
+
+/* Called every tick, try to delete a 'bucket' of queue */
+void
+dn_drain_queue(void)
+{
+ /* scan a bucket of flowset */
+ dn_ht_scan_bucket(dn_cfg.fshash, &dn_cfg.drain_fs,
+ drain_queue_fs_cb, NULL);
+ dn_cfg.drain_fs++;
+}
+
+/*
+ * Handler for the various dummynet socket options
+ */
+static int
+ip_dn_ctl(struct sockopt *sopt)
+{
+ void *p = NULL;
+ int error, l;
+
+ error = priv_check(sopt->sopt_td, PRIV_NETINET_DUMMYNET);
+ if (error)
+ return (error);
+
+ /* Disallow sets in really-really secure mode. */
+ if (sopt->sopt_dir == SOPT_SET) {
+ error = securelevel_ge(sopt->sopt_td->td_ucred, 3);
+ if (error)
+ return (error);
+ }
+
+ switch (sopt->sopt_name) {
+ default :
+ D("dummynet: unknown option %d", sopt->sopt_name);
+ error = EINVAL;
+ break;
+
+ case IP_DUMMYNET_FLUSH:
+ case IP_DUMMYNET_CONFIGURE:
+ case IP_DUMMYNET_DEL: /* remove a pipe or queue */
+ case IP_DUMMYNET_GET:
+ D("dummynet: compat option %d", sopt->sopt_name);
+ error = ip_dummynet_compat(sopt);
+ break;
+
+ case IP_DUMMYNET3 :
+ if (sopt->sopt_dir == SOPT_GET) {
+ error = dummynet_get(sopt, NULL);
+ break;
+ }
+ l = sopt->sopt_valsize;
+ if (l < sizeof(struct dn_id) || l > 12000) {
+ D("argument len %d invalid", l);
+ break;
+ }
+ p = malloc(l, M_TEMP, M_WAITOK); // XXX can it fail ?
+ error = sooptcopyin(sopt, p, l, l);
+ if (error)
+ break ;
+ error = do_config(p, l);
+ break;
+ }
+
+ if (p != NULL)
+ free(p, M_TEMP);
+
+ return error ;
+}
+
+
+static void
+ip_dn_init(void)
+{
+ if (dn_cfg.init_done)
+ return;
+ printf("DUMMYNET %p with IPv6 initialized (100409)\n", curvnet);
+ dn_cfg.init_done = 1;
+ /* Set defaults here. MSVC does not accept initializers,
+ * and this is also useful for vimages
+ */
+ /* queue limits */
+ dn_cfg.slot_limit = 100; /* Foot shooting limit for queues. */
+ dn_cfg.byte_limit = 1024 * 1024;
+ dn_cfg.expire = 1;
+
+ /* RED parameters */
+ dn_cfg.red_lookup_depth = 256; /* default lookup table depth */
+ dn_cfg.red_avg_pkt_size = 512; /* default medium packet size */
+ dn_cfg.red_max_pkt_size = 1500; /* default max packet size */
+
+ /* hash tables */
+ dn_cfg.max_hash_size = 65536; /* max in the hash tables */
+ dn_cfg.hash_size = 64; /* default hash size */
+
+ /* create hash tables for schedulers and flowsets.
+ * In both we search by key and by pointer.
+ */
+ dn_cfg.schedhash = dn_ht_init(NULL, dn_cfg.hash_size,
+ offsetof(struct dn_schk, schk_next),
+ schk_hash, schk_match, schk_new);
+ dn_cfg.fshash = dn_ht_init(NULL, dn_cfg.hash_size,
+ offsetof(struct dn_fsk, fsk_next),
+ fsk_hash, fsk_match, fsk_new);
+
+ /* bucket index to drain object */
+ dn_cfg.drain_fs = 0;
+ dn_cfg.drain_sch = 0;
+
+ heap_init(&dn_cfg.evheap, 16, offsetof(struct dn_id, id));
+ SLIST_INIT(&dn_cfg.fsu);
+ SLIST_INIT(&dn_cfg.schedlist);
+
+ DN_LOCK_INIT();
+
+ TASK_INIT(&dn_task, 0, dummynet_task, curvnet);
+ dn_tq = taskqueue_create("dummynet", M_WAITOK,
+ taskqueue_thread_enqueue, &dn_tq);
+ taskqueue_start_threads(&dn_tq, 1, PI_NET, "dummynet");
+
+ callout_init(&dn_timeout, CALLOUT_MPSAFE);
+ callout_reset(&dn_timeout, 1, dummynet, NULL);
+
+ /* Initialize curr_time adjustment mechanics. */
+ getmicrouptime(&dn_cfg.prev_t);
+}
+
+#ifdef KLD_MODULE
+static void
+ip_dn_destroy(int last)
+{
+ callout_drain(&dn_timeout);
+
+ DN_BH_WLOCK();
+ if (last) {
+ ND("removing last instance\n");
+ ip_dn_ctl_ptr = NULL;
+ ip_dn_io_ptr = NULL;
+ }
+
+ dummynet_flush();
+ DN_BH_WUNLOCK();
+ taskqueue_drain(dn_tq, &dn_task);
+ taskqueue_free(dn_tq);
+
+ dn_ht_free(dn_cfg.schedhash, 0);
+ dn_ht_free(dn_cfg.fshash, 0);
+ heap_free(&dn_cfg.evheap);
+
+ DN_LOCK_DESTROY();
+}
+#endif /* KLD_MODULE */
+
+static int
+dummynet_modevent(module_t mod, int type, void *data)
+{
+
+ if (type == MOD_LOAD) {
+ if (ip_dn_io_ptr) {
+ printf("DUMMYNET already loaded\n");
+ return EEXIST ;
+ }
+ ip_dn_init();
+ ip_dn_ctl_ptr = ip_dn_ctl;
+ ip_dn_io_ptr = dummynet_io;
+ return 0;
+ } else if (type == MOD_UNLOAD) {
+#if !defined(KLD_MODULE)
+ printf("dummynet statically compiled, cannot unload\n");
+ return EINVAL ;
+#else
+ ip_dn_destroy(1 /* last */);
+ return 0;
+#endif
+ } else
+ return EOPNOTSUPP;
+}
+
+/* modevent helpers for the modules */
+static int
+load_dn_sched(struct dn_alg *d)
+{
+ struct dn_alg *s;
+
+ if (d == NULL)
+ return 1; /* error */
+ ip_dn_init(); /* just in case, we need the lock */
+
+ /* Check that mandatory funcs exists */
+ if (d->enqueue == NULL || d->dequeue == NULL) {
+ D("missing enqueue or dequeue for %s", d->name);
+ return 1;
+ }
+
+ /* Search if scheduler already exists */
+ DN_BH_WLOCK();
+ SLIST_FOREACH(s, &dn_cfg.schedlist, next) {
+ if (strcmp(s->name, d->name) == 0) {
+ D("%s already loaded", d->name);
+ break; /* scheduler already exists */
+ }
+ }
+ if (s == NULL)
+ SLIST_INSERT_HEAD(&dn_cfg.schedlist, d, next);
+ DN_BH_WUNLOCK();
+ D("dn_sched %s %sloaded", d->name, s ? "not ":"");
+ return s ? 1 : 0;
+}
+
+static int
+unload_dn_sched(struct dn_alg *s)
+{
+ struct dn_alg *tmp, *r;
+ int err = EINVAL;
+
+ ND("called for %s", s->name);
+
+ DN_BH_WLOCK();
+ SLIST_FOREACH_SAFE(r, &dn_cfg.schedlist, next, tmp) {
+ if (strcmp(s->name, r->name) != 0)
+ continue;
+ ND("ref_count = %d", r->ref_count);
+ err = (r->ref_count != 0) ? EBUSY : 0;
+ if (err == 0)
+ SLIST_REMOVE(&dn_cfg.schedlist, r, dn_alg, next);
+ break;
+ }
+ DN_BH_WUNLOCK();
+ D("dn_sched %s %sunloaded", s->name, err ? "not ":"");
+ return err;
+}
+
+int
+dn_sched_modevent(module_t mod, int cmd, void *arg)
+{
+ struct dn_alg *sch = arg;
+
+ if (cmd == MOD_LOAD)
+ return load_dn_sched(sch);
+ else if (cmd == MOD_UNLOAD)
+ return unload_dn_sched(sch);
+ else
+ return EINVAL;
+}
+
+static moduledata_t dummynet_mod = {
+ "dummynet", dummynet_modevent, NULL
+};
+
+#define DN_SI_SUB SI_SUB_PROTO_IFATTACHDOMAIN
+#define DN_MODEV_ORD (SI_ORDER_ANY - 128) /* after ipfw */
+DECLARE_MODULE(dummynet, dummynet_mod, DN_SI_SUB, DN_MODEV_ORD);
+MODULE_DEPEND(dummynet, ipfw, 2, 2, 2);
+MODULE_VERSION(dummynet, 3);
+
+/*
+ * Starting up. Done in order after dummynet_modevent() has been called.
+ * VNET_SYSINIT is also called for each existing vnet and each new vnet.
+ */
+//VNET_SYSINIT(vnet_dn_init, DN_SI_SUB, DN_MODEV_ORD+2, ip_dn_init, NULL);
+
+/*
+ * Shutdown handlers up shop. These are done in REVERSE ORDER, but still
+ * after dummynet_modevent() has been called. Not called on reboot.
+ * VNET_SYSUNINIT is also called for each exiting vnet as it exits.
+ * or when the module is unloaded.
+ */
+//VNET_SYSUNINIT(vnet_dn_uninit, DN_SI_SUB, DN_MODEV_ORD+2, ip_dn_destroy, NULL);
+
+/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c
new file mode 100644
index 0000000..21a00bb
--- /dev/null
+++ b/sys/netinet/ipfw/ip_fw2.c
@@ -0,0 +1,2783 @@
+/*-
+ * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * The FreeBSD IP packet firewall, main file
+ */
+
+#include "opt_ipfw.h"
+#include "opt_ipdivert.h"
+#include "opt_inet.h"
+#ifndef INET
+#error "IPFIREWALL requires INET"
+#endif /* INET */
+#include "opt_inet6.h"
+#include "opt_ipsec.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/condvar.h>
+#include <sys/eventhandler.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/jail.h>
+#include <sys/module.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/sysctl.h>
+#include <sys/syslog.h>
+#include <sys/ucred.h>
+#include <net/ethernet.h> /* for ETHERTYPE_IP */
+#include <net/if.h>
+#include <net/route.h>
+#include <net/pf_mtag.h>
+#include <net/vnet.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_fw.h>
+#include <netinet/ipfw/ip_fw_private.h>
+#include <netinet/ip_carp.h>
+#include <netinet/pim.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/sctp.h>
+
+#include <netinet/ip6.h>
+#include <netinet/icmp6.h>
+#ifdef INET6
+#include <netinet6/in6_pcb.h>
+#include <netinet6/scope6_var.h>
+#include <netinet6/ip6_var.h>
+#endif
+
+#include <machine/in_cksum.h> /* XXX for in_cksum */
+
+#ifdef MAC
+#include <security/mac/mac_framework.h>
+#endif
+
+/*
+ * static variables followed by global ones.
+ * All ipfw global variables are here.
+ */
+
+/* ipfw_vnet_ready controls when we are open for business */
+static VNET_DEFINE(int, ipfw_vnet_ready) = 0;
+#define V_ipfw_vnet_ready VNET(ipfw_vnet_ready)
+
+static VNET_DEFINE(int, fw_deny_unknown_exthdrs);
+#define V_fw_deny_unknown_exthdrs VNET(fw_deny_unknown_exthdrs)
+
+static VNET_DEFINE(int, fw_permit_single_frag6) = 1;
+#define V_fw_permit_single_frag6 VNET(fw_permit_single_frag6)
+
+#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
+static int default_to_accept = 1;
+#else
+static int default_to_accept;
+#endif
+
+VNET_DEFINE(int, autoinc_step);
+VNET_DEFINE(int, fw_one_pass) = 1;
+
+VNET_DEFINE(unsigned int, fw_tables_max);
+/* Use 128 tables by default */
+static unsigned int default_fw_tables = IPFW_TABLES_DEFAULT;
+
+/*
+ * Each rule belongs to one of 32 different sets (0..31).
+ * The variable set_disable contains one bit per set.
+ * If the bit is set, all rules in the corresponding set
+ * are disabled. Set RESVD_SET(31) is reserved for the default rule
+ * and rules that are not deleted by the flush command,
+ * and CANNOT be disabled.
+ * Rules in set RESVD_SET can only be deleted individually.
+ */
+VNET_DEFINE(u_int32_t, set_disable);
+#define V_set_disable VNET(set_disable)
+
+VNET_DEFINE(int, fw_verbose);
+/* counter for ipfw_log(NULL...) */
+VNET_DEFINE(u_int64_t, norule_counter);
+VNET_DEFINE(int, verbose_limit);
+
+/* layer3_chain contains the list of rules for layer 3 */
+VNET_DEFINE(struct ip_fw_chain, layer3_chain);
+
+ipfw_nat_t *ipfw_nat_ptr = NULL;
+struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
+ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
+ipfw_nat_cfg_t *ipfw_nat_del_ptr;
+ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
+ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
+
+#ifdef SYSCTL_NODE
+uint32_t dummy_def = IPFW_DEFAULT_RULE;
+static int sysctl_ipfw_table_num(SYSCTL_HANDLER_ARGS);
+
+SYSBEGIN(f3)
+
+SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
+SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
+ CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0,
+ "Only do a single pass through ipfw when using dummynet(4)");
+SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step,
+ CTLFLAG_RW, &VNET_NAME(autoinc_step), 0,
+ "Rule number auto-increment step");
+SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose,
+ CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_verbose), 0,
+ "Log matches to ipfw rules");
+SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit,
+ CTLFLAG_RW, &VNET_NAME(verbose_limit), 0,
+ "Set upper limit of matches of ipfw rules logged");
+SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD,
+ &dummy_def, 0,
+ "The default/max possible rule number.");
+SYSCTL_VNET_PROC(_net_inet_ip_fw, OID_AUTO, tables_max,
+ CTLTYPE_UINT|CTLFLAG_RW, 0, 0, sysctl_ipfw_table_num, "IU",
+ "Maximum number of tables");
+SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN,
+ &default_to_accept, 0,
+ "Make the default rule accept all packets.");
+TUNABLE_INT("net.inet.ip.fw.default_to_accept", &default_to_accept);
+TUNABLE_INT("net.inet.ip.fw.tables_max", &default_fw_tables);
+SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, static_count,
+ CTLFLAG_RD, &VNET_NAME(layer3_chain.n_rules), 0,
+ "Number of static rules");
+
+#ifdef INET6
+SYSCTL_DECL(_net_inet6_ip6);
+SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
+SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs,
+ CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_deny_unknown_exthdrs), 0,
+ "Deny packets with unknown IPv6 Extension Headers");
+SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, permit_single_frag6,
+ CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_permit_single_frag6), 0,
+ "Permit single packet IPv6 fragments");
+#endif /* INET6 */
+
+SYSEND
+
+#endif /* SYSCTL_NODE */
+
+
+/*
+ * Some macros used in the various matching options.
+ * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
+ * Other macros just cast void * into the appropriate type
+ */
+#define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl))
+#define TCP(p) ((struct tcphdr *)(p))
+#define SCTP(p) ((struct sctphdr *)(p))
+#define UDP(p) ((struct udphdr *)(p))
+#define ICMP(p) ((struct icmphdr *)(p))
+#define ICMP6(p) ((struct icmp6_hdr *)(p))
+
+static __inline int
+icmptype_match(struct icmphdr *icmp, ipfw_insn_u32 *cmd)
+{
+ int type = icmp->icmp_type;
+
+ return (type <= ICMP_MAXTYPE && (cmd->d[0] & (1<<type)) );
+}
+
+#define TT ( (1 << ICMP_ECHO) | (1 << ICMP_ROUTERSOLICIT) | \
+ (1 << ICMP_TSTAMP) | (1 << ICMP_IREQ) | (1 << ICMP_MASKREQ) )
+
+static int
+is_icmp_query(struct icmphdr *icmp)
+{
+ int type = icmp->icmp_type;
+
+ return (type <= ICMP_MAXTYPE && (TT & (1<<type)) );
+}
+#undef TT
+
+/*
+ * The following checks use two arrays of 8 or 16 bits to store the
+ * bits that we want set or clear, respectively. They are in the
+ * low and high half of cmd->arg1 or cmd->d[0].
+ *
+ * We scan options and store the bits we find set. We succeed if
+ *
+ * (want_set & ~bits) == 0 && (want_clear & ~bits) == want_clear
+ *
+ * The code is sometimes optimized not to store additional variables.
+ */
+
+static int
+flags_match(ipfw_insn *cmd, u_int8_t bits)
+{
+ u_char want_clear;
+ bits = ~bits;
+
+ if ( ((cmd->arg1 & 0xff) & bits) != 0)
+ return 0; /* some bits we want set were clear */
+ want_clear = (cmd->arg1 >> 8) & 0xff;
+ if ( (want_clear & bits) != want_clear)
+ return 0; /* some bits we want clear were set */
+ return 1;
+}
+
+static int
+ipopts_match(struct ip *ip, ipfw_insn *cmd)
+{
+ int optlen, bits = 0;
+ u_char *cp = (u_char *)(ip + 1);
+ int x = (ip->ip_hl << 2) - sizeof (struct ip);
+
+ for (; x > 0; x -= optlen, cp += optlen) {
+ int opt = cp[IPOPT_OPTVAL];
+
+ if (opt == IPOPT_EOL)
+ break;
+ if (opt == IPOPT_NOP)
+ optlen = 1;
+ else {
+ optlen = cp[IPOPT_OLEN];
+ if (optlen <= 0 || optlen > x)
+ return 0; /* invalid or truncated */
+ }
+ switch (opt) {
+
+ default:
+ break;
+
+ case IPOPT_LSRR:
+ bits |= IP_FW_IPOPT_LSRR;
+ break;
+
+ case IPOPT_SSRR:
+ bits |= IP_FW_IPOPT_SSRR;
+ break;
+
+ case IPOPT_RR:
+ bits |= IP_FW_IPOPT_RR;
+ break;
+
+ case IPOPT_TS:
+ bits |= IP_FW_IPOPT_TS;
+ break;
+ }
+ }
+ return (flags_match(cmd, bits));
+}
+
+static int
+tcpopts_match(struct tcphdr *tcp, ipfw_insn *cmd)
+{
+ int optlen, bits = 0;
+ u_char *cp = (u_char *)(tcp + 1);
+ int x = (tcp->th_off << 2) - sizeof(struct tcphdr);
+
+ for (; x > 0; x -= optlen, cp += optlen) {
+ int opt = cp[0];
+ if (opt == TCPOPT_EOL)
+ break;
+ if (opt == TCPOPT_NOP)
+ optlen = 1;
+ else {
+ optlen = cp[1];
+ if (optlen <= 0)
+ break;
+ }
+
+ switch (opt) {
+
+ default:
+ break;
+
+ case TCPOPT_MAXSEG:
+ bits |= IP_FW_TCPOPT_MSS;
+ break;
+
+ case TCPOPT_WINDOW:
+ bits |= IP_FW_TCPOPT_WINDOW;
+ break;
+
+ case TCPOPT_SACK_PERMITTED:
+ case TCPOPT_SACK:
+ bits |= IP_FW_TCPOPT_SACK;
+ break;
+
+ case TCPOPT_TIMESTAMP:
+ bits |= IP_FW_TCPOPT_TS;
+ break;
+
+ }
+ }
+ return (flags_match(cmd, bits));
+}
+
+static int
+iface_match(struct ifnet *ifp, ipfw_insn_if *cmd, struct ip_fw_chain *chain, uint32_t *tablearg)
+{
+ if (ifp == NULL) /* no iface with this packet, match fails */
+ return 0;
+ /* Check by name or by IP address */
+ if (cmd->name[0] != '\0') { /* match by name */
+ if (cmd->name[0] == '\1') /* use tablearg to match */
+ return ipfw_lookup_table_extended(chain, cmd->p.glob,
+ ifp->if_xname, tablearg, IPFW_TABLE_INTERFACE);
+ /* Check name */
+ if (cmd->p.glob) {
+ if (fnmatch(cmd->name, ifp->if_xname, 0) == 0)
+ return(1);
+ } else {
+ if (strncmp(ifp->if_xname, cmd->name, IFNAMSIZ) == 0)
+ return(1);
+ }
+ } else {
+#ifdef __FreeBSD__ /* and OSX too ? */
+ struct ifaddr *ia;
+
+ if_addr_rlock(ifp);
+ TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
+ if (ia->ifa_addr->sa_family != AF_INET)
+ continue;
+ if (cmd->p.ip.s_addr == ((struct sockaddr_in *)
+ (ia->ifa_addr))->sin_addr.s_addr) {
+ if_addr_runlock(ifp);
+ return(1); /* match */
+ }
+ }
+ if_addr_runlock(ifp);
+#endif /* __FreeBSD__ */
+ }
+ return(0); /* no match, fail ... */
+}
+
+/*
+ * The verify_path function checks if a route to the src exists and
+ * if it is reachable via ifp (when provided).
+ *
+ * The 'verrevpath' option checks that the interface that an IP packet
+ * arrives on is the same interface that traffic destined for the
+ * packet's source address would be routed out of.
+ * The 'versrcreach' option just checks that the source address is
+ * reachable via any route (except default) in the routing table.
+ * These two are a measure to block forged packets. This is also
+ * commonly known as "anti-spoofing" or Unicast Reverse Path
+ * Forwarding (Unicast RFP) in Cisco-ese. The name of the knobs
+ * is purposely reminiscent of the Cisco IOS command,
+ *
+ * ip verify unicast reverse-path
+ * ip verify unicast source reachable-via any
+ *
+ * which implements the same functionality. But note that the syntax
+ * is misleading, and the check may be performed on all IP packets
+ * whether unicast, multicast, or broadcast.
+ */
+static int
+verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
+{
+#ifndef __FreeBSD__
+ return 0;
+#else
+ struct route ro;
+ struct sockaddr_in *dst;
+
+ bzero(&ro, sizeof(ro));
+
+ dst = (struct sockaddr_in *)&(ro.ro_dst);
+ dst->sin_family = AF_INET;
+ dst->sin_len = sizeof(*dst);
+ dst->sin_addr = src;
+ in_rtalloc_ign(&ro, 0, fib);
+
+ if (ro.ro_rt == NULL)
+ return 0;
+
+ /*
+ * If ifp is provided, check for equality with rtentry.
+ * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp,
+ * in order to pass packets injected back by if_simloop():
+ * if useloopback == 1 routing entry (via lo0) for our own address
+ * may exist, so we need to handle routing assymetry.
+ */
+ if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
+ RTFREE(ro.ro_rt);
+ return 0;
+ }
+
+ /* if no ifp provided, check if rtentry is not default route */
+ if (ifp == NULL &&
+ satosin(rt_key(ro.ro_rt))->sin_addr.s_addr == INADDR_ANY) {
+ RTFREE(ro.ro_rt);
+ return 0;
+ }
+
+ /* or if this is a blackhole/reject route */
+ if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
+ RTFREE(ro.ro_rt);
+ return 0;
+ }
+
+ /* found valid route */
+ RTFREE(ro.ro_rt);
+ return 1;
+#endif /* __FreeBSD__ */
+}
+
+#ifdef INET6
+/*
+ * ipv6 specific rules here...
+ */
+static __inline int
+icmp6type_match (int type, ipfw_insn_u32 *cmd)
+{
+ return (type <= ICMP6_MAXTYPE && (cmd->d[type/32] & (1<<(type%32)) ) );
+}
+
+static int
+flow6id_match( int curr_flow, ipfw_insn_u32 *cmd )
+{
+ int i;
+ for (i=0; i <= cmd->o.arg1; ++i )
+ if (curr_flow == cmd->d[i] )
+ return 1;
+ return 0;
+}
+
+/* support for IP6_*_ME opcodes */
+static int
+search_ip6_addr_net (struct in6_addr * ip6_addr)
+{
+ struct ifnet *mdc;
+ struct ifaddr *mdc2;
+ struct in6_ifaddr *fdm;
+ struct in6_addr copia;
+
+ TAILQ_FOREACH(mdc, &V_ifnet, if_link) {
+ if_addr_rlock(mdc);
+ TAILQ_FOREACH(mdc2, &mdc->if_addrhead, ifa_link) {
+ if (mdc2->ifa_addr->sa_family == AF_INET6) {
+ fdm = (struct in6_ifaddr *)mdc2;
+ copia = fdm->ia_addr.sin6_addr;
+ /* need for leaving scope_id in the sock_addr */
+ in6_clearscope(&copia);
+ if (IN6_ARE_ADDR_EQUAL(ip6_addr, &copia)) {
+ if_addr_runlock(mdc);
+ return 1;
+ }
+ }
+ }
+ if_addr_runlock(mdc);
+ }
+ return 0;
+}
+
+static int
+verify_path6(struct in6_addr *src, struct ifnet *ifp, u_int fib)
+{
+ struct route_in6 ro;
+ struct sockaddr_in6 *dst;
+
+ bzero(&ro, sizeof(ro));
+
+ dst = (struct sockaddr_in6 * )&(ro.ro_dst);
+ dst->sin6_family = AF_INET6;
+ dst->sin6_len = sizeof(*dst);
+ dst->sin6_addr = *src;
+
+ in6_rtalloc_ign(&ro, 0, fib);
+ if (ro.ro_rt == NULL)
+ return 0;
+
+ /*
+ * if ifp is provided, check for equality with rtentry
+ * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp,
+ * to support the case of sending packets to an address of our own.
+ * (where the former interface is the first argument of if_simloop()
+ * (=ifp), the latter is lo0)
+ */
+ if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
+ RTFREE(ro.ro_rt);
+ return 0;
+ }
+
+ /* if no ifp provided, check if rtentry is not default route */
+ if (ifp == NULL &&
+ IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(ro.ro_rt))->sin6_addr)) {
+ RTFREE(ro.ro_rt);
+ return 0;
+ }
+
+ /* or if this is a blackhole/reject route */
+ if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
+ RTFREE(ro.ro_rt);
+ return 0;
+ }
+
+ /* found valid route */
+ RTFREE(ro.ro_rt);
+ return 1;
+
+}
+
+static int
+is_icmp6_query(int icmp6_type)
+{
+ if ((icmp6_type <= ICMP6_MAXTYPE) &&
+ (icmp6_type == ICMP6_ECHO_REQUEST ||
+ icmp6_type == ICMP6_MEMBERSHIP_QUERY ||
+ icmp6_type == ICMP6_WRUREQUEST ||
+ icmp6_type == ICMP6_FQDN_QUERY ||
+ icmp6_type == ICMP6_NI_QUERY))
+ return (1);
+
+ return (0);
+}
+
+static void
+send_reject6(struct ip_fw_args *args, int code, u_int hlen, struct ip6_hdr *ip6)
+{
+ struct mbuf *m;
+
+ m = args->m;
+ if (code == ICMP6_UNREACH_RST && args->f_id.proto == IPPROTO_TCP) {
+ struct tcphdr *tcp;
+ tcp = (struct tcphdr *)((char *)ip6 + hlen);
+
+ if ((tcp->th_flags & TH_RST) == 0) {
+ struct mbuf *m0;
+ m0 = ipfw_send_pkt(args->m, &(args->f_id),
+ ntohl(tcp->th_seq), ntohl(tcp->th_ack),
+ tcp->th_flags | TH_RST);
+ if (m0 != NULL)
+ ip6_output(m0, NULL, NULL, 0, NULL, NULL,
+ NULL);
+ }
+ FREE_PKT(m);
+ } else if (code != ICMP6_UNREACH_RST) { /* Send an ICMPv6 unreach. */
+#if 0
+ /*
+ * Unlike above, the mbufs need to line up with the ip6 hdr,
+ * as the contents are read. We need to m_adj() the
+ * needed amount.
+ * The mbuf will however be thrown away so we can adjust it.
+ * Remember we did an m_pullup on it already so we
+ * can make some assumptions about contiguousness.
+ */
+ if (args->L3offset)
+ m_adj(m, args->L3offset);
+#endif
+ icmp6_error(m, ICMP6_DST_UNREACH, code, 0);
+ } else
+ FREE_PKT(m);
+
+ args->m = NULL;
+}
+
+#endif /* INET6 */
+
+
+/*
+ * sends a reject message, consuming the mbuf passed as an argument.
+ */
+static void
+send_reject(struct ip_fw_args *args, int code, int iplen, struct ip *ip)
+{
+
+#if 0
+ /* XXX When ip is not guaranteed to be at mtod() we will
+ * need to account for this */
+ * The mbuf will however be thrown away so we can adjust it.
+ * Remember we did an m_pullup on it already so we
+ * can make some assumptions about contiguousness.
+ */
+ if (args->L3offset)
+ m_adj(m, args->L3offset);
+#endif
+ if (code != ICMP_REJECT_RST) { /* Send an ICMP unreach */
+ /* We need the IP header in host order for icmp_error(). */
+ SET_HOST_IPLEN(ip);
+ icmp_error(args->m, ICMP_UNREACH, code, 0L, 0);
+ } else if (args->f_id.proto == IPPROTO_TCP) {
+ struct tcphdr *const tcp =
+ L3HDR(struct tcphdr, mtod(args->m, struct ip *));
+ if ( (tcp->th_flags & TH_RST) == 0) {
+ struct mbuf *m;
+ m = ipfw_send_pkt(args->m, &(args->f_id),
+ ntohl(tcp->th_seq), ntohl(tcp->th_ack),
+ tcp->th_flags | TH_RST);
+ if (m != NULL)
+ ip_output(m, NULL, NULL, 0, NULL, NULL);
+ }
+ FREE_PKT(args->m);
+ } else
+ FREE_PKT(args->m);
+ args->m = NULL;
+}
+
+/*
+ * Support for uid/gid/jail lookup. These tests are expensive
+ * (because we may need to look into the list of active sockets)
+ * so we cache the results. ugid_lookupp is 0 if we have not
+ * yet done a lookup, 1 if we succeeded, and -1 if we tried
+ * and failed. The function always returns the match value.
+ * We could actually spare the variable and use *uc, setting
+ * it to '(void *)check_uidgid if we have no info, NULL if
+ * we tried and failed, or any other value if successful.
+ */
+static int
+check_uidgid(ipfw_insn_u32 *insn, struct ip_fw_args *args, int *ugid_lookupp,
+ struct ucred **uc)
+{
+#ifndef __FreeBSD__
+ /* XXX */
+ return cred_check(insn, proto, oif,
+ dst_ip, dst_port, src_ip, src_port,
+ (struct bsd_ucred *)uc, ugid_lookupp, ((struct mbuf *)inp)->m_skb);
+#else /* FreeBSD */
+ struct in_addr src_ip, dst_ip;
+ struct inpcbinfo *pi;
+ struct ipfw_flow_id *id;
+ struct inpcb *pcb, *inp;
+ struct ifnet *oif;
+ int lookupflags;
+ int match;
+
+ id = &args->f_id;
+ inp = args->inp;
+ oif = args->oif;
+
+ /*
+ * Check to see if the UDP or TCP stack supplied us with
+ * the PCB. If so, rather then holding a lock and looking
+ * up the PCB, we can use the one that was supplied.
+ */
+ if (inp && *ugid_lookupp == 0) {
+ INP_LOCK_ASSERT(inp);
+ if (inp->inp_socket != NULL) {
+ *uc = crhold(inp->inp_cred);
+ *ugid_lookupp = 1;
+ } else
+ *ugid_lookupp = -1;
+ }
+ /*
+ * If we have already been here and the packet has no
+ * PCB entry associated with it, then we can safely
+ * assume that this is a no match.
+ */
+ if (*ugid_lookupp == -1)
+ return (0);
+ if (id->proto == IPPROTO_TCP) {
+ lookupflags = 0;
+ pi = &V_tcbinfo;
+ } else if (id->proto == IPPROTO_UDP) {
+ lookupflags = INPLOOKUP_WILDCARD;
+ pi = &V_udbinfo;
+ } else
+ return 0;
+ lookupflags |= INPLOOKUP_RLOCKPCB;
+ match = 0;
+ if (*ugid_lookupp == 0) {
+ if (id->addr_type == 6) {
+#ifdef INET6
+ if (oif == NULL)
+ pcb = in6_pcblookup_mbuf(pi,
+ &id->src_ip6, htons(id->src_port),
+ &id->dst_ip6, htons(id->dst_port),
+ lookupflags, oif, args->m);
+ else
+ pcb = in6_pcblookup_mbuf(pi,
+ &id->dst_ip6, htons(id->dst_port),
+ &id->src_ip6, htons(id->src_port),
+ lookupflags, oif, args->m);
+#else
+ *ugid_lookupp = -1;
+ return (0);
+#endif
+ } else {
+ src_ip.s_addr = htonl(id->src_ip);
+ dst_ip.s_addr = htonl(id->dst_ip);
+ if (oif == NULL)
+ pcb = in_pcblookup_mbuf(pi,
+ src_ip, htons(id->src_port),
+ dst_ip, htons(id->dst_port),
+ lookupflags, oif, args->m);
+ else
+ pcb = in_pcblookup_mbuf(pi,
+ dst_ip, htons(id->dst_port),
+ src_ip, htons(id->src_port),
+ lookupflags, oif, args->m);
+ }
+ if (pcb != NULL) {
+ INP_RLOCK_ASSERT(pcb);
+ *uc = crhold(pcb->inp_cred);
+ *ugid_lookupp = 1;
+ INP_RUNLOCK(pcb);
+ }
+ if (*ugid_lookupp == 0) {
+ /*
+ * We tried and failed, set the variable to -1
+ * so we will not try again on this packet.
+ */
+ *ugid_lookupp = -1;
+ return (0);
+ }
+ }
+ if (insn->o.opcode == O_UID)
+ match = ((*uc)->cr_uid == (uid_t)insn->d[0]);
+ else if (insn->o.opcode == O_GID)
+ match = groupmember((gid_t)insn->d[0], *uc);
+ else if (insn->o.opcode == O_JAIL)
+ match = ((*uc)->cr_prison->pr_id == (int)insn->d[0]);
+ return (match);
+#endif /* __FreeBSD__ */
+}
+
+/*
+ * Helper function to set args with info on the rule after the matching
+ * one. slot is precise, whereas we guess rule_id as they are
+ * assigned sequentially.
+ */
+static inline void
+set_match(struct ip_fw_args *args, int slot,
+ struct ip_fw_chain *chain)
+{
+ args->rule.chain_id = chain->id;
+ args->rule.slot = slot + 1; /* we use 0 as a marker */
+ args->rule.rule_id = 1 + chain->map[slot]->id;
+ args->rule.rulenum = chain->map[slot]->rulenum;
+}
+
+/*
+ * The main check routine for the firewall.
+ *
+ * All arguments are in args so we can modify them and return them
+ * back to the caller.
+ *
+ * Parameters:
+ *
+ * args->m (in/out) The packet; we set to NULL when/if we nuke it.
+ * Starts with the IP header.
+ * args->eh (in) Mac header if present, NULL for layer3 packet.
+ * args->L3offset Number of bytes bypassed if we came from L2.
+ * e.g. often sizeof(eh) ** NOTYET **
+ * args->oif Outgoing interface, NULL if packet is incoming.
+ * The incoming interface is in the mbuf. (in)
+ * args->divert_rule (in/out)
+ * Skip up to the first rule past this rule number;
+ * upon return, non-zero port number for divert or tee.
+ *
+ * args->rule Pointer to the last matching rule (in/out)
+ * args->next_hop Socket we are forwarding to (out).
+ * args->next_hop6 IPv6 next hop we are forwarding to (out).
+ * args->f_id Addresses grabbed from the packet (out)
+ * args->rule.info a cookie depending on rule action
+ *
+ * Return value:
+ *
+ * IP_FW_PASS the packet must be accepted
+ * IP_FW_DENY the packet must be dropped
+ * IP_FW_DIVERT divert packet, port in m_tag
+ * IP_FW_TEE tee packet, port in m_tag
+ * IP_FW_DUMMYNET to dummynet, pipe in args->cookie
+ * IP_FW_NETGRAPH into netgraph, cookie args->cookie
+ * args->rule contains the matching rule,
+ * args->rule.info has additional information.
+ *
+ */
+int
+ipfw_chk(struct ip_fw_args *args)
+{
+
+ /*
+ * Local variables holding state while processing a packet:
+ *
+ * IMPORTANT NOTE: to speed up the processing of rules, there
+ * are some assumption on the values of the variables, which
+ * are documented here. Should you change them, please check
+ * the implementation of the various instructions to make sure
+ * that they still work.
+ *
+ * args->eh The MAC header. It is non-null for a layer2
+ * packet, it is NULL for a layer-3 packet.
+ * **notyet**
+ * args->L3offset Offset in the packet to the L3 (IP or equiv.) header.
+ *
+ * m | args->m Pointer to the mbuf, as received from the caller.
+ * It may change if ipfw_chk() does an m_pullup, or if it
+ * consumes the packet because it calls send_reject().
+ * XXX This has to change, so that ipfw_chk() never modifies
+ * or consumes the buffer.
+ * ip is the beginning of the ip(4 or 6) header.
+ * Calculated by adding the L3offset to the start of data.
+ * (Until we start using L3offset, the packet is
+ * supposed to start with the ip header).
+ */
+ struct mbuf *m = args->m;
+ struct ip *ip = mtod(m, struct ip *);
+
+ /*
+ * For rules which contain uid/gid or jail constraints, cache
+ * a copy of the users credentials after the pcb lookup has been
+ * executed. This will speed up the processing of rules with
+ * these types of constraints, as well as decrease contention
+ * on pcb related locks.
+ */
+#ifndef __FreeBSD__
+ struct bsd_ucred ucred_cache;
+#else
+ struct ucred *ucred_cache = NULL;
+#endif
+ int ucred_lookup = 0;
+
+ /*
+ * oif | args->oif If NULL, ipfw_chk has been called on the
+ * inbound path (ether_input, ip_input).
+ * If non-NULL, ipfw_chk has been called on the outbound path
+ * (ether_output, ip_output).
+ */
+ struct ifnet *oif = args->oif;
+
+ int f_pos = 0; /* index of current rule in the array */
+ int retval = 0;
+
+ /*
+ * hlen The length of the IP header.
+ */
+ u_int hlen = 0; /* hlen >0 means we have an IP pkt */
+
+ /*
+ * offset The offset of a fragment. offset != 0 means that
+ * we have a fragment at this offset of an IPv4 packet.
+ * offset == 0 means that (if this is an IPv4 packet)
+ * this is the first or only fragment.
+ * For IPv6 offset|ip6f_mf == 0 means there is no Fragment Header
+ * or there is a single packet fragement (fragement header added
+ * without needed). We will treat a single packet fragment as if
+ * there was no fragment header (or log/block depending on the
+ * V_fw_permit_single_frag6 sysctl setting).
+ */
+ u_short offset = 0;
+ u_short ip6f_mf = 0;
+
+ /*
+ * Local copies of addresses. They are only valid if we have
+ * an IP packet.
+ *
+ * proto The protocol. Set to 0 for non-ip packets,
+ * or to the protocol read from the packet otherwise.
+ * proto != 0 means that we have an IPv4 packet.
+ *
+ * src_port, dst_port port numbers, in HOST format. Only
+ * valid for TCP and UDP packets.
+ *
+ * src_ip, dst_ip ip addresses, in NETWORK format.
+ * Only valid for IPv4 packets.
+ */
+ uint8_t proto;
+ uint16_t src_port = 0, dst_port = 0; /* NOTE: host format */
+ struct in_addr src_ip, dst_ip; /* NOTE: network format */
+ uint16_t iplen=0;
+ int pktlen;
+ uint16_t etype = 0; /* Host order stored ether type */
+
+ /*
+ * dyn_dir = MATCH_UNKNOWN when rules unchecked,
+ * MATCH_NONE when checked and not matched (q = NULL),
+ * MATCH_FORWARD or MATCH_REVERSE otherwise (q != NULL)
+ */
+ int dyn_dir = MATCH_UNKNOWN;
+ ipfw_dyn_rule *q = NULL;
+ struct ip_fw_chain *chain = &V_layer3_chain;
+
+ /*
+ * We store in ulp a pointer to the upper layer protocol header.
+ * In the ipv4 case this is easy to determine from the header,
+ * but for ipv6 we might have some additional headers in the middle.
+ * ulp is NULL if not found.
+ */
+ void *ulp = NULL; /* upper layer protocol pointer. */
+
+ /* XXX ipv6 variables */
+ int is_ipv6 = 0;
+ uint8_t icmp6_type = 0;
+ uint16_t ext_hd = 0; /* bits vector for extension header filtering */
+ /* end of ipv6 variables */
+
+ int is_ipv4 = 0;
+
+ int done = 0; /* flag to exit the outer loop */
+
+ if (m->m_flags & M_SKIP_FIREWALL || (! V_ipfw_vnet_ready))
+ return (IP_FW_PASS); /* accept */
+
+ dst_ip.s_addr = 0; /* make sure it is initialized */
+ src_ip.s_addr = 0; /* make sure it is initialized */
+ pktlen = m->m_pkthdr.len;
+ args->f_id.fib = M_GETFIB(m); /* note mbuf not altered) */
+ proto = args->f_id.proto = 0; /* mark f_id invalid */
+ /* XXX 0 is a valid proto: IP/IPv6 Hop-by-Hop Option */
+
+/*
+ * PULLUP_TO(len, p, T) makes sure that len + sizeof(T) is contiguous,
+ * then it sets p to point at the offset "len" in the mbuf. WARNING: the
+ * pointer might become stale after other pullups (but we never use it
+ * this way).
+ */
+#define PULLUP_TO(_len, p, T) PULLUP_LEN(_len, p, sizeof(T))
+#define PULLUP_LEN(_len, p, T) \
+do { \
+ int x = (_len) + T; \
+ if ((m)->m_len < x) { \
+ args->m = m = m_pullup(m, x); \
+ if (m == NULL) \
+ goto pullup_failed; \
+ } \
+ p = (mtod(m, char *) + (_len)); \
+} while (0)
+
+ /*
+ * if we have an ether header,
+ */
+ if (args->eh)
+ etype = ntohs(args->eh->ether_type);
+
+ /* Identify IP packets and fill up variables. */
+ if (pktlen >= sizeof(struct ip6_hdr) &&
+ (args->eh == NULL || etype == ETHERTYPE_IPV6) && ip->ip_v == 6) {
+ struct ip6_hdr *ip6 = (struct ip6_hdr *)ip;
+ is_ipv6 = 1;
+ args->f_id.addr_type = 6;
+ hlen = sizeof(struct ip6_hdr);
+ proto = ip6->ip6_nxt;
+
+ /* Search extension headers to find upper layer protocols */
+ while (ulp == NULL && offset == 0) {
+ switch (proto) {
+ case IPPROTO_ICMPV6:
+ PULLUP_TO(hlen, ulp, struct icmp6_hdr);
+ icmp6_type = ICMP6(ulp)->icmp6_type;
+ break;
+
+ case IPPROTO_TCP:
+ PULLUP_TO(hlen, ulp, struct tcphdr);
+ dst_port = TCP(ulp)->th_dport;
+ src_port = TCP(ulp)->th_sport;
+ /* save flags for dynamic rules */
+ args->f_id._flags = TCP(ulp)->th_flags;
+ break;
+
+ case IPPROTO_SCTP:
+ PULLUP_TO(hlen, ulp, struct sctphdr);
+ src_port = SCTP(ulp)->src_port;
+ dst_port = SCTP(ulp)->dest_port;
+ break;
+
+ case IPPROTO_UDP:
+ PULLUP_TO(hlen, ulp, struct udphdr);
+ dst_port = UDP(ulp)->uh_dport;
+ src_port = UDP(ulp)->uh_sport;
+ break;
+
+ case IPPROTO_HOPOPTS: /* RFC 2460 */
+ PULLUP_TO(hlen, ulp, struct ip6_hbh);
+ ext_hd |= EXT_HOPOPTS;
+ hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
+ proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
+ ulp = NULL;
+ break;
+
+ case IPPROTO_ROUTING: /* RFC 2460 */
+ PULLUP_TO(hlen, ulp, struct ip6_rthdr);
+ switch (((struct ip6_rthdr *)ulp)->ip6r_type) {
+ case 0:
+ ext_hd |= EXT_RTHDR0;
+ break;
+ case 2:
+ ext_hd |= EXT_RTHDR2;
+ break;
+ default:
+ if (V_fw_verbose)
+ printf("IPFW2: IPV6 - Unknown "
+ "Routing Header type(%d)\n",
+ ((struct ip6_rthdr *)
+ ulp)->ip6r_type);
+ if (V_fw_deny_unknown_exthdrs)
+ return (IP_FW_DENY);
+ break;
+ }
+ ext_hd |= EXT_ROUTING;
+ hlen += (((struct ip6_rthdr *)ulp)->ip6r_len + 1) << 3;
+ proto = ((struct ip6_rthdr *)ulp)->ip6r_nxt;
+ ulp = NULL;
+ break;
+
+ case IPPROTO_FRAGMENT: /* RFC 2460 */
+ PULLUP_TO(hlen, ulp, struct ip6_frag);
+ ext_hd |= EXT_FRAGMENT;
+ hlen += sizeof (struct ip6_frag);
+ proto = ((struct ip6_frag *)ulp)->ip6f_nxt;
+ offset = ((struct ip6_frag *)ulp)->ip6f_offlg &
+ IP6F_OFF_MASK;
+ ip6f_mf = ((struct ip6_frag *)ulp)->ip6f_offlg &
+ IP6F_MORE_FRAG;
+ if (V_fw_permit_single_frag6 == 0 &&
+ offset == 0 && ip6f_mf == 0) {
+ if (V_fw_verbose)
+ printf("IPFW2: IPV6 - Invalid "
+ "Fragment Header\n");
+ if (V_fw_deny_unknown_exthdrs)
+ return (IP_FW_DENY);
+ break;
+ }
+ args->f_id.extra =
+ ntohl(((struct ip6_frag *)ulp)->ip6f_ident);
+ ulp = NULL;
+ break;
+
+ case IPPROTO_DSTOPTS: /* RFC 2460 */
+ PULLUP_TO(hlen, ulp, struct ip6_hbh);
+ ext_hd |= EXT_DSTOPTS;
+ hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
+ proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
+ ulp = NULL;
+ break;
+
+ case IPPROTO_AH: /* RFC 2402 */
+ PULLUP_TO(hlen, ulp, struct ip6_ext);
+ ext_hd |= EXT_AH;
+ hlen += (((struct ip6_ext *)ulp)->ip6e_len + 2) << 2;
+ proto = ((struct ip6_ext *)ulp)->ip6e_nxt;
+ ulp = NULL;
+ break;
+
+ case IPPROTO_ESP: /* RFC 2406 */
+ PULLUP_TO(hlen, ulp, uint32_t); /* SPI, Seq# */
+ /* Anything past Seq# is variable length and
+ * data past this ext. header is encrypted. */
+ ext_hd |= EXT_ESP;
+ break;
+
+ case IPPROTO_NONE: /* RFC 2460 */
+ /*
+ * Packet ends here, and IPv6 header has
+ * already been pulled up. If ip6e_len!=0
+ * then octets must be ignored.
+ */
+ ulp = ip; /* non-NULL to get out of loop. */
+ break;
+
+ case IPPROTO_OSPFIGP:
+ /* XXX OSPF header check? */
+ PULLUP_TO(hlen, ulp, struct ip6_ext);
+ break;
+
+ case IPPROTO_PIM:
+ /* XXX PIM header check? */
+ PULLUP_TO(hlen, ulp, struct pim);
+ break;
+
+ case IPPROTO_CARP:
+ PULLUP_TO(hlen, ulp, struct carp_header);
+ if (((struct carp_header *)ulp)->carp_version !=
+ CARP_VERSION)
+ return (IP_FW_DENY);
+ if (((struct carp_header *)ulp)->carp_type !=
+ CARP_ADVERTISEMENT)
+ return (IP_FW_DENY);
+ break;
+
+ case IPPROTO_IPV6: /* RFC 2893 */
+ PULLUP_TO(hlen, ulp, struct ip6_hdr);
+ break;
+
+ case IPPROTO_IPV4: /* RFC 2893 */
+ PULLUP_TO(hlen, ulp, struct ip);
+ break;
+
+ default:
+ if (V_fw_verbose)
+ printf("IPFW2: IPV6 - Unknown "
+ "Extension Header(%d), ext_hd=%x\n",
+ proto, ext_hd);
+ if (V_fw_deny_unknown_exthdrs)
+ return (IP_FW_DENY);
+ PULLUP_TO(hlen, ulp, struct ip6_ext);
+ break;
+ } /*switch */
+ }
+ ip = mtod(m, struct ip *);
+ ip6 = (struct ip6_hdr *)ip;
+ args->f_id.src_ip6 = ip6->ip6_src;
+ args->f_id.dst_ip6 = ip6->ip6_dst;
+ args->f_id.src_ip = 0;
+ args->f_id.dst_ip = 0;
+ args->f_id.flow_id6 = ntohl(ip6->ip6_flow);
+ } else if (pktlen >= sizeof(struct ip) &&
+ (args->eh == NULL || etype == ETHERTYPE_IP) && ip->ip_v == 4) {
+ is_ipv4 = 1;
+ hlen = ip->ip_hl << 2;
+ args->f_id.addr_type = 4;
+
+ /*
+ * Collect parameters into local variables for faster matching.
+ */
+ proto = ip->ip_p;
+ src_ip = ip->ip_src;
+ dst_ip = ip->ip_dst;
+ offset = ntohs(ip->ip_off) & IP_OFFMASK;
+ iplen = ntohs(ip->ip_len);
+ pktlen = iplen < pktlen ? iplen : pktlen;
+
+ if (offset == 0) {
+ switch (proto) {
+ case IPPROTO_TCP:
+ PULLUP_TO(hlen, ulp, struct tcphdr);
+ dst_port = TCP(ulp)->th_dport;
+ src_port = TCP(ulp)->th_sport;
+ /* save flags for dynamic rules */
+ args->f_id._flags = TCP(ulp)->th_flags;
+ break;
+
+ case IPPROTO_SCTP:
+ PULLUP_TO(hlen, ulp, struct sctphdr);
+ src_port = SCTP(ulp)->src_port;
+ dst_port = SCTP(ulp)->dest_port;
+ break;
+
+ case IPPROTO_UDP:
+ PULLUP_TO(hlen, ulp, struct udphdr);
+ dst_port = UDP(ulp)->uh_dport;
+ src_port = UDP(ulp)->uh_sport;
+ break;
+
+ case IPPROTO_ICMP:
+ PULLUP_TO(hlen, ulp, struct icmphdr);
+ //args->f_id.flags = ICMP(ulp)->icmp_type;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ ip = mtod(m, struct ip *);
+ args->f_id.src_ip = ntohl(src_ip.s_addr);
+ args->f_id.dst_ip = ntohl(dst_ip.s_addr);
+ }
+#undef PULLUP_TO
+ if (proto) { /* we may have port numbers, store them */
+ args->f_id.proto = proto;
+ args->f_id.src_port = src_port = ntohs(src_port);
+ args->f_id.dst_port = dst_port = ntohs(dst_port);
+ }
+
+ IPFW_RLOCK(chain);
+ if (! V_ipfw_vnet_ready) { /* shutting down, leave NOW. */
+ IPFW_RUNLOCK(chain);
+ return (IP_FW_PASS); /* accept */
+ }
+ if (args->rule.slot) {
+ /*
+ * Packet has already been tagged as a result of a previous
+ * match on rule args->rule aka args->rule_id (PIPE, QUEUE,
+ * REASS, NETGRAPH, DIVERT/TEE...)
+ * Validate the slot and continue from the next one
+ * if still present, otherwise do a lookup.
+ */
+ f_pos = (args->rule.chain_id == chain->id) ?
+ args->rule.slot :
+ ipfw_find_rule(chain, args->rule.rulenum,
+ args->rule.rule_id);
+ } else {
+ f_pos = 0;
+ }
+
+ /*
+ * Now scan the rules, and parse microinstructions for each rule.
+ * We have two nested loops and an inner switch. Sometimes we
+ * need to break out of one or both loops, or re-enter one of
+ * the loops with updated variables. Loop variables are:
+ *
+ * f_pos (outer loop) points to the current rule.
+ * On output it points to the matching rule.
+ * done (outer loop) is used as a flag to break the loop.
+ * l (inner loop) residual length of current rule.
+ * cmd points to the current microinstruction.
+ *
+ * We break the inner loop by setting l=0 and possibly
+ * cmdlen=0 if we don't want to advance cmd.
+ * We break the outer loop by setting done=1
+ * We can restart the inner loop by setting l>0 and f_pos, f, cmd
+ * as needed.
+ */
+ for (; f_pos < chain->n_rules; f_pos++) {
+ ipfw_insn *cmd;
+ uint32_t tablearg = 0;
+ int l, cmdlen, skip_or; /* skip rest of OR block */
+ struct ip_fw *f;
+
+ f = chain->map[f_pos];
+ if (V_set_disable & (1 << f->set) )
+ continue;
+
+ skip_or = 0;
+ for (l = f->cmd_len, cmd = f->cmd ; l > 0 ;
+ l -= cmdlen, cmd += cmdlen) {
+ int match;
+
+ /*
+ * check_body is a jump target used when we find a
+ * CHECK_STATE, and need to jump to the body of
+ * the target rule.
+ */
+
+/* check_body: */
+ cmdlen = F_LEN(cmd);
+ /*
+ * An OR block (insn_1 || .. || insn_n) has the
+ * F_OR bit set in all but the last instruction.
+ * The first match will set "skip_or", and cause
+ * the following instructions to be skipped until
+ * past the one with the F_OR bit clear.
+ */
+ if (skip_or) { /* skip this instruction */
+ if ((cmd->len & F_OR) == 0)
+ skip_or = 0; /* next one is good */
+ continue;
+ }
+ match = 0; /* set to 1 if we succeed */
+
+ switch (cmd->opcode) {
+ /*
+ * The first set of opcodes compares the packet's
+ * fields with some pattern, setting 'match' if a
+ * match is found. At the end of the loop there is
+ * logic to deal with F_NOT and F_OR flags associated
+ * with the opcode.
+ */
+ case O_NOP:
+ match = 1;
+ break;
+
+ case O_FORWARD_MAC:
+ printf("ipfw: opcode %d unimplemented\n",
+ cmd->opcode);
+ break;
+
+ case O_GID:
+ case O_UID:
+ case O_JAIL:
+ /*
+ * We only check offset == 0 && proto != 0,
+ * as this ensures that we have a
+ * packet with the ports info.
+ */
+ if (offset != 0)
+ break;
+ if (proto == IPPROTO_TCP ||
+ proto == IPPROTO_UDP)
+ match = check_uidgid(
+ (ipfw_insn_u32 *)cmd,
+ args, &ucred_lookup,
+#ifdef __FreeBSD__
+ &ucred_cache);
+#else
+ (void *)&ucred_cache);
+#endif
+ break;
+
+ case O_RECV:
+ match = iface_match(m->m_pkthdr.rcvif,
+ (ipfw_insn_if *)cmd, chain, &tablearg);
+ break;
+
+ case O_XMIT:
+ match = iface_match(oif, (ipfw_insn_if *)cmd,
+ chain, &tablearg);
+ break;
+
+ case O_VIA:
+ match = iface_match(oif ? oif :
+ m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd,
+ chain, &tablearg);
+ break;
+
+ case O_MACADDR2:
+ if (args->eh != NULL) { /* have MAC header */
+ u_int32_t *want = (u_int32_t *)
+ ((ipfw_insn_mac *)cmd)->addr;
+ u_int32_t *mask = (u_int32_t *)
+ ((ipfw_insn_mac *)cmd)->mask;
+ u_int32_t *hdr = (u_int32_t *)args->eh;
+
+ match =
+ ( want[0] == (hdr[0] & mask[0]) &&
+ want[1] == (hdr[1] & mask[1]) &&
+ want[2] == (hdr[2] & mask[2]) );
+ }
+ break;
+
+ case O_MAC_TYPE:
+ if (args->eh != NULL) {
+ u_int16_t *p =
+ ((ipfw_insn_u16 *)cmd)->ports;
+ int i;
+
+ for (i = cmdlen - 1; !match && i>0;
+ i--, p += 2)
+ match = (etype >= p[0] &&
+ etype <= p[1]);
+ }
+ break;
+
+ case O_FRAG:
+ match = (offset != 0);
+ break;
+
+ case O_IN: /* "out" is "not in" */
+ match = (oif == NULL);
+ break;
+
+ case O_LAYER2:
+ match = (args->eh != NULL);
+ break;
+
+ case O_DIVERTED:
+ {
+ /* For diverted packets, args->rule.info
+ * contains the divert port (in host format)
+ * reason and direction.
+ */
+ uint32_t i = args->rule.info;
+ match = (i&IPFW_IS_MASK) == IPFW_IS_DIVERT &&
+ cmd->arg1 & ((i & IPFW_INFO_IN) ? 1 : 2);
+ }
+ break;
+
+ case O_PROTO:
+ /*
+ * We do not allow an arg of 0 so the
+ * check of "proto" only suffices.
+ */
+ match = (proto == cmd->arg1);
+ break;
+
+ case O_IP_SRC:
+ match = is_ipv4 &&
+ (((ipfw_insn_ip *)cmd)->addr.s_addr ==
+ src_ip.s_addr);
+ break;
+
+ case O_IP_SRC_LOOKUP:
+ case O_IP_DST_LOOKUP:
+ if (is_ipv4) {
+ uint32_t key =
+ (cmd->opcode == O_IP_DST_LOOKUP) ?
+ dst_ip.s_addr : src_ip.s_addr;
+ uint32_t v = 0;
+
+ if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) {
+ /* generic lookup. The key must be
+ * in 32bit big-endian format.
+ */
+ v = ((ipfw_insn_u32 *)cmd)->d[1];
+ if (v == 0)
+ key = dst_ip.s_addr;
+ else if (v == 1)
+ key = src_ip.s_addr;
+ else if (v == 6) /* dscp */
+ key = (ip->ip_tos >> 2) & 0x3f;
+ else if (offset != 0)
+ break;
+ else if (proto != IPPROTO_TCP &&
+ proto != IPPROTO_UDP)
+ break;
+ else if (v == 2)
+ key = htonl(dst_port);
+ else if (v == 3)
+ key = htonl(src_port);
+ else if (v == 4 || v == 5) {
+ check_uidgid(
+ (ipfw_insn_u32 *)cmd,
+ args, &ucred_lookup,
+#ifdef __FreeBSD__
+ &ucred_cache);
+ if (v == 4 /* O_UID */)
+ key = ucred_cache->cr_uid;
+ else if (v == 5 /* O_JAIL */)
+ key = ucred_cache->cr_prison->pr_id;
+#else /* !__FreeBSD__ */
+ (void *)&ucred_cache);
+ if (v ==4 /* O_UID */)
+ key = ucred_cache.uid;
+ else if (v == 5 /* O_JAIL */)
+ key = ucred_cache.xid;
+#endif /* !__FreeBSD__ */
+ key = htonl(key);
+ } else
+ break;
+ }
+ match = ipfw_lookup_table(chain,
+ cmd->arg1, key, &v);
+ if (!match)
+ break;
+ if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
+ match =
+ ((ipfw_insn_u32 *)cmd)->d[0] == v;
+ else
+ tablearg = v;
+ } else if (is_ipv6) {
+ uint32_t v = 0;
+ void *pkey = (cmd->opcode == O_IP_DST_LOOKUP) ?
+ &args->f_id.dst_ip6: &args->f_id.src_ip6;
+ match = ipfw_lookup_table_extended(chain,
+ cmd->arg1, pkey, &v,
+ IPFW_TABLE_CIDR);
+ if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
+ match = ((ipfw_insn_u32 *)cmd)->d[0] == v;
+ if (match)
+ tablearg = v;
+ }
+ break;
+
+ case O_IP_SRC_MASK:
+ case O_IP_DST_MASK:
+ if (is_ipv4) {
+ uint32_t a =
+ (cmd->opcode == O_IP_DST_MASK) ?
+ dst_ip.s_addr : src_ip.s_addr;
+ uint32_t *p = ((ipfw_insn_u32 *)cmd)->d;
+ int i = cmdlen-1;
+
+ for (; !match && i>0; i-= 2, p+= 2)
+ match = (p[0] == (a & p[1]));
+ }
+ break;
+
+ case O_IP_SRC_ME:
+ if (is_ipv4) {
+ struct ifnet *tif;
+
+ INADDR_TO_IFP(src_ip, tif);
+ match = (tif != NULL);
+ break;
+ }
+#ifdef INET6
+ /* FALLTHROUGH */
+ case O_IP6_SRC_ME:
+ match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
+#endif
+ break;
+
+ case O_IP_DST_SET:
+ case O_IP_SRC_SET:
+ if (is_ipv4) {
+ u_int32_t *d = (u_int32_t *)(cmd+1);
+ u_int32_t addr =
+ cmd->opcode == O_IP_DST_SET ?
+ args->f_id.dst_ip :
+ args->f_id.src_ip;
+
+ if (addr < d[0])
+ break;
+ addr -= d[0]; /* subtract base */
+ match = (addr < cmd->arg1) &&
+ ( d[ 1 + (addr>>5)] &
+ (1<<(addr & 0x1f)) );
+ }
+ break;
+
+ case O_IP_DST:
+ match = is_ipv4 &&
+ (((ipfw_insn_ip *)cmd)->addr.s_addr ==
+ dst_ip.s_addr);
+ break;
+
+ case O_IP_DST_ME:
+ if (is_ipv4) {
+ struct ifnet *tif;
+
+ INADDR_TO_IFP(dst_ip, tif);
+ match = (tif != NULL);
+ break;
+ }
+#ifdef INET6
+ /* FALLTHROUGH */
+ case O_IP6_DST_ME:
+ match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
+#endif
+ break;
+
+
+ case O_IP_SRCPORT:
+ case O_IP_DSTPORT:
+ /*
+ * offset == 0 && proto != 0 is enough
+ * to guarantee that we have a
+ * packet with port info.
+ */
+ if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP)
+ && offset == 0) {
+ u_int16_t x =
+ (cmd->opcode == O_IP_SRCPORT) ?
+ src_port : dst_port ;
+ u_int16_t *p =
+ ((ipfw_insn_u16 *)cmd)->ports;
+ int i;
+
+ for (i = cmdlen - 1; !match && i>0;
+ i--, p += 2)
+ match = (x>=p[0] && x<=p[1]);
+ }
+ break;
+
+ case O_ICMPTYPE:
+ match = (offset == 0 && proto==IPPROTO_ICMP &&
+ icmptype_match(ICMP(ulp), (ipfw_insn_u32 *)cmd) );
+ break;
+
+#ifdef INET6
+ case O_ICMP6TYPE:
+ match = is_ipv6 && offset == 0 &&
+ proto==IPPROTO_ICMPV6 &&
+ icmp6type_match(
+ ICMP6(ulp)->icmp6_type,
+ (ipfw_insn_u32 *)cmd);
+ break;
+#endif /* INET6 */
+
+ case O_IPOPT:
+ match = (is_ipv4 &&
+ ipopts_match(ip, cmd) );
+ break;
+
+ case O_IPVER:
+ match = (is_ipv4 &&
+ cmd->arg1 == ip->ip_v);
+ break;
+
+ case O_IPID:
+ case O_IPLEN:
+ case O_IPTTL:
+ if (is_ipv4) { /* only for IP packets */
+ uint16_t x;
+ uint16_t *p;
+ int i;
+
+ if (cmd->opcode == O_IPLEN)
+ x = iplen;
+ else if (cmd->opcode == O_IPTTL)
+ x = ip->ip_ttl;
+ else /* must be IPID */
+ x = ntohs(ip->ip_id);
+ if (cmdlen == 1) {
+ match = (cmd->arg1 == x);
+ break;
+ }
+ /* otherwise we have ranges */
+ p = ((ipfw_insn_u16 *)cmd)->ports;
+ i = cmdlen - 1;
+ for (; !match && i>0; i--, p += 2)
+ match = (x >= p[0] && x <= p[1]);
+ }
+ break;
+
+ case O_IPPRECEDENCE:
+ match = (is_ipv4 &&
+ (cmd->arg1 == (ip->ip_tos & 0xe0)) );
+ break;
+
+ case O_IPTOS:
+ match = (is_ipv4 &&
+ flags_match(cmd, ip->ip_tos));
+ break;
+
+ case O_TCPDATALEN:
+ if (proto == IPPROTO_TCP && offset == 0) {
+ struct tcphdr *tcp;
+ uint16_t x;
+ uint16_t *p;
+ int i;
+
+ tcp = TCP(ulp);
+ x = iplen -
+ ((ip->ip_hl + tcp->th_off) << 2);
+ if (cmdlen == 1) {
+ match = (cmd->arg1 == x);
+ break;
+ }
+ /* otherwise we have ranges */
+ p = ((ipfw_insn_u16 *)cmd)->ports;
+ i = cmdlen - 1;
+ for (; !match && i>0; i--, p += 2)
+ match = (x >= p[0] && x <= p[1]);
+ }
+ break;
+
+ case O_TCPFLAGS:
+ match = (proto == IPPROTO_TCP && offset == 0 &&
+ flags_match(cmd, TCP(ulp)->th_flags));
+ break;
+
+ case O_TCPOPTS:
+ PULLUP_LEN(hlen, ulp, (TCP(ulp)->th_off << 2));
+ match = (proto == IPPROTO_TCP && offset == 0 &&
+ tcpopts_match(TCP(ulp), cmd));
+ break;
+
+ case O_TCPSEQ:
+ match = (proto == IPPROTO_TCP && offset == 0 &&
+ ((ipfw_insn_u32 *)cmd)->d[0] ==
+ TCP(ulp)->th_seq);
+ break;
+
+ case O_TCPACK:
+ match = (proto == IPPROTO_TCP && offset == 0 &&
+ ((ipfw_insn_u32 *)cmd)->d[0] ==
+ TCP(ulp)->th_ack);
+ break;
+
+ case O_TCPWIN:
+ if (proto == IPPROTO_TCP && offset == 0) {
+ uint16_t x;
+ uint16_t *p;
+ int i;
+
+ x = ntohs(TCP(ulp)->th_win);
+ if (cmdlen == 1) {
+ match = (cmd->arg1 == x);
+ break;
+ }
+ /* Otherwise we have ranges. */
+ p = ((ipfw_insn_u16 *)cmd)->ports;
+ i = cmdlen - 1;
+ for (; !match && i > 0; i--, p += 2)
+ match = (x >= p[0] && x <= p[1]);
+ }
+ break;
+
+ case O_ESTAB:
+ /* reject packets which have SYN only */
+ /* XXX should i also check for TH_ACK ? */
+ match = (proto == IPPROTO_TCP && offset == 0 &&
+ (TCP(ulp)->th_flags &
+ (TH_RST | TH_ACK | TH_SYN)) != TH_SYN);
+ break;
+
+ case O_ALTQ: {
+ struct pf_mtag *at;
+ ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
+
+ match = 1;
+ at = pf_find_mtag(m);
+ if (at != NULL && at->qid != 0)
+ break;
+ at = pf_get_mtag(m);
+ if (at == NULL) {
+ /*
+ * Let the packet fall back to the
+ * default ALTQ.
+ */
+ break;
+ }
+ at->qid = altq->qid;
+ at->hdr = ip;
+ break;
+ }
+
+ case O_LOG:
+ ipfw_log(f, hlen, args, m,
+ oif, offset | ip6f_mf, tablearg, ip);
+ match = 1;
+ break;
+
+ case O_PROB:
+ match = (random()<((ipfw_insn_u32 *)cmd)->d[0]);
+ break;
+
+ case O_VERREVPATH:
+ /* Outgoing packets automatically pass/match */
+ match = ((oif != NULL) ||
+ (m->m_pkthdr.rcvif == NULL) ||
+ (
+#ifdef INET6
+ is_ipv6 ?
+ verify_path6(&(args->f_id.src_ip6),
+ m->m_pkthdr.rcvif, args->f_id.fib) :
+#endif
+ verify_path(src_ip, m->m_pkthdr.rcvif,
+ args->f_id.fib)));
+ break;
+
+ case O_VERSRCREACH:
+ /* Outgoing packets automatically pass/match */
+ match = (hlen > 0 && ((oif != NULL) ||
+#ifdef INET6
+ is_ipv6 ?
+ verify_path6(&(args->f_id.src_ip6),
+ NULL, args->f_id.fib) :
+#endif
+ verify_path(src_ip, NULL, args->f_id.fib)));
+ break;
+
+ case O_ANTISPOOF:
+ /* Outgoing packets automatically pass/match */
+ if (oif == NULL && hlen > 0 &&
+ ( (is_ipv4 && in_localaddr(src_ip))
+#ifdef INET6
+ || (is_ipv6 &&
+ in6_localaddr(&(args->f_id.src_ip6)))
+#endif
+ ))
+ match =
+#ifdef INET6
+ is_ipv6 ? verify_path6(
+ &(args->f_id.src_ip6),
+ m->m_pkthdr.rcvif,
+ args->f_id.fib) :
+#endif
+ verify_path(src_ip,
+ m->m_pkthdr.rcvif,
+ args->f_id.fib);
+ else
+ match = 1;
+ break;
+
+ case O_IPSEC:
+#ifdef IPSEC
+ match = (m_tag_find(m,
+ PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL);
+#endif
+ /* otherwise no match */
+ break;
+
+#ifdef INET6
+ case O_IP6_SRC:
+ match = is_ipv6 &&
+ IN6_ARE_ADDR_EQUAL(&args->f_id.src_ip6,
+ &((ipfw_insn_ip6 *)cmd)->addr6);
+ break;
+
+ case O_IP6_DST:
+ match = is_ipv6 &&
+ IN6_ARE_ADDR_EQUAL(&args->f_id.dst_ip6,
+ &((ipfw_insn_ip6 *)cmd)->addr6);
+ break;
+ case O_IP6_SRC_MASK:
+ case O_IP6_DST_MASK:
+ if (is_ipv6) {
+ int i = cmdlen - 1;
+ struct in6_addr p;
+ struct in6_addr *d =
+ &((ipfw_insn_ip6 *)cmd)->addr6;
+
+ for (; !match && i > 0; d += 2,
+ i -= F_INSN_SIZE(struct in6_addr)
+ * 2) {
+ p = (cmd->opcode ==
+ O_IP6_SRC_MASK) ?
+ args->f_id.src_ip6:
+ args->f_id.dst_ip6;
+ APPLY_MASK(&p, &d[1]);
+ match =
+ IN6_ARE_ADDR_EQUAL(&d[0],
+ &p);
+ }
+ }
+ break;
+
+ case O_FLOW6ID:
+ match = is_ipv6 &&
+ flow6id_match(args->f_id.flow_id6,
+ (ipfw_insn_u32 *) cmd);
+ break;
+
+ case O_EXT_HDR:
+ match = is_ipv6 &&
+ (ext_hd & ((ipfw_insn *) cmd)->arg1);
+ break;
+
+ case O_IP6:
+ match = is_ipv6;
+ break;
+#endif
+
+ case O_IP4:
+ match = is_ipv4;
+ break;
+
+ case O_TAG: {
+ struct m_tag *mtag;
+ uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
+ tablearg : cmd->arg1;
+
+ /* Packet is already tagged with this tag? */
+ mtag = m_tag_locate(m, MTAG_IPFW, tag, NULL);
+
+ /* We have `untag' action when F_NOT flag is
+ * present. And we must remove this mtag from
+ * mbuf and reset `match' to zero (`match' will
+ * be inversed later).
+ * Otherwise we should allocate new mtag and
+ * push it into mbuf.
+ */
+ if (cmd->len & F_NOT) { /* `untag' action */
+ if (mtag != NULL)
+ m_tag_delete(m, mtag);
+ match = 0;
+ } else {
+ if (mtag == NULL) {
+ mtag = m_tag_alloc( MTAG_IPFW,
+ tag, 0, M_NOWAIT);
+ if (mtag != NULL)
+ m_tag_prepend(m, mtag);
+ }
+ match = 1;
+ }
+ break;
+ }
+
+ case O_FIB: /* try match the specified fib */
+ if (args->f_id.fib == cmd->arg1)
+ match = 1;
+ break;
+
+ case O_SOCKARG: {
+ struct inpcb *inp = args->inp;
+ struct inpcbinfo *pi;
+
+ if (is_ipv6) /* XXX can we remove this ? */
+ break;
+
+ if (proto == IPPROTO_TCP)
+ pi = &V_tcbinfo;
+ else if (proto == IPPROTO_UDP)
+ pi = &V_udbinfo;
+ else
+ break;
+
+ /*
+ * XXXRW: so_user_cookie should almost
+ * certainly be inp_user_cookie?
+ */
+
+ /* For incomming packet, lookup up the
+ inpcb using the src/dest ip/port tuple */
+ if (inp == NULL) {
+ inp = in_pcblookup(pi,
+ src_ip, htons(src_port),
+ dst_ip, htons(dst_port),
+ INPLOOKUP_RLOCKPCB, NULL);
+ if (inp != NULL) {
+ tablearg =
+ inp->inp_socket->so_user_cookie;
+ if (tablearg)
+ match = 1;
+ INP_RUNLOCK(inp);
+ }
+ } else {
+ if (inp->inp_socket) {
+ tablearg =
+ inp->inp_socket->so_user_cookie;
+ if (tablearg)
+ match = 1;
+ }
+ }
+ break;
+ }
+
+ case O_TAGGED: {
+ struct m_tag *mtag;
+ uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
+ tablearg : cmd->arg1;
+
+ if (cmdlen == 1) {
+ match = m_tag_locate(m, MTAG_IPFW,
+ tag, NULL) != NULL;
+ break;
+ }
+
+ /* we have ranges */
+ for (mtag = m_tag_first(m);
+ mtag != NULL && !match;
+ mtag = m_tag_next(m, mtag)) {
+ uint16_t *p;
+ int i;
+
+ if (mtag->m_tag_cookie != MTAG_IPFW)
+ continue;
+
+ p = ((ipfw_insn_u16 *)cmd)->ports;
+ i = cmdlen - 1;
+ for(; !match && i > 0; i--, p += 2)
+ match =
+ mtag->m_tag_id >= p[0] &&
+ mtag->m_tag_id <= p[1];
+ }
+ break;
+ }
+
+ /*
+ * The second set of opcodes represents 'actions',
+ * i.e. the terminal part of a rule once the packet
+ * matches all previous patterns.
+ * Typically there is only one action for each rule,
+ * and the opcode is stored at the end of the rule
+ * (but there are exceptions -- see below).
+ *
+ * In general, here we set retval and terminate the
+ * outer loop (would be a 'break 3' in some language,
+ * but we need to set l=0, done=1)
+ *
+ * Exceptions:
+ * O_COUNT and O_SKIPTO actions:
+ * instead of terminating, we jump to the next rule
+ * (setting l=0), or to the SKIPTO target (setting
+ * f/f_len, cmd and l as needed), respectively.
+ *
+ * O_TAG, O_LOG and O_ALTQ action parameters:
+ * perform some action and set match = 1;
+ *
+ * O_LIMIT and O_KEEP_STATE: these opcodes are
+ * not real 'actions', and are stored right
+ * before the 'action' part of the rule.
+ * These opcodes try to install an entry in the
+ * state tables; if successful, we continue with
+ * the next opcode (match=1; break;), otherwise
+ * the packet must be dropped (set retval,
+ * break loops with l=0, done=1)
+ *
+ * O_PROBE_STATE and O_CHECK_STATE: these opcodes
+ * cause a lookup of the state table, and a jump
+ * to the 'action' part of the parent rule
+ * if an entry is found, or
+ * (CHECK_STATE only) a jump to the next rule if
+ * the entry is not found.
+ * The result of the lookup is cached so that
+ * further instances of these opcodes become NOPs.
+ * The jump to the next rule is done by setting
+ * l=0, cmdlen=0.
+ */
+ case O_LIMIT:
+ case O_KEEP_STATE:
+ if (ipfw_install_state(f,
+ (ipfw_insn_limit *)cmd, args, tablearg)) {
+ /* error or limit violation */
+ retval = IP_FW_DENY;
+ l = 0; /* exit inner loop */
+ done = 1; /* exit outer loop */
+ }
+ match = 1;
+ break;
+
+ case O_PROBE_STATE:
+ case O_CHECK_STATE:
+ /*
+ * dynamic rules are checked at the first
+ * keep-state or check-state occurrence,
+ * with the result being stored in dyn_dir.
+ * The compiler introduces a PROBE_STATE
+ * instruction for us when we have a
+ * KEEP_STATE (because PROBE_STATE needs
+ * to be run first).
+ */
+ if (dyn_dir == MATCH_UNKNOWN &&
+ (q = ipfw_lookup_dyn_rule(&args->f_id,
+ &dyn_dir, proto == IPPROTO_TCP ?
+ TCP(ulp) : NULL))
+ != NULL) {
+ /*
+ * Found dynamic entry, update stats
+ * and jump to the 'action' part of
+ * the parent rule by setting
+ * f, cmd, l and clearing cmdlen.
+ */
+ q->pcnt++;
+ q->bcnt += pktlen;
+ /* XXX we would like to have f_pos
+ * readily accessible in the dynamic
+ * rule, instead of having to
+ * lookup q->rule.
+ */
+ f = q->rule;
+ f_pos = ipfw_find_rule(chain,
+ f->rulenum, f->id);
+ cmd = ACTION_PTR(f);
+ l = f->cmd_len - f->act_ofs;
+ ipfw_dyn_unlock();
+ cmdlen = 0;
+ match = 1;
+ break;
+ }
+ /*
+ * Dynamic entry not found. If CHECK_STATE,
+ * skip to next rule, if PROBE_STATE just
+ * ignore and continue with next opcode.
+ */
+ if (cmd->opcode == O_CHECK_STATE)
+ l = 0; /* exit inner loop */
+ match = 1;
+ break;
+
+ case O_ACCEPT:
+ retval = 0; /* accept */
+ l = 0; /* exit inner loop */
+ done = 1; /* exit outer loop */
+ break;
+
+ case O_PIPE:
+ case O_QUEUE:
+ set_match(args, f_pos, chain);
+ args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
+ tablearg : cmd->arg1;
+ if (cmd->opcode == O_PIPE)
+ args->rule.info |= IPFW_IS_PIPE;
+ if (V_fw_one_pass)
+ args->rule.info |= IPFW_ONEPASS;
+ retval = IP_FW_DUMMYNET;
+ l = 0; /* exit inner loop */
+ done = 1; /* exit outer loop */
+ break;
+
+ case O_DIVERT:
+ case O_TEE:
+ if (args->eh) /* not on layer 2 */
+ break;
+ /* otherwise this is terminal */
+ l = 0; /* exit inner loop */
+ done = 1; /* exit outer loop */
+ retval = (cmd->opcode == O_DIVERT) ?
+ IP_FW_DIVERT : IP_FW_TEE;
+ set_match(args, f_pos, chain);
+ args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
+ tablearg : cmd->arg1;
+ break;
+
+ case O_COUNT:
+ f->pcnt++; /* update stats */
+ f->bcnt += pktlen;
+ f->timestamp = time_uptime;
+ l = 0; /* exit inner loop */
+ break;
+
+ case O_SKIPTO:
+ f->pcnt++; /* update stats */
+ f->bcnt += pktlen;
+ f->timestamp = time_uptime;
+ /* If possible use cached f_pos (in f->next_rule),
+ * whose version is written in f->next_rule
+ * (horrible hacks to avoid changing the ABI).
+ */
+ if (cmd->arg1 != IP_FW_TABLEARG &&
+ (uintptr_t)f->x_next == chain->id) {
+ f_pos = (uintptr_t)f->next_rule;
+ } else {
+ int i = (cmd->arg1 == IP_FW_TABLEARG) ?
+ tablearg : cmd->arg1;
+ /* make sure we do not jump backward */
+ if (i <= f->rulenum)
+ i = f->rulenum + 1;
+ f_pos = ipfw_find_rule(chain, i, 0);
+ /* update the cache */
+ if (cmd->arg1 != IP_FW_TABLEARG) {
+ f->next_rule =
+ (void *)(uintptr_t)f_pos;
+ f->x_next =
+ (void *)(uintptr_t)chain->id;
+ }
+ }
+ /*
+ * Skip disabled rules, and re-enter
+ * the inner loop with the correct
+ * f_pos, f, l and cmd.
+ * Also clear cmdlen and skip_or
+ */
+ for (; f_pos < chain->n_rules - 1 &&
+ (V_set_disable &
+ (1 << chain->map[f_pos]->set));
+ f_pos++)
+ ;
+ /* Re-enter the inner loop at the skipto rule. */
+ f = chain->map[f_pos];
+ l = f->cmd_len;
+ cmd = f->cmd;
+ match = 1;
+ cmdlen = 0;
+ skip_or = 0;
+ continue;
+ break; /* not reached */
+
+ case O_CALLRETURN: {
+ /*
+ * Implementation of `subroutine' call/return,
+ * in the stack carried in an mbuf tag. This
+ * is different from `skipto' in that any call
+ * address is possible (`skipto' must prevent
+ * backward jumps to avoid endless loops).
+ * We have `return' action when F_NOT flag is
+ * present. The `m_tag_id' field is used as
+ * stack pointer.
+ */
+ struct m_tag *mtag;
+ uint16_t jmpto, *stack;
+
+#define IS_CALL ((cmd->len & F_NOT) == 0)
+#define IS_RETURN ((cmd->len & F_NOT) != 0)
+ /*
+ * Hand-rolled version of m_tag_locate() with
+ * wildcard `type'.
+ * If not already tagged, allocate new tag.
+ */
+ mtag = m_tag_first(m);
+ while (mtag != NULL) {
+ if (mtag->m_tag_cookie ==
+ MTAG_IPFW_CALL)
+ break;
+ mtag = m_tag_next(m, mtag);
+ }
+ if (mtag == NULL && IS_CALL) {
+ mtag = m_tag_alloc(MTAG_IPFW_CALL, 0,
+ IPFW_CALLSTACK_SIZE *
+ sizeof(uint16_t), M_NOWAIT);
+ if (mtag != NULL)
+ m_tag_prepend(m, mtag);
+ }
+
+ /*
+ * On error both `call' and `return' just
+ * continue with next rule.
+ */
+ if (IS_RETURN && (mtag == NULL ||
+ mtag->m_tag_id == 0)) {
+ l = 0; /* exit inner loop */
+ break;
+ }
+ if (IS_CALL && (mtag == NULL ||
+ mtag->m_tag_id >= IPFW_CALLSTACK_SIZE)) {
+ printf("ipfw: call stack error, "
+ "go to next rule\n");
+ l = 0; /* exit inner loop */
+ break;
+ }
+
+ f->pcnt++; /* update stats */
+ f->bcnt += pktlen;
+ f->timestamp = time_uptime;
+ stack = (uint16_t *)(mtag + 1);
+
+ /*
+ * The `call' action may use cached f_pos
+ * (in f->next_rule), whose version is written
+ * in f->next_rule.
+ * The `return' action, however, doesn't have
+ * fixed jump address in cmd->arg1 and can't use
+ * cache.
+ */
+ if (IS_CALL) {
+ stack[mtag->m_tag_id] = f->rulenum;
+ mtag->m_tag_id++;
+ if (cmd->arg1 != IP_FW_TABLEARG &&
+ (uintptr_t)f->x_next == chain->id) {
+ f_pos = (uintptr_t)f->next_rule;
+ } else {
+ jmpto = (cmd->arg1 ==
+ IP_FW_TABLEARG) ? tablearg:
+ cmd->arg1;
+ f_pos = ipfw_find_rule(chain,
+ jmpto, 0);
+ /* update the cache */
+ if (cmd->arg1 !=
+ IP_FW_TABLEARG) {
+ f->next_rule =
+ (void *)(uintptr_t)
+ f_pos;
+ f->x_next =
+ (void *)(uintptr_t)
+ chain->id;
+ }
+ }
+ } else { /* `return' action */
+ mtag->m_tag_id--;
+ jmpto = stack[mtag->m_tag_id] + 1;
+ f_pos = ipfw_find_rule(chain, jmpto, 0);
+ }
+
+ /*
+ * Skip disabled rules, and re-enter
+ * the inner loop with the correct
+ * f_pos, f, l and cmd.
+ * Also clear cmdlen and skip_or
+ */
+ for (; f_pos < chain->n_rules - 1 &&
+ (V_set_disable &
+ (1 << chain->map[f_pos]->set)); f_pos++)
+ ;
+ /* Re-enter the inner loop at the dest rule. */
+ f = chain->map[f_pos];
+ l = f->cmd_len;
+ cmd = f->cmd;
+ cmdlen = 0;
+ skip_or = 0;
+ continue;
+ break; /* NOTREACHED */
+ }
+#undef IS_CALL
+#undef IS_RETURN
+
+ case O_REJECT:
+ /*
+ * Drop the packet and send a reject notice
+ * if the packet is not ICMP (or is an ICMP
+ * query), and it is not multicast/broadcast.
+ */
+ if (hlen > 0 && is_ipv4 && offset == 0 &&
+ (proto != IPPROTO_ICMP ||
+ is_icmp_query(ICMP(ulp))) &&
+ !(m->m_flags & (M_BCAST|M_MCAST)) &&
+ !IN_MULTICAST(ntohl(dst_ip.s_addr))) {
+ send_reject(args, cmd->arg1, iplen, ip);
+ m = args->m;
+ }
+ /* FALLTHROUGH */
+#ifdef INET6
+ case O_UNREACH6:
+ if (hlen > 0 && is_ipv6 &&
+ ((offset & IP6F_OFF_MASK) == 0) &&
+ (proto != IPPROTO_ICMPV6 ||
+ (is_icmp6_query(icmp6_type) == 1)) &&
+ !(m->m_flags & (M_BCAST|M_MCAST)) &&
+ !IN6_IS_ADDR_MULTICAST(&args->f_id.dst_ip6)) {
+ send_reject6(
+ args, cmd->arg1, hlen,
+ (struct ip6_hdr *)ip);
+ m = args->m;
+ }
+ /* FALLTHROUGH */
+#endif
+ case O_DENY:
+ retval = IP_FW_DENY;
+ l = 0; /* exit inner loop */
+ done = 1; /* exit outer loop */
+ break;
+
+ case O_FORWARD_IP:
+ if (args->eh) /* not valid on layer2 pkts */
+ break;
+ if (q == NULL || q->rule != f ||
+ dyn_dir == MATCH_FORWARD) {
+ struct sockaddr_in *sa;
+ sa = &(((ipfw_insn_sa *)cmd)->sa);
+ if (sa->sin_addr.s_addr == INADDR_ANY) {
+ bcopy(sa, &args->hopstore,
+ sizeof(*sa));
+ args->hopstore.sin_addr.s_addr =
+ htonl(tablearg);
+ args->next_hop = &args->hopstore;
+ } else {
+ args->next_hop = sa;
+ }
+ }
+ retval = IP_FW_PASS;
+ l = 0; /* exit inner loop */
+ done = 1; /* exit outer loop */
+ break;
+
+#ifdef INET6
+ case O_FORWARD_IP6:
+ if (args->eh) /* not valid on layer2 pkts */
+ break;
+ if (q == NULL || q->rule != f ||
+ dyn_dir == MATCH_FORWARD) {
+ struct sockaddr_in6 *sin6;
+
+ sin6 = &(((ipfw_insn_sa6 *)cmd)->sa);
+ args->next_hop6 = sin6;
+ }
+ retval = IP_FW_PASS;
+ l = 0; /* exit inner loop */
+ done = 1; /* exit outer loop */
+ break;
+#endif
+
+ case O_NETGRAPH:
+ case O_NGTEE:
+ set_match(args, f_pos, chain);
+ args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
+ tablearg : cmd->arg1;
+ if (V_fw_one_pass)
+ args->rule.info |= IPFW_ONEPASS;
+ retval = (cmd->opcode == O_NETGRAPH) ?
+ IP_FW_NETGRAPH : IP_FW_NGTEE;
+ l = 0; /* exit inner loop */
+ done = 1; /* exit outer loop */
+ break;
+
+ case O_SETFIB: {
+ uint32_t fib;
+
+ f->pcnt++; /* update stats */
+ f->bcnt += pktlen;
+ f->timestamp = time_uptime;
+ fib = (cmd->arg1 == IP_FW_TABLEARG) ? tablearg:
+ cmd->arg1;
+ if (fib >= rt_numfibs)
+ fib = 0;
+ M_SETFIB(m, fib);
+ args->f_id.fib = fib;
+ l = 0; /* exit inner loop */
+ break;
+ }
+
+ case O_NAT:
+ if (!IPFW_NAT_LOADED) {
+ retval = IP_FW_DENY;
+ } else {
+ struct cfg_nat *t;
+ int nat_id;
+
+ set_match(args, f_pos, chain);
+ /* Check if this is 'global' nat rule */
+ if (cmd->arg1 == 0) {
+ retval = ipfw_nat_ptr(args, NULL, m);
+ l = 0;
+ done = 1;
+ break;
+ }
+ t = ((ipfw_insn_nat *)cmd)->nat;
+ if (t == NULL) {
+ nat_id = (cmd->arg1 == IP_FW_TABLEARG) ?
+ tablearg : cmd->arg1;
+ t = (*lookup_nat_ptr)(&chain->nat, nat_id);
+
+ if (t == NULL) {
+ retval = IP_FW_DENY;
+ l = 0; /* exit inner loop */
+ done = 1; /* exit outer loop */
+ break;
+ }
+ if (cmd->arg1 != IP_FW_TABLEARG)
+ ((ipfw_insn_nat *)cmd)->nat = t;
+ }
+ retval = ipfw_nat_ptr(args, t, m);
+ }
+ l = 0; /* exit inner loop */
+ done = 1; /* exit outer loop */
+ break;
+
+ case O_REASS: {
+ int ip_off;
+
+ f->pcnt++;
+ f->bcnt += pktlen;
+ l = 0; /* in any case exit inner loop */
+ ip_off = ntohs(ip->ip_off);
+
+ /* if not fragmented, go to next rule */
+ if ((ip_off & (IP_MF | IP_OFFMASK)) == 0)
+ break;
+ /*
+ * ip_reass() expects len & off in host
+ * byte order.
+ */
+ SET_HOST_IPLEN(ip);
+
+ args->m = m = ip_reass(m);
+
+ /*
+ * do IP header checksum fixup.
+ */
+ if (m == NULL) { /* fragment got swallowed */
+ retval = IP_FW_DENY;
+ } else { /* good, packet complete */
+ int hlen;
+
+ ip = mtod(m, struct ip *);
+ hlen = ip->ip_hl << 2;
+ SET_NET_IPLEN(ip);
+ ip->ip_sum = 0;
+ if (hlen == sizeof(struct ip))
+ ip->ip_sum = in_cksum_hdr(ip);
+ else
+ ip->ip_sum = in_cksum(m, hlen);
+ retval = IP_FW_REASS;
+ set_match(args, f_pos, chain);
+ }
+ done = 1; /* exit outer loop */
+ break;
+ }
+
+ default:
+ panic("-- unknown opcode %d\n", cmd->opcode);
+ } /* end of switch() on opcodes */
+ /*
+ * if we get here with l=0, then match is irrelevant.
+ */
+
+ if (cmd->len & F_NOT)
+ match = !match;
+
+ if (match) {
+ if (cmd->len & F_OR)
+ skip_or = 1;
+ } else {
+ if (!(cmd->len & F_OR)) /* not an OR block, */
+ break; /* try next rule */
+ }
+
+ } /* end of inner loop, scan opcodes */
+#undef PULLUP_LEN
+
+ if (done)
+ break;
+
+/* next_rule:; */ /* try next rule */
+
+ } /* end of outer for, scan rules */
+
+ if (done) {
+ struct ip_fw *rule = chain->map[f_pos];
+ /* Update statistics */
+ rule->pcnt++;
+ rule->bcnt += pktlen;
+ rule->timestamp = time_uptime;
+ } else {
+ retval = IP_FW_DENY;
+ printf("ipfw: ouch!, skip past end of rules, denying packet\n");
+ }
+ IPFW_RUNLOCK(chain);
+#ifdef __FreeBSD__
+ if (ucred_cache != NULL)
+ crfree(ucred_cache);
+#endif
+ return (retval);
+
+pullup_failed:
+ if (V_fw_verbose)
+ printf("ipfw: pullup failed\n");
+ return (IP_FW_DENY);
+}
+
+/*
+ * Set maximum number of tables that can be used in given VNET ipfw instance.
+ */
+#ifdef SYSCTL_NODE
+static int
+sysctl_ipfw_table_num(SYSCTL_HANDLER_ARGS)
+{
+ int error;
+ unsigned int ntables;
+
+ ntables = V_fw_tables_max;
+
+ error = sysctl_handle_int(oidp, &ntables, 0, req);
+ /* Read operation or some error */
+ if ((error != 0) || (req->newptr == NULL))
+ return (error);
+
+ return (ipfw_resize_tables(&V_layer3_chain, ntables));
+}
+#endif
+/*
+ * Module and VNET glue
+ */
+
+/*
+ * Stuff that must be initialised only on boot or module load
+ */
+static int
+ipfw_init(void)
+{
+ int error = 0;
+
+ ipfw_dyn_attach();
+ /*
+ * Only print out this stuff the first time around,
+ * when called from the sysinit code.
+ */
+ printf("ipfw2 "
+#ifdef INET6
+ "(+ipv6) "
+#endif
+ "initialized, divert %s, nat %s, "
+ "rule-based forwarding "
+#ifdef IPFIREWALL_FORWARD
+ "enabled, "
+#else
+ "disabled, "
+#endif
+ "default to %s, logging ",
+#ifdef IPDIVERT
+ "enabled",
+#else
+ "loadable",
+#endif
+#ifdef IPFIREWALL_NAT
+ "enabled",
+#else
+ "loadable",
+#endif
+ default_to_accept ? "accept" : "deny");
+
+ /*
+ * Note: V_xxx variables can be accessed here but the vnet specific
+ * initializer may not have been called yet for the VIMAGE case.
+ * Tuneables will have been processed. We will print out values for
+ * the default vnet.
+ * XXX This should all be rationalized AFTER 8.0
+ */
+ if (V_fw_verbose == 0)
+ printf("disabled\n");
+ else if (V_verbose_limit == 0)
+ printf("unlimited\n");
+ else
+ printf("limited to %d packets/entry by default\n",
+ V_verbose_limit);
+
+ /* Check user-supplied table count for validness */
+ if (default_fw_tables > IPFW_TABLES_MAX)
+ default_fw_tables = IPFW_TABLES_MAX;
+
+ ipfw_log_bpf(1); /* init */
+ return (error);
+}
+
+/*
+ * Called for the removal of the last instance only on module unload.
+ */
+static void
+ipfw_destroy(void)
+{
+
+ ipfw_log_bpf(0); /* uninit */
+ ipfw_dyn_detach();
+ printf("IP firewall unloaded\n");
+}
+
+/*
+ * Stuff that must be initialized for every instance
+ * (including the first of course).
+ */
+static int
+vnet_ipfw_init(const void *unused)
+{
+ int error;
+ struct ip_fw *rule = NULL;
+ struct ip_fw_chain *chain;
+
+ chain = &V_layer3_chain;
+
+ /* First set up some values that are compile time options */
+ V_autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
+ V_fw_deny_unknown_exthdrs = 1;
+#ifdef IPFIREWALL_VERBOSE
+ V_fw_verbose = 1;
+#endif
+#ifdef IPFIREWALL_VERBOSE_LIMIT
+ V_verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
+#endif
+#ifdef IPFIREWALL_NAT
+ LIST_INIT(&chain->nat);
+#endif
+
+ /* insert the default rule and create the initial map */
+ chain->n_rules = 1;
+ chain->static_len = sizeof(struct ip_fw);
+ chain->map = malloc(sizeof(struct ip_fw *), M_IPFW, M_WAITOK | M_ZERO);
+ if (chain->map)
+ rule = malloc(chain->static_len, M_IPFW, M_WAITOK | M_ZERO);
+
+ /* Set initial number of tables */
+ V_fw_tables_max = default_fw_tables;
+ error = ipfw_init_tables(chain);
+ if (error) {
+ printf("ipfw2: setting up tables failed\n");
+ free(chain->map, M_IPFW);
+ free(rule, M_IPFW);
+ return (ENOSPC);
+ }
+
+ /* fill and insert the default rule */
+ rule->act_ofs = 0;
+ rule->rulenum = IPFW_DEFAULT_RULE;
+ rule->cmd_len = 1;
+ rule->set = RESVD_SET;
+ rule->cmd[0].len = 1;
+ rule->cmd[0].opcode = default_to_accept ? O_ACCEPT : O_DENY;
+ chain->rules = chain->default_rule = chain->map[0] = rule;
+ chain->id = rule->id = 1;
+
+ IPFW_LOCK_INIT(chain);
+ ipfw_dyn_init();
+
+ /* First set up some values that are compile time options */
+ V_ipfw_vnet_ready = 1; /* Open for business */
+
+ /*
+ * Hook the sockopt handler, and the layer2 (V_ip_fw_chk_ptr)
+ * and pfil hooks for ipv4 and ipv6. Even if the latter two fail
+ * we still keep the module alive because the sockopt and
+ * layer2 paths are still useful.
+ * ipfw[6]_hook return 0 on success, ENOENT on failure,
+ * so we can ignore the exact return value and just set a flag.
+ *
+ * Note that V_fw[6]_enable are manipulated by a SYSCTL_PROC so
+ * changes in the underlying (per-vnet) variables trigger
+ * immediate hook()/unhook() calls.
+ * In layer2 we have the same behaviour, except that V_ether_ipfw
+ * is checked on each packet because there are no pfil hooks.
+ */
+ V_ip_fw_ctl_ptr = ipfw_ctl;
+ V_ip_fw_chk_ptr = ipfw_chk;
+ error = ipfw_attach_hooks(1);
+ return (error);
+}
+
+/*
+ * Called for the removal of each instance.
+ */
+static int
+vnet_ipfw_uninit(const void *unused)
+{
+ struct ip_fw *reap, *rule;
+ struct ip_fw_chain *chain = &V_layer3_chain;
+ int i;
+
+ V_ipfw_vnet_ready = 0; /* tell new callers to go away */
+ /*
+ * disconnect from ipv4, ipv6, layer2 and sockopt.
+ * Then grab, release and grab again the WLOCK so we make
+ * sure the update is propagated and nobody will be in.
+ */
+ (void)ipfw_attach_hooks(0 /* detach */);
+ V_ip_fw_chk_ptr = NULL;
+ V_ip_fw_ctl_ptr = NULL;
+ IPFW_UH_WLOCK(chain);
+ IPFW_UH_WUNLOCK(chain);
+ IPFW_UH_WLOCK(chain);
+
+ IPFW_WLOCK(chain);
+ ipfw_dyn_uninit(0); /* run the callout_drain */
+ IPFW_WUNLOCK(chain);
+
+ ipfw_destroy_tables(chain);
+ reap = NULL;
+ IPFW_WLOCK(chain);
+ for (i = 0; i < chain->n_rules; i++) {
+ rule = chain->map[i];
+ rule->x_next = reap;
+ reap = rule;
+ }
+ if (chain->map)
+ free(chain->map, M_IPFW);
+ IPFW_WUNLOCK(chain);
+ IPFW_UH_WUNLOCK(chain);
+ if (reap != NULL)
+ ipfw_reap_rules(reap);
+ IPFW_LOCK_DESTROY(chain);
+ ipfw_dyn_uninit(1); /* free the remaining parts */
+ return 0;
+}
+
+/*
+ * Module event handler.
+ * In general we have the choice of handling most of these events by the
+ * event handler or by the (VNET_)SYS(UN)INIT handlers. I have chosen to
+ * use the SYSINIT handlers as they are more capable of expressing the
+ * flow of control during module and vnet operations, so this is just
+ * a skeleton. Note there is no SYSINIT equivalent of the module
+ * SHUTDOWN handler, but we don't have anything to do in that case anyhow.
+ */
+static int
+ipfw_modevent(module_t mod, int type, void *unused)
+{
+ int err = 0;
+
+ switch (type) {
+ case MOD_LOAD:
+ /* Called once at module load or
+ * system boot if compiled in. */
+ break;
+ case MOD_QUIESCE:
+ /* Called before unload. May veto unloading. */
+ break;
+ case MOD_UNLOAD:
+ /* Called during unload. */
+ break;
+ case MOD_SHUTDOWN:
+ /* Called during system shutdown. */
+ break;
+ default:
+ err = EOPNOTSUPP;
+ break;
+ }
+ return err;
+}
+
+static moduledata_t ipfwmod = {
+ "ipfw",
+ ipfw_modevent,
+ 0
+};
+
+/* Define startup order. */
+#define IPFW_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN
+#define IPFW_MODEVENT_ORDER (SI_ORDER_ANY - 255) /* On boot slot in here. */
+#define IPFW_MODULE_ORDER (IPFW_MODEVENT_ORDER + 1) /* A little later. */
+#define IPFW_VNET_ORDER (IPFW_MODEVENT_ORDER + 2) /* Later still. */
+
+DECLARE_MODULE(ipfw, ipfwmod, IPFW_SI_SUB_FIREWALL, IPFW_MODEVENT_ORDER);
+MODULE_VERSION(ipfw, 2);
+/* should declare some dependencies here */
+
+/*
+ * Starting up. Done in order after ipfwmod() has been called.
+ * VNET_SYSINIT is also called for each existing vnet and each new vnet.
+ */
+SYSINIT(ipfw_init, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER,
+ ipfw_init, NULL);
+VNET_SYSINIT(vnet_ipfw_init, IPFW_SI_SUB_FIREWALL, IPFW_VNET_ORDER,
+ vnet_ipfw_init, NULL);
+
+/*
+ * Closing up shop. These are done in REVERSE ORDER, but still
+ * after ipfwmod() has been called. Not called on reboot.
+ * VNET_SYSUNINIT is also called for each exiting vnet as it exits.
+ * or when the module is unloaded.
+ */
+SYSUNINIT(ipfw_destroy, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER,
+ ipfw_destroy, NULL);
+VNET_SYSUNINIT(vnet_ipfw_uninit, IPFW_SI_SUB_FIREWALL, IPFW_VNET_ORDER,
+ vnet_ipfw_uninit, NULL);
+/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_dynamic.c b/sys/netinet/ipfw/ip_fw_dynamic.c
new file mode 100644
index 0000000..7cff94f
--- /dev/null
+++ b/sys/netinet/ipfw/ip_fw_dynamic.c
@@ -0,0 +1,1242 @@
+/*-
+ * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define DEB(x)
+#define DDB(x) x
+
+/*
+ * Dynamic rule support for ipfw
+ */
+
+#include "opt_ipfw.h"
+#include "opt_inet.h"
+#ifndef INET
+#error IPFIREWALL requires INET.
+#endif /* INET */
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/syslog.h>
+#include <net/ethernet.h> /* for ETHERTYPE_IP */
+#include <net/if.h>
+#include <net/vnet.h>
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h> /* ip_defttl */
+#include <netinet/ip_fw.h>
+#include <netinet/ipfw/ip_fw_private.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp.h>
+
+#include <netinet/ip6.h> /* IN6_ARE_ADDR_EQUAL */
+#ifdef INET6
+#include <netinet6/in6_var.h>
+#include <netinet6/ip6_var.h>
+#endif
+
+#include <machine/in_cksum.h> /* XXX for in_cksum */
+
+#ifdef MAC
+#include <security/mac/mac_framework.h>
+#endif
+
+/*
+ * Description of dynamic rules.
+ *
+ * Dynamic rules are stored in lists accessed through a hash table
+ * (ipfw_dyn_v) whose size is curr_dyn_buckets. This value can
+ * be modified through the sysctl variable dyn_buckets which is
+ * updated when the table becomes empty.
+ *
+ * XXX currently there is only one list, ipfw_dyn.
+ *
+ * When a packet is received, its address fields are first masked
+ * with the mask defined for the rule, then hashed, then matched
+ * against the entries in the corresponding list.
+ * Dynamic rules can be used for different purposes:
+ * + stateful rules;
+ * + enforcing limits on the number of sessions;
+ * + in-kernel NAT (not implemented yet)
+ *
+ * The lifetime of dynamic rules is regulated by dyn_*_lifetime,
+ * measured in seconds and depending on the flags.
+ *
+ * The total number of dynamic rules is stored in dyn_count.
+ * The max number of dynamic rules is dyn_max. When we reach
+ * the maximum number of rules we do not create anymore. This is
+ * done to avoid consuming too much memory, but also too much
+ * time when searching on each packet (ideally, we should try instead
+ * to put a limit on the length of the list on each bucket...).
+ *
+ * Each dynamic rule holds a pointer to the parent ipfw rule so
+ * we know what action to perform. Dynamic rules are removed when
+ * the parent rule is deleted. XXX we should make them survive.
+ *
+ * There are some limitations with dynamic rules -- we do not
+ * obey the 'randomized match', and we do not do multiple
+ * passes through the firewall. XXX check the latter!!!
+ */
+
+/*
+ * Static variables followed by global ones
+ */
+static VNET_DEFINE(ipfw_dyn_rule **, ipfw_dyn_v);
+static VNET_DEFINE(u_int32_t, dyn_buckets);
+static VNET_DEFINE(u_int32_t, curr_dyn_buckets);
+static VNET_DEFINE(struct callout, ipfw_timeout);
+#define V_ipfw_dyn_v VNET(ipfw_dyn_v)
+#define V_dyn_buckets VNET(dyn_buckets)
+#define V_curr_dyn_buckets VNET(curr_dyn_buckets)
+#define V_ipfw_timeout VNET(ipfw_timeout)
+
+static uma_zone_t ipfw_dyn_rule_zone;
+#ifndef __FreeBSD__
+DEFINE_SPINLOCK(ipfw_dyn_mtx);
+#else
+static struct mtx ipfw_dyn_mtx; /* mutex guarding dynamic rules */
+#endif
+
+#define IPFW_DYN_LOCK_INIT() \
+ mtx_init(&ipfw_dyn_mtx, "IPFW dynamic rules", NULL, MTX_DEF)
+#define IPFW_DYN_LOCK_DESTROY() mtx_destroy(&ipfw_dyn_mtx)
+#define IPFW_DYN_LOCK() mtx_lock(&ipfw_dyn_mtx)
+#define IPFW_DYN_UNLOCK() mtx_unlock(&ipfw_dyn_mtx)
+#define IPFW_DYN_LOCK_ASSERT() mtx_assert(&ipfw_dyn_mtx, MA_OWNED)
+
+void
+ipfw_dyn_unlock(void)
+{
+ IPFW_DYN_UNLOCK();
+}
+
+/*
+ * Timeouts for various events in handing dynamic rules.
+ */
+static VNET_DEFINE(u_int32_t, dyn_ack_lifetime);
+static VNET_DEFINE(u_int32_t, dyn_syn_lifetime);
+static VNET_DEFINE(u_int32_t, dyn_fin_lifetime);
+static VNET_DEFINE(u_int32_t, dyn_rst_lifetime);
+static VNET_DEFINE(u_int32_t, dyn_udp_lifetime);
+static VNET_DEFINE(u_int32_t, dyn_short_lifetime);
+
+#define V_dyn_ack_lifetime VNET(dyn_ack_lifetime)
+#define V_dyn_syn_lifetime VNET(dyn_syn_lifetime)
+#define V_dyn_fin_lifetime VNET(dyn_fin_lifetime)
+#define V_dyn_rst_lifetime VNET(dyn_rst_lifetime)
+#define V_dyn_udp_lifetime VNET(dyn_udp_lifetime)
+#define V_dyn_short_lifetime VNET(dyn_short_lifetime)
+
+/*
+ * Keepalives are sent if dyn_keepalive is set. They are sent every
+ * dyn_keepalive_period seconds, in the last dyn_keepalive_interval
+ * seconds of lifetime of a rule.
+ * dyn_rst_lifetime and dyn_fin_lifetime should be strictly lower
+ * than dyn_keepalive_period.
+ */
+
+static VNET_DEFINE(u_int32_t, dyn_keepalive_interval);
+static VNET_DEFINE(u_int32_t, dyn_keepalive_period);
+static VNET_DEFINE(u_int32_t, dyn_keepalive);
+
+#define V_dyn_keepalive_interval VNET(dyn_keepalive_interval)
+#define V_dyn_keepalive_period VNET(dyn_keepalive_period)
+#define V_dyn_keepalive VNET(dyn_keepalive)
+
+static VNET_DEFINE(u_int32_t, dyn_count); /* # of dynamic rules */
+static VNET_DEFINE(u_int32_t, dyn_max); /* max # of dynamic rules */
+
+#define V_dyn_count VNET(dyn_count)
+#define V_dyn_max VNET(dyn_max)
+
+#ifdef SYSCTL_NODE
+
+SYSBEGIN(f2)
+
+SYSCTL_DECL(_net_inet_ip_fw);
+SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_buckets,
+ CTLFLAG_RW, &VNET_NAME(dyn_buckets), 0,
+ "Number of dyn. buckets");
+SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets,
+ CTLFLAG_RD, &VNET_NAME(curr_dyn_buckets), 0,
+ "Current Number of dyn. buckets");
+SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_count,
+ CTLFLAG_RD, &VNET_NAME(dyn_count), 0,
+ "Number of dyn. rules");
+SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_max,
+ CTLFLAG_RW, &VNET_NAME(dyn_max), 0,
+ "Max number of dyn. rules");
+SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime,
+ CTLFLAG_RW, &VNET_NAME(dyn_ack_lifetime), 0,
+ "Lifetime of dyn. rules for acks");
+SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime,
+ CTLFLAG_RW, &VNET_NAME(dyn_syn_lifetime), 0,
+ "Lifetime of dyn. rules for syn");
+SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_fin_lifetime,
+ CTLFLAG_RW, &VNET_NAME(dyn_fin_lifetime), 0,
+ "Lifetime of dyn. rules for fin");
+SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime,
+ CTLFLAG_RW, &VNET_NAME(dyn_rst_lifetime), 0,
+ "Lifetime of dyn. rules for rst");
+SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_udp_lifetime,
+ CTLFLAG_RW, &VNET_NAME(dyn_udp_lifetime), 0,
+ "Lifetime of dyn. rules for UDP");
+SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime,
+ CTLFLAG_RW, &VNET_NAME(dyn_short_lifetime), 0,
+ "Lifetime of dyn. rules for other situations");
+SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_keepalive,
+ CTLFLAG_RW, &VNET_NAME(dyn_keepalive), 0,
+ "Enable keepalives for dyn. rules");
+
+SYSEND
+
+#endif /* SYSCTL_NODE */
+
+
+static __inline int
+hash_packet6(struct ipfw_flow_id *id)
+{
+ u_int32_t i;
+ i = (id->dst_ip6.__u6_addr.__u6_addr32[2]) ^
+ (id->dst_ip6.__u6_addr.__u6_addr32[3]) ^
+ (id->src_ip6.__u6_addr.__u6_addr32[2]) ^
+ (id->src_ip6.__u6_addr.__u6_addr32[3]) ^
+ (id->dst_port) ^ (id->src_port);
+ return i;
+}
+
+/*
+ * IMPORTANT: the hash function for dynamic rules must be commutative
+ * in source and destination (ip,port), because rules are bidirectional
+ * and we want to find both in the same bucket.
+ */
+static __inline int
+hash_packet(struct ipfw_flow_id *id)
+{
+ u_int32_t i;
+
+#ifdef INET6
+ if (IS_IP6_FLOW_ID(id))
+ i = hash_packet6(id);
+ else
+#endif /* INET6 */
+ i = (id->dst_ip) ^ (id->src_ip) ^ (id->dst_port) ^ (id->src_port);
+ i &= (V_curr_dyn_buckets - 1);
+ return i;
+}
+
+static __inline void
+unlink_dyn_rule_print(struct ipfw_flow_id *id)
+{
+ struct in_addr da;
+#ifdef INET6
+ char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
+#else
+ char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
+#endif
+
+#ifdef INET6
+ if (IS_IP6_FLOW_ID(id)) {
+ ip6_sprintf(src, &id->src_ip6);
+ ip6_sprintf(dst, &id->dst_ip6);
+ } else
+#endif
+ {
+ da.s_addr = htonl(id->src_ip);
+ inet_ntoa_r(da, src);
+ da.s_addr = htonl(id->dst_ip);
+ inet_ntoa_r(da, dst);
+ }
+ printf("ipfw: unlink entry %s %d -> %s %d, %d left\n",
+ src, id->src_port, dst, id->dst_port, V_dyn_count - 1);
+}
+
+/**
+ * unlink a dynamic rule from a chain. prev is a pointer to
+ * the previous one, q is a pointer to the rule to delete,
+ * head is a pointer to the head of the queue.
+ * Modifies q and potentially also head.
+ */
+#define UNLINK_DYN_RULE(prev, head, q) { \
+ ipfw_dyn_rule *old_q = q; \
+ \
+ /* remove a refcount to the parent */ \
+ if (q->dyn_type == O_LIMIT) \
+ q->parent->count--; \
+ DEB(unlink_dyn_rule_print(&q->id);) \
+ if (prev != NULL) \
+ prev->next = q = q->next; \
+ else \
+ head = q = q->next; \
+ V_dyn_count--; \
+ uma_zfree(ipfw_dyn_rule_zone, old_q); }
+
+#define TIME_LEQ(a,b) ((int)((a)-(b)) <= 0)
+
+/**
+ * Remove dynamic rules pointing to "rule", or all of them if rule == NULL.
+ *
+ * If keep_me == NULL, rules are deleted even if not expired,
+ * otherwise only expired rules are removed.
+ *
+ * The value of the second parameter is also used to point to identify
+ * a rule we absolutely do not want to remove (e.g. because we are
+ * holding a reference to it -- this is the case with O_LIMIT_PARENT
+ * rules). The pointer is only used for comparison, so any non-null
+ * value will do.
+ */
+static void
+remove_dyn_rule(struct ip_fw *rule, ipfw_dyn_rule *keep_me)
+{
+ static u_int32_t last_remove = 0;
+
+#define FORCE (keep_me == NULL)
+
+ ipfw_dyn_rule *prev, *q;
+ int i, pass = 0, max_pass = 0;
+
+ IPFW_DYN_LOCK_ASSERT();
+
+ if (V_ipfw_dyn_v == NULL || V_dyn_count == 0)
+ return;
+ /* do not expire more than once per second, it is useless */
+ if (!FORCE && last_remove == time_uptime)
+ return;
+ last_remove = time_uptime;
+
+ /*
+ * because O_LIMIT refer to parent rules, during the first pass only
+ * remove child and mark any pending LIMIT_PARENT, and remove
+ * them in a second pass.
+ */
+next_pass:
+ for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
+ for (prev=NULL, q = V_ipfw_dyn_v[i] ; q ; ) {
+ /*
+ * Logic can become complex here, so we split tests.
+ */
+ if (q == keep_me)
+ goto next;
+ if (rule != NULL && rule != q->rule)
+ goto next; /* not the one we are looking for */
+ if (q->dyn_type == O_LIMIT_PARENT) {
+ /*
+ * handle parent in the second pass,
+ * record we need one.
+ */
+ max_pass = 1;
+ if (pass == 0)
+ goto next;
+ if (FORCE && q->count != 0 ) {
+ /* XXX should not happen! */
+ printf("ipfw: OUCH! cannot remove rule,"
+ " count %d\n", q->count);
+ }
+ } else {
+ if (!FORCE &&
+ !TIME_LEQ( q->expire, time_uptime ))
+ goto next;
+ }
+ if (q->dyn_type != O_LIMIT_PARENT || !q->count) {
+ UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
+ continue;
+ }
+next:
+ prev=q;
+ q=q->next;
+ }
+ }
+ if (pass++ < max_pass)
+ goto next_pass;
+}
+
+void
+ipfw_remove_dyn_children(struct ip_fw *rule)
+{
+ IPFW_DYN_LOCK();
+ remove_dyn_rule(rule, NULL /* force removal */);
+ IPFW_DYN_UNLOCK();
+}
+
+/*
+ * Lookup a dynamic rule, locked version.
+ */
+static ipfw_dyn_rule *
+lookup_dyn_rule_locked(struct ipfw_flow_id *pkt, int *match_direction,
+ struct tcphdr *tcp)
+{
+ /*
+ * Stateful ipfw extensions.
+ * Lookup into dynamic session queue.
+ */
+#define MATCH_REVERSE 0
+#define MATCH_FORWARD 1
+#define MATCH_NONE 2
+#define MATCH_UNKNOWN 3
+ int i, dir = MATCH_NONE;
+ ipfw_dyn_rule *prev, *q = NULL;
+
+ IPFW_DYN_LOCK_ASSERT();
+
+ if (V_ipfw_dyn_v == NULL)
+ goto done; /* not found */
+ i = hash_packet(pkt);
+ for (prev = NULL, q = V_ipfw_dyn_v[i]; q != NULL;) {
+ if (q->dyn_type == O_LIMIT_PARENT && q->count)
+ goto next;
+ if (TIME_LEQ(q->expire, time_uptime)) { /* expire entry */
+ UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
+ continue;
+ }
+ if (pkt->proto != q->id.proto || q->dyn_type == O_LIMIT_PARENT)
+ goto next;
+
+ if (IS_IP6_FLOW_ID(pkt)) {
+ if (IN6_ARE_ADDR_EQUAL(&pkt->src_ip6, &q->id.src_ip6) &&
+ IN6_ARE_ADDR_EQUAL(&pkt->dst_ip6, &q->id.dst_ip6) &&
+ pkt->src_port == q->id.src_port &&
+ pkt->dst_port == q->id.dst_port) {
+ dir = MATCH_FORWARD;
+ break;
+ }
+ if (IN6_ARE_ADDR_EQUAL(&pkt->src_ip6, &q->id.dst_ip6) &&
+ IN6_ARE_ADDR_EQUAL(&pkt->dst_ip6, &q->id.src_ip6) &&
+ pkt->src_port == q->id.dst_port &&
+ pkt->dst_port == q->id.src_port) {
+ dir = MATCH_REVERSE;
+ break;
+ }
+ } else {
+ if (pkt->src_ip == q->id.src_ip &&
+ pkt->dst_ip == q->id.dst_ip &&
+ pkt->src_port == q->id.src_port &&
+ pkt->dst_port == q->id.dst_port) {
+ dir = MATCH_FORWARD;
+ break;
+ }
+ if (pkt->src_ip == q->id.dst_ip &&
+ pkt->dst_ip == q->id.src_ip &&
+ pkt->src_port == q->id.dst_port &&
+ pkt->dst_port == q->id.src_port) {
+ dir = MATCH_REVERSE;
+ break;
+ }
+ }
+next:
+ prev = q;
+ q = q->next;
+ }
+ if (q == NULL)
+ goto done; /* q = NULL, not found */
+
+ if (prev != NULL) { /* found and not in front */
+ prev->next = q->next;
+ q->next = V_ipfw_dyn_v[i];
+ V_ipfw_dyn_v[i] = q;
+ }
+ if (pkt->proto == IPPROTO_TCP) { /* update state according to flags */
+ uint32_t ack;
+ u_char flags = pkt->_flags & (TH_FIN | TH_SYN | TH_RST);
+
+#define BOTH_SYN (TH_SYN | (TH_SYN << 8))
+#define BOTH_FIN (TH_FIN | (TH_FIN << 8))
+#define TCP_FLAGS (TH_FLAGS | (TH_FLAGS << 8))
+#define ACK_FWD 0x10000 /* fwd ack seen */
+#define ACK_REV 0x20000 /* rev ack seen */
+
+ q->state |= (dir == MATCH_FORWARD) ? flags : (flags << 8);
+ switch (q->state & TCP_FLAGS) {
+ case TH_SYN: /* opening */
+ q->expire = time_uptime + V_dyn_syn_lifetime;
+ break;
+
+ case BOTH_SYN: /* move to established */
+ case BOTH_SYN | TH_FIN: /* one side tries to close */
+ case BOTH_SYN | (TH_FIN << 8):
+#define _SEQ_GE(a,b) ((int)(a) - (int)(b) >= 0)
+ if (tcp == NULL)
+ break;
+
+ ack = ntohl(tcp->th_ack);
+ if (dir == MATCH_FORWARD) {
+ if (q->ack_fwd == 0 ||
+ _SEQ_GE(ack, q->ack_fwd)) {
+ q->ack_fwd = ack;
+ q->state |= ACK_FWD;
+ }
+ } else {
+ if (q->ack_rev == 0 ||
+ _SEQ_GE(ack, q->ack_rev)) {
+ q->ack_rev = ack;
+ q->state |= ACK_REV;
+ }
+ }
+ if ((q->state & (ACK_FWD | ACK_REV)) ==
+ (ACK_FWD | ACK_REV)) {
+ q->expire = time_uptime + V_dyn_ack_lifetime;
+ q->state &= ~(ACK_FWD | ACK_REV);
+ }
+ break;
+
+ case BOTH_SYN | BOTH_FIN: /* both sides closed */
+ if (V_dyn_fin_lifetime >= V_dyn_keepalive_period)
+ V_dyn_fin_lifetime = V_dyn_keepalive_period - 1;
+ q->expire = time_uptime + V_dyn_fin_lifetime;
+ break;
+
+ default:
+#if 0
+ /*
+ * reset or some invalid combination, but can also
+ * occur if we use keep-state the wrong way.
+ */
+ if ( (q->state & ((TH_RST << 8)|TH_RST)) == 0)
+ printf("invalid state: 0x%x\n", q->state);
+#endif
+ if (V_dyn_rst_lifetime >= V_dyn_keepalive_period)
+ V_dyn_rst_lifetime = V_dyn_keepalive_period - 1;
+ q->expire = time_uptime + V_dyn_rst_lifetime;
+ break;
+ }
+ } else if (pkt->proto == IPPROTO_UDP) {
+ q->expire = time_uptime + V_dyn_udp_lifetime;
+ } else {
+ /* other protocols */
+ q->expire = time_uptime + V_dyn_short_lifetime;
+ }
+done:
+ if (match_direction != NULL)
+ *match_direction = dir;
+ return (q);
+}
+
+ipfw_dyn_rule *
+ipfw_lookup_dyn_rule(struct ipfw_flow_id *pkt, int *match_direction,
+ struct tcphdr *tcp)
+{
+ ipfw_dyn_rule *q;
+
+ IPFW_DYN_LOCK();
+ q = lookup_dyn_rule_locked(pkt, match_direction, tcp);
+ if (q == NULL)
+ IPFW_DYN_UNLOCK();
+ /* NB: return table locked when q is not NULL */
+ return q;
+}
+
+static void
+realloc_dynamic_table(void)
+{
+ IPFW_DYN_LOCK_ASSERT();
+
+ /*
+ * Try reallocation, make sure we have a power of 2 and do
+ * not allow more than 64k entries. In case of overflow,
+ * default to 1024.
+ */
+
+ if (V_dyn_buckets > 65536)
+ V_dyn_buckets = 1024;
+ if ((V_dyn_buckets & (V_dyn_buckets-1)) != 0) { /* not a power of 2 */
+ V_dyn_buckets = V_curr_dyn_buckets; /* reset */
+ return;
+ }
+ V_curr_dyn_buckets = V_dyn_buckets;
+ if (V_ipfw_dyn_v != NULL)
+ free(V_ipfw_dyn_v, M_IPFW);
+ for (;;) {
+ V_ipfw_dyn_v = malloc(V_curr_dyn_buckets * sizeof(ipfw_dyn_rule *),
+ M_IPFW, M_NOWAIT | M_ZERO);
+ if (V_ipfw_dyn_v != NULL || V_curr_dyn_buckets <= 2)
+ break;
+ V_curr_dyn_buckets /= 2;
+ }
+}
+
+/**
+ * Install state of type 'type' for a dynamic session.
+ * The hash table contains two type of rules:
+ * - regular rules (O_KEEP_STATE)
+ * - rules for sessions with limited number of sess per user
+ * (O_LIMIT). When they are created, the parent is
+ * increased by 1, and decreased on delete. In this case,
+ * the third parameter is the parent rule and not the chain.
+ * - "parent" rules for the above (O_LIMIT_PARENT).
+ */
+static ipfw_dyn_rule *
+add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
+{
+ ipfw_dyn_rule *r;
+ int i;
+
+ IPFW_DYN_LOCK_ASSERT();
+
+ if (V_ipfw_dyn_v == NULL ||
+ (V_dyn_count == 0 && V_dyn_buckets != V_curr_dyn_buckets)) {
+ realloc_dynamic_table();
+ if (V_ipfw_dyn_v == NULL)
+ return NULL; /* failed ! */
+ }
+ i = hash_packet(id);
+
+ r = uma_zalloc(ipfw_dyn_rule_zone, M_NOWAIT | M_ZERO);
+ if (r == NULL) {
+ printf ("ipfw: sorry cannot allocate state\n");
+ return NULL;
+ }
+
+ /* increase refcount on parent, and set pointer */
+ if (dyn_type == O_LIMIT) {
+ ipfw_dyn_rule *parent = (ipfw_dyn_rule *)rule;
+ if ( parent->dyn_type != O_LIMIT_PARENT)
+ panic("invalid parent");
+ parent->count++;
+ r->parent = parent;
+ rule = parent->rule;
+ }
+
+ r->id = *id;
+ r->expire = time_uptime + V_dyn_syn_lifetime;
+ r->rule = rule;
+ r->dyn_type = dyn_type;
+ r->pcnt = r->bcnt = 0;
+ r->count = 0;
+
+ r->bucket = i;
+ r->next = V_ipfw_dyn_v[i];
+ V_ipfw_dyn_v[i] = r;
+ V_dyn_count++;
+ DEB({
+ struct in_addr da;
+#ifdef INET6
+ char src[INET6_ADDRSTRLEN];
+ char dst[INET6_ADDRSTRLEN];
+#else
+ char src[INET_ADDRSTRLEN];
+ char dst[INET_ADDRSTRLEN];
+#endif
+
+#ifdef INET6
+ if (IS_IP6_FLOW_ID(&(r->id))) {
+ ip6_sprintf(src, &r->id.src_ip6);
+ ip6_sprintf(dst, &r->id.dst_ip6);
+ } else
+#endif
+ {
+ da.s_addr = htonl(r->id.src_ip);
+ inet_ntoa_r(da, src);
+ da.s_addr = htonl(r->id.dst_ip);
+ inet_ntoa_r(da, dst);
+ }
+ printf("ipfw: add dyn entry ty %d %s %d -> %s %d, total %d\n",
+ dyn_type, src, r->id.src_port, dst, r->id.dst_port,
+ V_dyn_count);
+ })
+ return r;
+}
+
+/**
+ * lookup dynamic parent rule using pkt and rule as search keys.
+ * If the lookup fails, then install one.
+ */
+static ipfw_dyn_rule *
+lookup_dyn_parent(struct ipfw_flow_id *pkt, struct ip_fw *rule)
+{
+ ipfw_dyn_rule *q;
+ int i;
+
+ IPFW_DYN_LOCK_ASSERT();
+
+ if (V_ipfw_dyn_v) {
+ int is_v6 = IS_IP6_FLOW_ID(pkt);
+ i = hash_packet( pkt );
+ for (q = V_ipfw_dyn_v[i] ; q != NULL ; q=q->next)
+ if (q->dyn_type == O_LIMIT_PARENT &&
+ rule== q->rule &&
+ pkt->proto == q->id.proto &&
+ pkt->src_port == q->id.src_port &&
+ pkt->dst_port == q->id.dst_port &&
+ (
+ (is_v6 &&
+ IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
+ &(q->id.src_ip6)) &&
+ IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
+ &(q->id.dst_ip6))) ||
+ (!is_v6 &&
+ pkt->src_ip == q->id.src_ip &&
+ pkt->dst_ip == q->id.dst_ip)
+ )
+ ) {
+ q->expire = time_uptime + V_dyn_short_lifetime;
+ DEB(printf("ipfw: lookup_dyn_parent found 0x%p\n",q);)
+ return q;
+ }
+ }
+ return add_dyn_rule(pkt, O_LIMIT_PARENT, rule);
+}
+
+/**
+ * Install dynamic state for rule type cmd->o.opcode
+ *
+ * Returns 1 (failure) if state is not installed because of errors or because
+ * session limitations are enforced.
+ */
+int
+ipfw_install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
+ struct ip_fw_args *args, uint32_t tablearg)
+{
+ static int last_log;
+ ipfw_dyn_rule *q;
+ struct in_addr da;
+#ifdef INET6
+ char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
+#else
+ char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
+#endif
+
+ src[0] = '\0';
+ dst[0] = '\0';
+
+ IPFW_DYN_LOCK();
+
+ DEB(
+#ifdef INET6
+ if (IS_IP6_FLOW_ID(&(args->f_id))) {
+ ip6_sprintf(src, &args->f_id.src_ip6);
+ ip6_sprintf(dst, &args->f_id.dst_ip6);
+ } else
+#endif
+ {
+ da.s_addr = htonl(args->f_id.src_ip);
+ inet_ntoa_r(da, src);
+ da.s_addr = htonl(args->f_id.dst_ip);
+ inet_ntoa_r(da, dst);
+ }
+ printf("ipfw: %s: type %d %s %u -> %s %u\n",
+ __func__, cmd->o.opcode, src, args->f_id.src_port,
+ dst, args->f_id.dst_port);
+ src[0] = '\0';
+ dst[0] = '\0';
+ )
+
+ q = lookup_dyn_rule_locked(&args->f_id, NULL, NULL);
+
+ if (q != NULL) { /* should never occur */
+ DEB(
+ if (last_log != time_uptime) {
+ last_log = time_uptime;
+ printf("ipfw: %s: entry already present, done\n",
+ __func__);
+ })
+ IPFW_DYN_UNLOCK();
+ return (0);
+ }
+
+ if (V_dyn_count >= V_dyn_max)
+ /* Run out of slots, try to remove any expired rule. */
+ remove_dyn_rule(NULL, (ipfw_dyn_rule *)1);
+
+ if (V_dyn_count >= V_dyn_max) {
+ if (last_log != time_uptime) {
+ last_log = time_uptime;
+ printf("ipfw: %s: Too many dynamic rules\n", __func__);
+ }
+ IPFW_DYN_UNLOCK();
+ return (1); /* cannot install, notify caller */
+ }
+
+ switch (cmd->o.opcode) {
+ case O_KEEP_STATE: /* bidir rule */
+ add_dyn_rule(&args->f_id, O_KEEP_STATE, rule);
+ break;
+
+ case O_LIMIT: { /* limit number of sessions */
+ struct ipfw_flow_id id;
+ ipfw_dyn_rule *parent;
+ uint32_t conn_limit;
+ uint16_t limit_mask = cmd->limit_mask;
+
+ conn_limit = (cmd->conn_limit == IP_FW_TABLEARG) ?
+ tablearg : cmd->conn_limit;
+
+ DEB(
+ if (cmd->conn_limit == IP_FW_TABLEARG)
+ printf("ipfw: %s: O_LIMIT rule, conn_limit: %u "
+ "(tablearg)\n", __func__, conn_limit);
+ else
+ printf("ipfw: %s: O_LIMIT rule, conn_limit: %u\n",
+ __func__, conn_limit);
+ )
+
+ id.dst_ip = id.src_ip = id.dst_port = id.src_port = 0;
+ id.proto = args->f_id.proto;
+ id.addr_type = args->f_id.addr_type;
+ id.fib = M_GETFIB(args->m);
+
+ if (IS_IP6_FLOW_ID (&(args->f_id))) {
+ if (limit_mask & DYN_SRC_ADDR)
+ id.src_ip6 = args->f_id.src_ip6;
+ if (limit_mask & DYN_DST_ADDR)
+ id.dst_ip6 = args->f_id.dst_ip6;
+ } else {
+ if (limit_mask & DYN_SRC_ADDR)
+ id.src_ip = args->f_id.src_ip;
+ if (limit_mask & DYN_DST_ADDR)
+ id.dst_ip = args->f_id.dst_ip;
+ }
+ if (limit_mask & DYN_SRC_PORT)
+ id.src_port = args->f_id.src_port;
+ if (limit_mask & DYN_DST_PORT)
+ id.dst_port = args->f_id.dst_port;
+ if ((parent = lookup_dyn_parent(&id, rule)) == NULL) {
+ printf("ipfw: %s: add parent failed\n", __func__);
+ IPFW_DYN_UNLOCK();
+ return (1);
+ }
+
+ if (parent->count >= conn_limit) {
+ /* See if we can remove some expired rule. */
+ remove_dyn_rule(rule, parent);
+ if (parent->count >= conn_limit) {
+ if (V_fw_verbose && last_log != time_uptime) {
+ last_log = time_uptime;
+#ifdef INET6
+ /*
+ * XXX IPv6 flows are not
+ * supported yet.
+ */
+ if (IS_IP6_FLOW_ID(&(args->f_id))) {
+ char ip6buf[INET6_ADDRSTRLEN];
+ snprintf(src, sizeof(src),
+ "[%s]", ip6_sprintf(ip6buf,
+ &args->f_id.src_ip6));
+ snprintf(dst, sizeof(dst),
+ "[%s]", ip6_sprintf(ip6buf,
+ &args->f_id.dst_ip6));
+ } else
+#endif
+ {
+ da.s_addr =
+ htonl(args->f_id.src_ip);
+ inet_ntoa_r(da, src);
+ da.s_addr =
+ htonl(args->f_id.dst_ip);
+ inet_ntoa_r(da, dst);
+ }
+ log(LOG_SECURITY | LOG_DEBUG,
+ "ipfw: %d %s %s:%u -> %s:%u, %s\n",
+ parent->rule->rulenum,
+ "drop session",
+ src, (args->f_id.src_port),
+ dst, (args->f_id.dst_port),
+ "too many entries");
+ }
+ IPFW_DYN_UNLOCK();
+ return (1);
+ }
+ }
+ add_dyn_rule(&args->f_id, O_LIMIT, (struct ip_fw *)parent);
+ break;
+ }
+ default:
+ printf("ipfw: %s: unknown dynamic rule type %u\n",
+ __func__, cmd->o.opcode);
+ IPFW_DYN_UNLOCK();
+ return (1);
+ }
+
+ /* XXX just set lifetime */
+ lookup_dyn_rule_locked(&args->f_id, NULL, NULL);
+
+ IPFW_DYN_UNLOCK();
+ return (0);
+}
+
+/*
+ * Generate a TCP packet, containing either a RST or a keepalive.
+ * When flags & TH_RST, we are sending a RST packet, because of a
+ * "reset" action matched the packet.
+ * Otherwise we are sending a keepalive, and flags & TH_
+ * The 'replyto' mbuf is the mbuf being replied to, if any, and is required
+ * so that MAC can label the reply appropriately.
+ */
+struct mbuf *
+ipfw_send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
+ u_int32_t ack, int flags)
+{
+ struct mbuf *m = NULL; /* stupid compiler */
+ int len, dir;
+ struct ip *h = NULL; /* stupid compiler */
+#ifdef INET6
+ struct ip6_hdr *h6 = NULL;
+#endif
+ struct tcphdr *th = NULL;
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL)
+ return (NULL);
+
+ M_SETFIB(m, id->fib);
+#ifdef MAC
+ if (replyto != NULL)
+ mac_netinet_firewall_reply(replyto, m);
+ else
+ mac_netinet_firewall_send(m);
+#else
+ (void)replyto; /* don't warn about unused arg */
+#endif
+
+ switch (id->addr_type) {
+ case 4:
+ len = sizeof(struct ip) + sizeof(struct tcphdr);
+ break;
+#ifdef INET6
+ case 6:
+ len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
+ break;
+#endif
+ default:
+ /* XXX: log me?!? */
+ FREE_PKT(m);
+ return (NULL);
+ }
+ dir = ((flags & (TH_SYN | TH_RST)) == TH_SYN);
+
+ m->m_data += max_linkhdr;
+ m->m_flags |= M_SKIP_FIREWALL;
+ m->m_pkthdr.len = m->m_len = len;
+ m->m_pkthdr.rcvif = NULL;
+ bzero(m->m_data, len);
+
+ switch (id->addr_type) {
+ case 4:
+ h = mtod(m, struct ip *);
+
+ /* prepare for checksum */
+ h->ip_p = IPPROTO_TCP;
+ h->ip_len = htons(sizeof(struct tcphdr));
+ if (dir) {
+ h->ip_src.s_addr = htonl(id->src_ip);
+ h->ip_dst.s_addr = htonl(id->dst_ip);
+ } else {
+ h->ip_src.s_addr = htonl(id->dst_ip);
+ h->ip_dst.s_addr = htonl(id->src_ip);
+ }
+
+ th = (struct tcphdr *)(h + 1);
+ break;
+#ifdef INET6
+ case 6:
+ h6 = mtod(m, struct ip6_hdr *);
+
+ /* prepare for checksum */
+ h6->ip6_nxt = IPPROTO_TCP;
+ h6->ip6_plen = htons(sizeof(struct tcphdr));
+ if (dir) {
+ h6->ip6_src = id->src_ip6;
+ h6->ip6_dst = id->dst_ip6;
+ } else {
+ h6->ip6_src = id->dst_ip6;
+ h6->ip6_dst = id->src_ip6;
+ }
+
+ th = (struct tcphdr *)(h6 + 1);
+ break;
+#endif
+ }
+
+ if (dir) {
+ th->th_sport = htons(id->src_port);
+ th->th_dport = htons(id->dst_port);
+ } else {
+ th->th_sport = htons(id->dst_port);
+ th->th_dport = htons(id->src_port);
+ }
+ th->th_off = sizeof(struct tcphdr) >> 2;
+
+ if (flags & TH_RST) {
+ if (flags & TH_ACK) {
+ th->th_seq = htonl(ack);
+ th->th_flags = TH_RST;
+ } else {
+ if (flags & TH_SYN)
+ seq++;
+ th->th_ack = htonl(seq);
+ th->th_flags = TH_RST | TH_ACK;
+ }
+ } else {
+ /*
+ * Keepalive - use caller provided sequence numbers
+ */
+ th->th_seq = htonl(seq);
+ th->th_ack = htonl(ack);
+ th->th_flags = TH_ACK;
+ }
+
+ switch (id->addr_type) {
+ case 4:
+ th->th_sum = in_cksum(m, len);
+
+ /* finish the ip header */
+ h->ip_v = 4;
+ h->ip_hl = sizeof(*h) >> 2;
+ h->ip_tos = IPTOS_LOWDELAY;
+ h->ip_off = 0;
+ /* ip_len must be in host format for ip_output */
+ h->ip_len = len;
+ h->ip_ttl = V_ip_defttl;
+ h->ip_sum = 0;
+ break;
+#ifdef INET6
+ case 6:
+ th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(*h6),
+ sizeof(struct tcphdr));
+
+ /* finish the ip6 header */
+ h6->ip6_vfc |= IPV6_VERSION;
+ h6->ip6_hlim = IPV6_DEFHLIM;
+ break;
+#endif
+ }
+
+ return (m);
+}
+
+/*
+ * This procedure is only used to handle keepalives. It is invoked
+ * every dyn_keepalive_period
+ */
+static void
+ipfw_tick(void * vnetx)
+{
+ struct mbuf *m0, *m, *mnext, **mtailp;
+#ifdef INET6
+ struct mbuf *m6, **m6_tailp;
+#endif
+ int i;
+ ipfw_dyn_rule *q;
+#ifdef VIMAGE
+ struct vnet *vp = vnetx;
+#endif
+
+ CURVNET_SET(vp);
+ if (V_dyn_keepalive == 0 || V_ipfw_dyn_v == NULL || V_dyn_count == 0)
+ goto done;
+
+ /*
+ * We make a chain of packets to go out here -- not deferring
+ * until after we drop the IPFW dynamic rule lock would result
+ * in a lock order reversal with the normal packet input -> ipfw
+ * call stack.
+ */
+ m0 = NULL;
+ mtailp = &m0;
+#ifdef INET6
+ m6 = NULL;
+ m6_tailp = &m6;
+#endif
+ IPFW_DYN_LOCK();
+ for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
+ for (q = V_ipfw_dyn_v[i] ; q ; q = q->next ) {
+ if (q->dyn_type == O_LIMIT_PARENT)
+ continue;
+ if (q->id.proto != IPPROTO_TCP)
+ continue;
+ if ( (q->state & BOTH_SYN) != BOTH_SYN)
+ continue;
+ if (TIME_LEQ(time_uptime + V_dyn_keepalive_interval,
+ q->expire))
+ continue; /* too early */
+ if (TIME_LEQ(q->expire, time_uptime))
+ continue; /* too late, rule expired */
+
+ m = (q->state & ACK_REV) ? NULL :
+ ipfw_send_pkt(NULL, &(q->id), q->ack_rev - 1,
+ q->ack_fwd, TH_SYN);
+ mnext = (q->state & ACK_FWD) ? NULL :
+ ipfw_send_pkt(NULL, &(q->id), q->ack_fwd - 1,
+ q->ack_rev, 0);
+
+ switch (q->id.addr_type) {
+ case 4:
+ if (m != NULL) {
+ *mtailp = m;
+ mtailp = &(*mtailp)->m_nextpkt;
+ }
+ if (mnext != NULL) {
+ *mtailp = mnext;
+ mtailp = &(*mtailp)->m_nextpkt;
+ }
+ break;
+#ifdef INET6
+ case 6:
+ if (m != NULL) {
+ *m6_tailp = m;
+ m6_tailp = &(*m6_tailp)->m_nextpkt;
+ }
+ if (mnext != NULL) {
+ *m6_tailp = mnext;
+ m6_tailp = &(*m6_tailp)->m_nextpkt;
+ }
+ break;
+#endif
+ }
+ }
+ }
+ IPFW_DYN_UNLOCK();
+ for (m = m0; m != NULL; m = mnext) {
+ mnext = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ ip_output(m, NULL, NULL, 0, NULL, NULL);
+ }
+#ifdef INET6
+ for (m = m6; m != NULL; m = mnext) {
+ mnext = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
+ }
+#endif
+done:
+ callout_reset_on(&V_ipfw_timeout, V_dyn_keepalive_period * hz,
+ ipfw_tick, vnetx, 0);
+ CURVNET_RESTORE();
+}
+
+void
+ipfw_dyn_attach(void)
+{
+ ipfw_dyn_rule_zone = uma_zcreate("IPFW dynamic rule",
+ sizeof(ipfw_dyn_rule), NULL, NULL, NULL, NULL,
+ UMA_ALIGN_PTR, 0);
+
+ IPFW_DYN_LOCK_INIT();
+}
+
+void
+ipfw_dyn_detach(void)
+{
+ uma_zdestroy(ipfw_dyn_rule_zone);
+ IPFW_DYN_LOCK_DESTROY();
+}
+
+void
+ipfw_dyn_init(void)
+{
+ V_ipfw_dyn_v = NULL;
+ V_dyn_buckets = 256; /* must be power of 2 */
+ V_curr_dyn_buckets = 256; /* must be power of 2 */
+
+ V_dyn_ack_lifetime = 300;
+ V_dyn_syn_lifetime = 20;
+ V_dyn_fin_lifetime = 1;
+ V_dyn_rst_lifetime = 1;
+ V_dyn_udp_lifetime = 10;
+ V_dyn_short_lifetime = 5;
+
+ V_dyn_keepalive_interval = 20;
+ V_dyn_keepalive_period = 5;
+ V_dyn_keepalive = 1; /* do send keepalives */
+
+ V_dyn_max = 4096; /* max # of dynamic rules */
+ callout_init(&V_ipfw_timeout, CALLOUT_MPSAFE);
+ callout_reset_on(&V_ipfw_timeout, hz, ipfw_tick, curvnet, 0);
+}
+
+void
+ipfw_dyn_uninit(int pass)
+{
+ if (pass == 0)
+ callout_drain(&V_ipfw_timeout);
+ else {
+ if (V_ipfw_dyn_v != NULL)
+ free(V_ipfw_dyn_v, M_IPFW);
+ }
+}
+
+int
+ipfw_dyn_len(void)
+{
+ return (V_ipfw_dyn_v == NULL) ? 0 :
+ (V_dyn_count * sizeof(ipfw_dyn_rule));
+}
+
+void
+ipfw_get_dynamic(char **pbp, const char *ep)
+{
+ ipfw_dyn_rule *p, *last = NULL;
+ char *bp;
+ int i;
+
+ if (V_ipfw_dyn_v == NULL)
+ return;
+ bp = *pbp;
+
+ IPFW_DYN_LOCK();
+ for (i = 0 ; i < V_curr_dyn_buckets; i++)
+ for (p = V_ipfw_dyn_v[i] ; p != NULL; p = p->next) {
+ if (bp + sizeof *p <= ep) {
+ ipfw_dyn_rule *dst =
+ (ipfw_dyn_rule *)bp;
+ bcopy(p, dst, sizeof *p);
+ bcopy(&(p->rule->rulenum), &(dst->rule),
+ sizeof(p->rule->rulenum));
+ /*
+ * store set number into high word of
+ * dst->rule pointer.
+ */
+ bcopy(&(p->rule->set),
+ (char *)&dst->rule +
+ sizeof(p->rule->rulenum),
+ sizeof(p->rule->set));
+ /*
+ * store a non-null value in "next".
+ * The userland code will interpret a
+ * NULL here as a marker
+ * for the last dynamic rule.
+ */
+ bcopy(&dst, &dst->next, sizeof(dst));
+ last = dst;
+ dst->expire =
+ TIME_LEQ(dst->expire, time_uptime) ?
+ 0 : dst->expire - time_uptime ;
+ bp += sizeof(ipfw_dyn_rule);
+ }
+ }
+ IPFW_DYN_UNLOCK();
+ if (last != NULL) /* mark last dynamic rule */
+ bzero(&last->next, sizeof(last));
+ *pbp = bp;
+}
+/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_log.c b/sys/netinet/ipfw/ip_fw_log.c
new file mode 100644
index 0000000..b9ed6b3
--- /dev/null
+++ b/sys/netinet/ipfw/ip_fw_log.c
@@ -0,0 +1,469 @@
+/*-
+ * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Logging support for ipfw
+ */
+
+#include "opt_ipfw.h"
+#include "opt_inet.h"
+#ifndef INET
+#error IPFIREWALL requires INET.
+#endif /* INET */
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/syslog.h>
+#include <net/ethernet.h> /* for ETHERTYPE_IP */
+#include <net/if.h>
+#include <net/vnet.h>
+#include <net/if_types.h> /* for IFT_ETHER */
+#include <net/bpf.h> /* for BPF */
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_fw.h>
+#include <netinet/ipfw/ip_fw_private.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp.h>
+
+#include <netinet/ip6.h>
+#include <netinet/icmp6.h>
+#ifdef INET6
+#include <netinet6/in6_var.h> /* ip6_sprintf() */
+#endif
+
+#ifdef MAC
+#include <security/mac/mac_framework.h>
+#endif
+
+/*
+ * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
+ * Other macros just cast void * into the appropriate type
+ */
+#define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl))
+#define TCP(p) ((struct tcphdr *)(p))
+#define SCTP(p) ((struct sctphdr *)(p))
+#define UDP(p) ((struct udphdr *)(p))
+#define ICMP(p) ((struct icmphdr *)(p))
+#define ICMP6(p) ((struct icmp6_hdr *)(p))
+
+#define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
+#define SNP(buf) buf, sizeof(buf)
+
+#ifdef WITHOUT_BPF
+void
+ipfw_log_bpf(int onoff)
+{
+}
+#else /* !WITHOUT_BPF */
+static struct ifnet *log_if; /* hook to attach to bpf */
+
+/* we use this dummy function for all ifnet callbacks */
+static int
+log_dummy(struct ifnet *ifp, u_long cmd, caddr_t addr)
+{
+ return EINVAL;
+}
+
+static int
+ipfw_log_output(struct ifnet *ifp, struct mbuf *m,
+ struct sockaddr *dst, struct route *ro)
+{
+ if (m != NULL)
+ m_freem(m);
+ return EINVAL;
+}
+
+static void
+ipfw_log_start(struct ifnet* ifp)
+{
+ panic("ipfw_log_start() must not be called");
+}
+
+static const u_char ipfwbroadcastaddr[6] =
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+void
+ipfw_log_bpf(int onoff)
+{
+ struct ifnet *ifp;
+
+ if (onoff) {
+ if (log_if)
+ return;
+ ifp = if_alloc(IFT_ETHER);
+ if (ifp == NULL)
+ return;
+ if_initname(ifp, "ipfw", 0);
+ ifp->if_mtu = 65536;
+ ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_init = (void *)log_dummy;
+ ifp->if_ioctl = log_dummy;
+ ifp->if_start = ipfw_log_start;
+ ifp->if_output = ipfw_log_output;
+ ifp->if_addrlen = 6;
+ ifp->if_hdrlen = 14;
+ if_attach(ifp);
+ ifp->if_broadcastaddr = ipfwbroadcastaddr;
+ ifp->if_baudrate = IF_Mbps(10);
+ bpfattach(ifp, DLT_EN10MB, 14);
+ log_if = ifp;
+ } else {
+ if (log_if) {
+ ether_ifdetach(log_if);
+ if_free(log_if);
+ }
+ log_if = NULL;
+ }
+}
+#endif /* !WITHOUT_BPF */
+
+/*
+ * We enter here when we have a rule with O_LOG.
+ * XXX this function alone takes about 2Kbytes of code!
+ */
+void
+ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
+ struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
+ struct ip *ip)
+{
+ char *action;
+ int limit_reached = 0;
+ char action2[92], proto[128], fragment[32];
+
+ if (V_fw_verbose == 0) {
+#ifndef WITHOUT_BPF
+
+ if (log_if == NULL || log_if->if_bpf == NULL)
+ return;
+
+ if (args->eh) /* layer2, use orig hdr */
+ BPF_MTAP2(log_if, args->eh, ETHER_HDR_LEN, m);
+ else
+ /* Add fake header. Later we will store
+ * more info in the header.
+ */
+ BPF_MTAP2(log_if, "DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, m);
+#endif /* !WITHOUT_BPF */
+ return;
+ }
+ /* the old 'log' function */
+ fragment[0] = '\0';
+ proto[0] = '\0';
+
+ if (f == NULL) { /* bogus pkt */
+ if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit)
+ return;
+ V_norule_counter++;
+ if (V_norule_counter == V_verbose_limit)
+ limit_reached = V_verbose_limit;
+ action = "Refuse";
+ } else { /* O_LOG is the first action, find the real one */
+ ipfw_insn *cmd = ACTION_PTR(f);
+ ipfw_insn_log *l = (ipfw_insn_log *)cmd;
+
+ if (l->max_log != 0 && l->log_left == 0)
+ return;
+ l->log_left--;
+ if (l->log_left == 0)
+ limit_reached = l->max_log;
+ cmd += F_LEN(cmd); /* point to first action */
+ if (cmd->opcode == O_ALTQ) {
+ ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
+
+ snprintf(SNPARGS(action2, 0), "Altq %d",
+ altq->qid);
+ cmd += F_LEN(cmd);
+ }
+ if (cmd->opcode == O_PROB)
+ cmd += F_LEN(cmd);
+
+ if (cmd->opcode == O_TAG)
+ cmd += F_LEN(cmd);
+
+ action = action2;
+ switch (cmd->opcode) {
+ case O_DENY:
+ action = "Deny";
+ break;
+
+ case O_REJECT:
+ if (cmd->arg1==ICMP_REJECT_RST)
+ action = "Reset";
+ else if (cmd->arg1==ICMP_UNREACH_HOST)
+ action = "Reject";
+ else
+ snprintf(SNPARGS(action2, 0), "Unreach %d",
+ cmd->arg1);
+ break;
+
+ case O_UNREACH6:
+ if (cmd->arg1==ICMP6_UNREACH_RST)
+ action = "Reset";
+ else
+ snprintf(SNPARGS(action2, 0), "Unreach %d",
+ cmd->arg1);
+ break;
+
+ case O_ACCEPT:
+ action = "Accept";
+ break;
+ case O_COUNT:
+ action = "Count";
+ break;
+ case O_DIVERT:
+ snprintf(SNPARGS(action2, 0), "Divert %d",
+ cmd->arg1);
+ break;
+ case O_TEE:
+ snprintf(SNPARGS(action2, 0), "Tee %d",
+ cmd->arg1);
+ break;
+ case O_SETFIB:
+ snprintf(SNPARGS(action2, 0), "SetFib %d",
+ cmd->arg1);
+ break;
+ case O_SKIPTO:
+ snprintf(SNPARGS(action2, 0), "SkipTo %d",
+ cmd->arg1);
+ break;
+ case O_PIPE:
+ snprintf(SNPARGS(action2, 0), "Pipe %d",
+ cmd->arg1);
+ break;
+ case O_QUEUE:
+ snprintf(SNPARGS(action2, 0), "Queue %d",
+ cmd->arg1);
+ break;
+ case O_FORWARD_IP: {
+ ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd;
+ int len;
+ struct in_addr dummyaddr;
+ if (sa->sa.sin_addr.s_addr == INADDR_ANY)
+ dummyaddr.s_addr = htonl(tablearg);
+ else
+ dummyaddr.s_addr = sa->sa.sin_addr.s_addr;
+
+ len = snprintf(SNPARGS(action2, 0), "Forward to %s",
+ inet_ntoa(dummyaddr));
+
+ if (sa->sa.sin_port)
+ snprintf(SNPARGS(action2, len), ":%d",
+ sa->sa.sin_port);
+ }
+ break;
+#ifdef INET6
+ case O_FORWARD_IP6: {
+ char buf[INET6_ADDRSTRLEN];
+ ipfw_insn_sa6 *sa = (ipfw_insn_sa6 *)cmd;
+ int len;
+
+ len = snprintf(SNPARGS(action2, 0), "Forward to [%s]",
+ ip6_sprintf(buf, &sa->sa.sin6_addr));
+
+ if (sa->sa.sin6_port)
+ snprintf(SNPARGS(action2, len), ":%u",
+ sa->sa.sin6_port);
+ }
+ break;
+#endif
+ case O_NETGRAPH:
+ snprintf(SNPARGS(action2, 0), "Netgraph %d",
+ cmd->arg1);
+ break;
+ case O_NGTEE:
+ snprintf(SNPARGS(action2, 0), "Ngtee %d",
+ cmd->arg1);
+ break;
+ case O_NAT:
+ action = "Nat";
+ break;
+ case O_REASS:
+ action = "Reass";
+ break;
+ case O_CALLRETURN:
+ if (cmd->len & F_NOT)
+ action = "Return";
+ else
+ snprintf(SNPARGS(action2, 0), "Call %d",
+ cmd->arg1);
+ break;
+ default:
+ action = "UNKNOWN";
+ break;
+ }
+ }
+
+ if (hlen == 0) { /* non-ip */
+ snprintf(SNPARGS(proto, 0), "MAC");
+
+ } else {
+ int len;
+#ifdef INET6
+ char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
+#else
+ char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
+#endif
+ struct icmphdr *icmp;
+ struct tcphdr *tcp;
+ struct udphdr *udp;
+#ifdef INET6
+ struct ip6_hdr *ip6 = NULL;
+ struct icmp6_hdr *icmp6;
+ u_short ip6f_mf;
+#endif
+ src[0] = '\0';
+ dst[0] = '\0';
+#ifdef INET6
+ ip6f_mf = offset & IP6F_MORE_FRAG;
+ offset &= IP6F_OFF_MASK;
+
+ if (IS_IP6_FLOW_ID(&(args->f_id))) {
+ char ip6buf[INET6_ADDRSTRLEN];
+ snprintf(src, sizeof(src), "[%s]",
+ ip6_sprintf(ip6buf, &args->f_id.src_ip6));
+ snprintf(dst, sizeof(dst), "[%s]",
+ ip6_sprintf(ip6buf, &args->f_id.dst_ip6));
+
+ ip6 = (struct ip6_hdr *)ip;
+ tcp = (struct tcphdr *)(((char *)ip) + hlen);
+ udp = (struct udphdr *)(((char *)ip) + hlen);
+ } else
+#endif
+ {
+ tcp = L3HDR(struct tcphdr, ip);
+ udp = L3HDR(struct udphdr, ip);
+
+ inet_ntoa_r(ip->ip_src, src);
+ inet_ntoa_r(ip->ip_dst, dst);
+ }
+
+ switch (args->f_id.proto) {
+ case IPPROTO_TCP:
+ len = snprintf(SNPARGS(proto, 0), "TCP %s", src);
+ if (offset == 0)
+ snprintf(SNPARGS(proto, len), ":%d %s:%d",
+ ntohs(tcp->th_sport),
+ dst,
+ ntohs(tcp->th_dport));
+ else
+ snprintf(SNPARGS(proto, len), " %s", dst);
+ break;
+
+ case IPPROTO_UDP:
+ len = snprintf(SNPARGS(proto, 0), "UDP %s", src);
+ if (offset == 0)
+ snprintf(SNPARGS(proto, len), ":%d %s:%d",
+ ntohs(udp->uh_sport),
+ dst,
+ ntohs(udp->uh_dport));
+ else
+ snprintf(SNPARGS(proto, len), " %s", dst);
+ break;
+
+ case IPPROTO_ICMP:
+ icmp = L3HDR(struct icmphdr, ip);
+ if (offset == 0)
+ len = snprintf(SNPARGS(proto, 0),
+ "ICMP:%u.%u ",
+ icmp->icmp_type, icmp->icmp_code);
+ else
+ len = snprintf(SNPARGS(proto, 0), "ICMP ");
+ len += snprintf(SNPARGS(proto, len), "%s", src);
+ snprintf(SNPARGS(proto, len), " %s", dst);
+ break;
+#ifdef INET6
+ case IPPROTO_ICMPV6:
+ icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen);
+ if (offset == 0)
+ len = snprintf(SNPARGS(proto, 0),
+ "ICMPv6:%u.%u ",
+ icmp6->icmp6_type, icmp6->icmp6_code);
+ else
+ len = snprintf(SNPARGS(proto, 0), "ICMPv6 ");
+ len += snprintf(SNPARGS(proto, len), "%s", src);
+ snprintf(SNPARGS(proto, len), " %s", dst);
+ break;
+#endif
+ default:
+ len = snprintf(SNPARGS(proto, 0), "P:%d %s",
+ args->f_id.proto, src);
+ snprintf(SNPARGS(proto, len), " %s", dst);
+ break;
+ }
+
+#ifdef INET6
+ if (IS_IP6_FLOW_ID(&(args->f_id))) {
+ if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG))
+ snprintf(SNPARGS(fragment, 0),
+ " (frag %08x:%d@%d%s)",
+ args->f_id.extra,
+ ntohs(ip6->ip6_plen) - hlen,
+ ntohs(offset) << 3, ip6f_mf ? "+" : "");
+ } else
+#endif
+ {
+ int ipoff, iplen;
+ ipoff = ntohs(ip->ip_off);
+ iplen = ntohs(ip->ip_len);
+ if (ipoff & (IP_MF | IP_OFFMASK))
+ snprintf(SNPARGS(fragment, 0),
+ " (frag %d:%d@%d%s)",
+ ntohs(ip->ip_id), iplen - (ip->ip_hl << 2),
+ offset << 3,
+ (ipoff & IP_MF) ? "+" : "");
+ }
+ }
+#ifdef __FreeBSD__
+ if (oif || m->m_pkthdr.rcvif)
+ log(LOG_SECURITY | LOG_INFO,
+ "ipfw: %d %s %s %s via %s%s\n",
+ f ? f->rulenum : -1,
+ action, proto, oif ? "out" : "in",
+ oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname,
+ fragment);
+ else
+#endif
+ log(LOG_SECURITY | LOG_INFO,
+ "ipfw: %d %s %s [no if info]%s\n",
+ f ? f->rulenum : -1,
+ action, proto, fragment);
+ if (limit_reached)
+ log(LOG_SECURITY | LOG_NOTICE,
+ "ipfw: limit %d reached on entry %d\n",
+ limit_reached, f ? f->rulenum : -1);
+}
+/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_nat.c b/sys/netinet/ipfw/ip_fw_nat.c
new file mode 100644
index 0000000..dbeb254
--- /dev/null
+++ b/sys/netinet/ipfw/ip_fw_nat.c
@@ -0,0 +1,661 @@
+/*-
+ * Copyright (c) 2008 Paolo Pisati
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/eventhandler.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/rwlock.h>
+
+#define IPFW_INTERNAL /* Access to protected data structures in ip_fw.h. */
+
+#include <netinet/libalias/alias.h>
+#include <netinet/libalias/alias_local.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_fw.h>
+#include <netinet/ipfw/ip_fw_private.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+
+#include <machine/in_cksum.h> /* XXX for in_cksum */
+
+static VNET_DEFINE(eventhandler_tag, ifaddr_event_tag);
+#define V_ifaddr_event_tag VNET(ifaddr_event_tag)
+
+static void
+ifaddr_change(void *arg __unused, struct ifnet *ifp)
+{
+ struct cfg_nat *ptr;
+ struct ifaddr *ifa;
+ struct ip_fw_chain *chain;
+
+ chain = &V_layer3_chain;
+ IPFW_WLOCK(chain);
+ /* Check every nat entry... */
+ LIST_FOREACH(ptr, &chain->nat, _next) {
+ /* ...using nic 'ifp->if_xname' as dynamic alias address. */
+ if (strncmp(ptr->if_name, ifp->if_xname, IF_NAMESIZE) != 0)
+ continue;
+ if_addr_rlock(ifp);
+ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ if (ifa->ifa_addr == NULL)
+ continue;
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+ ptr->ip = ((struct sockaddr_in *)
+ (ifa->ifa_addr))->sin_addr;
+ LibAliasSetAddress(ptr->lib, ptr->ip);
+ }
+ if_addr_runlock(ifp);
+ }
+ IPFW_WUNLOCK(chain);
+}
+
+/*
+ * delete the pointers for nat entry ix, or all of them if ix < 0
+ */
+static void
+flush_nat_ptrs(struct ip_fw_chain *chain, const int ix)
+{
+ int i;
+ ipfw_insn_nat *cmd;
+
+ IPFW_WLOCK_ASSERT(chain);
+ for (i = 0; i < chain->n_rules; i++) {
+ cmd = (ipfw_insn_nat *)ACTION_PTR(chain->map[i]);
+ /* XXX skip log and the like ? */
+ if (cmd->o.opcode == O_NAT && cmd->nat != NULL &&
+ (ix < 0 || cmd->nat->id == ix))
+ cmd->nat = NULL;
+ }
+}
+
+static void
+del_redir_spool_cfg(struct cfg_nat *n, struct redir_chain *head)
+{
+ struct cfg_redir *r, *tmp_r;
+ struct cfg_spool *s, *tmp_s;
+ int i, num;
+
+ LIST_FOREACH_SAFE(r, head, _next, tmp_r) {
+ num = 1; /* Number of alias_link to delete. */
+ switch (r->mode) {
+ case REDIR_PORT:
+ num = r->pport_cnt;
+ /* FALLTHROUGH */
+ case REDIR_ADDR:
+ case REDIR_PROTO:
+ /* Delete all libalias redirect entry. */
+ for (i = 0; i < num; i++)
+ LibAliasRedirectDelete(n->lib, r->alink[i]);
+ /* Del spool cfg if any. */
+ LIST_FOREACH_SAFE(s, &r->spool_chain, _next, tmp_s) {
+ LIST_REMOVE(s, _next);
+ free(s, M_IPFW);
+ }
+ free(r->alink, M_IPFW);
+ LIST_REMOVE(r, _next);
+ free(r, M_IPFW);
+ break;
+ default:
+ printf("unknown redirect mode: %u\n", r->mode);
+ /* XXX - panic?!?!? */
+ break;
+ }
+ }
+}
+
+static void
+add_redir_spool_cfg(char *buf, struct cfg_nat *ptr)
+{
+ struct cfg_redir *r, *ser_r;
+ struct cfg_spool *s, *ser_s;
+ int cnt, off, i;
+
+ for (cnt = 0, off = 0; cnt < ptr->redir_cnt; cnt++) {
+ ser_r = (struct cfg_redir *)&buf[off];
+ r = malloc(SOF_REDIR, M_IPFW, M_WAITOK | M_ZERO);
+ memcpy(r, ser_r, SOF_REDIR);
+ LIST_INIT(&r->spool_chain);
+ off += SOF_REDIR;
+ r->alink = malloc(sizeof(struct alias_link *) * r->pport_cnt,
+ M_IPFW, M_WAITOK | M_ZERO);
+ switch (r->mode) {
+ case REDIR_ADDR:
+ r->alink[0] = LibAliasRedirectAddr(ptr->lib, r->laddr,
+ r->paddr);
+ break;
+ case REDIR_PORT:
+ for (i = 0 ; i < r->pport_cnt; i++) {
+ /* If remotePort is all ports, set it to 0. */
+ u_short remotePortCopy = r->rport + i;
+ if (r->rport_cnt == 1 && r->rport == 0)
+ remotePortCopy = 0;
+ r->alink[i] = LibAliasRedirectPort(ptr->lib,
+ r->laddr, htons(r->lport + i), r->raddr,
+ htons(remotePortCopy), r->paddr,
+ htons(r->pport + i), r->proto);
+ if (r->alink[i] == NULL) {
+ r->alink[0] = NULL;
+ break;
+ }
+ }
+ break;
+ case REDIR_PROTO:
+ r->alink[0] = LibAliasRedirectProto(ptr->lib ,r->laddr,
+ r->raddr, r->paddr, r->proto);
+ break;
+ default:
+ printf("unknown redirect mode: %u\n", r->mode);
+ break;
+ }
+ /* XXX perhaps return an error instead of panic ? */
+ if (r->alink[0] == NULL)
+ panic("LibAliasRedirect* returned NULL");
+ /* LSNAT handling. */
+ for (i = 0; i < r->spool_cnt; i++) {
+ ser_s = (struct cfg_spool *)&buf[off];
+ s = malloc(SOF_REDIR, M_IPFW, M_WAITOK | M_ZERO);
+ memcpy(s, ser_s, SOF_SPOOL);
+ LibAliasAddServer(ptr->lib, r->alink[0],
+ s->addr, htons(s->port));
+ off += SOF_SPOOL;
+ /* Hook spool entry. */
+ LIST_INSERT_HEAD(&r->spool_chain, s, _next);
+ }
+ /* And finally hook this redir entry. */
+ LIST_INSERT_HEAD(&ptr->redir_chain, r, _next);
+ }
+}
+
+static int
+ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m)
+{
+ struct mbuf *mcl;
+ struct ip *ip;
+ /* XXX - libalias duct tape */
+ int ldt, retval, found;
+ struct ip_fw_chain *chain;
+ char *c;
+
+ ldt = 0;
+ retval = 0;
+ mcl = m_megapullup(m, m->m_pkthdr.len);
+ if (mcl == NULL) {
+ args->m = NULL;
+ return (IP_FW_DENY);
+ }
+ ip = mtod(mcl, struct ip *);
+
+ /*
+ * XXX - Libalias checksum offload 'duct tape':
+ *
+ * locally generated packets have only pseudo-header checksum
+ * calculated and libalias will break it[1], so mark them for
+ * later fix. Moreover there are cases when libalias modifies
+ * tcp packet data[2], mark them for later fix too.
+ *
+ * [1] libalias was never meant to run in kernel, so it does
+ * not have any knowledge about checksum offloading, and
+ * expects a packet with a full internet checksum.
+ * Unfortunately, packets generated locally will have just the
+ * pseudo header calculated, and when libalias tries to adjust
+ * the checksum it will actually compute a wrong value.
+ *
+ * [2] when libalias modifies tcp's data content, full TCP
+ * checksum has to be recomputed: the problem is that
+ * libalias does not have any idea about checksum offloading.
+ * To work around this, we do not do checksumming in LibAlias,
+ * but only mark the packets in th_x2 field. If we receive a
+ * marked packet, we calculate correct checksum for it
+ * aware of offloading. Why such a terrible hack instead of
+ * recalculating checksum for each packet?
+ * Because the previous checksum was not checked!
+ * Recalculating checksums for EVERY packet will hide ALL
+ * transmission errors. Yes, marked packets still suffer from
+ * this problem. But, sigh, natd(8) has this problem, too.
+ *
+ * TODO: -make libalias mbuf aware (so
+ * it can handle delayed checksum and tso)
+ */
+
+ if (mcl->m_pkthdr.rcvif == NULL &&
+ mcl->m_pkthdr.csum_flags & CSUM_DELAY_DATA)
+ ldt = 1;
+
+ c = mtod(mcl, char *);
+
+ /* Check if this is 'global' instance */
+ if (t == NULL) {
+ if (args->oif == NULL) {
+ /* Wrong direction, skip processing */
+ args->m = mcl;
+ return (IP_FW_NAT);
+ }
+
+ found = 0;
+ chain = &V_layer3_chain;
+ IPFW_RLOCK(chain);
+ /* Check every nat entry... */
+ LIST_FOREACH(t, &chain->nat, _next) {
+ if ((t->mode & PKT_ALIAS_SKIP_GLOBAL) != 0)
+ continue;
+ retval = LibAliasOutTry(t->lib, c,
+ mcl->m_len + M_TRAILINGSPACE(mcl), 0);
+ if (retval == PKT_ALIAS_OK) {
+ /* Nat instance recognises state */
+ found = 1;
+ break;
+ }
+ }
+ IPFW_RUNLOCK(chain);
+ if (found != 1) {
+ /* No instance found, return ignore */
+ args->m = mcl;
+ return (IP_FW_NAT);
+ }
+ } else {
+ if (args->oif == NULL)
+ retval = LibAliasIn(t->lib, c,
+ mcl->m_len + M_TRAILINGSPACE(mcl));
+ else
+ retval = LibAliasOut(t->lib, c,
+ mcl->m_len + M_TRAILINGSPACE(mcl));
+ }
+
+ /*
+ * We drop packet when:
+ * 1. libalias returns PKT_ALIAS_ERROR;
+ * 2. For incoming packets:
+ * a) for unresolved fragments;
+ * b) libalias returns PKT_ALIAS_IGNORED and
+ * PKT_ALIAS_DENY_INCOMING flag is set.
+ */
+ if (retval == PKT_ALIAS_ERROR ||
+ (args->oif == NULL && (retval == PKT_ALIAS_UNRESOLVED_FRAGMENT ||
+ (retval == PKT_ALIAS_IGNORED &&
+ (t->mode & PKT_ALIAS_DENY_INCOMING) != 0)))) {
+ /* XXX - should i add some logging? */
+ m_free(mcl);
+ args->m = NULL;
+ return (IP_FW_DENY);
+ }
+
+ if (retval == PKT_ALIAS_RESPOND)
+ mcl->m_flags |= M_SKIP_FIREWALL;
+ mcl->m_pkthdr.len = mcl->m_len = ntohs(ip->ip_len);
+
+ /*
+ * XXX - libalias checksum offload
+ * 'duct tape' (see above)
+ */
+
+ if ((ip->ip_off & htons(IP_OFFMASK)) == 0 &&
+ ip->ip_p == IPPROTO_TCP) {
+ struct tcphdr *th;
+
+ th = (struct tcphdr *)(ip + 1);
+ if (th->th_x2)
+ ldt = 1;
+ }
+
+ if (ldt) {
+ struct tcphdr *th;
+ struct udphdr *uh;
+ u_short cksum;
+
+ ip->ip_len = ntohs(ip->ip_len);
+ cksum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
+ htons(ip->ip_p + ip->ip_len - (ip->ip_hl << 2)));
+
+ switch (ip->ip_p) {
+ case IPPROTO_TCP:
+ th = (struct tcphdr *)(ip + 1);
+ /*
+ * Maybe it was set in
+ * libalias...
+ */
+ th->th_x2 = 0;
+ th->th_sum = cksum;
+ mcl->m_pkthdr.csum_data =
+ offsetof(struct tcphdr, th_sum);
+ break;
+ case IPPROTO_UDP:
+ uh = (struct udphdr *)(ip + 1);
+ uh->uh_sum = cksum;
+ mcl->m_pkthdr.csum_data =
+ offsetof(struct udphdr, uh_sum);
+ break;
+ }
+ /* No hw checksum offloading: do it ourselves */
+ if ((mcl->m_pkthdr.csum_flags & CSUM_DELAY_DATA) == 0) {
+ in_delayed_cksum(mcl);
+ mcl->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
+ }
+ ip->ip_len = htons(ip->ip_len);
+ }
+ args->m = mcl;
+ return (IP_FW_NAT);
+}
+
+static struct cfg_nat *
+lookup_nat(struct nat_list *l, int nat_id)
+{
+ struct cfg_nat *res;
+
+ LIST_FOREACH(res, l, _next) {
+ if (res->id == nat_id)
+ break;
+ }
+ return res;
+}
+
+static int
+ipfw_nat_cfg(struct sockopt *sopt)
+{
+ struct cfg_nat *cfg, *ptr;
+ char *buf;
+ struct ip_fw_chain *chain = &V_layer3_chain;
+ size_t len;
+ int gencnt, error = 0;
+
+ len = sopt->sopt_valsize;
+ buf = malloc(len, M_TEMP, M_WAITOK | M_ZERO);
+ if ((error = sooptcopyin(sopt, buf, len, sizeof(struct cfg_nat))) != 0)
+ goto out;
+
+ cfg = (struct cfg_nat *)buf;
+ if (cfg->id < 0) {
+ error = EINVAL;
+ goto out;
+ }
+
+ /*
+ * Find/create nat rule.
+ */
+ IPFW_WLOCK(chain);
+ gencnt = chain->gencnt;
+ ptr = lookup_nat(&chain->nat, cfg->id);
+ if (ptr == NULL) {
+ IPFW_WUNLOCK(chain);
+ /* New rule: allocate and init new instance. */
+ ptr = malloc(sizeof(struct cfg_nat), M_IPFW, M_WAITOK | M_ZERO);
+ ptr->lib = LibAliasInit(NULL);
+ LIST_INIT(&ptr->redir_chain);
+ } else {
+ /* Entry already present: temporarily unhook it. */
+ LIST_REMOVE(ptr, _next);
+ flush_nat_ptrs(chain, cfg->id);
+ IPFW_WUNLOCK(chain);
+ }
+
+ /*
+ * Basic nat configuration.
+ */
+ ptr->id = cfg->id;
+ /*
+ * XXX - what if this rule doesn't nat any ip and just
+ * redirect?
+ * do we set aliasaddress to 0.0.0.0?
+ */
+ ptr->ip = cfg->ip;
+ ptr->redir_cnt = cfg->redir_cnt;
+ ptr->mode = cfg->mode;
+ LibAliasSetMode(ptr->lib, cfg->mode, cfg->mode);
+ LibAliasSetAddress(ptr->lib, ptr->ip);
+ memcpy(ptr->if_name, cfg->if_name, IF_NAMESIZE);
+
+ /*
+ * Redir and LSNAT configuration.
+ */
+ /* Delete old cfgs. */
+ del_redir_spool_cfg(ptr, &ptr->redir_chain);
+ /* Add new entries. */
+ add_redir_spool_cfg(&buf[(sizeof(struct cfg_nat))], ptr);
+
+ IPFW_WLOCK(chain);
+ /* Extra check to avoid race with another ipfw_nat_cfg() */
+ if (gencnt != chain->gencnt &&
+ ((cfg = lookup_nat(&chain->nat, ptr->id)) != NULL))
+ LIST_REMOVE(cfg, _next);
+ LIST_INSERT_HEAD(&chain->nat, ptr, _next);
+ chain->gencnt++;
+ IPFW_WUNLOCK(chain);
+
+out:
+ free(buf, M_TEMP);
+ return (error);
+}
+
+static int
+ipfw_nat_del(struct sockopt *sopt)
+{
+ struct cfg_nat *ptr;
+ struct ip_fw_chain *chain = &V_layer3_chain;
+ int i;
+
+ sooptcopyin(sopt, &i, sizeof i, sizeof i);
+ /* XXX validate i */
+ IPFW_WLOCK(chain);
+ ptr = lookup_nat(&chain->nat, i);
+ if (ptr == NULL) {
+ IPFW_WUNLOCK(chain);
+ return (EINVAL);
+ }
+ LIST_REMOVE(ptr, _next);
+ flush_nat_ptrs(chain, i);
+ IPFW_WUNLOCK(chain);
+ del_redir_spool_cfg(ptr, &ptr->redir_chain);
+ LibAliasUninit(ptr->lib);
+ free(ptr, M_IPFW);
+ return (0);
+}
+
+static int
+ipfw_nat_get_cfg(struct sockopt *sopt)
+{
+ struct ip_fw_chain *chain = &V_layer3_chain;
+ struct cfg_nat *n;
+ struct cfg_redir *r;
+ struct cfg_spool *s;
+ char *data;
+ int gencnt, nat_cnt, len, error;
+
+ nat_cnt = 0;
+ len = sizeof(nat_cnt);
+
+ IPFW_RLOCK(chain);
+retry:
+ gencnt = chain->gencnt;
+ /* Estimate memory amount */
+ LIST_FOREACH(n, &chain->nat, _next) {
+ nat_cnt++;
+ len += sizeof(struct cfg_nat);
+ LIST_FOREACH(r, &n->redir_chain, _next) {
+ len += sizeof(struct cfg_redir);
+ LIST_FOREACH(s, &r->spool_chain, _next)
+ len += sizeof(struct cfg_spool);
+ }
+ }
+ IPFW_RUNLOCK(chain);
+
+ data = malloc(len, M_TEMP, M_WAITOK | M_ZERO);
+ bcopy(&nat_cnt, data, sizeof(nat_cnt));
+
+ nat_cnt = 0;
+ len = sizeof(nat_cnt);
+
+ IPFW_RLOCK(chain);
+ if (gencnt != chain->gencnt) {
+ free(data, M_TEMP);
+ goto retry;
+ }
+ /* Serialize all the data. */
+ LIST_FOREACH(n, &chain->nat, _next) {
+ bcopy(n, &data[len], sizeof(struct cfg_nat));
+ len += sizeof(struct cfg_nat);
+ LIST_FOREACH(r, &n->redir_chain, _next) {
+ bcopy(r, &data[len], sizeof(struct cfg_redir));
+ len += sizeof(struct cfg_redir);
+ LIST_FOREACH(s, &r->spool_chain, _next) {
+ bcopy(s, &data[len], sizeof(struct cfg_spool));
+ len += sizeof(struct cfg_spool);
+ }
+ }
+ }
+ IPFW_RUNLOCK(chain);
+
+ error = sooptcopyout(sopt, data, len);
+ free(data, M_TEMP);
+
+ return (error);
+}
+
+static int
+ipfw_nat_get_log(struct sockopt *sopt)
+{
+ uint8_t *data;
+ struct cfg_nat *ptr;
+ int i, size;
+ struct ip_fw_chain *chain;
+
+ chain = &V_layer3_chain;
+
+ IPFW_RLOCK(chain);
+ /* one pass to count, one to copy the data */
+ i = 0;
+ LIST_FOREACH(ptr, &chain->nat, _next) {
+ if (ptr->lib->logDesc == NULL)
+ continue;
+ i++;
+ }
+ size = i * (LIBALIAS_BUF_SIZE + sizeof(int));
+ data = malloc(size, M_IPFW, M_NOWAIT | M_ZERO);
+ if (data == NULL) {
+ IPFW_RUNLOCK(chain);
+ return (ENOSPC);
+ }
+ i = 0;
+ LIST_FOREACH(ptr, &chain->nat, _next) {
+ if (ptr->lib->logDesc == NULL)
+ continue;
+ bcopy(&ptr->id, &data[i], sizeof(int));
+ i += sizeof(int);
+ bcopy(ptr->lib->logDesc, &data[i], LIBALIAS_BUF_SIZE);
+ i += LIBALIAS_BUF_SIZE;
+ }
+ IPFW_RUNLOCK(chain);
+ sooptcopyout(sopt, data, size);
+ free(data, M_IPFW);
+ return(0);
+}
+
+static void
+ipfw_nat_init(void)
+{
+
+ IPFW_WLOCK(&V_layer3_chain);
+ /* init ipfw hooks */
+ ipfw_nat_ptr = ipfw_nat;
+ lookup_nat_ptr = lookup_nat;
+ ipfw_nat_cfg_ptr = ipfw_nat_cfg;
+ ipfw_nat_del_ptr = ipfw_nat_del;
+ ipfw_nat_get_cfg_ptr = ipfw_nat_get_cfg;
+ ipfw_nat_get_log_ptr = ipfw_nat_get_log;
+ IPFW_WUNLOCK(&V_layer3_chain);
+ V_ifaddr_event_tag = EVENTHANDLER_REGISTER(
+ ifaddr_event, ifaddr_change,
+ NULL, EVENTHANDLER_PRI_ANY);
+}
+
+static void
+ipfw_nat_destroy(void)
+{
+ struct cfg_nat *ptr, *ptr_temp;
+ struct ip_fw_chain *chain;
+
+ chain = &V_layer3_chain;
+ IPFW_WLOCK(chain);
+ LIST_FOREACH_SAFE(ptr, &chain->nat, _next, ptr_temp) {
+ LIST_REMOVE(ptr, _next);
+ del_redir_spool_cfg(ptr, &ptr->redir_chain);
+ LibAliasUninit(ptr->lib);
+ free(ptr, M_IPFW);
+ }
+ EVENTHANDLER_DEREGISTER(ifaddr_event, V_ifaddr_event_tag);
+ flush_nat_ptrs(chain, -1 /* flush all */);
+ /* deregister ipfw_nat */
+ ipfw_nat_ptr = NULL;
+ lookup_nat_ptr = NULL;
+ ipfw_nat_cfg_ptr = NULL;
+ ipfw_nat_del_ptr = NULL;
+ ipfw_nat_get_cfg_ptr = NULL;
+ ipfw_nat_get_log_ptr = NULL;
+ IPFW_WUNLOCK(chain);
+}
+
+static int
+ipfw_nat_modevent(module_t mod, int type, void *unused)
+{
+ int err = 0;
+
+ switch (type) {
+ case MOD_LOAD:
+ ipfw_nat_init();
+ break;
+
+ case MOD_UNLOAD:
+ ipfw_nat_destroy();
+ break;
+
+ default:
+ return EOPNOTSUPP;
+ break;
+ }
+ return err;
+}
+
+static moduledata_t ipfw_nat_mod = {
+ "ipfw_nat",
+ ipfw_nat_modevent,
+ 0
+};
+
+DECLARE_MODULE(ipfw_nat, ipfw_nat_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
+MODULE_DEPEND(ipfw_nat, libalias, 1, 1, 1);
+MODULE_DEPEND(ipfw_nat, ipfw, 2, 2, 2);
+MODULE_VERSION(ipfw_nat, 1);
+/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_pfil.c b/sys/netinet/ipfw/ip_fw_pfil.c
new file mode 100644
index 0000000..695613d
--- /dev/null
+++ b/sys/netinet/ipfw/ip_fw_pfil.c
@@ -0,0 +1,460 @@
+/*-
+ * Copyright (c) 2004 Andre Oppermann, Internet Business Solutions AG
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ipfw.h"
+#include "opt_inet.h"
+#include "opt_inet6.h"
+#ifndef INET
+#error IPFIREWALL requires INET.
+#endif /* INET */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/pfil.h>
+#include <net/vnet.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_fw.h>
+#ifdef INET6
+#include <netinet/ip6.h>
+#include <netinet6/ip6_var.h>
+#endif
+#include <netinet/ipfw/ip_fw_private.h>
+#include <netgraph/ng_ipfw.h>
+
+#include <machine/in_cksum.h>
+
+static VNET_DEFINE(int, fw_enable) = 1;
+#define V_fw_enable VNET(fw_enable)
+
+#ifdef INET6
+static VNET_DEFINE(int, fw6_enable) = 1;
+#define V_fw6_enable VNET(fw6_enable)
+#endif
+
+int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
+
+/* Forward declarations. */
+static int ipfw_divert(struct mbuf **, int, struct ipfw_rule_ref *, int);
+
+#ifdef SYSCTL_NODE
+
+SYSBEGIN(f1)
+
+SYSCTL_DECL(_net_inet_ip_fw);
+SYSCTL_VNET_PROC(_net_inet_ip_fw, OID_AUTO, enable,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_enable), 0,
+ ipfw_chg_hook, "I", "Enable ipfw");
+#ifdef INET6
+SYSCTL_DECL(_net_inet6_ip6_fw);
+SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_AUTO, enable,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw6_enable), 0,
+ ipfw_chg_hook, "I", "Enable ipfw+6");
+#endif /* INET6 */
+
+SYSEND
+
+#endif /* SYSCTL_NODE */
+
+/*
+ * The pfilter hook to pass packets to ipfw_chk and then to
+ * dummynet, divert, netgraph or other modules.
+ * The packet may be consumed.
+ */
+int
+ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
+ struct inpcb *inp)
+{
+ struct ip_fw_args args;
+ struct m_tag *tag;
+ int ipfw;
+ int ret;
+
+ /* all the processing now uses ip_len in net format */
+ if (mtod(*m0, struct ip *)->ip_v == 4)
+ SET_NET_IPLEN(mtod(*m0, struct ip *));
+
+ /* convert dir to IPFW values */
+ dir = (dir == PFIL_IN) ? DIR_IN : DIR_OUT;
+ bzero(&args, sizeof(args));
+
+again:
+ /*
+ * extract and remove the tag if present. If we are left
+ * with onepass, optimize the outgoing path.
+ */
+ tag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL);
+ if (tag != NULL) {
+ args.rule = *((struct ipfw_rule_ref *)(tag+1));
+ m_tag_delete(*m0, tag);
+ if (args.rule.info & IPFW_ONEPASS) {
+ if (mtod(*m0, struct ip *)->ip_v == 4)
+ SET_HOST_IPLEN(mtod(*m0, struct ip *));
+ return (0);
+ }
+ }
+
+ args.m = *m0;
+ args.oif = dir == DIR_OUT ? ifp : NULL;
+ args.inp = inp;
+
+ ipfw = ipfw_chk(&args);
+ *m0 = args.m;
+
+ KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
+ __func__));
+
+ /* breaking out of the switch means drop */
+ ret = 0; /* default return value for pass */
+ switch (ipfw) {
+ case IP_FW_PASS:
+ /* next_hop may be set by ipfw_chk */
+ if (args.next_hop == NULL && args.next_hop6 == NULL)
+ break; /* pass */
+#if !defined(IPFIREWALL_FORWARD) || (!defined(INET6) && !defined(INET))
+ ret = EACCES;
+#else
+ {
+ struct m_tag *fwd_tag;
+ size_t len;
+
+ KASSERT(args.next_hop == NULL || args.next_hop6 == NULL,
+ ("%s: both next_hop=%p and next_hop6=%p not NULL", __func__,
+ args.next_hop, args.next_hop6));
+#ifdef INET6
+ if (args.next_hop6 != NULL)
+ len = sizeof(struct sockaddr_in6);
+#endif
+#ifdef INET
+ if (args.next_hop != NULL)
+ len = sizeof(struct sockaddr_in);
+#endif
+
+ /* Incoming packets should not be tagged so we do not
+ * m_tag_find. Outgoing packets may be tagged, so we
+ * reuse the tag if present.
+ */
+ fwd_tag = (dir == DIR_IN) ? NULL :
+ m_tag_find(*m0, PACKET_TAG_IPFORWARD, NULL);
+ if (fwd_tag != NULL) {
+ m_tag_unlink(*m0, fwd_tag);
+ } else {
+ fwd_tag = m_tag_get(PACKET_TAG_IPFORWARD, len,
+ M_NOWAIT);
+ if (fwd_tag == NULL) {
+ ret = EACCES;
+ break; /* i.e. drop */
+ }
+ }
+#ifdef INET6
+ if (args.next_hop6 != NULL) {
+ bcopy(args.next_hop6, (fwd_tag+1), len);
+ if (in6_localip(&args.next_hop6->sin6_addr))
+ (*m0)->m_flags |= M_FASTFWD_OURS;
+ }
+#endif
+#ifdef INET
+ if (args.next_hop != NULL) {
+ bcopy(args.next_hop, (fwd_tag+1), len);
+ if (in_localip(args.next_hop->sin_addr))
+ (*m0)->m_flags |= M_FASTFWD_OURS;
+ }
+#endif
+ m_tag_prepend(*m0, fwd_tag);
+ }
+#endif /* IPFIREWALL_FORWARD */
+ break;
+
+ case IP_FW_DENY:
+ ret = EACCES;
+ break; /* i.e. drop */
+
+ case IP_FW_DUMMYNET:
+ ret = EACCES;
+ if (ip_dn_io_ptr == NULL)
+ break; /* i.e. drop */
+ if (mtod(*m0, struct ip *)->ip_v == 4)
+ ret = ip_dn_io_ptr(m0, dir, &args);
+ else if (mtod(*m0, struct ip *)->ip_v == 6)
+ ret = ip_dn_io_ptr(m0, dir | PROTO_IPV6, &args);
+ else
+ break; /* drop it */
+ /*
+ * XXX should read the return value.
+ * dummynet normally eats the packet and sets *m0=NULL
+ * unless the packet can be sent immediately. In this
+ * case args is updated and we should re-run the
+ * check without clearing args.
+ */
+ if (*m0 != NULL)
+ goto again;
+ break;
+
+ case IP_FW_TEE:
+ case IP_FW_DIVERT:
+ if (ip_divert_ptr == NULL) {
+ ret = EACCES;
+ break; /* i.e. drop */
+ }
+ ret = ipfw_divert(m0, dir, &args.rule,
+ (ipfw == IP_FW_TEE) ? 1 : 0);
+ /* continue processing for the original packet (tee). */
+ if (*m0)
+ goto again;
+ break;
+
+ case IP_FW_NGTEE:
+ case IP_FW_NETGRAPH:
+ if (ng_ipfw_input_p == NULL) {
+ ret = EACCES;
+ break; /* i.e. drop */
+ }
+ ret = ng_ipfw_input_p(m0, dir, &args,
+ (ipfw == IP_FW_NGTEE) ? 1 : 0);
+ if (ipfw == IP_FW_NGTEE) /* ignore errors for NGTEE */
+ goto again; /* continue with packet */
+ break;
+
+ case IP_FW_NAT:
+ /* honor one-pass in case of successful nat */
+ if (V_fw_one_pass)
+ break; /* ret is already 0 */
+ goto again;
+
+ case IP_FW_REASS:
+ goto again; /* continue with packet */
+
+ default:
+ KASSERT(0, ("%s: unknown retval", __func__));
+ }
+
+ if (ret != 0) {
+ if (*m0)
+ FREE_PKT(*m0);
+ *m0 = NULL;
+ }
+ if (*m0 && mtod(*m0, struct ip *)->ip_v == 4)
+ SET_HOST_IPLEN(mtod(*m0, struct ip *));
+ return ret;
+}
+
+/* do the divert, return 1 on error 0 on success */
+static int
+ipfw_divert(struct mbuf **m0, int incoming, struct ipfw_rule_ref *rule,
+ int tee)
+{
+ /*
+ * ipfw_chk() has already tagged the packet with the divert tag.
+ * If tee is set, copy packet and return original.
+ * If not tee, consume packet and send it to divert socket.
+ */
+ struct mbuf *clone;
+ struct ip *ip = mtod(*m0, struct ip *);
+ struct m_tag *tag;
+
+ /* Cloning needed for tee? */
+ if (tee == 0) {
+ clone = *m0; /* use the original mbuf */
+ *m0 = NULL;
+ } else {
+ clone = m_dup(*m0, M_DONTWAIT);
+ /* If we cannot duplicate the mbuf, we sacrifice the divert
+ * chain and continue with the tee-ed packet.
+ */
+ if (clone == NULL)
+ return 1;
+ }
+
+ /*
+ * Divert listeners can normally handle non-fragmented packets,
+ * but we can only reass in the non-tee case.
+ * This means that listeners on a tee rule may get fragments,
+ * and have to live with that.
+ * Note that we now have the 'reass' ipfw option so if we care
+ * we can do it before a 'tee'.
+ */
+ if (!tee) switch (ip->ip_v) {
+ case IPVERSION:
+ if (ntohs(ip->ip_off) & (IP_MF | IP_OFFMASK)) {
+ int hlen;
+ struct mbuf *reass;
+
+ SET_HOST_IPLEN(ip); /* ip_reass wants host order */
+ reass = ip_reass(clone); /* Reassemble packet. */
+ if (reass == NULL)
+ return 0; /* not an error */
+ /* if reass = NULL then it was consumed by ip_reass */
+ /*
+ * IP header checksum fixup after reassembly and leave header
+ * in network byte order.
+ */
+ ip = mtod(reass, struct ip *);
+ hlen = ip->ip_hl << 2;
+ SET_NET_IPLEN(ip);
+ ip->ip_sum = 0;
+ if (hlen == sizeof(struct ip))
+ ip->ip_sum = in_cksum_hdr(ip);
+ else
+ ip->ip_sum = in_cksum(reass, hlen);
+ clone = reass;
+ }
+ break;
+#ifdef INET6
+ case IPV6_VERSION >> 4:
+ {
+ struct ip6_hdr *const ip6 = mtod(clone, struct ip6_hdr *);
+
+ if (ip6->ip6_nxt == IPPROTO_FRAGMENT) {
+ int nxt, off;
+
+ off = sizeof(struct ip6_hdr);
+ nxt = frag6_input(&clone, &off, 0);
+ if (nxt == IPPROTO_DONE)
+ return (0);
+ }
+ break;
+ }
+#endif
+ }
+
+ /* attach a tag to the packet with the reinject info */
+ tag = m_tag_alloc(MTAG_IPFW_RULE, 0,
+ sizeof(struct ipfw_rule_ref), M_NOWAIT);
+ if (tag == NULL) {
+ FREE_PKT(clone);
+ return 1;
+ }
+ *((struct ipfw_rule_ref *)(tag+1)) = *rule;
+ m_tag_prepend(clone, tag);
+
+ /* Do the dirty job... */
+ ip_divert_ptr(clone, incoming);
+ return 0;
+}
+
+/*
+ * attach or detach hooks for a given protocol family
+ */
+static int
+ipfw_hook(int onoff, int pf)
+{
+ struct pfil_head *pfh;
+
+ pfh = pfil_head_get(PFIL_TYPE_AF, pf);
+ if (pfh == NULL)
+ return ENOENT;
+
+ (void) (onoff ? pfil_add_hook : pfil_remove_hook)
+ (ipfw_check_hook, NULL, PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh);
+
+ return 0;
+}
+
+int
+ipfw_attach_hooks(int arg)
+{
+ int error = 0;
+
+ if (arg == 0) /* detach */
+ ipfw_hook(0, AF_INET);
+ else if (V_fw_enable && ipfw_hook(1, AF_INET) != 0) {
+ error = ENOENT; /* see ip_fw_pfil.c::ipfw_hook() */
+ printf("ipfw_hook() error\n");
+ }
+#ifdef INET6
+ if (arg == 0) /* detach */
+ ipfw_hook(0, AF_INET6);
+ else if (V_fw6_enable && ipfw_hook(1, AF_INET6) != 0) {
+ error = ENOENT;
+ printf("ipfw6_hook() error\n");
+ }
+#endif
+ return error;
+}
+
+int
+ipfw_chg_hook(SYSCTL_HANDLER_ARGS)
+{
+ int enable;
+ int oldenable;
+ int error;
+ int af;
+
+ if (arg1 == &VNET_NAME(fw_enable)) {
+ enable = V_fw_enable;
+ af = AF_INET;
+ }
+#ifdef INET6
+ else if (arg1 == &VNET_NAME(fw6_enable)) {
+ enable = V_fw6_enable;
+ af = AF_INET6;
+ }
+#endif
+ else
+ return (EINVAL);
+
+ oldenable = enable;
+
+ error = sysctl_handle_int(oidp, &enable, 0, req);
+
+ if (error)
+ return (error);
+
+ enable = (enable) ? 1 : 0;
+
+ if (enable == oldenable)
+ return (0);
+
+ error = ipfw_hook(enable, af);
+ if (error)
+ return (error);
+ if (af == AF_INET)
+ V_fw_enable = enable;
+#ifdef INET6
+ else if (af == AF_INET6)
+ V_fw6_enable = enable;
+#endif
+
+ return (0);
+}
+/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_private.h b/sys/netinet/ipfw/ip_fw_private.h
new file mode 100644
index 0000000..7f65c41
--- /dev/null
+++ b/sys/netinet/ipfw/ip_fw_private.h
@@ -0,0 +1,313 @@
+/*-
+ * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _IPFW2_PRIVATE_H
+#define _IPFW2_PRIVATE_H
+
+/*
+ * Internal constants and data structures used by ipfw components
+ * and not meant to be exported outside the kernel.
+ */
+
+#ifdef _KERNEL
+
+/*
+ * For platforms that do not have SYSCTL support, we wrap the
+ * SYSCTL_* into a function (one per file) to collect the values
+ * into an array at module initialization. The wrapping macros,
+ * SYSBEGIN() and SYSEND, are empty in the default case.
+ */
+#ifndef SYSBEGIN
+#define SYSBEGIN(x)
+#endif
+#ifndef SYSEND
+#define SYSEND
+#endif
+
+/* Return values from ipfw_chk() */
+enum {
+ IP_FW_PASS = 0,
+ IP_FW_DENY,
+ IP_FW_DIVERT,
+ IP_FW_TEE,
+ IP_FW_DUMMYNET,
+ IP_FW_NETGRAPH,
+ IP_FW_NGTEE,
+ IP_FW_NAT,
+ IP_FW_REASS,
+};
+
+/*
+ * Structure for collecting parameters to dummynet for ip6_output forwarding
+ */
+struct _ip6dn_args {
+ struct ip6_pktopts *opt_or;
+ struct route_in6 ro_or;
+ int flags_or;
+ struct ip6_moptions *im6o_or;
+ struct ifnet *origifp_or;
+ struct ifnet *ifp_or;
+ struct sockaddr_in6 dst_or;
+ u_long mtu_or;
+ struct route_in6 ro_pmtu_or;
+};
+
+
+/*
+ * Arguments for calling ipfw_chk() and dummynet_io(). We put them
+ * all into a structure because this way it is easier and more
+ * efficient to pass variables around and extend the interface.
+ */
+struct ip_fw_args {
+ struct mbuf *m; /* the mbuf chain */
+ struct ifnet *oif; /* output interface */
+ struct sockaddr_in *next_hop; /* forward address */
+ struct sockaddr_in6 *next_hop6; /* ipv6 forward address */
+
+ /*
+ * On return, it points to the matching rule.
+ * On entry, rule.slot > 0 means the info is valid and
+ * contains the starting rule for an ipfw search.
+ * If chain_id == chain->id && slot >0 then jump to that slot.
+ * Otherwise, we locate the first rule >= rulenum:rule_id
+ */
+ struct ipfw_rule_ref rule; /* match/restart info */
+
+ struct ether_header *eh; /* for bridged packets */
+
+ struct ipfw_flow_id f_id; /* grabbed from IP header */
+ //uint32_t cookie; /* a cookie depending on rule action */
+ struct inpcb *inp;
+
+ struct _ip6dn_args dummypar; /* dummynet->ip6_output */
+ struct sockaddr_in hopstore; /* store here if cannot use a pointer */
+};
+
+MALLOC_DECLARE(M_IPFW);
+
+/*
+ * Hooks sometime need to know the direction of the packet
+ * (divert, dummynet, netgraph, ...)
+ * We use a generic definition here, with bit0-1 indicating the
+ * direction, bit 2 indicating layer2 or 3, bit 3-4 indicating the
+ * specific protocol
+ * indicating the protocol (if necessary)
+ */
+enum {
+ DIR_MASK = 0x3,
+ DIR_OUT = 0,
+ DIR_IN = 1,
+ DIR_FWD = 2,
+ DIR_DROP = 3,
+ PROTO_LAYER2 = 0x4, /* set for layer 2 */
+ /* PROTO_DEFAULT = 0, */
+ PROTO_IPV4 = 0x08,
+ PROTO_IPV6 = 0x10,
+ PROTO_IFB = 0x0c, /* layer2 + ifbridge */
+ /* PROTO_OLDBDG = 0x14, unused, old bridge */
+};
+
+/* wrapper for freeing a packet, in case we need to do more work */
+#ifndef FREE_PKT
+#if defined(__linux__) || defined(_WIN32)
+#define FREE_PKT(m) netisr_dispatch(-1, m)
+#else
+#define FREE_PKT(m) m_freem(m)
+#endif
+#endif /* !FREE_PKT */
+
+/*
+ * Function definitions.
+ */
+
+/* attach (arg = 1) or detach (arg = 0) hooks */
+int ipfw_attach_hooks(int);
+#ifdef NOTYET
+void ipfw_nat_destroy(void);
+#endif
+
+/* In ip_fw_log.c */
+struct ip;
+void ipfw_log_bpf(int);
+void ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
+ struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
+ struct ip *ip);
+VNET_DECLARE(u_int64_t, norule_counter);
+#define V_norule_counter VNET(norule_counter)
+VNET_DECLARE(int, verbose_limit);
+#define V_verbose_limit VNET(verbose_limit)
+
+/* In ip_fw_dynamic.c */
+
+enum { /* result for matching dynamic rules */
+ MATCH_REVERSE = 0,
+ MATCH_FORWARD,
+ MATCH_NONE,
+ MATCH_UNKNOWN,
+};
+
+/*
+ * The lock for dynamic rules is only used once outside the file,
+ * and only to release the result of lookup_dyn_rule().
+ * Eventually we may implement it with a callback on the function.
+ */
+void ipfw_dyn_unlock(void);
+
+struct tcphdr;
+struct mbuf *ipfw_send_pkt(struct mbuf *, struct ipfw_flow_id *,
+ u_int32_t, u_int32_t, int);
+int ipfw_install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
+ struct ip_fw_args *args, uint32_t tablearg);
+ipfw_dyn_rule *ipfw_lookup_dyn_rule(struct ipfw_flow_id *pkt,
+ int *match_direction, struct tcphdr *tcp);
+void ipfw_remove_dyn_children(struct ip_fw *rule);
+void ipfw_get_dynamic(char **bp, const char *ep);
+
+void ipfw_dyn_attach(void); /* uma_zcreate .... */
+void ipfw_dyn_detach(void); /* uma_zdestroy ... */
+void ipfw_dyn_init(void); /* per-vnet initialization */
+void ipfw_dyn_uninit(int); /* per-vnet deinitialization */
+int ipfw_dyn_len(void);
+
+/* common variables */
+VNET_DECLARE(int, fw_one_pass);
+#define V_fw_one_pass VNET(fw_one_pass)
+
+VNET_DECLARE(int, fw_verbose);
+#define V_fw_verbose VNET(fw_verbose)
+
+VNET_DECLARE(struct ip_fw_chain, layer3_chain);
+#define V_layer3_chain VNET(layer3_chain)
+
+VNET_DECLARE(u_int32_t, set_disable);
+#define V_set_disable VNET(set_disable)
+
+VNET_DECLARE(int, autoinc_step);
+#define V_autoinc_step VNET(autoinc_step)
+
+VNET_DECLARE(unsigned int, fw_tables_max);
+#define V_fw_tables_max VNET(fw_tables_max)
+
+struct ip_fw_chain {
+ struct ip_fw *rules; /* list of rules */
+ struct ip_fw *reap; /* list of rules to reap */
+ struct ip_fw *default_rule;
+ int n_rules; /* number of static rules */
+ int static_len; /* total len of static rules */
+ struct ip_fw **map; /* array of rule ptrs to ease lookup */
+ LIST_HEAD(nat_list, cfg_nat) nat; /* list of nat entries */
+ struct radix_node_head **tables; /* IPv4 tables */
+ struct radix_node_head **xtables; /* extended tables */
+ uint8_t *tabletype; /* Array of table types */
+#if defined( __linux__ ) || defined( _WIN32 )
+ spinlock_t rwmtx;
+ spinlock_t uh_lock;
+#else
+ struct rwlock rwmtx;
+ struct rwlock uh_lock; /* lock for upper half */
+#endif
+ uint32_t id; /* ruleset id */
+ uint32_t gencnt; /* generation count */
+};
+
+struct sockopt; /* used by tcp_var.h */
+
+/*
+ * The lock is heavily used by ip_fw2.c (the main file) and ip_fw_nat.c
+ * so the variable and the macros must be here.
+ */
+
+#define IPFW_LOCK_INIT(_chain) do { \
+ rw_init(&(_chain)->rwmtx, "IPFW static rules"); \
+ rw_init(&(_chain)->uh_lock, "IPFW UH lock"); \
+ } while (0)
+
+#define IPFW_LOCK_DESTROY(_chain) do { \
+ rw_destroy(&(_chain)->rwmtx); \
+ rw_destroy(&(_chain)->uh_lock); \
+ } while (0)
+
+#define IPFW_WLOCK_ASSERT(_chain) rw_assert(&(_chain)->rwmtx, RA_WLOCKED)
+
+#define IPFW_RLOCK(p) rw_rlock(&(p)->rwmtx)
+#define IPFW_RUNLOCK(p) rw_runlock(&(p)->rwmtx)
+#define IPFW_WLOCK(p) rw_wlock(&(p)->rwmtx)
+#define IPFW_WUNLOCK(p) rw_wunlock(&(p)->rwmtx)
+
+#define IPFW_UH_RLOCK(p) rw_rlock(&(p)->uh_lock)
+#define IPFW_UH_RUNLOCK(p) rw_runlock(&(p)->uh_lock)
+#define IPFW_UH_WLOCK(p) rw_wlock(&(p)->uh_lock)
+#define IPFW_UH_WUNLOCK(p) rw_wunlock(&(p)->uh_lock)
+
+/* In ip_fw_sockopt.c */
+int ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id);
+int ipfw_add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule);
+int ipfw_ctl(struct sockopt *sopt);
+int ipfw_chk(struct ip_fw_args *args);
+void ipfw_reap_rules(struct ip_fw *head);
+
+/* In ip_fw_pfil */
+int ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
+ struct inpcb *inp);
+
+/* In ip_fw_table.c */
+struct radix_node;
+int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
+ uint32_t *val);
+int ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
+ uint32_t *val, int type);
+int ipfw_init_tables(struct ip_fw_chain *ch);
+void ipfw_destroy_tables(struct ip_fw_chain *ch);
+int ipfw_flush_table(struct ip_fw_chain *ch, uint16_t tbl);
+int ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
+ uint8_t plen, uint8_t mlen, uint8_t type, uint32_t value);
+int ipfw_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
+ uint8_t plen, uint8_t mlen, uint8_t type);
+int ipfw_count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt);
+int ipfw_dump_table_entry(struct radix_node *rn, void *arg);
+int ipfw_dump_table(struct ip_fw_chain *ch, ipfw_table *tbl);
+int ipfw_count_xtable(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt);
+int ipfw_dump_xtable(struct ip_fw_chain *ch, ipfw_xtable *tbl);
+int ipfw_resize_tables(struct ip_fw_chain *ch, unsigned int ntables);
+
+/* In ip_fw_nat.c -- XXX to be moved to ip_var.h */
+
+extern struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
+
+typedef int ipfw_nat_t(struct ip_fw_args *, struct cfg_nat *, struct mbuf *);
+typedef int ipfw_nat_cfg_t(struct sockopt *);
+
+extern ipfw_nat_t *ipfw_nat_ptr;
+#define IPFW_NAT_LOADED (ipfw_nat_ptr != NULL)
+
+extern ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
+extern ipfw_nat_cfg_t *ipfw_nat_del_ptr;
+extern ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
+extern ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
+
+#endif /* _KERNEL */
+#endif /* _IPFW2_PRIVATE_H */
diff --git a/sys/netinet/ipfw/ip_fw_sockopt.c b/sys/netinet/ipfw/ip_fw_sockopt.c
new file mode 100644
index 0000000..2a5f4e7
--- /dev/null
+++ b/sys/netinet/ipfw/ip_fw_sockopt.c
@@ -0,0 +1,1448 @@
+/*-
+ * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
+ *
+ * Supported by: Valeria Paoli
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Sockopt support for ipfw. The routines here implement
+ * the upper half of the ipfw code.
+ */
+
+#include "opt_ipfw.h"
+#include "opt_inet.h"
+#ifndef INET
+#error IPFIREWALL requires INET.
+#endif /* INET */
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h> /* struct m_tag used by nested headers */
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/sysctl.h>
+#include <sys/syslog.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <net/vnet.h>
+
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* hooks */
+#include <netinet/ip_fw.h>
+#include <netinet/ipfw/ip_fw_private.h>
+
+#ifdef MAC
+#include <security/mac/mac_framework.h>
+#endif
+
+MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
+
+/*
+ * static variables followed by global ones (none in this file)
+ */
+
+/*
+ * Find the smallest rule >= key, id.
+ * We could use bsearch but it is so simple that we code it directly
+ */
+int
+ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id)
+{
+ int i, lo, hi;
+ struct ip_fw *r;
+
+ for (lo = 0, hi = chain->n_rules - 1; lo < hi;) {
+ i = (lo + hi) / 2;
+ r = chain->map[i];
+ if (r->rulenum < key)
+ lo = i + 1; /* continue from the next one */
+ else if (r->rulenum > key)
+ hi = i; /* this might be good */
+ else if (r->id < id)
+ lo = i + 1; /* continue from the next one */
+ else /* r->id >= id */
+ hi = i; /* this might be good */
+ };
+ return hi;
+}
+
+/*
+ * allocate a new map, returns the chain locked. extra is the number
+ * of entries to add or delete.
+ */
+static struct ip_fw **
+get_map(struct ip_fw_chain *chain, int extra, int locked)
+{
+
+ for (;;) {
+ struct ip_fw **map;
+ int i;
+
+ i = chain->n_rules + extra;
+ map = malloc(i * sizeof(struct ip_fw *), M_IPFW,
+ locked ? M_NOWAIT : M_WAITOK);
+ if (map == NULL) {
+ printf("%s: cannot allocate map\n", __FUNCTION__);
+ return NULL;
+ }
+ if (!locked)
+ IPFW_UH_WLOCK(chain);
+ if (i >= chain->n_rules + extra) /* good */
+ return map;
+ /* otherwise we lost the race, free and retry */
+ if (!locked)
+ IPFW_UH_WUNLOCK(chain);
+ free(map, M_IPFW);
+ }
+}
+
+/*
+ * swap the maps. It is supposed to be called with IPFW_UH_WLOCK
+ */
+static struct ip_fw **
+swap_map(struct ip_fw_chain *chain, struct ip_fw **new_map, int new_len)
+{
+ struct ip_fw **old_map;
+
+ IPFW_WLOCK(chain);
+ chain->id++;
+ chain->n_rules = new_len;
+ old_map = chain->map;
+ chain->map = new_map;
+ IPFW_WUNLOCK(chain);
+ return old_map;
+}
+
+/*
+ * Add a new rule to the list. Copy the rule into a malloc'ed area, then
+ * possibly create a rule number and add the rule to the list.
+ * Update the rule_number in the input struct so the caller knows it as well.
+ * XXX DO NOT USE FOR THE DEFAULT RULE.
+ * Must be called without IPFW_UH held
+ */
+int
+ipfw_add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule)
+{
+ struct ip_fw *rule;
+ int i, l, insert_before;
+ struct ip_fw **map; /* the new array of pointers */
+
+ if (chain->rules == NULL || input_rule->rulenum > IPFW_DEFAULT_RULE-1)
+ return (EINVAL);
+
+ l = RULESIZE(input_rule);
+ rule = malloc(l, M_IPFW, M_WAITOK | M_ZERO);
+ /* get_map returns with IPFW_UH_WLOCK if successful */
+ map = get_map(chain, 1, 0 /* not locked */);
+ if (map == NULL) {
+ free(rule, M_IPFW);
+ return ENOSPC;
+ }
+
+ bcopy(input_rule, rule, l);
+ /* clear fields not settable from userland */
+ rule->x_next = NULL;
+ rule->next_rule = NULL;
+ rule->pcnt = 0;
+ rule->bcnt = 0;
+ rule->timestamp = 0;
+
+ if (V_autoinc_step < 1)
+ V_autoinc_step = 1;
+ else if (V_autoinc_step > 1000)
+ V_autoinc_step = 1000;
+ /* find the insertion point, we will insert before */
+ insert_before = rule->rulenum ? rule->rulenum + 1 : IPFW_DEFAULT_RULE;
+ i = ipfw_find_rule(chain, insert_before, 0);
+ /* duplicate first part */
+ if (i > 0)
+ bcopy(chain->map, map, i * sizeof(struct ip_fw *));
+ map[i] = rule;
+ /* duplicate remaining part, we always have the default rule */
+ bcopy(chain->map + i, map + i + 1,
+ sizeof(struct ip_fw *) *(chain->n_rules - i));
+ if (rule->rulenum == 0) {
+ /* write back the number */
+ rule->rulenum = i > 0 ? map[i-1]->rulenum : 0;
+ if (rule->rulenum < IPFW_DEFAULT_RULE - V_autoinc_step)
+ rule->rulenum += V_autoinc_step;
+ input_rule->rulenum = rule->rulenum;
+ }
+
+ rule->id = chain->id + 1;
+ map = swap_map(chain, map, chain->n_rules + 1);
+ chain->static_len += l;
+ IPFW_UH_WUNLOCK(chain);
+ if (map)
+ free(map, M_IPFW);
+ return (0);
+}
+
+/*
+ * Reclaim storage associated with a list of rules. This is
+ * typically the list created using remove_rule.
+ * A NULL pointer on input is handled correctly.
+ */
+void
+ipfw_reap_rules(struct ip_fw *head)
+{
+ struct ip_fw *rule;
+
+ while ((rule = head) != NULL) {
+ head = head->x_next;
+ free(rule, M_IPFW);
+ }
+}
+
+/*
+ * Used by del_entry() to check if a rule should be kept.
+ * Returns 1 if the rule must be kept, 0 otherwise.
+ *
+ * Called with cmd = {0,1,5}.
+ * cmd == 0 matches on rule numbers, excludes rules in RESVD_SET if n == 0 ;
+ * cmd == 1 matches on set numbers only, rule numbers are ignored;
+ * cmd == 5 matches on rule and set numbers.
+ *
+ * n == 0 is a wildcard for rule numbers, there is no wildcard for sets.
+ *
+ * Rules to keep are
+ * (default || reserved || !match_set || !match_number)
+ * where
+ * default ::= (rule->rulenum == IPFW_DEFAULT_RULE)
+ * // the default rule is always protected
+ *
+ * reserved ::= (cmd == 0 && n == 0 && rule->set == RESVD_SET)
+ * // RESVD_SET is protected only if cmd == 0 and n == 0 ("ipfw flush")
+ *
+ * match_set ::= (cmd == 0 || rule->set == set)
+ * // set number is ignored for cmd == 0
+ *
+ * match_number ::= (cmd == 1 || n == 0 || n == rule->rulenum)
+ * // number is ignored for cmd == 1 or n == 0
+ *
+ */
+static int
+keep_rule(struct ip_fw *rule, uint8_t cmd, uint8_t set, uint32_t n)
+{
+ return
+ (rule->rulenum == IPFW_DEFAULT_RULE) ||
+ (cmd == 0 && n == 0 && rule->set == RESVD_SET) ||
+ !(cmd == 0 || rule->set == set) ||
+ !(cmd == 1 || n == 0 || n == rule->rulenum);
+}
+
+/**
+ * Remove all rules with given number, or do set manipulation.
+ * Assumes chain != NULL && *chain != NULL.
+ *
+ * The argument is an uint32_t. The low 16 bit are the rule or set number;
+ * the next 8 bits are the new set; the top 8 bits indicate the command:
+ *
+ * 0 delete rules numbered "rulenum"
+ * 1 delete rules in set "rulenum"
+ * 2 move rules "rulenum" to set "new_set"
+ * 3 move rules from set "rulenum" to set "new_set"
+ * 4 swap sets "rulenum" and "new_set"
+ * 5 delete rules "rulenum" and set "new_set"
+ */
+static int
+del_entry(struct ip_fw_chain *chain, uint32_t arg)
+{
+ struct ip_fw *rule;
+ uint32_t num; /* rule number or old_set */
+ uint8_t cmd, new_set;
+ int start, end, i, ofs, n;
+ struct ip_fw **map = NULL;
+ int error = 0;
+
+ num = arg & 0xffff;
+ cmd = (arg >> 24) & 0xff;
+ new_set = (arg >> 16) & 0xff;
+
+ if (cmd > 5 || new_set > RESVD_SET)
+ return EINVAL;
+ if (cmd == 0 || cmd == 2 || cmd == 5) {
+ if (num >= IPFW_DEFAULT_RULE)
+ return EINVAL;
+ } else {
+ if (num > RESVD_SET) /* old_set */
+ return EINVAL;
+ }
+
+ IPFW_UH_WLOCK(chain); /* arbitrate writers */
+ chain->reap = NULL; /* prepare for deletions */
+
+ switch (cmd) {
+ case 0: /* delete rules "num" (num == 0 matches all) */
+ case 1: /* delete all rules in set N */
+ case 5: /* delete rules with number N and set "new_set". */
+
+ /*
+ * Locate first rule to delete (start), the rule after
+ * the last one to delete (end), and count how many
+ * rules to delete (n). Always use keep_rule() to
+ * determine which rules to keep.
+ */
+ n = 0;
+ if (cmd == 1) {
+ /* look for a specific set including RESVD_SET.
+ * Must scan the entire range, ignore num.
+ */
+ new_set = num;
+ for (start = -1, end = i = 0; i < chain->n_rules; i++) {
+ if (keep_rule(chain->map[i], cmd, new_set, 0))
+ continue;
+ if (start < 0)
+ start = i;
+ end = i;
+ n++;
+ }
+ end++; /* first non-matching */
+ } else {
+ /* Optimized search on rule numbers */
+ start = ipfw_find_rule(chain, num, 0);
+ for (end = start; end < chain->n_rules; end++) {
+ rule = chain->map[end];
+ if (num > 0 && rule->rulenum != num)
+ break;
+ if (!keep_rule(rule, cmd, new_set, num))
+ n++;
+ }
+ }
+
+ if (n == 0) {
+ /* A flush request (arg == 0 or cmd == 1) on empty
+ * ruleset returns with no error. On the contrary,
+ * if there is no match on a specific request,
+ * we return EINVAL.
+ */
+ if (arg != 0 && cmd != 1)
+ error = EINVAL;
+ break;
+ }
+
+ /* We have something to delete. Allocate the new map */
+ map = get_map(chain, -n, 1 /* locked */);
+ if (map == NULL) {
+ error = EINVAL;
+ break;
+ }
+
+ /* 1. bcopy the initial part of the map */
+ if (start > 0)
+ bcopy(chain->map, map, start * sizeof(struct ip_fw *));
+ /* 2. copy active rules between start and end */
+ for (i = ofs = start; i < end; i++) {
+ rule = chain->map[i];
+ if (keep_rule(rule, cmd, new_set, num))
+ map[ofs++] = rule;
+ }
+ /* 3. copy the final part of the map */
+ bcopy(chain->map + end, map + ofs,
+ (chain->n_rules - end) * sizeof(struct ip_fw *));
+ /* 4. swap the maps (under BH_LOCK) */
+ map = swap_map(chain, map, chain->n_rules - n);
+ /* 5. now remove the rules deleted from the old map */
+ for (i = start; i < end; i++) {
+ int l;
+ rule = map[i];
+ if (keep_rule(rule, cmd, new_set, num))
+ continue;
+ l = RULESIZE(rule);
+ chain->static_len -= l;
+ ipfw_remove_dyn_children(rule);
+ rule->x_next = chain->reap;
+ chain->reap = rule;
+ }
+ break;
+
+ /*
+ * In the next 3 cases the loop stops at (n_rules - 1)
+ * because the default rule is never eligible..
+ */
+
+ case 2: /* move rules with given RULE number to new set */
+ for (i = 0; i < chain->n_rules - 1; i++) {
+ rule = chain->map[i];
+ if (rule->rulenum == num)
+ rule->set = new_set;
+ }
+ break;
+
+ case 3: /* move rules with given SET number to new set */
+ for (i = 0; i < chain->n_rules - 1; i++) {
+ rule = chain->map[i];
+ if (rule->set == num)
+ rule->set = new_set;
+ }
+ break;
+
+ case 4: /* swap two sets */
+ for (i = 0; i < chain->n_rules - 1; i++) {
+ rule = chain->map[i];
+ if (rule->set == num)
+ rule->set = new_set;
+ else if (rule->set == new_set)
+ rule->set = num;
+ }
+ break;
+ }
+
+ rule = chain->reap;
+ chain->reap = NULL;
+ IPFW_UH_WUNLOCK(chain);
+ ipfw_reap_rules(rule);
+ if (map)
+ free(map, M_IPFW);
+ return error;
+}
+
+/*
+ * Clear counters for a specific rule.
+ * Normally run under IPFW_UH_RLOCK, but these are idempotent ops
+ * so we only care that rules do not disappear.
+ */
+static void
+clear_counters(struct ip_fw *rule, int log_only)
+{
+ ipfw_insn_log *l = (ipfw_insn_log *)ACTION_PTR(rule);
+
+ if (log_only == 0) {
+ rule->bcnt = rule->pcnt = 0;
+ rule->timestamp = 0;
+ }
+ if (l->o.opcode == O_LOG)
+ l->log_left = l->max_log;
+}
+
+/**
+ * Reset some or all counters on firewall rules.
+ * The argument `arg' is an u_int32_t. The low 16 bit are the rule number,
+ * the next 8 bits are the set number, the top 8 bits are the command:
+ * 0 work with rules from all set's;
+ * 1 work with rules only from specified set.
+ * Specified rule number is zero if we want to clear all entries.
+ * log_only is 1 if we only want to reset logs, zero otherwise.
+ */
+static int
+zero_entry(struct ip_fw_chain *chain, u_int32_t arg, int log_only)
+{
+ struct ip_fw *rule;
+ char *msg;
+ int i;
+
+ uint16_t rulenum = arg & 0xffff;
+ uint8_t set = (arg >> 16) & 0xff;
+ uint8_t cmd = (arg >> 24) & 0xff;
+
+ if (cmd > 1)
+ return (EINVAL);
+ if (cmd == 1 && set > RESVD_SET)
+ return (EINVAL);
+
+ IPFW_UH_RLOCK(chain);
+ if (rulenum == 0) {
+ V_norule_counter = 0;
+ for (i = 0; i < chain->n_rules; i++) {
+ rule = chain->map[i];
+ /* Skip rules not in our set. */
+ if (cmd == 1 && rule->set != set)
+ continue;
+ clear_counters(rule, log_only);
+ }
+ msg = log_only ? "All logging counts reset" :
+ "Accounting cleared";
+ } else {
+ int cleared = 0;
+ for (i = 0; i < chain->n_rules; i++) {
+ rule = chain->map[i];
+ if (rule->rulenum == rulenum) {
+ if (cmd == 0 || rule->set == set)
+ clear_counters(rule, log_only);
+ cleared = 1;
+ }
+ if (rule->rulenum > rulenum)
+ break;
+ }
+ if (!cleared) { /* we did not find any matching rules */
+ IPFW_UH_RUNLOCK(chain);
+ return (EINVAL);
+ }
+ msg = log_only ? "logging count reset" : "cleared";
+ }
+ IPFW_UH_RUNLOCK(chain);
+
+ if (V_fw_verbose) {
+ int lev = LOG_SECURITY | LOG_NOTICE;
+
+ if (rulenum)
+ log(lev, "ipfw: Entry %d %s.\n", rulenum, msg);
+ else
+ log(lev, "ipfw: %s.\n", msg);
+ }
+ return (0);
+}
+
+/*
+ * Check validity of the structure before insert.
+ * Rules are simple, so this mostly need to check rule sizes.
+ */
+static int
+check_ipfw_struct(struct ip_fw *rule, int size)
+{
+ int l, cmdlen = 0;
+ int have_action=0;
+ ipfw_insn *cmd;
+
+ if (size < sizeof(*rule)) {
+ printf("ipfw: rule too short\n");
+ return (EINVAL);
+ }
+ /* first, check for valid size */
+ l = RULESIZE(rule);
+ if (l != size) {
+ printf("ipfw: size mismatch (have %d want %d)\n", size, l);
+ return (EINVAL);
+ }
+ if (rule->act_ofs >= rule->cmd_len) {
+ printf("ipfw: bogus action offset (%u > %u)\n",
+ rule->act_ofs, rule->cmd_len - 1);
+ return (EINVAL);
+ }
+ /*
+ * Now go for the individual checks. Very simple ones, basically only
+ * instruction sizes.
+ */
+ for (l = rule->cmd_len, cmd = rule->cmd ;
+ l > 0 ; l -= cmdlen, cmd += cmdlen) {
+ cmdlen = F_LEN(cmd);
+ if (cmdlen > l) {
+ printf("ipfw: opcode %d size truncated\n",
+ cmd->opcode);
+ return EINVAL;
+ }
+ switch (cmd->opcode) {
+ case O_PROBE_STATE:
+ case O_KEEP_STATE:
+ case O_PROTO:
+ case O_IP_SRC_ME:
+ case O_IP_DST_ME:
+ case O_LAYER2:
+ case O_IN:
+ case O_FRAG:
+ case O_DIVERTED:
+ case O_IPOPT:
+ case O_IPTOS:
+ case O_IPPRECEDENCE:
+ case O_IPVER:
+ case O_SOCKARG:
+ case O_TCPFLAGS:
+ case O_TCPOPTS:
+ case O_ESTAB:
+ case O_VERREVPATH:
+ case O_VERSRCREACH:
+ case O_ANTISPOOF:
+ case O_IPSEC:
+#ifdef INET6
+ case O_IP6_SRC_ME:
+ case O_IP6_DST_ME:
+ case O_EXT_HDR:
+ case O_IP6:
+#endif
+ case O_IP4:
+ case O_TAG:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn))
+ goto bad_size;
+ break;
+
+ case O_FIB:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn))
+ goto bad_size;
+ if (cmd->arg1 >= rt_numfibs) {
+ printf("ipfw: invalid fib number %d\n",
+ cmd->arg1);
+ return EINVAL;
+ }
+ break;
+
+ case O_SETFIB:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn))
+ goto bad_size;
+ if ((cmd->arg1 != IP_FW_TABLEARG) &&
+ (cmd->arg1 >= rt_numfibs)) {
+ printf("ipfw: invalid fib number %d\n",
+ cmd->arg1);
+ return EINVAL;
+ }
+ goto check_action;
+
+ case O_UID:
+ case O_GID:
+ case O_JAIL:
+ case O_IP_SRC:
+ case O_IP_DST:
+ case O_TCPSEQ:
+ case O_TCPACK:
+ case O_PROB:
+ case O_ICMPTYPE:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_u32))
+ goto bad_size;
+ break;
+
+ case O_LIMIT:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_limit))
+ goto bad_size;
+ break;
+
+ case O_LOG:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_log))
+ goto bad_size;
+
+ ((ipfw_insn_log *)cmd)->log_left =
+ ((ipfw_insn_log *)cmd)->max_log;
+
+ break;
+
+ case O_IP_SRC_MASK:
+ case O_IP_DST_MASK:
+ /* only odd command lengths */
+ if ( !(cmdlen & 1) || cmdlen > 31)
+ goto bad_size;
+ break;
+
+ case O_IP_SRC_SET:
+ case O_IP_DST_SET:
+ if (cmd->arg1 == 0 || cmd->arg1 > 256) {
+ printf("ipfw: invalid set size %d\n",
+ cmd->arg1);
+ return EINVAL;
+ }
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
+ (cmd->arg1+31)/32 )
+ goto bad_size;
+ break;
+
+ case O_IP_SRC_LOOKUP:
+ case O_IP_DST_LOOKUP:
+ if (cmd->arg1 >= IPFW_TABLES_MAX) {
+ printf("ipfw: invalid table number %d\n",
+ cmd->arg1);
+ return (EINVAL);
+ }
+ if (cmdlen != F_INSN_SIZE(ipfw_insn) &&
+ cmdlen != F_INSN_SIZE(ipfw_insn_u32) + 1 &&
+ cmdlen != F_INSN_SIZE(ipfw_insn_u32))
+ goto bad_size;
+ break;
+ case O_MACADDR2:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_mac))
+ goto bad_size;
+ break;
+
+ case O_NOP:
+ case O_IPID:
+ case O_IPTTL:
+ case O_IPLEN:
+ case O_TCPDATALEN:
+ case O_TCPWIN:
+ case O_TAGGED:
+ if (cmdlen < 1 || cmdlen > 31)
+ goto bad_size;
+ break;
+
+ case O_MAC_TYPE:
+ case O_IP_SRCPORT:
+ case O_IP_DSTPORT: /* XXX artificial limit, 30 port pairs */
+ if (cmdlen < 2 || cmdlen > 31)
+ goto bad_size;
+ break;
+
+ case O_RECV:
+ case O_XMIT:
+ case O_VIA:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_if))
+ goto bad_size;
+ break;
+
+ case O_ALTQ:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_altq))
+ goto bad_size;
+ break;
+
+ case O_PIPE:
+ case O_QUEUE:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn))
+ goto bad_size;
+ goto check_action;
+
+ case O_FORWARD_IP:
+#ifdef IPFIREWALL_FORWARD
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_sa))
+ goto bad_size;
+ goto check_action;
+#else
+ return EINVAL;
+#endif
+
+#ifdef INET6
+ case O_FORWARD_IP6:
+#ifdef IPFIREWALL_FORWARD
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_sa6))
+ goto bad_size;
+ goto check_action;
+#else
+ return (EINVAL);
+#endif
+#endif /* INET6 */
+
+ case O_DIVERT:
+ case O_TEE:
+ if (ip_divert_ptr == NULL)
+ return EINVAL;
+ else
+ goto check_size;
+ case O_NETGRAPH:
+ case O_NGTEE:
+ if (ng_ipfw_input_p == NULL)
+ return EINVAL;
+ else
+ goto check_size;
+ case O_NAT:
+ if (!IPFW_NAT_LOADED)
+ return EINVAL;
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_nat))
+ goto bad_size;
+ goto check_action;
+ case O_FORWARD_MAC: /* XXX not implemented yet */
+ case O_CHECK_STATE:
+ case O_COUNT:
+ case O_ACCEPT:
+ case O_DENY:
+ case O_REJECT:
+#ifdef INET6
+ case O_UNREACH6:
+#endif
+ case O_SKIPTO:
+ case O_REASS:
+ case O_CALLRETURN:
+check_size:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn))
+ goto bad_size;
+check_action:
+ if (have_action) {
+ printf("ipfw: opcode %d, multiple actions"
+ " not allowed\n",
+ cmd->opcode);
+ return EINVAL;
+ }
+ have_action = 1;
+ if (l != cmdlen) {
+ printf("ipfw: opcode %d, action must be"
+ " last opcode\n",
+ cmd->opcode);
+ return EINVAL;
+ }
+ break;
+#ifdef INET6
+ case O_IP6_SRC:
+ case O_IP6_DST:
+ if (cmdlen != F_INSN_SIZE(struct in6_addr) +
+ F_INSN_SIZE(ipfw_insn))
+ goto bad_size;
+ break;
+
+ case O_FLOW6ID:
+ if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
+ ((ipfw_insn_u32 *)cmd)->o.arg1)
+ goto bad_size;
+ break;
+
+ case O_IP6_SRC_MASK:
+ case O_IP6_DST_MASK:
+ if ( !(cmdlen & 1) || cmdlen > 127)
+ goto bad_size;
+ break;
+ case O_ICMP6TYPE:
+ if( cmdlen != F_INSN_SIZE( ipfw_insn_icmp6 ) )
+ goto bad_size;
+ break;
+#endif
+
+ default:
+ switch (cmd->opcode) {
+#ifndef INET6
+ case O_IP6_SRC_ME:
+ case O_IP6_DST_ME:
+ case O_EXT_HDR:
+ case O_IP6:
+ case O_UNREACH6:
+ case O_IP6_SRC:
+ case O_IP6_DST:
+ case O_FLOW6ID:
+ case O_IP6_SRC_MASK:
+ case O_IP6_DST_MASK:
+ case O_ICMP6TYPE:
+ printf("ipfw: no IPv6 support in kernel\n");
+ return EPROTONOSUPPORT;
+#endif
+ default:
+ printf("ipfw: opcode %d, unknown opcode\n",
+ cmd->opcode);
+ return EINVAL;
+ }
+ }
+ }
+ if (have_action == 0) {
+ printf("ipfw: missing action\n");
+ return EINVAL;
+ }
+ return 0;
+
+bad_size:
+ printf("ipfw: opcode %d size %d wrong\n",
+ cmd->opcode, cmdlen);
+ return EINVAL;
+}
+
+
+/*
+ * Translation of requests for compatibility with FreeBSD 7.2/8.
+ * a static variable tells us if we have an old client from userland,
+ * and if necessary we translate requests and responses between the
+ * two formats.
+ */
+static int is7 = 0;
+
+struct ip_fw7 {
+ struct ip_fw7 *next; /* linked list of rules */
+ struct ip_fw7 *next_rule; /* ptr to next [skipto] rule */
+ /* 'next_rule' is used to pass up 'set_disable' status */
+
+ uint16_t act_ofs; /* offset of action in 32-bit units */
+ uint16_t cmd_len; /* # of 32-bit words in cmd */
+ uint16_t rulenum; /* rule number */
+ uint8_t set; /* rule set (0..31) */
+ // #define RESVD_SET 31 /* set for default and persistent rules */
+ uint8_t _pad; /* padding */
+ // uint32_t id; /* rule id, only in v.8 */
+ /* These fields are present in all rules. */
+ uint64_t pcnt; /* Packet counter */
+ uint64_t bcnt; /* Byte counter */
+ uint32_t timestamp; /* tv_sec of last match */
+
+ ipfw_insn cmd[1]; /* storage for commands */
+};
+
+ int convert_rule_to_7(struct ip_fw *rule);
+int convert_rule_to_8(struct ip_fw *rule);
+
+#ifndef RULESIZE7
+#define RULESIZE7(rule) (sizeof(struct ip_fw7) + \
+ ((struct ip_fw7 *)(rule))->cmd_len * 4 - 4)
+#endif
+
+
+/*
+ * Copy the static and dynamic rules to the supplied buffer
+ * and return the amount of space actually used.
+ * Must be run under IPFW_UH_RLOCK
+ */
+static size_t
+ipfw_getrules(struct ip_fw_chain *chain, void *buf, size_t space)
+{
+ char *bp = buf;
+ char *ep = bp + space;
+ struct ip_fw *rule, *dst;
+ int l, i;
+ time_t boot_seconds;
+
+ boot_seconds = boottime.tv_sec;
+ for (i = 0; i < chain->n_rules; i++) {
+ rule = chain->map[i];
+
+ if (is7) {
+ /* Convert rule to FreeBSd 7.2 format */
+ l = RULESIZE7(rule);
+ if (bp + l + sizeof(uint32_t) <= ep) {
+ int error;
+ bcopy(rule, bp, l + sizeof(uint32_t));
+ error = convert_rule_to_7((struct ip_fw *) bp);
+ if (error)
+ return 0; /*XXX correct? */
+ /*
+ * XXX HACK. Store the disable mask in the "next"
+ * pointer in a wild attempt to keep the ABI the same.
+ * Why do we do this on EVERY rule?
+ */
+ bcopy(&V_set_disable,
+ &(((struct ip_fw7 *)bp)->next_rule),
+ sizeof(V_set_disable));
+ if (((struct ip_fw7 *)bp)->timestamp)
+ ((struct ip_fw7 *)bp)->timestamp += boot_seconds;
+ bp += l;
+ }
+ continue; /* go to next rule */
+ }
+
+ /* normal mode, don't touch rules */
+ l = RULESIZE(rule);
+ if (bp + l > ep) { /* should not happen */
+ printf("overflow dumping static rules\n");
+ break;
+ }
+ dst = (struct ip_fw *)bp;
+ bcopy(rule, dst, l);
+ /*
+ * XXX HACK. Store the disable mask in the "next"
+ * pointer in a wild attempt to keep the ABI the same.
+ * Why do we do this on EVERY rule?
+ */
+ bcopy(&V_set_disable, &dst->next_rule, sizeof(V_set_disable));
+ if (dst->timestamp)
+ dst->timestamp += boot_seconds;
+ bp += l;
+ }
+ ipfw_get_dynamic(&bp, ep); /* protected by the dynamic lock */
+ return (bp - (char *)buf);
+}
+
+
+#define IP_FW3_OPLENGTH(x) ((x)->sopt_valsize - sizeof(ip_fw3_opheader))
+/**
+ * {set|get}sockopt parser.
+ */
+int
+ipfw_ctl(struct sockopt *sopt)
+{
+#define RULE_MAXSIZE (256*sizeof(u_int32_t))
+ int error;
+ size_t size, len, valsize;
+ struct ip_fw *buf, *rule;
+ struct ip_fw_chain *chain;
+ u_int32_t rulenum[2];
+ uint32_t opt;
+ char xbuf[128];
+ ip_fw3_opheader *op3 = NULL;
+
+ error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW);
+ if (error)
+ return (error);
+
+ /*
+ * Disallow modifications in really-really secure mode, but still allow
+ * the logging counters to be reset.
+ */
+ if (sopt->sopt_name == IP_FW_ADD ||
+ (sopt->sopt_dir == SOPT_SET && sopt->sopt_name != IP_FW_RESETLOG)) {
+ error = securelevel_ge(sopt->sopt_td->td_ucred, 3);
+ if (error)
+ return (error);
+ }
+
+ chain = &V_layer3_chain;
+ error = 0;
+
+ /* Save original valsize before it is altered via sooptcopyin() */
+ valsize = sopt->sopt_valsize;
+ if ((opt = sopt->sopt_name) == IP_FW3) {
+ /*
+ * Copy not less than sizeof(ip_fw3_opheader).
+ * We hope any IP_FW3 command will fit into 128-byte buffer.
+ */
+ if ((error = sooptcopyin(sopt, xbuf, sizeof(xbuf),
+ sizeof(ip_fw3_opheader))) != 0)
+ return (error);
+ op3 = (ip_fw3_opheader *)xbuf;
+ opt = op3->opcode;
+ }
+
+ switch (opt) {
+ case IP_FW_GET:
+ /*
+ * pass up a copy of the current rules. Static rules
+ * come first (the last of which has number IPFW_DEFAULT_RULE),
+ * followed by a possibly empty list of dynamic rule.
+ * The last dynamic rule has NULL in the "next" field.
+ *
+ * Note that the calculated size is used to bound the
+ * amount of data returned to the user. The rule set may
+ * change between calculating the size and returning the
+ * data in which case we'll just return what fits.
+ */
+ for (;;) {
+ int len = 0, want;
+
+ size = chain->static_len;
+ size += ipfw_dyn_len();
+ if (size >= sopt->sopt_valsize)
+ break;
+ buf = malloc(size, M_TEMP, M_WAITOK);
+ IPFW_UH_RLOCK(chain);
+ /* check again how much space we need */
+ want = chain->static_len + ipfw_dyn_len();
+ if (size >= want)
+ len = ipfw_getrules(chain, buf, size);
+ IPFW_UH_RUNLOCK(chain);
+ if (size >= want)
+ error = sooptcopyout(sopt, buf, len);
+ free(buf, M_TEMP);
+ if (size >= want)
+ break;
+ }
+ break;
+
+ case IP_FW_FLUSH:
+ /* locking is done within del_entry() */
+ error = del_entry(chain, 0); /* special case, rule=0, cmd=0 means all */
+ break;
+
+ case IP_FW_ADD:
+ rule = malloc(RULE_MAXSIZE, M_TEMP, M_WAITOK);
+ error = sooptcopyin(sopt, rule, RULE_MAXSIZE,
+ sizeof(struct ip_fw7) );
+
+ /*
+ * If the size of commands equals RULESIZE7 then we assume
+ * a FreeBSD7.2 binary is talking to us (set is7=1).
+ * is7 is persistent so the next 'ipfw list' command
+ * will use this format.
+ * NOTE: If wrong version is guessed (this can happen if
+ * the first ipfw command is 'ipfw [pipe] list')
+ * the ipfw binary may crash or loop infinitly...
+ */
+ if (sopt->sopt_valsize == RULESIZE7(rule)) {
+ is7 = 1;
+ error = convert_rule_to_8(rule);
+ if (error)
+ return error;
+ if (error == 0)
+ error = check_ipfw_struct(rule, RULESIZE(rule));
+ } else {
+ is7 = 0;
+ if (error == 0)
+ error = check_ipfw_struct(rule, sopt->sopt_valsize);
+ }
+ if (error == 0) {
+ /* locking is done within ipfw_add_rule() */
+ error = ipfw_add_rule(chain, rule);
+ size = RULESIZE(rule);
+ if (!error && sopt->sopt_dir == SOPT_GET) {
+ if (is7) {
+ error = convert_rule_to_7(rule);
+ size = RULESIZE7(rule);
+ if (error)
+ return error;
+ }
+ error = sooptcopyout(sopt, rule, size);
+ }
+ }
+ free(rule, M_TEMP);
+ break;
+
+ case IP_FW_DEL:
+ /*
+ * IP_FW_DEL is used for deleting single rules or sets,
+ * and (ab)used to atomically manipulate sets. Argument size
+ * is used to distinguish between the two:
+ * sizeof(u_int32_t)
+ * delete single rule or set of rules,
+ * or reassign rules (or sets) to a different set.
+ * 2*sizeof(u_int32_t)
+ * atomic disable/enable sets.
+ * first u_int32_t contains sets to be disabled,
+ * second u_int32_t contains sets to be enabled.
+ */
+ error = sooptcopyin(sopt, rulenum,
+ 2*sizeof(u_int32_t), sizeof(u_int32_t));
+ if (error)
+ break;
+ size = sopt->sopt_valsize;
+ if (size == sizeof(u_int32_t) && rulenum[0] != 0) {
+ /* delete or reassign, locking done in del_entry() */
+ error = del_entry(chain, rulenum[0]);
+ } else if (size == 2*sizeof(u_int32_t)) { /* set enable/disable */
+ IPFW_UH_WLOCK(chain);
+ V_set_disable =
+ (V_set_disable | rulenum[0]) & ~rulenum[1] &
+ ~(1<<RESVD_SET); /* set RESVD_SET always enabled */
+ IPFW_UH_WUNLOCK(chain);
+ } else
+ error = EINVAL;
+ break;
+
+ case IP_FW_ZERO:
+ case IP_FW_RESETLOG: /* argument is an u_int_32, the rule number */
+ rulenum[0] = 0;
+ if (sopt->sopt_val != 0) {
+ error = sooptcopyin(sopt, rulenum,
+ sizeof(u_int32_t), sizeof(u_int32_t));
+ if (error)
+ break;
+ }
+ error = zero_entry(chain, rulenum[0],
+ sopt->sopt_name == IP_FW_RESETLOG);
+ break;
+
+ /*--- TABLE manipulations are protected by the IPFW_LOCK ---*/
+ case IP_FW_TABLE_ADD:
+ {
+ ipfw_table_entry ent;
+
+ error = sooptcopyin(sopt, &ent,
+ sizeof(ent), sizeof(ent));
+ if (error)
+ break;
+ error = ipfw_add_table_entry(chain, ent.tbl,
+ &ent.addr, sizeof(ent.addr), ent.masklen,
+ IPFW_TABLE_CIDR, ent.value);
+ }
+ break;
+
+ case IP_FW_TABLE_DEL:
+ {
+ ipfw_table_entry ent;
+
+ error = sooptcopyin(sopt, &ent,
+ sizeof(ent), sizeof(ent));
+ if (error)
+ break;
+ error = ipfw_del_table_entry(chain, ent.tbl,
+ &ent.addr, sizeof(ent.addr), ent.masklen, IPFW_TABLE_CIDR);
+ }
+ break;
+
+ case IP_FW_TABLE_XADD: /* IP_FW3 */
+ case IP_FW_TABLE_XDEL: /* IP_FW3 */
+ {
+ ipfw_table_xentry *xent = (ipfw_table_xentry *)(op3 + 1);
+
+ /* Check minimum header size */
+ if (IP_FW3_OPLENGTH(sopt) < offsetof(ipfw_table_xentry, k)) {
+ error = EINVAL;
+ break;
+ }
+
+ /* Check if len field is valid */
+ if (xent->len > sizeof(ipfw_table_xentry)) {
+ error = EINVAL;
+ break;
+ }
+
+ len = xent->len - offsetof(ipfw_table_xentry, k);
+
+ error = (opt == IP_FW_TABLE_XADD) ?
+ ipfw_add_table_entry(chain, xent->tbl, &xent->k,
+ len, xent->masklen, xent->type, xent->value) :
+ ipfw_del_table_entry(chain, xent->tbl, &xent->k,
+ len, xent->masklen, xent->type);
+ }
+ break;
+
+ case IP_FW_TABLE_FLUSH:
+ {
+ u_int16_t tbl;
+
+ error = sooptcopyin(sopt, &tbl,
+ sizeof(tbl), sizeof(tbl));
+ if (error)
+ break;
+ error = ipfw_flush_table(chain, tbl);
+ }
+ break;
+
+ case IP_FW_TABLE_GETSIZE:
+ {
+ u_int32_t tbl, cnt;
+
+ if ((error = sooptcopyin(sopt, &tbl, sizeof(tbl),
+ sizeof(tbl))))
+ break;
+ IPFW_RLOCK(chain);
+ error = ipfw_count_table(chain, tbl, &cnt);
+ IPFW_RUNLOCK(chain);
+ if (error)
+ break;
+ error = sooptcopyout(sopt, &cnt, sizeof(cnt));
+ }
+ break;
+
+ case IP_FW_TABLE_LIST:
+ {
+ ipfw_table *tbl;
+
+ if (sopt->sopt_valsize < sizeof(*tbl)) {
+ error = EINVAL;
+ break;
+ }
+ size = sopt->sopt_valsize;
+ tbl = malloc(size, M_TEMP, M_WAITOK);
+ error = sooptcopyin(sopt, tbl, size, sizeof(*tbl));
+ if (error) {
+ free(tbl, M_TEMP);
+ break;
+ }
+ tbl->size = (size - sizeof(*tbl)) /
+ sizeof(ipfw_table_entry);
+ IPFW_RLOCK(chain);
+ error = ipfw_dump_table(chain, tbl);
+ IPFW_RUNLOCK(chain);
+ if (error) {
+ free(tbl, M_TEMP);
+ break;
+ }
+ error = sooptcopyout(sopt, tbl, size);
+ free(tbl, M_TEMP);
+ }
+ break;
+
+ case IP_FW_TABLE_XGETSIZE: /* IP_FW3 */
+ {
+ uint32_t *tbl;
+
+ if (IP_FW3_OPLENGTH(sopt) < sizeof(uint32_t)) {
+ error = EINVAL;
+ break;
+ }
+
+ tbl = (uint32_t *)(op3 + 1);
+
+ IPFW_RLOCK(chain);
+ error = ipfw_count_xtable(chain, *tbl, tbl);
+ IPFW_RUNLOCK(chain);
+ if (error)
+ break;
+ error = sooptcopyout(sopt, op3, sopt->sopt_valsize);
+ }
+ break;
+
+ case IP_FW_TABLE_XLIST: /* IP_FW3 */
+ {
+ ipfw_xtable *tbl;
+
+ if ((size = valsize) < sizeof(ipfw_xtable)) {
+ error = EINVAL;
+ break;
+ }
+
+ tbl = malloc(size, M_TEMP, M_ZERO | M_WAITOK);
+ memcpy(tbl, op3, sizeof(ipfw_xtable));
+
+ /* Get maximum number of entries we can store */
+ tbl->size = (size - sizeof(ipfw_xtable)) /
+ sizeof(ipfw_table_xentry);
+ IPFW_RLOCK(chain);
+ error = ipfw_dump_xtable(chain, tbl);
+ IPFW_RUNLOCK(chain);
+ if (error) {
+ free(tbl, M_TEMP);
+ break;
+ }
+
+ /* Revert size field back to bytes */
+ tbl->size = tbl->size * sizeof(ipfw_table_xentry) +
+ sizeof(ipfw_table);
+ /*
+ * Since we call sooptcopyin() with small buffer, sopt_valsize is
+ * decreased to reflect supplied buffer size. Set it back to original value
+ */
+ sopt->sopt_valsize = valsize;
+ error = sooptcopyout(sopt, tbl, size);
+ free(tbl, M_TEMP);
+ }
+ break;
+
+ /*--- NAT operations are protected by the IPFW_LOCK ---*/
+ case IP_FW_NAT_CFG:
+ if (IPFW_NAT_LOADED)
+ error = ipfw_nat_cfg_ptr(sopt);
+ else {
+ printf("IP_FW_NAT_CFG: %s\n",
+ "ipfw_nat not present, please load it");
+ error = EINVAL;
+ }
+ break;
+
+ case IP_FW_NAT_DEL:
+ if (IPFW_NAT_LOADED)
+ error = ipfw_nat_del_ptr(sopt);
+ else {
+ printf("IP_FW_NAT_DEL: %s\n",
+ "ipfw_nat not present, please load it");
+ error = EINVAL;
+ }
+ break;
+
+ case IP_FW_NAT_GET_CONFIG:
+ if (IPFW_NAT_LOADED)
+ error = ipfw_nat_get_cfg_ptr(sopt);
+ else {
+ printf("IP_FW_NAT_GET_CFG: %s\n",
+ "ipfw_nat not present, please load it");
+ error = EINVAL;
+ }
+ break;
+
+ case IP_FW_NAT_GET_LOG:
+ if (IPFW_NAT_LOADED)
+ error = ipfw_nat_get_log_ptr(sopt);
+ else {
+ printf("IP_FW_NAT_GET_LOG: %s\n",
+ "ipfw_nat not present, please load it");
+ error = EINVAL;
+ }
+ break;
+
+ default:
+ printf("ipfw: ipfw_ctl invalid option %d\n", sopt->sopt_name);
+ error = EINVAL;
+ }
+
+ return (error);
+#undef RULE_MAXSIZE
+}
+
+
+#define RULE_MAXSIZE (256*sizeof(u_int32_t))
+
+/* Functions to convert rules 7.2 <==> 8.0 */
+int
+convert_rule_to_7(struct ip_fw *rule)
+{
+ /* Used to modify original rule */
+ struct ip_fw7 *rule7 = (struct ip_fw7 *)rule;
+ /* copy of original rule, version 8 */
+ struct ip_fw *tmp;
+
+ /* Used to copy commands */
+ ipfw_insn *ccmd, *dst;
+ int ll = 0, ccmdlen = 0;
+
+ tmp = malloc(RULE_MAXSIZE, M_TEMP, M_NOWAIT | M_ZERO);
+ if (tmp == NULL) {
+ return 1; //XXX error
+ }
+ bcopy(rule, tmp, RULE_MAXSIZE);
+
+ /* Copy fields */
+ rule7->_pad = tmp->_pad;
+ rule7->set = tmp->set;
+ rule7->rulenum = tmp->rulenum;
+ rule7->cmd_len = tmp->cmd_len;
+ rule7->act_ofs = tmp->act_ofs;
+ rule7->next_rule = (struct ip_fw7 *)tmp->next_rule;
+ rule7->next = (struct ip_fw7 *)tmp->x_next;
+ rule7->cmd_len = tmp->cmd_len;
+ rule7->pcnt = tmp->pcnt;
+ rule7->bcnt = tmp->bcnt;
+ rule7->timestamp = tmp->timestamp;
+
+ /* Copy commands */
+ for (ll = tmp->cmd_len, ccmd = tmp->cmd, dst = rule7->cmd ;
+ ll > 0 ; ll -= ccmdlen, ccmd += ccmdlen, dst += ccmdlen) {
+ ccmdlen = F_LEN(ccmd);
+
+ bcopy(ccmd, dst, F_LEN(ccmd)*sizeof(uint32_t));
+
+ if (dst->opcode > O_NAT)
+ /* O_REASS doesn't exists in 7.2 version, so
+ * decrement opcode if it is after O_REASS
+ */
+ dst->opcode--;
+
+ if (ccmdlen > ll) {
+ printf("ipfw: opcode %d size truncated\n",
+ ccmd->opcode);
+ return EINVAL;
+ }
+ }
+ free(tmp, M_TEMP);
+
+ return 0;
+}
+
+int
+convert_rule_to_8(struct ip_fw *rule)
+{
+ /* Used to modify original rule */
+ struct ip_fw7 *rule7 = (struct ip_fw7 *) rule;
+
+ /* Used to copy commands */
+ ipfw_insn *ccmd, *dst;
+ int ll = 0, ccmdlen = 0;
+
+ /* Copy of original rule */
+ struct ip_fw7 *tmp = malloc(RULE_MAXSIZE, M_TEMP, M_NOWAIT | M_ZERO);
+ if (tmp == NULL) {
+ return 1; //XXX error
+ }
+
+ bcopy(rule7, tmp, RULE_MAXSIZE);
+
+ for (ll = tmp->cmd_len, ccmd = tmp->cmd, dst = rule->cmd ;
+ ll > 0 ; ll -= ccmdlen, ccmd += ccmdlen, dst += ccmdlen) {
+ ccmdlen = F_LEN(ccmd);
+
+ bcopy(ccmd, dst, F_LEN(ccmd)*sizeof(uint32_t));
+
+ if (dst->opcode > O_NAT)
+ /* O_REASS doesn't exists in 7.2 version, so
+ * increment opcode if it is after O_REASS
+ */
+ dst->opcode++;
+
+ if (ccmdlen > ll) {
+ printf("ipfw: opcode %d size truncated\n",
+ ccmd->opcode);
+ return EINVAL;
+ }
+ }
+
+ rule->_pad = tmp->_pad;
+ rule->set = tmp->set;
+ rule->rulenum = tmp->rulenum;
+ rule->cmd_len = tmp->cmd_len;
+ rule->act_ofs = tmp->act_ofs;
+ rule->next_rule = (struct ip_fw *)tmp->next_rule;
+ rule->x_next = (struct ip_fw *)tmp->next;
+ rule->cmd_len = tmp->cmd_len;
+ rule->id = 0; /* XXX see if is ok = 0 */
+ rule->pcnt = tmp->pcnt;
+ rule->bcnt = tmp->bcnt;
+ rule->timestamp = tmp->timestamp;
+
+ free (tmp, M_TEMP);
+ return 0;
+}
+
+/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_table.c b/sys/netinet/ipfw/ip_fw_table.c
new file mode 100644
index 0000000..597817b
--- /dev/null
+++ b/sys/netinet/ipfw/ip_fw_table.c
@@ -0,0 +1,758 @@
+/*-
+ * Copyright (c) 2004 Ruslan Ermilov and Vsevolod Lobko.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Lookup table support for ipfw
+ *
+ * Lookup tables are implemented (at the moment) using the radix
+ * tree used for routing tables. Tables store key-value entries, where
+ * keys are network prefixes (addr/masklen), and values are integers.
+ * As a degenerate case we can interpret keys as 32-bit integers
+ * (with a /32 mask).
+ *
+ * The table is protected by the IPFW lock even for manipulation coming
+ * from userland, because operations are typically fast.
+ */
+
+#include "opt_ipfw.h"
+#include "opt_inet.h"
+#ifndef INET
+#error IPFIREWALL requires INET.
+#endif /* INET */
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#include <sys/socket.h>
+#include <net/if.h> /* ip_fw.h requires IFNAMSIZ */
+#include <net/radix.h>
+#include <net/route.h>
+#include <net/vnet.h>
+
+#include <netinet/in.h>
+#include <netinet/ip_var.h> /* struct ipfw_rule_ref */
+#include <netinet/ip_fw.h>
+#include <sys/queue.h> /* LIST_HEAD */
+#include <netinet/ipfw/ip_fw_private.h>
+
+#ifdef MAC
+#include <security/mac/mac_framework.h>
+#endif
+
+static MALLOC_DEFINE(M_IPFW_TBL, "ipfw_tbl", "IpFw tables");
+
+struct table_entry {
+ struct radix_node rn[2];
+ struct sockaddr_in addr, mask;
+ u_int32_t value;
+};
+
+struct xaddr_iface {
+ uint8_t if_len; /* length of this struct */
+ uint8_t pad[7]; /* Align name */
+ char ifname[IF_NAMESIZE]; /* Interface name */
+};
+
+struct table_xentry {
+ struct radix_node rn[2];
+ union {
+#ifdef INET6
+ struct sockaddr_in6 addr6;
+#endif
+ struct xaddr_iface iface;
+ } a;
+ union {
+#ifdef INET6
+ struct sockaddr_in6 mask6;
+#endif
+ struct xaddr_iface ifmask;
+ } m;
+ u_int32_t value;
+};
+
+/*
+ * The radix code expects addr and mask to be array of bytes,
+ * with the first byte being the length of the array. rn_inithead
+ * is called with the offset in bits of the lookup key within the
+ * array. If we use a sockaddr_in as the underlying type,
+ * sin_len is conveniently located at offset 0, sin_addr is at
+ * offset 4 and normally aligned.
+ * But for portability, let's avoid assumption and make the code explicit
+ */
+#define KEY_LEN(v) *((uint8_t *)&(v))
+#define KEY_OFS (8*offsetof(struct sockaddr_in, sin_addr))
+/*
+ * Do not require radix to compare more than actual IPv4/IPv6 address
+ */
+#define KEY_LEN_INET (offsetof(struct sockaddr_in, sin_addr) + sizeof(in_addr_t))
+#define KEY_LEN_INET6 (offsetof(struct sockaddr_in6, sin6_addr) + sizeof(struct in6_addr))
+#define KEY_LEN_IFACE (offsetof(struct xaddr_iface, ifname))
+
+#define OFF_LEN_INET (8 * offsetof(struct sockaddr_in, sin_addr))
+#define OFF_LEN_INET6 (8 * offsetof(struct sockaddr_in6, sin6_addr))
+#define OFF_LEN_IFACE (8 * offsetof(struct xaddr_iface, ifname))
+
+
+static inline void
+ipv6_writemask(struct in6_addr *addr6, uint8_t mask)
+{
+ uint32_t *cp;
+
+ for (cp = (uint32_t *)addr6; mask >= 32; mask -= 32)
+ *cp++ = 0xFFFFFFFF;
+ *cp = htonl(mask ? ~((1 << (32 - mask)) - 1) : 0);
+}
+
+int
+ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
+ uint8_t plen, uint8_t mlen, uint8_t type, uint32_t value)
+{
+ struct radix_node_head *rnh, **rnh_ptr;
+ struct table_entry *ent;
+ struct table_xentry *xent;
+ struct radix_node *rn;
+ in_addr_t addr;
+ int offset;
+ void *ent_ptr;
+ struct sockaddr *addr_ptr, *mask_ptr;
+ char c;
+
+ if (tbl >= V_fw_tables_max)
+ return (EINVAL);
+
+ switch (type) {
+ case IPFW_TABLE_CIDR:
+ if (plen == sizeof(in_addr_t)) {
+#ifdef INET
+ /* IPv4 case */
+ if (mlen > 32)
+ return (EINVAL);
+ ent = malloc(sizeof(*ent), M_IPFW_TBL, M_WAITOK | M_ZERO);
+ ent->value = value;
+ /* Set 'total' structure length */
+ KEY_LEN(ent->addr) = KEY_LEN_INET;
+ KEY_LEN(ent->mask) = KEY_LEN_INET;
+ /* Set offset of IPv4 address in bits */
+ offset = OFF_LEN_INET;
+ ent->mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
+ addr = *((in_addr_t *)paddr);
+ ent->addr.sin_addr.s_addr = addr & ent->mask.sin_addr.s_addr;
+ /* Set pointers */
+ rnh_ptr = &ch->tables[tbl];
+ ent_ptr = ent;
+ addr_ptr = (struct sockaddr *)&ent->addr;
+ mask_ptr = (struct sockaddr *)&ent->mask;
+#endif
+#ifdef INET6
+ } else if (plen == sizeof(struct in6_addr)) {
+ /* IPv6 case */
+ if (mlen > 128)
+ return (EINVAL);
+ xent = malloc(sizeof(*xent), M_IPFW_TBL, M_WAITOK | M_ZERO);
+ xent->value = value;
+ /* Set 'total' structure length */
+ KEY_LEN(xent->a.addr6) = KEY_LEN_INET6;
+ KEY_LEN(xent->m.mask6) = KEY_LEN_INET6;
+ /* Set offset of IPv6 address in bits */
+ offset = OFF_LEN_INET6;
+ ipv6_writemask(&xent->m.mask6.sin6_addr, mlen);
+ memcpy(&xent->a.addr6.sin6_addr, paddr, sizeof(struct in6_addr));
+ APPLY_MASK(&xent->a.addr6.sin6_addr, &xent->m.mask6.sin6_addr);
+ /* Set pointers */
+ rnh_ptr = &ch->xtables[tbl];
+ ent_ptr = xent;
+ addr_ptr = (struct sockaddr *)&xent->a.addr6;
+ mask_ptr = (struct sockaddr *)&xent->m.mask6;
+#endif
+ } else {
+ /* Unknown CIDR type */
+ return (EINVAL);
+ }
+ break;
+
+ case IPFW_TABLE_INTERFACE:
+ /* Check if string is terminated */
+ c = ((char *)paddr)[IF_NAMESIZE - 1];
+ ((char *)paddr)[IF_NAMESIZE - 1] = '\0';
+ if (((mlen = strlen((char *)paddr)) == IF_NAMESIZE - 1) && (c != '\0'))
+ return (EINVAL);
+
+ /* Include last \0 into comparison */
+ mlen++;
+
+ xent = malloc(sizeof(*xent), M_IPFW_TBL, M_WAITOK | M_ZERO);
+ xent->value = value;
+ /* Set 'total' structure length */
+ KEY_LEN(xent->a.iface) = KEY_LEN_IFACE + mlen;
+ KEY_LEN(xent->m.ifmask) = KEY_LEN_IFACE + mlen;
+ /* Set offset of interface name in bits */
+ offset = OFF_LEN_IFACE;
+ memcpy(xent->a.iface.ifname, paddr, mlen);
+ /* Assume direct match */
+ /* TODO: Add interface pattern matching */
+#if 0
+ memset(xent->m.ifmask.ifname, 0xFF, IF_NAMESIZE);
+ mask_ptr = (struct sockaddr *)&xent->m.ifmask;
+#endif
+ /* Set pointers */
+ rnh_ptr = &ch->xtables[tbl];
+ ent_ptr = xent;
+ addr_ptr = (struct sockaddr *)&xent->a.iface;
+ mask_ptr = NULL;
+ break;
+
+ default:
+ return (EINVAL);
+ }
+
+ IPFW_WLOCK(ch);
+
+ /* Check if tabletype is valid */
+ if ((ch->tabletype[tbl] != 0) && (ch->tabletype[tbl] != type)) {
+ IPFW_WUNLOCK(ch);
+ free(ent_ptr, M_IPFW_TBL);
+ return (EINVAL);
+ }
+
+ /* Check if radix tree exists */
+ if ((rnh = *rnh_ptr) == NULL) {
+ IPFW_WUNLOCK(ch);
+ /* Create radix for a new table */
+ if (!rn_inithead((void **)&rnh, offset)) {
+ free(ent_ptr, M_IPFW_TBL);
+ return (ENOMEM);
+ }
+
+ IPFW_WLOCK(ch);
+ if (*rnh_ptr != NULL) {
+ /* Tree is already attached by other thread */
+ rn_detachhead((void **)&rnh);
+ rnh = *rnh_ptr;
+ /* Check table type another time */
+ if (ch->tabletype[tbl] != type) {
+ IPFW_WUNLOCK(ch);
+ free(ent_ptr, M_IPFW_TBL);
+ return (EINVAL);
+ }
+ } else {
+ *rnh_ptr = rnh;
+ /*
+ * Set table type. It can be set already
+ * (if we have IPv6-only table) but setting
+ * it another time does not hurt
+ */
+ ch->tabletype[tbl] = type;
+ }
+ }
+
+ rn = rnh->rnh_addaddr(addr_ptr, mask_ptr, rnh, ent_ptr);
+ IPFW_WUNLOCK(ch);
+
+ if (rn == NULL) {
+ free(ent_ptr, M_IPFW_TBL);
+ return (EEXIST);
+ }
+ return (0);
+}
+
+int
+ipfw_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
+ uint8_t plen, uint8_t mlen, uint8_t type)
+{
+ struct radix_node_head *rnh, **rnh_ptr;
+ struct table_entry *ent;
+ in_addr_t addr;
+ struct sockaddr_in sa, mask;
+ struct sockaddr *sa_ptr, *mask_ptr;
+ char c;
+
+ if (tbl >= V_fw_tables_max)
+ return (EINVAL);
+
+ switch (type) {
+ case IPFW_TABLE_CIDR:
+ if (plen == sizeof(in_addr_t)) {
+ /* Set 'total' structure length */
+ KEY_LEN(sa) = KEY_LEN_INET;
+ KEY_LEN(mask) = KEY_LEN_INET;
+ mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
+ addr = *((in_addr_t *)paddr);
+ sa.sin_addr.s_addr = addr & mask.sin_addr.s_addr;
+ rnh_ptr = &ch->tables[tbl];
+ sa_ptr = (struct sockaddr *)&sa;
+ mask_ptr = (struct sockaddr *)&mask;
+#ifdef INET6
+ } else if (plen == sizeof(struct in6_addr)) {
+ /* IPv6 case */
+ if (mlen > 128)
+ return (EINVAL);
+ struct sockaddr_in6 sa6, mask6;
+ memset(&sa6, 0, sizeof(struct sockaddr_in6));
+ memset(&mask6, 0, sizeof(struct sockaddr_in6));
+ /* Set 'total' structure length */
+ KEY_LEN(sa6) = KEY_LEN_INET6;
+ KEY_LEN(mask6) = KEY_LEN_INET6;
+ ipv6_writemask(&mask6.sin6_addr, mlen);
+ memcpy(&sa6.sin6_addr, paddr, sizeof(struct in6_addr));
+ APPLY_MASK(&sa6.sin6_addr, &mask6.sin6_addr);
+ rnh_ptr = &ch->xtables[tbl];
+ sa_ptr = (struct sockaddr *)&sa6;
+ mask_ptr = (struct sockaddr *)&mask6;
+#endif
+ } else {
+ /* Unknown CIDR type */
+ return (EINVAL);
+ }
+ break;
+
+ case IPFW_TABLE_INTERFACE:
+ /* Check if string is terminated */
+ c = ((char *)paddr)[IF_NAMESIZE - 1];
+ ((char *)paddr)[IF_NAMESIZE - 1] = '\0';
+ if (((mlen = strlen((char *)paddr)) == IF_NAMESIZE - 1) && (c != '\0'))
+ return (EINVAL);
+
+ struct xaddr_iface ifname, ifmask;
+ memset(&ifname, 0, sizeof(ifname));
+
+ /* Set 'total' structure length */
+ KEY_LEN(ifname) = mlen;
+ KEY_LEN(ifmask) = mlen;
+ /* Assume direct match */
+ /* FIXME: Add interface pattern matching */
+#if 0
+ memset(ifmask.ifname, 0xFF, IF_NAMESIZE);
+ mask_ptr = (struct sockaddr *)&ifmask;
+#endif
+ mask_ptr = NULL;
+ memcpy(ifname.ifname, paddr, mlen);
+ /* Set pointers */
+ rnh_ptr = &ch->xtables[tbl];
+ sa_ptr = (struct sockaddr *)&ifname;
+
+ break;
+
+ default:
+ return (EINVAL);
+ }
+
+ IPFW_WLOCK(ch);
+ if ((rnh = *rnh_ptr) == NULL) {
+ IPFW_WUNLOCK(ch);
+ return (ESRCH);
+ }
+
+ if (ch->tabletype[tbl] != type) {
+ IPFW_WUNLOCK(ch);
+ return (EINVAL);
+ }
+
+ ent = (struct table_entry *)rnh->rnh_deladdr(sa_ptr, mask_ptr, rnh);
+ IPFW_WUNLOCK(ch);
+
+ if (ent == NULL)
+ return (ESRCH);
+
+ free(ent, M_IPFW_TBL);
+ return (0);
+}
+
+static int
+flush_table_entry(struct radix_node *rn, void *arg)
+{
+ struct radix_node_head * const rnh = arg;
+ struct table_entry *ent;
+
+ ent = (struct table_entry *)
+ rnh->rnh_deladdr(rn->rn_key, rn->rn_mask, rnh);
+ if (ent != NULL)
+ free(ent, M_IPFW_TBL);
+ return (0);
+}
+
+int
+ipfw_flush_table(struct ip_fw_chain *ch, uint16_t tbl)
+{
+ struct radix_node_head *rnh, *xrnh;
+
+ if (tbl >= V_fw_tables_max)
+ return (EINVAL);
+
+ /*
+ * We free both (IPv4 and extended) radix trees and
+ * clear table type here to permit table to be reused
+ * for different type without module reload
+ */
+
+ IPFW_WLOCK(ch);
+ /* Set IPv4 table pointer to zero */
+ if ((rnh = ch->tables[tbl]) != NULL)
+ ch->tables[tbl] = NULL;
+ /* Set extended table pointer to zero */
+ if ((xrnh = ch->xtables[tbl]) != NULL)
+ ch->xtables[tbl] = NULL;
+ /* Zero table type */
+ ch->tabletype[tbl] = 0;
+ IPFW_WUNLOCK(ch);
+
+ if (rnh != NULL) {
+ rnh->rnh_walktree(rnh, flush_table_entry, rnh);
+ rn_detachhead((void **)&rnh);
+ }
+
+ if (xrnh != NULL) {
+ xrnh->rnh_walktree(xrnh, flush_table_entry, xrnh);
+ rn_detachhead((void **)&xrnh);
+ }
+
+ return (0);
+}
+
+void
+ipfw_destroy_tables(struct ip_fw_chain *ch)
+{
+ uint16_t tbl;
+
+ /* Flush all tables */
+ for (tbl = 0; tbl < V_fw_tables_max; tbl++)
+ ipfw_flush_table(ch, tbl);
+
+ /* Free pointers itself */
+ free(ch->tables, M_IPFW);
+ free(ch->xtables, M_IPFW);
+ free(ch->tabletype, M_IPFW);
+}
+
+int
+ipfw_init_tables(struct ip_fw_chain *ch)
+{
+ /* Allocate pointers */
+ ch->tables = malloc(V_fw_tables_max * sizeof(void *), M_IPFW, M_WAITOK | M_ZERO);
+ ch->xtables = malloc(V_fw_tables_max * sizeof(void *), M_IPFW, M_WAITOK | M_ZERO);
+ ch->tabletype = malloc(V_fw_tables_max * sizeof(uint8_t), M_IPFW, M_WAITOK | M_ZERO);
+ return (0);
+}
+
+int
+ipfw_resize_tables(struct ip_fw_chain *ch, unsigned int ntables)
+{
+ struct radix_node_head **tables, **xtables, *rnh;
+ struct radix_node_head **tables_old, **xtables_old;
+ uint8_t *tabletype, *tabletype_old;
+ unsigned int ntables_old, tbl;
+
+ /* Check new value for validity */
+ if (ntables > IPFW_TABLES_MAX)
+ ntables = IPFW_TABLES_MAX;
+
+ /* Allocate new pointers */
+ tables = malloc(ntables * sizeof(void *), M_IPFW, M_WAITOK | M_ZERO);
+ xtables = malloc(ntables * sizeof(void *), M_IPFW, M_WAITOK | M_ZERO);
+ tabletype = malloc(ntables * sizeof(uint8_t), M_IPFW, M_WAITOK | M_ZERO);
+
+ IPFW_WLOCK(ch);
+
+ tbl = (ntables >= V_fw_tables_max) ? V_fw_tables_max : ntables;
+
+ /* Copy old table pointers */
+ memcpy(tables, ch->tables, sizeof(void *) * tbl);
+ memcpy(xtables, ch->xtables, sizeof(void *) * tbl);
+ memcpy(tabletype, ch->tabletype, sizeof(uint8_t) * tbl);
+
+ /* Change pointers and number of tables */
+ tables_old = ch->tables;
+ xtables_old = ch->xtables;
+ tabletype_old = ch->tabletype;
+ ch->tables = tables;
+ ch->xtables = xtables;
+ ch->tabletype = tabletype;
+
+ ntables_old = V_fw_tables_max;
+ V_fw_tables_max = ntables;
+
+ IPFW_WUNLOCK(ch);
+
+ /* Check if we need to destroy radix trees */
+ if (ntables < ntables_old) {
+ for (tbl = ntables; tbl < ntables_old; tbl++) {
+ if ((rnh = tables_old[tbl]) != NULL) {
+ rnh->rnh_walktree(rnh, flush_table_entry, rnh);
+ rn_detachhead((void **)&rnh);
+ }
+
+ if ((rnh = xtables_old[tbl]) != NULL) {
+ rnh->rnh_walktree(rnh, flush_table_entry, rnh);
+ rn_detachhead((void **)&rnh);
+ }
+ }
+ }
+
+ /* Free old pointers */
+ free(tables_old, M_IPFW);
+ free(xtables_old, M_IPFW);
+ free(tabletype_old, M_IPFW);
+
+ return (0);
+}
+
+int
+ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
+ uint32_t *val)
+{
+ struct radix_node_head *rnh;
+ struct table_entry *ent;
+ struct sockaddr_in sa;
+
+ if (tbl >= V_fw_tables_max)
+ return (0);
+ if ((rnh = ch->tables[tbl]) == NULL)
+ return (0);
+ KEY_LEN(sa) = KEY_LEN_INET;
+ sa.sin_addr.s_addr = addr;
+ ent = (struct table_entry *)(rnh->rnh_lookup(&sa, NULL, rnh));
+ if (ent != NULL) {
+ *val = ent->value;
+ return (1);
+ }
+ return (0);
+}
+
+int
+ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
+ uint32_t *val, int type)
+{
+ struct radix_node_head *rnh;
+ struct table_xentry *xent;
+ struct sockaddr_in6 sa6;
+ struct xaddr_iface iface;
+
+ if (tbl >= V_fw_tables_max)
+ return (0);
+ if ((rnh = ch->xtables[tbl]) == NULL)
+ return (0);
+
+ switch (type) {
+ case IPFW_TABLE_CIDR:
+ KEY_LEN(sa6) = KEY_LEN_INET6;
+ memcpy(&sa6.sin6_addr, paddr, sizeof(struct in6_addr));
+ xent = (struct table_xentry *)(rnh->rnh_lookup(&sa6, NULL, rnh));
+ break;
+
+ case IPFW_TABLE_INTERFACE:
+ KEY_LEN(iface) = KEY_LEN_IFACE +
+ strlcpy(iface.ifname, (char *)paddr, IF_NAMESIZE);
+ /* Assume direct match */
+ /* FIXME: Add interface pattern matching */
+ xent = (struct table_xentry *)(rnh->rnh_lookup(&iface, NULL, rnh));
+ break;
+
+ default:
+ return (0);
+ }
+
+ if (xent != NULL) {
+ *val = xent->value;
+ return (1);
+ }
+ return (0);
+}
+
+static int
+count_table_entry(struct radix_node *rn, void *arg)
+{
+ u_int32_t * const cnt = arg;
+
+ (*cnt)++;
+ return (0);
+}
+
+int
+ipfw_count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt)
+{
+ struct radix_node_head *rnh;
+
+ if (tbl >= V_fw_tables_max)
+ return (EINVAL);
+ *cnt = 0;
+ if ((rnh = ch->tables[tbl]) == NULL)
+ return (0);
+ rnh->rnh_walktree(rnh, count_table_entry, cnt);
+ return (0);
+}
+
+static int
+dump_table_entry(struct radix_node *rn, void *arg)
+{
+ struct table_entry * const n = (struct table_entry *)rn;
+ ipfw_table * const tbl = arg;
+ ipfw_table_entry *ent;
+
+ if (tbl->cnt == tbl->size)
+ return (1);
+ ent = &tbl->ent[tbl->cnt];
+ ent->tbl = tbl->tbl;
+ if (in_nullhost(n->mask.sin_addr))
+ ent->masklen = 0;
+ else
+ ent->masklen = 33 - ffs(ntohl(n->mask.sin_addr.s_addr));
+ ent->addr = n->addr.sin_addr.s_addr;
+ ent->value = n->value;
+ tbl->cnt++;
+ return (0);
+}
+
+int
+ipfw_dump_table(struct ip_fw_chain *ch, ipfw_table *tbl)
+{
+ struct radix_node_head *rnh;
+
+ if (tbl->tbl >= V_fw_tables_max)
+ return (EINVAL);
+ tbl->cnt = 0;
+ if ((rnh = ch->tables[tbl->tbl]) == NULL)
+ return (0);
+ rnh->rnh_walktree(rnh, dump_table_entry, tbl);
+ return (0);
+}
+
+static int
+count_table_xentry(struct radix_node *rn, void *arg)
+{
+ uint32_t * const cnt = arg;
+
+ (*cnt) += sizeof(ipfw_table_xentry);
+ return (0);
+}
+
+int
+ipfw_count_xtable(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt)
+{
+ struct radix_node_head *rnh;
+
+ if (tbl >= V_fw_tables_max)
+ return (EINVAL);
+ *cnt = 0;
+ if ((rnh = ch->tables[tbl]) != NULL)
+ rnh->rnh_walktree(rnh, count_table_xentry, cnt);
+ if ((rnh = ch->xtables[tbl]) != NULL)
+ rnh->rnh_walktree(rnh, count_table_xentry, cnt);
+ /* Return zero if table is empty */
+ if (*cnt > 0)
+ (*cnt) += sizeof(ipfw_xtable);
+ return (0);
+}
+
+
+static int
+dump_table_xentry_base(struct radix_node *rn, void *arg)
+{
+ struct table_entry * const n = (struct table_entry *)rn;
+ ipfw_xtable * const tbl = arg;
+ ipfw_table_xentry *xent;
+
+ /* Out of memory, returning */
+ if (tbl->cnt == tbl->size)
+ return (1);
+ xent = &tbl->xent[tbl->cnt];
+ xent->len = sizeof(ipfw_table_xentry);
+ xent->tbl = tbl->tbl;
+ if (in_nullhost(n->mask.sin_addr))
+ xent->masklen = 0;
+ else
+ xent->masklen = 33 - ffs(ntohl(n->mask.sin_addr.s_addr));
+ /* Save IPv4 address as deprecated IPv6 compatible */
+ xent->k.addr6.s6_addr32[3] = n->addr.sin_addr.s_addr;
+ xent->value = n->value;
+ tbl->cnt++;
+ return (0);
+}
+
+static int
+dump_table_xentry_extended(struct radix_node *rn, void *arg)
+{
+ struct table_xentry * const n = (struct table_xentry *)rn;
+ ipfw_xtable * const tbl = arg;
+ ipfw_table_xentry *xent;
+#ifdef INET6
+ int i;
+ uint32_t *v;
+#endif
+ /* Out of memory, returning */
+ if (tbl->cnt == tbl->size)
+ return (1);
+ xent = &tbl->xent[tbl->cnt];
+ xent->len = sizeof(ipfw_table_xentry);
+ xent->tbl = tbl->tbl;
+
+ switch (tbl->type) {
+#ifdef INET6
+ case IPFW_TABLE_CIDR:
+ /* Count IPv6 mask */
+ v = (uint32_t *)&n->m.mask6.sin6_addr;
+ for (i = 0; i < sizeof(struct in6_addr) / 4; i++, v++)
+ xent->masklen += bitcount32(*v);
+ memcpy(&xent->k, &n->a.addr6.sin6_addr, sizeof(struct in6_addr));
+ break;
+#endif
+ case IPFW_TABLE_INTERFACE:
+ /* Assume exact mask */
+ xent->masklen = 8 * IF_NAMESIZE;
+ memcpy(&xent->k, &n->a.iface.ifname, IF_NAMESIZE);
+ break;
+
+ default:
+ /* unknown, skip entry */
+ return (0);
+ }
+
+ xent->value = n->value;
+ tbl->cnt++;
+ return (0);
+}
+
+int
+ipfw_dump_xtable(struct ip_fw_chain *ch, ipfw_xtable *tbl)
+{
+ struct radix_node_head *rnh;
+
+ if (tbl->tbl >= V_fw_tables_max)
+ return (EINVAL);
+ tbl->cnt = 0;
+ tbl->type = ch->tabletype[tbl->tbl];
+ if ((rnh = ch->tables[tbl->tbl]) != NULL)
+ rnh->rnh_walktree(rnh, dump_table_xentry_base, tbl);
+ if ((rnh = ch->xtables[tbl->tbl]) != NULL)
+ rnh->rnh_walktree(rnh, dump_table_xentry_extended, tbl);
+ return (0);
+}
+
+/* end of file */
diff --git a/sys/netinet/ipfw/test/Makefile b/sys/netinet/ipfw/test/Makefile
new file mode 100644
index 0000000..c556a4b
--- /dev/null
+++ b/sys/netinet/ipfw/test/Makefile
@@ -0,0 +1,51 @@
+#
+# $FreeBSD$
+#
+# Makefile for building userland tests
+# this is written in a form compatible with gmake
+
+SCHED_SRCS = test_dn_sched.c
+SCHED_SRCS += dn_sched_fifo.c
+SCHED_SRCS += dn_sched_prio.c
+SCHED_SRCS += dn_sched_qfq.c
+SCHED_SRCS += dn_sched_rr.c
+SCHED_SRCS += dn_sched_wf2q.c
+SCHED_SRCS += dn_heap.c
+SCHED_SRCS += main.c
+
+SCHED_OBJS=$(SCHED_SRCS:.c=.o)
+
+HEAP_SRCS = dn_heap.c test_dn_heap.c
+HEAP_OBJS=$(HEAP_SRCS:.c=.o)
+
+VPATH= .:..
+
+CFLAGS = -I.. -I. -Wall -Werror -O3 -DIPFW
+TARGETS= test_sched # no test_heap by default
+
+all: $(TARGETS)
+
+test_heap : $(HEAP_OBJS)
+ $(CC) -o $@ $(HEAP_OBJS)
+
+test_sched : $(SCHED_OBJS)
+ $(CC) -o $@ $(SCHED_OBJS)
+
+$(SCHED_OBJS): dn_test.h
+main.o: mylist.h
+
+clean:
+ - rm *.o $(TARGETS) *.core
+
+ALLSRCS = $(SCHED_SRCS) dn_test.h mylist.h \
+ dn_sched.h dn_heap.h ip_dn_private.h Makefile
+TMPBASE = /tmp/testXYZ
+TMPDIR = $(TMPBASE)/test
+
+tgz:
+ -rm -rf $(TMPDIR)
+ mkdir -p $(TMPDIR)
+ -cp -p $(ALLSRCS) $(TMPDIR)
+ -(cd ..; cp -p $(ALLSRCS) $(TMPDIR))
+ ls -la $(TMPDIR)
+ (cd $(TMPBASE); tar cvzf /tmp/test.tgz test)
diff --git a/sys/netinet/ipfw/test/dn_test.h b/sys/netinet/ipfw/test/dn_test.h
new file mode 100644
index 0000000..4e079bc
--- /dev/null
+++ b/sys/netinet/ipfw/test/dn_test.h
@@ -0,0 +1,175 @@
+/*
+ * $FreeBSD$
+ *
+ * userspace compatibility code for dummynet schedulers
+ */
+
+#ifndef _DN_TEST_H
+#define _DN_TEST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h> /* bzero, ffs, ... */
+#include <string.h> /* strcmp */
+#include <errno.h>
+#include <sys/queue.h>
+#include <sys/time.h>
+
+extern int debug;
+#define ND(fmt, args...) do {} while (0)
+#define D1(fmt, args...) do {} while (0)
+#define D(fmt, args...) fprintf(stderr, "%-8s " fmt "\n", \
+ __FUNCTION__, ## args)
+#define DX(lev, fmt, args...) do { \
+ if (debug > lev) D(fmt, ## args); } while (0)
+
+
+#ifndef offsetof
+#define offsetof(t,m) (int)((&((t *)0L)->m))
+#endif
+
+#include <mylist.h>
+
+/* prevent include of other system headers */
+#define _NETINET_IP_VAR_H_ /* ip_fw_args */
+#define _IPFW2_H
+#define _SYS_MBUF_H_
+
+enum {
+ DN_QUEUE,
+};
+
+enum {
+ DN_SCHED_FIFO,
+ DN_SCHED_WF2QP,
+};
+
+struct dn_id {
+ int type, subtype, len, id;
+};
+
+struct dn_fs {
+ int par[4]; /* flowset parameters */
+
+ /* simulation entries.
+ * 'index' is not strictly necessary
+ * y is used for the inverse mapping ,
+ */
+ int index;
+ int y; /* inverse mapping */
+ int base_y; /* inverse mapping */
+ int next_y; /* inverse mapping */
+ int n_flows;
+ int first_flow;
+ int next_flow; /* first_flow + n_flows */
+ /*
+ * when generating, let 'cur' go from 0 to n_flows-1,
+ * then point to flow first_flow + cur
+ */
+ int cur;
+};
+
+struct dn_sch {
+};
+
+struct dn_flow {
+ struct dn_id oid;
+ int length;
+ int len_bytes;
+ int drops;
+ uint64_t tot_bytes;
+ uint32_t flow_id;
+ struct list_head h; /* used by the generator */
+};
+
+struct dn_link {
+};
+
+struct ip_fw_args {
+};
+
+struct mbuf {
+ struct {
+ int len;
+ } m_pkthdr;
+ struct mbuf *m_nextpkt;
+ int flow_id; /* for testing, index of a flow */
+ //int flowset_id; /* for testing, index of a flowset */
+ void *cfg; /* config args */
+};
+
+#define MALLOC_DECLARE(x)
+#define KASSERT(x, y) do { if (!(x)) printf y ; exit(0); } while (0)
+struct ipfw_flow_id {
+};
+
+typedef void * module_t;
+
+struct _md_t {
+ const char *name;
+ int (*f)(module_t, int, void *);
+ void *p;
+};
+
+typedef struct _md_t moduledata_t;
+
+#define DECLARE_MODULE(name, b, c, d) \
+ moduledata_t *_g_##name = & b
+#define MODULE_DEPEND(a, b, c, d, e)
+
+#ifdef IPFW
+#include <dn_heap.h>
+#include <ip_dn_private.h>
+#include <dn_sched.h>
+#else
+struct dn_queue {
+ struct dn_fsk *fs; /* parent flowset. */
+ struct dn_sch_inst *_si; /* parent sched instance. */
+};
+struct dn_schk {
+};
+struct dn_fsk {
+ struct dn_fs fs;
+ struct dn_schk *sched;
+};
+struct dn_sch_inst {
+ struct dn_schk *sched;
+};
+struct dn_alg {
+ int type;
+ const char *name;
+ void *enqueue, *dequeue;
+ int q_datalen, si_datalen, schk_datalen;
+ int (*config)(struct dn_schk *);
+ int (*new_sched)(struct dn_sch_inst *);
+ int (*new_fsk)(struct dn_fsk *);
+ int (*new_queue)(struct dn_queue *q);
+};
+
+#endif
+
+#ifndef __FreeBSD__
+int fls(int);
+#endif
+
+static inline void
+mq_append(struct mq *q, struct mbuf *m)
+{
+ if (q->head == NULL)
+ q->head = m;
+ else
+ q->tail->m_nextpkt = m;
+ q->tail = m;
+ m->m_nextpkt = NULL;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DN_TEST_H */
diff --git a/sys/netinet/ipfw/test/main.c b/sys/netinet/ipfw/test/main.c
new file mode 100644
index 0000000..be9fdf5
--- /dev/null
+++ b/sys/netinet/ipfw/test/main.c
@@ -0,0 +1,636 @@
+/*
+ * $FreeBSD$
+ *
+ * Testing program for schedulers
+ *
+ * The framework include a simple controller which, at each
+ * iteration, decides whether we can enqueue and/or dequeue.
+ * Then the mainloop runs the required number of tests,
+ * keeping track of statistics.
+ */
+
+#include "dn_test.h"
+
+struct q_list {
+ struct list_head h;
+};
+
+struct cfg_s {
+ int ac;
+ char * const *av;
+
+ const char *name;
+ int loops;
+ struct timeval time;
+
+ /* running counters */
+ uint32_t _enqueue;
+ uint32_t drop;
+ uint32_t pending;
+ uint32_t dequeue;
+
+ /* generator parameters */
+ int th_min, th_max;
+ int maxburst;
+ int lmin, lmax; /* packet len */
+ int flows; /* number of flows */
+ int flowsets; /* number of flowsets */
+ int wsum; /* sum of weights of all flows */
+ int max_y; /* max random number in the generation */
+ int cur_y, cur_fs; /* used in generation, between 0 and max_y - 1 */
+ const char *fs_config; /* flowset config */
+ int can_dequeue;
+ int burst; /* count of packets sent in a burst */
+ struct mbuf *tosend; /* packet to send -- also flag to enqueue */
+
+ struct mbuf *freelist;
+
+ struct mbuf *head, *tail; /* a simple tailq */
+
+ /* scheduler hooks */
+ int (*enq)(struct dn_sch_inst *, struct dn_queue *,
+ struct mbuf *);
+ struct mbuf * (*deq)(struct dn_sch_inst *);
+ /* size of the three fields including sched-specific areas */
+ int schk_len;
+ int q_len; /* size of a queue including sched-fields */
+ int si_len; /* size of a sch_inst including sched-fields */
+ char *q; /* array of flow queues */
+ /* use a char* because size is variable */
+ struct dn_fsk *fs; /* array of flowsets */
+ struct dn_sch_inst *si;
+ struct dn_schk *sched;
+
+ /* generator state */
+ int state; /* 0 = going up, 1: going down */
+
+ /*
+ * We keep lists for each backlog level, and always serve
+ * the one with shortest backlog. llmask contains a bitmap
+ * of lists, and ll are the heads of the lists. The last
+ * entry (BACKLOG) contains all entries considered 'full'
+ * XXX to optimize things, entry i could contain queues with
+ * 2^{i-1}+1 .. 2^i entries.
+ */
+#define BACKLOG 30
+ uint32_t llmask;
+ struct list_head ll[BACKLOG + 10];
+};
+
+/* FI2Q and Q2FI converts from flow_id to dn_queue and back.
+ * We cannot easily use pointer arithmetic because it is variable size.
+ */
+#define FI2Q(c, i) ((struct dn_queue *)((c)->q + (c)->q_len * (i)))
+#define Q2FI(c, q) (((char *)(q) - (c)->q)/(c)->q_len)
+
+int debug = 0;
+
+struct dn_parms dn_cfg;
+
+static void controller(struct cfg_s *c);
+
+/* release a packet: put the mbuf in the freelist, and the queue in
+ * the bucket.
+ */
+int
+drop(struct cfg_s *c, struct mbuf *m)
+{
+ struct dn_queue *q;
+ int i;
+
+ c->drop++;
+ q = FI2Q(c, m->flow_id);
+ i = q->ni.length; // XXX or ffs...
+
+ ND("q %p id %d current length %d", q, m->flow_id, i);
+ if (i < BACKLOG) {
+ struct list_head *h = &q->ni.h;
+ c->llmask &= ~(1<<(i+1));
+ c->llmask |= (1<<(i));
+ list_del(h);
+ list_add_tail(h, &c->ll[i]);
+ }
+ m->m_nextpkt = c->freelist;
+ c->freelist = m;
+ return 0;
+}
+
+/* dequeue returns NON-NULL when a packet is dropped */
+static int
+enqueue(struct cfg_s *c, void *_m)
+{
+ struct mbuf *m = _m;
+ if (c->enq)
+ return c->enq(c->si, FI2Q(c, m->flow_id), m);
+ if (c->head == NULL)
+ c->head = m;
+ else
+ c->tail->m_nextpkt = m;
+ c->tail = m;
+ return 0; /* default - success */
+}
+
+/* dequeue returns NON-NULL when a packet is available */
+static void *
+dequeue(struct cfg_s *c)
+{
+ struct mbuf *m;
+ if (c->deq)
+ return c->deq(c->si);
+ if ((m = c->head)) {
+ m = c->head;
+ c->head = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ }
+ return m;
+}
+
+static int
+mainloop(struct cfg_s *c)
+{
+ int i;
+ struct mbuf *m;
+
+ for (i=0; i < c->loops; i++) {
+ /* implement histeresis */
+ controller(c);
+ DX(3, "loop %d enq %d send %p rx %d",
+ i, c->_enqueue, c->tosend, c->can_dequeue);
+ if ( (m = c->tosend) ) {
+ c->_enqueue++;
+ if (enqueue(c, m)) {
+ drop(c, m);
+ ND("loop %d enqueue fail", i );
+ } else {
+ ND("enqueue ok");
+ c->pending++;
+ }
+ }
+ if (c->can_dequeue) {
+ c->dequeue++;
+ if ((m = dequeue(c))) {
+ c->pending--;
+ drop(c, m);
+ c->drop--; /* compensate */
+ }
+ }
+ }
+ DX(1, "mainloop ends %d", i);
+ return 0;
+}
+
+int
+dump(struct cfg_s *c)
+{
+ int i;
+ struct dn_queue *q;
+
+ for (i=0; i < c->flows; i++) {
+ q = FI2Q(c, i);
+ DX(1, "queue %4d tot %10lld", i, q->ni.tot_bytes);
+ }
+ DX(1, "done %d loops\n", c->loops);
+ return 0;
+}
+
+/* interpret a number in human form */
+static long
+getnum(const char *s, char **next, const char *key)
+{
+ char *end = NULL;
+ long l;
+
+ if (next) /* default */
+ *next = NULL;
+ if (s && *s) {
+ DX(3, "token is <%s> %s", s, key ? key : "-");
+ l = strtol(s, &end, 0);
+ } else {
+ DX(3, "empty string");
+ l = -1;
+ }
+ if (l < 0) {
+ DX(2, "invalid %s for %s", s ? s : "NULL", (key ? key : "") );
+ return 0; // invalid
+ }
+ if (!end || !*end)
+ return l;
+ if (*end == 'n')
+ l = -l; /* multiply by n */
+ else if (*end == 'K')
+ l = l*1000;
+ else if (*end == 'M')
+ l = l*1000000;
+ else if (*end == 'k')
+ l = l*1024;
+ else if (*end == 'm')
+ l = l*1024*1024;
+ else if (*end == 'w')
+ ;
+ else {/* not recognized */
+ D("suffix %s for %s, next %p", end, key, next);
+ end--;
+ }
+ end++;
+ DX(3, "suffix now %s for %s, next %p", end, key, next);
+ if (next && *end) {
+ DX(3, "setting next to %s for %s", end, key);
+ *next = end;
+ }
+ return l;
+}
+
+/*
+ * flowsets are a comma-separated list of
+ * weight:maxlen:flows
+ * indicating how many flows are hooked to that fs.
+ * Both weight and range can be min-max-steps.
+ * In a first pass we just count the number of flowsets and flows,
+ * in a second pass we complete the setup.
+ */
+static void
+parse_flowsets(struct cfg_s *c, const char *fs, int pass)
+{
+ char *s, *cur, *next;
+ int n_flows = 0, n_fs = 0, wsum = 0;
+ int i, j;
+ struct dn_fs *prev = NULL;
+
+ DX(3, "--- pass %d flows %d flowsets %d", pass, c->flows, c->flowsets);
+ if (pass == 0)
+ c->fs_config = fs;
+ s = c->fs_config ? strdup(c->fs_config) : NULL;
+ if (s == NULL) {
+ if (pass == 0)
+ D("no fsconfig");
+ return;
+ }
+ for (next = s; (cur = strsep(&next, ","));) {
+ char *p = NULL;
+ int w, w_h, w_steps, wi;
+ int len, len_h, l_steps, li;
+ int flows;
+
+ w = getnum(strsep(&cur, ":"), &p, "weight");
+ if (w <= 0)
+ w = 1;
+ w_h = p ? getnum(p+1, &p, "weight_max") : w;
+ w_steps = p ? getnum(p+1, &p, "w_steps") : (w_h == w ?1:2);
+ len = getnum(strsep(&cur, ":"), &p, "len");
+ if (len <= 0)
+ len = 1000;
+ len_h = p ? getnum(p+1, &p, "len_max") : len;
+ l_steps = p ? getnum(p+1, &p, "l_steps") : (len_h == len ? 1 : 2);
+ flows = getnum(strsep(&cur, ":"), NULL, "flows");
+ if (flows == 0)
+ flows = 1;
+ DX(4, "weight %d..%d (%d) len %d..%d (%d) flows %d",
+ w, w_h, w_steps, len, len_h, l_steps, flows);
+ if (w == 0 || w_h < w || len == 0 || len_h < len ||
+ flows == 0) {
+ DX(4,"wrong parameters %s", fs);
+ return;
+ }
+ n_flows += flows * w_steps * l_steps;
+ for (i = 0; i < w_steps; i++) {
+ wi = w + ((w_h - w)* i)/(w_steps == 1 ? 1 : (w_steps-1));
+ for (j = 0; j < l_steps; j++, n_fs++) {
+ struct dn_fs *fs = &c->fs[n_fs].fs; // tentative
+ int x;
+
+ li = len + ((len_h - len)* j)/(l_steps == 1 ? 1 : (l_steps-1));
+ x = (wi*2048)/li;
+ DX(3, "----- fs %4d weight %4d lmax %4d X %4d flows %d",
+ n_fs, wi, li, x, flows);
+ if (pass == 0)
+ continue;
+ if (c->fs == NULL || c->flowsets <= n_fs) {
+ D("error in number of flowsets");
+ return;
+ }
+ wsum += wi * flows;
+ fs->par[0] = wi;
+ fs->par[1] = li;
+ fs->index = n_fs;
+ fs->n_flows = flows;
+ fs->cur = fs->first_flow = prev==NULL ? 0 : prev->next_flow;
+ fs->next_flow = fs->first_flow + fs->n_flows;
+ fs->y = x * flows;
+ fs->base_y = (prev == NULL) ? 0 : prev->next_y;
+ fs->next_y = fs->base_y + fs->y;
+ prev = fs;
+ }
+ }
+ }
+ c->max_y = prev ? prev->base_y + prev->y : 0;
+ c->flows = n_flows;
+ c->flowsets = n_fs;
+ c->wsum = wsum;
+ if (pass == 0)
+ return;
+
+ /* now link all flows to their parent flowsets */
+ DX(1,"%d flows on %d flowsets max_y %d", c->flows, c->flowsets, c->max_y);
+ for (i=0; i < c->flowsets; i++) {
+ struct dn_fs *fs = &c->fs[i].fs;
+ DX(1, "fs %3d w %5d l %4d flow %5d .. %5d y %6d .. %6d",
+ i, fs->par[0], fs->par[1],
+ fs->first_flow, fs->next_flow,
+ fs->base_y, fs->next_y);
+ for (j = fs->first_flow; j < fs->next_flow; j++) {
+ struct dn_queue *q = FI2Q(c, j);
+ q->fs = &c->fs[i];
+ }
+ }
+}
+
+static int
+init(struct cfg_s *c)
+{
+ int i;
+ int ac = c->ac;
+ char * const *av = c->av;
+
+ c->si_len = sizeof(struct dn_sch_inst);
+ c->q_len = sizeof(struct dn_queue);
+ moduledata_t *mod = NULL;
+ struct dn_alg *p = NULL;
+
+ c->th_min = 0;
+ c->th_max = -20;/* 20 packets per flow */
+ c->lmin = c->lmax = 1280; /* packet len */
+ c->flows = 1;
+ c->flowsets = 1;
+ c->name = "null";
+ ac--; av++;
+ while (ac > 1) {
+ if (!strcmp(*av, "-n")) {
+ c->loops = getnum(av[1], NULL, av[0]);
+ } else if (!strcmp(*av, "-d")) {
+ debug = atoi(av[1]);
+ } else if (!strcmp(*av, "-alg")) {
+ extern moduledata_t *_g_dn_fifo;
+ extern moduledata_t *_g_dn_wf2qp;
+ extern moduledata_t *_g_dn_rr;
+ extern moduledata_t *_g_dn_qfq;
+#ifdef WITH_KPS
+ extern moduledata_t *_g_dn_kps;
+#endif
+ if (!strcmp(av[1], "rr"))
+ mod = _g_dn_rr;
+ else if (!strcmp(av[1], "wf2qp"))
+ mod = _g_dn_wf2qp;
+ else if (!strcmp(av[1], "fifo"))
+ mod = _g_dn_fifo;
+ else if (!strcmp(av[1], "qfq"))
+ mod = _g_dn_qfq;
+#ifdef WITH_KPS
+ else if (!strcmp(av[1], "kps"))
+ mod = _g_dn_kps;
+#endif
+ else
+ mod = NULL;
+ c->name = mod ? mod->name : "NULL";
+ DX(3, "using scheduler %s", c->name);
+ } else if (!strcmp(*av, "-len")) {
+ c->lmin = getnum(av[1], NULL, av[0]);
+ c->lmax = c->lmin;
+ DX(3, "setting max to %d", c->th_max);
+ } else if (!strcmp(*av, "-burst")) {
+ c->maxburst = getnum(av[1], NULL, av[0]);
+ DX(3, "setting max to %d", c->th_max);
+ } else if (!strcmp(*av, "-qmax")) {
+ c->th_max = getnum(av[1], NULL, av[0]);
+ DX(3, "setting max to %d", c->th_max);
+ } else if (!strcmp(*av, "-qmin")) {
+ c->th_min = getnum(av[1], NULL, av[0]);
+ DX(3, "setting min to %d", c->th_min);
+ } else if (!strcmp(*av, "-flows")) {
+ c->flows = getnum(av[1], NULL, av[0]);
+ DX(3, "setting flows to %d", c->flows);
+ } else if (!strcmp(*av, "-flowsets")) {
+ parse_flowsets(c, av[1], 0);
+ DX(3, "setting flowsets to %d", c->flowsets);
+ } else {
+ D("option %s not recognised, ignore", *av);
+ }
+ ac -= 2; av += 2;
+ }
+ if (c->maxburst <= 0)
+ c->maxburst = 1;
+ if (c->loops <= 0)
+ c->loops = 1;
+ if (c->flows <= 0)
+ c->flows = 1;
+ if (c->flowsets <= 0)
+ c->flowsets = 1;
+ if (c->lmin <= 0)
+ c->lmin = 1;
+ if (c->lmax <= 0)
+ c->lmax = 1;
+ /* multiply by N */
+ if (c->th_min < 0)
+ c->th_min = c->flows * -c->th_min;
+ if (c->th_max < 0)
+ c->th_max = c->flows * -c->th_max;
+ if (c->th_max <= c->th_min)
+ c->th_max = c->th_min + 1;
+ if (mod) {
+ p = mod->p;
+ DX(3, "using module %s f %p p %p", mod->name, mod->f, mod->p);
+ DX(3, "modname %s ty %d", p->name, p->type);
+ c->enq = p->enqueue;
+ c->deq = p->dequeue;
+ c->si_len += p->si_datalen;
+ c->q_len += p->q_datalen;
+ c->schk_len += p->schk_datalen;
+ }
+ /* allocate queues, flowsets and one scheduler */
+ c->q = calloc(c->flows, c->q_len);
+ c->fs = calloc(c->flowsets, sizeof(struct dn_fsk));
+ c->si = calloc(1, c->si_len);
+ c->sched = calloc(c->flows, c->schk_len);
+ if (c->q == NULL || c->fs == NULL) {
+ D("error allocating memory for flows");
+ exit(1);
+ }
+ c->si->sched = c->sched;
+ if (p) {
+ if (p->config)
+ p->config(c->sched);
+ if (p->new_sched)
+ p->new_sched(c->si);
+ }
+ /* parse_flowsets links queues to their flowsets */
+ parse_flowsets(c, av[1], 1);
+ /* complete the work calling new_fsk */
+ for (i = 0; i < c->flowsets; i++) {
+ if (c->fs[i].fs.par[1] == 0)
+ c->fs[i].fs.par[1] = 1000; /* default pkt len */
+ c->fs[i].sched = c->sched;
+ if (p && p->new_fsk)
+ p->new_fsk(&c->fs[i]);
+ }
+
+ /* initialize the lists for the generator, and put
+ * all flows in the list for backlog = 0
+ */
+ for (i=0; i <= BACKLOG+5; i++)
+ INIT_LIST_HEAD(&c->ll[i]);
+
+ for (i = 0; i < c->flows; i++) {
+ struct dn_queue *q = FI2Q(c, i);
+ if (q->fs == NULL)
+ q->fs = &c->fs[0]; /* XXX */
+ q->_si = c->si;
+ if (p && p->new_queue)
+ p->new_queue(q);
+ INIT_LIST_HEAD(&q->ni.h);
+ list_add_tail(&q->ni.h, &c->ll[0]);
+ }
+ c->llmask = 1;
+ return 0;
+}
+
+
+int
+main(int ac, char *av[])
+{
+ struct cfg_s c;
+ struct timeval end;
+ double ll;
+ int i;
+ char msg[40];
+
+ bzero(&c, sizeof(c));
+ c.ac = ac;
+ c.av = av;
+ init(&c);
+ gettimeofday(&c.time, NULL);
+ mainloop(&c);
+ gettimeofday(&end, NULL);
+ end.tv_sec -= c.time.tv_sec;
+ end.tv_usec -= c.time.tv_usec;
+ if (end.tv_usec < 0) {
+ end.tv_usec += 1000000;
+ end.tv_sec--;
+ }
+ c.time = end;
+ ll = end.tv_sec*1000000 + end.tv_usec;
+ ll *= 1000; /* convert to nanoseconds */
+ ll /= c._enqueue;
+ sprintf(msg, "1::%d", c.flows);
+ D("%-8s n %d %d time %d.%06d %8.3f qlen %d %d flows %s drops %d",
+ c.name, c._enqueue, c.loops,
+ (int)c.time.tv_sec, (int)c.time.tv_usec, ll,
+ c.th_min, c.th_max,
+ c.fs_config ? c.fs_config : msg, c.drop);
+ dump(&c);
+ DX(1, "done ac %d av %p", ac, av);
+ for (i=0; i < ac; i++)
+ DX(1, "arg %d %s", i, av[i]);
+ return 0;
+}
+
+/*
+ * The controller decides whether in this iteration we should send
+ * (the packet is in c->tosend) and/or receive (flag c->can_dequeue)
+ */
+static void
+controller(struct cfg_s *c)
+{
+ struct mbuf *m;
+ struct dn_fs *fs;
+ int flow_id;
+
+ /* histeresis between max and min */
+ if (c->state == 0 && c->pending >= c->th_max)
+ c->state = 1;
+ else if (c->state == 1 && c->pending <= c->th_min)
+ c->state = 0;
+ ND(1, "state %d pending %2d", c->state, c->pending);
+ c->can_dequeue = c->state;
+ c->tosend = NULL;
+ if (c->state)
+ return;
+
+ if (1) {
+ int i;
+ struct dn_queue *q;
+ struct list_head *h;
+
+ i = ffs(c->llmask) - 1;
+ if (i < 0) {
+ DX(2, "no candidate");
+ c->can_dequeue = 1;
+ return;
+ }
+ h = &c->ll[i];
+ ND(1, "backlog %d p %p prev %p next %p", i, h, h->prev, h->next);
+ q = list_first_entry(h, struct dn_queue, ni.h);
+ list_del(&q->ni.h);
+ flow_id = Q2FI(c, q);
+ DX(2, "extracted flow %p %d backlog %d", q, flow_id, i);
+ if (list_empty(h)) {
+ ND(2, "backlog %d empty", i);
+ c->llmask &= ~(1<<i);
+ }
+ ND(1, "before %d p %p prev %p next %p", i+1, h+1, h[1].prev, h[1].next);
+ list_add_tail(&q->ni.h, h+1);
+ ND(1, " after %d p %p prev %p next %p", i+1, h+1, h[1].prev, h[1].next);
+ if (i < BACKLOG) {
+ ND(2, "backlog %d full", i+1);
+ c->llmask |= 1<<(1+i);
+ }
+ fs = &q->fs->fs;
+ c->cur_fs = q->fs - c->fs;
+ fs->cur = flow_id;
+ } else {
+ /* XXX this does not work ? */
+ /* now decide whom to send the packet, and the length */
+ /* lookup in the flow table */
+ if (c->cur_y >= c->max_y) { /* handle wraparound */
+ c->cur_y = 0;
+ c->cur_fs = 0;
+ }
+ fs = &c->fs[c->cur_fs].fs;
+ flow_id = fs->cur++;
+ if (fs->cur >= fs->next_flow)
+ fs->cur = fs->first_flow;
+ c->cur_y++;
+ if (c->cur_y >= fs->next_y)
+ c->cur_fs++;
+ }
+
+ /* construct a packet */
+ if (c->freelist) {
+ m = c->tosend = c->freelist;
+ c->freelist = c->freelist->m_nextpkt;
+ } else {
+ m = c->tosend = calloc(1, sizeof(struct mbuf));
+ }
+ if (m == NULL)
+ return;
+
+ m->cfg = c;
+ m->m_nextpkt = NULL;
+ m->m_pkthdr.len = fs->par[1]; // XXX maxlen
+ m->flow_id = flow_id;
+
+ ND(2,"y %6d flow %5d fs %3d weight %4d len %4d",
+ c->cur_y, m->flow_id, c->cur_fs,
+ fs->par[0], m->m_pkthdr.len);
+
+}
+
+/*
+Packet allocation:
+to achieve a distribution that matches weights, for each X=w/lmax class
+we should generate a number of packets proportional to Y = X times the number
+of flows in the class.
+So we construct an array with the cumulative distribution of Y's,
+and use it to identify the flow via inverse mapping (if the Y's are
+not too many we can use an array for the lookup). In practice,
+each flow will have X entries [virtually] pointing to it.
+
+*/
diff --git a/sys/netinet/ipfw/test/mylist.h b/sys/netinet/ipfw/test/mylist.h
new file mode 100644
index 0000000..6247f32
--- /dev/null
+++ b/sys/netinet/ipfw/test/mylist.h
@@ -0,0 +1,49 @@
+/*
+ * $FreeBSD$
+ *
+ * linux-like bidirectional lists
+ */
+
+#ifndef _MYLIST_H
+#define _MYLIST_H
+struct list_head {
+ struct list_head *prev, *next;
+};
+
+#define INIT_LIST_HEAD(l) do { (l)->prev = (l)->next = (l); } while (0)
+#define list_empty(l) ( (l)->next == l )
+static inline void
+__list_add(struct list_head *o, struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = o;
+ o->next = next;
+ o->prev = prev;
+ prev->next = o;
+}
+
+static inline void
+list_add_tail(struct list_head *o, struct list_head *head)
+{
+ __list_add(o, head->prev, head);
+}
+
+#define list_first_entry(pL, ty, member) \
+ (ty *)((char *)((pL)->next) - offsetof(ty, member))
+
+static inline void
+__list_del(struct list_head *prev, struct list_head *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+static inline void
+list_del(struct list_head *entry)
+{
+ ND("called on %p", entry);
+ __list_del(entry->prev, entry->next);
+ entry->next = entry->prev = NULL;
+}
+
+#endif /* _MYLIST_H */
diff --git a/sys/netinet/ipfw/test/test_dn_heap.c b/sys/netinet/ipfw/test/test_dn_heap.c
new file mode 100644
index 0000000..d460cf2
--- /dev/null
+++ b/sys/netinet/ipfw/test/test_dn_heap.c
@@ -0,0 +1,162 @@
+/*-
+ * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Userland code for testing binary heaps and hash tables
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <strings.h>
+#include <stdlib.h>
+
+#include "dn_heap.h"
+#define log(x, arg...) fprintf(stderr, ## arg)
+#define panic(x...) fprintf(stderr, ## x), exit(1)
+
+#include <string.h>
+
+struct x {
+ struct x *ht_link;
+ char buf[0];
+};
+
+uint32_t hf(uintptr_t key, int flags, void *arg)
+{
+ return (flags & DNHT_KEY_IS_OBJ) ?
+ ((struct x *)key)->buf[0] : *(char *)key;
+}
+
+int matchf(void *obj, uintptr_t key, int flags, void *arg)
+{
+ char *s = (flags & DNHT_KEY_IS_OBJ) ?
+ ((struct x *)key)->buf : (char *)key;
+ return (strcmp(((struct x *)obj)->buf, s) == 0);
+}
+
+void *newfn(uintptr_t key, int flags, void *arg)
+{
+ char *s = (char *)key;
+ struct x *p = malloc(sizeof(*p) + 1 + strlen(s));
+ if (p)
+ strcpy(p->buf, s);
+ return p;
+}
+
+char *strings[] = {
+ "undici", "unico", "doppio", "devoto",
+ "uno", "due", "tre", "quattro", "cinque", "sei",
+ "uno", "due", "tre", "quattro", "cinque", "sei",
+ NULL,
+};
+
+int doprint(void *_x, void *arg)
+{
+ struct x *x = _x;
+ printf("found element <%s>\n", x->buf);
+ return (int)arg;
+}
+
+static void
+test_hash()
+{
+ char **p;
+ struct dn_ht *h;
+ uintptr_t x = 0;
+ uintptr_t x1 = 0;
+
+ /* first, find and allocate */
+ h = dn_ht_init(NULL, 10, 0, hf, matchf, newfn);
+
+ for (p = strings; *p; p++) {
+ dn_ht_find(h, (uintptr_t)*p, DNHT_INSERT, NULL);
+ }
+ dn_ht_scan(h, doprint, 0);
+ printf("/* second -- find without allocate */\n");
+ h = dn_ht_init(NULL, 10, 0, hf, matchf, NULL);
+ for (p = strings; *p; p++) {
+ void **y = newfn((uintptr_t)*p, 0, NULL);
+ if (x == 0)
+ x = (uintptr_t)y;
+ else {
+ if (x1 == 0)
+ x1 = (uintptr_t)*p;
+ }
+ dn_ht_find(h, (uintptr_t)y, DNHT_INSERT | DNHT_KEY_IS_OBJ, NULL);
+ }
+ dn_ht_scan(h, doprint, 0);
+ printf("remove %p gives %p\n", (void *)x,
+ dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE, NULL));
+ printf("remove %p gives %p\n", (void *)x,
+ dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE, NULL));
+ printf("remove %p gives %p\n", (void *)x,
+ dn_ht_find(h, x1, DNHT_REMOVE, NULL));
+ printf("remove %p gives %p\n", (void *)x,
+ dn_ht_find(h, x1, DNHT_REMOVE, NULL));
+ dn_ht_scan(h, doprint, 0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct dn_heap h;
+ int i, n, n2, n3;
+
+ test_hash();
+ return 0;
+
+ /* n = elements, n2 = cycles */
+ n = (argc > 1) ? atoi(argv[1]) : 0;
+ if (n <= 0 || n > 1000000)
+ n = 100;
+ n2 = (argc > 2) ? atoi(argv[2]) : 0;
+ if (n2 <= 0)
+ n = 1000000;
+ n3 = (argc > 3) ? atoi(argv[3]) : 0;
+ bzero(&h, sizeof(h));
+ heap_init(&h, n, -1);
+ while (n2-- > 0) {
+ uint64_t prevk = 0;
+ for (i=0; i < n; i++)
+ heap_insert(&h, n3 ? n-i: random(), (void *)(100+i));
+
+ for (i=0; h.elements > 0; i++) {
+ uint64_t k = h.p[0].key;
+ if (k < prevk)
+ panic("wrong sequence\n");
+ prevk = k;
+ if (0)
+ printf("%d key %llu, val %p\n",
+ i, h.p[0].key, h.p[0].object);
+ heap_extract(&h, NULL);
+ }
+ }
+ return 0;
+}
diff --git a/sys/netinet/ipfw/test/test_dn_sched.c b/sys/netinet/ipfw/test/test_dn_sched.c
new file mode 100644
index 0000000..ee46c95
--- /dev/null
+++ b/sys/netinet/ipfw/test/test_dn_sched.c
@@ -0,0 +1,89 @@
+/*
+ * $FreeBSD$
+ *
+ * library functions for userland testing of dummynet schedulers
+ */
+
+#include "dn_test.h"
+
+void
+m_freem(struct mbuf *m)
+{
+ printf("free %p\n", m);
+}
+
+int
+dn_sched_modevent(module_t mod, int cmd, void *arg)
+{
+ return 0;
+}
+
+void
+dn_free_pkts(struct mbuf *m)
+{
+ struct mbuf *x;
+ while ( (x = m) ) {
+ m = m->m_nextpkt;
+ m_freem(x);
+ }
+}
+
+int
+dn_delete_queue(void *_q, void *do_free)
+{
+ struct dn_queue *q = _q;
+ if (q->mq.head)
+ dn_free_pkts(q->mq.head);
+ free(q);
+ return 0;
+}
+
+/*
+ * This is a simplified function for testing purposes, which does
+ * not implement statistics or random loss.
+ * Enqueue a packet in q, subject to space and queue management policy
+ * (whose parameters are in q->fs).
+ * Update stats for the queue and the scheduler.
+ * Return 0 on success, 1 on drop. The packet is consumed anyways.
+ */
+int
+dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop)
+{
+ if (drop)
+ goto drop;
+ if (q->ni.length >= 200)
+ goto drop;
+ mq_append(&q->mq, m);
+ q->ni.length++;
+ q->ni.tot_bytes += m->m_pkthdr.len;
+ return 0;
+
+drop:
+ q->ni.drops++;
+ return 1;
+}
+
+int
+ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg)
+{
+ if (*v < lo) {
+ *v = dflt;
+ } else if (*v > hi) {
+ *v = hi;
+ }
+ return *v;
+}
+
+#ifndef __FreeBSD__
+int
+fls(int mask)
+{
+ int bit;
+
+ if (mask == 0)
+ return (0);
+ for (bit = 1; mask != 1; bit++)
+ mask = (unsigned int)mask >> 1;
+ return (bit);
+}
+#endif
diff --git a/tools/build/mk/Makefile.boot b/tools/build/mk/Makefile.boot
index 0707ae2..b75809b 100644
--- a/tools/build/mk/Makefile.boot
+++ b/tools/build/mk/Makefile.boot
@@ -4,3 +4,6 @@ CFLAGS+= -I${WORLDTMP}/legacy/usr/include
DPADD+= ${WORLDTMP}/legacy/usr/lib/libegacy.a
LDADD+= -legacy
LDFLAGS+= -L${WORLDTMP}/legacy/usr/lib
+
+# we do not want to capture dependencies refering to the above
+UPDATE_DEPENDFILE= no
diff --git a/usr.bin/apply/Makefile.depend b/usr.bin/apply/Makefile.depend
new file mode 100644
index 0000000..887c9bd
--- /dev/null
+++ b/usr.bin/apply/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsbuf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ar/Makefile.depend b/usr.bin/ar/Makefile.depend
new file mode 100644
index 0000000..2d7f214
--- /dev/null
+++ b/usr.bin/ar/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libarchive \
+ lib/libc \
+ lib/libelf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+acplex.o: acplex.c
+acplex.o: y.tab.h
+acplex.po: acplex.c
+acplex.po: y.tab.h
+acpyacc.o: acpyacc.c
+acpyacc.po: acpyacc.c
+.endif
diff --git a/usr.bin/asa/Makefile.depend b/usr.bin/asa/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/asa/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/at/Makefile.depend b/usr.bin/at/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/at/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/atm/sscop/Makefile.depend b/usr.bin/atm/sscop/Makefile.depend
new file mode 100644
index 0000000..fa71584
--- /dev/null
+++ b/usr.bin/atm/sscop/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbegemot \
+ lib/libc \
+ lib/libnetgraph \
+ lib/libngatm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/awk/Makefile.depend b/usr.bin/awk/Makefile.depend
new file mode 100644
index 0000000..ad0c870
--- /dev/null
+++ b/usr.bin/awk/Makefile.depend
@@ -0,0 +1,40 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+awkgram.o: awkgram.c
+awkgram.po: awkgram.c
+b.o: ytab.h
+b.po: ytab.h
+lex.o: ytab.h
+lex.po: ytab.h
+lib.o: ytab.h
+lib.po: ytab.h
+main.o: ytab.h
+main.po: ytab.h
+parse.o: ytab.h
+parse.po: ytab.h
+proctab.o: proctab.c
+proctab.o: ytab.h
+proctab.po: proctab.c
+proctab.po: ytab.h
+run.o: ytab.h
+run.po: ytab.h
+tran.o: ytab.h
+tran.po: ytab.h
+.endif
diff --git a/usr.bin/banner/Makefile.depend b/usr.bin/banner/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/banner/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/basename/Makefile.depend b/usr.bin/basename/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/basename/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/bc/Makefile.depend b/usr.bin/bc/Makefile.depend
new file mode 100644
index 0000000..1c74339
--- /dev/null
+++ b/usr.bin/bc/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+bc.o: bc.c
+bc.po: bc.c
+scan.o: bc.h
+scan.o: scan.c
+scan.po: bc.h
+scan.po: scan.c
+.endif
diff --git a/usr.bin/biff/Makefile.depend b/usr.bin/biff/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/biff/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/bluetooth/bthost/Makefile.depend b/usr.bin/bluetooth/bthost/Makefile.depend
new file mode 100644
index 0000000..e188ca8
--- /dev/null
+++ b/usr.bin/bluetooth/bthost/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/bluetooth/btsockstat/Makefile.depend b/usr.bin/bluetooth/btsockstat/Makefile.depend
new file mode 100644
index 0000000..ed9965e
--- /dev/null
+++ b/usr.bin/bluetooth/btsockstat/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/bluetooth/rfcomm_sppd/Makefile.depend b/usr.bin/bluetooth/rfcomm_sppd/Makefile.depend
new file mode 100644
index 0000000..b3a6c2b
--- /dev/null
+++ b/usr.bin/bluetooth/rfcomm_sppd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+ lib/libsdp \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/brandelf/Makefile.depend b/usr.bin/brandelf/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/brandelf/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/bsdiff/bsdiff/Makefile.depend b/usr.bin/bsdiff/bsdiff/Makefile.depend
new file mode 100644
index 0000000..b2bb335
--- /dev/null
+++ b/usr.bin/bsdiff/bsdiff/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbz2 \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/bsdiff/bspatch/Makefile.depend b/usr.bin/bsdiff/bspatch/Makefile.depend
new file mode 100644
index 0000000..b2bb335
--- /dev/null
+++ b/usr.bin/bsdiff/bspatch/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbz2 \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/bzip2/Makefile.depend b/usr.bin/bzip2/Makefile.depend
new file mode 100644
index 0000000..44eda27
--- /dev/null
+++ b/usr.bin/bzip2/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbz2 \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/bzip2recover/Makefile.depend b/usr.bin/bzip2recover/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/bzip2recover/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/c89/Makefile.depend b/usr.bin/c89/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/c89/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/c99/Makefile.depend b/usr.bin/c99/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/c99/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/calendar/Makefile.depend b/usr.bin/calendar/Makefile.depend
new file mode 100644
index 0000000..d78f7b7
--- /dev/null
+++ b/usr.bin/calendar/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/cap_mkdb/Makefile.depend b/usr.bin/cap_mkdb/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/cap_mkdb/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/catman/Makefile.depend b/usr.bin/catman/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/catman/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/chat/Makefile.depend b/usr.bin/chat/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/chat/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/checknr/Makefile.depend b/usr.bin/checknr/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/checknr/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/chkey/Makefile.depend b/usr.bin/chkey/Makefile.depend
new file mode 100644
index 0000000..6e85033
--- /dev/null
+++ b/usr.bin/chkey/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmp \
+ lib/librpcsvc \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/chpass/Makefile.depend b/usr.bin/chpass/Makefile.depend
new file mode 100644
index 0000000..d9bca56
--- /dev/null
+++ b/usr.bin/chpass/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libutil \
+ lib/libypclnt \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/cksum/Makefile.depend b/usr.bin/cksum/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/cksum/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/clang/clang-tblgen/Makefile.depend b/usr.bin/clang/clang-tblgen/Makefile.depend
new file mode 100644
index 0000000..0d08e73
--- /dev/null
+++ b/usr.bin/clang/clang-tblgen/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/clang/libllvmsupport \
+ lib/clang/libllvmtablegen \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/clang/clang/Makefile.depend b/usr.bin/clang/clang/Makefile.depend
new file mode 100644
index 0000000..9c26a69
--- /dev/null
+++ b/usr.bin/clang/clang/Makefile.depend
@@ -0,0 +1,104 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/clang/libclanganalysis \
+ lib/clang/libclangarcmigrate \
+ lib/clang/libclangast \
+ lib/clang/libclangbasic \
+ lib/clang/libclangcodegen \
+ lib/clang/libclangdriver \
+ lib/clang/libclangedit \
+ lib/clang/libclangfrontend \
+ lib/clang/libclangfrontendtool \
+ lib/clang/libclanglex \
+ lib/clang/libclangparse \
+ lib/clang/libclangrewrite \
+ lib/clang/libclangsema \
+ lib/clang/libclangserialization \
+ lib/clang/libclangstaticanalyzercheckers \
+ lib/clang/libclangstaticanalyzercore \
+ lib/clang/libclangstaticanalyzerfrontend \
+ lib/clang/libllvmanalysis \
+ lib/clang/libllvmarchive \
+ lib/clang/libllvmarmasmparser \
+ lib/clang/libllvmarmcodegen \
+ lib/clang/libllvmarmdesc \
+ lib/clang/libllvmarmdisassembler \
+ lib/clang/libllvmarminfo \
+ lib/clang/libllvmarminstprinter \
+ lib/clang/libllvmasmparser \
+ lib/clang/libllvmasmprinter \
+ lib/clang/libllvmbitreader \
+ lib/clang/libllvmbitwriter \
+ lib/clang/libllvmcodegen \
+ lib/clang/libllvmcore \
+ lib/clang/libllvminstcombine \
+ lib/clang/libllvminstrumentation \
+ lib/clang/libllvmipa \
+ lib/clang/libllvmipo \
+ lib/clang/libllvmlinker \
+ lib/clang/libllvmmc \
+ lib/clang/libllvmmcparser \
+ lib/clang/libllvmmipsasmparser \
+ lib/clang/libllvmmipscodegen \
+ lib/clang/libllvmmipsdesc \
+ lib/clang/libllvmmipsinfo \
+ lib/clang/libllvmmipsinstprinter \
+ lib/clang/libllvmobject \
+ lib/clang/libllvmpowerpccodegen \
+ lib/clang/libllvmpowerpcdesc \
+ lib/clang/libllvmpowerpcinfo \
+ lib/clang/libllvmpowerpcinstprinter \
+ lib/clang/libllvmscalaropts \
+ lib/clang/libllvmselectiondag \
+ lib/clang/libllvmsupport \
+ lib/clang/libllvmtarget \
+ lib/clang/libllvmtransformutils \
+ lib/clang/libllvmvectorize \
+ lib/clang/libllvmx86asmparser \
+ lib/clang/libllvmx86codegen \
+ lib/clang/libllvmx86desc \
+ lib/clang/libllvmx86disassembler \
+ lib/clang/libllvmx86info \
+ lib/clang/libllvmx86instprinter \
+ lib/clang/libllvmx86utils \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+cc1_main.o: CC1Options.inc.h
+cc1_main.o: DiagnosticCommonKinds.inc.h
+cc1_main.o: DiagnosticDriverKinds.inc.h
+cc1_main.o: DiagnosticFrontendKinds.inc.h
+cc1_main.po: CC1Options.inc.h
+cc1_main.po: DiagnosticCommonKinds.inc.h
+cc1_main.po: DiagnosticDriverKinds.inc.h
+cc1_main.po: DiagnosticFrontendKinds.inc.h
+cc1as_main.o: CC1AsOptions.inc.h
+cc1as_main.o: DiagnosticCommonKinds.inc.h
+cc1as_main.o: DiagnosticDriverKinds.inc.h
+cc1as_main.o: DiagnosticFrontendKinds.inc.h
+cc1as_main.o: Options.inc.h
+cc1as_main.po: CC1AsOptions.inc.h
+cc1as_main.po: DiagnosticCommonKinds.inc.h
+cc1as_main.po: DiagnosticDriverKinds.inc.h
+cc1as_main.po: DiagnosticFrontendKinds.inc.h
+cc1as_main.po: Options.inc.h
+driver.o: CC1Options.inc.h
+driver.o: DiagnosticCommonKinds.inc.h
+driver.po: CC1Options.inc.h
+driver.po: DiagnosticCommonKinds.inc.h
+.endif
diff --git a/usr.bin/clang/tblgen/Makefile.depend b/usr.bin/clang/tblgen/Makefile.depend
new file mode 100644
index 0000000..0d08e73
--- /dev/null
+++ b/usr.bin/clang/tblgen/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libstdc++ \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/clang/libllvmsupport \
+ lib/clang/libllvmtablegen \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/cmp/Makefile.depend b/usr.bin/cmp/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/cmp/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/col/Makefile.depend b/usr.bin/col/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/col/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/colcrt/Makefile.depend b/usr.bin/colcrt/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/colcrt/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/colldef/Makefile.depend b/usr.bin/colldef/Makefile.depend
new file mode 100644
index 0000000..702a543
--- /dev/null
+++ b/usr.bin/colldef/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+parse.o: parse.c
+parse.po: parse.c
+scan.o: scan.c
+scan.o: y.tab.h
+scan.po: scan.c
+scan.po: y.tab.h
+.endif
diff --git a/usr.bin/colrm/Makefile.depend b/usr.bin/colrm/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/colrm/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/column/Makefile.depend b/usr.bin/column/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/column/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/comm/Makefile.depend b/usr.bin/comm/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/comm/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/compile_et/Makefile.depend b/usr.bin/compile_et/Makefile.depend
new file mode 100644
index 0000000..35d6a7c
--- /dev/null
+++ b/usr.bin/compile_et/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libroken \
+ kerberos5/lib/libvers \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+compile_et.o: parse.h
+compile_et.po: parse.h
+lex.o: lex.c
+lex.o: parse.h
+lex.po: lex.c
+lex.po: parse.h
+parse.o: parse.c
+parse.po: parse.c
+.endif
diff --git a/usr.bin/compress/Makefile.depend b/usr.bin/compress/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/compress/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/cpio/Makefile.depend b/usr.bin/cpio/Makefile.depend
new file mode 100644
index 0000000..97f5f95
--- /dev/null
+++ b/usr.bin/cpio/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libarchive \
+ lib/libbz2 \
+ lib/libc \
+ lib/libexpat \
+ lib/liblzma \
+ lib/libz \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/cpuset/Makefile.depend b/usr.bin/cpuset/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/cpuset/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/csplit/Makefile.depend b/usr.bin/csplit/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/csplit/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/csup/Makefile.depend b/usr.bin/csup/Makefile.depend
new file mode 100644
index 0000000..3aaa868
--- /dev/null
+++ b/usr.bin/csup/Makefile.depend
@@ -0,0 +1,31 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/libthr \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+config.o: parse.h
+config.po: parse.h
+parse.o: parse.c
+parse.po: parse.c
+token.o: parse.h
+token.o: token.c
+token.po: parse.h
+token.po: token.c
+.endif
diff --git a/usr.bin/ctags/Makefile.depend b/usr.bin/ctags/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/ctags/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ctlstat/Makefile.depend b/usr.bin/ctlstat/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/ctlstat/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/cut/Makefile.depend b/usr.bin/cut/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/cut/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/dc/Makefile.depend b/usr.bin/dc/Makefile.depend
new file mode 100644
index 0000000..510b4fd
--- /dev/null
+++ b/usr.bin/dc/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ secure/lib/libcrypto \
+ secure/lib/libssl \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/dig/Makefile.depend b/usr.bin/dig/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.bin/dig/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/dirname/Makefile.depend b/usr.bin/dirname/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/dirname/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/du/Makefile.depend b/usr.bin/du/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.bin/du/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ee/Makefile.depend b/usr.bin/ee/Makefile.depend
new file mode 100644
index 0000000..c74c89f
--- /dev/null
+++ b/usr.bin/ee/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/elf2aout/Makefile.depend b/usr.bin/elf2aout/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/elf2aout/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/elfdump/Makefile.depend b/usr.bin/elfdump/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/elfdump/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/enigma/Makefile.depend b/usr.bin/enigma/Makefile.depend
new file mode 100644
index 0000000..aaceb6e
--- /dev/null
+++ b/usr.bin/enigma/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/env/Makefile.depend b/usr.bin/env/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/env/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/expand/Makefile.depend b/usr.bin/expand/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/expand/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/false/Makefile.depend b/usr.bin/false/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/false/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/fetch/Makefile.depend b/usr.bin/fetch/Makefile.depend
new file mode 100644
index 0000000..341476b
--- /dev/null
+++ b/usr.bin/fetch/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libfetch \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/file/Makefile.depend b/usr.bin/file/Makefile.depend
new file mode 100644
index 0000000..d7d8c57
--- /dev/null
+++ b/usr.bin/file/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmagic \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/file2c/Makefile.depend b/usr.bin/file2c/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/file2c/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/find/Makefile.depend b/usr.bin/find/Makefile.depend
new file mode 100644
index 0000000..a76cd46
--- /dev/null
+++ b/usr.bin/find/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+getdate.o: getdate.c
+getdate.po: getdate.c
+.endif
diff --git a/usr.bin/finger/Makefile.depend b/usr.bin/finger/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/finger/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/fmt/Makefile.depend b/usr.bin/fmt/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/fmt/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/fold/Makefile.depend b/usr.bin/fold/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/fold/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/from/Makefile.depend b/usr.bin/from/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/from/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/fstat/Makefile.depend b/usr.bin/fstat/Makefile.depend
new file mode 100644
index 0000000..c80d9db
--- /dev/null
+++ b/usr.bin/fstat/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ lib/libprocstat \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/fsync/Makefile.depend b/usr.bin/fsync/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/fsync/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ftp/Makefile.depend b/usr.bin/ftp/Makefile.depend
new file mode 100644
index 0000000..703eab3
--- /dev/null
+++ b/usr.bin/ftp/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/libtelnet \
+ lib/libutil \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/gcore/Makefile.depend b/usr.bin/gcore/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.bin/gcore/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/gencat/Makefile.depend b/usr.bin/gencat/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.bin/gencat/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/getconf/Makefile.depend b/usr.bin/getconf/Makefile.depend
new file mode 100644
index 0000000..714ee8b
--- /dev/null
+++ b/usr.bin/getconf/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+confstr.o: confstr.c
+confstr.po: confstr.c
+limits.o: limits.c
+limits.po: limits.c
+pathconf.o: pathconf.c
+pathconf.po: pathconf.c
+progenv.o: progenv.c
+progenv.po: progenv.c
+sysconf.o: sysconf.c
+sysconf.po: sysconf.c
+.endif
diff --git a/usr.bin/getent/Makefile.depend b/usr.bin/getent/Makefile.depend
new file mode 100644
index 0000000..43e53d5
--- /dev/null
+++ b/usr.bin/getent/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/getopt/Makefile.depend b/usr.bin/getopt/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/getopt/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/gprof/Makefile.depend b/usr.bin/gprof/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/gprof/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/grep/Makefile.depend b/usr.bin/grep/Makefile.depend
new file mode 100644
index 0000000..9c35699
--- /dev/null
+++ b/usr.bin/grep/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ gnu/lib/libregex \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbz2 \
+ lib/libc \
+ lib/liblzma \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/gzip/Makefile.depend b/usr.bin/gzip/Makefile.depend
new file mode 100644
index 0000000..15ad9aa
--- /dev/null
+++ b/usr.bin/gzip/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbz2 \
+ lib/libc \
+ lib/liblzma \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/head/Makefile.depend b/usr.bin/head/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/head/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/hexdump/Makefile.depend b/usr.bin/hexdump/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/hexdump/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/host/Makefile.depend b/usr.bin/host/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.bin/host/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/id/Makefile.depend b/usr.bin/id/Makefile.depend
new file mode 100644
index 0000000..1aedff5
--- /dev/null
+++ b/usr.bin/id/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbsm \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/indent/Makefile.depend b/usr.bin/indent/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/indent/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ipcrm/Makefile.depend b/usr.bin/ipcrm/Makefile.depend
new file mode 100644
index 0000000..553674c
--- /dev/null
+++ b/usr.bin/ipcrm/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ipcs/Makefile.depend b/usr.bin/ipcs/Makefile.depend
new file mode 100644
index 0000000..553674c
--- /dev/null
+++ b/usr.bin/ipcs/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/join/Makefile.depend b/usr.bin/join/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/join/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/jot/Makefile.depend b/usr.bin/jot/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/jot/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/kdump/Makefile.depend b/usr.bin/kdump/Makefile.depend
new file mode 100644
index 0000000..cf6d120
--- /dev/null
+++ b/usr.bin/kdump/Makefile.depend
@@ -0,0 +1,31 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ioctl.o: ioctl.c
+ioctl.po: ioctl.c
+kdump.o: kdump_subr.h
+kdump.po: kdump_subr.h
+kdump_subr.o: kdump_subr.c
+kdump_subr.o: kdump_subr.h
+kdump_subr.po: kdump_subr.c
+kdump_subr.po: kdump_subr.h
+linux_syscalls.o: linux_syscalls.c
+linux_syscalls.po: linux_syscalls.c
+.endif
diff --git a/usr.bin/keylogin/Makefile.depend b/usr.bin/keylogin/Makefile.depend
new file mode 100644
index 0000000..60fe900
--- /dev/null
+++ b/usr.bin/keylogin/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/keylogout/Makefile.depend b/usr.bin/keylogout/Makefile.depend
new file mode 100644
index 0000000..6e9b14f
--- /dev/null
+++ b/usr.bin/keylogout/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/killall/Makefile.depend b/usr.bin/killall/Makefile.depend
new file mode 100644
index 0000000..7479d46
--- /dev/null
+++ b/usr.bin/killall/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libjail \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ktrace/Makefile.depend b/usr.bin/ktrace/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/ktrace/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ktrdump/Makefile.depend b/usr.bin/ktrdump/Makefile.depend
new file mode 100644
index 0000000..553674c
--- /dev/null
+++ b/usr.bin/ktrdump/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/lam/Makefile.depend b/usr.bin/lam/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/lam/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/last/Makefile.depend b/usr.bin/last/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/last/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/lastcomm/Makefile.depend b/usr.bin/lastcomm/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/lastcomm/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ldd/Makefile.depend b/usr.bin/ldd/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.bin/ldd/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/leave/Makefile.depend b/usr.bin/leave/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/leave/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/less/Makefile.depend b/usr.bin/less/Makefile.depend
new file mode 100644
index 0000000..c74c89f
--- /dev/null
+++ b/usr.bin/less/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/lessecho/Makefile.depend b/usr.bin/lessecho/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/lessecho/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/lesskey/Makefile.depend b/usr.bin/lesskey/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/lesskey/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/lex/Makefile.depend b/usr.bin/lex/Makefile.depend
new file mode 100644
index 0000000..1ff4094
--- /dev/null
+++ b/usr.bin/lex/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+parse.o: parse.c
+parse.po: parse.c
+scan.o: parse.h
+scan.o: scan.c
+scan.po: parse.h
+scan.po: scan.c
+skel.o: skel.c
+skel.po: skel.c
+yylex.o: parse.h
+yylex.po: parse.h
+.endif
diff --git a/usr.bin/lex/lib/Makefile.depend b/usr.bin/lex/lib/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.bin/lex/lib/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/limits/Makefile.depend b/usr.bin/limits/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.bin/limits/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/locale/Makefile.depend b/usr.bin/locale/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/locale/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/locate/bigram/Makefile.depend b/usr.bin/locate/bigram/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/locate/bigram/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/locate/code/Makefile.depend b/usr.bin/locate/code/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/locate/code/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/locate/locate/Makefile.depend b/usr.bin/locate/locate/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.bin/locate/locate/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/lock/Makefile.depend b/usr.bin/lock/Makefile.depend
new file mode 100644
index 0000000..aaceb6e
--- /dev/null
+++ b/usr.bin/lock/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/lockf/Makefile.depend b/usr.bin/lockf/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/lockf/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/logger/Makefile.depend b/usr.bin/logger/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/logger/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/login/Makefile.depend b/usr.bin/login/Makefile.depend
new file mode 100644
index 0000000..ef1e74a
--- /dev/null
+++ b/usr.bin/login/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbsm \
+ lib/libc \
+ lib/libpam/libpam \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/logins/Makefile.depend b/usr.bin/logins/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/logins/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/logname/Makefile.depend b/usr.bin/logname/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/logname/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/look/Makefile.depend b/usr.bin/look/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/look/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/lorder/Makefile.depend b/usr.bin/lorder/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.bin/lorder/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/lsvfs/Makefile.depend b/usr.bin/lsvfs/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/lsvfs/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/lzmainfo/Makefile.depend b/usr.bin/lzmainfo/Makefile.depend
new file mode 100644
index 0000000..5a47d9e
--- /dev/null
+++ b/usr.bin/lzmainfo/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/liblzma \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/m4/Makefile.depend b/usr.bin/m4/Makefile.depend
new file mode 100644
index 0000000..4953149
--- /dev/null
+++ b/usr.bin/m4/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/liby \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+parser.o: parser.c
+parser.po: parser.c
+tokenizer.o: parser.h
+tokenizer.o: tokenizer.c
+tokenizer.po: parser.h
+tokenizer.po: tokenizer.c
+.endif
diff --git a/usr.bin/mail/Makefile.depend b/usr.bin/mail/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/mail/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/make/Makefile.depend b/usr.bin/make/Makefile.depend
new file mode 100644
index 0000000..eba5cd5
--- /dev/null
+++ b/usr.bin/make/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/makewhatis/Makefile.depend b/usr.bin/makewhatis/Makefile.depend
new file mode 100644
index 0000000..1e192bd
--- /dev/null
+++ b/usr.bin/makewhatis/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/man/Makefile.depend b/usr.bin/man/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.bin/man/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/mesg/Makefile.depend b/usr.bin/mesg/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/mesg/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/minigzip/Makefile.depend b/usr.bin/minigzip/Makefile.depend
new file mode 100644
index 0000000..1e192bd
--- /dev/null
+++ b/usr.bin/minigzip/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ministat/Makefile.depend b/usr.bin/ministat/Makefile.depend
new file mode 100644
index 0000000..d78f7b7
--- /dev/null
+++ b/usr.bin/ministat/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/mkcsmapper_static/Makefile.depend b/usr.bin/mkcsmapper_static/Makefile.depend
new file mode 100644
index 0000000..c9b7aa9
--- /dev/null
+++ b/usr.bin/mkcsmapper_static/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+lex.o: lex.c
+lex.o: yacc.h
+lex.po: lex.c
+lex.po: yacc.h
+yacc.o: yacc.c
+yacc.po: yacc.c
+.endif
diff --git a/usr.bin/mkdep/Makefile.depend b/usr.bin/mkdep/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.bin/mkdep/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/mkfifo/Makefile.depend b/usr.bin/mkfifo/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/mkfifo/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/mklocale/Makefile.depend b/usr.bin/mklocale/Makefile.depend
new file mode 100644
index 0000000..293b44b
--- /dev/null
+++ b/usr.bin/mklocale/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+lex.o: lex.c
+lex.o: y.tab.h
+lex.po: lex.c
+lex.po: y.tab.h
+yacc.o: yacc.c
+yacc.po: yacc.c
+.endif
diff --git a/usr.bin/mkstr/Makefile.depend b/usr.bin/mkstr/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/mkstr/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/mktemp/Makefile.depend b/usr.bin/mktemp/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/mktemp/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/mkulzma/Makefile.depend b/usr.bin/mkulzma/Makefile.depend
new file mode 100644
index 0000000..5a47d9e
--- /dev/null
+++ b/usr.bin/mkulzma/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/liblzma \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/mkuzip/Makefile.depend b/usr.bin/mkuzip/Makefile.depend
new file mode 100644
index 0000000..1e192bd
--- /dev/null
+++ b/usr.bin/mkuzip/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/msgs/Makefile.depend b/usr.bin/msgs/Makefile.depend
new file mode 100644
index 0000000..c74c89f
--- /dev/null
+++ b/usr.bin/msgs/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/mt/Makefile.depend b/usr.bin/mt/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/mt/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/nc/Makefile.depend b/usr.bin/nc/Makefile.depend
new file mode 100644
index 0000000..c068132
--- /dev/null
+++ b/usr.bin/nc/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipsec \
+ lib/libtelnet \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ncal/Makefile.depend b/usr.bin/ncal/Makefile.depend
new file mode 100644
index 0000000..f07d640
--- /dev/null
+++ b/usr.bin/ncal/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcalendar \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ncplist/Makefile.depend b/usr.bin/ncplist/Makefile.depend
new file mode 100644
index 0000000..bfecf09
--- /dev/null
+++ b/usr.bin/ncplist/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipx \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ncplogin/Makefile.depend b/usr.bin/ncplogin/Makefile.depend
new file mode 100644
index 0000000..bfecf09
--- /dev/null
+++ b/usr.bin/ncplogin/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipx \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/netstat/Makefile.depend b/usr.bin/netstat/Makefile.depend
new file mode 100644
index 0000000..64ea564
--- /dev/null
+++ b/usr.bin/netstat/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipx \
+ lib/libkvm \
+ lib/libmemstat \
+ lib/libnetgraph \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/newgrp/Makefile.depend b/usr.bin/newgrp/Makefile.depend
new file mode 100644
index 0000000..cf2b455
--- /dev/null
+++ b/usr.bin/newgrp/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/newkey/Makefile.depend b/usr.bin/newkey/Makefile.depend
new file mode 100644
index 0000000..6e85033
--- /dev/null
+++ b/usr.bin/newkey/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmp \
+ lib/librpcsvc \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/nfsstat/Makefile.depend b/usr.bin/nfsstat/Makefile.depend
new file mode 100644
index 0000000..553674c
--- /dev/null
+++ b/usr.bin/nfsstat/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/nice/Makefile.depend b/usr.bin/nice/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/nice/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/nl/Makefile.depend b/usr.bin/nl/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/nl/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/nohup/Makefile.depend b/usr.bin/nohup/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/nohup/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/nslookup/Makefile.depend b/usr.bin/nslookup/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.bin/nslookup/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/nsupdate/Makefile.depend b/usr.bin/nsupdate/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.bin/nsupdate/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/opieinfo/Makefile.depend b/usr.bin/opieinfo/Makefile.depend
new file mode 100644
index 0000000..3dd961e
--- /dev/null
+++ b/usr.bin/opieinfo/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/libopie \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/opiekey/Makefile.depend b/usr.bin/opiekey/Makefile.depend
new file mode 100644
index 0000000..3dd961e
--- /dev/null
+++ b/usr.bin/opiekey/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/libopie \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/opiepasswd/Makefile.depend b/usr.bin/opiepasswd/Makefile.depend
new file mode 100644
index 0000000..3dd961e
--- /dev/null
+++ b/usr.bin/opiepasswd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/libopie \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/pagesize/Makefile.depend b/usr.bin/pagesize/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.bin/pagesize/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/pamtest/Makefile.depend b/usr.bin/pamtest/Makefile.depend
new file mode 100644
index 0000000..d6d3563
--- /dev/null
+++ b/usr.bin/pamtest/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libpam/libpam \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/passwd/Makefile.depend b/usr.bin/passwd/Makefile.depend
new file mode 100644
index 0000000..28fb49b
--- /dev/null
+++ b/usr.bin/passwd/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libpam/libpam \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/paste/Makefile.depend b/usr.bin/paste/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/paste/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/pathchk/Makefile.depend b/usr.bin/pathchk/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/pathchk/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/perror/Makefile.depend b/usr.bin/perror/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/perror/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/pr/Makefile.depend b/usr.bin/pr/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/pr/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/printenv/Makefile.depend b/usr.bin/printenv/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/printenv/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/printf/Makefile.depend b/usr.bin/printf/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/printf/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/procstat/Makefile.depend b/usr.bin/procstat/Makefile.depend
new file mode 100644
index 0000000..0dbdff2
--- /dev/null
+++ b/usr.bin/procstat/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ lib/libprocstat \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/quota/Makefile.depend b/usr.bin/quota/Makefile.depend
new file mode 100644
index 0000000..bf35174
--- /dev/null
+++ b/usr.bin/quota/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/rctl/Makefile.depend b/usr.bin/rctl/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.bin/rctl/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/renice/Makefile.depend b/usr.bin/renice/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/renice/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/rev/Makefile.depend b/usr.bin/rev/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/rev/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/revoke/Makefile.depend b/usr.bin/revoke/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/revoke/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/rlogin/Makefile.depend b/usr.bin/rlogin/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/rlogin/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/rpcgen/Makefile.depend b/usr.bin/rpcgen/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/rpcgen/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/rpcinfo/Makefile.depend b/usr.bin/rpcinfo/Makefile.depend
new file mode 100644
index 0000000..43e53d5
--- /dev/null
+++ b/usr.bin/rpcinfo/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/rs/Makefile.depend b/usr.bin/rs/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/rs/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/rsh/Makefile.depend b/usr.bin/rsh/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.bin/rsh/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/rup/Makefile.depend b/usr.bin/rup/Makefile.depend
new file mode 100644
index 0000000..2693011
--- /dev/null
+++ b/usr.bin/rup/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ruptime/Makefile.depend b/usr.bin/ruptime/Makefile.depend
new file mode 100644
index 0000000..25ca344
--- /dev/null
+++ b/usr.bin/ruptime/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/rusers/Makefile.depend b/usr.bin/rusers/Makefile.depend
new file mode 100644
index 0000000..2693011
--- /dev/null
+++ b/usr.bin/rusers/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/rwall/Makefile.depend b/usr.bin/rwall/Makefile.depend
new file mode 100644
index 0000000..6e9b14f
--- /dev/null
+++ b/usr.bin/rwall/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/rwho/Makefile.depend b/usr.bin/rwho/Makefile.depend
new file mode 100644
index 0000000..25ca344
--- /dev/null
+++ b/usr.bin/rwho/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/script/Makefile.depend b/usr.bin/script/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.bin/script/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/sed/Makefile.depend b/usr.bin/sed/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/sed/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/seq/Makefile.depend b/usr.bin/seq/Makefile.depend
new file mode 100644
index 0000000..d78f7b7
--- /dev/null
+++ b/usr.bin/seq/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/setchannel/Makefile.depend b/usr.bin/setchannel/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/setchannel/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/shar/Makefile.depend b/usr.bin/shar/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.bin/shar/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/showmount/Makefile.depend b/usr.bin/showmount/Makefile.depend
new file mode 100644
index 0000000..6e9b14f
--- /dev/null
+++ b/usr.bin/showmount/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/smbutil/Makefile.depend b/usr.bin/smbutil/Makefile.depend
new file mode 100644
index 0000000..f09f976
--- /dev/null
+++ b/usr.bin/smbutil/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkiconv \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/sockstat/Makefile.depend b/usr.bin/sockstat/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.bin/sockstat/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/sort/Makefile.depend b/usr.bin/sort/Makefile.depend
new file mode 100644
index 0000000..1313c32
--- /dev/null
+++ b/usr.bin/sort/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/libthr \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/split/Makefile.depend b/usr.bin/split/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/split/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/stat/Makefile.depend b/usr.bin/stat/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/stat/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/stdbuf/Makefile.depend b/usr.bin/stdbuf/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/stdbuf/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/su/Makefile.depend b/usr.bin/su/Makefile.depend
new file mode 100644
index 0000000..ef1e74a
--- /dev/null
+++ b/usr.bin/su/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbsm \
+ lib/libc \
+ lib/libpam/libpam \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/systat/Makefile.depend b/usr.bin/systat/Makefile.depend
new file mode 100644
index 0000000..e190a31
--- /dev/null
+++ b/usr.bin/systat/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libdevstat \
+ lib/libkvm \
+ lib/msun \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tabs/Makefile.depend b/usr.bin/tabs/Makefile.depend
new file mode 100644
index 0000000..c74c89f
--- /dev/null
+++ b/usr.bin/tabs/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tail/Makefile.depend b/usr.bin/tail/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/tail/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/talk/Makefile.depend b/usr.bin/talk/Makefile.depend
new file mode 100644
index 0000000..b352c71
--- /dev/null
+++ b/usr.bin/talk/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tar/Makefile.depend b/usr.bin/tar/Makefile.depend
new file mode 100644
index 0000000..97f5f95
--- /dev/null
+++ b/usr.bin/tar/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libarchive \
+ lib/libbz2 \
+ lib/libc \
+ lib/libexpat \
+ lib/liblzma \
+ lib/libz \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tcopy/Makefile.depend b/usr.bin/tcopy/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/tcopy/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tee/Makefile.depend b/usr.bin/tee/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/tee/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/telnet/Makefile.depend b/usr.bin/telnet/Makefile.depend
new file mode 100644
index 0000000..f76673a
--- /dev/null
+++ b/usr.bin/telnet/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ kerberos5/lib/libasn1 \
+ kerberos5/lib/libhx509 \
+ kerberos5/lib/libkrb5 \
+ kerberos5/lib/libroken \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcom_err \
+ lib/libcrypt \
+ lib/libipsec \
+ lib/libmp \
+ lib/libpam/libpam \
+ lib/libtelnet \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tftp/Makefile.depend b/usr.bin/tftp/Makefile.depend
new file mode 100644
index 0000000..501fd51
--- /dev/null
+++ b/usr.bin/tftp/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/time/Makefile.depend b/usr.bin/time/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/time/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tip/tip/Makefile.depend b/usr.bin/tip/tip/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/tip/tip/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/top/Makefile.depend b/usr.bin/top/Makefile.depend
new file mode 100644
index 0000000..2f52b59
--- /dev/null
+++ b/usr.bin/top/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ lib/msun \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+commands.o: sigdesc.h
+commands.po: sigdesc.h
+display.o: top.local.h
+display.po: top.local.h
+top.o: top.local.h
+top.po: top.local.h
+username.o: top.local.h
+username.po: top.local.h
+.endif
diff --git a/usr.bin/touch/Makefile.depend b/usr.bin/touch/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/touch/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tput/Makefile.depend b/usr.bin/tput/Makefile.depend
new file mode 100644
index 0000000..c74c89f
--- /dev/null
+++ b/usr.bin/tput/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tr/Makefile.depend b/usr.bin/tr/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/tr/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/true/Makefile.depend b/usr.bin/true/Makefile.depend
new file mode 100644
index 0000000..7267a8a
--- /dev/null
+++ b/usr.bin/true/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/truncate/Makefile.depend b/usr.bin/truncate/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.bin/truncate/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/truss/Makefile.depend b/usr.bin/truss/Makefile.depend
new file mode 100644
index 0000000..a0c7882
--- /dev/null
+++ b/usr.bin/truss/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+i386-fbsd.o: syscalls.h
+i386-fbsd.po: syscalls.h
+i386-linux.o: linux_syscalls.h
+i386-linux.po: linux_syscalls.h
+ioctl.o: ioctl.c
+ioctl.po: ioctl.c
+.endif
diff --git a/usr.bin/tset/Makefile.depend b/usr.bin/tset/Makefile.depend
new file mode 100644
index 0000000..c74c89f
--- /dev/null
+++ b/usr.bin/tset/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tsort/Makefile.depend b/usr.bin/tsort/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/tsort/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/tty/Makefile.depend b/usr.bin/tty/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/tty/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ul/Makefile.depend b/usr.bin/ul/Makefile.depend
new file mode 100644
index 0000000..c74c89f
--- /dev/null
+++ b/usr.bin/ul/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/uname/Makefile.depend b/usr.bin/uname/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/uname/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/unexpand/Makefile.depend b/usr.bin/unexpand/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/unexpand/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/unifdef/Makefile.depend b/usr.bin/unifdef/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/unifdef/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/uniq/Makefile.depend b/usr.bin/uniq/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/uniq/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/units/Makefile.depend b/usr.bin/units/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/units/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/unvis/Makefile.depend b/usr.bin/unvis/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/unvis/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/unzip/Makefile.depend b/usr.bin/unzip/Makefile.depend
new file mode 100644
index 0000000..7a6a31a
--- /dev/null
+++ b/usr.bin/unzip/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libarchive \
+ lib/libc \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/usbhidaction/Makefile.depend b/usr.bin/usbhidaction/Makefile.depend
new file mode 100644
index 0000000..f29032c
--- /dev/null
+++ b/usr.bin/usbhidaction/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libusbhid \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/usbhidctl/Makefile.depend b/usr.bin/usbhidctl/Makefile.depend
new file mode 100644
index 0000000..f29032c
--- /dev/null
+++ b/usr.bin/usbhidctl/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libusbhid \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/users/Makefile.depend b/usr.bin/users/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/users/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/uudecode/Makefile.depend b/usr.bin/uudecode/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.bin/uudecode/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/uuencode/Makefile.depend b/usr.bin/uuencode/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.bin/uuencode/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/vacation/Makefile.depend b/usr.bin/vacation/Makefile.depend
new file mode 100644
index 0000000..8af48f5
--- /dev/null
+++ b/usr.bin/vacation/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsm \
+ lib/libsmdb \
+ lib/libsmutil \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+vacation.o: sm_os.h
+vacation.po: sm_os.h
+.endif
diff --git a/usr.bin/vgrind/Makefile.depend b/usr.bin/vgrind/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/vgrind/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/vgrind/RETEST/Makefile.depend b/usr.bin/vgrind/RETEST/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/vgrind/RETEST/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/vi/Makefile.depend b/usr.bin/vi/Makefile.depend
new file mode 100644
index 0000000..c74c89f
--- /dev/null
+++ b/usr.bin/vi/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/vis/Makefile.depend b/usr.bin/vis/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/vis/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/vmstat/Makefile.depend b/usr.bin/vmstat/Makefile.depend
new file mode 100644
index 0000000..1a73c8d
--- /dev/null
+++ b/usr.bin/vmstat/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libdevstat \
+ lib/libkvm \
+ lib/libmemstat \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/w/Makefile.depend b/usr.bin/w/Makefile.depend
new file mode 100644
index 0000000..12b0105
--- /dev/null
+++ b/usr.bin/w/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/wall/Makefile.depend b/usr.bin/wall/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/wall/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/wc/Makefile.depend b/usr.bin/wc/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/wc/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/what/Makefile.depend b/usr.bin/what/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/what/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/whereis/Makefile.depend b/usr.bin/whereis/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/whereis/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/which/Makefile.depend b/usr.bin/which/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/which/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/who/Makefile.depend b/usr.bin/who/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/who/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/whois/Makefile.depend b/usr.bin/whois/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.bin/whois/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/write/Makefile.depend b/usr.bin/write/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/write/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/xargs/Makefile.depend b/usr.bin/xargs/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/xargs/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/xinstall/Makefile.depend b/usr.bin/xinstall/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/xinstall/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/xlint/lint1/Makefile.depend b/usr.bin/xlint/lint1/Makefile.depend
new file mode 100644
index 0000000..60d2a9b
--- /dev/null
+++ b/usr.bin/xlint/lint1/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+cgram.o: cgram.c
+cgram.po: cgram.c
+func.o: cgram.h
+func.po: cgram.h
+scan.o: cgram.h
+scan.o: scan.c
+scan.po: cgram.h
+scan.po: scan.c
+tree.o: cgram.h
+tree.po: cgram.h
+.endif
diff --git a/usr.bin/xlint/lint2/Makefile.depend b/usr.bin/xlint/lint2/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/xlint/lint2/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/xlint/llib/Makefile.depend b/usr.bin/xlint/llib/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.bin/xlint/llib/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/xlint/xlint/Makefile.depend b/usr.bin/xlint/xlint/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/xlint/xlint/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/xstr/Makefile.depend b/usr.bin/xstr/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/xstr/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/xz/Makefile.depend b/usr.bin/xz/Makefile.depend
new file mode 100644
index 0000000..5a47d9e
--- /dev/null
+++ b/usr.bin/xz/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/liblzma \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/xzdec/Makefile.depend b/usr.bin/xzdec/Makefile.depend
new file mode 100644
index 0000000..5a47d9e
--- /dev/null
+++ b/usr.bin/xzdec/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/liblzma \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/yacc/Makefile.depend b/usr.bin/yacc/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.bin/yacc/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/yes/Makefile.depend b/usr.bin/yes/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.bin/yes/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ypcat/Makefile.depend b/usr.bin/ypcat/Makefile.depend
new file mode 100644
index 0000000..6e9b14f
--- /dev/null
+++ b/usr.bin/ypcat/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ypmatch/Makefile.depend b/usr.bin/ypmatch/Makefile.depend
new file mode 100644
index 0000000..6e9b14f
--- /dev/null
+++ b/usr.bin/ypmatch/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.bin/ypwhich/Makefile.depend b/usr.bin/ypwhich/Makefile.depend
new file mode 100644
index 0000000..a3e1b44
--- /dev/null
+++ b/usr.bin/ypwhich/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/IPXrouted/Makefile.depend b/usr.sbin/IPXrouted/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/IPXrouted/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ac/Makefile.depend b/usr.sbin/ac/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/ac/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/accton/Makefile.depend b/usr.sbin/accton/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/accton/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/acpi/acpiconf/Makefile.depend b/usr.sbin/acpi/acpiconf/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/acpi/acpiconf/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/acpi/acpidb/Makefile.depend b/usr.sbin/acpi/acpidb/Makefile.depend
new file mode 100644
index 0000000..a274268
--- /dev/null
+++ b/usr.sbin/acpi/acpidb/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libthr \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/acpi/acpidump/Makefile.depend b/usr.sbin/acpi/acpidump/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/acpi/acpidump/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/acpi/iasl/Makefile.depend b/usr.sbin/acpi/iasl/Makefile.depend
new file mode 100644
index 0000000..ffc65ca
--- /dev/null
+++ b/usr.sbin/acpi/iasl/Makefile.depend
@@ -0,0 +1,87 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+aslanalyze.o: aslcompiler.y.h
+aslanalyze.po: aslcompiler.y.h
+aslbtypes.o: aslcompiler.y.h
+aslbtypes.po: aslcompiler.y.h
+aslcodegen.o: aslcompiler.y.h
+aslcodegen.po: aslcompiler.y.h
+aslcompilerlex.o: aslcompiler.y.h
+aslcompilerlex.o: aslcompilerlex.c
+aslcompilerlex.po: aslcompiler.y.h
+aslcompilerlex.po: aslcompilerlex.c
+aslcompilerparse.o: aslcompilerparse.c
+aslcompilerparse.po: aslcompilerparse.c
+aslfold.o: aslcompiler.y.h
+aslfold.po: aslcompiler.y.h
+asllength.o: aslcompiler.y.h
+asllength.po: aslcompiler.y.h
+asllisting.o: aslcompiler.y.h
+asllisting.po: aslcompiler.y.h
+aslload.o: aslcompiler.y.h
+aslload.po: aslcompiler.y.h
+asllookup.o: aslcompiler.y.h
+asllookup.po: aslcompiler.y.h
+aslopcodes.o: aslcompiler.y.h
+aslopcodes.po: aslcompiler.y.h
+asloperands.o: aslcompiler.y.h
+asloperands.po: aslcompiler.y.h
+aslopt.o: aslcompiler.y.h
+aslopt.po: aslcompiler.y.h
+aslpredef.o: aslcompiler.y.h
+aslpredef.po: aslcompiler.y.h
+aslresource.o: aslcompiler.y.h
+aslresource.po: aslcompiler.y.h
+aslrestype1.o: aslcompiler.y.h
+aslrestype1.po: aslcompiler.y.h
+aslrestype1i.o: aslcompiler.y.h
+aslrestype1i.po: aslcompiler.y.h
+aslrestype2.o: aslcompiler.y.h
+aslrestype2.po: aslcompiler.y.h
+aslrestype2d.o: aslcompiler.y.h
+aslrestype2d.po: aslcompiler.y.h
+aslrestype2q.o: aslcompiler.y.h
+aslrestype2q.po: aslcompiler.y.h
+aslrestype2s.o: aslcompiler.y.h
+aslrestype2s.po: aslcompiler.y.h
+aslrestype2w.o: aslcompiler.y.h
+aslrestype2w.po: aslcompiler.y.h
+asltransform.o: aslcompiler.y.h
+asltransform.po: aslcompiler.y.h
+asltree.o: aslcompiler.y.h
+asltree.po: aslcompiler.y.h
+aslutils.o: aslcompiler.y.h
+aslutils.po: aslcompiler.y.h
+aslwalks.o: aslcompiler.y.h
+aslwalks.po: aslcompiler.y.h
+dtexpress.o: dtparser.y.h
+dtexpress.po: dtparser.y.h
+dtparserlex.o: dtparser.y.h
+dtparserlex.o: dtparserlex.c
+dtparserlex.po: dtparser.y.h
+dtparserlex.po: dtparserlex.c
+dtparserparse.o: dtparserparse.c
+dtparserparse.po: dtparserparse.c
+prparserlex.o: prparser.y.h
+prparserlex.o: prparserlex.c
+prparserlex.po: prparser.y.h
+prparserlex.po: prparserlex.c
+prparserparse.o: prparserparse.c
+prparserparse.po: prparserparse.c
+.endif
diff --git a/usr.sbin/adduser/Makefile.depend b/usr.sbin/adduser/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/adduser/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/amd/amd/Makefile.depend b/usr.sbin/amd/amd/Makefile.depend
new file mode 100644
index 0000000..fd1a688
--- /dev/null
+++ b/usr.sbin/amd/amd/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+ usr.sbin/amd/include \
+ usr.sbin/amd/libamu \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+conf_parse.o: conf_parse.c
+conf_parse.po: conf_parse.c
+conf_tok.o: conf_parse.h
+conf_tok.o: conf_tok.c
+conf_tok.po: conf_parse.h
+conf_tok.po: conf_tok.c
+mount_xdr.o: mount_xdr.c
+mount_xdr.po: mount_xdr.c
+.endif
diff --git a/usr.sbin/amd/amq/Makefile.depend b/usr.sbin/amd/amq/Makefile.depend
new file mode 100644
index 0000000..66f893e
--- /dev/null
+++ b/usr.sbin/amd/amq/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+ usr.sbin/amd/include \
+ usr.sbin/amd/libamu \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/amd/fixmount/Makefile.depend b/usr.sbin/amd/fixmount/Makefile.depend
new file mode 100644
index 0000000..1ed02e5
--- /dev/null
+++ b/usr.sbin/amd/fixmount/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+ lib/libwrap \
+ usr.sbin/amd/include \
+ usr.sbin/amd/libamu \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/amd/fsinfo/Makefile.depend b/usr.sbin/amd/fsinfo/Makefile.depend
new file mode 100644
index 0000000..63070f4
--- /dev/null
+++ b/usr.sbin/amd/fsinfo/Makefile.depend
@@ -0,0 +1,33 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+ usr.sbin/amd/include \
+ usr.sbin/amd/libamu \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+fsi_gram.o: fsi_gram.c
+fsi_gram.po: fsi_gram.c
+fsi_lex.o: fsi_gram.h
+fsi_lex.o: fsi_lex.c
+fsi_lex.po: fsi_gram.h
+fsi_lex.po: fsi_lex.c
+fsinfo.o: fsi_gram.h
+fsinfo.po: fsi_gram.h
+.endif
diff --git a/usr.sbin/amd/hlfsd/Makefile.depend b/usr.sbin/amd/hlfsd/Makefile.depend
new file mode 100644
index 0000000..66f893e
--- /dev/null
+++ b/usr.sbin/amd/hlfsd/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+ usr.sbin/amd/include \
+ usr.sbin/amd/libamu \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/amd/include/Makefile.depend b/usr.sbin/amd/include/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/amd/include/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/amd/libamu/Makefile.depend b/usr.sbin/amd/libamu/Makefile.depend
new file mode 100644
index 0000000..a0399ce
--- /dev/null
+++ b/usr.sbin/amd/libamu/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/libwrap \
+ usr.sbin/amd/include \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+nfs_prot_x.o: nfs_prot_x.c
+nfs_prot_x.po: nfs_prot_x.c
+xdr_func_%undef.o: xdr_func_%undef.c
+xdr_func_%undef.po: xdr_func_%undef.c
+.endif
diff --git a/usr.sbin/amd/mk-amd-map/Makefile.depend b/usr.sbin/amd/mk-amd-map/Makefile.depend
new file mode 100644
index 0000000..66f893e
--- /dev/null
+++ b/usr.sbin/amd/mk-amd-map/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+ usr.sbin/amd/include \
+ usr.sbin/amd/libamu \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/amd/pawd/Makefile.depend b/usr.sbin/amd/pawd/Makefile.depend
new file mode 100644
index 0000000..66f893e
--- /dev/null
+++ b/usr.sbin/amd/pawd/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+ usr.sbin/amd/include \
+ usr.sbin/amd/libamu \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/amd/scripts/Makefile.depend b/usr.sbin/amd/scripts/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/amd/scripts/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/amd/wire-test/Makefile.depend b/usr.sbin/amd/wire-test/Makefile.depend
new file mode 100644
index 0000000..66f893e
--- /dev/null
+++ b/usr.sbin/amd/wire-test/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+ usr.sbin/amd/include \
+ usr.sbin/amd/libamu \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ancontrol/Makefile.depend b/usr.sbin/ancontrol/Makefile.depend
new file mode 100644
index 0000000..f7894b5
--- /dev/null
+++ b/usr.sbin/ancontrol/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/apm/Makefile.depend b/usr.sbin/apm/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/apm/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/apmd/Makefile.depend b/usr.sbin/apmd/Makefile.depend
new file mode 100644
index 0000000..554c4cc
--- /dev/null
+++ b/usr.sbin/apmd/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+apmdlex.o: apmdlex.c
+apmdlex.o: y.tab.h
+apmdlex.po: apmdlex.c
+apmdlex.po: y.tab.h
+apmdparse.o: apmdparse.c
+apmdparse.po: apmdparse.c
+.endif
diff --git a/usr.sbin/arp/Makefile.depend b/usr.sbin/arp/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/arp/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/arpaname/Makefile.depend b/usr.sbin/arpaname/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/arpaname/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/asf/Makefile.depend b/usr.sbin/asf/Makefile.depend
new file mode 100644
index 0000000..553674c
--- /dev/null
+++ b/usr.sbin/asf/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/audit/Makefile.depend b/usr.sbin/audit/Makefile.depend
new file mode 100644
index 0000000..1aedff5
--- /dev/null
+++ b/usr.sbin/audit/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbsm \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/auditd/Makefile.depend b/usr.sbin/auditd/Makefile.depend
new file mode 100644
index 0000000..e062403
--- /dev/null
+++ b/usr.sbin/auditd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libauditd \
+ lib/libbsm \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/auditreduce/Makefile.depend b/usr.sbin/auditreduce/Makefile.depend
new file mode 100644
index 0000000..1aedff5
--- /dev/null
+++ b/usr.sbin/auditreduce/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbsm \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/authpf/Makefile.depend b/usr.sbin/authpf/Makefile.depend
new file mode 100644
index 0000000..157f511
--- /dev/null
+++ b/usr.sbin/authpf/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/libutil \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bluetooth/ath3kfw/Makefile.depend b/usr.sbin/bluetooth/ath3kfw/Makefile.depend
new file mode 100644
index 0000000..f779151
--- /dev/null
+++ b/usr.sbin/bluetooth/ath3kfw/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libusb \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bluetooth/bcmfw/Makefile.depend b/usr.sbin/bluetooth/bcmfw/Makefile.depend
new file mode 100644
index 0000000..e6d80d3
--- /dev/null
+++ b/usr.sbin/bluetooth/bcmfw/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libnetgraph \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bluetooth/bt3cfw/Makefile.depend b/usr.sbin/bluetooth/bt3cfw/Makefile.depend
new file mode 100644
index 0000000..e6d80d3
--- /dev/null
+++ b/usr.sbin/bluetooth/bt3cfw/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libnetgraph \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bluetooth/bthidcontrol/Makefile.depend b/usr.sbin/bluetooth/bthidcontrol/Makefile.depend
new file mode 100644
index 0000000..bf7f962
--- /dev/null
+++ b/usr.sbin/bluetooth/bthidcontrol/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+ lib/libsdp \
+ lib/libusbhid \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+lexer.o: lexer.c
+lexer.o: parser.h
+lexer.po: lexer.c
+lexer.po: parser.h
+parser.o: parser.c
+parser.po: parser.c
+.endif
diff --git a/usr.sbin/bluetooth/bthidd/Makefile.depend b/usr.sbin/bluetooth/bthidd/Makefile.depend
new file mode 100644
index 0000000..61ae926
--- /dev/null
+++ b/usr.sbin/bluetooth/bthidd/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+ lib/libusbhid \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+lexer.o: lexer.c
+lexer.o: parser.h
+lexer.po: lexer.c
+lexer.po: parser.h
+parser.o: parser.c
+parser.po: parser.c
+.endif
diff --git a/usr.sbin/bluetooth/btpand/Makefile.depend b/usr.sbin/bluetooth/btpand/Makefile.depend
new file mode 100644
index 0000000..336a9db
--- /dev/null
+++ b/usr.sbin/bluetooth/btpand/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+ lib/libsdp \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bluetooth/hccontrol/Makefile.depend b/usr.sbin/bluetooth/hccontrol/Makefile.depend
new file mode 100644
index 0000000..e188ca8
--- /dev/null
+++ b/usr.sbin/bluetooth/hccontrol/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bluetooth/hcsecd/Makefile.depend b/usr.sbin/bluetooth/hcsecd/Makefile.depend
new file mode 100644
index 0000000..d800014
--- /dev/null
+++ b/usr.sbin/bluetooth/hcsecd/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+lexer.o: lexer.c
+lexer.o: parser.h
+lexer.po: lexer.c
+lexer.po: parser.h
+parser.o: parser.c
+parser.po: parser.c
+.endif
diff --git a/usr.sbin/bluetooth/hcseriald/Makefile.depend b/usr.sbin/bluetooth/hcseriald/Makefile.depend
new file mode 100644
index 0000000..e6d80d3
--- /dev/null
+++ b/usr.sbin/bluetooth/hcseriald/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libnetgraph \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bluetooth/l2control/Makefile.depend b/usr.sbin/bluetooth/l2control/Makefile.depend
new file mode 100644
index 0000000..e188ca8
--- /dev/null
+++ b/usr.sbin/bluetooth/l2control/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bluetooth/l2ping/Makefile.depend b/usr.sbin/bluetooth/l2ping/Makefile.depend
new file mode 100644
index 0000000..ff4e7a5
--- /dev/null
+++ b/usr.sbin/bluetooth/l2ping/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bluetooth/rfcomm_pppd/Makefile.depend b/usr.sbin/bluetooth/rfcomm_pppd/Makefile.depend
new file mode 100644
index 0000000..b3a6c2b
--- /dev/null
+++ b/usr.sbin/bluetooth/rfcomm_pppd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+ lib/libsdp \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bluetooth/sdpcontrol/Makefile.depend b/usr.sbin/bluetooth/sdpcontrol/Makefile.depend
new file mode 100644
index 0000000..b3a6c2b
--- /dev/null
+++ b/usr.sbin/bluetooth/sdpcontrol/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+ lib/libsdp \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bluetooth/sdpd/Makefile.depend b/usr.sbin/bluetooth/sdpd/Makefile.depend
new file mode 100644
index 0000000..e98dae0
--- /dev/null
+++ b/usr.sbin/bluetooth/sdpd/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbluetooth \
+ lib/libc \
+ lib/libsdp \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/boot0cfg/Makefile.depend b/usr.sbin/boot0cfg/Makefile.depend
new file mode 100644
index 0000000..378b35f
--- /dev/null
+++ b/usr.sbin/boot0cfg/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libexpat \
+ lib/libgeom \
+ lib/libsbuf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/boot98cfg/Makefile.depend b/usr.sbin/boot98cfg/Makefile.depend
new file mode 100644
index 0000000..25f093b
--- /dev/null
+++ b/usr.sbin/boot98cfg/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgeom \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bootparamd/bootparamd/Makefile.depend b/usr.sbin/bootparamd/bootparamd/Makefile.depend
new file mode 100644
index 0000000..4a1ecc5
--- /dev/null
+++ b/usr.sbin/bootparamd/bootparamd/Makefile.depend
@@ -0,0 +1,34 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+bootparam_prot_svc.o: bootparam_prot.h
+bootparam_prot_svc.o: bootparam_prot_svc.c
+bootparam_prot_svc.po: bootparam_prot.h
+bootparam_prot_svc.po: bootparam_prot_svc.c
+bootparam_prot_xdr.o: bootparam_prot.h
+bootparam_prot_xdr.o: bootparam_prot_xdr.c
+bootparam_prot_xdr.po: bootparam_prot.h
+bootparam_prot_xdr.po: bootparam_prot_xdr.c
+bootparamd.o: bootparam_prot.h
+bootparamd.po: bootparam_prot.h
+main.o: bootparam_prot.h
+main.po: bootparam_prot.h
+.endif
diff --git a/usr.sbin/bootparamd/callbootd/Makefile.depend b/usr.sbin/bootparamd/callbootd/Makefile.depend
new file mode 100644
index 0000000..a134d08
--- /dev/null
+++ b/usr.sbin/bootparamd/callbootd/Makefile.depend
@@ -0,0 +1,31 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+bootparam_prot_clnt.o: bootparam_prot.h
+bootparam_prot_clnt.o: bootparam_prot_clnt.c
+bootparam_prot_clnt.po: bootparam_prot.h
+bootparam_prot_clnt.po: bootparam_prot_clnt.c
+bootparam_prot_xdr.o: bootparam_prot.h
+bootparam_prot_xdr.o: bootparam_prot_xdr.c
+bootparam_prot_xdr.po: bootparam_prot.h
+bootparam_prot_xdr.po: bootparam_prot_xdr.c
+callbootd.o: bootparam_prot.h
+callbootd.po: bootparam_prot.h
+.endif
diff --git a/usr.sbin/bsdinstall/Makefile.depend b/usr.sbin/bsdinstall/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/bsdinstall/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bsdinstall/distextract/Makefile.depend b/usr.sbin/bsdinstall/distextract/Makefile.depend
new file mode 100644
index 0000000..975ca25
--- /dev/null
+++ b/usr.sbin/bsdinstall/distextract/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libdialog \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libarchive \
+ lib/libc \
+ lib/msun \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bsdinstall/distfetch/Makefile.depend b/usr.sbin/bsdinstall/distfetch/Makefile.depend
new file mode 100644
index 0000000..2c289cd
--- /dev/null
+++ b/usr.sbin/bsdinstall/distfetch/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libdialog \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libfetch \
+ lib/msun \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bsdinstall/partedit/Makefile.depend b/usr.sbin/bsdinstall/partedit/Makefile.depend
new file mode 100644
index 0000000..2ec2bb4
--- /dev/null
+++ b/usr.sbin/bsdinstall/partedit/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libdialog \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgeom \
+ lib/libutil \
+ lib/msun \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bsnmpd/bsnmpd/Makefile.depend b/usr.sbin/bsnmpd/bsnmpd/Makefile.depend
new file mode 100644
index 0000000..6b34d29
--- /dev/null
+++ b/usr.sbin/bsnmpd/bsnmpd/Makefile.depend
@@ -0,0 +1,51 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbegemot \
+ lib/libbsnmp/libbsnmp \
+ lib/libc \
+ lib/libwrap \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+action.o: oid.h
+action.o: tree.h
+action.po: oid.h
+action.po: tree.h
+config.o: tree.h
+config.po: tree.h
+export.o: tree.h
+export.po: tree.h
+main.o: oid.h
+main.o: tree.h
+main.po: oid.h
+main.po: tree.h
+trans_lsock.o: oid.h
+trans_lsock.o: tree.h
+trans_lsock.po: oid.h
+trans_lsock.po: tree.h
+trans_udp.o: oid.h
+trans_udp.o: tree.h
+trans_udp.po: oid.h
+trans_udp.po: tree.h
+trap.o: oid.h
+trap.o: tree.h
+trap.po: oid.h
+trap.po: tree.h
+tree.o: tree.c
+tree.o: tree.h
+tree.po: tree.c
+tree.po: tree.h
+.endif
diff --git a/usr.sbin/bsnmpd/gensnmptree/Makefile.depend b/usr.sbin/bsnmpd/gensnmptree/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/bsnmpd/gensnmptree/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bsnmpd/modules/Makefile.depend b/usr.sbin/bsnmpd/modules/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bsnmpd/modules/snmp_atm/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_atm/Makefile.depend
new file mode 100644
index 0000000..6c0e842
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_atm/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libbsnmp/libbsnmp \
+ usr.sbin/bsnmpd/modules \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+atm_sys.So: atm_oid.h
+atm_sys.So: atm_tree.h
+atm_sys.po: atm_oid.h
+atm_sys.po: atm_tree.h
+atm_tree.So: atm_tree.c
+atm_tree.So: atm_tree.h
+atm_tree.po: atm_tree.c
+atm_tree.po: atm_tree.h
+snmp_atm.So: atm_oid.h
+snmp_atm.So: atm_tree.h
+snmp_atm.po: atm_oid.h
+snmp_atm.po: atm_tree.h
+.endif
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_bridge/Makefile.depend
new file mode 100644
index 0000000..6399234
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/Makefile.depend
@@ -0,0 +1,38 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libbsnmp/libbsnmp \
+ usr.sbin/bsnmpd/modules \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+bridge_addrs.So: bridge_tree.h
+bridge_addrs.po: bridge_tree.h
+bridge_if.So: bridge_oid.h
+bridge_if.So: bridge_tree.h
+bridge_if.po: bridge_oid.h
+bridge_if.po: bridge_tree.h
+bridge_pf.So: bridge_tree.h
+bridge_pf.po: bridge_tree.h
+bridge_port.So: bridge_tree.h
+bridge_port.po: bridge_tree.h
+bridge_snmp.So: bridge_oid.h
+bridge_snmp.So: bridge_tree.h
+bridge_snmp.po: bridge_oid.h
+bridge_snmp.po: bridge_tree.h
+bridge_sys.So: bridge_tree.h
+bridge_sys.po: bridge_tree.h
+bridge_tree.So: bridge_tree.c
+bridge_tree.So: bridge_tree.h
+bridge_tree.po: bridge_tree.c
+bridge_tree.po: bridge_tree.h
+.endif
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile.depend
new file mode 100644
index 0000000..ea8cdcf
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile.depend
@@ -0,0 +1,79 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libbsnmp/libbsnmp \
+ lib/libdevinfo \
+ lib/libgeom \
+ lib/libkvm \
+ lib/libmemstat \
+ lib/msun \
+ usr.sbin/bsnmpd/modules \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+hostres_begemot.So: hostres_oid.h
+hostres_begemot.So: hostres_tree.h
+hostres_begemot.po: hostres_oid.h
+hostres_begemot.po: hostres_tree.h
+hostres_device_tbl.So: hostres_oid.h
+hostres_device_tbl.So: hostres_tree.h
+hostres_device_tbl.po: hostres_oid.h
+hostres_device_tbl.po: hostres_tree.h
+hostres_diskstorage_tbl.So: hostres_oid.h
+hostres_diskstorage_tbl.So: hostres_tree.h
+hostres_diskstorage_tbl.po: hostres_oid.h
+hostres_diskstorage_tbl.po: hostres_tree.h
+hostres_fs_tbl.So: hostres_oid.h
+hostres_fs_tbl.So: hostres_tree.h
+hostres_fs_tbl.po: hostres_oid.h
+hostres_fs_tbl.po: hostres_tree.h
+hostres_network_tbl.So: hostres_oid.h
+hostres_network_tbl.So: hostres_tree.h
+hostres_network_tbl.po: hostres_oid.h
+hostres_network_tbl.po: hostres_tree.h
+hostres_partition_tbl.So: hostres_oid.h
+hostres_partition_tbl.So: hostres_tree.h
+hostres_partition_tbl.po: hostres_oid.h
+hostres_partition_tbl.po: hostres_tree.h
+hostres_printer_tbl.So: hostres_oid.h
+hostres_printer_tbl.So: hostres_tree.h
+hostres_printer_tbl.po: hostres_oid.h
+hostres_printer_tbl.po: hostres_tree.h
+hostres_processor_tbl.So: hostres_oid.h
+hostres_processor_tbl.So: hostres_tree.h
+hostres_processor_tbl.po: hostres_oid.h
+hostres_processor_tbl.po: hostres_tree.h
+hostres_scalars.So: hostres_oid.h
+hostres_scalars.So: hostres_tree.h
+hostres_scalars.po: hostres_oid.h
+hostres_scalars.po: hostres_tree.h
+hostres_snmp.So: hostres_oid.h
+hostres_snmp.So: hostres_tree.h
+hostres_snmp.po: hostres_oid.h
+hostres_snmp.po: hostres_tree.h
+hostres_storage_tbl.So: hostres_oid.h
+hostres_storage_tbl.So: hostres_tree.h
+hostres_storage_tbl.po: hostres_oid.h
+hostres_storage_tbl.po: hostres_tree.h
+hostres_swinstalled_tbl.So: hostres_oid.h
+hostres_swinstalled_tbl.So: hostres_tree.h
+hostres_swinstalled_tbl.po: hostres_oid.h
+hostres_swinstalled_tbl.po: hostres_tree.h
+hostres_swrun_tbl.So: hostres_oid.h
+hostres_swrun_tbl.So: hostres_tree.h
+hostres_swrun_tbl.po: hostres_oid.h
+hostres_swrun_tbl.po: hostres_tree.h
+hostres_tree.So: hostres_tree.c
+hostres_tree.So: hostres_tree.h
+hostres_tree.po: hostres_tree.c
+hostres_tree.po: hostres_tree.h
+.endif
diff --git a/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile.depend
new file mode 100644
index 0000000..118a7bd
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_mibII/Makefile.depend
@@ -0,0 +1,68 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libbsnmp/libbsnmp \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+mibII.So: mibII_oid.h
+mibII.So: mibII_tree.h
+mibII.po: mibII_oid.h
+mibII.po: mibII_tree.h
+mibII_begemot.So: mibII_oid.h
+mibII_begemot.So: mibII_tree.h
+mibII_begemot.po: mibII_oid.h
+mibII_begemot.po: mibII_tree.h
+mibII_ifmib.So: mibII_oid.h
+mibII_ifmib.So: mibII_tree.h
+mibII_ifmib.po: mibII_oid.h
+mibII_ifmib.po: mibII_tree.h
+mibII_ifstack.So: mibII_tree.h
+mibII_ifstack.po: mibII_tree.h
+mibII_interfaces.So: mibII_oid.h
+mibII_interfaces.So: mibII_tree.h
+mibII_interfaces.po: mibII_oid.h
+mibII_interfaces.po: mibII_tree.h
+mibII_ip.So: mibII_oid.h
+mibII_ip.So: mibII_tree.h
+mibII_ip.po: mibII_oid.h
+mibII_ip.po: mibII_tree.h
+mibII_ipaddr.So: mibII_oid.h
+mibII_ipaddr.So: mibII_tree.h
+mibII_ipaddr.po: mibII_oid.h
+mibII_ipaddr.po: mibII_tree.h
+mibII_nettomedia.So: mibII_oid.h
+mibII_nettomedia.So: mibII_tree.h
+mibII_nettomedia.po: mibII_oid.h
+mibII_nettomedia.po: mibII_tree.h
+mibII_rcvaddr.So: mibII_oid.h
+mibII_rcvaddr.So: mibII_tree.h
+mibII_rcvaddr.po: mibII_oid.h
+mibII_rcvaddr.po: mibII_tree.h
+mibII_route.So: mibII_oid.h
+mibII_route.So: mibII_tree.h
+mibII_route.po: mibII_oid.h
+mibII_route.po: mibII_tree.h
+mibII_tcp.So: mibII_oid.h
+mibII_tcp.So: mibII_tree.h
+mibII_tcp.po: mibII_oid.h
+mibII_tcp.po: mibII_tree.h
+mibII_tree.So: mibII_tree.c
+mibII_tree.So: mibII_tree.h
+mibII_tree.po: mibII_tree.c
+mibII_tree.po: mibII_tree.h
+mibII_udp.So: mibII_oid.h
+mibII_udp.So: mibII_tree.h
+mibII_udp.po: mibII_oid.h
+mibII_udp.po: mibII_tree.h
+.endif
diff --git a/usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile.depend
new file mode 100644
index 0000000..e5425f3
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_netgraph/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libbsnmp/libbsnmp \
+ lib/libnetgraph \
+ usr.sbin/bsnmpd/modules \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+netgraph_tree.So: netgraph_tree.c
+netgraph_tree.So: netgraph_tree.h
+netgraph_tree.po: netgraph_tree.c
+netgraph_tree.po: netgraph_tree.h
+snmp_netgraph.So: netgraph_oid.h
+snmp_netgraph.So: netgraph_tree.h
+snmp_netgraph.po: netgraph_oid.h
+snmp_netgraph.po: netgraph_tree.h
+.endif
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_pf/Makefile.depend
new file mode 100644
index 0000000..a1ecc91
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libbsnmp/libbsnmp \
+ usr.sbin/bsnmpd/modules \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+pf_snmp.So: pf_oid.h
+pf_snmp.So: pf_tree.h
+pf_snmp.po: pf_oid.h
+pf_snmp.po: pf_tree.h
+pf_tree.So: pf_tree.c
+pf_tree.So: pf_tree.h
+pf_tree.po: pf_tree.c
+pf_tree.po: pf_tree.h
+.endif
diff --git a/usr.sbin/bsnmpd/modules/snmp_target/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_target/Makefile.depend
new file mode 100644
index 0000000..5d9de80
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_target/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libbsnmp/libbsnmp \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+target_snmp.So: target_oid.h
+target_snmp.So: target_tree.h
+target_snmp.po: target_oid.h
+target_snmp.po: target_tree.h
+target_tree.So: target_tree.c
+target_tree.So: target_tree.h
+target_tree.po: target_tree.c
+target_tree.po: target_tree.h
+.endif
diff --git a/usr.sbin/bsnmpd/modules/snmp_usm/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_usm/Makefile.depend
new file mode 100644
index 0000000..bf3304a
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_usm/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libbsnmp/libbsnmp \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+usm_snmp.So: usm_oid.h
+usm_snmp.So: usm_tree.h
+usm_snmp.po: usm_oid.h
+usm_snmp.po: usm_tree.h
+usm_tree.So: usm_tree.c
+usm_tree.So: usm_tree.h
+usm_tree.po: usm_tree.c
+usm_tree.po: usm_tree.h
+.endif
diff --git a/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile.depend
new file mode 100644
index 0000000..0c08629
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_vacm/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libbsnmp/libbsnmp \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+vacm_snmp.So: vacm_oid.h
+vacm_snmp.So: vacm_tree.h
+vacm_snmp.po: vacm_oid.h
+vacm_snmp.po: vacm_tree.h
+vacm_tree.So: vacm_tree.c
+vacm_tree.So: vacm_tree.h
+vacm_tree.po: vacm_tree.c
+vacm_tree.po: vacm_tree.h
+.endif
diff --git a/usr.sbin/bsnmpd/modules/snmp_wlan/Makefile.depend b/usr.sbin/bsnmpd/modules/snmp_wlan/Makefile.depend
new file mode 100644
index 0000000..3c1e872
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_wlan/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libbsnmp/libbsnmp \
+ usr.sbin/bsnmpd/modules \
+ usr.sbin/bsnmpd/modules/snmp_mibII \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+wlan_snmp.So: wlan_oid.h
+wlan_snmp.So: wlan_tree.h
+wlan_snmp.po: wlan_oid.h
+wlan_snmp.po: wlan_tree.h
+wlan_sys.So: wlan_tree.h
+wlan_sys.po: wlan_tree.h
+wlan_tree.So: wlan_tree.c
+wlan_tree.So: wlan_tree.h
+wlan_tree.po: wlan_tree.c
+wlan_tree.po: wlan_tree.h
+.endif
diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/Makefile.depend b/usr.sbin/bsnmpd/tools/bsnmptools/Makefile.depend
new file mode 100644
index 0000000..58da794
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/bsnmptools/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbsnmp/libbsnmp \
+ lib/libc \
+ secure/lib/libcrypto \
+ usr.sbin/bsnmpd/tools/libbsnmptools \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/Makefile.depend b/usr.sbin/bsnmpd/tools/libbsnmptools/Makefile.depend
new file mode 100644
index 0000000..05587d8
--- /dev/null
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libbsnmp/libbsnmp \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/btxld/Makefile.depend b/usr.sbin/btxld/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/btxld/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/burncd/Makefile.depend b/usr.sbin/burncd/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/burncd/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/cdcontrol/Makefile.depend b/usr.sbin/cdcontrol/Makefile.depend
new file mode 100644
index 0000000..501fd51
--- /dev/null
+++ b/usr.sbin/cdcontrol/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/chkgrp/Makefile.depend b/usr.sbin/chkgrp/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/chkgrp/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/chown/Makefile.depend b/usr.sbin/chown/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/chown/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/chroot/Makefile.depend b/usr.sbin/chroot/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/chroot/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ckdist/Makefile.depend b/usr.sbin/ckdist/Makefile.depend
new file mode 100644
index 0000000..7520d5d
--- /dev/null
+++ b/usr.sbin/ckdist/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/clear_locks/Makefile.depend b/usr.sbin/clear_locks/Makefile.depend
new file mode 100644
index 0000000..60fe900
--- /dev/null
+++ b/usr.sbin/clear_locks/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/config/Makefile.depend b/usr.sbin/config/Makefile.depend
new file mode 100644
index 0000000..d414840
--- /dev/null
+++ b/usr.sbin/config/Makefile.depend
@@ -0,0 +1,36 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsbuf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+config.o: config.c
+config.po: config.c
+kernconf.o: kernconf.c
+kernconf.po: kernconf.c
+lang.o: lang.c
+lang.o: y.tab.h
+lang.po: lang.c
+lang.po: y.tab.h
+main.o: y.tab.h
+main.po: y.tab.h
+mkheaders.o: y.tab.h
+mkheaders.po: y.tab.h
+mkmakefile.o: y.tab.h
+mkmakefile.po: y.tab.h
+mkoptions.o: y.tab.h
+mkoptions.po: y.tab.h
+.endif
diff --git a/usr.sbin/cpucontrol/Makefile.depend b/usr.sbin/cpucontrol/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/cpucontrol/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/crashinfo/Makefile.depend b/usr.sbin/crashinfo/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/crashinfo/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/cron/cron/Makefile.depend b/usr.sbin/cron/cron/Makefile.depend
new file mode 100644
index 0000000..e033fdf
--- /dev/null
+++ b/usr.sbin/cron/cron/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libpam/libpam \
+ lib/libutil \
+ usr.sbin/cron/lib \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/cron/crontab/Makefile.depend b/usr.sbin/cron/crontab/Makefile.depend
new file mode 100644
index 0000000..faa54bd
--- /dev/null
+++ b/usr.sbin/cron/crontab/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/libutil \
+ usr.sbin/cron/lib \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/cron/lib/Makefile.depend b/usr.sbin/cron/lib/Makefile.depend
new file mode 100644
index 0000000..4046f0e
--- /dev/null
+++ b/usr.sbin/cron/lib/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/crunch/crunchgen/Makefile.depend b/usr.sbin/crunch/crunchgen/Makefile.depend
new file mode 100644
index 0000000..56c209e
--- /dev/null
+++ b/usr.sbin/crunch/crunchgen/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+crunched_skel.o: crunched_skel.c
+crunched_skel.po: crunched_skel.c
+.endif
diff --git a/usr.sbin/crunch/crunchide/Makefile.depend b/usr.sbin/crunch/crunchide/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/crunch/crunchide/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ctladm/Makefile.depend b/usr.sbin/ctladm/Makefile.depend
new file mode 100644
index 0000000..7dcf1b8
--- /dev/null
+++ b/usr.sbin/ctladm/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcam \
+ lib/libexpat \
+ lib/libsbuf \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ctm/ctm/Makefile.depend b/usr.sbin/ctm/ctm/Makefile.depend
new file mode 100644
index 0000000..7520d5d
--- /dev/null
+++ b/usr.sbin/ctm/ctm/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ctm/ctm_dequeue/Makefile.depend b/usr.sbin/ctm/ctm_dequeue/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/ctm/ctm_dequeue/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ctm/ctm_rmail/Makefile.depend b/usr.sbin/ctm/ctm_rmail/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/ctm/ctm_rmail/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ctm/ctm_smail/Makefile.depend b/usr.sbin/ctm/ctm_smail/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/ctm/ctm_smail/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/daemon/Makefile.depend b/usr.sbin/daemon/Makefile.depend
new file mode 100644
index 0000000..2530420
--- /dev/null
+++ b/usr.sbin/daemon/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/dconschat/Makefile.depend b/usr.sbin/dconschat/Makefile.depend
new file mode 100644
index 0000000..6e3782c
--- /dev/null
+++ b/usr.sbin/dconschat/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ lib/libtelnet \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ddns-confgen/Makefile.depend b/usr.sbin/ddns-confgen/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/ddns-confgen/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/devinfo/Makefile.depend b/usr.sbin/devinfo/Makefile.depend
new file mode 100644
index 0000000..36a5a32
--- /dev/null
+++ b/usr.sbin/devinfo/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libdevinfo \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/digictl/Makefile.depend b/usr.sbin/digictl/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/digictl/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/diskinfo/Makefile.depend b/usr.sbin/diskinfo/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.sbin/diskinfo/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/dnssec-dsfromkey/Makefile.depend b/usr.sbin/dnssec-dsfromkey/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/dnssec-dsfromkey/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/dnssec-keyfromlabel/Makefile.depend b/usr.sbin/dnssec-keyfromlabel/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/dnssec-keyfromlabel/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/dnssec-keygen/Makefile.depend b/usr.sbin/dnssec-keygen/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/dnssec-keygen/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/dnssec-revoke/Makefile.depend b/usr.sbin/dnssec-revoke/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/dnssec-revoke/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/dnssec-settime/Makefile.depend b/usr.sbin/dnssec-settime/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/dnssec-settime/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/dnssec-signzone/Makefile.depend b/usr.sbin/dnssec-signzone/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/dnssec-signzone/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/dumpcis/Makefile.depend b/usr.sbin/dumpcis/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/dumpcis/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/editmap/Makefile.depend b/usr.sbin/editmap/Makefile.depend
new file mode 100644
index 0000000..48902cc
--- /dev/null
+++ b/usr.sbin/editmap/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsm \
+ lib/libsmdb \
+ lib/libsmutil \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+editmap.o: sm_os.h
+editmap.po: sm_os.h
+.endif
diff --git a/usr.sbin/edquota/Makefile.depend b/usr.sbin/edquota/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.sbin/edquota/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/eeprom/Makefile.depend b/usr.sbin/eeprom/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/eeprom/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/extattr/Makefile.depend b/usr.sbin/extattr/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.sbin/extattr/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/extattrctl/Makefile.depend b/usr.sbin/extattrctl/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.sbin/extattrctl/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/faithd/Makefile.depend b/usr.sbin/faithd/Makefile.depend
new file mode 100644
index 0000000..c262920
--- /dev/null
+++ b/usr.sbin/faithd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/fdcontrol/Makefile.depend b/usr.sbin/fdcontrol/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/fdcontrol/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/fdformat/Makefile.depend b/usr.sbin/fdformat/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/fdformat/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/fdread/Makefile.depend b/usr.sbin/fdread/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/fdread/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/fdwrite/Makefile.depend b/usr.sbin/fdwrite/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/fdwrite/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/fifolog/fifolog_create/Makefile.depend b/usr.sbin/fifolog/fifolog_create/Makefile.depend
new file mode 100644
index 0000000..46df9bb
--- /dev/null
+++ b/usr.sbin/fifolog/fifolog_create/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+ usr.sbin/fifolog/lib \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/fifolog/fifolog_reader/Makefile.depend b/usr.sbin/fifolog/fifolog_reader/Makefile.depend
new file mode 100644
index 0000000..5b0d32e
--- /dev/null
+++ b/usr.sbin/fifolog/fifolog_reader/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+ lib/libz \
+ usr.sbin/fifolog/lib \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/fifolog/fifolog_writer/Makefile.depend b/usr.sbin/fifolog/fifolog_writer/Makefile.depend
new file mode 100644
index 0000000..5b0d32e
--- /dev/null
+++ b/usr.sbin/fifolog/fifolog_writer/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+ lib/libz \
+ usr.sbin/fifolog/lib \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/fifolog/lib/Makefile.depend b/usr.sbin/fifolog/lib/Makefile.depend
new file mode 100644
index 0000000..e28547c
--- /dev/null
+++ b/usr.sbin/fifolog/lib/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libz \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+getdate.o: getdate.c
+getdate.po: getdate.c
+.endif
diff --git a/usr.sbin/flowctl/Makefile.depend b/usr.sbin/flowctl/Makefile.depend
new file mode 100644
index 0000000..1835644
--- /dev/null
+++ b/usr.sbin/flowctl/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libnetgraph \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/freebsd-update/Makefile.depend b/usr.sbin/freebsd-update/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/freebsd-update/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ftp-proxy/ftp-proxy/Makefile.depend b/usr.sbin/ftp-proxy/ftp-proxy/Makefile.depend
new file mode 100644
index 0000000..dd343ad
--- /dev/null
+++ b/usr.sbin/ftp-proxy/ftp-proxy/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ usr.sbin/ftp-proxy/libevent \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ftp-proxy/libevent/Makefile.depend b/usr.sbin/ftp-proxy/libevent/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/usr.sbin/ftp-proxy/libevent/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/fwcontrol/Makefile.depend b/usr.sbin/fwcontrol/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/fwcontrol/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/genrandom/Makefile.depend b/usr.sbin/genrandom/Makefile.depend
new file mode 100644
index 0000000..418e041
--- /dev/null
+++ b/usr.sbin/genrandom/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/getfmac/Makefile.depend b/usr.sbin/getfmac/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/getfmac/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/getpmac/Makefile.depend b/usr.sbin/getpmac/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/getpmac/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/gpioctl/Makefile.depend b/usr.sbin/gpioctl/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/gpioctl/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/gssd/Makefile.depend b/usr.sbin/gssd/Makefile.depend
new file mode 100644
index 0000000..cdbb525
--- /dev/null
+++ b/usr.sbin/gssd/Makefile.depend
@@ -0,0 +1,34 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/gssapi \
+ include/rpc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libgssapi \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+gssd.o: gssd.h
+gssd.po: gssd.h
+gssd_prot.o: gssd.h
+gssd_prot.po: gssd.h
+gssd_svc.o: gssd.h
+gssd_svc.o: gssd_svc.c
+gssd_svc.po: gssd.h
+gssd_svc.po: gssd_svc.c
+gssd_xdr.o: gssd.h
+gssd_xdr.o: gssd_xdr.c
+gssd_xdr.po: gssd.h
+gssd_xdr.po: gssd_xdr.c
+.endif
diff --git a/usr.sbin/gstat/Makefile.depend b/usr.sbin/gstat/Makefile.depend
new file mode 100644
index 0000000..b5ed130
--- /dev/null
+++ b/usr.sbin/gstat/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libdevstat \
+ lib/libedit \
+ lib/libexpat \
+ lib/libgeom \
+ lib/libkvm \
+ lib/libsbuf \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/i2c/Makefile.depend b/usr.sbin/i2c/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/i2c/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ifmcstat/Makefile.depend b/usr.sbin/ifmcstat/Makefile.depend
new file mode 100644
index 0000000..e6478bb
--- /dev/null
+++ b/usr.sbin/ifmcstat/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/inetd/Makefile.depend b/usr.sbin/inetd/Makefile.depend
new file mode 100644
index 0000000..e9ba4b9
--- /dev/null
+++ b/usr.sbin/inetd/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipsec \
+ lib/libutil \
+ lib/libwrap \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/iostat/Makefile.depend b/usr.sbin/iostat/Makefile.depend
new file mode 100644
index 0000000..022357f
--- /dev/null
+++ b/usr.sbin/iostat/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libdevstat \
+ lib/libkvm \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ip6addrctl/Makefile.depend b/usr.sbin/ip6addrctl/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/ip6addrctl/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ipfwpcap/Makefile.depend b/usr.sbin/ipfwpcap/Makefile.depend
new file mode 100644
index 0000000..447f532
--- /dev/null
+++ b/usr.sbin/ipfwpcap/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libpcap \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/isc-hmac-fixup/Makefile.depend b/usr.sbin/isc-hmac-fixup/Makefile.depend
new file mode 100644
index 0000000..418e041
--- /dev/null
+++ b/usr.sbin/isc-hmac-fixup/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/jail/Makefile.depend b/usr.sbin/jail/Makefile.depend
new file mode 100644
index 0000000..e3e2159
--- /dev/null
+++ b/usr.sbin/jail/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libjail \
+ lib/libkvm \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+jaillex.o: jaillex.c
+jaillex.o: y.tab.h
+jaillex.po: jaillex.c
+jaillex.po: y.tab.h
+jailparse.o: jailparse.c
+jailparse.po: jailparse.c
+.endif
diff --git a/usr.sbin/jexec/Makefile.depend b/usr.sbin/jexec/Makefile.depend
new file mode 100644
index 0000000..5c682ee
--- /dev/null
+++ b/usr.sbin/jexec/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libjail \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/jls/Makefile.depend b/usr.sbin/jls/Makefile.depend
new file mode 100644
index 0000000..3d5f6ab
--- /dev/null
+++ b/usr.sbin/jls/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libjail \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/kbdcontrol/Makefile.depend b/usr.sbin/kbdcontrol/Makefile.depend
new file mode 100644
index 0000000..37e3bbd
--- /dev/null
+++ b/usr.sbin/kbdcontrol/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+lex.o: lex.c
+lex.po: lex.c
+.endif
diff --git a/usr.sbin/kbdmap/Makefile.depend b/usr.sbin/kbdmap/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/kbdmap/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/keyserv/Makefile.depend b/usr.sbin/keyserv/Makefile.depend
new file mode 100644
index 0000000..e5b3b87
--- /dev/null
+++ b/usr.sbin/keyserv/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmp \
+ lib/librpcsvc \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+crypt_server.o: crypt.h
+crypt_server.po: crypt.h
+crypt_svc.o: crypt.h
+crypt_svc.o: crypt_svc.c
+crypt_svc.po: crypt.h
+crypt_svc.po: crypt_svc.c
+.endif
diff --git a/usr.sbin/kgmon/Makefile.depend b/usr.sbin/kgmon/Makefile.depend
new file mode 100644
index 0000000..553674c
--- /dev/null
+++ b/usr.sbin/kgmon/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/kgzip/Makefile.depend b/usr.sbin/kgzip/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/kgzip/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/kldxref/Makefile.depend b/usr.sbin/kldxref/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/kldxref/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lastlogin/Makefile.depend b/usr.sbin/lastlogin/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/lastlogin/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lmcconfig/Makefile.depend b/usr.sbin/lmcconfig/Makefile.depend
new file mode 100644
index 0000000..e6d80d3
--- /dev/null
+++ b/usr.sbin/lmcconfig/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libnetgraph \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/chkprintcap/Makefile.depend b/usr.sbin/lpr/chkprintcap/Makefile.depend
new file mode 100644
index 0000000..2eeeb7a
--- /dev/null
+++ b/usr.sbin/lpr/chkprintcap/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ usr.sbin/lpr/common_source \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/common_source/Makefile.depend b/usr.sbin/lpr/common_source/Makefile.depend
new file mode 100644
index 0000000..e54ec8c
--- /dev/null
+++ b/usr.sbin/lpr/common_source/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/filters.ru/Makefile.depend b/usr.sbin/lpr/filters.ru/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/lpr/filters.ru/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/filters.ru/koi2855/Makefile.depend b/usr.sbin/lpr/filters.ru/koi2855/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.sbin/lpr/filters.ru/koi2855/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/filters.ru/koi2alt/Makefile.depend b/usr.sbin/lpr/filters.ru/koi2alt/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.sbin/lpr/filters.ru/koi2alt/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/filters/Makefile.depend b/usr.sbin/lpr/filters/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/lpr/filters/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/lp/Makefile.depend b/usr.sbin/lpr/lp/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/lpr/lp/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/lpc/Makefile.depend b/usr.sbin/lpr/lpc/Makefile.depend
new file mode 100644
index 0000000..529eecd
--- /dev/null
+++ b/usr.sbin/lpr/lpc/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/ncurses/ncurses \
+ usr.sbin/lpr/common_source \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/lpd/Makefile.depend b/usr.sbin/lpr/lpd/Makefile.depend
new file mode 100644
index 0000000..a8a1c2b
--- /dev/null
+++ b/usr.sbin/lpr/lpd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ usr.sbin/lpr/common_source \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/lpq/Makefile.depend b/usr.sbin/lpr/lpq/Makefile.depend
new file mode 100644
index 0000000..2eeeb7a
--- /dev/null
+++ b/usr.sbin/lpr/lpq/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ usr.sbin/lpr/common_source \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/lpr/Makefile.depend b/usr.sbin/lpr/lpr/Makefile.depend
new file mode 100644
index 0000000..2eeeb7a
--- /dev/null
+++ b/usr.sbin/lpr/lpr/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ usr.sbin/lpr/common_source \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/lprm/Makefile.depend b/usr.sbin/lpr/lprm/Makefile.depend
new file mode 100644
index 0000000..2eeeb7a
--- /dev/null
+++ b/usr.sbin/lpr/lprm/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ usr.sbin/lpr/common_source \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/lptest/Makefile.depend b/usr.sbin/lpr/lptest/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.sbin/lpr/lptest/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lpr/pac/Makefile.depend b/usr.sbin/lpr/pac/Makefile.depend
new file mode 100644
index 0000000..2eeeb7a
--- /dev/null
+++ b/usr.sbin/lpr/pac/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ usr.sbin/lpr/common_source \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/lptcontrol/Makefile.depend b/usr.sbin/lptcontrol/Makefile.depend
new file mode 100644
index 0000000..ac1b131
--- /dev/null
+++ b/usr.sbin/lptcontrol/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mailstats/Makefile.depend b/usr.sbin/mailstats/Makefile.depend
new file mode 100644
index 0000000..19ee02b
--- /dev/null
+++ b/usr.sbin/mailstats/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsm \
+ lib/libsmutil \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+mailstats.o: sm_os.h
+mailstats.po: sm_os.h
+.endif
diff --git a/usr.sbin/mailwrapper/Makefile.depend b/usr.sbin/mailwrapper/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.sbin/mailwrapper/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/makefs/Makefile.depend b/usr.sbin/makefs/Makefile.depend
new file mode 100644
index 0000000..887c9bd
--- /dev/null
+++ b/usr.sbin/makefs/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsbuf \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/makemap/Makefile.depend b/usr.sbin/makemap/Makefile.depend
new file mode 100644
index 0000000..c1dc46a
--- /dev/null
+++ b/usr.sbin/makemap/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsm \
+ lib/libsmdb \
+ lib/libsmutil \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+makemap.o: sm_os.h
+makemap.po: sm_os.h
+.endif
diff --git a/usr.sbin/manctl/Makefile.depend b/usr.sbin/manctl/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/manctl/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/memcontrol/Makefile.depend b/usr.sbin/memcontrol/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/memcontrol/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mergemaster/Makefile.depend b/usr.sbin/mergemaster/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/mergemaster/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mfiutil/Makefile.depend b/usr.sbin/mfiutil/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.sbin/mfiutil/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mixer/Makefile.depend b/usr.sbin/mixer/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/mixer/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mld6query/Makefile.depend b/usr.sbin/mld6query/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/mld6query/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mlxcontrol/Makefile.depend b/usr.sbin/mlxcontrol/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/mlxcontrol/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mount_nwfs/Makefile.depend b/usr.sbin/mount_nwfs/Makefile.depend
new file mode 100644
index 0000000..bfecf09
--- /dev/null
+++ b/usr.sbin/mount_nwfs/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipx \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mount_portalfs/Makefile.depend b/usr.sbin/mount_portalfs/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/mount_portalfs/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mount_smbfs/Makefile.depend b/usr.sbin/mount_smbfs/Makefile.depend
new file mode 100644
index 0000000..18a3d5f
--- /dev/null
+++ b/usr.sbin/mount_smbfs/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkiconv \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mountd/Makefile.depend b/usr.sbin/mountd/Makefile.depend
new file mode 100644
index 0000000..7ca71be
--- /dev/null
+++ b/usr.sbin/mountd/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/moused/Makefile.depend b/usr.sbin/moused/Makefile.depend
new file mode 100644
index 0000000..8825ffd
--- /dev/null
+++ b/usr.sbin/moused/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mptable/Makefile.depend b/usr.sbin/mptable/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/mptable/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mptutil/Makefile.depend b/usr.sbin/mptutil/Makefile.depend
new file mode 100644
index 0000000..f9f3597
--- /dev/null
+++ b/usr.sbin/mptutil/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcam \
+ lib/libsbuf \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mtest/Makefile.depend b/usr.sbin/mtest/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/mtest/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/mtree/Makefile.depend b/usr.sbin/mtree/Makefile.depend
new file mode 100644
index 0000000..7520d5d
--- /dev/null
+++ b/usr.sbin/mtree/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/named-checkconf/Makefile.depend b/usr.sbin/named-checkconf/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/named-checkconf/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/named-checkzone/Makefile.depend b/usr.sbin/named-checkzone/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/named-checkzone/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/named-journalprint/Makefile.depend b/usr.sbin/named-journalprint/Makefile.depend
new file mode 100644
index 0000000..418e041
--- /dev/null
+++ b/usr.sbin/named-journalprint/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/named/Makefile.depend b/usr.sbin/named/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/named/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ndiscvt/Makefile.depend b/usr.sbin/ndiscvt/Makefile.depend
new file mode 100644
index 0000000..ee58cc4
--- /dev/null
+++ b/usr.sbin/ndiscvt/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+inf-parse.o: inf-parse.c
+inf-parse.po: inf-parse.c
+inf-token.o: inf-token.c
+inf-token.o: y.tab.h
+inf-token.po: inf-token.c
+inf-token.po: y.tab.h
+.endif
diff --git a/usr.sbin/ndp/Makefile.depend b/usr.sbin/ndp/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/ndp/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/newsyslog/Makefile.depend b/usr.sbin/newsyslog/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/newsyslog/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/nfscbd/Makefile.depend b/usr.sbin/nfscbd/Makefile.depend
new file mode 100644
index 0000000..1832799
--- /dev/null
+++ b/usr.sbin/nfscbd/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/nfsd/Makefile.depend b/usr.sbin/nfsd/Makefile.depend
new file mode 100644
index 0000000..a3e1b44
--- /dev/null
+++ b/usr.sbin/nfsd/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/nfsdumpstate/Makefile.depend b/usr.sbin/nfsdumpstate/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/nfsdumpstate/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/nfsrevoke/Makefile.depend b/usr.sbin/nfsrevoke/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/nfsrevoke/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/nfsuserd/Makefile.depend b/usr.sbin/nfsuserd/Makefile.depend
new file mode 100644
index 0000000..1832799
--- /dev/null
+++ b/usr.sbin/nfsuserd/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ngctl/Makefile.depend b/usr.sbin/ngctl/Makefile.depend
new file mode 100644
index 0000000..90942ad
--- /dev/null
+++ b/usr.sbin/ngctl/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/libnetgraph \
+ lib/libthr \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/nghook/Makefile.depend b/usr.sbin/nghook/Makefile.depend
new file mode 100644
index 0000000..e6d80d3
--- /dev/null
+++ b/usr.sbin/nghook/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libnetgraph \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/nologin/Makefile.depend b/usr.sbin/nologin/Makefile.depend
new file mode 100644
index 0000000..f5418c0
--- /dev/null
+++ b/usr.sbin/nologin/Makefile.depend
@@ -0,0 +1,17 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/nscd/Makefile.depend b/usr.sbin/nscd/Makefile.depend
new file mode 100644
index 0000000..0853258
--- /dev/null
+++ b/usr.sbin/nscd/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libthr \
+ lib/libutil \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/nsec3hash/Makefile.depend b/usr.sbin/nsec3hash/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/nsec3hash/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ntp/libntp/Makefile.depend b/usr.sbin/ntp/libntp/Makefile.depend
new file mode 100644
index 0000000..09476fe
--- /dev/null
+++ b/usr.sbin/ntp/libntp/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/libmd \
+ lib/msun \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ntp/libopts/Makefile.depend b/usr.sbin/ntp/libopts/Makefile.depend
new file mode 100644
index 0000000..e248139
--- /dev/null
+++ b/usr.sbin/ntp/libopts/Makefile.depend
@@ -0,0 +1,16 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ntp/libparse/Makefile.depend b/usr.sbin/ntp/libparse/Makefile.depend
new file mode 100644
index 0000000..db05d20
--- /dev/null
+++ b/usr.sbin/ntp/libparse/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/msun \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ntp/ntp-keygen/Makefile.depend b/usr.sbin/ntp/ntp-keygen/Makefile.depend
new file mode 100644
index 0000000..b26d4df
--- /dev/null
+++ b/usr.sbin/ntp/ntp-keygen/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ secure/lib/libcrypto \
+ usr.sbin/ntp/libntp \
+ usr.sbin/ntp/libopts \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ntp/ntpd/Makefile.depend b/usr.sbin/ntp/ntpd/Makefile.depend
new file mode 100644
index 0000000..72d3eb6
--- /dev/null
+++ b/usr.sbin/ntp/ntpd/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/librt \
+ lib/msun \
+ secure/lib/libcrypto \
+ usr.sbin/ntp/libntp \
+ usr.sbin/ntp/libopts \
+ usr.sbin/ntp/libparse \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+version.o: version.c
+version.po: version.c
+.endif
diff --git a/usr.sbin/ntp/ntpdate/Makefile.depend b/usr.sbin/ntp/ntpdate/Makefile.depend
new file mode 100644
index 0000000..b27014c
--- /dev/null
+++ b/usr.sbin/ntp/ntpdate/Makefile.depend
@@ -0,0 +1,27 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/librt \
+ lib/msun \
+ secure/lib/libcrypto \
+ usr.sbin/ntp/libntp \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+version.o: version.c
+version.po: version.c
+.endif
diff --git a/usr.sbin/ntp/ntpdc/Makefile.depend b/usr.sbin/ntp/ntpdc/Makefile.depend
new file mode 100644
index 0000000..80ce108
--- /dev/null
+++ b/usr.sbin/ntp/ntpdc/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/libedit/edit/readline \
+ lib/libmd \
+ lib/msun \
+ lib/ncurses/ncurses \
+ secure/lib/libcrypto \
+ usr.sbin/ntp/libntp \
+ usr.sbin/ntp/libopts \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+version.o: version.c
+version.po: version.c
+.endif
diff --git a/usr.sbin/ntp/ntpq/Makefile.depend b/usr.sbin/ntp/ntpq/Makefile.depend
new file mode 100644
index 0000000..80ce108
--- /dev/null
+++ b/usr.sbin/ntp/ntpq/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/libedit/edit/readline \
+ lib/libmd \
+ lib/msun \
+ lib/ncurses/ncurses \
+ secure/lib/libcrypto \
+ usr.sbin/ntp/libntp \
+ usr.sbin/ntp/libopts \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+version.o: version.c
+version.po: version.c
+.endif
diff --git a/usr.sbin/ntp/ntptime/Makefile.depend b/usr.sbin/ntp/ntptime/Makefile.depend
new file mode 100644
index 0000000..d4203a9
--- /dev/null
+++ b/usr.sbin/ntp/ntptime/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ usr.sbin/ntp/libntp \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ntp/sntp/Makefile.depend b/usr.sbin/ntp/sntp/Makefile.depend
new file mode 100644
index 0000000..84c4708
--- /dev/null
+++ b/usr.sbin/ntp/sntp/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+ usr.sbin/ntp/libopts \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ofwdump/Makefile.depend b/usr.sbin/ofwdump/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/ofwdump/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pc-sysinstall/backend-partmanager/Makefile.depend b/usr.sbin/pc-sysinstall/backend-partmanager/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/pc-sysinstall/backend-partmanager/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pc-sysinstall/backend-query/Makefile.depend b/usr.sbin/pc-sysinstall/backend-query/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/pc-sysinstall/backend-query/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pc-sysinstall/backend/Makefile.depend b/usr.sbin/pc-sysinstall/backend/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/pc-sysinstall/backend/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pc-sysinstall/conf/Makefile.depend b/usr.sbin/pc-sysinstall/conf/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/pc-sysinstall/conf/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pc-sysinstall/pc-sysinstall/Makefile.depend b/usr.sbin/pc-sysinstall/pc-sysinstall/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/pc-sysinstall/pc-sysinstall/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pciconf/Makefile.depend b/usr.sbin/pciconf/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/pciconf/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/periodic/Makefile.depend b/usr.sbin/periodic/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/periodic/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pkg/Makefile.depend b/usr.sbin/pkg/Makefile.depend
new file mode 100644
index 0000000..b097b19
--- /dev/null
+++ b/usr.sbin/pkg/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libarchive \
+ lib/libc \
+ lib/libelf \
+ lib/libfetch \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pkg_install/add/Makefile.depend b/usr.sbin/pkg_install/add/Makefile.depend
new file mode 100644
index 0000000..fa35fef
--- /dev/null
+++ b/usr.sbin/pkg_install/add/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libfetch \
+ lib/libmd \
+ lib/libutil \
+ secure/lib/libcrypto \
+ secure/lib/libssl \
+ usr.sbin/pkg_install/lib \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pkg_install/create/Makefile.depend b/usr.sbin/pkg_install/create/Makefile.depend
new file mode 100644
index 0000000..be409ac
--- /dev/null
+++ b/usr.sbin/pkg_install/create/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/libutil \
+ usr.sbin/pkg_install/lib \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pkg_install/delete/Makefile.depend b/usr.sbin/pkg_install/delete/Makefile.depend
new file mode 100644
index 0000000..be409ac
--- /dev/null
+++ b/usr.sbin/pkg_install/delete/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libmd \
+ lib/libutil \
+ usr.sbin/pkg_install/lib \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pkg_install/info/Makefile.depend b/usr.sbin/pkg_install/info/Makefile.depend
new file mode 100644
index 0000000..fa35fef
--- /dev/null
+++ b/usr.sbin/pkg_install/info/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libfetch \
+ lib/libmd \
+ lib/libutil \
+ secure/lib/libcrypto \
+ secure/lib/libssl \
+ usr.sbin/pkg_install/lib \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pkg_install/lib/Makefile.depend b/usr.sbin/pkg_install/lib/Makefile.depend
new file mode 100644
index 0000000..8d84ca1
--- /dev/null
+++ b/usr.sbin/pkg_install/lib/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+ lib/libfetch \
+ lib/libmd \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pkg_install/updating/Makefile.depend b/usr.sbin/pkg_install/updating/Makefile.depend
new file mode 100644
index 0000000..fa35fef
--- /dev/null
+++ b/usr.sbin/pkg_install/updating/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libfetch \
+ lib/libmd \
+ lib/libutil \
+ secure/lib/libcrypto \
+ secure/lib/libssl \
+ usr.sbin/pkg_install/lib \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pkg_install/version/Makefile.depend b/usr.sbin/pkg_install/version/Makefile.depend
new file mode 100644
index 0000000..fa35fef
--- /dev/null
+++ b/usr.sbin/pkg_install/version/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libfetch \
+ lib/libmd \
+ lib/libutil \
+ secure/lib/libcrypto \
+ secure/lib/libssl \
+ usr.sbin/pkg_install/lib \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pmcannotate/Makefile.depend b/usr.sbin/pmcannotate/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/pmcannotate/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pmccontrol/Makefile.depend b/usr.sbin/pmccontrol/Makefile.depend
new file mode 100644
index 0000000..43f31ea
--- /dev/null
+++ b/usr.sbin/pmccontrol/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libpmc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pmcstat/Makefile.depend b/usr.sbin/pmcstat/Makefile.depend
new file mode 100644
index 0000000..c2f6f64
--- /dev/null
+++ b/usr.sbin/pmcstat/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libelf \
+ lib/libkvm \
+ lib/libpmc \
+ lib/msun \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pnpinfo/Makefile.depend b/usr.sbin/pnpinfo/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/pnpinfo/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/portsnap/make_index/Makefile.depend b/usr.sbin/portsnap/make_index/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/portsnap/make_index/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/portsnap/phttpget/Makefile.depend b/usr.sbin/portsnap/phttpget/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/portsnap/phttpget/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/portsnap/portsnap/Makefile.depend b/usr.sbin/portsnap/portsnap/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/portsnap/portsnap/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/powerd/Makefile.depend b/usr.sbin/powerd/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.sbin/powerd/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ppp/Makefile.depend b/usr.sbin/ppp/Makefile.depend
new file mode 100644
index 0000000..7022136
--- /dev/null
+++ b/usr.sbin/ppp/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libalias/libalias \
+ lib/libc \
+ lib/libcrypt \
+ lib/libmd \
+ lib/libnetgraph \
+ lib/libpam/libpam \
+ lib/libradius \
+ lib/libutil \
+ lib/libz \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pppctl/Makefile.depend b/usr.sbin/pppctl/Makefile.depend
new file mode 100644
index 0000000..bc668b2
--- /dev/null
+++ b/usr.sbin/pppctl/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/libthr \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/praliases/Makefile.depend b/usr.sbin/praliases/Makefile.depend
new file mode 100644
index 0000000..fd254a5
--- /dev/null
+++ b/usr.sbin/praliases/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsm \
+ lib/libsmdb \
+ lib/libsmutil \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+praliases.o: sm_os.h
+praliases.po: sm_os.h
+.endif
diff --git a/usr.sbin/praudit/Makefile.depend b/usr.sbin/praudit/Makefile.depend
new file mode 100644
index 0000000..1aedff5
--- /dev/null
+++ b/usr.sbin/praudit/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libbsm \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/procctl/Makefile.depend b/usr.sbin/procctl/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/procctl/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pstat/Makefile.depend b/usr.sbin/pstat/Makefile.depend
new file mode 100644
index 0000000..f814107
--- /dev/null
+++ b/usr.sbin/pstat/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pw/Makefile.depend b/usr.sbin/pw/Makefile.depend
new file mode 100644
index 0000000..cf2b455
--- /dev/null
+++ b/usr.sbin/pw/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/pwd_mkdb/Makefile.depend b/usr.sbin/pwd_mkdb/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/pwd_mkdb/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/quot/Makefile.depend b/usr.sbin/quot/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/quot/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/quotaon/Makefile.depend b/usr.sbin/quotaon/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.sbin/quotaon/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rarpd/Makefile.depend b/usr.sbin/rarpd/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/rarpd/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/repquota/Makefile.depend b/usr.sbin/repquota/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.sbin/repquota/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rip6query/Makefile.depend b/usr.sbin/rip6query/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/rip6query/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rmt/Makefile.depend b/usr.sbin/rmt/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/rmt/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rndc-confgen/Makefile.depend b/usr.sbin/rndc-confgen/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/rndc-confgen/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rndc/Makefile.depend b/usr.sbin/rndc/Makefile.depend
new file mode 100644
index 0000000..78e28c0
--- /dev/null
+++ b/usr.sbin/rndc/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/bind/bind9 \
+ lib/bind/dns \
+ lib/bind/isc \
+ lib/bind/isccc \
+ lib/bind/isccfg \
+ lib/bind/lwres \
+ lib/libc \
+ lib/libthr \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/route6d/Makefile.depend b/usr.sbin/route6d/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/route6d/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rpc.lockd/Makefile.depend b/usr.sbin/rpc.lockd/Makefile.depend
new file mode 100644
index 0000000..5b47922
--- /dev/null
+++ b/usr.sbin/rpc.lockd/Makefile.depend
@@ -0,0 +1,26 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+nlm_prot_svc.o: nlm_prot_svc.c
+nlm_prot_svc.po: nlm_prot_svc.c
+.endif
diff --git a/usr.sbin/rpc.statd/Makefile.depend b/usr.sbin/rpc.statd/Makefile.depend
new file mode 100644
index 0000000..f541eb9
--- /dev/null
+++ b/usr.sbin/rpc.statd/Makefile.depend
@@ -0,0 +1,32 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+file.o: sm_inter.h
+file.po: sm_inter.h
+procs.o: sm_inter.h
+procs.po: sm_inter.h
+sm_inter_svc.o: sm_inter.h
+sm_inter_svc.o: sm_inter_svc.c
+sm_inter_svc.po: sm_inter.h
+sm_inter_svc.po: sm_inter_svc.c
+statd.o: sm_inter.h
+statd.po: sm_inter.h
+.endif
diff --git a/usr.sbin/rpc.umntall/Makefile.depend b/usr.sbin/rpc.umntall/Makefile.depend
new file mode 100644
index 0000000..6e9b14f
--- /dev/null
+++ b/usr.sbin/rpc.umntall/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rpc.yppasswdd/Makefile.depend b/usr.sbin/rpc.yppasswdd/Makefile.depend
new file mode 100644
index 0000000..52d3eca
--- /dev/null
+++ b/usr.sbin/rpc.yppasswdd/Makefile.depend
@@ -0,0 +1,49 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libcrypt \
+ lib/librpcsvc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+yp_clnt.o: yp.h
+yp_clnt.o: yp_clnt.c
+yp_clnt.po: yp.h
+yp_clnt.po: yp_clnt.c
+yppasswd_private_svc.o: yppasswd_private.h
+yppasswd_private_svc.o: yppasswd_private_svc.c
+yppasswd_private_svc.po: yppasswd_private.h
+yppasswd_private_svc.po: yppasswd_private_svc.c
+yppasswd_private_xdr.o: yppasswd_private.h
+yppasswd_private_xdr.o: yppasswd_private_xdr.c
+yppasswd_private_xdr.po: yppasswd_private.h
+yppasswd_private_xdr.po: yppasswd_private_xdr.c
+yppasswd_svc.o: yppasswd.h
+yppasswd_svc.o: yppasswd_svc.c
+yppasswd_svc.po: yppasswd.h
+yppasswd_svc.po: yppasswd_svc.c
+yppasswdd_main.o: yppasswd.h
+yppasswdd_main.o: yppasswd_private.h
+yppasswdd_main.po: yppasswd.h
+yppasswdd_main.po: yppasswd_private.h
+yppasswdd_server.o: yppasswd.h
+yppasswdd_server.o: yppasswd_private.h
+yppasswdd_server.po: yppasswd.h
+yppasswdd_server.po: yppasswd_private.h
+.endif
diff --git a/usr.sbin/rpc.ypupdated/Makefile.depend b/usr.sbin/rpc.ypupdated/Makefile.depend
new file mode 100644
index 0000000..51b99b7
--- /dev/null
+++ b/usr.sbin/rpc.ypupdated/Makefile.depend
@@ -0,0 +1,30 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ypupdate_prot_svc.o: ypupdate_prot.h
+ypupdate_prot_svc.o: ypupdate_prot_svc.c
+ypupdate_prot_svc.po: ypupdate_prot.h
+ypupdate_prot_svc.po: ypupdate_prot_svc.c
+ypupdated_main.o: ypupdate_prot.h
+ypupdated_main.po: ypupdate_prot.h
+ypupdated_server.o: ypupdate_prot.h
+ypupdated_server.po: ypupdate_prot.h
+.endif
diff --git a/usr.sbin/rpc.ypxfrd/Makefile.depend b/usr.sbin/rpc.ypxfrd/Makefile.depend
new file mode 100644
index 0000000..f5063de
--- /dev/null
+++ b/usr.sbin/rpc.ypxfrd/Makefile.depend
@@ -0,0 +1,31 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+ypxfrd_main.o: ypxfrd.h
+ypxfrd_main.po: ypxfrd.h
+ypxfrd_server.o: ypxfrd.h
+ypxfrd_server.po: ypxfrd.h
+ypxfrd_svc.o: ypxfrd.h
+ypxfrd_svc.o: ypxfrd_svc.c
+ypxfrd_svc.po: ypxfrd.h
+ypxfrd_svc.po: ypxfrd_svc.c
+.endif
diff --git a/usr.sbin/rpcbind/Makefile.depend b/usr.sbin/rpcbind/Makefile.depend
new file mode 100644
index 0000000..018259c
--- /dev/null
+++ b/usr.sbin/rpcbind/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+ lib/libwrap \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rrenumd/Makefile.depend b/usr.sbin/rrenumd/Makefile.depend
new file mode 100644
index 0000000..8b4e2b8
--- /dev/null
+++ b/usr.sbin/rrenumd/Makefile.depend
@@ -0,0 +1,28 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipsec \
+ lib/liby \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+lexer.o: lexer.c
+lexer.o: y.tab.h
+lexer.po: lexer.c
+lexer.po: y.tab.h
+parser.o: parser.c
+parser.po: parser.c
+.endif
diff --git a/usr.sbin/rtadvctl/Makefile.depend b/usr.sbin/rtadvctl/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/rtadvctl/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rtadvd/Makefile.depend b/usr.sbin/rtadvd/Makefile.depend
new file mode 100644
index 0000000..c262920
--- /dev/null
+++ b/usr.sbin/rtadvd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rtprio/Makefile.depend b/usr.sbin/rtprio/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/rtprio/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rtsold/Makefile.depend b/usr.sbin/rtsold/Makefile.depend
new file mode 100644
index 0000000..e6478bb
--- /dev/null
+++ b/usr.sbin/rtsold/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libkvm \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/rwhod/Makefile.depend b/usr.sbin/rwhod/Makefile.depend
new file mode 100644
index 0000000..083e419
--- /dev/null
+++ b/usr.sbin/rwhod/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/sa/Makefile.depend b/usr.sbin/sa/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/sa/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/sade/Makefile.depend b/usr.sbin/sade/Makefile.depend
new file mode 100644
index 0000000..9f05925
--- /dev/null
+++ b/usr.sbin/sade/Makefile.depend
@@ -0,0 +1,24 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libdialog \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libdisk \
+ lib/libutil \
+ lib/msun \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/sendmail/Makefile.depend b/usr.sbin/sendmail/Makefile.depend
new file mode 100644
index 0000000..9298bd4
--- /dev/null
+++ b/usr.sbin/sendmail/Makefile.depend
@@ -0,0 +1,107 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libsm \
+ lib/libsmutil \
+ lib/libutil \
+ lib/libwrap \
+ secure/lib/libcrypto \
+ secure/lib/libssl \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+alias.o: sm_os.h
+alias.po: sm_os.h
+arpadate.o: sm_os.h
+arpadate.po: sm_os.h
+bf.o: sm_os.h
+bf.po: sm_os.h
+collect.o: sm_os.h
+collect.po: sm_os.h
+conf.o: sm_os.h
+conf.po: sm_os.h
+control.o: sm_os.h
+control.po: sm_os.h
+convtime.o: sm_os.h
+convtime.po: sm_os.h
+daemon.o: sm_os.h
+daemon.po: sm_os.h
+deliver.o: sm_os.h
+deliver.po: sm_os.h
+domain.o: sm_os.h
+domain.po: sm_os.h
+envelope.o: sm_os.h
+envelope.po: sm_os.h
+err.o: sm_os.h
+err.po: sm_os.h
+headers.o: sm_os.h
+headers.po: sm_os.h
+macro.o: sm_os.h
+macro.po: sm_os.h
+main.o: sm_os.h
+main.po: sm_os.h
+map.o: sm_os.h
+map.po: sm_os.h
+mci.o: sm_os.h
+mci.po: sm_os.h
+milter.o: sm_os.h
+milter.po: sm_os.h
+mime.o: sm_os.h
+mime.po: sm_os.h
+parseaddr.o: sm_os.h
+parseaddr.po: sm_os.h
+queue.o: sm_os.h
+queue.po: sm_os.h
+ratectrl.o: sm_os.h
+ratectrl.po: sm_os.h
+readcf.o: sm_os.h
+readcf.po: sm_os.h
+recipient.o: sm_os.h
+recipient.po: sm_os.h
+sasl.o: sm_os.h
+sasl.po: sm_os.h
+savemail.o: sm_os.h
+savemail.po: sm_os.h
+sfsasl.o: sm_os.h
+sfsasl.po: sm_os.h
+shmticklib.o: sm_os.h
+shmticklib.po: sm_os.h
+sm_resolve.o: sm_os.h
+sm_resolve.po: sm_os.h
+srvrsmtp.o: sm_os.h
+srvrsmtp.po: sm_os.h
+stab.o: sm_os.h
+stab.po: sm_os.h
+stats.o: sm_os.h
+stats.po: sm_os.h
+sysexits.o: sm_os.h
+sysexits.po: sm_os.h
+timers.o: sm_os.h
+timers.po: sm_os.h
+tls.o: sm_os.h
+tls.po: sm_os.h
+trace.o: sm_os.h
+trace.po: sm_os.h
+udb.o: sm_os.h
+udb.po: sm_os.h
+usersmtp.o: sm_os.h
+usersmtp.po: sm_os.h
+util.o: sm_os.h
+util.po: sm_os.h
+version.o: sm_os.h
+version.po: sm_os.h
+.endif
diff --git a/usr.sbin/service/Makefile.depend b/usr.sbin/service/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/service/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/services_mkdb/Makefile.depend b/usr.sbin/services_mkdb/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.sbin/services_mkdb/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/setfib/Makefile.depend b/usr.sbin/setfib/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/setfib/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/setfmac/Makefile.depend b/usr.sbin/setfmac/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/setfmac/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/setpmac/Makefile.depend b/usr.sbin/setpmac/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/setpmac/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/sicontrol/Makefile.depend b/usr.sbin/sicontrol/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/sicontrol/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/smbmsg/Makefile.depend b/usr.sbin/smbmsg/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/smbmsg/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/snapinfo/Makefile.depend b/usr.sbin/snapinfo/Makefile.depend
new file mode 100644
index 0000000..250cad8
--- /dev/null
+++ b/usr.sbin/snapinfo/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libufs \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/spkrtest/Makefile.depend b/usr.sbin/spkrtest/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/spkrtest/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/spray/Makefile.depend b/usr.sbin/spray/Makefile.depend
new file mode 100644
index 0000000..60fe900
--- /dev/null
+++ b/usr.sbin/spray/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/librpcsvc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/syslogd/Makefile.depend b/usr.sbin/syslogd/Makefile.depend
new file mode 100644
index 0000000..c262920
--- /dev/null
+++ b/usr.sbin/syslogd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/tcpdchk/Makefile.depend b/usr.sbin/tcpdchk/Makefile.depend
new file mode 100644
index 0000000..b30ae55
--- /dev/null
+++ b/usr.sbin/tcpdchk/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/tcpdmatch/Makefile.depend b/usr.sbin/tcpdmatch/Makefile.depend
new file mode 100644
index 0000000..b30ae55
--- /dev/null
+++ b/usr.sbin/tcpdmatch/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/tcpdrop/Makefile.depend b/usr.sbin/tcpdrop/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/tcpdrop/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/tcpdump/tcpdump/Makefile.depend b/usr.sbin/tcpdump/tcpdump/Makefile.depend
new file mode 100644
index 0000000..02177cb
--- /dev/null
+++ b/usr.sbin/tcpdump/tcpdump/Makefile.depend
@@ -0,0 +1,25 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libpcap \
+ secure/lib/libcrypto \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+version.o: version.c
+version.po: version.c
+.endif
diff --git a/usr.sbin/timed/timed/Makefile.depend b/usr.sbin/timed/timed/Makefile.depend
new file mode 100644
index 0000000..359f90d
--- /dev/null
+++ b/usr.sbin/timed/timed/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/timed/timedc/Makefile.depend b/usr.sbin/timed/timedc/Makefile.depend
new file mode 100644
index 0000000..083e419
--- /dev/null
+++ b/usr.sbin/timed/timedc/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/protocols \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/traceroute/Makefile.depend b/usr.sbin/traceroute/Makefile.depend
new file mode 100644
index 0000000..3c92034
--- /dev/null
+++ b/usr.sbin/traceroute/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipsec \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+version.o: version.c
+version.po: version.c
+.endif
diff --git a/usr.sbin/traceroute6/Makefile.depend b/usr.sbin/traceroute6/Makefile.depend
new file mode 100644
index 0000000..3b4bd93
--- /dev/null
+++ b/usr.sbin/traceroute6/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libipsec \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/trpt/Makefile.depend b/usr.sbin/trpt/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/trpt/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/tzsetup/Makefile.depend b/usr.sbin/tzsetup/Makefile.depend
new file mode 100644
index 0000000..3f1092b
--- /dev/null
+++ b/usr.sbin/tzsetup/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libdialog \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/msun \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/uathload/Makefile.depend b/usr.sbin/uathload/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/uathload/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ugidfw/Makefile.depend b/usr.sbin/ugidfw/Makefile.depend
new file mode 100644
index 0000000..2b665a8
--- /dev/null
+++ b/usr.sbin/ugidfw/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libugidfw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/uhsoctl/Makefile.depend b/usr.sbin/uhsoctl/Makefile.depend
new file mode 100644
index 0000000..c262920
--- /dev/null
+++ b/usr.sbin/uhsoctl/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/usbconfig/Makefile.depend b/usr.sbin/usbconfig/Makefile.depend
new file mode 100644
index 0000000..f779151
--- /dev/null
+++ b/usr.sbin/usbconfig/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libusb \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/usbdump/Makefile.depend b/usr.sbin/usbdump/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/usbdump/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/utx/Makefile.depend b/usr.sbin/utx/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/utx/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/vidcontrol/Makefile.depend b/usr.sbin/vidcontrol/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/vidcontrol/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/vipw/Makefile.depend b/usr.sbin/vipw/Makefile.depend
new file mode 100644
index 0000000..2dd29af
--- /dev/null
+++ b/usr.sbin/vipw/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/wake/Makefile.depend b/usr.sbin/wake/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/wake/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/watch/Makefile.depend b/usr.sbin/watch/Makefile.depend
new file mode 100644
index 0000000..c74c89f
--- /dev/null
+++ b/usr.sbin/watch/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/ncurses/ncurses \
+ lib/ncurses/ncursesw \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/watchdogd/Makefile.depend b/usr.sbin/watchdogd/Makefile.depend
new file mode 100644
index 0000000..8825ffd
--- /dev/null
+++ b/usr.sbin/watchdogd/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libutil \
+ lib/msun \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/wlandebug/Makefile.depend b/usr.sbin/wlandebug/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/wlandebug/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/wlconfig/Makefile.depend b/usr.sbin/wlconfig/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/wlconfig/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/wpa/hostapd/Makefile.depend b/usr.sbin/wpa/hostapd/Makefile.depend
new file mode 100644
index 0000000..07fb89b
--- /dev/null
+++ b/usr.sbin/wpa/hostapd/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libpcap \
+ secure/lib/libcrypto \
+ secure/lib/libssl \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/wpa/hostapd_cli/Makefile.depend b/usr.sbin/wpa/hostapd_cli/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/wpa/hostapd_cli/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/wpa/ndis_events/Makefile.depend b/usr.sbin/wpa/ndis_events/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/wpa/ndis_events/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/wpa/wpa_cli/Makefile.depend b/usr.sbin/wpa/wpa_cli/Makefile.depend
new file mode 100644
index 0000000..5018218
--- /dev/null
+++ b/usr.sbin/wpa/wpa_cli/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libedit \
+ lib/libedit/edit/readline \
+ lib/ncurses/ncurses \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/wpa/wpa_passphrase/Makefile.depend b/usr.sbin/wpa/wpa_passphrase/Makefile.depend
new file mode 100644
index 0000000..16b5e42
--- /dev/null
+++ b/usr.sbin/wpa/wpa_passphrase/Makefile.depend
@@ -0,0 +1,20 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/wpa/wpa_supplicant/Makefile.depend b/usr.sbin/wpa/wpa_supplicant/Makefile.depend
new file mode 100644
index 0000000..07fb89b
--- /dev/null
+++ b/usr.sbin/wpa/wpa_supplicant/Makefile.depend
@@ -0,0 +1,23 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libpcap \
+ secure/lib/libcrypto \
+ secure/lib/libssl \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/yp_mkdb/Makefile.depend b/usr.sbin/yp_mkdb/Makefile.depend
new file mode 100644
index 0000000..6e9b14f
--- /dev/null
+++ b/usr.sbin/yp_mkdb/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/ypbind/Makefile.depend b/usr.sbin/ypbind/Makefile.depend
new file mode 100644
index 0000000..a3e1b44
--- /dev/null
+++ b/usr.sbin/ypbind/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/yppoll/Makefile.depend b/usr.sbin/yppoll/Makefile.depend
new file mode 100644
index 0000000..6e9b14f
--- /dev/null
+++ b/usr.sbin/yppoll/Makefile.depend
@@ -0,0 +1,21 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/yppush/Makefile.depend b/usr.sbin/yppush/Makefile.depend
new file mode 100644
index 0000000..ff4f7af
--- /dev/null
+++ b/usr.sbin/yppush/Makefile.depend
@@ -0,0 +1,29 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+yp_clnt.o: yp.h
+yp_clnt.o: yp_clnt.c
+yp_clnt.po: yp.h
+yp_clnt.po: yp_clnt.c
+yppush_svc.o: yp.h
+yppush_svc.o: yppush_svc.c
+yppush_svc.po: yp.h
+yppush_svc.po: yppush_svc.c
+.endif
diff --git a/usr.sbin/ypserv/Makefile.depend b/usr.sbin/ypserv/Makefile.depend
new file mode 100644
index 0000000..c00e105
--- /dev/null
+++ b/usr.sbin/ypserv/Makefile.depend
@@ -0,0 +1,35 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+ lib/libwrap \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+yp_main.o: yp.h
+yp_main.po: yp.h
+yp_server.o: yp.h
+yp_server.po: yp.h
+yp_svc.o: yp.h
+yp_svc.o: yp_svc.c
+yp_svc.po: yp.h
+yp_svc.po: yp_svc.c
+ypxfr_clnt.o: yp.h
+ypxfr_clnt.o: ypxfr_clnt.c
+ypxfr_clnt.po: yp.h
+ypxfr_clnt.po: ypxfr_clnt.c
+.endif
diff --git a/usr.sbin/ypset/Makefile.depend b/usr.sbin/ypset/Makefile.depend
new file mode 100644
index 0000000..a3e1b44
--- /dev/null
+++ b/usr.sbin/ypset/Makefile.depend
@@ -0,0 +1,22 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/arpa \
+ include/rpc \
+ include/rpcsvc \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/zic/zdump/Makefile.depend b/usr.sbin/zic/zdump/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/zic/zdump/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/zic/zic/Makefile.depend b/usr.sbin/zic/zic/Makefile.depend
new file mode 100644
index 0000000..a839545
--- /dev/null
+++ b/usr.sbin/zic/zic/Makefile.depend
@@ -0,0 +1,19 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+ gnu/lib/libgcc \
+ include \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libc \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/usr.sbin/zzz/Makefile.depend b/usr.sbin/zzz/Makefile.depend
new file mode 100644
index 0000000..29fda55
--- /dev/null
+++ b/usr.sbin/zzz/Makefile.depend
@@ -0,0 +1,14 @@
+# Autogenerated - do NOT edit!
+
+DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
+
+DEP_MACHINE := ${.PARSEFILE:E}
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
OpenPOWER on IntegriCloud