From 42e0d83cb3a1a1c5b25183f1ab74ce7edbe25de7 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Sun, 9 Aug 1998 00:43:13 +0000 Subject: [PATCH] Initial revision --- ANNOUNCEMENT | 90 + CHANGES | 545 +++++ COPYRIGHT | 9 + INSTALL | 136 ++ Make-common | 200 ++ Make-common.um | 200 ++ Makefile | 392 ++++ README | 59 + build/Make-append | 78 + build/Make-template | 38 + build/PORTS | 98 + build/README-unproto | 3 + build/db.1.85.patch | 158 ++ build/install.sh | 45 + build/mkdep | 133 ++ build/platforms/Make-setup | 68 + build/platforms/Makefile | 46 + build/platforms/aix-cc/Make-platform | 18 + build/platforms/aix-gcc/Make-platform | 19 + build/platforms/freebsd-gcc/Make-platform | 16 + build/platforms/hpux-c89/Make-platform | 27 + build/platforms/hpux-cc/Make-platform | 33 + build/platforms/hpux-gcc/Make-platform | 28 + build/platforms/irix-cc/Make-platform | 29 + build/platforms/irix-gcc/Make-platform | 29 + build/platforms/linux-gcc/Make-platform | 17 + build/platforms/ncr-mp-ras-2-cc/Make-platform | 34 + build/platforms/netbsd-cc/Make-platform | 17 + build/platforms/netbsd-gcc/Make-platform | 16 + build/platforms/nextstep-cc/Make-platform | 15 + build/platforms/osf1-cc/Make-platform | 24 + build/platforms/sco-cc/Make-platform | 23 + build/platforms/sco-gcc/Make-platform | 22 + build/platforms/sunos4-cc/Make-platform | 25 + build/platforms/sunos4-gcc/Make-platform | 19 + build/platforms/sunos5-cc/Make-platform | 29 + build/platforms/sunos5-gcc/Make-platform | 28 + build/platforms/ultrix-cc/Make-platform | 16 + build/platforms/ultrix-gcc/Make-platform | 16 + build/platforms/vms/Makefile | 31 + build/platforms/vms/make.com | 95 + build/uname.sh | 109 + build/unproto/Makefile | 123 ++ build/unproto/README | 160 ++ build/unproto/acc.sh | 35 + build/unproto/cpp.sh | 35 + build/unproto/error.c | 97 + build/unproto/error.h | 6 + build/unproto/example.c | 222 ++ build/unproto/example.out | 271 +++ build/unproto/hash.c | 54 + build/unproto/stdarg.h | 90 + build/unproto/stddef.h | 23 + build/unproto/stdlib.h | 53 + build/unproto/strsave.c | 71 + build/unproto/symbol.c | 144 ++ build/unproto/symbol.h | 11 + build/unproto/tok_class.c | 432 ++++ build/unproto/tok_io.c | 612 ++++++ build/unproto/tok_pool.c | 103 + build/unproto/token.h | 55 + build/unproto/unproto.1 | 152 ++ build/unproto/unproto.c | 999 +++++++++ build/unproto/varargs.c | 32 + build/unproto/vstring.c | 122 ++ build/unproto/vstring.h | 15 + build/version | 1 + clients/Make-template | 84 + clients/fax500/Make-template | 87 + clients/fax500/README | 104 + clients/fax500/Version.c | 13 + clients/fax500/Versionrp.c | 13 + clients/fax500/faxtotpc.c | 248 +++ clients/fax500/main.c | 1499 ++++++++++++++ clients/fax500/rp500.c | 283 +++ clients/fax500/xrpcomp | 85 + clients/finger/Make-template | 70 + clients/finger/Version.c | 13 + clients/finger/main.c | 429 ++++ clients/gopher/Make-template | 91 + clients/gopher/README | 188 ++ clients/gopher/Version.c | 13 + clients/gopher/Versiongw.c | 13 + clients/gopher/detach.c | 80 + clients/gopher/go500.c | 568 +++++ clients/gopher/go500gw.c | 891 ++++++++ clients/gopher/go500gw.help | 17 + clients/gopher/setproctitle.c | 46 + clients/mail500/Make-template | 68 + clients/mail500/README | 186 ++ clients/mail500/Version.c | 13 + clients/mail500/main.c | 1691 +++++++++++++++ clients/mail500/sendmail.cf | 203 ++ clients/rcpt500/Make-template | 71 + clients/rcpt500/README | 115 ++ clients/rcpt500/Version.c | 13 + clients/rcpt500/cmds.c | 28 + clients/rcpt500/help.c | 49 + clients/rcpt500/main.c | 384 ++++ clients/rcpt500/query.c | 348 ++++ clients/rcpt500/rcpt500.h | 36 + clients/rcpt500/rcpt500.help | 44 + clients/tools/Make-template | 118 ++ clients/tools/Versionldd.c | 13 + clients/tools/Versionldm.c | 13 + clients/tools/Versionldr.c | 13 + clients/tools/Versionlds.c | 13 + clients/tools/ldapdelete.c | 156 ++ clients/tools/ldapmodify.c | 798 ++++++++ clients/tools/ldapmodrdn.c | 196 ++ clients/tools/ldapsearch.c | 475 +++++ clients/ud/Make-template | 100 + clients/ud/README | 31 + clients/ud/Version.c | 13 + clients/ud/auth.c | 427 ++++ clients/ud/edit.c | 453 ++++ clients/ud/etc.ud.conf | 2 + clients/ud/find.c | 496 +++++ clients/ud/globals.c | 71 + clients/ud/group.c | 1242 +++++++++++ clients/ud/help.c | 193 ++ clients/ud/main.c | 724 +++++++ clients/ud/mod.c | 814 ++++++++ clients/ud/print.c | 653 ++++++ clients/ud/string_to_key.c | 257 +++ clients/ud/ud.h | 158 ++ clients/ud/util.c | 662 ++++++ contrib/README | 23 + contrib/saucer/Make-template | 54 + contrib/saucer/README | 41 + contrib/saucer/main.c | 690 +++++++ contrib/saucer/sample.saucerrc | 2 + contrib/saucer/saucer.1 | 186 ++ contrib/web500gw/README | 11 + contrib/whois++/BUGS | 37 + contrib/whois++/INSTALL | 65 + contrib/whois++/Makefile | 81 + contrib/whois++/README | 23 + contrib/whois++/TODO | 9 + contrib/whois++/command.c | 748 +++++++ contrib/whois++/config.c | 226 ++ contrib/whois++/describe.c | 229 +++ contrib/whois++/help.c | 89 + contrib/whois++/helpfiles/english/command | 1 + contrib/whois++/helpfiles/english/commands | 9 + contrib/whois++/helpfiles/english/constraints | 39 + contrib/whois++/helpfiles/english/describe | 5 + contrib/whois++/helpfiles/english/general | 7 + contrib/whois++/helpfiles/english/help | 30 + contrib/whois++/helpfiles/english/list | 3 + contrib/whois++/helpfiles/english/search | 33 + contrib/whois++/helpfiles/english/show | 2 + contrib/whois++/helpfiles/english/version | 3 + contrib/whois++/output.c | 358 ++++ contrib/whois++/root.Makefile.diff | 83 + contrib/whois++/template.c | 169 ++ contrib/whois++/templates/applicationentity | 2 + contrib/whois++/templates/organizationalrole | 1 + contrib/whois++/templates/organizationalunit | 2 + contrib/whois++/templates/person | 12 + contrib/whois++/util.c | 167 ++ contrib/whois++/version.c | 35 + contrib/whois++/whois++.c | 417 ++++ contrib/whois++/whois++.h | 147 ++ contrib/whois++/whois++d.man | 162 ++ contrib/whois++/whois++dtailor | 5 + doc/Make-template | 95 + doc/guides/Make-template | 29 + doc/man/Make-template | 84 + doc/man/man1/Make-template | 52 + doc/man/man1/ldapdelete.1 | 109 + doc/man/man1/ldapmodify.1 | 301 +++ doc/man/man1/ldapmodify.1.links | 1 + doc/man/man1/ldapmodrdn.1 | 132 ++ doc/man/man1/ldapsearch.1 | 291 +++ doc/man/man1/ud.1 | 73 + doc/man/man3/Make-template | 52 + doc/man/man3/cldap_close.3 | 30 + doc/man/man3/cldap_open.3 | 53 + doc/man/man3/cldap_search_s.3 | 105 + doc/man/man3/cldap_setretryinfo.3 | 42 + doc/man/man3/lber-decode.3 | 358 ++++ doc/man/man3/lber-encode.3 | 315 +++ doc/man/man3/ldap.3 | 501 +++++ doc/man/man3/ldap.3.links | 1 + doc/man/man3/ldap_abandon.3 | 42 + doc/man/man3/ldap_add.3 | 60 + doc/man/man3/ldap_add.3.links | 1 + doc/man/man3/ldap_bind.3 | 196 ++ doc/man/man3/ldap_bind.3.links | 11 + doc/man/man3/ldap_cache.3 | 117 ++ doc/man/man3/ldap_cache.3.links | 7 + doc/man/man3/ldap_charset.3 | 127 ++ doc/man/man3/ldap_charset.3.links | 6 + doc/man/man3/ldap_compare.3 | 51 + doc/man/man3/ldap_compare.3.links | 1 + doc/man/man3/ldap_delete.3 | 48 + doc/man/man3/ldap_delete.3.links | 1 + doc/man/man3/ldap_disptmpl.3 | 450 ++++ doc/man/man3/ldap_disptmpl.3.links | 11 + doc/man/man3/ldap_entry2text.3 | 326 +++ doc/man/man3/ldap_entry2text.3.links | 5 + doc/man/man3/ldap_error.3 | 219 ++ doc/man/man3/ldap_error.3.links | 5 + doc/man/man3/ldap_first_attribute.3 | 79 + doc/man/man3/ldap_first_attribute.3.links | 1 + doc/man/man3/ldap_first_entry.3 | 83 + doc/man/man3/ldap_first_entry.3.links | 2 + doc/man/man3/ldap_friendly.3 | 68 + doc/man/man3/ldap_friendly.3.links | 2 + doc/man/man3/ldap_get_dn.3 | 116 ++ doc/man/man3/ldap_get_dn.3.links | 4 + doc/man/man3/ldap_get_values.3 | 99 + doc/man/man3/ldap_get_values.3.links | 5 + doc/man/man3/ldap_getfilter.3 | 193 ++ doc/man/man3/ldap_getfilter.3.links | 7 + doc/man/man3/ldap_modify.3 | 113 + doc/man/man3/ldap_modify.3.links | 2 + doc/man/man3/ldap_modrdn.3 | 75 + doc/man/man3/ldap_modrdn.3.links | 3 + doc/man/man3/ldap_open.3 | 113 + doc/man/man3/ldap_open.3.links | 1 + doc/man/man3/ldap_result.3 | 106 + doc/man/man3/ldap_result.3.links | 1 + doc/man/man3/ldap_search.3 | 116 ++ doc/man/man3/ldap_search.3.links | 2 + doc/man/man3/ldap_searchprefs.3 | 158 ++ doc/man/man3/ldap_searchprefs.3.links | 5 + doc/man/man3/ldap_sort.3 | 101 + doc/man/man3/ldap_sort.3.links | 3 + doc/man/man3/ldap_ufn.3 | 130 ++ doc/man/man3/ldap_ufn.3.links | 6 + doc/man/man3/ldap_url.3 | 136 ++ doc/man/man3/ldap_url.3.links | 6 + doc/man/man3/regex.3 | 326 +++ doc/man/man5/Make-template | 52 + doc/man/man5/ldapfilter.conf.5 | 198 ++ doc/man/man5/ldapfriendly.5 | 26 + doc/man/man5/ldapsearchprefs.conf.5 | 246 +++ doc/man/man5/ldaptemplates.conf.5 | 275 +++ doc/man/man5/ldif.5 | 107 + doc/man/man5/slapd.conf.5 | 340 +++ doc/man/man5/slapd.replog.5 | 158 ++ doc/man/man5/ud.conf.5 | 96 + doc/man/man8/Make-template | 52 + doc/man/man8/centipede.8 | 154 ++ doc/man/man8/chlog2replog.8 | 102 + doc/man/man8/edb2ldif.8 | 99 + doc/man/man8/go500.8 | 170 ++ doc/man/man8/go500gw.8 | 170 ++ doc/man/man8/in.xfingerd.8 | 79 + doc/man/man8/ldapd.8 | 127 ++ doc/man/man8/ldbmcat.8 | 61 + doc/man/man8/ldif.8 | 48 + doc/man/man8/ldif2ldbm.8 | 113 + doc/man/man8/ldif2ldbm.8.links | 3 + doc/man/man8/mail500.8 | 287 +++ doc/man/man8/mail500.8.links | 1 + doc/man/man8/rcpt500.8 | 86 + doc/man/man8/slapd.8 | 104 + doc/man/man8/slurpd.8 | 151 ++ doc/rfc/Make-template | 29 + doc/rfc/rfc1558.txt | 171 ++ doc/rfc/rfc1777.txt | 1235 +++++++++++ doc/rfc/rfc1778.txt | 675 ++++++ doc/rfc/rfc1779.txt | 454 ++++ doc/rfc/rfc1798.txt | 507 +++++ doc/rfc/rfc1823.txt | 1235 +++++++++++ include/Make-template | 63 + include/avl.h | 56 + include/disptmpl.h | 330 +++ include/lber.h | 184 ++ include/ldap.h | 592 ++++++ include/ldapconfig.h.edit | 268 +++ include/ldapconfig.h.um | 273 +++ include/ldbm.h | 165 ++ include/ldif.h | 56 + include/lthread.h | 174 ++ include/portable.h | 215 ++ include/proto-lber.h | 102 + include/proto-ldap.h | 276 +++ include/regex.h | 43 + include/srchpref.h | 106 + include/sysexits-compat.h | 102 + libraries/Make-template | 86 + libraries/libavl/Make-template | 71 + libraries/libavl/Version.c | 13 + libraries/libavl/avl.c | 778 +++++++ libraries/libavl/testavl.c | 117 ++ libraries/liblber/Make-template | 85 + libraries/liblber/Version.c | 13 + libraries/liblber/bprint.c | 60 + libraries/liblber/decode.c | 598 ++++++ libraries/liblber/dtest.c | 61 + libraries/liblber/encode.c | 644 ++++++ libraries/liblber/etest.c | 166 ++ libraries/liblber/idtest.c | 62 + libraries/liblber/io.c | 601 ++++++ libraries/libldap/Make-template | 143 ++ libraries/libldap/Version.c | 13 + libraries/libldap/abandon.c | 186 ++ libraries/libldap/add.c | 123 ++ libraries/libldap/addentry.c | 56 + libraries/libldap/bind.c | 133 ++ libraries/libldap/cache.c | 654 ++++++ libraries/libldap/charset.c | 1821 +++++++++++++++++ libraries/libldap/cldap.c | 537 +++++ libraries/libldap/compare.c | 94 + libraries/libldap/delete.c | 83 + libraries/libldap/disptmpl.c | 725 +++++++ libraries/libldap/dsparse.c | 220 ++ libraries/libldap/error.c | 171 ++ libraries/libldap/free.c | 94 + libraries/libldap/friendly.c | 130 ++ libraries/libldap/getattr.c | 80 + libraries/libldap/getdn.c | 269 +++ libraries/libldap/getdxbyname.c | 218 ++ libraries/libldap/getentry.c | 60 + libraries/libldap/getfilter.c | 432 ++++ libraries/libldap/getvalues.c | 171 ++ libraries/libldap/kbind.c | 302 +++ libraries/libldap/ldap-int.h | 189 ++ libraries/libldap/ldapfilter.conf | 105 + libraries/libldap/ldapfriendly | 242 +++ libraries/libldap/ldapsearchprefs.conf | 153 ++ libraries/libldap/ldaptemplates.conf | 677 ++++++ libraries/libldap/modify.c | 125 ++ libraries/libldap/modrdn.c | 96 + libraries/libldap/open.c | 226 ++ libraries/libldap/os-ip.c | 330 +++ libraries/libldap/regex.c | 906 ++++++++ libraries/libldap/request.c | 965 +++++++++ libraries/libldap/result.c | 836 ++++++++ libraries/libldap/sbind.c | 112 + libraries/libldap/search.c | 571 ++++++ libraries/libldap/sort.c | 153 ++ libraries/libldap/srchpref.c | 421 ++++ libraries/libldap/test.c | 1023 +++++++++ libraries/libldap/tmplout.c | 1090 ++++++++++ libraries/libldap/tmpltest.c | 277 +++ libraries/libldap/ufn.c | 510 +++++ libraries/libldap/unbind.c | 155 ++ libraries/libldap/url.c | 395 ++++ libraries/libldbm/Make-template | 71 + libraries/libldbm/Version.c | 13 + libraries/libldbm/ldbm.c | 348 ++++ libraries/libldif/Make-template | 69 + libraries/libldif/Version.c | 13 + libraries/libldif/line64.c | 307 +++ libraries/liblthread/Make-template | 69 + libraries/liblthread/Version.c | 13 + libraries/liblthread/stack.c | 69 + libraries/liblthread/thread.c | 487 +++++ libraries/macintosh/Make-template | 48 + libraries/macintosh/README | 67 + libraries/macintosh/getopt.c | 104 + libraries/macintosh/kerberos-macos.c | 80 + libraries/macintosh/macos-ip.c | 291 +++ libraries/macintosh/macos.h | 32 + libraries/macintosh/strings.c | 90 + libraries/macintosh/tcp/AddressXlation.h | 200 ++ libraries/macintosh/tcp/GetMyIPAddr.h | 46 + libraries/macintosh/tcp/MacTCPCommonTypes.h | 220 ++ libraries/macintosh/tcp/MiscIPPB.h | 179 ++ libraries/macintosh/tcp/TCPPB.h | 404 ++++ libraries/macintosh/tcp/UDPPB.h | 190 ++ libraries/macintosh/tcp/dnr.c | 529 +++++ libraries/macintosh/tcp/tcp.c | 982 +++++++++ libraries/macintosh/tcp/tcp.h | 79 + libraries/msdos/Make-template | 48 + libraries/msdos/README | 12 + libraries/msdos/README.CSA | 100 + libraries/msdos/README.NFS | 55 + libraries/msdos/README.WSA | 228 +++ libraries/msdos/lp.c | 265 +++ libraries/msdos/makefile.msc | 78 + libraries/msdos/makefile.nfs | 60 + libraries/msdos/makelber.msc | 58 + libraries/msdos/makelber.nfs | 50 + libraries/msdos/makeldap.msc | 92 + libraries/msdos/makeldap.nfs | 97 + libraries/msdos/makeud.msc | 76 + libraries/msdos/msdos.c | 84 + libraries/msdos/msdos.h | 52 + libraries/msdos/opendos.c | 393 ++++ libraries/msdos/protoud.h | 28 + libraries/msdos/winsock/include/file.h | 4 + libraries/msdos/winsock/include/filio.h | 4 + libraries/msdos/winsock/include/in.h | 4 + libraries/msdos/winsock/include/ioctl.h | 4 + libraries/msdos/winsock/include/krb/des.h | 63 + libraries/msdos/winsock/include/krb/krb.h | 504 +++++ .../winsock/include/krb/mit/arpa/nameser.h | 257 +++ .../msdos/winsock/include/krb/mit/conf-pc.h | 80 + .../msdos/winsock/include/krb/mit/conf.h | 81 + .../msdos/winsock/include/krb/mit/hesiod.h | 113 + .../msdos/winsock/include/krb/mit/lsh_pwd.h | 56 + .../msdos/winsock/include/krb/mit/mit_copy.h | 22 + .../msdos/winsock/include/krb/mit/osconf.h | 63 + .../msdos/winsock/include/krb/mit/resolv.h | 144 ++ .../msdos/winsock/include/krb/mit/wshelper.h | 62 + .../msdos/winsock/include/net/_sys/filio.h | 4 + .../msdos/winsock/include/net/_sys/ioctl.h | 4 + libraries/msdos/winsock/include/net/netdb.h | 4 + libraries/msdos/winsock/include/param.h | 4 + libraries/msdos/winsock/include/select.h | 4 + libraries/msdos/winsock/include/socket.h | 4 + libraries/msdos/winsock/include/time.h | 4 + libraries/msdos/winsock/include/wsa.h | 132 ++ libraries/msdos/winsock/include/wsa/errno.c | 21 + libraries/msdos/winsock/include/wsa/errno.rc | 57 + .../msdos/winsock/include/wsa/winsock.def | 84 + libraries/msdos/winsock/include/wsa/winsock.h | 906 ++++++++ libraries/msdos/winsock/kerberos.c | 119 ++ libraries/msdos/winsock/ldap32.def | 166 ++ libraries/msdos/winsock/ldap32.mak | 1632 +++++++++++++++ libraries/msdos/winsock/ldap32.mdp | Bin 0 -> 43520 bytes libraries/msdos/winsock/libldap.def | 165 ++ libraries/msdos/winsock/libldap.mak | 667 ++++++ libraries/msdos/winsock/libldap.rc | 40 + libraries/msdos/winsock/ltest/console.c | 257 +++ libraries/msdos/winsock/ltest/console.h | 19 + libraries/msdos/winsock/ltest/inpdlg.dlg | 14 + libraries/msdos/winsock/ltest/inpdlg.h | 1 + libraries/msdos/winsock/ltest/ltest.def | 9 + libraries/msdos/winsock/ltest/ltest.mak | 140 ++ libraries/msdos/winsock/ltest/ltest.rc | 22 + libraries/msdos/winsock/ltest/ltest32.mak | 348 ++++ libraries/msdos/winsock/ltest/ltest32.mdp | Bin 0 -> 37376 bytes libraries/msdos/winsock/ltest/textwind.c | 130 ++ libraries/msdos/winsock/ltest/textwind.h | 13 + libraries/msdos/winsock/makefile | 680 ++++++ libraries/msdos/winsock/openwsa.c | 133 ++ libraries/msdos/winsock/setupwsa.bat | 69 + libraries/msdos/winsock/unsetupwsa.bat | 77 + .../msdos/winsock/winkit/help/ldap32.hlp | Bin 0 -> 72697 bytes .../msdos/winsock/winkit/help/ldap32.hpj | 21 + .../msdos/winsock/winkit/help/libldap.hlp | Bin 0 -> 76104 bytes .../msdos/winsock/winkit/help/libldap.hpj | 14 + libraries/msdos/winsock/winkit/readme.txt | 182 ++ libraries/msdos/winsock/winkit/windowskit.cmd | 1 + libraries/msdos/winsock/winkit/windowskit.mak | 172 ++ libraries/msdos/winsock/wsa.c | 91 + libraries/msdos/winsock/wsa/errno.c | 21 + libraries/msdos/winsock/wsa/errno.rc | 57 + libraries/msdos/winsock/wsa/winsock.def | 84 + libraries/msdos/winsock/wsa/winsock.h | 826 ++++++++ libraries/msdos/winsock/wsockip.c | 467 +++++ libraries/vms/Make-template | 48 + libraries/vms/README.VMS | 16 + libraries/vms/getopt.c | 106 + libraries/vms/strings.c | 97 + libraries/vms/ucx_select.h | 28 + servers/Make-template | 88 + servers/ldapd/Make-template | 122 ++ servers/ldapd/Version.c | 13 + servers/ldapd/abandon.c | 61 + servers/ldapd/add.c | 126 ++ servers/ldapd/association.c | 280 +++ servers/ldapd/bind.c | 271 +++ servers/ldapd/certificate.c | 316 +++ servers/ldapd/common.h | 72 + servers/ldapd/compare.c | 131 ++ servers/ldapd/delete.c | 107 + servers/ldapd/detach.c | 90 + servers/ldapd/error.c | 189 ++ servers/ldapd/kerberos.c | 143 ++ servers/ldapd/ldap.py | 231 +++ servers/ldapd/main.c | 691 +++++++ servers/ldapd/message.c | 172 ++ servers/ldapd/modify.c | 645 ++++++ servers/ldapd/modrdn.c | 119 ++ servers/ldapd/proto-ldapd.h | 158 ++ servers/ldapd/request.c | 518 +++++ servers/ldapd/result.c | 379 ++++ servers/ldapd/search.c | 710 +++++++ servers/ldapd/setproctitle.c | 48 + servers/ldapd/syntax.c | 1029 ++++++++++ servers/ldapd/util.c | 185 ++ servers/slapd/Make-template | 266 +++ servers/slapd/Version.c | 13 + servers/slapd/abandon.c | 70 + servers/slapd/acl.c | 404 ++++ servers/slapd/aclparse.c | 376 ++++ servers/slapd/add.c | 186 ++ servers/slapd/attr.c | 339 +++ servers/slapd/ava.c | 38 + servers/slapd/back-ldbm/Make-template | 148 ++ servers/slapd/back-ldbm/Version.c | 13 + servers/slapd/back-ldbm/abandon.c | 5 + servers/slapd/back-ldbm/add.c | 173 ++ servers/slapd/back-ldbm/attr.c | 165 ++ servers/slapd/back-ldbm/back-ldbm.h | 114 ++ servers/slapd/back-ldbm/bind.c | 150 ++ servers/slapd/back-ldbm/cache.c | 342 ++++ servers/slapd/back-ldbm/close.c | 14 + servers/slapd/back-ldbm/compare.c | 55 + servers/slapd/back-ldbm/config.c | 86 + servers/slapd/back-ldbm/dbcache.c | 247 +++ servers/slapd/back-ldbm/delete.c | 67 + servers/slapd/back-ldbm/dn2id.c | 182 ++ servers/slapd/back-ldbm/filterindex.c | 356 ++++ servers/slapd/back-ldbm/id2children.c | 88 + servers/slapd/back-ldbm/id2entry.c | 133 ++ servers/slapd/back-ldbm/idl.c | 821 ++++++++ servers/slapd/back-ldbm/index.c | 364 ++++ servers/slapd/back-ldbm/init.c | 71 + servers/slapd/back-ldbm/kerberos.c | 46 + servers/slapd/back-ldbm/modify.c | 216 ++ servers/slapd/back-ldbm/modrdn.c | 132 ++ servers/slapd/back-ldbm/nextid.c | 132 ++ servers/slapd/back-ldbm/proto-back-ldbm.h | 107 + servers/slapd/back-ldbm/search.c | 414 ++++ servers/slapd/back-ldbm/unbind.c | 16 + servers/slapd/back-passwd/Make-template | 78 + servers/slapd/back-passwd/Version.c | 13 + servers/slapd/back-passwd/config.c | 41 + servers/slapd/back-passwd/search.c | 153 ++ servers/slapd/back-shell/Make-template | 113 + servers/slapd/back-shell/Version.c | 13 + servers/slapd/back-shell/abandon.c | 59 + servers/slapd/back-shell/add.c | 50 + servers/slapd/back-shell/bind.c | 52 + servers/slapd/back-shell/compare.c | 47 + servers/slapd/back-shell/config.c | 124 ++ servers/slapd/back-shell/delete.c | 44 + servers/slapd/back-shell/fork.c | 63 + servers/slapd/back-shell/init.c | 18 + servers/slapd/back-shell/modify.c | 67 + servers/slapd/back-shell/modrdn.c | 48 + servers/slapd/back-shell/result.c | 90 + servers/slapd/back-shell/search.c | 69 + servers/slapd/back-shell/searchexample.conf | 4 + servers/slapd/back-shell/searchexample.sh | 40 + servers/slapd/back-shell/shell.h | 13 + servers/slapd/back-shell/unbind.c | 45 + servers/slapd/backend.c | 233 +++ servers/slapd/bind.c | 175 ++ servers/slapd/ch_malloc.c | 58 + servers/slapd/charray.c | 132 ++ servers/slapd/compare.c | 85 + servers/slapd/config.c | 510 +++++ servers/slapd/configinfo.c | 70 + servers/slapd/connection.c | 215 ++ servers/slapd/daemon.c | 363 ++++ servers/slapd/delete.c | 89 + servers/slapd/detach.c | 96 + servers/slapd/dn.c | 262 +++ servers/slapd/entry.c | 198 ++ servers/slapd/filter.c | 449 ++++ servers/slapd/filterentry.c | 446 ++++ servers/slapd/init.c | 37 + servers/slapd/lock.c | 64 + servers/slapd/main.c | 273 +++ servers/slapd/modify.c | 259 +++ servers/slapd/modrdn.c | 102 + servers/slapd/monitor.c | 174 ++ servers/slapd/operation.c | 74 + servers/slapd/phonetic.c | 431 ++++ servers/slapd/proto-slap.h | 202 ++ servers/slapd/regex.c | 909 ++++++++ servers/slapd/repl.c | 124 ++ servers/slapd/result.c | 434 ++++ servers/slapd/schema.c | 179 ++ servers/slapd/schemaparse.c | 79 + servers/slapd/search.c | 179 ++ servers/slapd/shell-backends/Make-template | 66 + servers/slapd/shell-backends/passwd-shell.c | 191 ++ servers/slapd/shell-backends/passwd-shell.h | 13 + servers/slapd/shell-backends/pwd-Version.c | 13 + servers/slapd/shell-backends/shellutil.c | 366 ++++ servers/slapd/shell-backends/shellutil.h | 96 + servers/slapd/slap.h | 265 +++ servers/slapd/slapd.at.conf | 23 + servers/slapd/slapd.conf | 14 + servers/slapd/slapd.oc.conf | 903 ++++++++ servers/slapd/str2filter.c | 250 +++ servers/slapd/strdup.c | 18 + servers/slapd/tempnam.c | 38 + servers/slapd/tools/Make-template | 219 ++ servers/slapd/tools/Vers-edb2.c | 13 + servers/slapd/tools/centipede.c | 986 +++++++++ servers/slapd/tools/chlog2replog.c | 709 +++++++ servers/slapd/tools/edb2ldif.c | 916 +++++++++ servers/slapd/tools/ldapsyntax.c | 457 +++++ servers/slapd/tools/ldapsyntax.h | 26 + servers/slapd/tools/ldbmcat.c | 66 + servers/slapd/tools/ldbmtest.c | 805 ++++++++ servers/slapd/tools/ldif.c | 93 + servers/slapd/tools/ldif2id2children.c | 312 +++ servers/slapd/tools/ldif2id2entry.c | 204 ++ servers/slapd/tools/ldif2index.c | 181 ++ servers/slapd/tools/ldif2ldbm.c | 334 +++ servers/slapd/tools/sizecount.c | 184 ++ servers/slapd/unbind.c | 49 + servers/slapd/value.c | 212 ++ servers/slurpd/DESIGN | 51 + servers/slurpd/Make-template | 147 ++ servers/slurpd/Version.c | 13 + servers/slurpd/admin.c | 41 + servers/slurpd/args.c | 148 ++ servers/slurpd/ch_malloc.c | 108 + servers/slurpd/config.c | 406 ++++ servers/slurpd/detach.c | 96 + servers/slurpd/fm.c | 268 +++ servers/slurpd/globals.c | 72 + servers/slurpd/globals.h | 64 + servers/slurpd/ldap_op.c | 858 ++++++++ servers/slurpd/lock.c | 134 ++ servers/slurpd/main.c | 155 ++ servers/slurpd/re.c | 734 +++++++ servers/slurpd/reject.c | 96 + servers/slurpd/replica.c | 71 + servers/slurpd/replog.c | 182 ++ servers/slurpd/ri.c | 266 +++ servers/slurpd/rq.c | 434 ++++ servers/slurpd/sanity.c | 204 ++ servers/slurpd/slurp.h | 349 ++++ servers/slurpd/st.c | 309 +++ servers/slurpd/tsleep.c | 159 ++ tests/Make-template | 35 + tests/README | 3 + tests/data/acl.out.master | 278 +++ tests/data/modify.out.master | 391 ++++ tests/data/search.out.master | 343 ++++ tests/data/slapd-acl.conf | 36 + tests/data/slapd-master.conf | 19 + tests/data/slapd-repl-master.conf | 26 + tests/data/slapd-repl-slave.conf | 20 + tests/data/slapd.at.conf | 23 + tests/data/slapd.oc.conf | 903 ++++++++ tests/data/test-ordered.ldif | 423 ++++ tests/data/test.ldif | 423 ++++ tests/scripts/all | 23 + tests/scripts/defines.sh | 33 + tests/scripts/makeldbm.sh | 15 + tests/scripts/test001-ldif2ldbm | 50 + tests/scripts/test001-slapadd | 50 + tests/scripts/test002-populate | 57 + tests/scripts/test003-search | 89 + tests/scripts/test004-modify | 126 ++ tests/scripts/test005-modrdn | 5 + tests/scripts/test006-acls | 118 ++ tests/scripts/test007-replication | 161 ++ 644 files changed, 118767 insertions(+) create mode 100644 ANNOUNCEMENT create mode 100644 CHANGES create mode 100644 COPYRIGHT create mode 100644 INSTALL create mode 100644 Make-common create mode 100644 Make-common.um create mode 100644 Makefile create mode 100644 README create mode 100644 build/Make-append create mode 100644 build/Make-template create mode 100644 build/PORTS create mode 100644 build/README-unproto create mode 100644 build/db.1.85.patch create mode 100755 build/install.sh create mode 100755 build/mkdep create mode 100644 build/platforms/Make-setup create mode 100644 build/platforms/Makefile create mode 100644 build/platforms/aix-cc/Make-platform create mode 100644 build/platforms/aix-gcc/Make-platform create mode 100644 build/platforms/freebsd-gcc/Make-platform create mode 100644 build/platforms/hpux-c89/Make-platform create mode 100644 build/platforms/hpux-cc/Make-platform create mode 100644 build/platforms/hpux-gcc/Make-platform create mode 100644 build/platforms/irix-cc/Make-platform create mode 100644 build/platforms/irix-gcc/Make-platform create mode 100644 build/platforms/linux-gcc/Make-platform create mode 100644 build/platforms/ncr-mp-ras-2-cc/Make-platform create mode 100644 build/platforms/netbsd-cc/Make-platform create mode 100644 build/platforms/netbsd-gcc/Make-platform create mode 100644 build/platforms/nextstep-cc/Make-platform create mode 100644 build/platforms/osf1-cc/Make-platform create mode 100644 build/platforms/sco-cc/Make-platform create mode 100644 build/platforms/sco-gcc/Make-platform create mode 100644 build/platforms/sunos4-cc/Make-platform create mode 100644 build/platforms/sunos4-gcc/Make-platform create mode 100644 build/platforms/sunos5-cc/Make-platform create mode 100644 build/platforms/sunos5-gcc/Make-platform create mode 100644 build/platforms/ultrix-cc/Make-platform create mode 100644 build/platforms/ultrix-gcc/Make-platform create mode 100644 build/platforms/vms/Makefile create mode 100644 build/platforms/vms/make.com create mode 100644 build/uname.sh create mode 100644 build/unproto/Makefile create mode 100644 build/unproto/README create mode 100755 build/unproto/acc.sh create mode 100755 build/unproto/cpp.sh create mode 100644 build/unproto/error.c create mode 100644 build/unproto/error.h create mode 100644 build/unproto/example.c create mode 100644 build/unproto/example.out create mode 100644 build/unproto/hash.c create mode 100644 build/unproto/stdarg.h create mode 100644 build/unproto/stddef.h create mode 100644 build/unproto/stdlib.h create mode 100644 build/unproto/strsave.c create mode 100644 build/unproto/symbol.c create mode 100644 build/unproto/symbol.h create mode 100644 build/unproto/tok_class.c create mode 100644 build/unproto/tok_io.c create mode 100644 build/unproto/tok_pool.c create mode 100644 build/unproto/token.h create mode 100644 build/unproto/unproto.1 create mode 100644 build/unproto/unproto.c create mode 100644 build/unproto/varargs.c create mode 100644 build/unproto/vstring.c create mode 100644 build/unproto/vstring.h create mode 100644 build/version create mode 100644 clients/Make-template create mode 100644 clients/fax500/Make-template create mode 100644 clients/fax500/README create mode 100644 clients/fax500/Version.c create mode 100644 clients/fax500/Versionrp.c create mode 100644 clients/fax500/faxtotpc.c create mode 100644 clients/fax500/main.c create mode 100644 clients/fax500/rp500.c create mode 100644 clients/fax500/xrpcomp create mode 100644 clients/finger/Make-template create mode 100644 clients/finger/Version.c create mode 100644 clients/finger/main.c create mode 100644 clients/gopher/Make-template create mode 100644 clients/gopher/README create mode 100644 clients/gopher/Version.c create mode 100644 clients/gopher/Versiongw.c create mode 100644 clients/gopher/detach.c create mode 100644 clients/gopher/go500.c create mode 100644 clients/gopher/go500gw.c create mode 100644 clients/gopher/go500gw.help create mode 100644 clients/gopher/setproctitle.c create mode 100644 clients/mail500/Make-template create mode 100644 clients/mail500/README create mode 100644 clients/mail500/Version.c create mode 100644 clients/mail500/main.c create mode 100644 clients/mail500/sendmail.cf create mode 100644 clients/rcpt500/Make-template create mode 100644 clients/rcpt500/README create mode 100644 clients/rcpt500/Version.c create mode 100644 clients/rcpt500/cmds.c create mode 100644 clients/rcpt500/help.c create mode 100644 clients/rcpt500/main.c create mode 100644 clients/rcpt500/query.c create mode 100644 clients/rcpt500/rcpt500.h create mode 100644 clients/rcpt500/rcpt500.help create mode 100644 clients/tools/Make-template create mode 100644 clients/tools/Versionldd.c create mode 100644 clients/tools/Versionldm.c create mode 100644 clients/tools/Versionldr.c create mode 100644 clients/tools/Versionlds.c create mode 100644 clients/tools/ldapdelete.c create mode 100644 clients/tools/ldapmodify.c create mode 100644 clients/tools/ldapmodrdn.c create mode 100644 clients/tools/ldapsearch.c create mode 100644 clients/ud/Make-template create mode 100644 clients/ud/README create mode 100644 clients/ud/Version.c create mode 100644 clients/ud/auth.c create mode 100644 clients/ud/edit.c create mode 100644 clients/ud/etc.ud.conf create mode 100644 clients/ud/find.c create mode 100644 clients/ud/globals.c create mode 100644 clients/ud/group.c create mode 100644 clients/ud/help.c create mode 100644 clients/ud/main.c create mode 100644 clients/ud/mod.c create mode 100644 clients/ud/print.c create mode 100644 clients/ud/string_to_key.c create mode 100644 clients/ud/ud.h create mode 100644 clients/ud/util.c create mode 100644 contrib/README create mode 100644 contrib/saucer/Make-template create mode 100644 contrib/saucer/README create mode 100644 contrib/saucer/main.c create mode 100644 contrib/saucer/sample.saucerrc create mode 100644 contrib/saucer/saucer.1 create mode 100644 contrib/web500gw/README create mode 100644 contrib/whois++/BUGS create mode 100644 contrib/whois++/INSTALL create mode 100644 contrib/whois++/Makefile create mode 100644 contrib/whois++/README create mode 100644 contrib/whois++/TODO create mode 100644 contrib/whois++/command.c create mode 100644 contrib/whois++/config.c create mode 100644 contrib/whois++/describe.c create mode 100644 contrib/whois++/help.c create mode 100644 contrib/whois++/helpfiles/english/command create mode 100644 contrib/whois++/helpfiles/english/commands create mode 100644 contrib/whois++/helpfiles/english/constraints create mode 100644 contrib/whois++/helpfiles/english/describe create mode 100644 contrib/whois++/helpfiles/english/general create mode 100644 contrib/whois++/helpfiles/english/help create mode 100644 contrib/whois++/helpfiles/english/list create mode 100644 contrib/whois++/helpfiles/english/search create mode 100644 contrib/whois++/helpfiles/english/show create mode 100644 contrib/whois++/helpfiles/english/version create mode 100644 contrib/whois++/output.c create mode 100644 contrib/whois++/root.Makefile.diff create mode 100644 contrib/whois++/template.c create mode 100644 contrib/whois++/templates/applicationentity create mode 100644 contrib/whois++/templates/organizationalrole create mode 100644 contrib/whois++/templates/organizationalunit create mode 100644 contrib/whois++/templates/person create mode 100644 contrib/whois++/util.c create mode 100644 contrib/whois++/version.c create mode 100644 contrib/whois++/whois++.c create mode 100644 contrib/whois++/whois++.h create mode 100644 contrib/whois++/whois++d.man create mode 100644 contrib/whois++/whois++dtailor create mode 100644 doc/Make-template create mode 100644 doc/guides/Make-template create mode 100644 doc/man/Make-template create mode 100644 doc/man/man1/Make-template create mode 100644 doc/man/man1/ldapdelete.1 create mode 100644 doc/man/man1/ldapmodify.1 create mode 100644 doc/man/man1/ldapmodify.1.links create mode 100644 doc/man/man1/ldapmodrdn.1 create mode 100644 doc/man/man1/ldapsearch.1 create mode 100644 doc/man/man1/ud.1 create mode 100644 doc/man/man3/Make-template create mode 100644 doc/man/man3/cldap_close.3 create mode 100644 doc/man/man3/cldap_open.3 create mode 100644 doc/man/man3/cldap_search_s.3 create mode 100644 doc/man/man3/cldap_setretryinfo.3 create mode 100644 doc/man/man3/lber-decode.3 create mode 100644 doc/man/man3/lber-encode.3 create mode 100644 doc/man/man3/ldap.3 create mode 100644 doc/man/man3/ldap.3.links create mode 100644 doc/man/man3/ldap_abandon.3 create mode 100644 doc/man/man3/ldap_add.3 create mode 100644 doc/man/man3/ldap_add.3.links create mode 100644 doc/man/man3/ldap_bind.3 create mode 100644 doc/man/man3/ldap_bind.3.links create mode 100644 doc/man/man3/ldap_cache.3 create mode 100644 doc/man/man3/ldap_cache.3.links create mode 100644 doc/man/man3/ldap_charset.3 create mode 100644 doc/man/man3/ldap_charset.3.links create mode 100644 doc/man/man3/ldap_compare.3 create mode 100644 doc/man/man3/ldap_compare.3.links create mode 100644 doc/man/man3/ldap_delete.3 create mode 100644 doc/man/man3/ldap_delete.3.links create mode 100644 doc/man/man3/ldap_disptmpl.3 create mode 100644 doc/man/man3/ldap_disptmpl.3.links create mode 100644 doc/man/man3/ldap_entry2text.3 create mode 100644 doc/man/man3/ldap_entry2text.3.links create mode 100644 doc/man/man3/ldap_error.3 create mode 100644 doc/man/man3/ldap_error.3.links create mode 100644 doc/man/man3/ldap_first_attribute.3 create mode 100644 doc/man/man3/ldap_first_attribute.3.links create mode 100644 doc/man/man3/ldap_first_entry.3 create mode 100644 doc/man/man3/ldap_first_entry.3.links create mode 100644 doc/man/man3/ldap_friendly.3 create mode 100644 doc/man/man3/ldap_friendly.3.links create mode 100644 doc/man/man3/ldap_get_dn.3 create mode 100644 doc/man/man3/ldap_get_dn.3.links create mode 100644 doc/man/man3/ldap_get_values.3 create mode 100644 doc/man/man3/ldap_get_values.3.links create mode 100644 doc/man/man3/ldap_getfilter.3 create mode 100644 doc/man/man3/ldap_getfilter.3.links create mode 100644 doc/man/man3/ldap_modify.3 create mode 100644 doc/man/man3/ldap_modify.3.links create mode 100644 doc/man/man3/ldap_modrdn.3 create mode 100644 doc/man/man3/ldap_modrdn.3.links create mode 100644 doc/man/man3/ldap_open.3 create mode 100644 doc/man/man3/ldap_open.3.links create mode 100644 doc/man/man3/ldap_result.3 create mode 100644 doc/man/man3/ldap_result.3.links create mode 100644 doc/man/man3/ldap_search.3 create mode 100644 doc/man/man3/ldap_search.3.links create mode 100644 doc/man/man3/ldap_searchprefs.3 create mode 100644 doc/man/man3/ldap_searchprefs.3.links create mode 100644 doc/man/man3/ldap_sort.3 create mode 100644 doc/man/man3/ldap_sort.3.links create mode 100644 doc/man/man3/ldap_ufn.3 create mode 100644 doc/man/man3/ldap_ufn.3.links create mode 100644 doc/man/man3/ldap_url.3 create mode 100644 doc/man/man3/ldap_url.3.links create mode 100644 doc/man/man3/regex.3 create mode 100644 doc/man/man5/Make-template create mode 100644 doc/man/man5/ldapfilter.conf.5 create mode 100644 doc/man/man5/ldapfriendly.5 create mode 100644 doc/man/man5/ldapsearchprefs.conf.5 create mode 100644 doc/man/man5/ldaptemplates.conf.5 create mode 100644 doc/man/man5/ldif.5 create mode 100644 doc/man/man5/slapd.conf.5 create mode 100644 doc/man/man5/slapd.replog.5 create mode 100644 doc/man/man5/ud.conf.5 create mode 100644 doc/man/man8/Make-template create mode 100644 doc/man/man8/centipede.8 create mode 100644 doc/man/man8/chlog2replog.8 create mode 100644 doc/man/man8/edb2ldif.8 create mode 100644 doc/man/man8/go500.8 create mode 100644 doc/man/man8/go500gw.8 create mode 100644 doc/man/man8/in.xfingerd.8 create mode 100644 doc/man/man8/ldapd.8 create mode 100644 doc/man/man8/ldbmcat.8 create mode 100644 doc/man/man8/ldif.8 create mode 100644 doc/man/man8/ldif2ldbm.8 create mode 100644 doc/man/man8/ldif2ldbm.8.links create mode 100644 doc/man/man8/mail500.8 create mode 100644 doc/man/man8/mail500.8.links create mode 100644 doc/man/man8/rcpt500.8 create mode 100644 doc/man/man8/slapd.8 create mode 100644 doc/man/man8/slurpd.8 create mode 100644 doc/rfc/Make-template create mode 100644 doc/rfc/rfc1558.txt create mode 100644 doc/rfc/rfc1777.txt create mode 100644 doc/rfc/rfc1778.txt create mode 100644 doc/rfc/rfc1779.txt create mode 100644 doc/rfc/rfc1798.txt create mode 100644 doc/rfc/rfc1823.txt create mode 100644 include/Make-template create mode 100644 include/avl.h create mode 100644 include/disptmpl.h create mode 100644 include/lber.h create mode 100644 include/ldap.h create mode 100644 include/ldapconfig.h.edit create mode 100644 include/ldapconfig.h.um create mode 100644 include/ldbm.h create mode 100644 include/ldif.h create mode 100644 include/lthread.h create mode 100644 include/portable.h create mode 100644 include/proto-lber.h create mode 100644 include/proto-ldap.h create mode 100644 include/regex.h create mode 100644 include/srchpref.h create mode 100644 include/sysexits-compat.h create mode 100644 libraries/Make-template create mode 100644 libraries/libavl/Make-template create mode 100644 libraries/libavl/Version.c create mode 100644 libraries/libavl/avl.c create mode 100644 libraries/libavl/testavl.c create mode 100644 libraries/liblber/Make-template create mode 100644 libraries/liblber/Version.c create mode 100644 libraries/liblber/bprint.c create mode 100644 libraries/liblber/decode.c create mode 100644 libraries/liblber/dtest.c create mode 100644 libraries/liblber/encode.c create mode 100644 libraries/liblber/etest.c create mode 100644 libraries/liblber/idtest.c create mode 100644 libraries/liblber/io.c create mode 100644 libraries/libldap/Make-template create mode 100644 libraries/libldap/Version.c create mode 100644 libraries/libldap/abandon.c create mode 100644 libraries/libldap/add.c create mode 100644 libraries/libldap/addentry.c create mode 100644 libraries/libldap/bind.c create mode 100644 libraries/libldap/cache.c create mode 100644 libraries/libldap/charset.c create mode 100644 libraries/libldap/cldap.c create mode 100644 libraries/libldap/compare.c create mode 100644 libraries/libldap/delete.c create mode 100644 libraries/libldap/disptmpl.c create mode 100644 libraries/libldap/dsparse.c create mode 100644 libraries/libldap/error.c create mode 100644 libraries/libldap/free.c create mode 100644 libraries/libldap/friendly.c create mode 100644 libraries/libldap/getattr.c create mode 100644 libraries/libldap/getdn.c create mode 100644 libraries/libldap/getdxbyname.c create mode 100644 libraries/libldap/getentry.c create mode 100644 libraries/libldap/getfilter.c create mode 100644 libraries/libldap/getvalues.c create mode 100644 libraries/libldap/kbind.c create mode 100644 libraries/libldap/ldap-int.h create mode 100644 libraries/libldap/ldapfilter.conf create mode 100644 libraries/libldap/ldapfriendly create mode 100644 libraries/libldap/ldapsearchprefs.conf create mode 100644 libraries/libldap/ldaptemplates.conf create mode 100644 libraries/libldap/modify.c create mode 100644 libraries/libldap/modrdn.c create mode 100644 libraries/libldap/open.c create mode 100644 libraries/libldap/os-ip.c create mode 100644 libraries/libldap/regex.c create mode 100644 libraries/libldap/request.c create mode 100644 libraries/libldap/result.c create mode 100644 libraries/libldap/sbind.c create mode 100644 libraries/libldap/search.c create mode 100644 libraries/libldap/sort.c create mode 100644 libraries/libldap/srchpref.c create mode 100644 libraries/libldap/test.c create mode 100644 libraries/libldap/tmplout.c create mode 100644 libraries/libldap/tmpltest.c create mode 100644 libraries/libldap/ufn.c create mode 100644 libraries/libldap/unbind.c create mode 100644 libraries/libldap/url.c create mode 100644 libraries/libldbm/Make-template create mode 100644 libraries/libldbm/Version.c create mode 100644 libraries/libldbm/ldbm.c create mode 100644 libraries/libldif/Make-template create mode 100644 libraries/libldif/Version.c create mode 100644 libraries/libldif/line64.c create mode 100644 libraries/liblthread/Make-template create mode 100644 libraries/liblthread/Version.c create mode 100644 libraries/liblthread/stack.c create mode 100644 libraries/liblthread/thread.c create mode 100644 libraries/macintosh/Make-template create mode 100644 libraries/macintosh/README create mode 100644 libraries/macintosh/getopt.c create mode 100644 libraries/macintosh/kerberos-macos.c create mode 100644 libraries/macintosh/macos-ip.c create mode 100644 libraries/macintosh/macos.h create mode 100644 libraries/macintosh/strings.c create mode 100644 libraries/macintosh/tcp/AddressXlation.h create mode 100644 libraries/macintosh/tcp/GetMyIPAddr.h create mode 100644 libraries/macintosh/tcp/MacTCPCommonTypes.h create mode 100644 libraries/macintosh/tcp/MiscIPPB.h create mode 100644 libraries/macintosh/tcp/TCPPB.h create mode 100644 libraries/macintosh/tcp/UDPPB.h create mode 100644 libraries/macintosh/tcp/dnr.c create mode 100644 libraries/macintosh/tcp/tcp.c create mode 100644 libraries/macintosh/tcp/tcp.h create mode 100644 libraries/msdos/Make-template create mode 100644 libraries/msdos/README create mode 100644 libraries/msdos/README.CSA create mode 100644 libraries/msdos/README.NFS create mode 100644 libraries/msdos/README.WSA create mode 100644 libraries/msdos/lp.c create mode 100644 libraries/msdos/makefile.msc create mode 100644 libraries/msdos/makefile.nfs create mode 100644 libraries/msdos/makelber.msc create mode 100644 libraries/msdos/makelber.nfs create mode 100644 libraries/msdos/makeldap.msc create mode 100644 libraries/msdos/makeldap.nfs create mode 100644 libraries/msdos/makeud.msc create mode 100644 libraries/msdos/msdos.c create mode 100644 libraries/msdos/msdos.h create mode 100644 libraries/msdos/opendos.c create mode 100644 libraries/msdos/protoud.h create mode 100644 libraries/msdos/winsock/include/file.h create mode 100644 libraries/msdos/winsock/include/filio.h create mode 100644 libraries/msdos/winsock/include/in.h create mode 100644 libraries/msdos/winsock/include/ioctl.h create mode 100644 libraries/msdos/winsock/include/krb/des.h create mode 100644 libraries/msdos/winsock/include/krb/krb.h create mode 100644 libraries/msdos/winsock/include/krb/mit/arpa/nameser.h create mode 100644 libraries/msdos/winsock/include/krb/mit/conf-pc.h create mode 100644 libraries/msdos/winsock/include/krb/mit/conf.h create mode 100644 libraries/msdos/winsock/include/krb/mit/hesiod.h create mode 100644 libraries/msdos/winsock/include/krb/mit/lsh_pwd.h create mode 100644 libraries/msdos/winsock/include/krb/mit/mit_copy.h create mode 100644 libraries/msdos/winsock/include/krb/mit/osconf.h create mode 100644 libraries/msdos/winsock/include/krb/mit/resolv.h create mode 100644 libraries/msdos/winsock/include/krb/mit/wshelper.h create mode 100644 libraries/msdos/winsock/include/net/_sys/filio.h create mode 100644 libraries/msdos/winsock/include/net/_sys/ioctl.h create mode 100644 libraries/msdos/winsock/include/net/netdb.h create mode 100644 libraries/msdos/winsock/include/param.h create mode 100644 libraries/msdos/winsock/include/select.h create mode 100644 libraries/msdos/winsock/include/socket.h create mode 100644 libraries/msdos/winsock/include/time.h create mode 100644 libraries/msdos/winsock/include/wsa.h create mode 100644 libraries/msdos/winsock/include/wsa/errno.c create mode 100644 libraries/msdos/winsock/include/wsa/errno.rc create mode 100644 libraries/msdos/winsock/include/wsa/winsock.def create mode 100644 libraries/msdos/winsock/include/wsa/winsock.h create mode 100644 libraries/msdos/winsock/kerberos.c create mode 100644 libraries/msdos/winsock/ldap32.def create mode 100644 libraries/msdos/winsock/ldap32.mak create mode 100644 libraries/msdos/winsock/ldap32.mdp create mode 100644 libraries/msdos/winsock/libldap.def create mode 100644 libraries/msdos/winsock/libldap.mak create mode 100644 libraries/msdos/winsock/libldap.rc create mode 100644 libraries/msdos/winsock/ltest/console.c create mode 100644 libraries/msdos/winsock/ltest/console.h create mode 100644 libraries/msdos/winsock/ltest/inpdlg.dlg create mode 100644 libraries/msdos/winsock/ltest/inpdlg.h create mode 100644 libraries/msdos/winsock/ltest/ltest.def create mode 100644 libraries/msdos/winsock/ltest/ltest.mak create mode 100644 libraries/msdos/winsock/ltest/ltest.rc create mode 100644 libraries/msdos/winsock/ltest/ltest32.mak create mode 100644 libraries/msdos/winsock/ltest/ltest32.mdp create mode 100644 libraries/msdos/winsock/ltest/textwind.c create mode 100644 libraries/msdos/winsock/ltest/textwind.h create mode 100644 libraries/msdos/winsock/makefile create mode 100644 libraries/msdos/winsock/openwsa.c create mode 100644 libraries/msdos/winsock/setupwsa.bat create mode 100644 libraries/msdos/winsock/unsetupwsa.bat create mode 100644 libraries/msdos/winsock/winkit/help/ldap32.hlp create mode 100644 libraries/msdos/winsock/winkit/help/ldap32.hpj create mode 100644 libraries/msdos/winsock/winkit/help/libldap.hlp create mode 100644 libraries/msdos/winsock/winkit/help/libldap.hpj create mode 100644 libraries/msdos/winsock/winkit/readme.txt create mode 100644 libraries/msdos/winsock/winkit/windowskit.cmd create mode 100644 libraries/msdos/winsock/winkit/windowskit.mak create mode 100644 libraries/msdos/winsock/wsa.c create mode 100644 libraries/msdos/winsock/wsa/errno.c create mode 100644 libraries/msdos/winsock/wsa/errno.rc create mode 100644 libraries/msdos/winsock/wsa/winsock.def create mode 100644 libraries/msdos/winsock/wsa/winsock.h create mode 100644 libraries/msdos/winsock/wsockip.c create mode 100644 libraries/vms/Make-template create mode 100644 libraries/vms/README.VMS create mode 100644 libraries/vms/getopt.c create mode 100644 libraries/vms/strings.c create mode 100644 libraries/vms/ucx_select.h create mode 100644 servers/Make-template create mode 100644 servers/ldapd/Make-template create mode 100644 servers/ldapd/Version.c create mode 100644 servers/ldapd/abandon.c create mode 100644 servers/ldapd/add.c create mode 100644 servers/ldapd/association.c create mode 100644 servers/ldapd/bind.c create mode 100644 servers/ldapd/certificate.c create mode 100644 servers/ldapd/common.h create mode 100644 servers/ldapd/compare.c create mode 100644 servers/ldapd/delete.c create mode 100644 servers/ldapd/detach.c create mode 100644 servers/ldapd/error.c create mode 100644 servers/ldapd/kerberos.c create mode 100644 servers/ldapd/ldap.py create mode 100644 servers/ldapd/main.c create mode 100644 servers/ldapd/message.c create mode 100644 servers/ldapd/modify.c create mode 100644 servers/ldapd/modrdn.c create mode 100644 servers/ldapd/proto-ldapd.h create mode 100644 servers/ldapd/request.c create mode 100644 servers/ldapd/result.c create mode 100644 servers/ldapd/search.c create mode 100644 servers/ldapd/setproctitle.c create mode 100644 servers/ldapd/syntax.c create mode 100644 servers/ldapd/util.c create mode 100644 servers/slapd/Make-template create mode 100644 servers/slapd/Version.c create mode 100644 servers/slapd/abandon.c create mode 100644 servers/slapd/acl.c create mode 100644 servers/slapd/aclparse.c create mode 100644 servers/slapd/add.c create mode 100644 servers/slapd/attr.c create mode 100644 servers/slapd/ava.c create mode 100644 servers/slapd/back-ldbm/Make-template create mode 100644 servers/slapd/back-ldbm/Version.c create mode 100644 servers/slapd/back-ldbm/abandon.c create mode 100644 servers/slapd/back-ldbm/add.c create mode 100644 servers/slapd/back-ldbm/attr.c create mode 100644 servers/slapd/back-ldbm/back-ldbm.h create mode 100644 servers/slapd/back-ldbm/bind.c create mode 100644 servers/slapd/back-ldbm/cache.c create mode 100644 servers/slapd/back-ldbm/close.c create mode 100644 servers/slapd/back-ldbm/compare.c create mode 100644 servers/slapd/back-ldbm/config.c create mode 100644 servers/slapd/back-ldbm/dbcache.c create mode 100644 servers/slapd/back-ldbm/delete.c create mode 100644 servers/slapd/back-ldbm/dn2id.c create mode 100644 servers/slapd/back-ldbm/filterindex.c create mode 100644 servers/slapd/back-ldbm/id2children.c create mode 100644 servers/slapd/back-ldbm/id2entry.c create mode 100644 servers/slapd/back-ldbm/idl.c create mode 100644 servers/slapd/back-ldbm/index.c create mode 100644 servers/slapd/back-ldbm/init.c create mode 100644 servers/slapd/back-ldbm/kerberos.c create mode 100644 servers/slapd/back-ldbm/modify.c create mode 100644 servers/slapd/back-ldbm/modrdn.c create mode 100644 servers/slapd/back-ldbm/nextid.c create mode 100644 servers/slapd/back-ldbm/proto-back-ldbm.h create mode 100644 servers/slapd/back-ldbm/search.c create mode 100644 servers/slapd/back-ldbm/unbind.c create mode 100644 servers/slapd/back-passwd/Make-template create mode 100644 servers/slapd/back-passwd/Version.c create mode 100644 servers/slapd/back-passwd/config.c create mode 100644 servers/slapd/back-passwd/search.c create mode 100644 servers/slapd/back-shell/Make-template create mode 100644 servers/slapd/back-shell/Version.c create mode 100644 servers/slapd/back-shell/abandon.c create mode 100644 servers/slapd/back-shell/add.c create mode 100644 servers/slapd/back-shell/bind.c create mode 100644 servers/slapd/back-shell/compare.c create mode 100644 servers/slapd/back-shell/config.c create mode 100644 servers/slapd/back-shell/delete.c create mode 100644 servers/slapd/back-shell/fork.c create mode 100644 servers/slapd/back-shell/init.c create mode 100644 servers/slapd/back-shell/modify.c create mode 100644 servers/slapd/back-shell/modrdn.c create mode 100644 servers/slapd/back-shell/result.c create mode 100644 servers/slapd/back-shell/search.c create mode 100644 servers/slapd/back-shell/searchexample.conf create mode 100644 servers/slapd/back-shell/searchexample.sh create mode 100644 servers/slapd/back-shell/shell.h create mode 100644 servers/slapd/back-shell/unbind.c create mode 100644 servers/slapd/backend.c create mode 100644 servers/slapd/bind.c create mode 100644 servers/slapd/ch_malloc.c create mode 100644 servers/slapd/charray.c create mode 100644 servers/slapd/compare.c create mode 100644 servers/slapd/config.c create mode 100644 servers/slapd/configinfo.c create mode 100644 servers/slapd/connection.c create mode 100644 servers/slapd/daemon.c create mode 100644 servers/slapd/delete.c create mode 100644 servers/slapd/detach.c create mode 100644 servers/slapd/dn.c create mode 100644 servers/slapd/entry.c create mode 100644 servers/slapd/filter.c create mode 100644 servers/slapd/filterentry.c create mode 100644 servers/slapd/init.c create mode 100644 servers/slapd/lock.c create mode 100644 servers/slapd/main.c create mode 100644 servers/slapd/modify.c create mode 100644 servers/slapd/modrdn.c create mode 100644 servers/slapd/monitor.c create mode 100644 servers/slapd/operation.c create mode 100644 servers/slapd/phonetic.c create mode 100644 servers/slapd/proto-slap.h create mode 100644 servers/slapd/regex.c create mode 100644 servers/slapd/repl.c create mode 100644 servers/slapd/result.c create mode 100644 servers/slapd/schema.c create mode 100644 servers/slapd/schemaparse.c create mode 100644 servers/slapd/search.c create mode 100644 servers/slapd/shell-backends/Make-template create mode 100644 servers/slapd/shell-backends/passwd-shell.c create mode 100644 servers/slapd/shell-backends/passwd-shell.h create mode 100644 servers/slapd/shell-backends/pwd-Version.c create mode 100644 servers/slapd/shell-backends/shellutil.c create mode 100644 servers/slapd/shell-backends/shellutil.h create mode 100644 servers/slapd/slap.h create mode 100644 servers/slapd/slapd.at.conf create mode 100644 servers/slapd/slapd.conf create mode 100644 servers/slapd/slapd.oc.conf create mode 100644 servers/slapd/str2filter.c create mode 100644 servers/slapd/strdup.c create mode 100644 servers/slapd/tempnam.c create mode 100644 servers/slapd/tools/Make-template create mode 100644 servers/slapd/tools/Vers-edb2.c create mode 100644 servers/slapd/tools/centipede.c create mode 100644 servers/slapd/tools/chlog2replog.c create mode 100644 servers/slapd/tools/edb2ldif.c create mode 100644 servers/slapd/tools/ldapsyntax.c create mode 100644 servers/slapd/tools/ldapsyntax.h create mode 100644 servers/slapd/tools/ldbmcat.c create mode 100644 servers/slapd/tools/ldbmtest.c create mode 100644 servers/slapd/tools/ldif.c create mode 100644 servers/slapd/tools/ldif2id2children.c create mode 100644 servers/slapd/tools/ldif2id2entry.c create mode 100644 servers/slapd/tools/ldif2index.c create mode 100644 servers/slapd/tools/ldif2ldbm.c create mode 100644 servers/slapd/tools/sizecount.c create mode 100644 servers/slapd/unbind.c create mode 100644 servers/slapd/value.c create mode 100644 servers/slurpd/DESIGN create mode 100644 servers/slurpd/Make-template create mode 100644 servers/slurpd/Version.c create mode 100644 servers/slurpd/admin.c create mode 100644 servers/slurpd/args.c create mode 100644 servers/slurpd/ch_malloc.c create mode 100644 servers/slurpd/config.c create mode 100644 servers/slurpd/detach.c create mode 100644 servers/slurpd/fm.c create mode 100644 servers/slurpd/globals.c create mode 100644 servers/slurpd/globals.h create mode 100644 servers/slurpd/ldap_op.c create mode 100644 servers/slurpd/lock.c create mode 100644 servers/slurpd/main.c create mode 100644 servers/slurpd/re.c create mode 100644 servers/slurpd/reject.c create mode 100644 servers/slurpd/replica.c create mode 100644 servers/slurpd/replog.c create mode 100644 servers/slurpd/ri.c create mode 100644 servers/slurpd/rq.c create mode 100644 servers/slurpd/sanity.c create mode 100644 servers/slurpd/slurp.h create mode 100644 servers/slurpd/st.c create mode 100644 servers/slurpd/tsleep.c create mode 100644 tests/Make-template create mode 100644 tests/README create mode 100644 tests/data/acl.out.master create mode 100644 tests/data/modify.out.master create mode 100644 tests/data/search.out.master create mode 100644 tests/data/slapd-acl.conf create mode 100644 tests/data/slapd-master.conf create mode 100644 tests/data/slapd-repl-master.conf create mode 100644 tests/data/slapd-repl-slave.conf create mode 100644 tests/data/slapd.at.conf create mode 100644 tests/data/slapd.oc.conf create mode 100644 tests/data/test-ordered.ldif create mode 100644 tests/data/test.ldif create mode 100755 tests/scripts/all create mode 100755 tests/scripts/defines.sh create mode 100755 tests/scripts/makeldbm.sh create mode 100755 tests/scripts/test001-ldif2ldbm create mode 100755 tests/scripts/test001-slapadd create mode 100755 tests/scripts/test002-populate create mode 100755 tests/scripts/test003-search create mode 100755 tests/scripts/test004-modify create mode 100755 tests/scripts/test005-modrdn create mode 100755 tests/scripts/test006-acls create mode 100755 tests/scripts/test007-replication diff --git a/ANNOUNCEMENT b/ANNOUNCEMENT new file mode 100644 index 0000000000..0075060e70 --- /dev/null +++ b/ANNOUNCEMENT @@ -0,0 +1,90 @@ + A N N O U N C E M E N T + + LDAP 3.3 + + The University of Michigan is pleased to announce release 3.3 of + UM-LDAP, an implementation of the Lightweight Directory Access + Protocol. LDAP is a draft Internet standard directory service + protocol that runs over TCP/IP. It can be used to provide a + stand-alone directory service, or to provide lightweight access to + the X.500 directory. LDAP is defined by RFC 1777 and RFC 1778. + + This release includes the following components: + + - slapd - a stand-alone LDAP directory server + - slurpd - a stand-alone LDAP replication server + - ldapd - an LDAP-to-X.500 gateway server + - centipede - an LDAP centroid generation and maintenance program + - libldap - an LDAP client library + - liblber - a lightweight BER/DER encoding/decoding library + - ldif tools - data conversion tools for use with slapd + - in.xfingerd - a finger-to-LDAP gateway server + - go500 - a gopher-to-LDAP gateway server for searching + - go500gw - a gopher-to-LDAP gateway server for searching and browsing + - rcpt500 - an email-to-LDAP query responder + - mail500 - an LDAP-capable mailer + - fax500 - an LDAP-capable mailer that supports remote printing + - LDAP tools - A collection of shell-based LDAP utility programs + + In addition, there are some contributed components: + + - web500 - an HTTP-to-LDAP gateway + - whois++d - a WHOIS++-to-LDAP gateway + - saucer - a simple command-line oriented client program + +CHANGES + + Changes since release 3.2 of LDAP include + + - slurpd has been rewritten as a single process threaded daemon + - ldaptools (ldapsearch, etc) now support the LDIF format + - support for LDAP URLs added to libldap + - improved support for LDAP referrals in libldap + - preliminary test scripts included + - support for additional platforms + - various bug fixes and build fixes + + See the CHANGES file in the distribution for more details. + +AVAILABILITY + + This software is freely available to anyone for any lawful purpose, + subject to the U-M copyright notice and disclaimer. The software is + available for anonymous ftp from the following location: + + ftp://terminator.rs.itd.umich.edu/ldap/ldap-3.3.tar.Z + +SUPPORT + + The software is provided as is without any express or implied + warranty, but there is a bug reporting mail address which is + responded to on a best-effort basis: + + ldap-support@umich.edu + + In addition, there is a discussion list for issues relating to this + implementation of ldap: + + ldap@umich.edu -- discussion list + ldap-request@umich.edu -- to join the list + + Comments or questions about the LDAP protocol in general should be + sent to the IETF ASID discussion group: + + ietf-asid@umich.edu -- discussion list + ietf-asid-request@umich.edu -- to join the list + + An LDAP home page containing lots of interesting information and + online documentation is available at this URL: + + http://www.umich.edu/~rsug/ldap/ + +SUPPORTED PLATFORMS + + This release has been ported to many UNIX platforms, including + SunOS 4.1.x, Solaris 2.x, Ultrix 4.3, HP-UX 9.05, AIX 3.2.5, + SCO, FreeBSD, NetBSD, LINUX, IRIX, Digital Unix (OSF/1), and + NeXTSTEP 3.2. This release has also been ported to VMS. + + The client libraries and some clients have also been ported to + MacOS 7.x, MSDOS (some TCP stacks), and MS Windows 3.1/95/NT. diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000000..924b505e3e --- /dev/null +++ b/CHANGES @@ -0,0 +1,545 @@ +Changes since 3.3b1 + +Various Make-template files - update by doing 'make depend' + +include/disptmpl.h - add LDAP_DISP_OPT_HTMLBODYONLY option + +libraries/liblber/io.c - under MacOS, limit tcpwrite() calls to a + maximum of 64K bytes; ber_flush() int/long fix + +libraries/libldap/friendly.c - don't use errno on MacOS or DOS +libraries/libldap/regex.c - fix re_exec() to that ".*" matches "" +libraries/libldap/result.c - eliminate memory leak in wait4msg() +libraries/libldap/request.c - eliminate double-free impurity +libraries/libldap/tmplout.c - add LDAP_DISP_OPT_HTMLBODYONLY option +libraries/libldap/ufn.c - purify: avoid bad frees; plug memory leaks + +libraries/libldif/line64.c - str_parse_line() now 0-terminates base64 vals. + +libraries/macintosh/* - tcpwrite()/OpenTransport bug fixes + - better error checking for MacTCP driver opens + - don't use old routine names any more + +libraries/msdos/winsock/* - various bugs fixes & improvements + +servers/slapd/modify.c - fix bug causing unnormalized attr names +servers/slapd/monitor.c - return new "version" attribute +servers/slapd/regex.c - fix re_exec() to that ".*" matches "" +servers/slapd/tools/ldbmcat.c - make -n option work (don't open file "-n" ) +servers/slapd/tools/ldif2id2entry.c - include ids in stored entries +servers/slapd/schema.c - log some information useful in tracking + down schema-check problems +servers/slapd/dn.c - dn_upcase() was not returning anything (doh!) +servers/slapd/backend.c - pass unbind request to all backends +servers/slapd/unbind.c - pass unbind request to all backends +servers/slapd/Version.c - remove leading spaces from Versionstr[] + +servers/slapd/back-ldbm/unbind.c - make arguments consistent +servers/slapd/back-ldbm/bind.c - fix bug which allowed anyone to bind as + anyone else using kerberos, if there was + at least one krbName in an entry + +servers/slurpd/replog.c - do all replog copying with buffered i/o +servers/slurpd/fm.c - fix inconsistency in arguments +servers/slurpd/main.c - fix inconsistency in arguments + +clients/tools/ldapdelete.c - add -K flag - only does LDAP_AUTH_KRBV41 +clients/tools/ldapmodify.c - add -K flag - only does LDAP_AUTH_KRBV41 +clients/tools/ldapmodrdn.c - add -K flag - only does LDAP_AUTH_KRBV41 +clients/tools/ldapsearch.c - add -K flag - only does LDAP_AUTH_KRBV41 + +doc/man/man1/ldapdelete.1 - add -K flag - only does LDAP_AUTH_KRBV41 +doc/man/man1/ldapmodify.1 - add -K flag - only does LDAP_AUTH_KRBV41 +doc/man/man1/ldapmodrdn.1 - add -K flag - only does LDAP_AUTH_KRBV41 +doc/man/man1/ldapsearch.1 - add -K flag - only does LDAP_AUTH_KRBV41 +doc/man/man3/ldap_entry2text.3 - document LDAP_DISP_OPT_HTMLBODYONLY option +doc/man/man8/slapd.8 - add BUGS section and document modrdn bug + +---------------------------------------------------------------------------- +Changes since 3.2 + +Makefile - added support for IRIX (SGI) + - make depend improvements + +tests/ - all new test scripts -- make test + +include/lber.h - use short include file names #ifdef WINSOCK +include/ldap.h - change LDAPCache struct definition to reduce + cache overhead + - use short include file names #ifdef WINSOCK + - LDAP URL support + - add lr_conn to LDAPRequest (needed by abandon) + - add LDAP_OPT_RESTART for select() restart + - revised Debug() macro #ifdef WINSOCK +include/ldbm.h - under NDBM, use O_RDWR instead of O_CREAT + - in LDBM_WRCREAT and LDBM_NEWDB +include/proto-lber.h - changes for WIN32 +include/proto-ldap.h - changes for WIN32 + - added LDAP URL routines +include/disptmpl.h - changes for WIN32 +include/ldif.h - includes for new libldif library +include/srchpref.h - changes for WIN32 +libraries/liblber/decode.c - vararg changes for WIN32 +libraries/liblber/encode.c - vararg changes for WIN32 +libraries/libldap/abandon.c - make ldap_abandon() work with referrals +libraries/libldap/bind.c - added new ldap_set_rebind_proc() routine +libraries/libldap/cache.c - reduce cache overhead + - fix small cache size infinite loop bug + - clarify debugging messages +libraries/libldap/charset.c - new routines: ldap_translate_from_t61, + ldap_translate_to_t61, + ldap_enable_translation +libraries/libldap/cldap.c - changes to support referral re-bind w/auth +libraries/libldap/getfilter.c - ldap_build_filter: don't use NULL value +libraries/libldap/kbind.c - changes to support referral re-bind w/auth +libraries/libldap/ldap-int.h - changes to support referral re-bind w/auth + - rename do_select() to do_ldap_select() +libraries/libldap/open.c - changes to support referral re-bind w/auth + - ld_options = LDAP_OPT_REFERRALS by default +libraries/libldap/os-ip.c - include to fix HP/UX gcc builds + - rename do_select() to do_ldap_select() +libraries/libldap/result.c - wait4msg debugging now shows timeout values + - changes to support referral re-bind w/auth + - rename do_select() to do_ldap_select() + - buf fix in ldap_msgdelete() -- update prev + - support LDAP_OPT_RESTART option +libraries/libldap/request.c - changes to support referral re-bind w/auth + - initialize new lr_conn field (for abandon) +libraries/libldap/test.c - changes to support referral re-bind w/auth +libraries/libldap/tmplout.c - searchact uses "-dnt" and "-dnb", not "-dn" +libraries/libldap/url.c - new routines: ldap_is_ldap_url, + ldap_parse_url, ldap_url_search + ldap_url_search_s, ldap_url_search_st + +libraries/libldif/ - new library that contains line64 routines + +clients/tools/ldapmodify.c - preferred input format is now slapd.replog +clients/tools/ldapsearch.c - added -L option (output in LDIF format) + - don't print initial blank line when -f used + - support "-f -" for reading filters from stdin +clients/ud/*.c - various bug fixes & auth. streamlining + +doc/man/man3/ldap.3 - add several new routines +doc/man/man3/ldap_bind.3/.links - add new ldap_set_rebind_proc() routine +doc/man/man3/ldap_charset.3/.links - add new routines +doc/man/man3/ldap_disptmpl.3 - added missing *'s in ldap_init... arg. lists +doc/man/man3/ldap_result.3 - add details r.e. timeout parameter +doc/man/man3/ldap_open.3 - document LDAP_OPT_REFERRALS default to on +doc/man/man3/ldap_url.3/.links - document new LDAP URL routines + +Make-common.dist and .um - add LDBMINCLUDE variable + - use ISODEPACKAGE and ICRELEASE in place of + ICR1 and XTISODE defines + - remove LDAP_DNS stuff + +build/Make-append - add LDBMINCLUDE variable + - add NO_SETPROCTITLE to SERVERDEFS + - use ISODEPACKAGE and ICRELEASE in place of + ICR1 and XTISODE defines +build/mkdep - use compiler passed in, not always cc + - remove system dependencies when gcc is used +build/platforms/attsvr4-cc/ - AT&T SVR4 support +build/platforms/irix-cc/ - SGI IRIX support +build/platforms/irix-gcc/ - SGI IRIX support + +servers/ldapd/common.h - add missing extern function declarations +servers/ldapd/association.c - use ISODEPACKAGE test instead of ICR1, etc. +servers/ldapd/certificate.c - add missing extern declaration +servers/ldapd/error.c - use ISODEPACKAGE test instead of ICR1, etc. +servers/ldapd/kerberos.c - use ISODEPACKAGE test instead of ICR1, etc. +servers/ldapd/request.c - use ISODEPACKAGE test instead of ICR1, etc. +servers/ldapd/main.c - set proctitle to calling host (bug fix) + - CLDAP: don't timeout/exit prematurely +servers/ldapd/proctitle.c - don't compile file if NO_SETPROCTITLE is on +servers/ldapd/Make-template - don't try to make depend if don't have isode +servers/ldap - bug fixes, support ICR3 + +servers/slapd/tools/ldif.c - use correct pointer when calling realloc +servers/slapd/tools/edb2ldif.c - properly #ifdef code to handle potential + lack of file_attr_dir and turbo disk stuff + - add RDN attribute values to entries + - don't pre-pend './' to EDB files on cmd. line +servers/slapd/tools/ldapsyntax.c- use static buffer to speed things up +servers/slapd/tools/Make-template - don't try to make depend some tools + - if we don't have isode +servers/slapd - fix acl handling +servers/slapd - fix race condition setting o_dn +servers/slapd - bug fixes + +servers/slurpd - complete re-write + +tests/ - new - test scripts to verify basic + functionality of libraries, slapd, slurpd + +---------------------------------------------------------------------------- +Changes since 3.2b3 + +slapd admin guide - document ldbmtest changes + - clarify quick-start instructions + +include/ldapconfig.h.dist - move likely-to-change things to top + +Make-common.dist - add phonetic algorithm config lines +build/Make-append - add def for phonetic algorithm config lines + +libraries/libldbm/ldbm.c - fix bug with gdbm cache size handling + +libraries/liblber/encode.c - cap lengths at 32-bits for Alpha compatibility + +libraries/libldap/disptmpl.c - recognize both "addact" and "adddnact" +libraries/libldap/getdn.c - handle \ escapes in DNs better + +clients/tools/ldapsearch.c - added -S option to sort results + - print results as they are received (if no -S) + +servers/slapd/* - added function prototypes +servers/slapd/phonetic.c - make phonetic alg settable in Make-common +servers/slapd/tools/ldbmtest.c - fix bugs, use dbcache routines (like slapd) + - add 'b' and 'B' commands +servers/slapd/tools/edb2ldif.c - include quipu/config.h & quipu/entry.h + - this fixes TURBO_DISK problems +servers/ldapd/* - misc. fixes for VMS and OSF/1 + - added function prototypes + +---------------------------------------------------------------------------- +Changes since 3.2b2 + +servers/slapd/* - lots of changes/fixes/improvements +servers/slapd/tools/* - add ldif program + - add centipede program + - numerous fixes/improvements + +clients/tools/ldapmodify.c - add -b option (read binary vals from a file) + - add trailing \ feature for iattr, etc. +clients/tools/ldapsearch.c - add -z sizelimit and -l timelimit options + - add -B (allow non-ascii values_ option + - change /tmp template used with -t + +include/lber.h - add LBER_MAX_INCOMING_SIZE option + +libraries/liblber/io.c - support LBER_MAX_INCOMING_SIZE option + - new ber_init() and ber_reset() routines + +libraries/libldap/* - various improvements to LDAP_REFERRALS code + - minor changes for Mac re-port + +libraries/libldap/disptmpl.c - "addact" is now "adddnact" +libraries/libldap/cache.c - we now cache compare results that have error + of LDAP_NO_SUCH_ATTRIBUTE +libraries/libldap/open.c - support :port on ldap_open() hosts +libraries/libldap/charset.c - new T.61 to ISO-8859 conversion support + - thanks to enrique.silvestre@uv.es + +libraries/libldap/kbind.c - a few changes for MS Windows + +libraries/msdos/winsock/* - a few changes for Kerberos support + +servers/ldapd/modify.c - added support for JPEG non-file attrs. + - added support for octetstring attrs. + +servers/ldapd/syntax.c - DN syntax fixes (OID. and replace {ASN} w/#) + - don't escape '$' in DeliveryMethod attrs. + - added support for JPEG non-file attrs. + - added support for octetstring attrs. + +---------------------------------------------------------------------------- +Changes since 3.2b1 + +servers/slapd/ - add better database concurrency + - remove multiple dn support + - add stats logging + - fix syslogging + - add include config file option + - add dbcachesize option + - add abandon + - add lastmod/creator attrs + - add monitoring capability + - normalize dns properly + - base 64 value encoding support + - add schema checking + - fix various bugs + - add srvtab config option +servers/slapd/tools - whole new set of db creation/conversion tools + +clients/finger/main.c - added -c option & use of FINGER_RDNCOUNT +clients/gopher/go500.c - added -c option & use of GO500_RDNCOUNT +clients/gopher/go500gw.c - added -c option & use of GO500GW_RDNCOUNT + - removed non-functional -s option +clients/rcpt500/main.c - added -c option & use of RCPT500_RDNCOUNT +clients/rcpt500/query.c - use rdncount instead of hard-coded 2 + +include/ldapconfig.h.edit - added _RDNCOUNT #defines + +libraries/libldap/tmplout.c - made rdncount of 0 show all DN components + +libraries/libldap/getdn.c - added ldap_is_dns_dn() routine + +libraries/libldap/* - many #ifndef NO_REFERRALS changes + - new ldap_init() routine + +---------------------------------------------------------------------------- +Changes since 3.1 final + +General/various files - incorporated changes for Borland C 3.1 + +Makefile - added support for NeXTSTEP + +libraries/liblber/io.c - add ability to save ldap session to a file +include/lber.h - add ability to save ldap session to a file + + +build/platforms/nextstep-cc/Make-platform + - added -all_load option for ld +build/platforms/sunos5-cc/Make-platform + - define SYSEXITSPATH as for sunos5-gcc + +build/uname.sh - new replacement uname for NeXTSTEP, etc. + +clients/finger/main.c - don't use fprintf for entry2text +clients/gopher/go500.c - use GO500_HOSTNAME (bug fix) + - don't use fprintf for entry2text +clients/gopher/go500gw.c - use GO500GW_HOSTNAME (bug fix) + - don't use fprintf for entry2text +clients/mail500/main.c - improved error logging + - fixed "errors-to is a group" bug + - don't look in people space for groups + - don't bounce loop messages back to sender + - misc. fixes +clients/tools/ldapdelete.c - add -c option to continue after errors occur +clients/tools/ldapmodify.c - add -c option to continue after errors occur +clients/tools/ldapmodrdn.c - add -c option to continue after errors occur +clients/tools/ldapsearch.c - added -t option to write values to tmp files + - added -A option for "attributes only" +clients/ud/print.c - make sure ldap_count_values() returns > 0 + - before trying to use returned values + +doc/man/man1/ldapdelete.1 - updated to mention new -c option +doc/man/man1/ldapmodify.1 - updated to mention new -c option +doc/man/man1/ldapmodrdn.1 - updated to mention new -c option +doc/man/man1/ldapsearch.1 - updated to mention new -A & -t options +doc/man/man3/ldap_friendly.3 - fixed typo in ldap_free_friendlymap() +doc/man/man5/ldapfilter.conf.5 - add missing part of example config file + +include/disptmpl.h - appended 'L' to long #defined contants + - added entry2html family of routines +include/lber.h - added sb_options to allow copy to file + - added ber_wptr to re-start partial writes +include/ldap.h - added debug levels for sldapd + - added LDAP_SYSLOG to send debug using syslog +include/ldapconfig.h.edit - added GO500GW_HOSTNAME +include/ldapconfig.h.dist - added GO500GW_HOSTNAME +include/portable.h - select() macro fix for HP/UX /bin/cc +include/proto-lber.h - Borland C fixes + - added ber_bvdup() prototype +include/sysexits-compat.h - new file, in case we ever need it + +libraries/libavl/* - new library; used in sldapd +libraries/liblber/decode.c - new 'o' feature for ber_scanf() + - new ber_bvdup() routine + - Borland C fixes +libraries/liblber/encode.c - Borland C fixes +libraries/liblber/io.c - ensure that write size <= 64K under VMS + - use ber_wptr to restart partial writes + - added LBER_TO_FILE/FILE_ONLY option support +libraries/libldap/abandon.c - use correct message id in abandon requests +libraries/libldap/cache.c - use time() in a more portable manner +libraries/libldap/cldap.c - retry correct number of times (off by one) +libraries/libldap/error.c - define empty ldap_perror if NO_USERINTERFACE +libraries/libldap/getdn.c - ldap_dn2ufn() now returns dn if no '=' + - ldap_explode_dn handles DNs without '=' +libraries/libldap/open.c - "host" can now be a space-separated list +libraries/libldap/sort.c - make function declarations more portable +libraries/libldap/srchpref.c - fixed memory leak in options parsing +libraries/libldap/test.c - added -t & -T options for ber output to file + - added 'E' command to explode a DN +libraries/libldap/tmplout.c - added entry2html() + - added entry2html_search() + - added entry2vals() + - remove extraneous ber_free when not using tmpl + - fix non-ASCII core dump bugs +libraries/libldap/ldapfriendly - added EE & RU +libraries/libldap/ldapfilter.conf + - remove '\' inside [] in reg exprs. + - add web500gw to filter tags + - added xax500-auth section +libraries/libldap/ldapsearchprefs.conf + - changed xax500 tags +libraries/libldap/ldaptemplates.conf + - added co to Country template + - add missing types & options to comments + - add "Last Modified" attrs. to all templates + - make "Last Modified" attrs. read-only +libraries/libldbm/* - new library; used in sldapd +libraries/liblthread/* - new library; used in sldapd +libraries/msdos/README.WSA - updated to include Borland C instructions +libraries/vms/README.VMS - fixed pathname typo + +servers/ldapd/add.c - make BER tags unsigned long everywhere +servers/ldapd/certificate.c - make parsing consistent with printing code +servers/ldapd/main.c - moved openlog() after detach() call +servers/ldapd/modify.c - correct tag usage in ber_first/next loop + - output all debugging to stderr + - pass and use Sockbuf * in modify_result() call +servers/ldapd/result.c - change to always use DER encoding +servers/ldapd/search.c - change to always use DER encoding +servers/ldapd/syntax.c - add support for telexNumber +servers/sldapd - all new "standalone LDAP server" + + + +---------------------------------------------------------------------------- +Changes since 3.1b8 + +Make-common - added note r.e. -DNO_USERINTERFACE +servers/ldapd/association.c - don't include filio.h under AIX +build/platforms/aix-cc and -gcc - add _BSD to defines +include/portable.h - define OPENLOG_OPTIONS +clients/*/*.c - use OPENLOG_OPTIONS +servers/ldapd/main.c - use OPENLOG_OPTIONS +servers/ldapd/syntax.c - add iattr support (from craig watkins) + +---------------------------------------------------------------------------- +Changes since 3.1b7 + +Many System V portability fixes.... +A few fixes for VMS.... + +Makefile - support Linux & NetBSD +Make-common - add support for NEXOR version of isode + - add ISODEBASELIBS + +include/Make-template - make ldapconfig.h depend on Makefile +include/ldapconfig.h.edit - add RCPT500_LISTLIMIT, RCPT500_UFN + - add GO500_TIMEOUT, GO500_UFN + - add FINGER_UFN, FINGER_TIMEOUT, + - add GO500GW_UFN + - change *_DEREF to be LDAP_DEREF_FINDING +include/regex.h - use NEED_BSDREGEX +include/portable.h - SYSV changes & general re-vamping +include/disptmpl.h - fix typo in ldap_name2template() prototype + - add LDAP_SYN_RFC822ADDR + +libraries/liblber/io.c - make ber_alloc actually use BER + +libraries/libldap/cldap.c - preserve old log DN if NULL is passed +libraries/libldap/regex.c - use NEED_BSDREGEX +libraries/libldap/disptmpl.c - add support for LDAP_SYN_RFC822ADDR +libraries/libldap/tmplout.c - add support for LDAP_SYN_RFC822ADDR +libraries/libldap/getfilter.c - always #include "regex.h" + +servers/ldapd/main.c - don't check openlog return code +servers/ldapd/request.c - only do syslog if dosyslog is set +servers/ldapd/syntax.c - add support for user certificates (from ER) +servers/ldapd/certificate.c - add support for user certificates (new file) + +clients/finger/main.c - add -t disptmplfile option + - add -p port option + - add ufn support + +clients/gopher/go500.c - add -t disptmplfile option + - add ufn support + +clients/gopher/go500gw.c - add -t disptmplfile option + - add ufn support + +clients/mail500/main.c - add -t disptmplfile option + - add support for mail to -owner + +clients/rcpt500/main.c,query.c - add support for RCPT500_LISTLIMIT + - support -p ldapport option + - add ufn support + +clients/tools/ldapsearch.c - recognize -w option properly +clients/tools/ldapdelete.c - recognize -k option properly +clients/tools/ldapmodrdn.c - new program + +clients/ud/edit.c - use execlp() instead of execle() +clients/ud/main.c - include sys/ioctl.h under NetBSD +clients/ud/print.c - updated time2text() from libldap/tmplout.c + +contrib/saucer - new contributed client from Eric Rosenquist + +build/platforms - added netbsd-cc & netbsd-gcc + - updated sunos5-cc and sunos5-gcc + - added missing CC=gcc in hpux-gcc + - added vms +build/Make-append - change ISODELIBS + +doc/man/man8/rcpt500.8 - new manual page +doc/man/man3/ldap.3 - add (3) to routine names in INDEX section +doc/man/man3/ldap_search.3 - remove reference to ldap_parse(3) +doc/man/man3/ldap_modrdn.3 - new manual page +doc/man/man3/ldap_modrdn.3.links- new links file +doc/man/man3/ldap_disptmpl.3 - re-word ldap_octemplate description + - document LDAP_SYN_RFC822ADDR +doc/man/man5/ldap_searchprefs.5 - fix formatting +doc/man/man5/ldaptemplatesconf.5- document "mail" syntax type +doc/man/* - use ETCDIR everywhere (was %ETCDIR%) + + + +------- +ldap-3.1b7 CHANGES file - summary of major changes to each component +since the last release + +source tree - completely reorganized for your convenience + - makes full use of ansi-style prototypes + - supports non-ansi compilers through unproto utility + +configuration - all client configuration has been moved to ldapconfig.h.edit + (no need to edit multiple source code files) + +build procedure - completely revamped for your convenience + - automaticly figures out your platform/compiler + - supports multiple objects from a single source tree + +liblbdap - added support for display templates + - added support for search preferences + - added ldap_sort routines for sorting entries + - rearranged some routines/source files to allow + better incremental linking to reduce code bloat + - added support for CLDAP + +liblber - added O option to ber_scanf: allocate octet string w/length + - big tags (greater than 31) now supported + - distinguished encoding rules supported (runtime choice + between ber and der) + +in.xfingerd - now uses display template routines + - now uses ldap sorting routines + - editable configuration info moved to ldapconfig.h.edit + +go500 - now uses display template routines + - now uses ldap sorting routines + - editable configuration info moved to ldapconfig.h.edit + +go500gw - now uses display template routines + - now uses ldap sorting routines + - editable configuration info moved to ldapconfig.h.edit + +rcpt500 - now uses display template routines + - now uses ldap sorting routines + - editable configuration info moved to ldapconfig.h.edit + +mail500 - addition of a new "vacation" feature + - editable configuration info moved to ldapconfig.h.edit + +ldap tools - new addition of some shell-based tools + +whois++ g/w - moved to contrib/ directory + +web500 - new addition, in contrib/ directory + +ldapd - lots of bug fixes + - bring CLDAP code in line with latest Internet Draft + +documentation - library man pages have been completely re-done, split + into separate manuals, with new pages for each set of + routines. + - new man pages for most client programs (more on the way) + +windows ldap - support for Win32 (unfinished?) + - added VERSIONINFO resource to dll + - check for > 64K response packet and don't crash + +macintosh ldap - support Apple's new Universal Header files diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 0000000000..ea961e7c24 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,9 @@ +Copyright (c) 1992-1996 Regents of the University of Michigan. +All rights reserved. + +Redistribution and use in source and binary forms are permitted +provided that this notice is preserved and that due credit is given +to the University of Michigan at Ann Arbor. The name of the University +may not be used to endorse or promote products derived from this +software without specific prior written permission. This software +is provided ``as is'' without express or implied warranty. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000000..958d72e704 --- /dev/null +++ b/INSTALL @@ -0,0 +1,136 @@ +Making and Installing the U-M LDAP Distribution + +** It is recommended that you read or at least skim through ALL of the +** instructions in this file before attempting to build the software. + +If you want to build binaries for more than one platform from a single +source tree, skip ahead to the "Building LDAP For More Than One Platform" +section near the end of this file. If you are planning to run slapd, +you should read the "SLAPD and SLURPD Administrator's Guide", found in +the doc/guides/ directory within the distribution. + +If you simply want to build LDAP for a single machine platform, follow +these steps: + + 1. untar the distribution and cd to the top: + + % zcat ldap-3.3.tar.Z | tar xf - + % cd ldap-3.3 + + If you are reading this file, you probably have already done this! + + + 2. edit the files Make-common and include/ldapconfig.h.edit to configure + the software for your site (the files are well-commented): + + % vi Make-common + % vi include/ldapconfig.h.edit + + Note that you should NOT need to edit the Makefile located at the + top of the distribution. + + If you just want to see if things will build, you can leave the + configuration alone and change it later. + + If you have the ISODE package built and want to build the + LDAP-to-X.500 server (ldapd), be sure to uncomment the appropriate + lines near the end of the Make-common file. By default only the + stand-alone server, LDAP libraries and client software are built. + + 3. make the software: + + % make + + If all goes well, then make will figure out what platform you are on, + pick a compiler to use, construct Makefiles, and build everything. + If you see a message like "unknown platform..." LDAP has probably not + been set up to build on your machine. See the file build/PORTS for + hints on what to do in that case. + + Note that if your make does not use the Bourne (sh) shell by + default when executing internal scripts (reportedly the case on SGI + machines at least), you will need to run the make explicitly from + within a Bourne shell. If you a syntax error such as "Missing ]" + when you do the make under your usual shell, try this: + + % sh + $ make + + If you don't like the some of the platform-specific options chosen + by the automatic build process (such as the compiler to use, etc), + you can intervene and edit them before anything is actually compiled + by explicitly doing a "make platform" step, editing the .make-platform + file (actually a link to the file to be edited), and then doing a + regular make: + + % make platform + % vi .make-platform + % make + + If you want to choose the build platform yourself from among those that + the distribution supports, cd to the appropriate directory underneath + build/platforms and make from there. For example, if you are on a + machine running SunOS 4.1.4 and you want to force the use of the cc + compiler, you would do this: + + % cd build/platforms/sunos4-cc + % make + + If you want to run some simple tests after the build is complete, you + can do this: + + % make test + + 4. install the binaries and man pages. You may need to be superuser to + do this (depending on where you are installing things): + + % su + # make install + + That's it! See the man pages for the individual clients for information + on configuring and using them. Eventually you will probably want to + edit the configuration files used by the various clients (installed in + the LDAP etc directory). The files are: + + ldapfilter.conf - search filter configuration + ldapfriendly - mapping of X.500 names to human-friendly names + ldapsearchprefs.conf - search object definitions + ldaptemplates.conf - display template definitions + + There are section 5 man pages for all of these files. + + +Building LDAP For More Than One Platform + +It is now possible to build LDAP for more than one platform from the same +source tree. This is accomplished by some rules in the Makefiles that +create a shadow (linked) directory tree where the binaries are placed. + +Follow these steps for each different platform: + + 1. move to the directory that matches the platform and compiler you + want to build for and type make. The directories are all located + underneath the build/platforms directory. If your platform is not + there, you may need to do a port - see the build/PORTS file for + more information. For a Sun running SunOS 4.1.4, you might do + this: + + % cd build/platforms/sunos4-cc + % make links + + This will create a linked source area. + + + 2. move to the new directory and make as for a single platform. Follow steps + 1-4 above to accomplish this. For example: + + % cd obj-sunos4-cc + % make + + That's all there is to it. You can also create the linked source area(s) + by just typing "make links" at the top of the distribution, in which case + the Makefile will try to automatically determine the platform and + compiler. + + +End of LDAP INSTALL file. diff --git a/Make-common b/Make-common new file mode 100644 index 0000000000..32683c7652 --- /dev/null +++ b/Make-common @@ -0,0 +1,200 @@ +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# LDAP common Make defines (included in all but top-level Makefile) +# +#----------------------------------------------------------------------------- + +############################################################################# +## Edit the following variables to have appropriate values for your system ## +############################################################################# + +############################################################################# +## LDAP install paths ## +############################################################################# +# +# by default, everything is installed below INSTROOT +# servers, config files, etc. are put in ETCDIR +# include files get put in INCLUDEDIR +# libraries are put in LIBDIR +# man pages are put under MANDIR +# programs end-users will run are put in BINDIR +# +INSTROOT=/usr/local +ETCDIR= $(INSTROOT)/etc +INCLUDEDIR= $(INSTROOT)/include +LIBDIR= $(INSTROOT)/lib +MANDIR= $(INSTROOT)/man +BINDIR= $(INSTROOT)/bin +# +# if you want things to run in a different directory from where they +# are installed, set this accordingly (this path gets compiled into a +# few binaries). otherwise, leave it alone. +RUNTIMEETCDIR= $(ETCDIR) + +############################################################################# +## General compiler options ## +############################################################################# +# Passed to every compile (cc or gcc). This is where you put -O or -g, etc. +#EXTRACFLAGS=-g +# Passed to every link (ld). Include -g here if you did in EXTRACFLAGS. +#EXTRALDFLAGS=-g + +############################################################################# +## If you are NOT using Kerberos authentication, you can skip this section.## +############################################################################# +# +# Otherwise, to enable kerberos authentication, uncomment KERBEROS (and +# AFSKERBEROS if you are running the AFS version of kerberos). Also +# uncomment and change the various KRB* lines to point to where the +# kerberos libraries and include files are installed at your site. +# +#KERBEROS=-DKERBEROS +#AFSKERBEROS=-DAFSKERBEROS +#KRBINCLUDEFLAG = -I/usr/local/kerberos/include +#KRBLIBFLAG = -L/usr/local/kerberos/lib +#KRBLIBS = -lkrb -ldes + +############################################################################# +## ISODE is required ONLY to build the ldap <-> X.500 server (ldapd) ## +## If you don't want to build it, you can skip this section. ## +############################################################################# +# +# To build the ldap server, uncomment the HAVEISODE line, +# and the section describing build settings for your version of isode. +# +#HAVEISODE = yes +# If you compiled ISODE with TURBO_DISK defined, uncomment this +#ISODETURBOLIBS = -lgdbm +# uncomment these to have ldapd "pretty print" protocol elements w/debugging +#PEPSY_DUMP=-DPEPSY_DUMP +#PEPSY=/usr/local/ic/bin/pepsy +# uncommment this line to have ldapd load PP syntax handlers +# you'll also need to add -lpp to ISODEBASELIBS below +#LDAP_USE_PP=-DLDAP_USE_PP +# uncomment NO_SETPROCTITLE to have ldapd NOT change its title +#NO_SETPROCTITLE=-DNOSETPROCTITLE +# +# ISODE Consortium release build settings +# You should change the next line so that ICRELEASE matches the (integer) +# version number of whatever IC release you have, e.g. 1, 2, or 3 and +# also uncomment the next 5 lines. +#ICRELEASE=-DICRELEASE=1 +#ISODEPACKAGE=-DISODEPACKAGE=IC +#ISODEINCLUDEFLAG= -I/usr/local/ic/include/isode -I/usr/local/ic/include +#ISODELIBFLAG = -L/usr/local/ic/lib +#ISODEBASELIBS = -lisode +# +# Freely available ISODE 8.0 release build settings (uncomment the next 4 lines) +#ISODEPACKAGE=-DISODEPACKAGE +#ISODEINCLUDEFLAG= -I/usr/local/isode/include +#ISODELIBFLAG = -L/usr/local/isode/lib +#ISODEBASELIBS = -ldsap -lisode +# +# NEXOR ISODE release build settings (uncomment the next 4 lines) +#ISODEPACKAGE=-DISODEPACKAGE=XT +#ISODEINCLUDEFLAG= -I/usr/include/isode +#ISODELIBFLAG = -L/usr/local/lib -L/usr/sunlink/osi/lib +#ISODEBASELIBS = -lxtpp -lresolv -lxtdsap -lxtisode -losi + +############################################################################# +## If you don't want to run slapd, skip this section. ## +############################################################################# +# +# To build slapd (the stand-alone ldap daemon), uncomment the MAKESLAPD +# line and select the SLAPD_BACKENDS you want to use. If you enable the +# LDBM backend, also select one of the LDBM backends. +MAKESLAPD= yes +# +# remove the defines for backends you don't want to enable +SLAPD_BACKENDS= -DLDAP_LDBM -DLDAP_SHELL -DLDAP_PASSWD +# +# If you have included -DLDAP_LDBM in the SLAPD_BACKENDS line you need +# to specify which low-level database package to use. There are +# four choices: Berkeley db b-tree, Berkeley db hash, GNU dbm, or ndbm. +# +# berkeley db btree package +#LDBMBACKEND=-DLDBM_USE_DBBTREE +#LDBMINCLUDE=-I/usr/local/db/include +#LDBMLIB=-ldb +# berkeley db hash package +#LDBMBACKEND=-DLDBM_USE_DBHASH +#LDBMINCLUDE=-I/usr/local/db/include +#LDBMLIB=-ldb +# gnu dbm (gdbm) +#LDBMBACKEND=-DLDBM_USE_GDBM +#LDBMINCLUDE=-I/usr/local/gdbm/include +#LDBMLIB=-lgdbm +# standard unix ndbm +LDBMBACKEND=-DLDBM_USE_NDBM +# +# if you want to use a non-default threads package change these lines +#THREADS=-DNO_THREADS +#THREADSLIB= + +############################################################################# +## The following options are used by the xax500 client. If you haven't ## +## retrieved the xax500 source and dropped it into the "clients" ## +## directory, you can skip this section. ## +############################################################################# +# +# location of your X include files +#XINCLUDES= -I/usr/X11/include +# +# location of your X libraries +#XLIBDIRS=-L/usr/X11/lib +# +# include any extra X libraries you need here +# the following works with sunos 4 and X11R5 +#XLIBS = $(XLIBDIRS) -lXm -lXt -lX11 +# the following has been known to work with Solaris 2.4 and X11R6 +#XLIBS = $(XLIBDIRS) -lXm -lXext -lSM -lICE -lXpm -lXt -lX11 + +############################################################################# +## If you don't want to do auto-translation of character sets, skip this ## +############################################################################# +# +# Otherwise, uncomment this line and set the following options. +#STR_TRANSLATION=-DSTR_TRANSLATION +# +# remove the defines for LDAP client library T.61 character translation +# you do not need. If you use LDAP_CHARSET_8859, replace the '1' in "88591" +# with the number of the particular character set you use. E.g., use "88594" +# if you use the ISO 8859-4 chracter set. +#LIBLDAP_CHARSETS=-DLDAP_CHARSET_8859="88591" +# +# uncomment one these lines to enable automatic T.61 translation by default +#LIBLDAP_DEF_CHARSET=-DLDAP_DEFAULT_CHARSET=LDAP_CHARSET_8859 + +############################################################################# +## General options ## +############################################################################# +# uncomment this line to enable debugging code (a good idea) +LDAP_DEBUG=-DLDAP_DEBUG + +# uncomment this line to turn on a few U of Michigan specific things +#UOFM=-DUOFM + +# uncomment this line to delete a few printfs in the lber and ldap libraries. +#NO_USERINTERFACE=-DNO_USERINTERFACE + +# uncomment this line to include Connectionless LDAP support +#CLDAP=-DCLDAP + +# uncomment this line to eliminate local caching support in the libldap +#NO_CACHE=-DNO_CACHE + +# uncomment this line to enable support for LDAP referrals in libldap +LDAP_REFERRALS=-DLDAP_REFERRALS + +# uncomment this line to use soundex for approximate matches in slapd. +# the default is to use the metaphone algorithm. +#PHONETIC=-DSOUNDEX diff --git a/Make-common.um b/Make-common.um new file mode 100644 index 0000000000..6fa3121e69 --- /dev/null +++ b/Make-common.um @@ -0,0 +1,200 @@ +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# LDAP common Make defines (included in all but top-level Makefile) +# +#----------------------------------------------------------------------------- + +############################################################################# +## Edit the following variables to have appropriate values for your system ## +############################################################################# + +############################################################################# +## LDAP install paths ## +############################################################################# +# +# by default, everything is installed below INSTROOT +# servers, config files, etc. are put in ETCDIR +# include files get put in INCLUDEDIR +# libraries are put in LIBDIR +# man pages are put under MANDIR +# programs end-users will run are put in BINDIR +# +INSTROOT=/usr/local +ETCDIR= $(INSTROOT)/etc +INCLUDEDIR= $(INSTROOT)/include +LIBDIR= $(INSTROOT)/lib +MANDIR= $(INSTROOT)/man +BINDIR= $(INSTROOT)/bin +# +# if you want things to run in a different directory from where they +# are installed, set this accordingly (this path gets compiled into a +# few binaries). otherwise, leave it alone. +RUNTIMEETCDIR= $(ETCDIR) + +############################################################################# +## General compiler options ## +############################################################################# +# Passed to every compile (cc or gcc). This is where you put -O or -g, etc. +EXTRACFLAGS=-g +# Passed to every link (ld). Include -g here if you did in EXTRACFLAGS. +EXTRALDFLAGS=-g + +############################################################################# +## If you are NOT using Kerberos authentication, you can skip this section.## +############################################################################# +# +# Otherwise, to enable kerberos authentication, uncomment KERBEROS (and +# AFSKERBEROS if you are running the AFS version of kerberos). Also +# uncomment and change the various KRB* lines to point to where the +# kerberos libraries and include files are installed at your site. +# +KERBEROS=-DKERBEROS +AFSKERBEROS=-DAFSKERBEROS +KRBINCLUDEFLAG = -I/usr/local/kerberos/include +KRBLIBFLAG = -L/usr/local/kerberos/lib +KRBLIBS = -lkrb -ldes + +############################################################################# +## ISODE is required ONLY to build the ldap <-> X.500 server (ldapd) ## +## If you don't want to build it, you can skip this section. ## +############################################################################# +# +# To build the ldap server, uncomment the HAVEISODE line, +# and the section describing build settings for your version of isode. +# +HAVEISODE = yes +# If you compiled ISODE with TURBO_DISK defined, uncomment this +#ISODETURBOLIBS = -lgdbm +# uncomment these to have ldapd "pretty print" protocol elements w/debugging +PEPSY_DUMP=-DPEPSY_DUMP +PEPSY=/usr/local/ic/bin/pepsy +# uncommment this line to have ldapd load PP syntax handlers +# you'll also need to add -lpp to ISODEBASELIBS below +#LDAP_USE_PP=-DLDAP_USE_PP +# uncomment NO_SETPROCTITLE to have ldapd NOT change its title +#NO_SETPROCTITLE=-DNOSETPROCTITLE +# +# ISODE Consortium release build settings +# You should change the next line so that ICRELEASE matches the (integer) +# version number of whatever IC release you have, e.g. 1, 2, or 3 and +# also uncomment the next 5 lines. +ICRELEASE=-DICRELEASE=2 +ISODEPACKAGE=-DISODEPACKAGE=IC +ISODEINCLUDEFLAG= -I/usr/local/ic/include +ISODELIBFLAG = -L/usr/local/ic/lib +ISODEBASELIBS = -lisode +# +# Freely available ISODE 8.0 release build settings (uncomment the next 4 lines) +#ISODEPACKAGE=-DISODEPACKAGE +#ISODEINCLUDEFLAG= -I/usr/local/isode/include +#ISODELIBFLAG = -L/usr/local/isode/lib +#ISODEBASELIBS = -ldsap -lisode +# +# NEXOR ISODE release build settings (uncomment the next 4 lines) +#ISODEPACKAGE=-DISODEPACKAGE=XT +#ISODEINCLUDEFLAG= -I/usr/include/isode +#ISODELIBFLAG = -L/usr/local/lib -L/usr/sunlink/osi/lib +#ISODEBASELIBS = -lxtpp -lresolv -lxtdsap -lxtisode -losi + +############################################################################# +## If you don't want to run slapd, skip this section. ## +############################################################################# +# +# To build slapd (the stand-alone ldap daemon), uncomment the MAKESLAPD +# line and select the SLAPD_BACKENDS you want to use. If you enable the +# LDBM backend, also select one of the LDBM backends. +MAKESLAPD= yes +# +# remove the defines for backends you don't want to enable +SLAPD_BACKENDS= -DLDAP_LDBM -DLDAP_SHELL -DLDAP_PASSWD +# +# If you have included -DLDAP_LDBM in the SLAPD_BACKENDS line you need +# to specify which low-level database package to use. There are +# four choices: Berkeley db b-tree, Berkeley db hash, GNU dbm, or ndbm. +# +# berkeley db btree package +LDBMBACKEND=-DLDBM_USE_DBBTREE +LDBMINCLUDE=-I/usr/local/include +LDBMLIB=-ldb +# berkeley db hash package +#LDBMBACKEND=-DLDBM_USE_DBHASH +#LDBMINCLUDE=-I/usr/local/include +#LDBMLIB=-ldb +# gnu dbm (gdbm) +#LDBMBACKEND=-DLDBM_USE_GDBM +#LDBMINCLUDE=-I/usr/local/include +#LDBMLIB=-lgdbm +# standard unix ndbm +#LDBMBACKEND=-DLDBM_USE_NDBM +# +# if you want to use a non-default threads package change these lines +#THREADS=-DNO_THREADS +#THREADSLIB= + +############################################################################# +## The following options are used by the xax500 client. If you haven't ## +## retrieved the xax500 source and dropped it into the "clients" ## +## directory, you can skip this section. ## +############################################################################# +# +# location of your X include files +#XINCLUDES= -I/usr/local/X11/include +# +# location of your X libraries +#XLIBDIRS=-L/usr/local/X11/lib +# +# include any extra X libraries you need here +# the following works with sunos 4 and X11R5 +#XLIBS = $(XLIBDIRS) -lXm -lXt -lX11 +# the following has been known to work with Solaris 2.4 and X11R6 +#XLIBS = $(XLIBDIRS) -lXm -lXext -lSM -lICE -lXpm -lXt -lX11 + +############################################################################# +## If you don't want to do auto-translation of character sets, skip this ## +############################################################################# +# +# Otherwise, uncomment this line and set the following options. +#STR_TRANSLATION=-DSTR_TRANSLATION +# +# remove the defines for LDAP client library T.61 character translation +# you do not need. If you use LDAP_CHARSET_8859, replace the '1' in "88591" +# with the number of the particular character set you use. E.g., use "88594" +# if you use the ISO 8859-4 chracter set. +#LIBLDAP_CHARSETS=-DLDAP_CHARSET_8859="88591" +# +# uncomment one these lines to enable automatic T.61 translation by default +#LIBLDAP_DEF_CHARSET=-DLDAP_DEFAULT_CHARSET=LDAP_CHARSET_8859 + +############################################################################# +## General options ## +############################################################################# +# uncomment this line to enable debugging code (a good idea) +LDAP_DEBUG=-DLDAP_DEBUG + +# uncomment this line to turn on a few U of Michigan specific things +UOFM=-DUOFM + +# uncomment this line to delete a few printfs in the lber and ldap libraries. +#NO_USERINTERFACE=-DNO_USERINTERFACE + +# uncomment this line to include Connectionless LDAP support +CLDAP=-DCLDAP + +# uncomment this line to eliminate local caching support in the libldap +#NO_CACHE=-DNO_CACHE + +# uncomment this line to enable support for LDAP referrals in libldap +LDAP_REFERRALS=-DLDAP_REFERRALS + +# uncomment this line to use soundex for approximate matches in slapd. +# the default is to use the metaphone algorithm. +#PHONETIC=-DSOUNDEX diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..a8103f2270 --- /dev/null +++ b/Makefile @@ -0,0 +1,392 @@ +# +# You will usually NOT need to edit this file at all: instead, edit the +# Make-common file. See the LDAP INSTALL file for more information. +# +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# LDAP lightweight X.500 Directory access top level makefile +# +#----------------------------------------------------------------------------- +# +############################################################################ +# # +# Usually you will not need to edit anything in this file # +# # +############################################################################ +# +# Note that these definitions of standard Unix utilities are only used +# in this Makefile. The Make-common (and .make-platform) files have a +# similar set of definitions that are used in all the other LDAP Makefiles. +# +RM=rm -f +MV=mv -f +CP=cp +CAT=cat +PWD=pwd +TAIL=tail +CHMOD=chmod +FIND=find +SED=sed +LN=ln -s +MKDIR=mkdir +GREP=grep +DIRNAME=dirname +BASENAME=basename +TAR=tar +COMPRESS=compress +CO=co +CI=ci + + +SRCDIRS= include libraries clients servers doc +TESTDIR= tests + +# +# LDAPSRC is used by the links rule +# +LDAPSRC= .. + + +# +# rules to make the software +# + +all: makeconfig + @echo "making all" + @for i in $(SRCDIRS); do \ + echo; echo " cd $$i; $(MAKE) $(MFLAGS) all"; \ + ( cd $$i; $(MAKE) $(MFLAGS) all ); \ + done + +lib-only: makeconfig + @echo "making libraries only" + @echo " cd include; $(MAKE) $(MFLAGS) all"; \ + cd include; $(MAKE) $(MFLAGS) all + @echo " cd libraries; $(MAKE) $(MFLAGS) all"; \ + cd libraries; $(MAKE) $(MFLAGS) all + + +# +# rules to install the software +# + +install: makeconfig + @for i in $(SRCDIRS); do \ + echo; echo "cd $$i; $(MAKE) $(MFLAGS) install"; \ + ( cd $$i; $(MAKE) $(MFLAGS) install ); \ + done + +inst-lib: makeconfig + @echo "cd libraries; $(MAKE) $(MFLAGS) install" + @( cd libraries; $(MAKE) $(MFLAGS) install ) + + +# +# rules to test the LDAP software +# +test: all + @echo " cd $(TESTDIR); $(MAKE) $(MFLAGS) all"; \ + ( cd $(TESTDIR); $(MAKE) $(MFLAGS) all ); + +# +# rules to make clean +# + +clean: FORCE + @if [ -f .makefiles ]; then \ + for i in $(SRCDIRS) $(TESTDIR); do \ + echo; echo "cd $$i; $(MAKE) $(MFLAGS) clean"; \ + ( cd $$i; $(MAKE) $(MFLAGS) clean ); \ + done; \ + fi; \ + ( for d in ./obj-*; do \ + if [ $$d != "./obj-*" ]; then \ + ( echo "making clean in $$d..."; \ + cd $$d; $(MAKE) $(MFLAGS) clean; ) \ + else \ + exit 0; \ + fi; \ + done ) + +veryclean: FORCE + @echo; echo "cd build; $(MAKE) $(MFLAGS) -f Make-template veryclean"; \ + ( cd build; $(MAKE) $(MFLAGS) -f Make-template veryclean ); \ + if [ -f .makefiles ]; then \ + for i in $(SRCDIRS) $(TESTDIR); do \ + echo; echo "cd $$i; $(MAKE) $(MFLAGS) veryclean"; \ + ( cd $$i; $(MAKE) $(MFLAGS) veryclean ); \ + done; \ + echo "finding and removing Makefiles..."; \ + for i in `$(FIND) . -type d -print`; do \ + if [ -f $$i/Make-template ]; then \ + echo "removing file $$i/Makefile"; \ + $(RM) $$i/Makefile; \ + fi; \ + done; \ + echo "removing file .makefiles"; \ + $(RM) .makefiles; \ + fi; \ + ( for d in ./obj-*; do \ + if [ $$d != "./obj-*" ]; then \ + echo "removing $$d..."; $(RM) -r $$d; \ + else \ + exit 0; \ + fi; \ + done ); \ + if [ -f .make-platform ]; then \ + echo "removing link .make-platform"; \ + $(RM) .make-platform; \ + else \ + exit 0; \ + fi + + +# +# rules to make depend +# +# +depend: makeconfig + @echo "making depend everywhere"; \ + echo " cd include; $(MAKE) $(MFLAGS) all"; \ + ( cd include; $(MAKE) $(MFLAGS) all ); \ + for i in $(SRCDIRS); do \ + echo; echo "cd $$i; $(MAKE) $(MFLAGS) depend"; \ + ( cd $$i; $(MAKE) $(MFLAGS) depend ); \ + done; \ + $(MAKE) $(MFLAGS) makefiles + +# +# rules to check out and in Make-template files +# +co-mktmpls: FORCE + @echo "checking out Make-template files..."; \ + for mkfile in `$(FIND) . -name Make-template -type f -print`; do \ + $(CO) -l $$mkfile; \ + done + +ci-mktmpls: FORCE + @echo "enter a one-word log message:"; \ + read logmsg; \ + echo "checking in Make-template files..."; \ + for mkfile in `$(FIND) . -name Make-template -type f -print`; do \ + $(CI) -m$$logmsg -u $$mkfile; \ + done + + +lib-depend: makeconfig + @echo "cd libraries; $(MAKE) $(MFLAGS) depend" + @( cd libraries; $(MAKE) $(MFLAGS) depend )" + +# +# rules to cut a new ldap distribution +# +distribution: makeconfig checkin tar + +checkin: FORCE + @-VERSION=V`cat ./build/version | $(SED) -e 's/\.//'` ; \ + echo "Checking in version $$VERSION"; \ + for i in `$(FIND) . -name \*,v -print | \ + $(SED) -e 's%RCS/%%' -e 's%,v%%'`; \ + do ( \ + ci -m"pre-version $$VERSION check-in" -u $$i; \ + rcs -N$$VERSION: $$i ) \ + done + +tar: veryclean + @PWD=`pwd`; \ + $(RM) ./Make-common; \ + $(CP) ./Make-common.dist ./Make-common; \ + $(CHMOD) 644 ./Make-common; \ + $(RM) ./include/ldapconfig.h.edit; \ + $(CP) ./include/ldapconfig.h.dist ./include/ldapconfig.h.edit; \ + $(CHMOD) 644 ./include/ldapconfig.h.edit; \ + BASE=`$(BASENAME) $$PWD`; XFILE=/tmp/ldap-x.$$$$; \ + ( cd .. ; $(CAT) $$BASE/exclude >$$XFILE; \ + $(FIND) $$BASE -name RCS -print >> $$XFILE ; \ + $(FIND) $$BASE -name obj-\* -print >> $$XFILE ; \ + $(FIND) $$BASE -name tags -print >> $$XFILE ; \ + $(TAR) cvfX ./$$BASE.tar $$XFILE $$BASE; \ + ); \ + $(RM) $$XFILE; \ + echo "compressing ../$$BASE.tar..."; \ + $(COMPRESS) ../$$BASE.tar + +# +# rule to force check for change of platform +# +platform: FORCE + @if [ -f .make-platform ]; then \ + echo "removing old link .make-platform"; \ + $(RM) .make-platform; \ + fi; \ + $(MAKE) $(MFLAGS) .make-platform + + +makeconfig: .makefiles buildtools + +.make-platform: + @if [ -f /usr/bin/swconfig ]; then \ + UNAME=./build/uname.sh; \ + elif [ -f /bin/uname ]; then \ + UNAME=/bin/uname; \ + elif [ -f /usr/bin/uname ]; then \ + UNAME=/usr/bin/uname; \ + else \ + UNAME=./build/uname.sh; \ + fi; \ + if [ -z "$$UNAME" ]; then \ + echo "unknown platform (no $$UNAME or /usr/bin/uname)"; \ + echo "see the file build/PORTS for more information."; \ + exit 1; \ + else \ + OS=`$$UNAME -s` ; OSRELEASE=`$$UNAME -r` ; \ + OSVERSION=`$$UNAME -v` ; \ + case $$OS in \ + SunOS) \ + if [ $$OSRELEASE -gt "5" -o $$OSRELEASE -lt "4" ]; then \ + echo "SunOS release $$OSRELEASE unknown..."; exit 1; \ + fi; \ + if [ $$OSRELEASE -ge "5" ]; then \ + PLATFORM="sunos5"; \ + else \ + PLATFORM="sunos4"; \ + fi; \ + ;; \ + ULTRIX) \ + PLATFORM="ultrix" \ + ;; \ + OSF1) \ + PLATFORM="osf1" \ + ;; \ + AIX) \ + PLATFORM="aix" \ + ;; \ + HP-UX) \ + PLATFORM="hpux" \ + ;; \ + Linux) \ + PLATFORM="linux" \ + ;; \ + NetBSD) \ + PLATFORM="netbsd" \ + ;; \ + FreeBSD) \ + PLATFORM="freebsd" \ + ;; \ + NeXTSTEP) \ + PLATFORM="nextstep" \ + ;; \ + SCO) \ + PLATFORM="sco" \ + ;; \ + IRIX|IRIX64) \ + PLATFORM="irix" \ + ;; \ + *) echo "unknown platform ($$OS $$OSVERSION $$OSRELEASE)..."; \ + echo "see the file build/PORTS for more information."; \ + exit 1; \ + ;; \ + esac; \ + fi; \ + CC=$(CC); \ + OLDIFS="$$IFS"; \ + IFS=":"; \ + for dir in $$PATH; do \ + if [ -f $$dir/gcc ]; then \ + CC=gcc; \ + break; \ + fi; \ + done; \ + IFS="$$OLDIFS"; \ + $(LN) ./build/platforms/$$PLATFORM-$$CC/Make-platform .make-platform; \ + echo ""; \ + echo "** Set platform to $$PLATFORM with compiler $$CC..."; \ + echo "" + +# +# rule to build Makefiles by concatenating Make-template file in each +# subdirectory with global Make-common, .make-platform, and +# build/Make-append files +# +.makefiles: Make-common .make-platform build/Make-append + @echo "making Makefiles..."; \ + HDRFILE=/tmp/Makehdr.$$$$; \ + DEFSFILE=/tmp/Makedefs.$$$$; \ + $(CAT) build/Make-append ./.make-platform ./Make-common > $$DEFSFILE; \ + echo "# --------------------------------------------------------" > $$HDRFILE; \ + echo "# This file was automatically generated. Do not edit it." >> $$HDRFILE; \ + echo "# Instead, edit the Make-common file (located in the root" >> $$HDRFILE; \ + echo "# (of the LDAP distribution). See the LDAP INSTALL file" >> $$HDRFILE; \ + echo "# for more information." >> $$HDRFILE; \ + echo "# --------------------------------------------------------" >> $$HDRFILE; \ + echo "#" >> $$HDRFILE; \ + for i in `$(FIND) . -type d -print`; do \ + if [ -f $$i/Make-template ]; then \ + echo " creating $$i/Makefile"; \ + $(RM) $$i/Makefile; \ + $(CAT) $$HDRFILE $$i/Make-template $$DEFSFILE > $$i/Makefile; \ + $(CHMOD) 444 $$i/Makefile; \ + fi; \ + done; \ + $(RM) .makefiles; \ + touch .makefiles; \ + $(RM) $$HDRFILE $$DEFSFILE + +# +# rule to always build makefiles +# +makefiles: FORCE + $(RM) .makefiles + $(MAKE) $(MFLAGS) .makefiles + +# +# rule to create any tools we need to build everything else +# +buildtools: FORCE + @echo "making buildtools" + @echo " cd build; $(MAKE) $(MFLAGS)" + @( cd build; $(MAKE) $(MFLAGS) ) + +# +# rule to make a shadow (linked) build area +# +links: FORCE + @if [ -f /usr/bin/swconfig ]; then \ + UNAME=./build/uname.sh; \ + elif [ -f /bin/uname ]; then \ + UNAME=/bin/uname; \ + elif [ -f /usr/bin/uname ]; then \ + UNAME=/usr/bin/uname; \ + else \ + UNAME=./build/uname.sh; \ + fi; \ + if [ ! -z "$(DEST)" ]; then \ + DEST="$(DEST)"; \ + else \ + DEST=./obj-`$$UNAME -s`-`$$UNAME -r` ; \ + fi; \ + echo "making links in $$DEST..."; \ + LINKLIST=/tmp/ldaplinklist.$$$$; \ + $(RM) $$LINKLIST; \ + $(MKDIR) $$DEST; \ + cd $$DEST; $(LN) $(LDAPSRC) .src; \ + $(LN) .src/Makefile . ; \ + $(CP) .src/Make-common . ; $(CHMOD) 644 ./Make-common; \ + for d in build $(SRCDIRS) $(TESTDIR); do \ + ( $(MKDIR) $$d; cd $$d; $(LN) ../.src/$$d .src; \ + $(LN) .src/Make-template . ; \ + $(MAKE) $(MFLAGS) MKDIR="$(MKDIR)" LN="$(LN)" \ + -f Make-template links ) ; \ + done; \ + echo ""; echo "Now type:"; echo " cd $$DEST"; echo "and make there" + +FORCE: diff --git a/README b/README new file mode 100644 index 0000000000..fb8dd8ab36 --- /dev/null +++ b/README @@ -0,0 +1,59 @@ +UM-LDAP 3.3 README file + + This is the UM-LDAP version 3.3 distribution. For a description of + what this distribution contains, see the ANNOUNCEMENT file in this + directory. For a description of changes from previous releases, + see the CHANGES file in this directory. For a more detailed + description of how to make and install the distribution, see the + INSTALL file in this directory. For more information on making and + installing slapd, see the "SLAPD and SLURPD Administrator's Guide" + in the doc/guides/ directory. + +MAKING AND INSTALLING THE DISTRIBUTION + + You should be able to make and install the distribution with a pretty + standard default configuration by typing the following commands + + % make + % su + # make install + + in this directory. This should produce something that basically + works. + + You will probably want to do a little configuration to suit your + site, though. There are two files you might want to edit: + + Make-common This file contains definitions for + where things will be installed, where + to find various things, etc. If you + want to build an ldap server, you'll + definitely need to edit this file + + include/ldapconfig.h.edit This file contains #defines used + by many parts of the distribution. + You'll at least want to change + DEFAULT_BASE. + + See the INSTALL file in this directory for more information. + +DOCUMENTATION + + There are man pages for most programs in the distribution and + routines in the various libraries. See ldap(3) for details. + + There is a postscript version of an administrator's guide for + slapd in doc/guides/slapd.ps. + + There is an LDAP homepage available that contains the latest + LDAP news, releases announcements, pointers to other LDAP resources, + etc. You can access it at this URL: + + http://www.umich.edu/~rsug/ldap/ + +FEEDBACK / PROBLEM REPORTS + + We would appreciate any feedback you can provide. If you have + problems, report them to this address: + + ldap-support@umich.edu diff --git a/build/Make-append b/build/Make-append new file mode 100644 index 0000000000..67a2f29bb0 --- /dev/null +++ b/build/Make-append @@ -0,0 +1,78 @@ +# +# Do NOT edit this file -- it is automatically appended to all Makefiles +# except the LDAP top-level Makefile. See the LDAP INSTALL file for more +# information. +# +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# LDAP standard Make defines (appended to all but top-level Makefile) +# +#----------------------------------------------------------------------------- + +# DEFS are included in CFLAGS +DEFS = $(PLATFORMCFLAGS) $(LDAP_DEBUG) $(KERBEROS) $(AFSKERBEROS) \ + $(UOFM) $(UOFA) $(NO_USERINTERFACE) $(CLDAP) $(NO_CACHE) \ + $(LDAP_REFERRALS) $(LDAP_DNS) $(STR_TRANSLATION) \ + $(LIBLDAP_CHARSETS) $(LIBLDAP_DEF_CHARSET) \ + $(SLAPD_BACKENDS) $(LDBMBACKEND) $(LDBMINCLUDE) $(PHONETIC) + +# SERVERDEFS are added to server builds CFLAGS (in addition to DEFS) +SERVERDEFS = $(ISODEPACKAGE) $(ICRELEASE) $(LDAP_USE_PP) \ + $(NO_SETPROCTITLE) $(PEPSY_DUMP) + +# +# ISODELIBS are used in server/ldapd builds +# +ISODELIBS = $(ISODEBASELIBS) -lm $(ISODETURBOLIBS) + +# ACFLAGS are added to CFLAGS but not passed to mkdep, lint, etc +ACFLAGS = $(EXTRACFLAGS) $(UNPROTOCFLAGS) + +# ALDFLAGS are always placed near the beginning of all linker (cc -o) commands +ALDFLAGS = $(EXTRALDFLAGS) $(PLATFORMLDFLAGS) + +# ALIBS are always placed at the end of all linker (cc -o) commands +ALIBS = $(PLATFORMLIBS) + +# +# default definitions for Unix utilities (may be over-ridden in Make-platform) +CC = cc +MAKE = make +RANLIB = ranlib +AR = ar +RM = rm -f +MV = mv -f +CP = cp +CHMOD = chmod +CAT = cat +LN = ln -s +HARDLN = ln +TAIL = tail +SED = sed +LINT = lint +5LINT = lint +MKDIR = mkdir +INSTALL = install +INSTALLFLAGS = -c +BASENAME= basename +DIRNAME = dirname +MKDEP = $(LDAPSRC)/build/mkdep -s -f Make-template +PWD = pwd +DATE = date +HOSTNAME= hostname + + +# +# empty target used to force rules to be invoked +# +FORCE: + diff --git a/build/Make-template b/build/Make-template new file mode 100644 index 0000000000..28055d9f1f --- /dev/null +++ b/build/Make-template @@ -0,0 +1,38 @@ +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# LDAP buildtools makefile +# +#----------------------------------------------------------------------------- + +all: FORCE + @if [ ! -z "$(NEEDUNPROTO)" ]; then \ + cd unproto; $(MAKE) $(MFLAGS) CC=$(CC); \ + else \ + exit 0; \ + fi + +install: FORCE + +clean: + cd unproto; $(MAKE) $(MFLAGS) clean + cd platforms; $(MAKE) $(MFLAGS) clean + +veryclean: + cd unproto; $(MAKE) $(MFLAGS) clean + cd platforms; $(MAKE) $(MFLAGS) veryclean + +links: + @echo "making links in `$(PWD)`"; \ + $(LN) .src/version .src/platforms .src/Make-append .src/install.sh . ; \ + ( $(MKDIR) unproto; cd unproto; $(LN) ../.src/unproto .src; \ + $(LN) .src/Makefile .src/*.[ch] . ) + diff --git a/build/PORTS b/build/PORTS new file mode 100644 index 0000000000..b51ba12a1d --- /dev/null +++ b/build/PORTS @@ -0,0 +1,98 @@ +This file gives some helpful hints for building LDAP on various machines. + +LDAP has been built and tested on the following platforms. It will +probably build fine under similar versions of the OS (e.g. it has +been built and tested under SunOS 4.1.4, but probably builds fine +under all SunOS 4.1.x systems). + +If you port LDAP to a new platform, let us know so we can add it here. +See the end of this file for some hints on doing a port. The following +tables give some indication of the level of support there is for various +platforms where the LDAP release has been built. Key: + + X - all pieces are known to build and work + B - all pieces build and are believed to work + S - some pieces build and work + O - an older LDAP release has been ported here; current status unknown + ? - unknown + - - does not build and/or work at all + +** Unix and Unix-like platforms: + + OS Version libraries clients ldapd slapd slurpd + ---------- --------- ------- ----- ----- ------ + AIX 3.2.5 X X B B -(1) + + HP-UX 9.05 X X ? B -(1) + + Linux 1.3.76 X X O X -(1) + + FreeBSD 2.0.5 X X ? B ? + + NETBSD 0.9a O O ? ? ? + + NeXTSTEP 3.2 O O ? ? ? + + SunOS 4.1.4 X X X X X + + SunOS 5.5 X X B X X + (Solaris 2.5) + + Ultrix 4.3 X X B B ? + + OSF/1 3.2 X X X X ? + + IRIX 5.x/6.x B B ? B ? + + NCR MP-RAS 2.3 X X ? ? ? + +(1) - required threads support not provided by vendor + +** Non-Unix Platforms: + + OS Version libraries clients ldapd slapd slurpd + ---------- --------- ------- ----- ----- ------ + MacOS 7.5 X - - - - + (see the file libraries/macintosh/README for build instructions) + + MSDOS O S - - - + (see the file libraries/msdos/README for build instructions) + + MS-Windows 3.x O - - - - + (see the file libraries/msdos/README.WSA for build instructions) + + MS-Win NT & 95 O ? ? ? ? + + VMS X S X X ? + (see the file libraries/vms/README.VMS for build instructions) + + +** Hints on Porting LDAP to a New Platform + +If your platform is not listed here, you will need to do a port. The +place to start for Unix systems is by creating a new directory under +the LDAP build/platforms directory and creating an appropriate +Make-platform file. It is probably easiest to start by duplicating a +directory there that is for a platform similar to yours. + +Variables commonly set in the Make-platform files include: + +CC - compiler to use, e.g. CC=cc or CC=gcc +PLATFORMCFLAGS - flags added to every compile +PLATFORMLDFLAGS - flags added to every link +PLATFORMLIBS - extra libraries needed (added to the end of all link commands) +LDBMLIB - ndbm library, needed if not in libc (e.g. LDBMLIB=-lndbm) +NEEDUNPROTO=yes - set if your compiler doesn't understand prototypes; see the + sunos4-cc and hpux-cc files for example usage +INSTALL - BSD-like install command; if necessary, you can use a script + we provide: INSTALL=$(LDAPSRC)/build/install.sh +RANLIB - command to convert libraries for efficient random access; + if your system has no ranlib, use RANLIB = "" +other commands - see the file build/Make-append for a list + +You will also need to modify the top-level LDAP Makefile .make-platform +rule to know about your platform. Finally, you should look through the +include/portable.h file and make any necessary adjustments. + +Please send changes via e-mail to: ldap-support@umich.edu so they can be +incorporated into future releases. diff --git a/build/README-unproto b/build/README-unproto new file mode 100644 index 0000000000..05def5e9ca --- /dev/null +++ b/build/README-unproto @@ -0,0 +1,3 @@ +The unproto code was obtained from: + + ftp://ftp.win.tue.nl/pub/unix/unproto5.shar.Z diff --git a/build/db.1.85.patch b/build/db.1.85.patch new file mode 100644 index 0000000000..b6e227b273 --- /dev/null +++ b/build/db.1.85.patch @@ -0,0 +1,158 @@ +*** ./hash/hash.h.bak Fri May 12 11:00:42 1995 +--- ./hash/hash.h Fri May 12 11:01:07 1995 +*************** +*** 103,109 **** + BUFHEAD *cpage; /* Current page */ + int cbucket; /* Current bucket */ + int cndx; /* Index of next item on cpage */ +! int errno; /* Error Number -- for DBM + * compatability */ + int new_file; /* Indicates if fd is backing store + * or no */ +--- 103,109 ---- + BUFHEAD *cpage; /* Current page */ + int cbucket; /* Current bucket */ + int cndx; /* Index of next item on cpage */ +! int h_errno; /* Error Number -- for DBM + * compatability */ + int new_file; /* Indicates if fd is backing store + * or no */ +*** ./hash/hash.c.bak Fri May 12 11:02:03 1995 +--- ./hash/hash.c Fri May 12 11:02:42 1995 +*************** +*** 505,511 **** + else + if (wsize != sizeof(HASHHDR)) { + errno = EFTYPE; +! hashp->errno = errno; + return (-1); + } + for (i = 0; i < NCACHED; i++) +--- 505,511 ---- + else + if (wsize != sizeof(HASHHDR)) { + errno = EFTYPE; +! hashp->h_errno = errno; + return (-1); + } + for (i = 0; i < NCACHED; i++) +*************** +*** 536,542 **** + + hashp = (HTAB *)dbp->internal; + if (flag) { +! hashp->errno = errno = EINVAL; + return (ERROR); + } + return (hash_access(hashp, HASH_GET, (DBT *)key, data)); +--- 536,542 ---- + + hashp = (HTAB *)dbp->internal; + if (flag) { +! hashp->h_errno = errno = EINVAL; + return (ERROR); + } + return (hash_access(hashp, HASH_GET, (DBT *)key, data)); +*************** +*** 553,563 **** + + hashp = (HTAB *)dbp->internal; + if (flag && flag != R_NOOVERWRITE) { +! hashp->errno = errno = EINVAL; + return (ERROR); + } + if ((hashp->flags & O_ACCMODE) == O_RDONLY) { +! hashp->errno = errno = EPERM; + return (ERROR); + } + return (hash_access(hashp, flag == R_NOOVERWRITE ? +--- 553,563 ---- + + hashp = (HTAB *)dbp->internal; + if (flag && flag != R_NOOVERWRITE) { +! hashp->h_errno = errno = EINVAL; + return (ERROR); + } + if ((hashp->flags & O_ACCMODE) == O_RDONLY) { +! hashp->h_errno = errno = EPERM; + return (ERROR); + } + return (hash_access(hashp, flag == R_NOOVERWRITE ? +*************** +*** 574,584 **** + + hashp = (HTAB *)dbp->internal; + if (flag && flag != R_CURSOR) { +! hashp->errno = errno = EINVAL; + return (ERROR); + } + if ((hashp->flags & O_ACCMODE) == O_RDONLY) { +! hashp->errno = errno = EPERM; + return (ERROR); + } + return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL)); +--- 574,584 ---- + + hashp = (HTAB *)dbp->internal; + if (flag && flag != R_CURSOR) { +! hashp->h_errno = errno = EINVAL; + return (ERROR); + } + if ((hashp->flags & O_ACCMODE) == O_RDONLY) { +! hashp->h_errno = errno = EPERM; + return (ERROR); + } + return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL)); +*************** +*** 729,735 **** + + hashp = (HTAB *)dbp->internal; + if (flag && flag != R_FIRST && flag != R_NEXT) { +! hashp->errno = errno = EINVAL; + return (ERROR); + } + #ifdef HASH_STATISTICS +--- 729,735 ---- + + hashp = (HTAB *)dbp->internal; + if (flag && flag != R_FIRST && flag != R_NEXT) { +! hashp->h_errno = errno = EINVAL; + return (ERROR); + } + #ifdef HASH_STATISTICS +*** ./hash/ndbm.c.bak Fri May 12 11:02:06 1995 +--- ./hash/ndbm.c Fri May 12 11:02:54 1995 +*************** +*** 180,186 **** + HTAB *hp; + + hp = (HTAB *)db->internal; +! return (hp->errno); + } + + extern int +--- 180,186 ---- + HTAB *hp; + + hp = (HTAB *)db->internal; +! return (hp->h_errno); + } + + extern int +*************** +*** 190,196 **** + HTAB *hp; + + hp = (HTAB *)db->internal; +! hp->errno = 0; + return (0); + } + +--- 190,196 ---- + HTAB *hp; + + hp = (HTAB *)db->internal; +! hp->h_errno = 0; + return (0); + } + diff --git a/build/install.sh b/build/install.sh new file mode 100755 index 0000000000..b9ac07f89a --- /dev/null +++ b/build/install.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# simple BSD-like install replacement +# +# Copyright (c) 1994 The Regents of the University of Michigan +# + +MODE=0755 +USAGE="usage: $0 [-c] [-m mode] file dir" + +while [ $# != 0 ]; do + case "$1" in + -c) + ;; + -m) + MODE=$2 + shift + ;; + -*) + echo "$USAGE" + exit 1 + ;; + *) + break + ;; + esac + shift +done + +if [ $# != 2 ]; then + echo "$USAGE" + exit 1 +fi + +FILE=$1 +DIR=$2 + +cp $FILE $DIR +if [ -d $DIR ]; then + chmod $MODE $DIR/`basename $FILE` +else +# +# DIR is really the destination file +# + chmod $MODE $DIR +fi diff --git a/build/mkdep b/build/mkdep new file mode 100755 index 0000000000..006f05abbc --- /dev/null +++ b/build/mkdep @@ -0,0 +1,133 @@ +#!/bin/sh - +# +# Copyright (c) 1987 Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that the above copyright notice and this paragraph are +# duplicated in all such forms and that any documentation, +# advertising materials, and other materials related to such +# distribution and use acknowledge that the software was developed +# by the University of California, Berkeley. The name of the +# University may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +# +# @(#)mkdep.sh 5.12 (Berkeley) 6/30/88 +# +# We now use whatever path is already set by the invoker +#PATH=/bin:/usr/bin:/usr/ucb +#export PATH + +set -e # exit immediately if any errors occur + +MAKE=Makefile # default makefile name is "Makefile" +NOSLASH="no" # by default, / dependencies are included +CC=cc # default compiler is cc + +while : + do case "$1" in + # -f allows you to select a makefile name + -f) + MAKE=$2 + shift; shift ;; + + # -c allows you to select a compiler to use (default is cc) + -c) + CC=$2 + shift; shift ;; + + # the -p flag produces "program: program.c" style dependencies + # so .o's don't get produced + -p) + SED='s;\.o;;' + shift ;; + + # the -s flag removes dependencies to files that begin with / + -s) + NOSLASH=yes; + shift ;; + +# -*) shift ;; + + *) + break ;; + esac +done + +if [ $# = 0 ] ; then + echo 'usage: mkdep [-p] [-f makefile] [flags] file ...' + exit 1 +fi + +if [ ! -w $MAKE ]; then + echo "mkdep: no writeable file \"$MAKE\"" + exit 1 +fi + +TMP=/tmp/mkdep$$ + +trap 'rm -f $TMP ; exit 1' 1 2 3 13 15 + +cp $MAKE ${MAKE}.bak + +sed -e '/DO NOT DELETE THIS LINE/,$d' < $MAKE > $TMP + +cat << _EOF_ >> $TMP +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +_EOF_ + +# If your compiler doesn't have -M, add it. If you can't, the next two +# lines will try and replace the "cc -M". The real problem is that this +# hack can't deal with anything that requires a search path, and doesn't +# even try for anything using bracket (<>) syntax. +# +# egrep '^#include[ ]*".*"' /dev/null $* | +# sed -e 's/:[^"]*"\([^"]*\)".*/: \1/' -e 's/\.c/.o/' | + +$CC -M $* | +sed " + s; \./; ;g + $SED" | +awk ' +$1 ~ /:/ { + filenm=$1 + dep=$2 +} +$1 !~ /:/ { + dep=$1 +} +/.*/ { + if ( noslash = "yes" && dep ~ /^\// ) next + if (filenm != prev) { + if (rec != "") + print rec; + rec = filenm " " dep; + prev = filenm; + } + else { + if (length(rec dep) > 78) { + print rec; + rec = filenm " " dep; + } + else + rec = rec " " dep + } + } +END { + print rec +}' noslash="$NOSLASH" >> $TMP + +cat << _EOF_ >> $TMP + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY +_EOF_ + +# copy to preserve permissions +cp $TMP $MAKE +rm -f ${MAKE}.bak $TMP +exit 0 diff --git a/build/platforms/Make-setup b/build/platforms/Make-setup new file mode 100644 index 0000000000..9e0991908e --- /dev/null +++ b/build/platforms/Make-setup @@ -0,0 +1,68 @@ +# +# You should NOT need to edit this file at all: if you just type make +# in this directory, LDAP will be built for this platform using this +# compiler. If you type make links a build area will be created for +# you under ./obj. You should # cd in there and edit the Make-common file +# before building. See the LDAP INSTALL file for more information. +# +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# LDAP lightweight X.500 Directory access platform setup makefile +# +#----------------------------------------------------------------------------- +# +############################################################################ +# # +# You should not have to edit anything in this file # +# # +############################################################################ +LN=ln -s +RM=rm -f +SED=sed +PWD=pwd + +LDAPSRC= ../../.. + +all: platform + ( cd $(LDAPSRC); $(MAKE) $(MFLAGS) ) + +install: platform + ( cd $(LDAPSRC); $(MAKE) $(MFLAGS) install ) + +platform: FORCE + @PWD=`$(PWD)`; \ + PLATFORMCC=`basename $$PWD`; \ + PLATFORM=`echo $$PLATFORMCC | $(SED) 's/-.*$$//'`; \ + CC=`echo $$PLATFORMCC | $(SED) 's/^.*-//'`; \ + echo "** Setting platform to $$PLATFORM and compiler $$CC"; \ + ( cd $(LDAPSRC); \ + $(RM) .make-platform; \ + $(LN) build/platforms/$$PLATFORMCC/Make-platform .make-platform ) + +links: FORCE + @PWD=`$(PWD)`; \ + PLATFORMCC=`basename $$PWD`; \ + DEST=./obj-$$PLATFORMCC; \ + PLATFORM=`echo $$PLATFORMCC | $(SED) 's/-.*$$//'`; \ + CC=`echo $$PLATFORMCC | $(SED) 's/^.*-//'`; \ + echo "** Setting platform to $$PLATFORM and compiler $$CC"; \ + ( cd $(LDAPSRC); $(MAKE) $(MFLAGS) DEST=$$DEST links; \ + cd $$DEST; \ + $(LN) .src/build/platforms/$$PLATFORMCC/Make-platform .make-platform ); \ + $(LN) $(LDAPSRC)/$$DEST . + +clean: FORCE + +veryclean: + -$(RM) -r ./obj-* + +FORCE: diff --git a/build/platforms/Makefile b/build/platforms/Makefile new file mode 100644 index 0000000000..38f3194d63 --- /dev/null +++ b/build/platforms/Makefile @@ -0,0 +1,46 @@ +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# LDAP build/platforms Makefile +# +#----------------------------------------------------------------------------- + +############################################################################ +# # +# You should not have to edit anything below this point # +# # +############################################################################ + +all: FORCE + + +install: FORCE + +clean: FORCE + @echo "making clean in `pwd`" + @for i in *; do \ + if [ -d $$i -a $$i != "RCS" ]; then \ + echo; echo " cd $$i; $(MAKE) $(MFLAGS) clean"; \ + ( cd $$i; $(MAKE) $(MFLAGS) clean ); \ + fi; \ + done + +veryclean: FORCE + @echo "making veryclean in `pwd`" + @for i in *; do \ + if [ -d $$i -a $$i != "RCS" ]; then \ + echo; echo " cd $$i; $(MAKE) $(MFLAGS) veryclean"; \ + ( cd $$i; $(MAKE) $(MFLAGS) veryclean ); \ + fi; \ + done + +FORCE: + diff --git a/build/platforms/aix-cc/Make-platform b/build/platforms/aix-cc/Make-platform new file mode 100644 index 0000000000..cb2e2fd0ba --- /dev/null +++ b/build/platforms/aix-cc/Make-platform @@ -0,0 +1,18 @@ +# +# LDAP AIX standard cc Make-platform file +# + + +# +# add any platform-specific overrides below here +# + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- + +# install with BSD semantics +INSTALL=/usr/ucb/install + +PLATFORMCFLAGS= -Daix diff --git a/build/platforms/aix-gcc/Make-platform b/build/platforms/aix-gcc/Make-platform new file mode 100644 index 0000000000..29a7774e25 --- /dev/null +++ b/build/platforms/aix-gcc/Make-platform @@ -0,0 +1,19 @@ +# +# LDAP AIX standard cc Make-platform file +# + + +# +# add any platform-specific overrides below here +# + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +CC = gcc + +# install with BSD commandline +INSTALL=/usr/ucb/install + +PLATFORMCFLAGS= -Daix diff --git a/build/platforms/freebsd-gcc/Make-platform b/build/platforms/freebsd-gcc/Make-platform new file mode 100644 index 0000000000..895b32f2af --- /dev/null +++ b/build/platforms/freebsd-gcc/Make-platform @@ -0,0 +1,16 @@ +# +# LDAP FreeBSD GNU C Make-platform file +# + + +# +# add any platform-specific overrides below here +# + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +CC = gcc + +PLATFORMCFLAGS= -Dfreebsd diff --git a/build/platforms/hpux-c89/Make-platform b/build/platforms/hpux-c89/Make-platform new file mode 100644 index 0000000000..f3d502e59b --- /dev/null +++ b/build/platforms/hpux-c89/Make-platform @@ -0,0 +1,27 @@ +# +# HP-UX optional c89 Make-platform file +# + +# +# add any platform-specific overrides below here +# + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +CC=c89 + +# ranlib not needed under HP-UX +RANLIB = "" + +# install under HP-UX is not like on BSD systems, so we use our own script +INSTALL=$(LDAPSRC)/build/install.sh + +# we need to link a separate library to get ndbm routines under HP/UX +LDBMLIB=-lndbm + +# we need to link in the V3 library to get sigset() +PLATFORMLIBS= -lV3 + +PLATFORMCFLAGS= -Dhpux -Aa -D_HPUX_SOURCE diff --git a/build/platforms/hpux-cc/Make-platform b/build/platforms/hpux-cc/Make-platform new file mode 100644 index 0000000000..3c813670ef --- /dev/null +++ b/build/platforms/hpux-cc/Make-platform @@ -0,0 +1,33 @@ +# +# LDAP HP-UX standard cc Make-platform file +# + +# +# add any platform-specific overrides below here +# + + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +# ranlib not needed under HP-UX +RANLIB = "" + +# install under HP-UX is not like on BSD systems, so we use our own script +INSTALL=$(LDAPSRC)/build/install.sh + +# we need to link a separate library to get ndbm routines under HP/UX +LDBMLIB=-lndbm + +PLATFORMCFLAGS= -Dhpux + +# we need to link in the V3 library to get sigset() +PLATFORMLIBS= -lV3 + +# +# the HP-UX cc compiler doesn't understand function prototypes, so we +# need the unproto preprocessor +# +NEEDUNPROTO=yes +UNPROTOCFLAGS=-tp,$(LDAPSRC)/build/unproto/cpp diff --git a/build/platforms/hpux-gcc/Make-platform b/build/platforms/hpux-gcc/Make-platform new file mode 100644 index 0000000000..2c3d77d7f8 --- /dev/null +++ b/build/platforms/hpux-gcc/Make-platform @@ -0,0 +1,28 @@ +# +# LDAP HP-UX gcc Make-platform file +# + +# +# add any platform-specific overrides below here +# + + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +CC=gcc + +# ranlib not needed under HP-UX +RANLIB = "" + +# install under HP-UX is not like on BSD systems, so we use our own script +INSTALL=$(LDAPSRC)/build/install.sh + +# we need to link a separate library to get ndbm routines under HP/UX +LDBMLIB=-lndbm + +# we need to link in the V3 library to get sigset() +PLATFORMLIBS= -lV3 + +PLATFORMCFLAGS= -Dhpux diff --git a/build/platforms/irix-cc/Make-platform b/build/platforms/irix-cc/Make-platform new file mode 100644 index 0000000000..c4b195515b --- /dev/null +++ b/build/platforms/irix-cc/Make-platform @@ -0,0 +1,29 @@ +# +# LDAP IRIX standard cc Make-platform file +# + +# +# add any platform-specific overrides below here +# + + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +# ranlib not needed under IRIX +RANLIB = "" + +# be explicit about which CC to use +CC=cc + +# give full path to hostname since it may not be in user's path +HOSTNAME=/usr/bsd/hostname + +# don't count on a BSD install being present or first in path +INSTALL=$(LDAPSRC)/build/install.sh + +PLATFORMCFLAGS=-DUSE_WAITPID +PLATFORMLIBS= +THREADS= +THREADSLIB= diff --git a/build/platforms/irix-gcc/Make-platform b/build/platforms/irix-gcc/Make-platform new file mode 100644 index 0000000000..96f698d132 --- /dev/null +++ b/build/platforms/irix-gcc/Make-platform @@ -0,0 +1,29 @@ +# +# LDAP IRIX standard cc Make-platform file +# + +# +# add any platform-specific overrides below here +# + + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +# ranlib not needed under IRIX +RANLIB = "" + +# be explicit about which CC to use +CC=gcc + +# give full path to hostname since it may not be in user's path +HOSTNAME=/usr/bsd/hostname + +# don't count on a BSD install being present or first in path +INSTALL=$(LDAPSRC)/build/install.sh + +PLATFORMCFLAGS=-DUSE_WAITPID +PLATFORMLIBS= +THREADS= +THREADSLIB= diff --git a/build/platforms/linux-gcc/Make-platform b/build/platforms/linux-gcc/Make-platform new file mode 100644 index 0000000000..45f3823921 --- /dev/null +++ b/build/platforms/linux-gcc/Make-platform @@ -0,0 +1,17 @@ +# +# LDAP Linux GNU C Make-platform file +# + +# +# add any platform-specific overrides below here +# + + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +CC = gcc +RANLIB = "ranlib" + +PLATFORMCFLAGS= -Dlinux diff --git a/build/platforms/ncr-mp-ras-2-cc/Make-platform b/build/platforms/ncr-mp-ras-2-cc/Make-platform new file mode 100644 index 0000000000..ce98b2c0b4 --- /dev/null +++ b/build/platforms/ncr-mp-ras-2-cc/Make-platform @@ -0,0 +1,34 @@ +# +# LDAP SVR4 standard cc Make-platform file +# +# Uses the std SVR4 stuff whenever possible. +# Some references to the BSD compatibility required. +# + +# +# add any platform-specific overrides below here +# + +# compiler to use, e.g. CC=cc or CC=gcc +CC = cc + +# flags added to every compile +# Use the BSD include files but only after the SVR4 files. +PLATFORMCFLAGS= -DSYSV -DSVR4 -I/usr/include -I/usr/ucbinclude + +# flags added to every link +PLATFORMLDFLAGS = + +# extra libraries needed (added to the end of all link commands) +PLATFORMLIBS = -lnsl -lnet -lsocket + +# ndbm library, needed if not in libc (e.g. LDBMLIB=-lndbm) +LDBMLIB = -L/usr/ucblib -lucb + +# BSD-like install command; if necessary, you can use a script +INSTALL = /usr/ucb/install + +# command to convert libraries for efficient random access; +RANLIB = "" + +# other commands - see the file build/Make-append for a list diff --git a/build/platforms/netbsd-cc/Make-platform b/build/platforms/netbsd-cc/Make-platform new file mode 100644 index 0000000000..e176e6d6a3 --- /dev/null +++ b/build/platforms/netbsd-cc/Make-platform @@ -0,0 +1,17 @@ +# +# LDAP NetBSD cc Make-platform file +# on NetBSD, cc is gcc +# + + +# +# add any platform-specific overrides below here +# + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +CC = gcc + +PLATFORMCFLAGS= -Dnetbsd diff --git a/build/platforms/netbsd-gcc/Make-platform b/build/platforms/netbsd-gcc/Make-platform new file mode 100644 index 0000000000..b66f8304f6 --- /dev/null +++ b/build/platforms/netbsd-gcc/Make-platform @@ -0,0 +1,16 @@ +# +# LDAP NetBSD GNU C Make-platform file +# + + +# +# add any platform-specific overrides below here +# + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +CC = gcc + +PLATFORMCFLAGS= -Dnetbsd diff --git a/build/platforms/nextstep-cc/Make-platform b/build/platforms/nextstep-cc/Make-platform new file mode 100644 index 0000000000..1105e6c493 --- /dev/null +++ b/build/platforms/nextstep-cc/Make-platform @@ -0,0 +1,15 @@ +# +# LDAP NeXTSTEP cc Make-platform file +# + + +# +# add any platform-specific overrides below here +# + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +PLATFORMCFLAGS= -Dnextstep +PLATFORMLDFLAGS= -all_load diff --git a/build/platforms/osf1-cc/Make-platform b/build/platforms/osf1-cc/Make-platform new file mode 100644 index 0000000000..2fd6b205c3 --- /dev/null +++ b/build/platforms/osf1-cc/Make-platform @@ -0,0 +1,24 @@ +# +# LDAP OSF1 standard cc Make-platform file +# + +# +# add any platform-specific overrides below here +# + + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- + +# Even though prototypes are supported by the compiler, OSF's CC doesn't +# seem to define __STDC__ so we explicitly defined NEEDPROTOS here. +PLATFORMCFLAGS= -Dosf1 -DNEEDPROTOS +PLATFORMLDFLAGS= + +THREADS= -DTHREAD_DCE_PTHREADS +THREADSLIB= -lpthreads + +# the BSD-like install under OSF/1 is called installbsd +INSTALL=installbsd diff --git a/build/platforms/sco-cc/Make-platform b/build/platforms/sco-cc/Make-platform new file mode 100644 index 0000000000..31ff05d498 --- /dev/null +++ b/build/platforms/sco-cc/Make-platform @@ -0,0 +1,23 @@ +# +# LDAP SCO standard cc Make-platform file +# + +# +# add any platform-specific overrides below here +# + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +# ranlib not needed under SCO +RANLIB = "" + +# be explicit about which CC to use +CC=/bin/cc + +# don't count on /usr/ucb/install being present or first in path +INSTALL=$(LDAPSRC)/build/install.sh + +PLATFORMCFLAGS= -DSCO -DNEED_BSDREGEX -DSYSV -DNOTERMCAP +PLATFORMLIBS= -lsocket -lnsl_s diff --git a/build/platforms/sco-gcc/Make-platform b/build/platforms/sco-gcc/Make-platform new file mode 100644 index 0000000000..1abaa79e00 --- /dev/null +++ b/build/platforms/sco-gcc/Make-platform @@ -0,0 +1,22 @@ +# +# LDAP SCO gcc Make-platform file +# + +# +# add any platform-specific overrides below here +# + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +# ranlib not needed under SCO +RANLIB = "" + +CC=gcc + +# don't count on /usr/ucb/install being present or first in path +INSTALL=$(LDAPSRC)/build/install.sh + +PLATFORMCFLAGS= -DSCO -DNEED_BSDREGEX -DSYSV -DNOTERMCAP +PLATFORMLIBS= -lsocket -lnsl_s diff --git a/build/platforms/sunos4-cc/Make-platform b/build/platforms/sunos4-cc/Make-platform new file mode 100644 index 0000000000..6f94bd4808 --- /dev/null +++ b/build/platforms/sunos4-cc/Make-platform @@ -0,0 +1,25 @@ +# +# LDAP SunOS standard cc Make-platform file +# + +# +# add any platform-specific overrides below here +# + + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +5LINT = /usr/5bin/lint + +PLATFORMCFLAGS= -Dsunos4 +THREADS= -DTHREAD_SUNOS4_LWP +THREADSLIB=-llwp + +# +# the SunOS 4 cc compiler doesn't understand function prototypes, so we +# need the unproto preprocessor +# +NEEDUNPROTO=yes +UNPROTOCFLAGS=-Qpath $(LDAPSRC)/build/unproto diff --git a/build/platforms/sunos4-gcc/Make-platform b/build/platforms/sunos4-gcc/Make-platform new file mode 100644 index 0000000000..81c97f93c8 --- /dev/null +++ b/build/platforms/sunos4-gcc/Make-platform @@ -0,0 +1,19 @@ +# +# LDAP SunOS GNU C Make-platform file +# + + +# +# add any platform-specific overrides below here +# + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +CC = gcc +5LINT = /usr/5bin/lint + +PLATFORMCFLAGS= -Dsunos4 +THREADS= -DTHREAD_SUNOS4_LWP +THREADSLIB=-llwp diff --git a/build/platforms/sunos5-cc/Make-platform b/build/platforms/sunos5-cc/Make-platform new file mode 100644 index 0000000000..beaad9fe91 --- /dev/null +++ b/build/platforms/sunos5-cc/Make-platform @@ -0,0 +1,29 @@ +# +# LDAP SunOS5 standard cc Make-platform file +# + +# +# add any platform-specific overrides below here +# + + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +# ranlib not needed under SunOS5 +RANLIB = "" + +# be explicit about which CC to use +CC=cc + +# give full path to hostname since it may not be in user's path +HOSTNAME=/usr/ucb/hostname + +# don't count on /usr/ucb/install being present or first in path +INSTALL=$(LDAPSRC)/build/install.sh + +PLATFORMCFLAGS= -Dsunos5 -D_REENTRANT +PLATFORMLIBS= -lsocket -lnsl -lgen +THREADS= -DTHREAD_SUNOS5_LWP +THREADSLIB=-lthread diff --git a/build/platforms/sunos5-gcc/Make-platform b/build/platforms/sunos5-gcc/Make-platform new file mode 100644 index 0000000000..20c5e4756b --- /dev/null +++ b/build/platforms/sunos5-gcc/Make-platform @@ -0,0 +1,28 @@ +# +# LDAP SunOS5 GNU C Make-platform file +# + +# +# add any platform-specific overrides below here +# + + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- +CC = gcc + +# ranlib not needed under SunOS5 +RANLIB = "" + +# give full path to hostname since it may not be in user's path +HOSTNAME=/usr/ucb/hostname + +# don't count on /usr/ucb/install being present or first in path +INSTALL=$(LDAPSRC)/build/install.sh + +PLATFORMCFLAGS= -Dsunos5 -D_REENTRANT +PLATFORMLIBS= -lsocket -lnsl -lgen +THREADS= -DTHREAD_SUNOS5_LWP +THREADSLIB=-lthread diff --git a/build/platforms/ultrix-cc/Make-platform b/build/platforms/ultrix-cc/Make-platform new file mode 100644 index 0000000000..8139f5f848 --- /dev/null +++ b/build/platforms/ultrix-cc/Make-platform @@ -0,0 +1,16 @@ +# +# LDAP Ultrix standard cc Make-platform file +# + +# +# add any platform-specific overrides below here +# + + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- + +PLATFORMCFLAGS= -Dultrix -YSYSTEM_FIVE +PLATFORMLDFLAGS= -YSYSTEM_FIVE diff --git a/build/platforms/ultrix-gcc/Make-platform b/build/platforms/ultrix-gcc/Make-platform new file mode 100644 index 0000000000..976e069a62 --- /dev/null +++ b/build/platforms/ultrix-gcc/Make-platform @@ -0,0 +1,16 @@ +# +# LDAP Ultrix standard gcc Make-platform file +# + +# +# add any platform-specific overrides below here +# + + +# +# ------------------------------------------------------------------------- +# you will probably not need to edit anything below this point +# ------------------------------------------------------------------------- + +CC= gcc +PLATFORMCFLAGS= -Dultrix diff --git a/build/platforms/vms/Makefile b/build/platforms/vms/Makefile new file mode 100644 index 0000000000..65467d23d9 --- /dev/null +++ b/build/platforms/vms/Makefile @@ -0,0 +1,31 @@ +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# LDAP build/platforms/vms Makefile (do nothing) +# +#----------------------------------------------------------------------------- +# +############################################################################ +# # +# You should not have to edit anything in this file # +# # +############################################################################ +LDAPSRC= ../../.. + +all: FORCE + +links: FORCE + +clean: FORCE + +veryclean: FORCE + +FORCE: diff --git a/build/platforms/vms/make.com b/build/platforms/vms/make.com new file mode 100644 index 0000000000..01fe3265a4 --- /dev/null +++ b/build/platforms/vms/make.com @@ -0,0 +1,95 @@ +$! 30-Nov-1995 ldap V3.2 Craig Watkins Innosoft International, Inc. +$! +$! This is a crude make procedure to build the ldap libraries and the test +$! program. This should work with DECC or VAXC compilers. +$! +$! This links with UCX libraries so that it should work on any TCP/IP +$! package that has UCX emulation. This has been tested with MultiNet. +$! You may have to change the LINK to find your copy of UCX$IPC.OLB. +$! +$ ARCH = "VAX" +$ if f$getsyi("hw_model") .GE. 1024 then ARCH = "ALPHA" +$ ! +$ ! If we are on an alpha/axp, we need to use DECC -- otherwise, your choice +$ COMPILER = "VAXC" +$ if ARCH .eqs. "ALPHA" then COMPILER = "DECC" +$ ! +$ if COMPILER .eqs. "VAXC" +$ then +$ define arpa sys$library: +$ define sys sys$library: +$ define netinet sys$library: +$! This assumes your default compiler is VAXC; if not, add /VAXC below +$ cc_switches = "/include=([---.include],[---.libraries.vms])/define=(LDAP_DEBUG,CLDAP,LDAP_REFERRALS,STR_TRANSLATION,LDAP_CHARSET_8859=88591)" +$! +$ else +$! +$ cc_switches = "/decc/standard=vaxc/include=([---.include],[---.libraries.vms])/define=(__STDC__,LDAP_DEBUG,CLDAP,LDAP_REFERRALS,STR_TRANSLATION,LDAP_CHARSET_8859=88591) +$ endif +$ ! +$ cc 'CC_SWITCHES' 'P1' [---.libraries.liblber]io +$ cc 'CC_SWITCHES' 'P1' [---.libraries.liblber]encode +$ cc 'CC_SWITCHES' 'P1' [---.libraries.liblber]decode +$ cc 'CC_SWITCHES' 'P1' [---.libraries.liblber]version +$ ! +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]ABANDON +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]ADD +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]ADDENTRY +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]BIND +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]CACHE +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]CHARSET +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]CLDAP +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]COMPARE +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]DELETE +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]DISPTMPL +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]DSPARSE +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]ERROR +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]FREE +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]FRIENDLY +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]GETATTR +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]GETDN +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]GETDXBYNAME +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]GETENTRY +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]GETFILTER +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]GETVALUES +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]KBIND +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]MODIFY +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]MODRDN +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]OPEN +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]OS-IP +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]REGEX +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]REQUEST +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]RESULT +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]SBIND +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]SEARCH +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]SORT +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]SRCHPREF +$ cc 'CC_SWITCHES' 'P1' /define="TEMPLATEFILE=""LDAP_ETC:ldaptemplates.conf""" - + [---.libraries.libldap]TMPLOUT +$!CC 'CC_SWITCHES' 'P1' [---.libraries.libldap]TMPLTEST +$ cc 'CC_SWITCHES' 'P1' /define="FILTERFILE=""LDAP_ETC:ldapfilter.conf""" - + [---.libraries.libldap]UFN +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]UNBIND +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]VERSION +$ ! +$ cc 'CC_SWITCHES' 'P1' [---.libraries.vms]getopt +$ cc 'CC_SWITCHES' 'P1' [---.libraries.vms]strings +$ ! +$ library/create/log ldap.olb *.obj +$ ! +$ cc 'CC_SWITCHES' 'P1' [---.libraries.libldap]TEST +$ ! +$ if COMPILER .eqs. "VAXC" +$ then +$! +$ link test, sys$input/opt +ldap.olb/lib +sys$library:ucx$ipc.olb/lib +sys$share:vaxcrtl.exe/share +$! +$ else +$! +$ link test, sys$input/opt +ldap.olb/lib +$ endif +$! diff --git a/build/uname.sh b/build/uname.sh new file mode 100644 index 0000000000..fbb58ddd5c --- /dev/null +++ b/build/uname.sh @@ -0,0 +1,109 @@ +#!/bin/sh +# simple BSD-like uname replacement for those systems without it +# +# Copyright (c) 1995 The Regents of the University of Michigan +# + + +# +# if /bin/uname or /usr/bin/uname exists, just use it +# ...unless we are on SCO, where the provided uname is bad +# +if [ ! -f /usr/bin/swconfig ]; then + if [ -f /bin/uname ]; then + exec /bin/uname $* + fi + + if [ -f /usr/bin/uname ]; then + exec /usr/bin/uname $* + fi +fi + + +# +# flags to keep track of what to output +# +PRINT_SYSTEM=0 +PRINT_VERSION=0 +PRINT_RELEASE=0 + +# +# process arguments +# +USAGE="usage: $0 [-s] [-v] [-r]" + +while [ $# != 0 ]; do + case "$1" in + -s) + PRINT_SYSTEM=1 + ;; + -v) + PRINT_VERSION=1 + ;; + -r) + PRINT_RELEASE=1 + ;; + *) + echo "$USAGE" + exit 1 + ;; + esac + shift +done + + +# +# print system name by default +# +if [ $PRINT_VERSION = "0" -a $PRINT_RELEASE = "0" ]; then + PRINT_SYSTEM=1 +fi + + +# +# default to unknown everything... +# +SYSTEM="Unknown-System" +VERSION="Unknown-Version" +RELEASE="Unknown-Release" + +# +# check to see if we are on a machine that runs NextSTEP or SCO +# +if [ -r /NextApps ]; then + SYSTEM="NeXTSTEP" +elif [ -f /usr/bin/swconfig ]; then + SYSTEM="SCO" +fi + + +# +# output requested information +# +OUTPUT=0 +if [ $PRINT_SYSTEM = "1" ]; then + echo -n "$SYSTEM" + OUTPUT=1 +fi + +if [ $PRINT_VERSION = "1" ]; then + if [ $OUTPUT = "1" ]; then + echo -n " $VERSION" + else + echo -n "$VERSION" + OUTPUT=1 + fi +fi + +if [ $PRINT_RELEASE = "1" ]; then + if [ $OUTPUT = "1" ]; then + echo -n " $RELEASE" + else + echo -n "$RELEASE" + OUTPUT=1 + fi +fi + +echo + +exit 0 diff --git a/build/unproto/Makefile b/build/unproto/Makefile new file mode 100644 index 0000000000..2d7a98c7da --- /dev/null +++ b/build/unproto/Makefile @@ -0,0 +1,123 @@ +# @(#) Makefile 1.6 93/06/18 22:29:40 + +## BEGIN CONFIGURATION STUFF + +# In the unlikely case that your compiler has no hooks for alternate +# compiler passes, use a "cc cflags -E file.c | unproto >file.i" +# pipeline, then "cc cflags -c file.i" to compile the resulting +# intermediate file. +# +# Otherwise, the "/lib/cpp | unproto" pipeline can be packaged as an +# executable shell script (see the provided "cpp.sh" script) that should +# be installed as "/whatever/cpp". This script should then be specified +# to the C compiler as a non-default preprocessor. +# +# PROG = unproto +# PIPE = + +# The overhead and problems of shell script interpretation can be +# eliminated by having the unprototyper program itself open the pipe to +# the preprocessor. In that case, define the PIPE_THROUGH_CPP macro as +# the path name of the default C preprocessor (usually "/lib/cpp"), +# install the unprototyper as "/whatever/cpp" and specify that to the C +# compiler as a non-default preprocessor. +# +PROG = cpp +PIPE = -DPIPE_THROUGH_CPP=\"/lib/cpp\" + +# Some compilers complain about some #directives. The following is only a +# partial solution, because the directives are still seen by /lib/cpp. +# Be careful with filtering out #pragma, because some pre-ANSI compilers +# (SunOS) rely on its use. +# +# SKIP = -DIGNORE_DIRECTIVES=\"pragma\",\"foo\",\"bar\" +# +SKIP = + +# The bell character code depends on the character set. With ASCII, it is +# 7. Specify a string constant with exactly three octal digits. If you +# change this definition, you will have to update the example.out file. +# +BELL = -DBELL=\"007\" + +# Some C compilers have problems with "void". The nature of the problems +# depends on the age of the compiler. +# +# If your compiler does not understand "void" at all, compile with +# -DMAP_VOID. The unprototyper will replace "void *" by "char *", a +# (void) argument list by an empty one, and will replace all other +# instances of "void" by "int". +# +# If your compiler has problems with "void *" only, compile with +# -DMAP_VOID_STAR. The unprototyper will replace "void *" by "char *", +# and will replace a (void) argument list by an empty one. All other +# instances of "void" will be left alone. +# +# If neither of these are defined, (void) argument lists will be replaced +# by empty ones. +# +# MAP = -DMAP_VOID_STAR + +# Now that we have brought up the subject of antique C compilers, here's +# a couple of aliases that may be useful, too. +# +# ALIAS = -Dstrchr=index + +# If you need support for functions that implement ANSI-style variable +# length argument lists, edit the stdarg.h file provided with this +# package so that it contains the proper definitions for your machine. + +## END CONFIGURATION STUFF + +SHELL = /bin/sh + +CFILES = unproto.c tok_io.c tok_class.c tok_pool.c vstring.c symbol.c error.c \ + hash.c strsave.c +HFILES = error.h token.h vstring.h symbol.h +SCRIPTS = cpp.sh acc.sh +SAMPLES = stdarg.h stddef.h stdlib.h varargs.c example.c example.out +SOURCES = README $(CFILES) $(HFILES) Makefile $(SCRIPTS) $(SAMPLES) +FILES = $(SOURCES) unproto.1 +OBJECTS = tok_io.o tok_class.o tok_pool.o unproto.o vstring.o symbol.o error.o \ + hash.o strsave.o + +CFLAGS = -O $(PIPE) $(SKIP) $(BELL) $(MAP) $(ALIAS) +#CFLAGS = -O $(PIPE) $(SKIP) $(BELL) $(MAP) $(ALIAS) -p -Dstatic= +#CFLAGS = -g $(PIPE) $(SKIP) $(BELL) $(MAP) $(ALIAS) -DDEBUG + +$(PROG): $(OBJECTS) + $(CC) $(CFLAGS) -o $@ $(OBJECTS) $(MALLOC) + +# For linting, enable all bells and whistles. + +lint: + lint -DPIPE_THROUGH_CPP=\"foo\" -DIGNORE_DIRECTIVES=\"foo\",\"bar\" \ + $(BELL) -DMAP_VOID $(ALIAS) $(CFILES) + +# Testing requires that the program is compiled with -DDEBUG. + +test: $(PROG) cpp example.c example.out + ./cpp example.c >example.tmp + @echo the following diff command should produce no output + diff -b example.out example.tmp + rm -f example.tmp + +shar: $(FILES) + @shar $(FILES) + +archive: + $(ARCHIVE) $(SOURCES) + +clean: + rm -f *.o core cpp unproto mon.out varargs.o varargs example.tmp + +error.o : error.c token.h error.h Makefile +hash.o : hash.c Makefile +strsave.o : strsave.c error.h Makefile +symbol.o : symbol.c error.h token.h symbol.h Makefile +tok_class.o : tok_class.c error.h vstring.h token.h symbol.h Makefile +tok_io.o : tok_io.c token.h vstring.h error.h Makefile +tok_pool.o : tok_pool.c token.h vstring.h error.h Makefile +unproto.o : unproto.c vstring.h stdarg.h token.h error.h symbol.h Makefile +varargs.o : varargs.c stdarg.h Makefile +vstring.o : vstring.c vstring.h Makefile diff --git a/build/unproto/README b/build/unproto/README new file mode 100644 index 0000000000..10748743ec --- /dev/null +++ b/build/unproto/README @@ -0,0 +1,160 @@ +@(#) README 1.6 93/06/18 22:29:34 + +unproto - Compile ANSI C with traditional UNIX C compiler + +Description: +------------ + +This is a filter that sits in between the UNIX C preprocessor and the +next UNIX C compiler stage, on the fly transforming ANSI C syntax to +old C syntax. Line number information is preserved so that compiler +diagnostics still make sense. It runs at roughly the same speed as +/lib/cpp, so it has negligible impact on compilation time. + +Typically, the program is invoked by the native UNIX C compiler as an +alternate preprocessor. The unprototyper in turn invokes the native C +preprocessor and massages its output. Similar tricks can be used with +the lint(1) command. Details are given below. + +The filter rewrites ANSI-style function headings, function pointer +types and type casts, function prototypes, and combinations thereof. +Unlike some other unprototypers, this one is fully recursive and does +not depend on source file layout (see the example.c file). + +Besides the rewriting of argument lists, the program does the following +transformations: string concatenation, conversion of \a and \x escape +sequences to their octal equivalents, translation of the __TIME__ and +__DATE__ macros, optional mapping of `void *' to `char *', and optional +mapping of plain `void' to `int'. + +The unprototyper provides hooks for compilers that require special +tricks for variadic functions (fortunately, many don't). +support is provided for sparc, mips, mc68k, 80x86, vax, and others. + +The program has been tested with SunOS 4.1.1 (sparc), Ultrix 4.0 and +4.2 (mips), and Microport System V Release 2 (80286). It should work +with almost every PCC-based UNIX C compiler. + +Restrictions: +------------- + +A description of restrictions and workarounds can be found in the +unproto.1 manual page. + +Problems fixed with this release: +--------------------------------- + +Prototypes and definitions of functions returning pointer to function +were not rewritten to old style. + +Operation: +---------- + +This package implements a non-default C preprocessor (the output from +the default C preprocessor being piped through the unprototyper). How +one tells the C compiler to use a non-default preprocessor program is +somewhat compiler-dependent: + + SunOS 4.x: cc -Qpath directory_with_alternate_cpp ... + + Ultrix 4.x: cc -tp -hdirectory_with_alternate_cpp -B ... + + System V.2: cc -Bdirectory_with_alternate_cpp/ -tp ... + +Examples of these, and others, can be found in the acc.sh shell script +that emulates an ANSI C compiler. Your C compiler manual page should +provide the necessary information. + +A more portable, but less efficient, approach relies on the observation +that almost every UNIX C compiler supports the -E (write preprocessor +output to stdout) and -P options (preprocess file.c into file.i). Just +add the following lines to your Makefiles: + + .c.o: + $(CC) $(CFLAGS) -E $*.c | unproto >$*.i # simulate -P option + $(CC) $(CFLAGS) -c $*.i + rm -f $*.i + +On some systems the lint(1) command is just a shell script, and writing +a version that uses the unprototyper should not be too hard. With SunOS +4.x, /usr/bin/lint is not a shell script, but it does accept the same +syntax as the cc(1) command for the specification of a non-default +compiler pass. + +You may have to do some research on the lint command provided with your +own machine. + +Configuration: +-------------- + +Check the contents of the `stdarg.h' file provided with this package. +This file serves a dual purpose: (1) on systems that do not provide a +stdarg.h file, it should be included by C source files that implements +ANSI-style variadic functions; (2) it is also used to configure the +unprototyper so that it emits the proper magic when it sees `...'. + +The `stdarg.h' file has support for sparc, mips, and for compilers that +pass arguments via the stack (typical for 80*86, mc68k and vax). It +gives general hints for other compilers. + +The other sample header files (stddef.h and stdlib.h) are not required +to build the unprototyper. + +The `varargs.c' file provided with this package can be used to verify +that the `stdarg.h' file has been set up correctly. + +If your C compiler has no hooks for an alternate preprocessor (the +unprototyper will be used as: `cc cflags -E file.c | unproto >file.i'), +build the `unproto' executable without the `PIPE_THROUGH_CPP' feature. +Details are given in the Makefile. + +Otherwise, the `cpp.sh' shell script can be used to set up the pipe +between the native C preprocessor and the unprototyper command. The +script assumes that the unprototyper binary is called `unproto', and +that it was compiled without the `PIPE_THROUGH_CPP' feature. See the +Makefile and the `cpp.sh' script for details and for a description of +possible problems with this approach. + +The overhead and problems of shell-script interpretation can be avoided +by letting the unprototyper itself pipe its standard input through the +C preprocessor. For this mode of operation, the unprototyper binary +should be called `cpp', and the `unproto.c' source file should be +compiled with the `PIPE_THROUGH_CPP' macro defined as the absolute +pathname of the native C preprocessor (usually `/lib/cpp'). See the +Makefile for details. + +Installation: +------------- + +Install the `unproto.1' manual page in a suitable place. If your system +does not provide a `stdarg.h' file, find a suitable place for the one +provided with the unprototyper and install it there. The same goes for +the sample stddef.h and stdlib.h files; make sure that the definitions +in there apply to your environment. Most or all of the latter files are +already part of Ultrix 4.x and SunOS 4.1.1. + +The ANSI float.h and limits.h files can be generated with the config +program by Steve Pemberton (comp.sources.misc volume 10, issue 62, +available from ftp.uu.net as comp.sources.misc/volume10/config42.Z). + +If you run the unprototyper with "cc -E" just install the `unproto' +binary; the `cpp' and `acc' shell scripts will not be needed. + +If you use the `cpp' shell script to pipe the preprocessor output +through the unprototyper program, install the `unproto' binary in a +place where the `cpp' shell script can find it, and install the `cpp' +shell script in a suitable place. Edit the `acc' shell script and +install it in a suitable place. From now on, type `acc' instead of +`cc'. + +If the unprototyper itself opens the pipe to the C preprocessor (i.e. +the unprototyper was built with the `PIPE_THROUGH_CPP' macro defined), +install the `cpp' unprototyper binary in a suitable place. Edit the +`acc' shell script and install it in a suitable place. From now on, +type `acc' instead of `cc'. + + Wietse Venema + wietse@wzv.win.tue.nl + Mathematics and Computing Science + Eindhoven University of Technology + The Netherlands diff --git a/build/unproto/acc.sh b/build/unproto/acc.sh new file mode 100755 index 0000000000..124e700d01 --- /dev/null +++ b/build/unproto/acc.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +# @(#) acc.sh 1.1 93/06/18 22:29:42 +# +# Script to emulate most of an ANSI C compiler with a traditional UNIX +# C compiler. + +# INCDIR should be the directory with auxiliary include files from the +# unproto source distribution (stdarg.h, stdlib.h, stddef.h, and other +# stuff that is missing from your compilation environment). With Ultrix +# 4.[0-2] you need unproto's stdarg.h even though the system provides +# one. +# +INCDIR=. + +# CPPDIR should be the directory with the unprototypeing cpp filter +# (preferably the version with the PIPE_THROUGH_CPP feature). +# +CPPDIR=. + +# DEFINES: you will want to define volatile and const, and maybe even +# __STDC__. +# +DEFINES="-Dvolatile= -Dconst= -D__STDC__" + +# Possible problem: INCDIR should be listed after the user-specified -I +# command-line options, not before them as we do here. This is a problem +# only if you attempt to redefine system libraries. +# +# Choose one of the commands below that is appropriate for your system. +# +exec cc -Qpath ${CPPDIR} -I${INCDIR} ${DEFINES} "$@" # SunOS 4.x +exec cc -tp -h${CPPDIR} -B -I${INCDIR} ${DEFINES} "$@" # Ultrix 4.2 +exec cc -Yp,${CPPDIR} -I${INCDIR} ${DEFINES} "$@" # M88 SysV.3 +exec cc -B${CPPDIR}/ -tp -I${INCDIR} ${DEFINES} "$@" # System V.2 diff --git a/build/unproto/cpp.sh b/build/unproto/cpp.sh new file mode 100755 index 0000000000..a0391461ea --- /dev/null +++ b/build/unproto/cpp.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +# @(#) cpp.sh 1.3 92/01/15 21:53:22 + +# Unprototypeing preprocessor for pre-ANSI C compilers. On some systems, +# this script can be as simple as: +# +# /lib/cpp "$@" | unproto +# +# However, some cc(1) drivers specify output file names on the +# preprocessor command line, so this shell script must be prepared to +# intercept them. Depending on the driver program, the cpp options may +# even go before or after the file name argument(s). The script below +# tries to tackle all these cases. +# +# You may want to add -Ipath_to_stdarg.h_file, -Dvoid=, -Dvolatile=, +# and even -D__STDC__. + +cpp_args="" + +while : +do + case $1 in + "") break;; + -*) cpp_args="$cpp_args $1";; + *) cpp_args="$cpp_args $1" + case $2 in + ""|-*) ;; + *) exec 1> $2 || exit 1; shift;; + esac;; + esac + shift +done + +/lib/cpp $cpp_args | unproto diff --git a/build/unproto/error.c b/build/unproto/error.c new file mode 100644 index 0000000000..667d978cbb --- /dev/null +++ b/build/unproto/error.c @@ -0,0 +1,97 @@ +/*++ +/* NAME +/* error 3 +/* SUMMARY +/* diagnostics +/* PACKAGE +/* unproto +/* SYNOPSIS +/* #include "error.h" +/* +/* int errcount; +/* +/* void error(text) +/* char *text; +/* +/* void error_where(path, line, text) +/* char *path; +/* int line; +/* char *text; +/* +/* void fatal(text) +/* char *text; +/* DESCRIPTION +/* The routines in this file print a diagnostic (text). Some also +/* terminate the program. Upon each error*() call, the errcount variable +/* is incremented. +/* +/* error() provides a default context, i.e. the source-file +/* coordinate of the last read token. +/* +/* error_where() allows the caller to explicitly specify context: path +/* is a source-file name, and line is a line number. +/* +/* fatal() is like error() but terminates the program with a non-zero +/* exit status. +/* +/* context is ignored if the line number is zero or if the path +/* is an empty string. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 92/01/15 21:53:10 +/* VERSION/RELEASE +/* 1.2 +/*--*/ + +static char error_sccsid[] = "@(#) error.c 1.2 92/01/15 21:53:10"; + +/* C library */ + +#include + +extern void exit(); + +/* Application-specific stuff */ + +#include "token.h" +#include "error.h" + +int errcount = 0; /* error counter */ + +/* error - report problem (implicit context) */ + +void error(text) +char *text; +{ + error_where(in_path, in_line, text); +} + +/* error_where - report problem (explicit context) */ + +void error_where(path, line, text) +char *path; +int line; +char *text; +{ + errcount++; + + /* Suppress context info if there is none. */ + + if (line && path[0]) + fprintf(stderr, "%s, line %d: ", path, line); + + fprintf(stderr, "%s\n", text); +} + +/* fatal - report problem and terminate unsuccessfully */ + +void fatal(text) +char *text; +{ + error(text); + exit(1); +} diff --git a/build/unproto/error.h b/build/unproto/error.h new file mode 100644 index 0000000000..dfb27e9067 --- /dev/null +++ b/build/unproto/error.h @@ -0,0 +1,6 @@ +/* @(#) error.h 1.2 92/01/15 21:53:14 */ + +extern int errcount; /* error counter */ +extern void error(); /* default context */ +extern void error_where(); /* user-specified context */ +extern void fatal(); /* fatal error */ diff --git a/build/unproto/example.c b/build/unproto/example.c new file mode 100644 index 0000000000..bf2f838f2a --- /dev/null +++ b/build/unproto/example.c @@ -0,0 +1,222 @@ + /* + * @(#) example.c 1.5 93/06/18 22:29:46 + * + * Examples of things that can be done with the unproto package + */ + +typedef char *charstar; + + /* + * New-style argument list with structured argument, one field being pointer + * to function returning pointer to function with function-pointer argument + */ + +x(struct { + struct { + int (*(*foo) (int (*arg1) (double))) (float arg2); + } foo; +} baz) { + return (0); +} + + /* New-style function-pointer declaration. */ + +int (*(*bar0) (float)) (int); + + /* Old-style argument list with new-style argument type. */ + +baz0(bar) +int (*(*bar) (float)) (int); +{} + + /* + * New-style argument list with new-style argument type, declaration + * embedded within block. Plus a couple assignments with function calls that + * look like casts. + */ + +foo(int (*(*bar) (float)) (int)) +{ + int (*baz) (int) = (int (*) (int)) 0, + y = (y * (*baz) (y)), + *(*z) (int) = (int *(*) (int)) 0; + + struct { int (*foo)(int); } *(*s)(int) = + (struct { int (*foo)(int); } *(*)(int)) 0; + + { + y = (y * (*baz) (y)); + } + { + z = (int *(*) (int)) 0; + } + { + s = (struct { int (*foo)(int); } *(*)(int)) 0; + } + + return (0); +} + +/* Multiple declarations in one statement */ + +test1() +{ + int foo2,*(*(*bar)(int))(float),*baz(double); +} + +/* Discriminate declarations from executable statements */ + +test2(charstar y) +{ + int foo = 5,atoi(charstar); + + foo = 5,atoi(y); +} + +/* Declarations without explicit type */ + +test3,test4(int); + +test5(int y) +{ + { + test3; + } + { + test4(y); + } +} + +test6[1],test7(int); + +test7(int x) +{ + { + test6[1]; + } + { + test7(x); + } +} + +/* Checking a complicated cast */ + +struct { + struct { + int (*f)(int), o; + } bar; +} (*baz2)(int) = (struct { struct { int (*f)(int), o; } bar; } (*)(int)) 0; + +/* Distinguish things with the same shape but with different meaning */ + +test8(x) +{ + { + struct { + int foo; + } bar(charstar); + } + { + do { + int foo; + } while (x); + } +} + +/* Do not think foo(*bar) is a function pointer declaration */ + +test9(char *bar) +{ + foo(*bar); +} + +/* another couple of special-cased words. */ + +test10(int x) +{ + { + int test10(int); + do test10(x); + while (x); + } + { + return test10(x); + } +} + +test11(int *x) +{ + while (*x) + (putchar(*x++)); +} + +test11a(int *x) +{ + for (*x;;) + (putchar(*x++)); +} + +/* #include directive between stuff that requires lookahead */ + +test12() +{ + char *x = "\xf\0002\002\02\2" /* foo */ +#include "/dev/null" + "\abar"; + + printf("foo" /* 1 */ "bar" /* 2 */ "baz"); + + *x = '\a'; + *x = '\xff'; +} + +int test13(void); + +/* line continuations in the middle of tokens */ + +te\ +st14(); +charstar test15 = "foo\ +bar"; +char test16 = "foo\\ +abar"; + +/* Array dimensions with unexpanded macros */ + +test17(charstar foo[bar]){} + +int (*(*test18[bar])(charstar))(charstar) = \ + (int (*(*[bar])(charstar))(charstar)) 0; + +/* Function returning pointer to function */ + +int (*(*test19(long))(int))(double); + +/* GCC accepts the following stuff, K&R C does not... */ + +void test20(int test21(double)) {} + +void test22(struct { int foo; } test23(short)) {} + +/* Do not blindly rewrite (*name(stuff))(otherstuff) */ + +void test23() +{ + int (*test24(int)) (int), + y = (*test24(2)) (3), + z = ((*test24(2)) (3)); +} + +/* Function returning pointer to function */ + +int (*(*test25(long foo))(int bar))(double baz){ /* body */ } + +int (*(*test26(foo))())() +long foo; +{ /* body */ } + +#define ARGSTR() struct {int l; char c[1];} + +void functie(ARGSTR() *cmdlin, ARGSTR() *c1) +{ +} diff --git a/build/unproto/example.out b/build/unproto/example.out new file mode 100644 index 0000000000..0b14e1b8ae --- /dev/null +++ b/build/unproto/example.out @@ -0,0 +1,271 @@ +# 1 "example.c" + + + + + + +typedef char *charstar; + + + + + + +x( + + + +baz) +# 14 "example.c" +struct { + struct { + int (*(*foo)())(); + } foo; +} baz; +# 18 "example.c" +{/*1*/ + /* end dcls */return (0); +}/*1*/ + + + +int (*(*bar0)())(); + + + +baz0(bar) +int (*(*bar)())(); +{/*1*/}/*1*/ + + + + + + + +foo(bar) +# 38 "example.c" +int (*(*bar)())(); +{/*1*/ + int (*baz)()= (int (*)()) 0, + y = (y * (*baz)(y)), + *(*z)()= (int *(*)()) 0; + + struct {/*2*/ int (*foo)(); }/*2*/ *(*s)()= + (struct { int (*foo)(); } *(*)()) 0; + + /* end dcls */{/*2*/ + y /* end dcls */= (y * (*baz)(y)); + }/*2*/ + {/*2*/ + z /* end dcls */= (int *(*)()) 0; + }/*2*/ + {/*2*/ + s /* end dcls */= (struct { int (*foo)(); } *(*)()) 0; + }/*2*/ + + return (0); +}/*1*/ + + + +test1() +{/*1*/ + int foo2,*(*(*bar)())(),*baz(); +}/*1*/ + + + +test2(y) +# 69 "example.c" +charstar y; +{/*1*/ + int foo = 5,atoi(); + + foo /* end dcls */= 5,atoi(y); +}/*1*/ + + + +test3,test4(); + +test5(y) +# 80 "example.c" +int y; +{/*1*/ + /* end dcls */{/*2*/ + test3/* end dcls */; + }/*2*/ + {/*2*/ + test4/* end dcls */(y); + }/*2*/ +}/*1*/ + +test6[1],test7(); + +test7(x) +# 92 "example.c" +int x; +{/*1*/ + /* end dcls */{/*2*/ + test6/* end dcls */[1]; + }/*2*/ + {/*2*/ + test7/* end dcls */(x); + }/*2*/ +}/*1*/ + + + +struct {/*1*/ + struct {/*2*/ + int (*f)(), o; + }/*2*/ bar; +}/*1*/ (*baz2)()= (struct { struct { int (*f)(), o; } bar; } (*)()) 0; + + + +test8(x) +{/*1*/ + /* end dcls */{/*2*/ + struct {/*3*/ + int foo; + }/*3*/ bar(); + }/*2*/ + {/*2*/ + /* end dcls */do {/*3*/ + int foo; + }/*3*/ while (x); + }/*2*/ +}/*1*/ + + + +test9(bar) +# 128 "example.c" +char *bar; +{/*1*/ + foo/* end dcls */(*bar); +}/*1*/ + + + +test10(x) +# 135 "example.c" +int x; +{/*1*/ + /* end dcls */{/*2*/ + int test10(); + /* end dcls */do test10(x); + while (x); + }/*2*/ + {/*2*/ + /* end dcls */return test10(x); + }/*2*/ +}/*1*/ + +test11(x) +# 147 "example.c" +int *x; +{/*1*/ + /* end dcls */while (*x) + (putchar(*x++)); +}/*1*/ + +test11a(x) +# 153 "example.c" +int *x; +{/*1*/ + /* end dcls */for (*x;;) + (putchar(*x++)); +}/*1*/ + + + +test12() +{/*1*/ + char *x = +# 1 "/dev/null" 1 +# 165 "example.c" 2 +# 163 "example.c" +"\017\0002\002\002\002\007bar" + + ; + + printf/* end dcls */("foobarbaz" ); + + *x = '\007'; + *x = '\377'; +}/*1*/ + +int test13(); + + + +test14(); + +charstar test15 = "foobar"; + +char test16 = "foo\007bar"; + + + + +test17(foo) +# 186 "example.c" +charstar foo[bar]; +# 186 "example.c" +{/*1*/}/*1*/ + +int (*(*test18[bar])())()= (int (*(*[bar])())()) 0; + + + + +int (*(*test19())())(); + + + +void test20(test21) +# 197 "example.c" +int test21(); +# 197 "example.c" +{/*1*/}/*1*/ + +void test22(test23) +# 199 "example.c" +struct { int foo; } test23(); +# 199 "example.c" +{/*1*/}/*1*/ + + + +void test23() +{/*1*/ + int (*test24())(), + y = (*test24(2)) (3), + z = ((*test24(2))(3)); +}/*1*/ + + + +int (*(*test25(foo))())() +# 212 "example.c" +long foo; +# 212 "example.c" +{/*1*/ }/*1*/ + +int (*(*test26(foo))())() +long foo; +{/*1*/ }/*1*/ + + + +void functie(cmdlin,c1) +# 220 "example.c" +struct {int l; char c[1];} *cmdlin; +# 220 "example.c" +struct {int l; char c[1];} *c1; +{/*1*/ +}/*1*/ diff --git a/build/unproto/hash.c b/build/unproto/hash.c new file mode 100644 index 0000000000..153f6b7df9 --- /dev/null +++ b/build/unproto/hash.c @@ -0,0 +1,54 @@ +/*++ +/* NAME +/* hash 3 +/* SUMMARY +/* compute hash value for string +/* SYNOPSIS +/* int hash(string, size) +/* char *string; +/* int size; +/* DESCRIPTION +/* This function computes for the given null-terminated string an +/* integer hash value in the range 0..size-1. +/* SEE ALSO +/* .fi +/* Alfred V. Aho, Ravi Sethi and Jeffrey D. Ullman: Compilers: +/* principles, techniques and tools; Addison-Wesley, Amsterdam, 1986. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* +/* Originally written by: P. J. Weinberger at Bell Labs. +/* LAST MODIFICATION +/* 92/01/15 21:53:12 +/* VERSION/RELEASE +/* %I +/*--*/ + +static char hash_sccsid[] = "@(#) hash.c 1.1 92/01/15 21:53:12"; + +/* hash - hash a string; original author: P. J. Weinberger at Bell Labs. */ + +int hash(s, size) +register char *s; +unsigned size; +{ + register unsigned long h = 0; + register unsigned long g; + + /* + * For a performance comparison with the hash function presented in K&R, + * first edition, see the "Dragon" book by Aho, Sethi and Ullman. + */ + + while (*s) { + h = (h << 4) + *s++; + if (g = (h & 0xf0000000)) { + h ^= (g >> 24); + h ^= g; + } + } + return (h % size); +} diff --git a/build/unproto/stdarg.h b/build/unproto/stdarg.h new file mode 100644 index 0000000000..20f6fe7727 --- /dev/null +++ b/build/unproto/stdarg.h @@ -0,0 +1,90 @@ + /* + * @(#) stdarg.h 1.4 93/06/18 22:29:44 + * + * Sample stdarg.h file for use with the unproto filter. + * + * This file serves two purposes. + * + * 1 - On systems that do not have a /usr/include/stdarg.h file, it should be + * included by C source files that implement ANSI-style variadic functions. + * Ultrix 4.[0-2] comes with stdarg.h but still needs the one that is + * provided with the unproto filter. + * + * 2 - To configure the unprototyper itself. If the _VA_ALIST_ macro is + * defined, its value will appear in the place of the "..." at the end of + * argument lists of variadic function *definitions* (not declarations). + * Some compilers (such as Greenhills m88k) have a non-empty va_dcl + * definition in the system header file varargs.h. If that is the case, + * define "_VA_DCL_" with the same value as va_dcl. If _VA_DCL_ is defined, + * the unprototyper will emit its value just before the opening "{". + * + * Compilers that always pass arguments via the stack can use the default code + * at the end of this file (this usually applies for the vax, mc68k and + * 80*86 architectures). + * + * Special tricks are needed for compilers that pass some or all function + * arguments via registers. Examples of the latter are given for the mips + * and sparc architectures. Usually the compiler special-cases an argument + * declaration such as "va_alist" or "__builtin_va_alist". For inspiration, + * see the local /usr/include/varargs.h file. + * + * You can use the varargs.c program provided with the unproto package to + * verify that the stdarg.h file has been set up correctly. + */ + +#ifdef sparc /* tested with SunOS 4.1.1 */ + +#define _VA_ALIST_ "__builtin_va_alist" +typedef char *va_list; +#define va_start(ap, p) (ap = (char *) &__builtin_va_alist) +#define va_arg(ap, type) ((type *) __builtin_va_arg_incr((type *) ap))[0] +#define va_end(ap) + +#else +#ifdef mips /* tested with Ultrix 4.0 and 4.2 */ + +#define _VA_ALIST_ "va_alist" +#include "/usr/include/stdarg.h" + +#else +#ifdef m88k /* Motorola SYSTEM V/88 R32V3 */ + +#define _VA_ALIST_ "va_alist" +#define _VA_DCL_ "va_type va_alist;" +typedef struct _va_struct { + int va_narg; + int *va_stkaddr; + int *va_iregs; +} va_list; +#define va_start(ap, p) \ +((ap).va_narg=(int *)&va_alist-va_stkarg, \ + (ap).va_stkaddr=va_stkarg, \ + (ap).va_iregs=(int *)va_intreg) +#define va_end(p) +#if defined(LittleEndian) +#define va_arg(p,mode) \ + (*(mode *)_gh_va_arg(&p, va_align(mode), va_regtyp(mode), sizeof(mode))) +#else /* defined(LittleEndian) */ +#define va_arg(p,mode) ( \ + (p).va_narg += ((p).va_narg & (va_align(mode) == 8)) + \ + (sizeof(mode)+3)/4, \ + ((mode *)((va_regtyp(mode) && (p).va_narg <= 8 ? \ + (p).va_iregs: \ + (p).va_stkaddr) + (p).va_narg))[-1]) +#endif /* defined(LittleEndian) */ + +#else +#ifdef hpux +#include + +#else /* vax, mc68k, 80*86 */ + +typedef char *va_list; +#define va_start(ap, p) (ap = (char *) (&(p)+1)) +#define va_arg(ap, type) ((type *) (ap += sizeof(type)))[-1] +#define va_end(ap) + +#endif /* hpux */ +#endif /* m88k */ +#endif /* mips */ +#endif /* sparc */ diff --git a/build/unproto/stddef.h b/build/unproto/stddef.h new file mode 100644 index 0000000000..97dbc01048 --- /dev/null +++ b/build/unproto/stddef.h @@ -0,0 +1,23 @@ +/* @(#) stddef.h 1.1 92/02/15 17:25:46 */ + +#ifndef _stddef_h_ +#define _stddef_h_ + +/* NULL is also defined in */ + +#ifndef NULL +#define NULL 0 +#endif + +/* Structure member offset - some compilers barf on this. */ + +#define offsetof(type, member) ((size_t) &((type *)0)->member) + +/* Some of the following types may already be defined in . */ + +/* #include */ +/* typedef long ptrdiff_t; /* type of pointer difference */ +/* typedef unsigned short wchar_t; /* wide character type */ +/* typedef unsigned size_t; /* type of sizeof */ + +#endif /* _stddef_h_ */ diff --git a/build/unproto/stdlib.h b/build/unproto/stdlib.h new file mode 100644 index 0000000000..78d99dd983 --- /dev/null +++ b/build/unproto/stdlib.h @@ -0,0 +1,53 @@ +/* @(#) stdlib.h 1.1 92/02/15 17:25:45 */ + +#ifndef _stdlib_h_ +#define _stdlib_h_ + +/* NULL is also defined in */ + +#ifndef NULL +#define NULL 0 +#endif + +/* + * Some functions in this file will be missing from the typical pre-ANSI + * UNIX library. Some pre-ANSI UNIX library functions have return types + * that differ from what ANSI requires. + */ + +extern double atof(); +extern int atoi(); +extern long atol(); +extern double strtod(); +extern long strtol(); +extern unsigned long strtoul(); +extern int rand(); +extern void srand(); +extern char *calloc(); +extern char *malloc(); +extern char *realloc(); +extern void free(); +extern void abort(); +extern void exit(); +extern int atextit(); +extern int system(); +extern char *getenv(); +extern char *bsearch(); +extern void qsort(); +extern int abs(); +extern long labs(); + +typedef struct { + int quot; + int rem; +} div_t; + +typedef struct { + long quot; + long rem; +} ldiv_t; + +extern div_t div(); +extern ldiv_t ldiv(); + +#endif /* _stdlib_h_ */ diff --git a/build/unproto/strsave.c b/build/unproto/strsave.c new file mode 100644 index 0000000000..c2a4b15e5b --- /dev/null +++ b/build/unproto/strsave.c @@ -0,0 +1,71 @@ +/*++ +/* NAME +/* strsave 3 +/* SUMMARY +/* maintain unique copy of a string +/* SYNOPSIS +/* char *strsave(string) +/* char *string; +/* DESCRIPTION +/* This function returns a pointer to an unique copy of its +/* argument. +/* DIAGNOSTISC +/* strsave() calls fatal() when it runs out of memory. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 92/01/15 21:53:13 +/* VERSION/RELEASE +/* 1.1 +/*--*/ + +static char strsave_sccsid[] = "@(#) strsave.c 1.1 92/01/15 21:53:13"; + +/* C library */ + +extern char *strcpy(); +extern char *malloc(); + +/* Application-specific stuff */ + +#include "error.h" + +#define STR_TABSIZE 100 + +struct string { + char *strval; /* unique string copy */ + struct string *next; /* next one in hash chain */ +}; + +static struct string *str_tab[STR_TABSIZE] = {0,}; + +/* More string stuff. Maybe it should go to an #include file. */ + +#define STREQ(x,y) (*(x) == *(y) && strcmp((x),(y)) == 0) + +/* strsave - save unique copy of string */ + +char *strsave(str) +register char *str; +{ + register struct string *s; + register int where = hash(str, STR_TABSIZE); + + /* Look for existing entry. */ + + for (s = str_tab[where]; s; s = s->next) + if (STREQ(str, s->strval)) + return (s->strval); + + /* Add new entry. */ + + if ((s = (struct string *) malloc(sizeof(*s))) == 0 + || (s->strval = malloc(strlen(str) + 1)) == 0) + fatal("out of memory"); + s->next = str_tab[where]; + str_tab[where] = s; + return (strcpy(s->strval, str)); +} diff --git a/build/unproto/symbol.c b/build/unproto/symbol.c new file mode 100644 index 0000000000..ce9f7d9a01 --- /dev/null +++ b/build/unproto/symbol.c @@ -0,0 +1,144 @@ +/*++ +/* NAME +/* symbol 3 +/* SUMMARY +/* rudimentary symbol table package +/* SYNOPSIS +/* #include "symbol.h" +/* +/* void sym_init() +/* +/* void sym_enter(name, type) +/* char *name; +/* int type; +/* +/* struct symbol *sym_find(name) +/* char *name; +/* DESCRIPTION +/* This is a rudimentary symbol-table package, just enough to +/* keep track of a couple of C keywords. +/* +/* sym_init() primes the table with C keywords. At present, most of +/* the keywords that have to do with types are left out. +/* We need a different strategy to detect type definitions because +/* we do not keep track of typedef names. +/* +/* sym_enter() adds an entry to the symbol table. +/* +/* sym_find() locates a symbol table entry (it returns 0 if +/* it is not found). +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 92/02/15 18:59:56 +/* VERSION/RELEASE +/* 1.4 +/*--*/ + +static char symbol_sccsid[] = "@(#) symbol.c 1.4 92/02/15 18:59:56"; + +/* C library */ + +extern char *strcpy(); +extern char *malloc(); + +/* Application-specific stuff */ + +#include "error.h" +#include "token.h" +#include "symbol.h" + +#define SYM_TABSIZE 20 + +static struct symbol *sym_tab[SYM_TABSIZE] = {0,}; + +/* More string stuff. Maybe it should go to an #include file. */ + +#define STREQ(x,y) (*(x) == *(y) && strcmp((x),(y)) == 0) + +/* sym_enter - enter symbol into table */ + +void sym_enter(name, type) +char *name; +int type; +{ + struct symbol *s; + int where; + + if ((s = (struct symbol *) malloc(sizeof(*s))) == 0 + || (s->name = malloc(strlen(name) + 1)) == 0) + fatal("out of memory"); + (void) strcpy(s->name, name); + s->type = type; + + where = hash(name, SYM_TABSIZE); + s->next = sym_tab[where]; + sym_tab[where] = s; +} + +/* sym_find - locate symbol definition */ + +struct symbol *sym_find(name) +register char *name; +{ + register struct symbol *s; + + /* + * This function is called for almost every "word" token, so it better be + * fast. + */ + + for (s = sym_tab[hash(name, SYM_TABSIZE)]; s; s = s->next) + if (STREQ(name, s->name)) + return (s); + return (0); +} + + /* + * Initialization data for symbol table. We do not enter keywords for types. + * We use a different strategy to detect type declarations because we do not + * keep track of typedef names. + */ + +struct sym { + char *name; + int tokno; +}; + +static struct sym syms[] = { + "if", TOK_CONTROL, + "else", TOK_CONTROL, + "for", TOK_CONTROL, + "while", TOK_CONTROL, + "do", TOK_CONTROL, + "switch", TOK_CONTROL, + "case", TOK_CONTROL, + "default", TOK_CONTROL, + "return", TOK_CONTROL, + "continue", TOK_CONTROL, + "break", TOK_CONTROL, + "goto", TOK_CONTROL, + "struct", TOK_COMPOSITE, + "union", TOK_COMPOSITE, + "__DATE__", TOK_DATE, + "__TIME__", TOK_TIME, +#if defined(MAP_VOID_STAR) || defined(MAP_VOID) + "void", TOK_VOID, +#endif + "asm", TOK_OTHER, + 0, +}; + +/* sym_init - enter known keywords into symbol table */ + +void sym_init() +{ + register struct sym *p; + + for (p = syms; p->name; p++) + sym_enter(p->name, p->tokno); +} + diff --git a/build/unproto/symbol.h b/build/unproto/symbol.h new file mode 100644 index 0000000000..0711c1f4dc --- /dev/null +++ b/build/unproto/symbol.h @@ -0,0 +1,11 @@ +/* @(#) symbol.h 1.1 91/09/22 21:21:42 */ + +struct symbol { + char *name; /* symbol name */ + int type; /* symbol type */ + struct symbol *next; +}; + +extern void sym_enter(); /* add symbol to table */ +extern struct symbol *sym_find(); /* locate symbol */ +extern void sym_init(); /* prime the table */ diff --git a/build/unproto/tok_class.c b/build/unproto/tok_class.c new file mode 100644 index 0000000000..38ccd0d76e --- /dev/null +++ b/build/unproto/tok_class.c @@ -0,0 +1,432 @@ +/*++ +/* NAME +/* tok_class 3 +/* SUMMARY +/* token classification +/* PACKAGE +/* unproto +/* SYNOPSIS +/* #include "token.h" +/* +/* void tok_unget(t) +/* struct token *t; +/* +/* struct token *tok_class() +/* DESCRIPTION +/* tok_class() collects single and composite tokens, and +/* recognizes keywords. +/* At present, the only composite tokens are ()-delimited, +/* comma-separated lists, and non-whitespace tokens with attached +/* whitespace or comment tokens. +/* +/* Source transformations are: __DATE__ and __TIME__ are rewritten +/* to string constants with the current date and time, respectively. +/* Multiple string constants are concatenated. Optionally, "void *" +/* is mapped to "char *", and plain "void" to "int". +/* +/* tok_unget() implements an arbitrary amount of token pushback. +/* Only tokens obtained through tok_class() should be given to +/* tok_unget(). This function accepts a list of tokens in +/* last-read-first order. +/* DIAGNOSTICS +/* The code complains if input terminates in the middle of a list. +/* BUGS +/* Does not preserve white space at the beginning of a list element +/* or after the end of a list. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 92/01/15 21:53:02 +/* VERSION/RELEASE +/* 1.4 +/*--*/ + +static char class_sccsid[] = "@(#) tok_class.c 1.4 92/01/15 21:53:02"; + +/* C library */ + +#include + +extern char *strcpy(); +extern long time(); +extern char *ctime(); + +/* Application-specific stuff */ + +#include "error.h" +#include "vstring.h" +#include "token.h" +#include "symbol.h" + +static struct token *tok_list(); +static void tok_list_struct(); +static void tok_list_append(); +static void tok_strcat(); +static void tok_time(); +static void tok_date(); +static void tok_space_append(); + +#if defined(MAP_VOID_STAR) || defined(MAP_VOID) +static void tok_void(); /* rewrite void keyword */ +#endif + +static struct token *tok_buf = 0; /* token push-back storage */ + +/* TOK_PREPEND - add token to LIFO queue, return head */ + +#define TOK_PREPEND(list,t) (t->next = list, list = t) + +/* tok_space_append - append trailing space except at start of or after list */ + +static void tok_space_append(list, t) +register struct token *list; +register struct token *t; +{ + + /* + * The head/tail fields of a token do triple duty. They are used to keep + * track of the members that make up a (list); to keep track of the + * non-blank tokens that make up one list member; and, finally, to tack + * whitespace and comment tokens onto the non-blank tokens that make up + * one list member. + * + * Within a (list), white space and comment tokens are always tacked onto + * the non-blank tokens to avoid parsing complications later on. For this + * reason, blanks and comments at the beginning of a list member are + * discarded because there is no token to tack them onto. (Well, we could + * start each list member with a dummy token, but that would mess up the + * whole unprototyper). + * + * Blanks or comments that follow a (list) are discarded, because the + * head/tail fields of a (list) are already being used for other + * purposes. + * + * Newlines within a (list) are discarded because they can mess up the + * output when we rewrite function headers. The output routines will + * regenerate discarded newlines, anyway. + */ + + if (list == 0 || list->tokno == TOK_LIST) { + tok_free(t); + } else { + tok_list_append(list, t); + } +} + +/* tok_class - discriminate single tokens, keywords, and composite tokens */ + +struct token *tok_class() +{ + register struct token *t; + register struct symbol *s; + + /* + * Use push-back token, if available. Push-back tokens are already + * canonical and can be passed on to the caller without further + * inspection. + */ + + if (t = tok_buf) { + tok_buf = t->next; + t->next = 0; + return (t); + } + /* Read a new token and canonicalize it. */ + + if (t = tok_get()) { + switch (t->tokno) { + case '(': /* beginning of list */ + t = tok_list(t); + break; + case TOK_WORD: /* look up keyword */ + if ((s = sym_find(t->vstr->str))) { + switch (s->type) { + case TOK_TIME: /* map __TIME__ to string */ + tok_time(t); + tok_strcat(t); /* look for more strings */ + break; + case TOK_DATE: /* map __DATE__ to string */ + tok_date(t); + tok_strcat(t); /* look for more strings */ + break; +#if defined(MAP_VOID_STAR) || defined(MAP_VOID) + case TOK_VOID: /* optionally map void types */ + tok_void(t); + break; +#endif + default: /* other keyword */ + t->tokno = s->type; + break; + } + } + break; + case '"': /* string, look for more */ + tok_strcat(t); + break; + } + } + return (t); +} + +/* tok_list - collect ()-delimited, comma-separated list of tokens */ + +static struct token *tok_list(t) +struct token *t; +{ + register struct token *list = tok_alloc(); + char *filename; + int lineno; + + /* Save context of '(' for diagnostics. */ + + filename = t->path; + lineno = t->line; + + list->tokno = TOK_LIST; + list->head = list->tail = t; + list->path = t->path; + list->line = t->line; +#ifdef DEBUG + strcpy(list->vstr->str, "LIST"); +#endif + + /* + * Read until the matching ')' is found, accounting for structured stuff + * (enclosed by '{' and '}' tokens). Break the list up at each ',' token, + * and try to preserve as much whitespace as possible. Newlines are + * discarded so that they will not mess up the layout when we rewrite + * argument lists. The output routines will regenerate discarded + * newlines. + */ + + while (t = tok_class()) { /* skip blanks */ + switch (t->tokno) { + case ')': /* end of list */ + tok_list_append(list, t); + return (list); + case '{': /* struct/union type */ + tok_list_struct(list->tail, t); + break; + case TOK_WSPACE: /* preserve trailing blanks */ + tok_space_append(list->tail->tail, t); /* except after list */ + break; + case '\n': /* fix newlines later */ + tok_free(t); + break; + case ',': /* list separator */ + tok_list_append(list, t); + break; + default: /* other */ + tok_list_append(list->tail, t); + break; + } + } + error_where(filename, lineno, "unmatched '('"); + return (list); /* do not waste any data */ +} + +/* tok_list_struct - collect structured type info within list */ + +static void tok_list_struct(list, t) +register struct token *list; +register struct token *t; +{ + char *filename; + int lineno; + + /* + * Save context of '{' for diagnostics. This routine is called by the one + * that collects list members. If the '}' is not found, the list + * collector will not see the closing ')' either. + */ + + filename = t->path; + lineno = t->line; + + tok_list_append(list, t); + + /* + * Collect tokens until the matching '}' is found. Try to preserve as + * much whitespace as possible. Newlines are discarded so that they do + * not interfere when rewriting argument lists. The output routines will + * regenerate discarded newlines. + */ + + while (t = tok_class()) { + switch (t->tokno) { + case TOK_WSPACE: /* preserve trailing blanks */ + tok_space_append(list->tail, t); /* except after list */ + break; + case '\n': /* fix newlines later */ + tok_free(t); + break; + case '{': /* recurse */ + tok_list_struct(list, t); + break; + case '}': /* done */ + tok_list_append(list, t); + return; + default: /* other */ + tok_list_append(list, t); + break; + } + } + error_where(filename, lineno, "unmatched '{'"); +} + +/* tok_strcat - concatenate multiple string constants */ + +static void tok_strcat(t1) +register struct token *t1; +{ + register struct token *t2; + register struct token *lookahead = 0; + + /* + * Read ahead past whitespace, comments and newlines. If we find a string + * token, concatenate it with the previous one and push back the + * intervening tokens (thus preserving as much information as possible). + * If we find something else, push back all lookahead tokens. + */ + +#define PUSHBACK_AND_RETURN { if (lookahead) tok_unget(lookahead); return; } + + while (t2 = tok_class()) { + switch (t2->tokno) { + case TOK_WSPACE: /* read past comments/blanks */ + case '\n': /* read past newlines */ + TOK_PREPEND(lookahead, t2); + break; + case '"': /* concatenate string tokens */ + if (vs_strcpy(t1->vstr, + t1->vstr->str + strlen(t1->vstr->str) - 1, + t2->vstr->str + 1) == 0) + fatal("out of memory"); + tok_free(t2); + PUSHBACK_AND_RETURN; + default: /* something else, push back */ + tok_unget(t2); + PUSHBACK_AND_RETURN; + } + } + PUSHBACK_AND_RETURN; /* hit EOF */ +} + +#if defined(MAP_VOID_STAR) || defined(MAP_VOID) + +/* tok_void - support for compilers that have problems with "void" */ + +static void tok_void(t) +register struct token *t; +{ + register struct token *t2; + register struct token *lookahead = 0; + + /* + * Look ahead beyond whitespace, comments and newlines until we see a '*' + * token. If one is found, replace "void" by "char". If we find something + * else, and if "void" should always be mapped, replace "void" by "int". + * Always push back the lookahead tokens. + * + * XXX The code also replaces the (void) argument list; this must be + * accounted for later on. The alternative would be to add (in unproto.c) + * TOK_VOID cases all over the place and that would be too error-prone. + */ + +#define PUSHBACK_AND_RETURN { if (lookahead) tok_unget(lookahead); return; } + + while (t2 = tok_class()) { + switch (TOK_PREPEND(lookahead, t2)->tokno) { + case TOK_WSPACE: /* read past comments/blanks */ + case '\n': /* read past newline */ + break; + case '*': /* "void *" -> "char *" */ + if (vs_strcpy(t->vstr, t->vstr->str, "char") == 0) + fatal("out of memory"); + PUSHBACK_AND_RETURN; + default: +#ifdef MAP_VOID /* plain "void" -> "int" */ + if (vs_strcpy(t->vstr, t->vstr->str, "int") == 0) + fatal("out of memory"); +#endif + PUSHBACK_AND_RETURN; + } + } + PUSHBACK_AND_RETURN; /* hit EOF */ +} + +#endif + +/* tok_time - rewrite __TIME__ to "hh:mm:ss" string constant */ + +static void tok_time(t) +struct token *t; +{ + long now; + char *cp; + char buf[BUFSIZ]; + + /* + * Using sprintf() to select parts of a string is gross, but this should + * be fast enough. + */ + + (void) time(&now); + cp = ctime(&now); + sprintf(buf, "\"%.8s\"", cp + 11); + if (vs_strcpy(t->vstr, t->vstr->str, buf) == 0) + fatal("out of memory"); + t->tokno = buf[0]; +} + +/* tok_date - rewrite __DATE__ to "Mmm dd yyyy" string constant */ + +static void tok_date(t) +struct token *t; +{ + long now; + char *cp; + char buf[BUFSIZ]; + + /* + * Using sprintf() to select parts of a string is gross, but this should + * be fast enough. + */ + + (void) time(&now); + cp = ctime(&now); + sprintf(buf, "\"%.3s %.2s %.4s\"", cp + 4, cp + 8, cp + 20); + if (vs_strcpy(t->vstr, t->vstr->str, buf) == 0) + fatal("out of memory"); + t->tokno = buf[0]; +} + +/* tok_unget - push back one or more possibly composite tokens */ + +void tok_unget(t) +register struct token *t; +{ + register struct token *next; + + do { + next = t->next; + TOK_PREPEND(tok_buf, t); + } while (t = next); +} + +/* tok_list_append - append data to list */ + +static void tok_list_append(h, t) +struct token *h; +struct token *t; +{ + if (h->head == 0) { + h->head = h->tail = t; + } else { + h->tail->next = t; + h->tail = t; + } +} diff --git a/build/unproto/tok_io.c b/build/unproto/tok_io.c new file mode 100644 index 0000000000..74ae6bcfee --- /dev/null +++ b/build/unproto/tok_io.c @@ -0,0 +1,612 @@ +/*++ +/* NAME +/* tok_io 3 +/* SUMMARY +/* token I/O +/* PACKAGE +/* unproto +/* SYNOPSIS +/* #include "token.h" +/* +/* struct token *tok_get() +/* +/* void tok_flush(t) +/* struct token *t; +/* +/* void tok_show(t) +/* struct token *t; +/* +/* void tok_show_ch(t) +/* struct token *t; +/* +/* void put_str(s) +/* char *s; +/* +/* void put_ch(c) +/* int c; +/* +/* void put_nl() +/* +/* char *in_path; +/* int in_line; +/* DESCRIPTION +/* These functions read from stdin and write to stdout. The +/* tokenizer keeps track of where the token appeared in the input +/* stream; on output, this information is used to preserve correct +/* line number information (even after lots of token lookahead or +/* after function-header rewriting) so that diagnostics from the +/* next compiler stage make sense. +/* +/* tok_get() reads the next token from standard input. It returns +/* a null pointer when the end of input is reached. +/* +/* tok_show() displays the contents of a (possibly composite) token +/* on the standard output. +/* +/* tok_show_ch() displays the contents of a single-character token +/* on the standard output. The character should not be a newline. +/* +/* tok_flush() displays the contents of a (possibly composite) token +/* on the standard output and makes it available for re-use. +/* +/* put_str() writes a null-terminated string to standard output. +/* There should be no newline characters in the string argument. +/* +/* put_ch() writes one character to standard output. The character +/* should not be a newline. +/* +/* put_nl() outputs a newline character and adjusts the program's idea of +/* the current output line. +/* +/* The in_path and in_line variables contain the file name and +/* line number of the most recently read token. +/* BUGS +/* The tokenizer is just good enough for the unproto filter. +/* As a benefit, it is quite fast. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 92/01/15 21:52:59 +/* VERSION/RELEASE +/* 1.3 +/*--*/ + +static char io_sccsid[] = "@(#) tok_io.c 1.3 92/01/15 21:52:59"; + +/* C library */ + +#include +#include + +extern char *strchr(); +extern char *malloc(); +extern char *realloc(); +extern char *strcpy(); + +/* Application-specific stuff */ + +#include "token.h" +#include "vstring.h" +#include "error.h" + +extern char *strsave(); /* XXX need include file */ + +/* Stuff to keep track of original source file name and position */ + +static char def_path[] = ""; /* default path name */ + +char *in_path = def_path; /* current input file name */ +int in_line = 1; /* current input line number */ + +static char *out_path = def_path; /* last name in output line control */ +static int out_line = 1; /* current output line number */ +int last_ch; /* type of last output */ + +/* Forward declarations */ + +static int read_quoted(); +static void read_comment(); +static int backslash_newline(); +static char *read_hex(); +static char *read_octal(); +static void fix_line_control(); + + /* + * Character input with one level of pushback. The INPUT() macro recursively + * strips backslash-newline pairs from the input stream. The UNPUT() macro + * should be used only for characters obtained through the INPUT() macro. + * + * After skipping a backslash-newline pair, the input line counter is not + * updated, and we continue with the same logical source line. We just + * update a counter with the number of backslash-newline sequences that must + * be accounted for (backslash_newline() updates the counter). At the end of + * the logical source line, an appropriate number of newline characters is + * pushed back (in tok_get()). I do not know how GCC handles this, but it + * seems to produce te same output. + * + * Because backslash_newline() recursively calls itself (through the INPUT() + * macro), we will run out of stack space, given a sufficiently long + * sequence of backslash-newline pairs. + */ + +static char in_char = 0; /* push-back storage */ +static int in_flag = 0; /* pushback available */ +static int nl_compensate = 0; /* line continuation kluge */ + +#define INPUT(c) (in_flag ? (in_flag = 0, c = in_char) : \ + (c = getchar()) != '\\' ? c : \ + (c = getchar()) != '\n' ? (ungetc(c, stdin), c = '\\') : \ + (c = backslash_newline())) +#define UNPUT(c) (in_flag = 1, in_char = c) + +/* Directives that should be ignored. */ + +#ifdef IGNORE_DIRECTIVES + +static char *ignore_directives[] = { + IGNORE_DIRECTIVES, + 0, +}; + +#endif + +/* Modified string and ctype stuff. */ + +#define STREQUAL(x,y) (*(x) == *(y) && strcmp((x),(y)) == 0) + +#define ISALNUM(c) (isalnum(c) || (c) == '_') +#define ISALPHA(c) (isalpha(c) || (c) == '_') +#define ISSPACE(c) (isspace(c) && c != '\n') +#define ISDOT(c) (c == '.') +#define ISHEX(c) (isdigit(c) || strchr("abcdefABCDEF", c) != 0) +#define ISOCTAL(c) (isdigit(c) && (c) != '8' && (c) != '9') + +/* Collect all characters that satisfy one condition */ + +#define COLLECT(v,c,cond) { \ + register struct vstring *vs = v; \ + register char *cp = vs->str; \ + *cp++ = c; \ + while (INPUT(c) != EOF) { \ + if (cond) { \ + if (VS_ADDCH(vs, cp, c) == 0) \ + fatal("out of memory"); \ + } else { \ + UNPUT(c); \ + break; \ + } \ + } \ + *cp = 0; \ + } + +/* Ensure that output line information is correct */ + +#define CHECK_LINE_CONTROL(p,l) { if (out_path != (p) || out_line != (l)) \ + fix_line_control((p),(l)); } + +/* do_control - parse control line */ + +static int do_control() +{ + struct token *t; + int line; + char *path; + + /* Make sure that the directive shows up in the right place. */ + + CHECK_LINE_CONTROL(in_path, in_line); + + while (t = tok_get()) { + switch (t->tokno) { + + case TOK_WSPACE: + /* Ignore blanks after "#" token. */ + tok_free(t); + break; + + case TOK_NUMBER: + + /* + * Line control is of the form: number pathname junk. Since we + * have no idea what junk the preprocessor may generate, we copy + * all line control tokens to stdout. + */ + + put_str("# "); + line = atoi(t->vstr->str); /* extract line number */ + tok_flush(t); + while ((t = tok_get()) && t->tokno == TOK_WSPACE) + tok_flush(t); /* copy white space */ + if (t) { /* extract path name */ + path = (t->tokno == '"') ? strsave(t->vstr->str) : in_path; + do { + tok_flush(t); /* copy until newline */ + } while (t->tokno != '\n' && (t = tok_get())); + } + out_line = in_line = line; /* synchronize */ + out_path = in_path = path; /* synchronize */ + return; + +#ifdef IGNORE_DIRECTIVES + + case TOK_WORD: + + /* + * Optionally ignore other #directives. This is only a partial + * solution, because the preprocessor will still see them. + */ + { + char **cpp; + char *cp = t->vstr->str; + + for (cpp = ignore_directives; *cpp; cpp++) { + if (STREQUAL(cp, *cpp)) { + do { + tok_free(t); + } while (t->tokno != '\n' && (t = tok_get())); + return; + } + } + } + /* FALLTHROUGH */ +#endif + default: + /* Pass through. */ + put_ch('#'); + do { + tok_flush(t); + } while (t->tokno != '\n' && (t = tok_get())); + return; + + case 0: + /* Hit EOF, punt. */ + put_ch('#'); + return; + } + } +} + +/* backslash_newline - fix up things after reading a backslash-newline pair */ + +static int backslash_newline() +{ + register int c; + + nl_compensate++; + return (INPUT(c)); +} + +/* tok_get - get next token */ + +static int last_tokno = '\n'; + +struct token *tok_get() +{ + register struct token *t; + register int c; + int d; + + /* + * Get one from the pool and fill it in. The loop is here in case we hit + * a preprocessor control line, which happens in a minority of all cases. + * We update the token input path and line info *after* backslash-newline + * processing or the newline compensation would go wrong. + */ + + t = tok_alloc(); + + for (;;) { + if ((INPUT(c)) == EOF) { + tok_free(t); + return (0); + } else if ((t->line = in_line, t->path = in_path), !isascii(c)) { + t->vstr->str[0] = c; + t->vstr->str[1] = 0; + t->tokno = TOK_OTHER; + break; + } else if (ISSPACE(c)) { + COLLECT(t->vstr, c, ISSPACE(c)); + t->tokno = TOK_WSPACE; + break; + } else if (ISALPHA(c)) { + COLLECT(t->vstr, c, ISALNUM(c)); + t->tokno = TOK_WORD; + break; + } else if (isdigit(c)) { + COLLECT(t->vstr, c, isdigit(c)); + t->tokno = TOK_NUMBER; + break; + } else if (c == '"' || c == '\'') { + t->tokno = read_quoted(t->vstr, c); /* detect missing end quote */ + break; + } else if (ISDOT(c)) { + COLLECT(t->vstr, c, ISDOT(c)); + t->tokno = TOK_OTHER; + break; + } else if (c == '#' && last_tokno == '\n') { + do_control(); + continue; + } else { + t->vstr->str[0] = c; + if (c == '\n') { + in_line++; + if (nl_compensate > 0) { /* compensation for bs-nl */ + UNPUT('\n'); + nl_compensate--; + } + } else if (c == '/') { + if ((INPUT(d)) == '*') { + t->vstr->str[1] = d; /* comment */ + read_comment(t->vstr); + t->tokno = TOK_WSPACE; + break; + } else { + if (d != EOF) + UNPUT(d); + } + } else if (c == '\\') { + t->vstr->str[1] = (INPUT(c) == EOF ? 0 : c); + t->vstr->str[2] = 0; + t->tokno = TOK_OTHER; + break; + } + t->vstr->str[1] = 0; + t->tokno = c; + break; + } + } + last_tokno = t->tokno; + t->end_line = in_line; + return (t); +} + +/* read_quoted - read string or character literal, canonicalize escapes */ + +static int read_quoted(vs, ch) +register struct vstring *vs; +int ch; +{ + register char *cp = vs->str; + register int c; + int ret = TOK_OTHER; + + *cp++ = ch; + + /* + * Clobber the token type in case of a premature newline or EOF. This + * prevents us from attempting to concatenate string constants with + * broken ones that have no closing quote. + */ + + while (INPUT(c) != EOF) { + if (c == '\n') { /* newline in string */ + UNPUT(c); + break; + } + if (VS_ADDCH(vs, cp, c) == 0) /* store character */ + fatal("out of memory"); + if (c == ch) { /* closing quote */ + ret = c; + break; + } + if (c == '\\') { /* parse escape sequence */ + if ((INPUT(c)) == EOF) { /* EOF, punt */ + break; + } else if (c == 'a') { /* \a -> audible bell */ + if ((cp = vs_strcpy(vs, cp, BELL)) == 0) + fatal("out of memory"); + } else if (c == 'x') { /* \xhh -> \nnn */ + cp = read_hex(vs, cp); + } else if (ISOCTAL(c) && ch != '\'') { + cp = read_octal(vs, cp, c); /* canonicalize \octal */ + } else { + if (VS_ADDCH(vs, cp, c) == 0) /* \other: leave alone */ + fatal("out of memory"); + } + } + } + *cp = 0; + return (ret); +} + +/* read_comment - stuff a whole comment into one huge token */ + +static void read_comment(vs) +register struct vstring *vs; +{ + register char *cp = vs->str + 2; /* skip slash star */ + register int c; + register int d; + + while (INPUT(c) != EOF) { + if (VS_ADDCH(vs, cp, c) == 0) + fatal("out of memory"); + if (c == '*') { + if ((INPUT(d)) == '/') { + if (VS_ADDCH(vs, cp, d) == 0) + fatal("out of memory"); + break; + } else { + if (d != EOF) + UNPUT(d); + } + } else if (c == '\n') { + in_line++; + } else if (c == '\\') { + if ((INPUT(d)) != EOF && VS_ADDCH(vs, cp, d) == 0) + fatal("out of memory"); + } + } + *cp = 0; +} + +/* read_hex - rewrite hex escape to three-digit octal escape */ + +static char *read_hex(vs, cp) +struct vstring *vs; +register char *cp; +{ + register int c; + register int i; + char buf[BUFSIZ]; + int len; + unsigned val; + + /* + * Eat up all subsequent hex digits. Complain later when there are too + * many. + */ + + for (i = 0; i < sizeof(buf) && (INPUT(c) != EOF) && ISHEX(c); i++) + buf[i] = c; + buf[i] = 0; + + if (i < sizeof(buf) && c) + UNPUT(c); + + /* + * Convert hex form to three-digit octal form. The three-digit form is + * used so that strings can be concatenated without problems. Complain + * about malformed input; truncate the result to at most three octal + * digits. + */ + + if (i == 0) { + error("\\x escape sequence without hexadecimal digits"); + if (VS_ADDCH(vs, cp, 'x') == 0) + fatal("out of memory"); + } else { + (void) sscanf(buf, "%x", &val); + sprintf(buf, "%03o", val); + if ((len = strlen(buf)) > 3) + error("\\x escape sequence yields non-character value"); + if ((cp = vs_strcpy(vs, cp, buf + len - 3)) == 0) + fatal("out of memory"); + } + return (cp); +} + +/* read_octal - convert octal escape to three-digit format */ + +static char obuf[] = "00123"; + +static char *read_octal(vs, cp, c) +register struct vstring *vs; +register char *cp; +register int c; +{ + register int i; + +#define buf_input (obuf + 2) + + /* Eat up at most three octal digits. */ + + buf_input[0] = c; + for (i = 1; i < 3 && (INPUT(c) != EOF) && ISOCTAL(c); i++) + buf_input[i] = c; + buf_input[i] = 0; + + if (i < 3 && c) + UNPUT(c); + + /* + * Leave three-digit octal escapes alone. Convert one-digit and two-digit + * octal escapes to three-digit form by prefixing them with a suitable + * number of '0' characters. This is done so that strings can be + * concatenated without problems. + */ + + if ((cp = vs_strcpy(vs, cp, buf_input + i - 3)) == 0) + fatal("out of memory"); + return (cp); +} + +/* put_nl - emit newline and adjust output line count */ + +void put_nl() +{ + put_ch('\n'); + out_line++; +} + +/* fix_line_control - to adjust path and/or line count info in output */ + +static void fix_line_control(path, line) +register char *path; +register int line; +{ + + /* + * This function is called sporadically, so it should not be a problem + * that we repeat some of the tests that preceded this function call. + * + * Emit a newline if we are not at the start of a line. + * + * If we switch files, or if we jump backwards, emit line control. If we + * jump forward, emit the proper number of newlines to compensate. + */ + + if (last_ch != '\n') /* terminate open line */ + put_nl(); + if (path != out_path || line < out_line) { /* file switch or back jump */ + printf("# %d %s\n", out_line = line, out_path = path); + last_ch = '\n'; + } else { /* forward jump */ + while (line > out_line) + put_nl(); + } +} + +/* tok_show_ch - output single-character token (not newline) */ + +void tok_show_ch(t) +register struct token *t; +{ + CHECK_LINE_CONTROL(t->path, t->line); + + put_ch(t->tokno); /* show token contents */ +} + +/* tok_show - output (possibly composite) token */ + +void tok_show(t) +register struct token *t; +{ + register struct token *p; + + if (t->tokno == TOK_LIST) { + register struct token *s; + + /* + * This branch is completely in terms of tok_xxx() primitives, so + * there is no need to check the line control information. + */ + + for (s = t->head; s; s = s->next) { + tok_show_ch(s); /* '(' or ',' or ')' */ + for (p = s->head; p; p = p->next) + tok_show(p); /* show list element */ + } + } else { + register char *cp = t->vstr->str; + + /* + * Measurements show that it pays off to give special treatment to + * single-character tokens. Note that both types of token may cause a + * change of output line number. + */ + + CHECK_LINE_CONTROL(t->path, t->line); + if (cp[1] == 0) { + put_ch(*cp); /* single-character token */ + } else { + put_str(cp); /* multi_character token */ + } + out_line = t->end_line; /* may span multiple lines */ + for (p = t->head; p; p = p->next) + tok_show(p); /* trailing blanks */ + } +} diff --git a/build/unproto/tok_pool.c b/build/unproto/tok_pool.c new file mode 100644 index 0000000000..e2ed107ce7 --- /dev/null +++ b/build/unproto/tok_pool.c @@ -0,0 +1,103 @@ +/*++ +/* NAME +/* tok_pool 3 +/* SUMMARY +/* maintain pool of unused token structures +/* PACKAGE +/* unproto +/* SYNOPSIS +/* #include "token.h" +/* +/* struct token *tok_alloc() +/* +/* void tok_free(t) +/* struct token *t; +/* DESCRIPTION +/* tok_alloc() and tok_free() maintain a pool of unused token +/* structures. +/* +/* tok_alloc() takes the first free token structure from the pool +/* or allocates a new one if the pool is empty. +/* +/* tok_free() adds a (possibly composite) token structure to the pool. +/* BUGS +/* The pool never shrinks. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 92/01/15 21:53:04 +/* VERSION/RELEASE +/* 1.2 +/*--*/ + +static char pool_sccsid[] = "@(#) tok_pool.c 1.2 92/01/15 21:53:04"; + +/* C library */ + +extern char *malloc(); + +/* Application-specific stuff */ + +#include "token.h" +#include "vstring.h" +#include "error.h" + +#define TOKLEN 5 /* initial string buffer length */ + +struct token *tok_pool = 0; /* free token pool */ + +/* tok_alloc - allocate token structure from pool or heap */ + +struct token *tok_alloc() +{ + register struct token *t; + + if (tok_pool) { /* re-use an old one */ + t = tok_pool; + tok_pool = t->next; + } else { /* create a new one */ + if ((t = (struct token *) malloc(sizeof(struct token))) == 0 + || (t->vstr = vs_alloc(TOKLEN)) == 0) + fatal("out of memory"); + } + t->next = t->head = t->tail = 0; +#ifdef DEBUG + strcpy(t->vstr->str, "BUSY"); +#endif + return (t); +} + +/* tok_free - return (possibly composite) token to pool of free tokens */ + +void tok_free(t) +register struct token *t; +{ +#ifdef DEBUG + /* Check if we are freeing free token */ + + register struct token *p; + + for (p = tok_pool; p; p = p->next) + if (p == t) + fatal("freeing free token"); +#endif + + /* Free neighbours and subordinates first */ + + if (t->next) + tok_free(t->next); + if (t->head) + tok_free(t->head); + + /* Free self */ + + t->next = tok_pool; + t->head = t->tail = 0; + tok_pool = t; +#ifdef DEBUG + strcpy(t->vstr->str, "FREE"); +#endif +} diff --git a/build/unproto/token.h b/build/unproto/token.h new file mode 100644 index 0000000000..bb2f50a106 --- /dev/null +++ b/build/unproto/token.h @@ -0,0 +1,55 @@ +/* @(#) token.h 1.4 92/01/15 21:53:17 */ + +struct token { + int tokno; /* token value, see below */ + char *path; /* file name */ + int line; /* line number at token start */ + int end_line; /* line number at token end */ + struct vstring *vstr; /* token contents */ + struct token *next; + struct token *head; + struct token *tail; +}; + +/* Special token values */ + +#define TOK_LIST 256 /* () delimited list */ +#define TOK_WORD 257 /* keyword or identifier */ +#define TOK_NUMBER 258 /* one or more digits */ +#define TOK_WSPACE 259 /* comment, white space, not newline */ +#define TOK_OTHER 260 /* other token */ +#define TOK_CONTROL 261 /* flow control keyword */ +#define TOK_COMPOSITE 262 /* struct or union keyword */ +#define TOK_DATE 263 /* date: Mmm dd yyyy */ +#define TOK_TIME 264 /* time: hh:mm:ss */ +#define TOK_VOID 265 /* void keyword */ + +/* Input/output functions and macros */ + +extern struct token *tok_get(); /* read next single token */ +extern void tok_show(); /* display (composite) token */ +extern struct token *tok_class(); /* classify tokens */ +extern void tok_unget(); /* stuff token back into input */ +extern void put_nl(); /* print newline character */ +extern void tok_show_ch(); /* emit single-character token */ + +#define tok_flush(t) (tok_show(t), tok_free(t)) + +#ifdef DEBUG +#define put_ch(c) (putchar(last_ch = c),fflush(stdout)) +#define put_str(s) (fputs(s,stdout),last_ch = 0,fflush(stdout)) +#else +#define put_ch(c) putchar(last_ch = c) +#define put_str(s) (fputs(s,stdout),last_ch = 0) +#endif + +/* Memory management */ + +struct token *tok_alloc(); /* allocate token storage */ +extern void tok_free(); /* re-cycle storage */ + +/* Context */ + +extern char *in_path; /* current input path name */ +extern int in_line; /* current input line number */ +extern int last_ch; /* type of last output */ diff --git a/build/unproto/unproto.1 b/build/unproto/unproto.1 new file mode 100644 index 0000000000..31490c36fb --- /dev/null +++ b/build/unproto/unproto.1 @@ -0,0 +1,152 @@ +.TH UNPROTO 1 +.ad +.fi +.SH NAME +unproto +\- +compile ANSI C with traditional UNIX C compiler +.SH PACKAGE +.na +.nf +unproto +.SH SYNOPSIS +.na +.nf +/somewhere/cpp ... + +cc cflags -E file.c | unproto >file.i; cc cflags -c file.i +.SH DESCRIPTION +.ad +.fi +This document describes a filter that sits in between the UNIX +C preprocessor and the next UNIX C compiler stage, on the fly rewriting +ANSI-style syntax to old-style syntax. Typically, the program is +invoked by the native UNIX C compiler as an alternate preprocessor. +The unprototyper in turn invokes the native C preprocessor and +massages its output. Similar tricks can be used with the lint(1) +command. + +Language constructs that are always rewritten: +.TP +function headings, prototypes, pointer types +ANSI-C style function headings, function prototypes, function +pointer types and type casts are rewritten to old style. + support is provided for functions with variable-length +argument lists. +.TP +character and string constants +The \\a and \\x escape sequences are rewritten to their (three-digit) +octal equivalents. + +Multiple string tokens are concatenated; an arbitrary number of +whitespace or comment tokens may appear between successive +string tokens. + +Within string constants, octal escape sequences are rewritten to the +three-digit \\ddd form, so that string concatenation produces correct +results. +.TP +date and time +The __DATE__ and __TIME__ tokens are replaced by string constants +of the form "Mmm dd yyyy" and "hh:mm:ss", respectively. The result +is subjected to string concatenation, just like any other string +constant. +.PP +Language constructs that are rewritten only if the program has been +configured to do so: +.TP +void types +The unprototyper can be configured to rewrite "void *" to "char *", +and even to rewrite plain "void" to "int". +These features are configurable because many traditional UNIX C +compilers do not need them. + +Note: (void) argument lists are always replaced by empty ones. +.PP +ANSI C constructs that are not rewritten because the traditional +UNIX C preprocessor provides suitable workarounds: +.TP +const and volatile +Use the "-Dconst=" and/or "-Dvolatile=" preprocessor directives to +get rid of unimplemented keywords. +.TP +token pasting and stringizing +The traditional UNIX C preprocessor provides excellent alternatives. +For example: + +.nf +.ne 2 +#define string(bar) "bar" /* instead of: # x */ +#define paste(x,y) x/**\/y /* instead of: x##y */ +.fi + +There is a good reason why the # and ## operators are not implemented +in the unprototyper. +After program text has gone through a non-ANSI C preprocessor, all +information about the grouping of the operands of # and ## is lost. +Thus, if the unprototyper were to perform these operations, it would +produce correct results only in the most trivial cases. Operands +with embedded blanks, operands that expand to null tokens, and nested +use of # and/or ## would cause all kinds of obscure problems. +.PP +Unsupported ANSI features: +.TP +trigraphs and #pragmas +Trigraphs are useful only for systems with broken character sets. +If the local compiler chokes on #pragma, insert a blank before the +"#" character, and enclose the offending directive between #ifdef +and #endif. +.SH SEE ALSO +.na +.nf +.ad +.fi +cc(1), how to specify a non-default C preprocessor. +Some versions of the lint(1) command are implemented as a shell +script. It should require only minor modification for integration +with the unprototyper. Other versions of the lint(1) command accept +the same command syntax as the C compiler for the specification of a +non-default preprocessor. Some research may be needed. +.SH FILES +.na +.nf +/wherever/stdarg.h, provided with the unproto filter. +.SH DIAGNOSTICS +.ad +.fi +Problems are reported on the standard error stream. +A non-zero exit status means that there was a problem. +.SH BUGS +.ad +.fi +The unprototyper should be run on preprocessed source only: +unexpanded macros may confuse the program. + +Declarations of (object) are misunderstood and will result in +syntax errors: the objects between parentheses disappear. + +Sometimes does not preserve whitespace after parentheses and commas. +This is a purely aesthetical matter, and the compiler should not care. +Whitespace within string constants is, of course, left intact. + +Does not generate explicit type casts for function-argument +expressions. The lack of explicit conversions between integral +and/or pointer argument types should not be a problem in environments +where sizeof(int) == sizeof(long) == sizeof(pointer). A more serious +problem is the lack of automatic type conversions between integral and +floating-point argument types. Let lint(1) be your friend. +.SH AUTHOR(S) +.na +.nf +Wietse Venema (wietse@wzv.win.tue.nl) +Eindhoven University of Technology +Department of Mathematics and Computer Science +Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +.SH LAST MODIFICATION +.na +.nf +93/06/18 22:29:37 +.SH VERSION/RELEASE +.na +.nf +1.6 diff --git a/build/unproto/unproto.c b/build/unproto/unproto.c new file mode 100644 index 0000000000..2b2e7648b7 --- /dev/null +++ b/build/unproto/unproto.c @@ -0,0 +1,999 @@ +/*++ +/* NAME +/* unproto 1 +/* SUMMARY +/* compile ANSI C with traditional UNIX C compiler +/* PACKAGE +/* unproto +/* SYNOPSIS +/* /somewhere/cpp ... +/* +/* cc cflags -E file.c | unproto >file.i; cc cflags -c file.i +/* DESCRIPTION +/* This document describes a filter that sits in between the UNIX +/* C preprocessor and the next UNIX C compiler stage, on the fly rewriting +/* ANSI-style syntax to old-style syntax. Typically, the program is +/* invoked by the native UNIX C compiler as an alternate preprocessor. +/* The unprototyper in turn invokes the native C preprocessor and +/* massages its output. Similar tricks can be used with the lint(1) +/* command. +/* +/* Language constructs that are always rewritten: +/* .TP +/* function headings, prototypes, pointer types +/* ANSI-C style function headings, function prototypes, function +/* pointer types and type casts are rewritten to old style. +/* support is provided for functions with variable-length +/* argument lists. +/* .TP +/* character and string constants +/* The \\a and \\x escape sequences are rewritten to their (three-digit) +/* octal equivalents. +/* +/* Multiple string tokens are concatenated; an arbitrary number of +/* whitespace or comment tokens may appear between successive +/* string tokens. +/* +/* Within string constants, octal escape sequences are rewritten to the +/* three-digit \\ddd form, so that string concatenation produces correct +/* results. +/* .TP +/* date and time +/* The __DATE__ and __TIME__ tokens are replaced by string constants +/* of the form "Mmm dd yyyy" and "hh:mm:ss", respectively. The result +/* is subjected to string concatenation, just like any other string +/* constant. +/* .PP +/* Language constructs that are rewritten only if the program has been +/* configured to do so: +/* .TP +/* void types +/* The unprototyper can be configured to rewrite "void *" to "char *", +/* and even to rewrite plain "void" to "int". +/* These features are configurable because many traditional UNIX C +/* compilers do not need them. +/* +/* Note: (void) argument lists are always replaced by empty ones. +/* .PP +/* ANSI C constructs that are not rewritten because the traditional +/* UNIX C preprocessor provides suitable workarounds: +/* .TP +/* const and volatile +/* Use the "-Dconst=" and/or "-Dvolatile=" preprocessor directives to +/* get rid of unimplemented keywords. +/* .TP +/* token pasting and stringizing +/* The traditional UNIX C preprocessor provides excellent alternatives. +/* For example: +/* +/* .nf +/* .ne 2 +/* #define string(bar) "bar" /* instead of: # x */ +/* #define paste(x,y) x/**\/y /* instead of: x##y */ +/* .fi +/* +/* There is a good reason why the # and ## operators are not implemented +/* in the unprototyper. +/* After program text has gone through a non-ANSI C preprocessor, all +/* information about the grouping of the operands of # and ## is lost. +/* Thus, if the unprototyper were to perform these operations, it would +/* produce correct results only in the most trivial cases. Operands +/* with embedded blanks, operands that expand to null tokens, and nested +/* use of # and/or ## would cause all kinds of obscure problems. +/* .PP +/* Unsupported ANSI features: +/* .TP +/* trigraphs and #pragmas +/* Trigraphs are useful only for systems with broken character sets. +/* If the local compiler chokes on #pragma, insert a blank before the +/* "#" character, and enclose the offending directive between #ifdef +/* and #endif. +/* SEE ALSO +/* .ad +/* .fi +/* cc(1), how to specify a non-default C preprocessor. +/* Some versions of the lint(1) command are implemented as a shell +/* script. It should require only minor modification for integration +/* with the unprototyper. Other versions of the lint(1) command accept +/* the same command syntax as the C compiler for the specification of a +/* non-default preprocessor. Some research may be needed. +/* FILES +/* /wherever/stdarg.h, provided with the unproto filter. +/* DIAGNOSTICS +/* Problems are reported on the standard error stream. +/* A non-zero exit status means that there was a problem. +/* BUGS +/* The unprototyper should be run on preprocessed source only: +/* unexpanded macros may confuse the program. +/* +/* Declarations of (object) are misunderstood and will result in +/* syntax errors: the objects between parentheses disappear. +/* +/* Sometimes does not preserve whitespace after parentheses and commas. +/* This is a purely aesthetical matter, and the compiler should not care. +/* Whitespace within string constants is, of course, left intact. +/* +/* Does not generate explicit type casts for function-argument +/* expressions. The lack of explicit conversions between integral +/* and/or pointer argument types should not be a problem in environments +/* where sizeof(int) == sizeof(long) == sizeof(pointer). A more serious +/* problem is the lack of automatic type conversions between integral and +/* floating-point argument types. Let lint(1) be your friend. +/* AUTHOR(S) +/* Wietse Venema (wietse@wzv.win.tue.nl) +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 93/06/18 22:29:37 +/* VERSION/RELEASE +/* 1.6 +/*--*/ + +static char unproto_sccsid[] = "@(#) unproto.c 1.6 93/06/18 22:29:37"; + +/* C library */ + +#include +#include +#include +#include + +extern void exit(); +extern int optind; +extern char *optarg; +extern int getopt(); + +/* Application-specific stuff */ + +#include "vstring.h" +#include "stdarg.h" +#include "token.h" +#include "error.h" +#include "symbol.h" + +/* Forward declarations. */ + +static struct token *dcl_flush(); +static void block_flush(); +static void block_dcls(); +static struct token *show_func_ptr_type(); +static struct token *show_struct_type(); +static void show_arg_name(); +static void show_type(); +static void pair_flush(); +static void check_cast(); +static void show_empty_list(); + +#define check_cast_flush(t) (check_cast(t), tok_free(t)) + +#ifdef PIPE_THROUGH_CPP +static int pipe_stdin_through_cpp(); +#endif + +/* Disable debugging printfs while preserving side effects. */ + +#ifdef DEBUG +#define DPRINTF printf +#else +#define DPRINTF (void) +#endif + +/* An attempt to make some complicated expressions a bit more readable. */ + +#define STREQ(x,y) (*(x) == *(y) && !strcmp((x),(y))) + +#define LAST_ARG_AND_EQUAL(s,c) ((s)->next && (s)->next->next == 0 \ + && (s)->head && ((s)->head == (s)->tail) \ + && (STREQ((s)->head->vstr->str, (c)))) + +#define LIST_BEGINS_WITH_STAR(s) (s->head->head && s->head->head->tokno == '*') + +#define IS_FUNC_PTR_TYPE(s) (s->tokno == TOK_LIST && s->next \ + && s->next->tokno == TOK_LIST \ + && LIST_BEGINS_WITH_STAR(s)) + +/* What to look for to detect a (void) argument list. */ + +#ifdef MAP_VOID +#define VOID_ARG "int" /* bare "void" is mapped to "int" */ +#else +#define VOID_ARG "void" /* bare "void" is left alone */ +#endif + +/* main - driver */ + +int main(argc, argv) +int argc; +char **argv; +{ + register struct token *t; +#ifdef PIPE_THROUGH_CPP /* pipe through /lib/cpp */ + int cpp_status; + int wait_pid; + int cpp_pid; + + cpp_pid = pipe_stdin_through_cpp(argv); +#endif + + sym_init(); /* prime the symbol table */ + + while (t = tok_class()) { + if (t = dcl_flush(t)) { /* try declaration */ + if (t->tokno == '{') { /* examine rejected token */ + block_flush(t); /* body */ + } else { + tok_flush(t); /* other, recover */ + } + } + } + +#ifdef PIPE_THROUGH_CPP /* pipe through /lib/cpp */ + while ((wait_pid = wait(&cpp_status)) != -1 && wait_pid != cpp_pid) + /* void */ ; + return (errcount != 0 || wait_pid != cpp_pid || cpp_status != 0); +#else + return (errcount != 0); +#endif +} + +#ifdef PIPE_THROUGH_CPP /* pipe through /lib/cpp */ + +/* pipe_stdin_through_cpp - avoid shell script overhead */ + +static int pipe_stdin_through_cpp(argv) +char **argv; +{ + int pipefds[2]; + int pid; + char **cpptr = argv; + int i; + struct stat st; + + /* + * The code that sets up the pipe requires that file descriptors 0,1,2 + * are already open. All kinds of mysterious things will happen if that + * is not the case. The following loops makes sure that descriptors 0,1,2 + * are set up properly. + */ + + for (i = 0; i < 3; i++) { + if (fstat(i, &st) == -1 && open("/dev/null", 2) != i) { + perror("open /dev/null"); + exit(1); + } + } + + /* + * With most UNIX implementations, the second non-option argument to + * /lib/cpp specifies the output file. If an output file other than + * stdout is specified, we must force /lib/cpp to write to stdout, and we + * must redirect our own standard output to the specified output file. + */ + +#define IS_OPTION(cp) ((cp)[0] == '-' && (cp)[1] != 0) + + /* Skip to first non-option argument, if any. */ + + while (*++cpptr && IS_OPTION(*cpptr)) + /* void */ ; + + /* + * Assume that the first non-option argument is the input file name. The + * next argument could be the output destination or an option (System V + * Release 2 /lib/cpp gets the options *after* the file arguments). + */ + + if (*cpptr && *++cpptr && **cpptr != '-') { + + /* + * The first non-option argument is followed by another argument that + * is not an option ("-stuff") or a hyphen ("-"). Redirect our own + * standard output before we clobber the file name. + */ + + if (freopen(*cpptr, "w", stdout) == 0) { + perror(*cpptr); + exit(1); + } + /* Clobber the file name argument so that /lib/cpp writes to stdout */ + + *cpptr = "-"; + } + /* Set up the pipe that connects /lib/cpp to our standard input. */ + + if (pipe(pipefds)) { + perror("pipe"); + exit(1); + } + switch (pid = fork()) { + case -1: /* error */ + perror("fork"); + exit(1); + /* NOTREACHED */ + case 0: /* child */ + (void) close(pipefds[0]); /* close reading end */ + (void) close(1); /* connect stdout to pipe */ + if (dup(pipefds[1]) != 1) + fatal("dup() problem"); + (void) close(pipefds[1]); /* close redundant fd */ + (void) execv(PIPE_THROUGH_CPP, argv); + perror(PIPE_THROUGH_CPP); + exit(1); + /* NOTREACHED */ + default: /* parent */ + (void) close(pipefds[1]); /* close writing end */ + (void) close(0); /* connect stdin to pipe */ + if (dup(pipefds[0]) != 0) + fatal("dup() problem"); + close(pipefds[0]); /* close redundant fd */ + return (pid); + } +} + +#endif + +/* show_arg_names - display function argument names */ + +static void show_arg_names(t) +register struct token *t; +{ + register struct token *s; + + /* Do argument names, but suppress void and rewrite trailing ... */ + + if (LAST_ARG_AND_EQUAL(t->head, VOID_ARG)) { + show_empty_list(t); /* no arguments */ + } else { + for (s = t->head; s; s = s->next) { /* foreach argument... */ + if (LAST_ARG_AND_EQUAL(s, "...")) { +#ifdef _VA_ALIST_ /* see ./stdarg.h */ + tok_show_ch(s); /* ',' */ + put_str(_VA_ALIST_); /* varargs magic */ +#endif + } else { + tok_show_ch(s); /* '(' or ',' or ')' */ + show_arg_name(s); /* extract argument name */ + } + } + } +} + +/* show_arg_types - display function argument types */ + +static void show_arg_types(t) +register struct token *t; +{ + register struct token *s; + + /* Do argument types, but suppress void and trailing ... */ + + if (!LAST_ARG_AND_EQUAL(t->head, VOID_ARG)) { + for (s = t->head; s; s = s->next) { /* foreach argument... */ + if (LAST_ARG_AND_EQUAL(s, "...")) { +#ifdef _VA_DCL_ /* see ./stdarg.h */ + put_str(_VA_DCL_); /* varargs magic */ + put_nl(); /* make output look nicer */ +#endif + } else { + if (s->head != s->tail) { /* really new-style argument? */ + show_type(s); /* rewrite type info */ + put_ch(';'); + put_nl(); /* make output look nicer */ + } + } + } + } +} + +/* header_flush - rewrite new-style function heading to old style */ + +static void header_flush(t) +register struct token *t; +{ + show_arg_names(t); /* show argument names */ + put_nl(); /* make output look nicer */ + show_arg_types(t); /* show argument types */ + tok_free(t); /* discard token */ +} + +/* fpf_header_names - define func returning ptr to func, no argument types */ + +static void fpf_header_names(list) +struct token *list; +{ + register struct token *s; + register struct token *p; + + /* + * Recurse until we find the argument list. Account for the rare case + * that list is a comma-separated list (which should be a syntax error). + * Display old-style fuction argument names. + */ + + for (s = list->head; s; s = s->next) { + tok_show_ch(s); /* '(' or ',' or ')' */ + for (p = s->head; p; p = p->next) { + if (p->tokno == TOK_LIST) { + if (IS_FUNC_PTR_TYPE(p)) { /* recurse */ + fpf_header_names(p); + show_empty_list(p = p->next); + } else { /* display argument names */ + show_arg_names(p); + } + } else { /* pass through other stuff */ + tok_show(p); + } + } + } +} + +/* fpf_header_types - define func returning ptr to func, argument types only */ + +static void fpf_header_types(list) +struct token *list; +{ + register struct token *s; + register struct token *p; + + /* + * Recurse until we find the argument list. Account for the rare case + * that list is a comma-separated list (which should be a syntax error). + * Display old-style function argument types. + */ + + for (s = list->head; s; s = s->next) { + for (p = s->head; p; p = p->next) { + if (p->tokno == TOK_LIST) { + if (IS_FUNC_PTR_TYPE(p)) { /* recurse */ + fpf_header_types(p); + p = p->next; + } else { /* display argument types */ + show_arg_types(p); + } + } + } + } +} + +/* fpf_header - define function returning pointer to function */ + +static void fpf_header(l1, l2) +struct token *l1; +struct token *l2; +{ + fpf_header_names(l1); /* strip argument types */ + show_empty_list(l2); /* strip prototype */ + put_nl(); /* nicer output */ + fpf_header_types(l1); /* show argument types */ +} + +/* skip_enclosed - skip over enclosed tokens */ + +static struct token *skip_enclosed(p, stop) +register struct token *p; +register int stop; +{ + register int start = p->tokno; + + /* Always return a pointer to the last processed token, never NULL. */ + + while (p->next) { + p = p->next; + if (p->tokno == start) { + p = skip_enclosed(p, stop); /* recurse */ + } else if (p->tokno == stop) { + break; /* done */ + } + } + return (p); +} + +/* show_arg_name - extract argument name from argument type info */ + +static void show_arg_name(s) +register struct token *s; +{ + if (s->head) { + register struct token *p; + register struct token *t = 0; + + /* Find the last interesting item. */ + + for (p = s->head; p; p = p->next) { + if (p->tokno == TOK_WORD) { + t = p; /* remember last word */ + } else if (p->tokno == '{') { + p = skip_enclosed(p, '}'); /* skip structured stuff */ + } else if (p->tokno == '[') { + break; /* dimension may be a macro */ + } else if (IS_FUNC_PTR_TYPE(p)) { + t = p; /* or function pointer */ + p = p->next; + } + } + + /* Extract argument name from last interesting item. */ + + if (t) { + if (t->tokno == TOK_LIST) + show_arg_name(t->head); /* function pointer, recurse */ + else + tok_show(t); /* print last word */ + } + } +} + +/* show_type - rewrite type to old-style syntax */ + +static void show_type(s) +register struct token *s; +{ + register struct token *p; + + /* + * Rewrite (*stuff)(args) to (*stuff)(). Rewrite word(args) to word(), + * but only if the word was preceded by a word, '*' or '}'. Leave + * anything else alone. + */ + + for (p = s->head; p; p = p->next) { + if (IS_FUNC_PTR_TYPE(p)) { + p = show_func_ptr_type(p, p->next); /* function pointer type */ + } else { + register struct token *q; + register struct token *r; + + tok_show(p); /* other */ + if ((p->tokno == TOK_WORD || p->tokno == '*' || p->tokno == '}') + && (q = p->next) && q->tokno == TOK_WORD + && (r = q->next) && r->tokno == TOK_LIST) { + tok_show(q); /* show name */ + show_empty_list(p = r); /* strip args */ + } + } + } +} + +/* show_func_ptr_type - display function_pointer type using old-style syntax */ + +static struct token *show_func_ptr_type(t1, t2) +struct token *t1; +struct token *t2; +{ + register struct token *s; + + /* + * Rewrite (list1) (list2) to (list1) (). Account for the rare case that + * (list1) is a comma-separated list. That should be an error, but we do + * not want to waste any information. + */ + + for (s = t1->head; s; s = s->next) { + tok_show_ch(s); /* '(' or ',' or ')' */ + show_type(s); /* recurse */ + } + show_empty_list(t2); + return (t2); +} + +/* show_empty_list - display opening and closing parentheses (if available) */ + +static void show_empty_list(t) +register struct token *t; +{ + tok_show_ch(t->head); /* opening paren */ + if (t->tail->tokno == ')') + tok_show_ch(t->tail); /* closing paren */ +} + +/* show_struct_type - display structured type, rewrite function-pointer types */ + +static struct token *show_struct_type(p) +register struct token *p; +{ + tok_show(p); /* opening brace */ + + while (p->next) { /* XXX cannot return 0 */ + p = p->next; + if (IS_FUNC_PTR_TYPE(p)) { + p = show_func_ptr_type(p, p->next); /* function-pointer member */ + } else if (p->tokno == '{') { + p = show_struct_type(p); /* recurse */ + } else { + tok_show(p); /* other */ + if (p->tokno == '}') { + return (p); /* done */ + } + } + } + DPRINTF("/* missing '}' */"); + return (p); +} + +/* is_func_ptr_cast - recognize function-pointer type cast */ + +static int is_func_ptr_cast(t) +register struct token *t; +{ + register struct token *p; + + /* + * Examine superficial structure. Require (list1) (list2). Require that + * list1 begins with a star. + */ + + if (!IS_FUNC_PTR_TYPE(t)) + return (0); + + /* + * Make sure that there is no name in (list1). Do not worry about + * unexpected tokens, because the compiler will complain anyway. + */ + + for (p = t->head->head; p; p = p->next) { + switch (p->tokno) { + case TOK_LIST: /* recurse */ + return (is_func_ptr_cast(p)); + case TOK_WORD: /* name in list */ + return (0); + case '[': + return (1); /* dimension may be a macro */ + } + } + return (1); /* no name found */ +} + +/* check_cast - display ()-delimited, comma-separated list */ + +static void check_cast(t) +struct token *t; +{ + register struct token *s; + register struct token *p; + + /* + * Rewrite function-pointer types and function-pointer casts. Do not + * blindly rewrite (*list1)(list2) to (*list1)(). Function argument lists + * are about the only thing we can discard without provoking diagnostics + * from the compiler. + */ + + for (s = t->head; s; s = s->next) { + tok_show_ch(s); /* '(' or ',' or ')' */ + for (p = s->head; p; p = p->next) { + switch (p->tokno) { + case TOK_LIST: + if (is_func_ptr_cast(p)) { /* not: IS_FUNC_PTR_TYPE(p) */ + p = show_func_ptr_type(p, p->next); + } else { + check_cast(p); /* recurse */ + } + break; + case '{': + p = show_struct_type(p); /* rewrite func. ptr. types */ + break; + default: + tok_show(p); + break; + } + } + } +} + +/* block_dcls - on the fly rewrite decls/initializers at start of block */ + +static void block_dcls() +{ + register struct token *t; + + /* + * Away from the top level, a declaration should be preceded by type or + * storage-class information. That is why inside blocks, structs and + * unions we insist on reading one word before passing the _next_ token + * to the dcl_flush() function. + * + * Struct and union declarations look the same everywhere: we make an + * exception for these more regular constructs and pass the "struct" and + * "union" tokens to the type_dcl() function. + */ + + while (t = tok_class()) { + switch (t->tokno) { + case TOK_WSPACE: /* preserve white space */ + case '\n': /* preserve line count */ + tok_flush(t); + break; + case TOK_WORD: /* type declarations? */ + tok_flush(t); /* advance to next token */ + t = tok_class(); /* null return is ok */ + /* FALLTRHOUGH */ + case TOK_COMPOSITE: /* struct or union */ + if ((t = dcl_flush(t)) == 0) + break; + /* FALLTRHOUGH */ + default: /* end of declarations */ + DPRINTF("/* end dcls */"); + /* FALLTRHOUGH */ + case '}': /* end of block */ + tok_unget(t); + return; + } + } +} + +/* block_flush - rewrite struct, union or statement block on the fly */ + +static void block_flush(t) +register struct token *t; +{ + static int count = 0; + + tok_flush(t); + DPRINTF("/*%d*/", ++count); + + /* + * Rewrite function pointer types in declarations and function pointer + * casts in initializers at start of block. + */ + + block_dcls(); + + /* Remainder of block: only rewrite function pointer casts. */ + + while (t = tok_class()) { + if (t->tokno == TOK_LIST) { + check_cast_flush(t); + } else if (t->tokno == '{') { + block_flush(t); + } else { + tok_flush(t); + if (t->tokno == '}') { + DPRINTF("/*%d*/", count--); + return; + } + } + } + DPRINTF("/* missing '}' */"); +} + +/* pair_flush - on the fly rewrite casts in grouped stuff */ + +static void pair_flush(t, start, stop) +register struct token *t; +register int start; +register int stop; +{ + tok_flush(t); + + while (t = tok_class()) { + if (t->tokno == start) { /* recurse */ + pair_flush(t, start, stop); + } else if (t->tokno == TOK_LIST) { /* expression or cast */ + check_cast_flush(t); + } else { /* other, copy */ + tok_flush(t); + if (t->tokno == stop) { /* done */ + return; + } + } + } + DPRINTF("/* missing '%c' */", stop); +} + +/* initializer - on the fly rewrite casts in initializer */ + +static void initializer() +{ + register struct token *t; + + while (t = tok_class()) { + switch (t->tokno) { + case ',': /* list separator */ + case ';': /* list terminator */ + tok_unget(t); + return; + case TOK_LIST: /* expression or cast */ + check_cast_flush(t); + break; + case '[': /* array subscript, may nest */ + pair_flush(t, '[', ']'); + break; + case '{': /* structured data, may nest */ + pair_flush(t, '{', '}'); + break; + default: /* other, just copy */ + tok_flush(t); + break; + } + } +} + +/* func_ptr_dcl_flush - rewrite function pointer stuff */ + +static struct token *func_ptr_dcl_flush(list) +register struct token *list; +{ + register struct token *t; + register struct token *t2; + + /* + * Ignore blanks and newlines because we are too lazy to maintain more + * than one token worth of lookahead. The output routines will regenerate + * discarded newline tokens. + */ + + while (t = tok_class()) { + switch (t->tokno) { + case TOK_WSPACE: + case '\n': + tok_free(t); + break; + case TOK_LIST: + /* Function pointer or function returning pointer to function. */ + while ((t2 = tok_class()) /* skip blanks etc. */ + &&(t2->tokno == TOK_WSPACE || t2->tokno == '\n')) + tok_free(t2); + switch (t2 ? t2->tokno : 0) { + case '{': /* function heading (new) */ + fpf_header(list, t); + break; + case TOK_WORD: /* function heading (old) */ + tok_show(list); + tok_show(t); + break; + default: /* func pointer type */ + (void) show_func_ptr_type(list, t); + break; + } + tok_free(list); + tok_free(t); + if (t2) + tok_unget(t2); + return (0); + default: /* not a declaration */ + tok_unget(t); + return (list); + } + } + + /* Hit EOF; must be mistake, but do not waste any information. */ + + return (list); +} + +/* function_dcl_flush - rewrite function { heading, type declaration } */ + +static struct token *function_dcl_flush(list) +register struct token *list; +{ + register struct token *t; + + /* + * Ignore blanks and newlines because we are too lazy to maintain more + * than one token worth of lookahead. The output routines will regenerate + * ignored newline tokens. + */ + + while (t = tok_class()) { + switch (t->tokno) { + case TOK_WSPACE: + case '\n': + tok_free(t); + break; + case '{': + /* Function heading: word (list) { -> old style heading */ + header_flush(list); + tok_unget(t); + return (0); + case TOK_WORD: + /* Old-style function heading: word (list) word... */ + tok_flush(list); + tok_unget(t); + return (0); + case TOK_LIST: + /* Function pointer: word (list1) (list2) -> word (list1) () */ + tok_flush(list); + show_empty_list(t); + tok_free(t); + return (0); + case ',': + case ';': + /* Function type declaration: word (list) -> word () */ + show_empty_list(list); + tok_free(list); + tok_unget(t); + return (0); + default: + /* Something else, reject the list. */ + tok_unget(t); + return (list); + } + } + + /* Hit EOF; must be mistake, but do not waste any information. */ + + return (list); +} + +/* dcl_flush - parse declaration on the fly, return rejected token */ + +static struct token *dcl_flush(t) +register struct token *t; +{ + register int got_word; + + /* + * Away from the top level, type or storage-class information is required + * for an (extern or forward) function type declaration or a variable + * declaration. + * + * With our naive word-counting approach, this means that the caller should + * read one word before passing the next token to us. This is how we + * distinguish, for example, function declarations from function calls. + * + * An exception are structs and unions, because they look the same at any + * level. The caller should give is the "struct" or "union" token. + */ + + for (got_word = 0; t; t = tok_class()) { + switch (t->tokno) { + case TOK_WSPACE: /* advance past blanks */ + case '\n': /* advance past newline */ + case '*': /* indirection: keep trying */ + tok_flush(t); + break; + case TOK_WORD: /* word: keep trying */ + case TOK_COMPOSITE: /* struct or union */ + got_word = 1; + tok_flush(t); + break; + default: + + /* + * Function pointer types can be preceded by zero or more words + * (at least one when not at the top level). Other stuff can be + * accepted only after we have seen at least one word (two words + * when not at the top level). See also the above comment on + * structs and unions. + */ + + if (t->tokno == TOK_LIST && LIST_BEGINS_WITH_STAR(t)) { + if (t = func_ptr_dcl_flush(t)) { + return (t); /* reject token */ + } else { + got_word = 1; /* for = and [ and , and ; */ + } + } else if (got_word == 0) { + return (t); /* reject token */ + } else { + switch (t->tokno) { + case TOK_LIST: /* function type */ + if (t = function_dcl_flush(t)) + return (t); /* reject token */ + break; + case '[': /* dimension, does not nest */ + pair_flush(t, '[', ']'); + break; + case '=': /* initializer follows */ + tok_flush(t); + initializer(); /* rewrite casts */ + break; + case '{': /* struct, union, may nest */ + block_flush(t); /* use code for stmt blocks */ + break; + case ',': /* separator: keep trying */ + got_word = 0; + tok_flush(t); + break; + case ';': /* terminator: succeed */ + tok_flush(t); + return (0); + default: /* reject token */ + return (t); + } + } + } + } + return (0); /* hit EOF */ +} diff --git a/build/unproto/varargs.c b/build/unproto/varargs.c new file mode 100644 index 0000000000..4ca56d8155 --- /dev/null +++ b/build/unproto/varargs.c @@ -0,0 +1,32 @@ + /* + * @(#) varargs.c 1.1 91/09/01 23:08:45 + * + * This program can be used to verify that the stdarg.h file is set up + * correctly for your system. If it works, it should print one line with the + * text "stdarg.h works". + */ + +#include +#include "stdarg.h" + +main(int argc, char *argv[]) +{ + varargs_test("%s %s\n", "stdarg.h", "works"); +} + +varargs_test(char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + while (*fmt) { + if (strncmp("%s", fmt, 2) == 0) { + fputs(va_arg(ap, char *), stdout); + fmt += 2; + } else { + putchar(*fmt); + fmt++; + } + } + va_end(ap); +} diff --git a/build/unproto/vstring.c b/build/unproto/vstring.c new file mode 100644 index 0000000000..220bd530fe --- /dev/null +++ b/build/unproto/vstring.c @@ -0,0 +1,122 @@ +/*++ +/* NAME +/* vs_alloc(), VS_ADDCH() +/* SUMMARY +/* auto-resizing string library +/* PACKAGE +/* vstring +/* SYNOPSIS +/* #include "vstring.h" +/* +/* struct vstring *vs_alloc(len) +/* int len; +/* +/* int VS_ADDCH(vs, wp, ch) +/* struct vstring *vs; +/* char *wp; +/* int ch; +/* +/* char *vs_strcpy(vp, dst, src) +/* struct vstring *vp; +/* char *dst; +/* char *src; +/* DESCRIPTION +/* These functions and macros implement a small library for +/* arbitrary-length strings that grow automatically when +/* they fill up. The allocation strategy is such that there +/* will always be place for the terminating null character. +/* +/* vs_alloc() allocates storage for a variable-length string +/* of at least "len" bytes. +/* +/* VS_ADDCH() adds a character to a variable-length string +/* and automagically extends the string if fills up. +/* \fIvs\fP is a pointer to a vstring structure; \fIwp\fP +/* the current write position in the corresponding character +/* array; \fIch\fP the character value to be written. +/* Note that VS_ADDCH() is a macro that evaluates some +/* arguments more than once. +/* +/* vs_strcpy() appends a null-terminated string to a variable-length +/* string. \fIsrc\fP provides the data to be copied; \fIvp\fP is the +/* target, and \fIdst\fP the current write position within the target. +/* The result is null-terminated. The return value is the new write +/* position. +/* DIAGNOSTICS +/* VS_ADDCH() returns zero if it was unable to dynamically +/* resize a string. +/* +/* vs_alloc() returns a null pointer in case of problems. +/* +/* vs_strcpy() returns a null pointer if the request failed. +/* BUGS +/* Auto-resizing may change the address of the string data in +/* a vstring structure. Beware of dangling pointers. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 92/01/15 21:53:06 +/* VERSION/RELEASE +/* 1.3 +/*--*/ + +static char vstring_sccsid[] = "@(#) vstring.c 1.3 92/01/15 21:53:06"; + +/* C library */ + +extern char *malloc(); +extern char *realloc(); + +/* Application-specific stuff */ + +#include "vstring.h" + +/* vs_alloc - initial string allocation */ + +struct vstring *vs_alloc(len) +int len; +{ + register struct vstring *vp; + + if (len < 1 + || (vp = (struct vstring *) malloc(sizeof(struct vstring))) == 0 + || (vp->str = malloc(len)) == 0) + return (0); + vp->last = vp->str + len - 1; + return (vp); +} + +/* vs_realloc - extend string, update write pointer */ + +char *vs_realloc(vp, cp) +register struct vstring *vp; +char *cp; +{ + int where = cp - vp->str; + int len = vp->last - vp->str + 1; + + if ((vp->str = realloc(vp->str, len *= 2)) == 0) + return (0); + vp->last = vp->str + len - 1; + return (vp->str + where); +} + +/* vs_strcpy - copy string */ + +char *vs_strcpy(vp, dst, src) +register struct vstring *vp; +register char *dst; +register char *src; +{ + while (*src) { + if (VS_ADDCH(vp, dst, *src) == 0) + return (0); + src++; + } + *dst = '\0'; + return (dst); +} + diff --git a/build/unproto/vstring.h b/build/unproto/vstring.h new file mode 100644 index 0000000000..c2e1f88a77 --- /dev/null +++ b/build/unproto/vstring.h @@ -0,0 +1,15 @@ +/* @(#) vstring.h 1.2 92/01/15 21:53:19 */ + +struct vstring { + char *str; /* string value */ + char *last; /* last position */ +}; + +extern struct vstring *vs_alloc(); /* initial allocation */ +extern char *vs_realloc(); /* string extension */ +extern char *vs_strcpy(); /* copy string */ + +/* macro to add one character to auto-resized string */ + +#define VS_ADDCH(vs,wp,c) \ + ((wp < (vs)->last || (wp = vs_realloc(vs,wp))) ? (*wp++ = c) : 0) diff --git a/build/version b/build/version new file mode 100644 index 0000000000..eb39e5382f --- /dev/null +++ b/build/version @@ -0,0 +1 @@ +3.3 diff --git a/clients/Make-template b/clients/Make-template new file mode 100644 index 0000000000..76a02d5a26 --- /dev/null +++ b/clients/Make-template @@ -0,0 +1,84 @@ +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# LDAP clients Makefile +# +#----------------------------------------------------------------------------- + +############################################################################ +# # +# You should not have to edit anything below this point # +# # +############################################################################ + +all: FORCE + @echo "making all in `$(PWD)`" + @for i in *; do \ + if [ -d $$i -a $$i != "RCS" ]; then \ + echo; echo " cd $$i; $(MAKE) $(MFLAGS) all"; \ + ( cd $$i; $(MAKE) $(MFLAGS) all ); \ + fi; \ + done + + +# +# rules to install the software +# + +install: FORCE + @echo "making install in `$(PWD)`" + @for i in *; do \ + if [ -d $$i -a $$i != "RCS" ]; then \ + echo; echo " cd $$i; $(MAKE) $(MFLAGS) install"; \ + ( cd $$i; $(MAKE) $(MFLAGS) install ); \ + fi; \ + done + +# +# rules to make clean +# + +clean: FORCE + @echo "making clean in `$(PWD)`" + @for i in *; do \ + if [ -d $$i -a $$i != "RCS" ]; then \ + echo; echo " cd $$i; $(MAKE) $(MFLAGS) clean"; \ + ( cd $$i; $(MAKE) $(MFLAGS) clean ); \ + fi; \ + done + +veryclean: clean + +# +# rules to make depend +# +# + +depend: FORCE + @echo "making depend in `$(PWD)`" + @for i in *; do \ + if [ -d $$i -a $$i != "RCS" ]; then \ + echo; echo " cd $$i; $(MAKE) $(MFLAGS) depend"; \ + ( cd $$i; $(MAKE) $(MFLAGS) depend ); \ + fi; \ + done + +links: + @echo "making links in `$(PWD)`"; \ + for i in .src/*; do \ + if [ -d $$i -a $$i != ".src/RCS" ]; then \ + d=`basename $$i`; \ + ( $(MKDIR) $$d; cd $$d; $(LN) ../.src/$$d .src; \ + $(LN) ../.src/$$d/Make-template . ; \ + $(MAKE) $(MFLAGS) MKDIR="$(MKDIR)" LN="$(LN)" \ + -f Make-template links ) ; \ + fi; \ + done diff --git a/clients/fax500/Make-template b/clients/fax500/Make-template new file mode 100644 index 0000000000..e3b224d772 --- /dev/null +++ b/clients/fax500/Make-template @@ -0,0 +1,87 @@ +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# X.500 ldap fax mailer makefile +# +#----------------------------------------------------------------------------- +LDAPSRC = ../.. +HDIR = $(LDAPSRC)/include +LDIR = $(LDAPSRC)/libraries +VERSIONFILE = $(LDAPSRC)/build/version + +SRCS = rp500.c main.c faxtotpc.c +OBJS = rp500.o main.o faxtotpc.o + +INCLUDES= -I$(HDIR) +DEFINES = $(DEFS) + +CFLAGS = $(INCLUDES) $(DEFINES) $(ACFLAGS) +LIBS = -lldap -llber $(KRBLIBFLAG) $(KRBLIBS) $(ALIBS) + +all: rp500 fax500 + +rp500: rpversion.o + $(CC) $(ALDFLAGS) -o $@ faxtotpc.o rp500.o rpversion.o \ + -L$(LDIR) $(LIBS) + +fax500: fax5version.o + $(CC) $(ALDFLAGS) -o $@ main.o fax5version.o faxtotpc.o \ + -L$(LDIR) $(LIBS) + +rpversion.c: faxtotpc.o rp500.o $(LDIR)/libldap.a + $(RM) $@ + (u=$${USER-root} v=`$(CAT) $(VERSIONFILE)` d=`$(PWD)` h=`$(HOSTNAME)` \ + t=`$(DATE)`; $(SED) -e "s|%WHEN%|$${t}|" \ + -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \ + -e "s|%VERSION%|$${v}|" \ + < Versionrp.c > $@) + +fax5version.c: main.o faxtotpc.o $(LDIR)/libldap.a + $(RM) $@ + (u=$${USER-root} v=`$(CAT) $(VERSIONFILE)` d=`$(PWD)` h=`$(HOSTNAME)` \ + t=`$(DATE)`; $(SED) -e "s|%WHEN%|$${t}|" \ + -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \ + -e "s|%VERSION%|$${v}|" \ + < Version.c > $@ ) + +install: rp500 xrpcomp fax500 FORCE + -$(MKDIR) -p $(ETCDIR) $(BINDIR) + $(INSTALL) $(INSTALLFLAGS) -m 755 rp500 $(ETCDIR) + $(SED) -e 's%ETCDIR%$(ETCDIR)%' xrpcomp > /tmp/xrpcomp.tmp + $(INSTALL) $(INSTALLFLAGS) -m 755 /tmp/xrpcomp.tmp $(BINDIR)/xrpcomp + $(RM) /tmp/xrpcomp.tmp + $(INSTALL) $(INSTALLFLAGS) -m 755 fax500 $(ETCDIR) + +lint: FORCE + $(LINT) $(INCLUDES) $(DEFINES) $(SRCS) + +5lint: FORCE + $(5LINT) $(INCLUDES) $(DEFINES) $(SRCS) + +clean: FORCE + $(RM) *.o core a.out rpversion.c fax5version.c rp500 fax500 + +depend: FORCE + $(MKDEP) $(INCLUDES) $(DEFINES) $(SRCS) + +links: + @$(LN) .src/README .src/xrpcomp .src/*.[ch] . + +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +rp500.o: rp500.c ../../include/ldapconfig.h ../../include/lber.h +rp500.o: ../../include/ldap.h +main.o: main.c ../../include/ldapconfig.h ../../include/portable.h +main.o: ../../include/lber.h ../../include/ldap.h +faxtotpc.o: faxtotpc.c + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/clients/fax500/README b/clients/fax500/README new file mode 100644 index 0000000000..5b0e1a35dc --- /dev/null +++ b/clients/fax500/README @@ -0,0 +1,104 @@ +README file for fax500 + +xrpcomp +------- + +This directory contains a modified version of the rpcomp program, used +with the Internet remote-printing experiment. More info on the experiment +can be found in /mrose/tpc on ftp.ics.uci.edu. + +The xrpcomp program (it's a shell script) is like rpcomp, except that it +will look in X.500 if no fax recipients are found in the .rpdb file. +It still uses .rpdb to extract the originator information. + +There are a couple of things in rp500.c you will want to tailor to use +xrpcomp at your site: + + DAPUSER This is the user the rp500 program, called from + xrpcomp will bind to the directory as. It can + be set to NULL. + + DEFAULT_BASE This is the search base rp500 will use when looking + in the directory for fax recipients. + + DEFAULT_FILTERCONF + Where to find the ldapfilter.conf file. Should + make setting this automatic, but for now... + + PHONE_PREFIX The prefix of phones in your local area. If + rp500 finds a fax number in the directory that is + not fully qualified, it will append as many of + these digits as necessary to make it fully + qualified. NB it assumes US-format numbers. + + DEFAULT_LDAPHOST + The host running the default ldap server to + contact. + +Things to note: + +The rp500 program knows a little about the US phone number format, in +an attempt to deal with (evil) people who have not put fully qualified +international format (e.g. +1 ... ) phone numbers in their entry. If +your users do not have US-format phone numbers, you'll need to take a +look at the fax2email() routine in rp500.c and change it around a bit. + +7/30/93 -- Tim + + +fax500 +------ + +This directory also contains the fax500 program. fax500 is just like +mail500, except that it looks up the facsimileTelephoneNumber +attribute, constructs an appropriate "remote-printer@blah.tpc.int" +address, and send the mail there. For example, the facsimile number +"+1 313 555 1212" corresponds to the address +"remote-printer@2.1.2.1.5.5.5.3.1.3.1.tpc.int." For a complete +explanation of the Internet remote-printing experiment, look in +/mrose/tpc on ftp.ics.uci.edu, or send mail to tpc-faq@town.hall.org. + +The general idea is that you can set things up so that mail sent to +"user@fax.domain" will get printed on the user's fax machine, if +they've entered a fax number in their X.500 entry. + +NOTE: you will need to modify faxtotpc.c if you have any "abbreviated" +phone number capabilities. For example, our telephone switches allow +you to dial only the last 5 digits of campus telephone numbers. People, +therefore, tend to list the last 5 digits of their fax numbers. The +routine "munge_phone()" takes care of fixing up abbreviated phone +numbers. You may need to write your own code. + +fax500 is not yet complete. In particular, the following work still needs +to be done: + +- If the group entry itself has a fax number, don't send to all the members' + individual fax numbers. Instead, just send to the group's fax number. +- The -h flag for fax500 defines both the host name and the search base. + This causes problems because the host name we want is "fax.umich.edu" + but we need to search "umich.edu." The workaround is to add an + Associated Domain corresponding to the domain you want for your fax + service to each X.500 group which is to be accessible. +- We're working toward mail500 and fax500 being the same binary. Depending + on what argv[0] is, you'll get different behavior. Although this + binary should work just like mail500 if you name it "mail500" it's + not yet been tested. +- fax500 currently assumes that incoming messages are plain text, and + therefore constructs a destination address like + "remote-printer.user_name@2.1.2.1.5.5.5.3.1.3.1.tpc.int". If + the message is already MIME-compliant with an "application/remote-printing" + content type, we lose, since the remote-printing software assumes + that anything other than "remote-printer" on ther lhs of the address + means the message is plain text. Not sure about the solution to this. +- Regarding group support - typically, when we collect all the fax numbers + for a group, we'll end up either with (a) people who haven't registered + fax numbers, or (b) "email-only" group members who do not have entries + in X.500 (they only have an email address associated with the group). + The question is: what do you do with faxes for these folks? You could + (1) bounce to the sender (current behavior) or you could (2) send + email to the members with no fax numbers, informing them that someone + tried to send them a fax. I tend to prefer solution (2) for case (a), + and solution (1) for case (b). +- A configuration file-driven "munge_phone()" would be nice. + +8/23/93 - Gordon diff --git a/clients/fax500/Version.c b/clients/fax500/Version.c new file mode 100644 index 0000000000..8bc6c81799 --- /dev/null +++ b/clients/fax500/Version.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 1993 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. + */ + +char Version[] = " fax500 v%VERSION% (%WHEN%)\n\t%WHOANDWHERE%\n"; diff --git a/clients/fax500/Versionrp.c b/clients/fax500/Versionrp.c new file mode 100644 index 0000000000..75d8dd79a7 --- /dev/null +++ b/clients/fax500/Versionrp.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 1993 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. + */ + +char Version[] = " rp500 v%VERSION% (%WHEN%)\n\t%WHOANDWHERE%\n"; diff --git a/clients/fax500/faxtotpc.c b/clients/fax500/faxtotpc.c new file mode 100644 index 0000000000..d4631b43e6 --- /dev/null +++ b/clients/fax500/faxtotpc.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 1993 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. + * + * + * Routines for parsing the facsimileTelephoneNumber field out of + * an X.500 entry and converting it to a "tpc.int" domain name. + * + * char *faxtotpc(str) + * char *str; + * + * faxtotpc() returns a pointer to a string allocated with malloc(3). + */ + +#include +#include +#include +#include + +#ifdef ultrix +extern char *strdup(); +#endif + + +#define TPCDOMAIN "tpc.int" + +/* + * Remove everything from 'str' which is not a digit + */ +void strip_nonnum(str) +char *str; +{ + char *p, *q; + p = q = str; + for (;;) { + if (*p == '\0') { + *q = *p; + return; + } + + if (isdigit((u_char) *p)) { + *q = *p; + p++; + q++; + } else { + p++; + } + } +} + + + +/* + * Remove anything of the form (blah) where + * "blah" contains a non-numeric character. + */ +char *remove_parens(ibuf, obuf) +char *ibuf; +char *obuf; +{ + char *p = ibuf; + char *q = obuf; + + while (*p != '\0') { + char *s; + char *t; + if (*p == '(') { + /* look for a closing paren */ + if (( s = strchr(p, ')')) != NULL) { + /* Check the string between p and s */ + /* for non-numeric characters */ + t = p + 1; + while (t < s) { + if (!isdigit((u_char) *t)) { + /* garbage, delete */ + p = s + 1; + t = p; + break; + } + t++; + } + /* when we get here, p points to the first */ + /* thing we want to keep, t to the last. */ + strncpy(q, p, t - p); + q += t - p; + p = t; + } else { + /* no closing paren, what to do? keep it */ + *q = *p; + p++; + q++; + } + } else { + /* not a paren - copy out */ + *q = *p; + p++; + q++; + } + } + *q = '\0'; /* terminate output string */ + return(obuf); +} + + + + +/* + * Apply local fixups to phone numbers here. Replace this routine + * with code to expand common "abbreviations" for phone numbers. For + * example, on the U-M campus, it's only necessary to dial the last + * 5 digits of the telephone number, and hence people here tend to + * give only the last 5 digits of their fax numbers. + * + * Local U-M mods: + * If exactly 5 digits were provided, assume it's a campus + * phone number and prepend "1313nm" where "mn" are computed + * according to the following: + * first digit of + * 5-digit "Local" + * phone mn + * ----- -- + * 3 76 e.g. "31234" -> "7631234" + * 4 76 + * 7 74 + * 6 93 + * 8 99 + */ +char *munge_phone(ibuf, obuf) +char *ibuf; +char *obuf; +{ +#define UMAREACODE "1313" + + char prefix[3]; + + if (strlen(ibuf) == 7) { + /* Assume local number w/o area code */ + sprintf(obuf, "%s%s", UMAREACODE, ibuf); + return(obuf); + } + if (strlen(ibuf) == 10) { + /* Assume local number with area code */ + sprintf(obuf, "%s%s", "1", ibuf); + return(obuf); + } + if (strlen(ibuf) != 5) { + /* Not 5 digits - leave alone */ + strcpy(obuf, ibuf); + return(obuf); + } + + switch (ibuf[0]) { + case '3' : + case '4' : strcpy(prefix, "76"); + break; + case '7' : strcpy(prefix, "74"); + break; + case '6' : strcpy(prefix, "93"); + break; + case '8' : strcpy(prefix, "99"); + break; + default : /* Unknown, leave alone */ + strcpy(obuf, ibuf); + return(obuf); + } + sprintf(obuf, "%s%s%s", UMAREACODE, prefix, ibuf); + return(obuf); +} + + + + + + + + +/* + * Convert string to "tpc.int" domain name. + */ +char *faxtotpc(phone, userinfo) +char *phone; +char *userinfo; +{ + char *p; + char *q; + char ibuf[255]; + char obuf[255]; + + /* nuke spaces */ + strcpy(ibuf, phone); + for (p = ibuf, q = obuf; *p != '\0'; p++) { + if (*p != ' ') { + *q = *p; + q++; + } + } + *q = '\0'; + strcpy(ibuf, obuf); + + remove_parens(ibuf, obuf); + strcpy(ibuf, obuf); + + /* Look for "+" - if followed by a number, + assume it's an international number and leave + it alone. + */ + if ((p = strchr(ibuf, '+')) != NULL) { + if (isdigit((u_char) *(p + 1))) { + /* strip any non-digits */ + strip_nonnum(ibuf); + } + } else { + strip_nonnum(ibuf); + + /* Apply local munges */ + munge_phone(ibuf, obuf); + strcpy(ibuf, obuf); + } + + /* Convert string of form abcd to remote-printer@d.c.b.a.tpc.int */ + q = obuf; + for (p = ibuf + strlen(ibuf) - 1; p >= ibuf; p--) { + *q++ = *p; + *q++ = '.'; + } + *q = '\0'; + strcpy(ibuf, obuf); + strcpy(obuf, "remote-printer"); + + /* include userinfo if present */ + if (userinfo != NULL && strlen(userinfo)) { + strcat(obuf, "."); + strcat(obuf, userinfo); + } + strcat(obuf, "@"); + strcat(obuf, ibuf); /* tack on reversed phone number */ + strcat(obuf, TPCDOMAIN); /* tack on domain name */ + p = strdup(obuf); + return(p); + +} diff --git a/clients/fax500/main.c b/clients/fax500/main.c new file mode 100644 index 0000000000..7481d4980e --- /dev/null +++ b/clients/fax500/main.c @@ -0,0 +1,1499 @@ +/* + * Copyright (c) 1990 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "portable.h" + +#include "lber.h" +#include "ldap.h" + +#define USER 0 +#define GROUP_ERRORS 1 +#define GROUP_REQUEST 2 +#define GROUP_MEMBERS 3 + +#define ERRORS "errors" +#define REQUEST "request" +#define MEMBERS "members" + +LDAP *ld; +char *errorsfrom = NULL; +char *mailfrom = NULL; +char *host = NULL; +int hostlen = 0; +char *faxtotpc(); + +int identity; +#define MAIL500 1 +#define FAX500 2 + +typedef struct errs { + int e_code; +#define E_USERUNKNOWN 1 +#define E_AMBIGUOUS 2 +#define E_NOEMAIL 3 +#define E_NOREQUEST 4 +#define E_NOERRORS 5 +#define E_BADMEMBER 6 +#define E_JOINMEMBERNOEMAIL 7 +#define E_MEMBERNOEMAIL 8 +#define E_NOFAXNUM 9 +#define E_JOINMEMBERNOFAXNUM 10 +#define E_MEMBERNOFAXNUM 11 +#define E_FAXTOEMAILMBR 12 + + char *e_addr; + LDAPMessage *e_msg; +} Error; + +typedef struct groupto { + char *g_dn; + char *g_errorsto; + char **g_members; +} Group; + +typedef struct baseinfo { + char *b_dn; /* dn to start searching at */ + char b_rdnpref; /* give rdn's preference when searching? */ + char *b_filter[3]; /* filter to apply - name substituted for %s */ + /* (up to three of them) */ +} Base; + +Base base[] = + { "ou=People, o=University of Michigan, c=US", 0, + "uid=%s", "cn=%s", NULL, + "ou=System Groups, ou=Groups, o=University of Michigan, c=US", 1, + "(&(cn=%s)(associatedDomain=%h))", NULL, NULL, + "ou=User Groups, ou=Groups, o=University of Michigan, c=US", 1, + "(&(cn=%s)(associatedDomain=%h))", NULL, NULL, + NULL + }; + +char *sendmailargs[] = { FAX_SENDMAIL, "-oMrX.500", "-odi", "-oi", "-f", NULL, NULL }; + +static char *attrs[] = { "objectClass", "title", "postaladdress", + "telephoneNumber", "mail", "description", + "errorsTo", "rfc822ErrorsTo", "requestsTo", + "rfc822RequestsTo", "joinable", "cn", "member", + "facsimileTelephoneNumber", NULL }; + +static do_address(); +static do_group(); +static do_group_members(); +static send_message(); +static send_errors(); +static do_noemailorfax(); +static do_ambiguous(); +static add_to(); +static isgroup(); +static add_error(); +static add_group(); +static unbind_and_exit(); +static group_loop(); +static send_group(); +static has_attributes(); +static char **get_attributes_mail_dn(); +static char *canonical(); + +main (argc, argv) +int argc; +char **argv; +{ + char *myname; + char **tolist; + Error *errlist; + Group *togroups; + int numto, ngroups, numerr, nargs; + int i, j; + FILE *fp; + extern int optind, errno; + extern char *optarg; + + while ( (i = getopt( argc, argv, "f:h:m:" )) != EOF ) { + switch( i ) { + case 'f': /* who it's from & where errors should go */ + mailfrom = strdup( optarg ); + for ( j = 0; sendmailargs[j] != NULL; j++ ) { + if ( strcmp( sendmailargs[j], "-f" ) == 0 ) { + sendmailargs[j+1] = mailfrom; + break; + } + } + break; + + case 'h': /* hostname */ + host = strdup( optarg ); + hostlen = strlen(host); + break; + + /* mailer-daemon address - who we should */ + case 'm': /* say errors come from */ + errorsfrom = strdup( optarg ); + break; + + default: + syslog( LOG_ALERT, "unknown option" ); + break; + } + } + + if ( (myname = strrchr( argv[0], '/' )) == NULL ) + myname = strdup( argv[0] ); + else + myname = strdup( myname + 1 ); + if (!strcmp(myname, "mail500")) { + identity = MAIL500; + } else if (!strcmp(myname, "fax500")) { + identity = FAX500; + } else { + /* I give up, I must be mail500 */ + identity = MAIL500; + } + +#ifdef LOG_MAIL + openlog( myname, OPENLOG_OPTIONS, LOG_MAIL ); +#else + openlog( myname, OPENLOG_OPTIONS ); +#endif + + if ( mailfrom == NULL ) { + syslog( LOG_ALERT, "required argument -f not present" ); + exit( EX_TEMPFAIL ); + } + if ( errorsfrom == NULL ) { + syslog( LOG_ALERT, "required argument -m not present" ); + exit( EX_TEMPFAIL ); + } + if ( host == NULL ) { + syslog( LOG_ALERT, "required argument -h not present" ); + exit( EX_TEMPFAIL ); + } + + if ( connect_to_x500() != 0 ) + exit( EX_TEMPFAIL ); + + setuid( geteuid() ); +/* +{ + char buf[1024]; + int i; + + strcpy( buf, argv[0] ); + for ( i = 1; i < argc; i++ ) { + strcat( buf, " " ); + strcat( buf, argv[i] ); + } + + syslog( LOG_ALERT, "args: (%s)", buf ); +} +*/ + numto = 0; + add_to( &tolist, &numto, sendmailargs ); + nargs = numto; + ngroups = numerr = 0; + togroups = NULL; + errlist = NULL; + for ( i = optind; i < argc; i++ ) { + char *s; + int type; + + for ( j = 0; argv[i][j] != '\0'; j++ ) { + if ( argv[i][j] == '.' || argv[i][j] == '_' ) + argv[i][j] = ' '; + } + + type = USER; + if ( (s = strrchr( argv[i], '-' )) != NULL ) { + s++; + + if ( strcmp( s, ERRORS ) == 0 ) { + type = GROUP_ERRORS; + *(--s) = '\0'; + } else if ( strcmp( s, REQUEST ) == 0 ) { + type = GROUP_REQUEST; + *(--s) = '\0'; + } else if ( strcmp( s, MEMBERS ) == 0 ) { + type = GROUP_MEMBERS; + *(--s) = '\0'; + } + } + + do_address( argv[i], &tolist, &numto, &togroups, &ngroups, + &errlist, &numerr, type ); + } + + /* + * If we have both errors and successful deliveries to make or if + * if there are any groups to deliver to, we basically need to read + * the message twice. So, we have to put it in a tmp file. + */ + + if ( numerr > 0 && numto > nargs || ngroups > 0 ) { + int fd; + char buf[BUFSIZ]; + + umask( 077 ); + if ( (fp = tmpfile()) == NULL ) { + syslog( LOG_ALERT, "could not open tmp file" ); + unbind_and_exit( EX_TEMPFAIL ); + } + + /* copy the message to a temp file */ + while ( fgets( buf, sizeof(buf), stdin ) != NULL ) { + if ( fputs( buf, fp ) == EOF ) { + syslog( LOG_ALERT, "error writing tmpfile" ); + unbind_and_exit( EX_TEMPFAIL ); + } + } + + if ( dup2( fileno( fp ), 0 ) == -1 ) { + syslog( LOG_ALERT, "could not dup2 tmpfile" ); + unbind_and_exit( EX_TEMPFAIL ); + } + + fclose( fp ); + } + + /* deal with errors */ + if ( numerr > 0 ) { + (void) rewind( stdin ); + send_errors( errlist, numerr ); + } + + (void) ldap_unbind( ld ); + + /* send to groups with errorsTo */ + if ( ngroups > 0 ) { + (void) rewind( stdin ); + send_group( togroups, ngroups ); + } + + /* send to expanded aliases and groups w/o errorsTo */ + if ( numto > nargs ) { + (void) rewind( stdin ); + send_message( tolist ); + } + + return( EX_OK ); +} + +connect_to_x500() +{ + if ( (ld = ldap_open( LDAPHOST, LDAP_PORT )) == NULL ) { + syslog( LOG_ALERT, "ldap_open failed" ); + return( -1 ); + } + ld->ld_sizelimit = FAX_MAXAMBIGUOUS; + ld->ld_deref = LDAP_DEREF_ALWAYS; + + if ( ldap_simple_bind_s( ld, FAX_BINDDN, NULL ) != LDAP_SUCCESS ) { + syslog( LOG_ALERT, "ldap_simple_bind_s failed" ); + return( -1 ); + } + + return( 0 ); +} + + +static +do_address( name, to, nto, togroups, ngroups, err, nerr, type ) + char *name; + char ***to; + int *nto; + Group **togroups; + int *ngroups; + Error **err; + int *nerr; + int type; +{ + int rc, b, f, match; + LDAPMessage *e, *res; + struct timeval timeout; + char *dn; + char filter[1024]; + char **mail; + char **fax; + + /* + * Look up the name in X.500, add the appropriate addresses found + * to the to list, or to the err list in case of error. Groups are + * handled by the do_group routine, individuals are handled here. + * When looking up name, we follow the bases hierarchy, looking + * in base[0] first, then base[1], etc. For each base, there is + * a set of search filters to try, in order. If something goes + * wrong here trying to contact X.500, we exit with EX_TEMPFAIL. + * If the b_rdnpref flag is set, then we give preference to entries + * that matched name because it's their rdn, otherwise not. + */ + + timeout.tv_sec = FAX_TIMEOUT; + timeout.tv_usec = 0; + for ( b = 0, match = 0; !match && base[b].b_dn != NULL; b++ ) { + for ( f = 0; base[b].b_filter[f] != NULL; f++ ) { + char *format, *p, *argv[3]; + int argc; + + for ( argc = 0; argc < 3; argc++ ) { + argv[argc] = NULL; + } + + format = strdup( base[b].b_filter[f] ); + for ( argc = 0, p = format; *p; p++ ) { + if ( *p == '%' ) { + switch ( *++p ) { + case 's': /* %s is the name */ + argv[argc] = name; + break; + + case 'h': /* %h is the host */ + *p = 's'; + argv[argc] = host; + break; + + default: + syslog( LOG_ALERT, + "unknown format %c", *p ); + break; + } + + argc++; + } + } + + /* three names ought to do... */ + sprintf( filter, format, argv[0], argv[1], argv[2] ); + free( format ); + + res = NULL; + rc = ldap_search_st( ld, base[b].b_dn, + LDAP_SCOPE_SUBTREE, filter, attrs, 0, &timeout, + &res ); + + /* some other trouble - try again later */ + if ( rc != LDAP_SUCCESS && + rc != LDAP_SIZELIMIT_EXCEEDED ) { + syslog( LOG_ALERT, "return %d from X.500", rc ); + unbind_and_exit( EX_TEMPFAIL ); + } + + if ( (match = ldap_count_entries( ld, res )) != 0 ) + break; + + ldap_msgfree( res ); + } + + if ( match ) + break; + } + + /* trouble - try again later */ + if ( match == -1 ) { + syslog( LOG_ALERT, "error parsing result from X.500" ); + unbind_and_exit( EX_TEMPFAIL ); + } + + /* no matches - bounce with user unknown */ + if ( match == 0 ) { + add_error( err, nerr, E_USERUNKNOWN, name, NULLMSG ); + return; + } + + /* more than one match - bounce with ambiguous user? */ + if ( match > 1 ) { + LDAPMessage *next, *tmpres = NULL; + char *dn; + char **xdn; + + /* not giving rdn preference - bounce with ambiguous user */ + if ( base[b].b_rdnpref == 0 ) { + add_error( err, nerr, E_AMBIGUOUS, name, res ); + return; + } + + /* + * giving rdn preference - see if any entries were matched + * because of their rdn. If so, collect them to deal with + * later (== 1 we deliver, > 1 we bounce). + */ + + for ( e = ldap_first_entry( ld, res ); e != NULL; e = next ) { + next = ldap_next_entry( ld, e ); + dn = ldap_get_dn( ld, e ); + xdn = ldap_explode_dn( dn, 1 ); + + /* XXX bad, but how else can we do it? XXX */ + if ( strcasecmp( xdn[0], name ) == 0 ) { + ldap_delete_result_entry( &res, e ); + ldap_add_result_entry( &tmpres, e ); + } + + ldap_value_free( xdn ); + free( dn ); + } + + /* nothing matched by rdn - go ahead and bounce */ + if ( tmpres == NULL ) { + add_error( err, nerr, E_AMBIGUOUS, name, res ); + return; + + /* more than one matched by rdn - bounce with rdn matches */ + } else if ( (match = ldap_count_entries( ld, tmpres )) > 1 ) { + add_error( err, nerr, E_AMBIGUOUS, name, tmpres ); + return; + + /* trouble... */ + } else if ( match < 0 ) { + syslog( LOG_ALERT, "error parsing result from X.500" ); + unbind_and_exit( EX_TEMPFAIL ); + } + + /* otherwise one matched by rdn - send to it */ + ldap_msgfree( res ); + res = tmpres; + } + + /* + * if we get this far, it means that we found a single match for + * name. for a user, we deliver to the mail attribute or bounce + * with address and phone if no mail attr. for a group, we + * deliver to all members or bounce to rfc822ErrorsTo if no members. + */ + + /* trouble */ + if ( (e = ldap_first_entry( ld, res )) == NULL ) { + syslog( LOG_ALERT, "error parsing entry from X.500" ); + unbind_and_exit( EX_TEMPFAIL ); + } + + dn = ldap_get_dn( ld, e ); + + if ( type == GROUP_ERRORS ) { + /* sent to group-errors - resend to [rfc822]ErrorsTo attr */ + do_group_errors( e, dn, to, nto, err, nerr ); + + } else if ( type == GROUP_REQUEST ) { + /* sent to group-request - resend to [rfc822]RequestsTo attr */ + do_group_request( e, dn, to, nto, err, nerr ); + + } else if ( type == GROUP_MEMBERS ) { + /* sent to group-members - expand */ + do_group_members( e, dn, to, nto, togroups, ngroups, err, + nerr ); + + } else if ( isgroup( e ) ) { + /* + * sent to group - resend from [rfc822]ErrorsTo if it's there, + * otherwise, expand the group + */ + + do_group( e, dn, to, nto, togroups, ngroups, err, nerr ); + + ldap_msgfree( res ); + + } else { + /* + * sent to user - mail attribute => add it to the to list, + * otherwise bounce + */ + switch (identity) { + case FAX500 : + if ( (mail = ldap_get_values( ld, e, + "facsimileTelephoneNumber" )) != NULL ) { + char *fdn; + char **ufn; + int i; + + fdn = ldap_get_dn( ld, e ); + ufn = ldap_explode_dn( fdn, 1 ); + /* Convert spaces to underscores for rp */ + for (i = 0; ufn[0][i] != '\0'; i++) { + if (ufn[0][i] == ' ') { + ufn[0][i] = '_'; + } + } + *mail = faxtotpc(*mail, ufn[0]); + + add_to(to, nto, mail); + + if (fdn != NULL) { + free(fdn); + } + ldap_value_free( ufn ); + ldap_value_free( mail ); + ldap_msgfree( res ); + } else { + add_error( err, nerr, E_NOFAXNUM, + name, res ); + } + break; + case MAIL500 : + if ( (mail = ldap_get_values( ld, e, "mail" )) + != NULL ) { + add_to( to, nto, mail ); + + ldap_value_free( mail ); + ldap_msgfree( res ); + } else { + add_error( err, nerr, E_NOEMAIL, + name, res ); + } + break; + } + } + + free( dn ); + + return; +} + +static +do_group( e, dn, to, nto, togroups, ngroups, err, nerr ) + LDAPMessage *e; + char *dn; + char ***to; + int *nto; + Group **togroups; + int *ngroups; + Error **err; + int *nerr; +{ + /* + * If this group has an rfc822ErrorsTo attribute, we need to + * arrange for errors involving this group to go there, not + * to the sender. Since sendmail only has the concept of a + * single sender, we arrange for errors to go to groupname-errors, + * which we then handle specially when (if) it comes back to us + * by expanding to all the rfc822ErrorsTo addresses. If it has no + * rfc822ErrorsTo attribute, we call do_group_members() to expand + * the group. + */ + + if ( group_loop( dn ) ) { + return( -1 ); + } + + if ( has_attributes( e, "rfc822ErrorsTo", "errorsTo" ) ) { + add_group( dn, togroups, ngroups ); + + return( 0 ); + } + + do_group_members( e, dn, to, nto, togroups, ngroups, err, nerr ); + + return( 0 ); +} + +/* ARGSUSED */ +static +do_group_members( e, dn, to, nto, togroups, ngroups, err, nerr ) + LDAPMessage *e; + char *dn; + char ***to; + int *nto; + Group **togroups; + int *ngroups; + Error **err; + int *nerr; +{ + int i, rc; + char *ndn; + char **mail, **member, **joinable; + char filter[256]; + LDAPMessage *ee, *res; + struct timeval timeout; + + /* + * if all has gone according to plan, we've already arranged for + * errors to go to the [rfc822]ErrorsTo attributes (if they exist), + * so all we have to do here is arrange to send to the + * rfc822Mailbox attribute, the member attribute, and anyone who + * has joined the group by setting memberOfGroup equal to the + * group dn. + */ + + /* add members in the group itself - mail attribute */ + if ( (mail = ldap_get_values( ld, e, "mail" )) != NULL ) { + /* + * These are only email addresses - impossible + * to have a fax number + */ + switch (identity) { + case FAX500 : + /* XXX How do we want to inform sender that the */ + /* group they sent to has email-only members? */ + break; + case MAIL500 : + add_to( to, nto, mail ); + break; + } + + ldap_value_free( mail ); + } + + /* add members in the group itself - member attribute */ + if ( (member = ldap_get_values( ld, e, "member" )) != NULL ) { + for ( i = 0; member[i] != NULL; i++ ) { + add_member( dn, member[i], to, nto, togroups, + ngroups, err, nerr ); + } + + ldap_value_free( member ); + } + + /* add members who have joined by setting memberOfGroup */ + if ( (joinable = ldap_get_values( ld, e, "joinable" )) != NULL ) { + if ( strcasecmp( joinable[0], "FALSE" ) == 0 ) { + ldap_value_free( joinable ); + return; + } + ldap_value_free( joinable ); + + sprintf( filter, "(memberOfGroup=%s)", dn ); + + timeout.tv_sec = FAX_TIMEOUT; + timeout.tv_usec = 0; + + /* for each subtree to look in... */ + ld->ld_sizelimit = FAX_MAXMEMBERS; + for ( i = 0; base[i].b_dn != NULL; i++ ) { + /* find entries that have joined this group... */ + rc = ldap_search_st( ld, base[i].b_dn, + LDAP_SCOPE_SUBTREE, filter, attrs, 0, &timeout, + &res ); + + if ( rc == LDAP_SIZELIMIT_EXCEEDED || + rc == LDAP_TIMELIMIT_EXCEEDED ) { + syslog( LOG_ALERT, + "group search limit exceeded %d", rc ); + unbind_and_exit( EX_TEMPFAIL ); + } + + if ( rc != LDAP_SUCCESS ) { + syslog( LOG_ALERT, "group search bad return %d", + rc ); + unbind_and_exit( EX_TEMPFAIL ); + } + + /* for each entry that has joined... */ + for ( ee = ldap_first_entry( ld, res ); ee != NULL; + ee = ldap_next_entry( ld, ee ) ) { + if ( isgroup( ee ) ) { + ndn = ldap_get_dn( ld, ee ); + + if ( do_group( e, ndn, to, nto, + togroups, ngroups, err, nerr ) + == -1 ) { + syslog( LOG_ALERT, + "group loop (%s) (%s)", + dn, ndn ); + } + + free( ndn ); + + continue; + } + + /* add them to the to list */ + switch (identity) { + case FAX500 : + if ( (mail = ldap_get_values( ld, ee, + "facsimileTelephoneNumber" )) + != NULL ) { + char *fdn; + char **ufn; + int i; + + fdn = ldap_get_dn( ld, ee ); + ufn = ldap_explode_dn( fdn, 1 ); + /* + * Convert spaces to + * underscores for rp + */ + for (i = 0; ufn[0][i] != '\0'; + i++) { + if (ufn[0][i] == ' ') { + ufn[0][i] = '_'; + } + } + *mail = faxtotpc(*mail, ufn[0]); + add_to(to, nto, mail); + + ldap_value_free( mail ); + ldap_msgfree( res ); + } else { + ndn = ldap_get_dn( ld, ee ); + + add_error( err, nerr, + E_JOINMEMBERNOFAXNUM, ndn, + NULLMSG ); + + free( ndn ); + } + break; + case MAIL500 : + if ( (mail = ldap_get_values( ld, ee, + "mail" )) != NULL ) { + add_to( to, nto, mail ); + + ldap_value_free( mail ); + + /* else generate a bounce */ + } else { + ndn = ldap_get_dn( ld, ee ); + + add_error( err, nerr, + E_JOINMEMBERNOEMAIL, ndn, + NULLMSG ); + + free( ndn ); + } + break; + } + } + + ldap_msgfree( res ); + } + ld->ld_sizelimit = FAX_MAXAMBIGUOUS; + } + + return; +} + +add_member( gdn, dn, to, nto, togroups, ngroups, err, nerr ) + char *gdn; + char *dn; + char ***to; + int *nto; + Group **togroups; + int *ngroups; + Error **err; + int *nerr; +{ + char *ndn; + char **mail; + int rc; + LDAPMessage *res, *e; + struct timeval timeout; + + timeout.tv_sec = FAX_TIMEOUT; + timeout.tv_usec = 0; + if ( (rc = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "(objectclass=*)", + attrs, 0, &timeout, &res )) != LDAP_SUCCESS ) { + if ( rc == LDAP_NO_SUCH_OBJECT ) { + add_error( err, nerr, E_BADMEMBER, dn, NULLMSG ); + + return; + } else { + syslog( LOG_ALERT, "member search bad return %d", rc ); + + unbind_and_exit( EX_TEMPFAIL ); + } + } + + if ( (e = ldap_first_entry( ld, res )) == NULL ) { + syslog( LOG_ALERT, "member search error parsing entry" ); + + unbind_and_exit( EX_TEMPFAIL ); + } + ndn = ldap_get_dn( ld, e ); + + /* allow groups within groups */ + if ( isgroup( e ) ) { + if ( do_group( e, ndn, to, nto, togroups, ngroups, err, nerr ) + == -1 ) { + syslog( LOG_ALERT, "group loop (%s) (%s)", gdn, ndn ); + } + + free( ndn ); + + return; + } + + switch (identity) { + case FAX500 : + if ( (mail = ldap_get_values( ld, e, + "facsimileTelephoneNumber" )) != NULL ) { + char *fdn; + char **ufn; + int i; + fdn = ldap_get_dn( ld, e ); + ufn = ldap_explode_dn( fdn, 1 ); + /* Convert spaces to underscores for rp */ + for (i = 0; ufn[0][i] != '\0'; i++) { + if (ufn[0][i] == ' ') { + ufn[0][i] = '_'; + } + } + *mail = faxtotpc(*mail, ufn[0]); + add_to(to, nto, mail); + + ldap_value_free( mail ); + ldap_msgfree( res ); + } else { + add_error( err, nerr, E_MEMBERNOFAXNUM, ndn, NULLMSG ); + } + break; + case MAIL500 : + /* send to the member's mail attribute */ + if ( (mail = ldap_get_values( ld, e, "mail" )) != NULL ) { + add_to( to, nto, mail ); + + ldap_value_free( mail ); + + /* else generate a bounce */ + } else { + add_error( err, nerr, E_MEMBERNOEMAIL, ndn, NULLMSG ); + } + + free( ndn ); + } + return; +} + +do_group_request( e, dn, to, nto, err, nerr ) + LDAPMessage *e; + char *dn; + char ***to; + int *nto; + Error **err; + int *nerr; +{ + char **requeststo; + + if ( (requeststo = get_attributes_mail_dn( e, "rfc822RequestsTo", + "requestsTo" )) != NULL ) { + add_to( to, nto, requeststo ); + + ldap_value_free( requeststo ); + } else { + add_error( err, nerr, E_NOREQUEST, dn, NULLMSG ); + } + + return; +} + +do_group_errors( e, dn, to, nto, err, nerr ) + LDAPMessage *e; + char *dn; + char ***to; + int *nto; + Error **err; + int *nerr; +{ + char **errorsto; + + if ( (errorsto = get_attributes_mail_dn( e, "rfc822ErrorsTo", + "errorsTo" )) != NULL ) { + add_to( to, nto, errorsto ); + + ldap_value_free( errorsto ); + } else { + add_error( err, nerr, E_NOERRORS, dn, NULLMSG ); + } + + return; +} + +static +send_message( to ) + char **to; +{ + int pid; +#ifndef USE_WAITPID + WAITSTATUSTYPE status; +#endif + + + /* parent */ + if ( pid = fork() ) { +#ifdef USE_WAITPID + waitpid( pid, (int *) NULL, 0 ); +#else + wait4( pid, &status, WAIT_FLAGS, 0 ); +#endif + /* child */ + } else { + /* to includes sendmailargs */ + execv( FAX_SENDMAIL, to ); + + syslog( LOG_ALERT, "execv failed" ); + + exit( EX_TEMPFAIL ); + } +} + +static +send_group( group, ngroup ) + Group *group; + int ngroup; +{ + int i, pid; + char **argv; + int argc; + char *iargv[7]; +#ifndef USE_WAITPID + WAITSTATUSTYPE status; +#endif + + for ( i = 0; i < ngroup; i++ ) { + (void) rewind( stdin ); + + iargv[0] = FAX_SENDMAIL; + iargv[1] = "-f"; + iargv[2] = group[i].g_errorsto; + iargv[3] = "-oMrX.500"; + iargv[4] = "-odi"; + iargv[5] = "-oi"; + iargv[6] = NULL; + + argv = NULL; + argc = 0; + add_to( &argv, &argc, iargv ); + add_to( &argv, &argc, group[i].g_members ); + + + /* parent */ + if ( pid = fork() ) { +#ifdef USE_WAITPID + waitpid( pid, (int *) NULL, 0 ); +#else + wait4( pid, &status, WAIT_FLAGS, 0 ); +#endif + /* child */ + } else { + execv( FAX_SENDMAIL, argv ); + + syslog( LOG_ALERT, "execv failed" ); + + exit( EX_TEMPFAIL ); + } + } + + return; +} + +static +send_errors( err, nerr ) + Error *err; + int nerr; +{ + int i, namelen; + FILE *fp; + char buf[1024]; + + sprintf( buf, "%s -oMrX.500 -odi -oi -f %s %s", FAX_SENDMAIL, errorsfrom, + mailfrom ); + if ( (fp = popen( buf, "w" )) == NULL ) { + syslog( LOG_ALERT, "could not popen sendmail for errs" ); + return; + } + + fprintf( fp, "To: %s\n", mailfrom ); + fprintf( fp, "From: %s\n", errorsfrom ); + fprintf( fp, "Subject: undeliverable mail\n" ); + fprintf( fp, "\n" ); + fprintf( fp, "The following errors occurred when trying to deliver the attached mail:\n" ); + for ( i = 0; i < nerr; i++ ) { + namelen = strlen( err[i].e_addr ); + fprintf( fp, "\n" ); + + switch ( err[i].e_code ) { + case E_USERUNKNOWN: + fprintf( fp, "%s: User unknown\n", err[i].e_addr ); + break; + + case E_BADMEMBER: + fprintf( fp, "%s: Group member does not exist\n", + err[i].e_addr ); + break; + + case E_NOREQUEST: + fprintf( fp, "%s: Group exists but has no request address\n", + err[i].e_addr ); + break; + + case E_NOERRORS: + fprintf( fp, "%s: Group exists but has no errors-to address\n", + err[i].e_addr ); + break; + + case E_AMBIGUOUS: + do_ambiguous( fp, &err[i], namelen ); + break; + + case E_NOEMAIL: + do_noemailorfax( fp, &err[i], namelen, E_NOEMAIL ); + break; + + case E_MEMBERNOEMAIL: + fprintf( fp, "%s: Group member exists but does not have an email address\n", + err[i].e_addr ); + break; + + case E_JOINMEMBERNOEMAIL: + fprintf( fp, "%s: User has joined group but does not have an email address\n", + err[i].e_addr ); + break; + + case E_NOFAXNUM: + do_noemailorfax( fp, &err[i], namelen, E_NOFAXNUM ); + break; + + case E_MEMBERNOFAXNUM: + fprintf( fp, "%s: Group member exists but does not have a fax number\n", + err[i].e_addr ); + break; + + case E_JOINMEMBERNOFAXNUM: + fprintf( fp, "%s: User has joined group but does not have a fax number\n", + err[i].e_addr ); + break; + + default: + syslog( LOG_ALERT, "unknown error %d", err[i].e_code ); + unbind_and_exit( EX_TEMPFAIL ); + break; + } + } + + fprintf( fp, "\n------- The original message sent:\n\n" ); + + while ( fgets( buf, sizeof(buf), stdin ) != NULL ) { + fputs( buf, fp ); + } + + if ( pclose( fp ) == -1 ) { + syslog( LOG_ALERT, "pclose failed" ); + unbind_and_exit( EX_TEMPFAIL ); + } + + return; +} + + +static +do_noemailorfax( fp, err, namelen, errtype ) + FILE *fp; + Error *err; + int namelen; + int errtype; +{ + int i, last; + char *dn, *rdn; + char **ufn, **vals; + + if (errtype == E_NOFAXNUM) { + fprintf(fp, "%s: User has no facsimile number registered.\n", + err->e_addr ); + } else if (errtype == E_NOEMAIL) { + fprintf(fp, "%s: User has no email address registered.\n", + err->e_addr ); + } + fprintf( fp, "%*s Name, title, postal address and phone for '%s':\n\n", + namelen, " ", err->e_addr ); + + /* name */ + dn = ldap_get_dn( ld, err->e_msg ); + ufn = ldap_explode_dn( dn, 1 ); + rdn = strdup( ufn[0] ); + if ( strcasecmp( rdn, err->e_addr ) == 0 ) { + if ( (vals = ldap_get_values( ld, err->e_msg, "cn" )) + != NULL ) { + for ( i = 0; vals[i]; i++ ) { + last = strlen( vals[i] ) - 1; + if ( isdigit( vals[i][last] ) ) { + rdn = strdup( vals[i] ); + break; + } + } + + ldap_value_free( vals ); + } + } + fprintf( fp, "%*s %s\n", namelen, " ", rdn ); + free( dn ); + free( rdn ); + ldap_value_free( ufn ); + + /* titles or descriptions */ + if ( (vals = ldap_get_values( ld, err->e_msg, "title" )) == NULL && + (vals = ldap_get_values( ld, err->e_msg, "description" )) + == NULL ) { + fprintf( fp, "%*s No title or description registered\n", + namelen, " " ); + } else { + for ( i = 0; vals[i] != NULL; i++ ) { + fprintf( fp, "%*s %s\n", namelen, " ", vals[i] ); + } + + ldap_value_free( vals ); + } + + /* postal address */ + if ( (vals = ldap_get_values( ld, err->e_msg, "postalAddress" )) + == NULL ) { + fprintf( fp, "%*s No postal address registered\n", namelen, + " " ); + } else { + fprintf( fp, "%*s ", namelen, " " ); + for ( i = 0; vals[0][i] != '\0'; i++ ) { + if ( vals[0][i] == '$' ) { + fprintf( fp, "\n%*s ", namelen, " " ); + while ( isspace( vals[0][i+1] ) ) + i++; + } else { + fprintf( fp, "%c", vals[0][i] ); + } + } + fprintf( fp, "\n" ); + + ldap_value_free( vals ); + } + + /* telephone number */ + if ( (vals = ldap_get_values( ld, err->e_msg, "telephoneNumber" )) + == NULL ) { + fprintf( fp, "%*s No phone number registered\n", namelen, + " " ); + } else { + for ( i = 0; vals[i] != NULL; i++ ) { + fprintf( fp, "%*s %s\n", namelen, " ", vals[i] ); + } + + ldap_value_free( vals ); + } +} + +/* ARGSUSED */ +static +do_ambiguous( fp, err, namelen ) + FILE *fp; + Error *err; + int namelen; +{ + int i, last; + char *dn, *rdn; + char **ufn, **vals; + LDAPMessage *e; + + i = ldap_result2error( ld, err->e_msg, 0 ); + + fprintf( fp, "%s: Ambiguous user. %s%d matches found:\n\n", + err->e_addr, i == LDAP_SIZELIMIT_EXCEEDED ? "First " : "", + ldap_count_entries( ld, err->e_msg ) ); + + for ( e = ldap_first_entry( ld, err->e_msg ); e != NULL; + e = ldap_next_entry( ld, e ) ) { + dn = ldap_get_dn( ld, e ); + ufn = ldap_explode_dn( dn, 1 ); + rdn = strdup( ufn[0] ); + if ( strcasecmp( rdn, err->e_addr ) == 0 ) { + if ( (vals = ldap_get_values( ld, e, "cn" )) != NULL ) { + for ( i = 0; vals[i]; i++ ) { + last = strlen( vals[i] ) - 1; + if ( isdigit( vals[i][last] ) ) { + rdn = strdup( vals[i] ); + break; + } + } + + ldap_value_free( vals ); + } + } + + if ( isgroup( e ) ) { + vals = ldap_get_values( ld, e, "description" ); + } else { + vals = ldap_get_values( ld, e, "title" ); + } + + fprintf( fp, " %-20s %s\n", rdn, vals ? vals[0] : "" ); + for ( i = 1; vals && vals[i] != NULL; i++ ) { + fprintf( fp, " %s\n", vals[i] ); + } + + free( dn ); + free( rdn ); + ldap_value_free( ufn ); + if ( vals != NULL ) + ldap_value_free( vals ); + } +} + +static +count_values( list ) + char **list; +{ + int i; + + for ( i = 0; list && list[i] != NULL; i++ ) + ; /* NULL */ + + return( i ); +} + +static +add_to( list, nlist, new ) + char ***list; + int *nlist; + char **new; +{ + int i, nnew, oldnlist; + + nnew = count_values( new ); + + oldnlist = *nlist; + if ( *list == NULL || *nlist == 0 ) { + *list = (char **) malloc( (nnew + 1) * sizeof(char *) ); + *nlist = nnew; + } else { + *list = (char **) realloc( *list, *nlist * sizeof(char *) + + nnew * sizeof(char *) + sizeof(char *) ); + *nlist += nnew; + } + + for ( i = 0; i < nnew; i++ ) { + (*list)[i + oldnlist] = strdup( new[i] ); + } + (*list)[*nlist] = NULL; + + return; +} + +static +isgroup( e ) + LDAPMessage *e; +{ + int i; + char **oclist; + + oclist = ldap_get_values( ld, e, "objectClass" ); + + for ( i = 0; oclist[i] != NULL; i++ ) { + if ( strcasecmp( oclist[i], "rfc822MailGroup" ) == 0 ) { + ldap_value_free( oclist ); + return( 1 ); + } + } + ldap_value_free( oclist ); + + return( 0 ); +} + +static +add_error( err, nerr, code, addr, msg ) + Error **err; + int *nerr; + int code; + char *addr; + LDAPMessage *msg; +{ + if ( *nerr == 0 ) { + *err = (Error *) malloc( sizeof(Error) ); + } else { + *err = (Error *) realloc( *err, (*nerr + 1) * sizeof(Error) ); + } + + (*err)[*nerr].e_code = code; + (*err)[*nerr].e_addr = strdup( addr ); + (*err)[*nerr].e_msg = msg; + (*nerr)++; + + return; +} + +static +add_group( dn, list, nlist ) + char *dn; + Group **list; + int *nlist; +{ + int i, namelen; + char **ufn; + + for ( i = 0; i < *nlist; i++ ) { + if ( strcmp( dn, (*list)[i].g_dn ) == 0 ) { + syslog( LOG_ALERT, "group loop 2 detected (%s)", dn ); + return; + } + } + + ufn = ldap_explode_dn( dn, 1 ); + namelen = strlen( ufn[0] ); + + if ( *nlist == 0 ) { + *list = (Group *) malloc( sizeof(Group) ); + } else { + *list = (Group *) realloc( *list, (*nlist + 1) * + sizeof(Group) ); + } + + /* send errors to groupname-errors@host */ + (*list)[*nlist].g_errorsto = (char *) malloc( namelen + sizeof(ERRORS) + + hostlen + 2 ); + sprintf( (*list)[*nlist].g_errorsto, "%s-%s@%s", ufn[0], ERRORS, host ); + (void) canonical( (*list)[*nlist].g_errorsto ); + + /* send to groupname-members@host - make it a list for send_group */ + (*list)[*nlist].g_members = (char **) malloc( 2 * sizeof(char *) ); + (*list)[*nlist].g_members[0] = (char *) malloc( namelen + + sizeof(MEMBERS) + hostlen + 2 ); + sprintf( (*list)[*nlist].g_members[0], "%s-%s@%s", ufn[0], MEMBERS, + host ); + (void) canonical( (*list)[*nlist].g_members[0] ); + (*list)[*nlist].g_members[1] = NULL; + + /* save the group's dn so we can check for loops above */ + (*list)[*nlist].g_dn = strdup( dn ); + + (*nlist)++; + + ldap_value_free( ufn ); + + return; +} + +static +unbind_and_exit( rc ) + int rc; +{ + int i; + + if ( (i = ldap_unbind( ld )) != LDAP_SUCCESS ) + syslog( LOG_ALERT, "ldap_unbind failed %d\n", i ); + + exit( rc ); +} + +static char * +canonical( s ) + char *s; +{ + char *saves = s; + + for ( ; *s != '\0'; s++ ) { + if ( *s == ' ' ) + *s = '.'; + } + + return( saves ); +} + +static +group_loop( dn ) + char *dn; +{ + int i; + static char **groups; + static int ngroups; + + for ( i = 0; i < ngroups; i++ ) { + if ( strcmp( dn, groups[i] ) == 0 ) + return( 1 ); + } + + if ( ngroups == 0 ) + groups = (char **) malloc( sizeof(char *) ); + else + groups = (char **) realloc( groups, + (ngroups + 1) * sizeof(char *) ); + + groups[ngroups++] = strdup( dn ); + + return( 0 ); +} + +static +has_attributes( e, attr1, attr2 ) + LDAPMessage *e; + char *attr1; + char *attr2; +{ + char **attr; + + if ( (attr = ldap_get_values( ld, e, attr1 )) != NULL ) { + ldap_value_free( attr ); + return( 1 ); + } + + if ( (attr = ldap_get_values( ld, e, attr2 )) != NULL ) { + ldap_value_free( attr ); + return( 1 ); + } + + return( 0 ); +} + +static char ** +get_attributes_mail_dn( e, attr1, attr2 ) + LDAPMessage *e; + char *attr1; + char *attr2; /* this one is dn-valued */ +{ + LDAPMessage *ee, *res; + char **vals, **dnlist, **mail; + int nto, i, rc; + struct timeval timeout; + + vals = ldap_get_values( ld, e, attr1 ); + for ( nto = 0; vals != NULL && vals[nto] != NULL; nto++ ) + ; /* NULL */ + + if ( (dnlist = ldap_get_values( ld, e, attr2 )) != NULL ) { + timeout.tv_sec = FAX_TIMEOUT; + timeout.tv_usec = 0; + + for ( i = 0; dnlist[i] != NULL; i++ ) { + if ( (rc = ldap_search_st( ld, dnlist[i], + LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, + &timeout, &res )) != LDAP_SUCCESS ) { + if ( rc != LDAP_NO_SUCH_OBJECT ) { + unbind_and_exit( EX_TEMPFAIL ); + } + + syslog( LOG_ALERT, "bad (%s) dn (%s)", attr2, + dnlist[i] ); + + continue; + } + + if ( (ee = ldap_first_entry( ld, res )) == NULL ) { + syslog( LOG_ALERT, "error parsing x500 entry" ); + continue; + } + + if ( (mail = ldap_get_values( ld, ee, "mail" )) + != NULL ) { + add_to( &vals, &nto, mail ); + + ldap_value_free( mail ); + } + + ldap_msgfree( res ); + } + } + + return( vals ); +} diff --git a/clients/fax500/rp500.c b/clients/fax500/rp500.c new file mode 100644 index 0000000000..25eece609d --- /dev/null +++ b/clients/fax500/rp500.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 1990 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lber.h" +#include "ldap.h" + +#define DEFAULT_PORT 79 +#define DEFAULT_SIZELIMIT 50 + +int debug; +char *ldaphost = LDAPHOST; +char *base = DEFAULT_BASE; +int deref; +int sizelimit; +LDAPFiltDesc *filtd; + +static print_entry(); + +static +usage( name ) + char *name; +{ + fprintf( stderr, "usage: %s [-d debuglevel] [-x ldaphost] [-b searchbase] [-a] [-z sizelimit] [-f filterfile] searchstring\r\n", name ); + exit( -1 ); +} + +main (argc, argv) + int argc; + char **argv; +{ + int i, rc, matches; + char *filterfile = FILTERFILE; + struct timeval timeout; + char buf[10]; + char *key; + LDAP *ld; + LDAPMessage *result, *e; + LDAPFiltDesc *filtd; + LDAPFiltInfo *fi; + static char *attrs[] = { "title", "o", "ou", "postalAddress", + "telephoneNumber", "mail", + "facsimileTelephoneNumber", NULL }; + extern char *optarg; + extern int optind; + + deref = LDAP_DEREF_ALWAYS; + while ( (i = getopt( argc, argv, "ab:d:f:x:z:" )) != EOF ) { + switch( i ) { + case 'a': /* do not deref aliases when searching */ + deref = LDAP_DEREF_FINDING; + break; + + case 'b': /* search base */ + base = strdup( optarg ); + break; + + case 'd': /* turn on debugging */ + debug = atoi( optarg ); + break; + + case 'f': /* ldap filter file */ + filterfile = strdup( optarg ); + break; + + case 'x': /* specify ldap host */ + ldaphost = strdup( optarg ); + break; + + case 'z': /* size limit */ + sizelimit = atoi( optarg ); + break; + + default: + usage( argv[0] ); + } + } + + if ( optind == argc ) { + usage( argv[0] ); + } + key = argv[optind]; + + if ( (filtd = ldap_init_getfilter( filterfile )) == NULL ) { + fprintf( stderr, "Cannot open filter file (%s)\n", filterfile ); + exit( -1 ); + } + + if ( (ld = ldap_open( ldaphost, LDAP_PORT )) == NULL ) { + perror( "ldap_open" ); + exit( -1 ); + } + ld->ld_sizelimit = sizelimit ? sizelimit : DEFAULT_SIZELIMIT; + ld->ld_deref = deref; + + if ( ldap_simple_bind_s( ld, RP_BINDDN, NULL ) != LDAP_SUCCESS ) { + fprintf( stderr, "X.500 is temporarily unavailable.\n" ); + ldap_perror( ld, "ldap_simple_bind_s" ); + exit( -1 ); + } + + result = NULL; + if ( strchr( key, ',' ) != NULL ) { + ld->ld_deref = LDAP_DEREF_FINDING; + if ( (rc = ldap_ufn_search_s( ld, key, attrs, 0, &result )) + != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED && + rc != LDAP_TIMELIMIT_EXCEEDED ) + { + ldap_perror( ld, "ldap_ufn_search_s" ); + exit( -1 ); + } + matches = ldap_count_entries( ld, result ); + } else { + for ( fi = ldap_getfirstfilter( filtd, "rp500", key ); + fi != NULL; fi = ldap_getnextfilter( filtd ) ) { + if ( (rc = ldap_search_s( ld, base, LDAP_SCOPE_SUBTREE, + fi->lfi_filter, attrs, 0, &result )) + != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED + && rc != LDAP_TIMELIMIT_EXCEEDED ) + { + ldap_perror( ld, "ldap_search" ); + exit( -1 ); + } + + if ( (matches = ldap_count_entries( ld, result )) != 0 + || rc != LDAP_SUCCESS ) { + break; + } + } + } + + if ( matches == 1 ) { + e = ldap_first_entry( ld, result ); + + print_entry( ld, e ); + } else if ( matches > 1 ) { + fprintf( stderr, "%d %s matches for \"%s\":\r\n", matches, + fi->lfi_desc, key ); + + for ( i = 1, e = ldap_first_entry( ld, result ); e != NULL; + i++, e = ldap_next_entry( ld, e ) ) { + int j; + char *p, *dn, *rdn; + char **title; + + dn = ldap_get_dn( ld, e ); + rdn = dn; + if ( (p = strchr( dn, ',' )) != NULL ) + *p = '\0'; + while ( *rdn && *rdn != '=' ) + rdn++; + if ( *rdn ) + rdn++; + if ( strcasecmp( rdn, buf ) == 0 ) { + char **cn; + char *s; + int i, last; + + cn = ldap_get_values( ld, e, "cn" ); + for ( i = 0; cn[i] != NULL; i++ ) { + last = strlen( cn[i] ) - 1; + if ( isdigit( cn[i][last] ) ) { + rdn = strdup( cn[i] ); + break; + } + } + } + + title = ldap_get_values( ld, e, "title" ); + + fprintf( stderr, " %d: %-20s %s\r\n", i, rdn, + title ? title[0] : "" ); + if ( title != NULL ) { + for ( j = 1; title[j] != NULL; j++ ) + fprintf( stderr, " %-20s %s\r\n", + "", title[j] ); + } + if ( title != NULL ) + ldap_value_free( title ); + + free( dn ); + } + if ( rc == LDAP_SIZELIMIT_EXCEEDED + || rc == LDAP_TIMELIMIT_EXCEEDED ) { + fprintf( stderr, "(Size or time limit exceeded)\n" ); + } + + fprintf( stderr, "Enter the number of the person you want: "); + + if ( fgets( buf, sizeof(buf), stdin ) == NULL + || buf[0] == '\n' ) { + exit( 1 ); + } + i = atoi( buf ) - 1; + e = ldap_first_entry( ld, result ); + for ( ; i > 0 && e != NULL; i-- ) { + e = ldap_next_entry( ld, e ); + } + if ( e == NULL ) { + fprintf( stderr, "Invalid choice!\n" ); + exit( 1 ); + } + + print_entry( ld, e ); + } else if ( matches == 0 ) { + fprintf( stderr, "No matches found for \"%s\"\n", key ); + exit( 1 ); + } else { + fprintf( stderr, "Error return from ldap_count_entries\n" ); + exit( -1 ); + } + + ldap_unbind( ld ); + return( 0 ); +} + +static +print_entry( ld, e ) + LDAP *ld; + LDAPMessage *e; +{ + int i; + char *dn, *rdn; + char **ufn; + char **title, **dept, **addr, **phone, **fax, **mail; + char *faxmail, *org, *faxtotpc(); + + dn = ldap_get_dn( ld, e ); + ufn = ldap_explode_dn( dn, 0 ); + rdn = strchr( ufn[0], '=' ) + 1; + + if ( (fax = ldap_get_values( ld, e, "facsimileTelephoneNumber" )) + == NULL ) { + fprintf( stderr, "Entry \"%s\" has no fax number.\n", dn ); + exit( 1 ); + } + faxmail = faxtotpc( fax[0] ); + title = ldap_get_values( ld, e, "title" ); + phone = ldap_get_values( ld, e, "telephoneNumber" ); + mail = ldap_get_values( ld, e, "mail" ); + dept = ldap_get_values( ld, e, "ou" ); + addr = ldap_get_values( ld, e, "postalAddress" ); + org = ""; + for ( i = 0; ufn[i] != NULL; i++ ) { + if ( strncmp( "o=", ufn[i], 2 ) == 0 ) { + org = strdup( strchr( ufn[i], '=' ) + 1 ); + break; + } + } + + printf( "To: %s\n", faxmail ); + printf( "Subject:\n" ); + printf( "--------\n" ); + printf( "#&1 + exit 1 +fi + +DB=".rpdb" +if [ ! -s "$DB" ]; then + DB="$HOME/.rpdb" +fi +if [ ! -s "$DB" ]; then + echo "unable to read $DB" 2>&1 + exit 1 +fi + +C=/tmp/rp$$.comp S=/tmp/rp$$.sh O=/tmp/rp$$.orig +trap "rm -f $C $S $O" 0 1 2 3 13 15 + +cp /dev/null $S +gawk -v NAME="$NAME" -v S="$S" -v O="$O" ' +function rev(f) { + s = "" + for (l = length(f); l > 0; l--) + s = s "." substr(f, l, 1) + return substr(s, 2, length(s) - 1) +} + +BEGIN { + RS= ""; FS = "\n" + } + { + if (NR == 1) { + from = $2 + gsub("Recipient[ ]*:", "Originator:", from); + orig = "\r\n" from + for (i = 3; i <= NF; i++) + orig = orig "\r\n" $i; + printf orig "\r\n" > O + } + + if ($1 != NAME) + next + for (i = 2; i <= NF; i++) { + if (match($i, "Facsimile[ ]*:") > 0) { + fax = substr($i, RSTART+RLENGTH) + gsub("[ +-]", "", fax) + + printf "ADDR=\"remote-printer@%s.tpc.int\"\n", rev(fax) > S + printf "To: remote-printer@%s.tpc.int\n", rev(fax) + printf "Subject:\n" + printf "--------\n" + printf "# $C +. $S +if [ -z "$ADDR" ]; then + echo "recipient \"$NAME\" not in $DB, checking X.500..." 2>&1 + $RP500 "$NAME" > $C + RC=$? + if [ $RC = 1 ]; then + exit 1 + elif [ $RC = 0 ]; then + cat $O >> $C + echo "#" >> $C + else + echo "error searching X.500" 2>&1 + exit 1 + fi +fi + +shift +comp -form $C $* -editor rpprompter diff --git a/clients/finger/Make-template b/clients/finger/Make-template new file mode 100644 index 0000000000..d55329f839 --- /dev/null +++ b/clients/finger/Make-template @@ -0,0 +1,70 @@ +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# X.500 ldap finger daemon makefile +# +#----------------------------------------------------------------------------- + +LDAPSRC = ../.. +HDIR = $(LDAPSRC)/include +LDIR = $(LDAPSRC)/libraries +VERSIONFILE = $(LDAPSRC)/build/version + +SRCS = main.c +OBJS = main.o + +INCLUDES=-I$(HDIR) +DEFINES = $(DEFS) + +CFLAGS = $(INCLUDES) $(DEFINES) $(ACFLAGS) +LIBS = -lldap -llber $(KRBLIBFLAG) $(KRBLIBS) $(ALIBS) + +all: in.xfingerd + +in.xfingerd: version.o + $(CC) $(ALDFLAGS) -o $@ $(OBJS) version.o \ + -L$(LDIR) $(LIBS) + +version.c: $(OBJS) $(LDIR)/libldap.a + $(RM) $@ + (u=$${USER-root} v=`$(CAT) $(VERSIONFILE)` d=`$(PWD)` h=`$(HOSTNAME)` \ + t=`$(DATE)`; $(SED) -e "s|%WHEN%|$${t}|" \ + -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \ + -e "s|%VERSION%|$${v}|" \ + < Version.c > $@) + +install: in.xfingerd FORCE + -$(MKDIR) -p $(ETCDIR) + $(INSTALL) $(INSTALLFLAGS) -m 755 in.xfingerd $(ETCDIR) + +lint: FORCE + $(LINT) $(INCLUDES) $(DEFINES) $(SRCS) + +5lint: FORCE + $(5LINT) $(INCLUDES) $(DEFINES) $(SRCS) + +clean: FORCE + $(RM) *.o core a.out version.c in.xfingerd + +depend: FORCE + $(MKDEP) $(INCLUDES) $(DEFINES) $(SRCS) + +links: + @$(LN) .src/README .src/*.[ch] . + +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +main.o: main.c ../../include/lber.h ../../include/ldap.h +main.o: ../../include/disptmpl.h ../../include/portable.h +main.o: ../../include/ldapconfig.h + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/clients/finger/Version.c b/clients/finger/Version.c new file mode 100644 index 0000000000..90456ee53f --- /dev/null +++ b/clients/finger/Version.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 1991 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. + */ + +char Version[] = " in.xfingerd v%VERSION% (%WHEN%)\n\t%WHOANDWHERE%\n"; diff --git a/clients/finger/main.c b/clients/finger/main.c new file mode 100644 index 0000000000..38c8dfc769 --- /dev/null +++ b/clients/finger/main.c @@ -0,0 +1,429 @@ +/* + * Copyright (c) 1990,1994 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. + */ + +#include "lber.h" +#include "ldap.h" +#include "disptmpl.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef aix +#include +#endif /* aix */ +#include +#include "portable.h" +#include "ldapconfig.h" + +#ifdef USE_SYSCONF +#include +#endif /* USE_SYSCONF */ + +int dosyslog = 1; +char *ldaphost = LDAPHOST; +int ldapport = LDAP_PORT; +char *base = FINGER_BASE; +int deref; +char *filterfile = FILTERFILE; +char *templatefile = TEMPLATEFILE; +int rdncount = FINGER_RDNCOUNT; + +static do_query(); +static do_search(); +static do_read(); +static print_attr(); + +static usage( name ) +char *name; +{ + fprintf( stderr, "usage: %s [-l] [-x ldaphost] [-p ldapport] [-f filterfile] [-t templatefile] [-c rdncount]\r\n", name ); + exit( 1 ); +} + +main (argc, argv) +int argc; +char **argv; +{ + int i; + char *myname; + unsigned long mypeer = -1; + struct hostent *hp; + struct sockaddr_in peername; + int peernamelen; + int interactive = 0; + extern char *optarg; + + deref = FINGER_DEREF; + while ( (i = getopt( argc, argv, "f:ilp:t:x:p:c:" )) != EOF ) { + switch( i ) { + case 'f': /* ldap filter file */ + filterfile = strdup( optarg ); + break; + + case 'i': /* interactive */ + interactive = 1; + break; + + case 'l': /* don't do syslogging */ + dosyslog = 0; + break; + + case 't': /* ldap template file */ + templatefile = strdup( optarg ); + break; + + case 'x': /* specify ldap host */ + ldaphost = strdup( optarg ); + break; + + case 'p': /* specify ldap port */ + ldapport = atoi( optarg ); + break; + + case 'c': /* specify number of DN components to show */ + rdncount = atoi( optarg ); + break; + + default: + usage( argv[0] ); + } + } + + if ( !interactive ) { + peernamelen = sizeof(peername); + if ( getpeername( 0, (struct sockaddr *)&peername, + &peernamelen ) != 0 ) { + perror( "getpeername" ); + exit( 1 ); + } + mypeer = (unsigned long) peername.sin_addr.s_addr; + } + +#ifdef FINGER_BANNER + if ( FINGER_BANNER != NULL && strcmp( FINGER_BANNER, "" ) != 0 ) { + printf( FINGER_BANNER ); + fflush( stdout ); + } +#endif + + if ( (myname = strrchr( argv[0], '/' )) == NULL ) + myname = strdup( argv[0] ); + else + myname = strdup( myname + 1 ); + + if ( dosyslog ) { +#ifdef LOG_LOCAL4 + openlog( myname, OPENLOG_OPTIONS, LOG_LOCAL4 ); +#else + openlog( myname, OPENLOG_OPTIONS ); +#endif + } + + if ( dosyslog && mypeer != -1 ) { + struct in_addr addr; + + hp = gethostbyaddr( (char *) &mypeer, sizeof(mypeer), AF_INET ); + addr.s_addr = mypeer; + syslog( LOG_INFO, "connection from %s (%s)", (hp == NULL) ? + "unknown" : hp->h_name, inet_ntoa( addr ) ); + } + + do_query(); + + return( 0 ); +} + +static do_query() +{ + char buf[256]; + int len, rc, tblsize; + struct timeval timeout; + fd_set readfds; + LDAP *ld; + + if ( (ld = ldap_open( ldaphost, ldapport )) == NULL ) { + fprintf( stderr, FINGER_UNAVAILABLE ); + perror( "ldap_open" ); + exit( 1 ); + } + ld->ld_sizelimit = FINGER_SIZELIMIT; + ld->ld_deref = deref; + + if ( ldap_simple_bind_s( ld, FINGER_BINDDN, NULL ) != LDAP_SUCCESS ) { + fprintf( stderr, FINGER_UNAVAILABLE ); + ldap_perror( ld, "ldap_simple_bind_s" ); + exit( 1 ); + } + +#ifdef USE_SYSCONF + tblsize = sysconf( _SC_OPEN_MAX ); +#else /* USE_SYSCONF */ + tblsize = getdtablesize(); +#endif /* USE_SYSCONF */ + + timeout.tv_sec = FINGER_TIMEOUT; + timeout.tv_usec = 0; + FD_ZERO( &readfds ); + FD_SET( fileno( stdin ), &readfds ); + + if ( (rc = select( tblsize, &readfds, 0, 0, &timeout )) <= 0 ) { + if ( rc < 0 ) + perror( "select" ); + else + fprintf( stderr, "connection timed out on input\r\n" ); + exit( 1 ); + } + + if ( fgets( buf, sizeof(buf), stdin ) == NULL ) + exit( 1 ); + + len = strlen( buf ); + + /* strip off \r \n */ + if ( buf[len - 1] == '\n' ) { + buf[len - 1] = '\0'; + len--; + } + if ( buf[len - 1] == '\r' ) { + buf[len - 1] = '\0'; + len--; + } + + if ( len == 0 ) { + printf( "No campus-wide login information available. Info for this machine only:\r\n" ); + fflush( stdout ); + execl( FINGER_CMD, FINGER_CMD, NULL ); + } else { + char *p; + + /* skip and ignore stinking /w */ + if ( strncmp( buf, "/W ", 2 ) == 0 ) { + p = buf + 2; + } else { + p = buf; + } + + for ( ; *p && isspace( *p ); p++ ) + ; /* NULL */ + + do_search( ld, p ); + } +} + +static void +spaces2dots( s ) + char *s; +{ + for ( ; *s; s++ ) { + if ( *s == ' ' ) { + *s = '.'; + } + } +} + +static do_search( ld, buf ) +LDAP *ld; +char *buf; +{ + char *dn, *rdn; + char **title; + int rc, matches, i, ufn; + struct timeval tv; + LDAPFiltInfo *fi; + LDAPMessage *result, *e; + static char *attrs[] = { "cn", "title", "objectClass", "joinable", +#ifdef FINGER_SORT_ATTR + FINGER_SORT_ATTR, +#endif + 0 }; + extern int strcasecmp(); + + ufn = 0; +#ifdef FINGER_UFN + if ( strchr( buf, ',' ) != NULL ) { + ldap_ufn_setprefix( ld, base ); + tv.tv_sec = FINGER_TIMEOUT; + tv.tv_usec = 0; + ldap_ufn_timeout( (void *) &tv ); + + if ( (rc = ldap_ufn_search_s( ld, buf, attrs, 0, &result )) + != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED ) { + fprintf( stderr, FINGER_UNAVAILABLE ); + ldap_perror( ld, "ldap_search_st" ); + exit( 1 ); + } + + matches = ldap_count_entries( ld, result ); + ufn = 1; + } else { +#endif + if ( (ld->ld_filtd = ldap_init_getfilter( filterfile )) + == NULL ) { + fprintf( stderr, "Cannot open filter file (%s)\n", + filterfile ); + exit( 1 ); + } + + for ( fi = ldap_getfirstfilter( ld->ld_filtd, "finger", buf ); + fi != NULL; + fi = ldap_getnextfilter( ld->ld_filtd ) ) + { + tv.tv_sec = FINGER_TIMEOUT; + tv.tv_usec = 0; + if ( (rc = ldap_search_st( ld, base, LDAP_SCOPE_SUBTREE, + fi->lfi_filter, attrs, 0, &tv, &result )) + != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED + && rc != LDAP_TIMELIMIT_EXCEEDED ) + { + fprintf( stderr, FINGER_UNAVAILABLE ); + ldap_perror( ld, "ldap_search_st" ); + exit( 1 ); + } + + if ( (matches = ldap_count_entries( ld, result )) != 0 ) + break; + + ldap_msgfree( result ); + result = NULL; + } +#ifdef FINGER_UFN + } +#endif + + if ( rc == LDAP_SIZELIMIT_EXCEEDED ) { + printf( "(Partial results - a size limit was exceeded)\r\n" ); + } else if ( rc == LDAP_TIMELIMIT_EXCEEDED ) { + printf( "(Partial results - a time limit was exceeded)\r\n" ); + } + + if ( matches == 0 ) { + printf( FINGER_NOMATCH ); + fflush( stdout ); + } else if ( matches < 0 ) { + fprintf( stderr, "error return from ldap_count_entries\r\n" ); + exit( 1 ); + } else if ( matches <= FINGER_LISTLIMIT ) { + printf( "%d %s match%s found for \"%s\":\r\n", matches, + ufn ? "UFN" : fi->lfi_desc, matches > 1 ? "es" : "", buf ); + fflush( stdout ); + + for ( e = ldap_first_entry( ld, result ); e != NULL; ) { + do_read( ld, e ); + e = ldap_next_entry( ld, e ); + if ( e != NULL ) { + printf( "--------------------\r\n" ); + } + } + } else { + printf( "%d %s matches for \"%s\":\r\n", matches, + ufn ? "UFN" : fi->lfi_desc, buf ); + fflush( stdout ); + +#ifdef FINGER_SORT_ATTR + ldap_sort_entries( ld, &result, FINGER_SORT_ATTR, strcasecmp ); +#endif + + for ( e = ldap_first_entry( ld, result ); e != NULL; + e = ldap_next_entry( ld, e ) ) { + char *p; + + dn = ldap_get_dn( ld, e ); + rdn = dn; + if ( (p = strchr( dn, ',' )) != NULL ) + *p = '\0'; + while ( *rdn && *rdn != '=' ) + rdn++; + if ( *rdn ) + rdn++; + + /* hack attack */ + for ( i = 0; buf[i] != '\0'; i++ ) { + if ( buf[i] == '.' || buf[i] == '_' ) + buf[i] = ' '; + } + if ( strcasecmp( rdn, buf ) == 0 ) { + char **cn; + int i, last; + + cn = ldap_get_values( ld, e, "cn" ); + for ( i = 0; cn[i] != NULL; i++ ) { + last = strlen( cn[i] ) - 1; + if ( isdigit( cn[i][last] ) ) { + rdn = strdup( cn[i] ); + break; + } + } + } + + title = ldap_get_values( ld, e, "title" ); + + spaces2dots( rdn ); + printf( " %-20s %s\r\n", rdn, + title ? title[0] : "" ); + if ( title != NULL ) { + for ( i = 1; title[i] != NULL; i++ ) + printf( " %-20s %s\r\n", "", + title[i] ); + } + fflush( stdout ); + + if ( title != NULL ) + ldap_value_free( title ); + + free( dn ); + } + } + + if ( result != NULL ) { + ldap_msgfree( result ); + } + ldap_unbind( ld ); +} + + +static int +entry2textwrite( void *fp, char *buf, int len ) +{ + return( fwrite( buf, len, 1, (FILE *)fp ) == 0 ? -1 : len ); +} + + +static do_read( ld, e ) +LDAP *ld; +LDAPMessage *e; +{ + static struct ldap_disptmpl *tmpllist; + static char *defattrs[] = { "mail", NULL }; + static char *mailvals[] = FINGER_NOEMAIL; + static char **defvals[] = { mailvals, NULL }; + + ldap_init_templates( templatefile, &tmpllist ); + + if ( ldap_entry2text_search( ld, NULL, base, e, tmpllist, defattrs, + defvals, entry2textwrite, (void *)stdout, "\r\n", rdncount, + LDAP_DISP_OPT_DOSEARCHACTIONS ) != LDAP_SUCCESS ) { + ldap_perror( ld, "ldap_entry2text_search" ); + exit( 1 ); + } + + if ( tmpllist != NULL ) { + ldap_free_templates( tmpllist ); + } +} diff --git a/clients/gopher/Make-template b/clients/gopher/Make-template new file mode 100644 index 0000000000..9c45559d7a --- /dev/null +++ b/clients/gopher/Make-template @@ -0,0 +1,91 @@ +#----------------------------------------------------------------------------- +# Copyright (c) 1994 Regents of the University of Michigan. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that this notice is preserved and that due credit is given +# to the University of Michigan at Ann Arbor. The name of the University +# may not be used to endorse or promote products derived from this +# software without specific prior written permission. This software +# is provided ``as is'' without express or implied warranty. +# +# gopher to x.500 gateway makefile +# +#----------------------------------------------------------------------------- + +LDAPSRC = ../.. +HDIR = $(LDAPSRC)/include +LDIR = $(LDAPSRC)/libraries +VERSIONFILE = $(LDAPSRC)/build/version + +SRCS = go500.c go500gw.c detach.c setproctitle.c +OBJS = go500.o go500gw.o detach.o setproctitle.o +GOOBJS = go500.o detach.o goversion.o setproctitle.o +GWOBJS = go500gw.o detach.o gwversion.o setproctitle.o + +INCLUDES= -I$(HDIR) +DEFINES = $(DEFS) + +CFLAGS = $(INCLUDES) $(DEFS) $(ACFLAGS) +LIBS = -lldap -llber $(KRBLIBFLAG) $(KRBLIBS) $(ALIBS) + +DLIBS = $(LDIR)/libldap.a $(LDIR)/liblber.a + +all: go500gw go500 + +go500gw: gwversion.o + $(CC) $(ALDFLAGS) -o $@ $(GWOBJS) -L$(LDIR) $(LIBS) + +go500: goversion.o + $(CC) $(ALDFLAGS) -o $@ $(GOOBJS) -L$(LDIR) $(LIBS) + +goversion.c: go500.o detach.o setproctitle.o $(DLIBS) + $(RM) $@ + (u=$${USER-root} v=`$(CAT) $(VERSIONFILE)` d=`$(PWD)` h=`$(HOSTNAME)` \ + t=`$(DATE)`; $(SED) -e "s|%WHEN%|$${t}|" \ + -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \ + -e "s|%VERSION%|$${v}|" \ + < Version.c > $@) + +gwversion.c: go500gw.o detach.o setproctitle.o $(DLIBS) + $(RM) $@ + (u=$${USER-root} v=`$(CAT) $(VERSIONFILE)` d=`$(PWD)` h=`$(HOSTNAME)` \ + t=`$(DATE)`; $(SED) -e "s|%WHEN%|$${t}|" \ + -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \ + -e "s|%VERSION%|$${v}|" \ + < Versiongw.c > $@) + +install: go500 go500gw go500gw.help FORCE + -$(MKDIR) -p $(ETCDIR) + $(INSTALL) $(INSTALLFLAGS) -m 755 go500 $(ETCDIR) + $(INSTALL) $(INSTALLFLAGS) -m 755 go500gw $(ETCDIR) + -$(MV) $(ETCDIR)/go500gw.help $(ETCDIR)/go500gw.help- + $(INSTALL) $(INSTALLFLAGS) -m 644 go500gw.help $(ETCDIR) + +lint: FORCE + $(LINT) $(INCLUDES) $(DEFINES) $(SRCS) + +5lint: FORCE + $(5LINT) $(INCLUDES) $(DEFINES) $(SRCS) + +clean: FORCE + $(RM) *.o core a.out gwversion.c goversion.c go500gw go500 + +depend: FORCE + $(MKDEP) $(INCLUDES) $(DEFINES) $(SRCS) + +links: + @$(LN) .src/README .src/*.help .src/*.[ch] . + +# DO NOT DELETE THIS LINE -- mkdep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + +go500.o: go500.c ../../include/portable.h ../../include/ldapconfig.h +go500.o: ../../include/lber.h ../../include/ldap.h ../../include/disptmpl.h +go500gw.o: go500gw.c ../../include/lber.h ../../include/ldap.h +go500gw.o: ../../include/disptmpl.h ../../include/portable.h +go500gw.o: ../../include/ldapconfig.h +detach.o: detach.c ../../include/portable.h +setproctitle.o: setproctitle.c + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/clients/gopher/README b/clients/gopher/README new file mode 100644 index 0000000000..1289269343 --- /dev/null +++ b/clients/gopher/README @@ -0,0 +1,188 @@ +This directory contains source for two programs: + + go500 A gopher index search server to X.500 gateway + + go500gw A more general gopher to X.500 gateway + +Both programs use the LDAP protocol to talk to X.500. If you did not +get this software with the U-M LDAP software distribution, you will +need to have the LDAP libraries on hand to be able to make this software. +The LDAP distribution is available for anonymous ftp from the host +terminator.rs.itd.umich.edu in the x500/ directory. + +What you are trying to set up looks like this: + + -------- ----------------- -------- -------- +| gopher | | gopher to| LDAP | | LDAP | | X.500 | +| client |<- gophr ->| LDAP g/w | API |<- LDAP ->| server |<- DAP ->| server | +|________| |__________|______| |________| |________| + go500gw ldapd + or + go500 + +Both go500 and go500gw can be run either from inetd or as stand-alone +servers. + +go500 is useful when you always want to search a fixed portion of the X.500 +tree. It does not let you browse around or change where you search. + +go500gw is useful when you want to provide a more general and flexible +gateway from gopher to X.500. It allows users to browse around anywhere +in the X.500 tree, doing searches at any point. + +************************************************************************** +* RUNNING go500 * +************************************************************************** + +1) Make and install the ldap distribution if you have not already done so: + + (cd ../; make lib-only; make inst-lib) + + or + + (cd ../; make all; make install) + + Use the second form if you don't already have an ldapd running + somewhere you can connect to. Note that to make an ldap server, + you will need the ISODE libraries and include files. + +2) Tailor go500 to your site before compiling: + + vi go500.c + + There are a couple of things to change in go500.c: + + DAPUSER - This is the DN go500 will bind to the directory as. + You can specify NULL if you want. + + DEFAULT_BASE - This is the DN of the object below which go500 + will conduct its search. You typically want this to + be the DN or your organization. + + DEFAULT_LDAPHOST - This is the host that is running the ldap + server. If it's not on the localhost, you'll need to + change this. + +3) Make go500: + + make + +4) Start the ldap daemon: + + ldapd [-c dsaname] + + You only need to do this if you're not already running one. + +5) Start go500 as a stand-alone server: + + go500 + + or arrange to have it start from inetd: + + # vi /etc/services /* add the following line */ + go500 5555/tcp go500 # go500 server + + # vi /etc/inetd.conf /* add the following line */ + go500 stream tcp nowait nobody $(ETCDIR)/go500 go500 -I + + # kill -HUP /* make inetd notice the change */ + + where $(ETCDIR) is replaced by the ETCDIR from the top level Makefile + and is replaced by the pid of the inetd process. + +6) Configure your local gopher server to have an entry for go500. + A sample .link file is given below, with the things you should + change given in <>'s: + + Name=